/* ==========================================================================
   MAIN STYLES  —  sebastiangraysen.com homepage
   --------------------------------------------------------------------------
   This file paints the page. It reads the colours, fonts, and spacing values
   from tokens.css (which must be loaded first) and applies them.

   Sections in this file, in order:
     1. FONTS ............ loads Fraunces and Inter from the /fonts/ folder
     2. RESET ............ irons out inconsistent browser defaults
     3. BASE ............. background, base text, links, headings
     4. HELPERS .......... skip link + screen-reader-only text
     5. LAYOUT ........... the centred content column + section spacing
     6. NAV .............. the top-right menu
     7. HERO ............. first screen: photo, name, headline, Listen link
     8. LISTEN ........... Spotify player + italic caption
     9. INTRODUCTION ..... the statement paragraph + Read more link
    10. SUBSCRIBE ........ mailing-list line + email box
    11. FOOTER
    12. MOTION .......... the fade animations (and the switch that turns them
                          off for people who prefer reduced motion)

   You normally will not need to edit this file to change wording — that lives
   in index.html. Edit here only to change how things LOOK.
   ========================================================================== */


/* ==========================================================================
   1. FONTS
   The actual font files sit in /fonts/. These rules tell the browser which
   file is which. "swap" means text shows immediately in a fallback font and
   is upgraded to the real font the instant it finishes loading.
   ========================================================================== */

@font-face {
  font-family: "Fraunces";
  src: url("../fonts/fraunces-variable.woff2") format("woff2");
  font-weight: 100 900;                /* one file covers every weight */
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Fraunces";
  src: url("../fonts/fraunces-variable-italic.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;                  /* the slanted version, used for captions */
  font-display: swap;
}
@font-face {
  font-family: "Inter";
  src: url("../fonts/inter-variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}


/* ==========================================================================
   2. RESET — a light, modern reset so the page looks the same across browsers.
   ========================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }     /* sane sizing maths */

* { margin: 0; }                          /* remove default outer spacing */

img,
picture,
iframe { display: block; max-width: 100%; } /* media behaves predictably */

/* Photographs carry width="" and height="" in the HTML so the browser can
   reserve the right space before the picture arrives (it stops the page
   jumping about as things load). This line stops that stated height from
   also forcing the picture's height on screen — the layout decides that.
   Anything that genuinely needs a fixed height sets one of its own below. */
img { height: auto; }

input,
button { font: inherit; color: inherit; } /* form controls inherit the page font */

a { color: inherit; text-decoration: none; } /* links styled explicitly below */


/* ==========================================================================
   3. BASE — the overall look: near-black background, warm text, the fonts.
   ========================================================================== */

html {
  -webkit-text-size-adjust: 100%;
}

/* The page must never scroll sideways, on any screen. */
html, body { overflow-x: hidden; }

/* Smooth scrolling for the on-page "Listen" / "Subscribe" links — but only
   for visitors who have not asked their device to reduce motion. */
@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

body {
  background-color: var(--near-black);
  color: var(--warm-grey);              /* body text colour */
  font-family: var(--font-body);        /* Inter */
  font-size: 1.125rem;                  /* 18px base */
  line-height: 1.7;                     /* generous, page-like reading rhythm */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Headings and the artist name use the display serif, in the cream colour.
   "optical-sizing: auto" lets Fraunces subtly refine its letterforms at large
   sizes — the detail that separates a display serif from a plain webfont. */
h1, h2, h3 {
  font-family: var(--font-display);     /* Fraunces */
  color: var(--warm-cream);
  font-weight: 400;
  line-height: 1.05;
  font-optical-sizing: auto;
}


/* ==========================================================================
   4. HELPERS
   ========================================================================== */

/* Skip link — hidden until a keyboard user presses Tab, then it appears
   top-left so they can jump past the menu straight to the content. */
.skip-link {
  position: absolute;
  left: var(--space-2);
  top: -100px;                          /* parked off-screen */
  z-index: 100;
  background: var(--near-black);
  color: var(--warm-cream);
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--hairline);
  transition: top var(--dur-fast) var(--ease-cinematic);
}
.skip-link:focus { top: var(--space-2); }

/* Visually hidden — text that screen readers can read but eyes cannot see.
   Used for the email box's label. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0);
  white-space: nowrap; border: 0;
}


/* ==========================================================================
   5. LAYOUT — the centred reading column and the space around each section.
   ========================================================================== */

/* .wrap is the page column: it caps the overall width at 1280px, centres it,
   and holds the outer side margins. Content blocks sit INSIDE it. */
.wrap {
  width: 100%;
  max-width: var(--content-max);        /* 1280px */
  margin-inline: auto;
  padding-inline: var(--outer-margin);  /* 24px on phones → 64px on desktop */
}

/* .col is a constrained block of content placed asymmetrically inside .wrap.
   Empty space on the opposite side is deliberate — it's half the design. */
.col { max-width: var(--prose-max); }         /* narrow, page-like measure */
.col--left  { margin-inline-end: auto; }      /* hug the left, space on the right */
.col--right { margin-inline-start: auto; }    /* hug the right, space on the left */

/* Each below-the-fold section. Generous vertical space is the whole point. */
.section {
  padding-block: var(--space-12);       /* 96px top & bottom on mobile */
  border-top: 1px solid var(--hairline);/* faint divider between sections */
}
@media (min-width: 768px) {
  .section { padding-block: var(--space-20); } /* 160px on desktop */
}

/* A single 1px hairline running the full height of the screen, anchored to
   the left edge of the page column — a quiet architectural skeleton.
   Hidden on narrow phones where it would crowd the content. */
body::before {
  content: "";
  position: fixed;
  top: 0; bottom: 0;
  /* line up with the inner-left of the centred 1280px column */
  left: max(var(--outer-margin), calc((100vw - var(--content-max)) / 2 + var(--outer-margin)));
  width: 1px;
  background: var(--hairline);
  pointer-events: none;                 /* never blocks clicks */
  z-index: 1;
  display: none;
}
@media (min-width: 900px) {
  body::before { display: block; }
}


/* ==========================================================================
   6. NAV — the small uppercase menu, top-right, floating over the hero.
   ========================================================================== */

.site-header {
  position: absolute;
  top: 0; right: 0;
  z-index: 10;
  padding: var(--space-3) var(--space-4);
}

.nav__list {
  list-style: none;
  padding: 0;                           /* browsers indent every list by ~40px by default.
                                           Invisible on a laptop, but on the smallest phones
                                           that hidden indent was what pushed "Subscribe"
                                           off the right edge of the screen. */
  display: flex;
  flex-wrap: wrap;                      /* on a phone the items drop to a second line */
  justify-content: flex-end;
  gap: var(--space-2) var(--space-3);
}

.nav a {
  font-family: var(--font-body);        /* Inter */
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--warm-grey);
  transition: color var(--dur-fast) var(--ease-cinematic);
}
.nav a:hover { color: var(--ember-lit); }   /* accent shows only on hover */

/* --- ON PHONES: the same five links, just tightened so they fit on one line.
   Nothing is hidden and nothing wraps — it's the same menu as on a computer. */
@media (max-width: 767px) {
  .nav__list {
    flex-wrap: nowrap;
    gap: 12px;
  }
  .nav a {
    font-size: 10px;
    letter-spacing: 0.08em;
  }
  .site-header {                        /* homepage: the floating menu hugs the corner more tightly */
    padding: var(--space-2) var(--space-2);
  }
  .site-header--solid {                 /* inner pages: the name sits above the menu row */
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-2);
  }
  .site-header--solid .nav__list { justify-content: flex-start; }
}


/* ==========================================================================
   7. HERO — the first screen.
   ========================================================================== */

.hero {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;                   /* fills the screen on mobile too */
  overflow: hidden;
  display: flex;
  align-items: flex-end;                /* text sits toward the bottom */
}

/* --------------------------------------------------------------------------
   THE DISSOLVE — the single most important rule on this site.

   A photograph must never look like a rectangle pasted onto a page. Two things
   together make it disappear into the page instead:

     1. The page background is the SAME warm black the photographs fade into.
        That colour was measured out of the photo files, not chosen by eye —
        see the note beside --near-black in tokens.css.
     2. The edges of every photograph are faded out to nothing, so there is no
        border, no corner, no line where picture stops and page starts.

   These two masks do the fading — one across, one down. Used together they
   soften all four edges at once. Any photo given the class .photo-dissolve
   gets this treatment.

   HOW FAR EACH EDGE FADES is adjustable per photograph, because it depends on
   the picture. A photo whose edge is already dark (the bridge at night) needs
   almost no fade to disappear. A photo with something BRIGHT at its edge (the
   out-of-focus stone at the bottom of the black-and-white one) needs a much
   longer fade, or you see a hard line. The four numbers below are the default;
   each page can override them in the PER-PAGE FADES block further down.

     --fade-left    where the picture becomes fully solid, coming in from the left
     --fade-right   where it starts fading out again toward the right
     --fade-top     where it becomes solid, coming down from the top
     --fade-bottom  where it starts fading out toward the bottom

   Bigger left/top numbers = longer, softer fade. Smaller right/bottom = ditto.
   -------------------------------------------------------------------------- */
.hero__media,
.page-hero__media,
.photo-dissolve {
  --fade-left:   27%;
  --fade-right:  94%;
  --fade-top:    11%;
  --fade-bottom: 89%;

  --dissolve-across: linear-gradient(to right,
      transparent 0%, #000 var(--fade-left), #000 var(--fade-right), transparent 100%);
  --dissolve-down: linear-gradient(to bottom,
      transparent 0%, #000 var(--fade-top), #000 var(--fade-bottom), transparent 100%);
}
.photo-dissolve {
  -webkit-mask-image: var(--dissolve-across), var(--dissolve-down);
          mask-image: var(--dissolve-across), var(--dissolve-down);
  -webkit-mask-composite: source-in;      /* older Safari/Chrome spelling */
          mask-composite: intersect;      /* the current standard spelling */
}

/* --------------------------------------------------------------------------
   PER-PAGE FADES — tuned to what is actually at the edge of each photograph.
   If a picture ever looks like it has a hard line on one side, this is the
   block to change. Nudge by a few per cent at a time.
   -------------------------------------------------------------------------- */

/* ABOUT — the black-and-white one. Bright out-of-focus stone across the
   bottom and light brickwork on the left, so both need a long fade. */
.page-hero--about .page-hero__media {
  --fade-bottom: 54%;
  --fade-left:   34%;
  --fade-right:  88%;
}

/* WORK — pale stone on the right edge and a light wall across the top. */
.page-hero--work .page-hero__media {
  --fade-top:   18%;
  --fade-right: 90%;
}

/* MUSIC — the lit street runs right to the bottom of the frame. */
.page-hero--music .page-hero__media {
  --fade-bottom: 78%;
}

/* CONTACT — dark almost everywhere; barely needs any fade at all. */
.page-hero--contact .page-hero__media {
  --fade-bottom: 92%;
  --fade-top:     8%;
}

/* The photograph. It was shot UPRIGHT (tall), so it is handled in two ways:

     • On a phone  — it simply fills the whole screen.
     • On a laptop — it stands as a tall panel on the RIGHT, as large as it can
       be while STILL SHOWING THE WHOLE FRAME (head and feet, nothing cut), and
       its edges dissolve into the page. The words sit in that darkness.

   The rule that does the fading lives in the wide-screen block further down
   (search for "HERO ON WIDE SCREENS"). */
.hero__media {
  position: absolute;
  inset: 0;                             /* stretch to all four edges */
  z-index: 0;
  background: var(--near-black);
}
.hero__img {
  width: 100%;
  height: 100%;
  object-fit: cover;                    /* fill without squashing */
  object-position: 46% 50%;             /* which part to keep when cropped */
  /* A light grade only. The warm street light IS the colour of this site,
     so it is deliberately NOT drained to grey. */
  filter: contrast(1.03) saturate(1.02) brightness(1.02);
}

/* The wash — a soft darkening over the photo so the words stay readable.
   On a phone it rises from the bottom; on a laptop it comes in from the left
   (see the wide-screen block below). */
.hero__wash {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to top,
    rgba(16, 12, 6, 0.94) 0%,
    rgba(16, 12, 6, 0.62) 34%,
    rgba(16, 12, 6, 0.16) 66%,
    transparent 100%);
}

/* Inset vignette — darkens the edges to draw the eye inward. */
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  box-shadow: inset 0 0 200px 60px rgba(0, 0, 0, 0.85);
}

/* Grain overlay — a faint film-grain texture, generated here (no image file).
   Kept at ~4% opacity so it is felt more than seen. */
.hero::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  opacity: 0.04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* The hero text block sits above the photo, vignette, and grain, inside the
   page column (so it lines up with the vertical hairline), and low on screen. */
.hero__inner {
  position: relative;
  z-index: 3;
  width: 100%;
  max-width: var(--content-max);        /* the 1280px column */
  margin-inline: auto;
  padding-inline: var(--outer-margin);
  padding-bottom: var(--space-16);      /* lift the text off the bottom edge */
}

/* The words hug the left and stop well short of the right — the empty right
   side is the cinematic negative space. */
.hero__text {
  max-width: 62ch;
}

/* --------------------------------------------------------------------------
   HERO ON WIDE SCREENS (laptops and desktops, roughly 1000px and wider).

   This is where the tall photo becomes a panel on the right. If you ever want
   the photo to fill the WHOLE screen instead, with the words sitting on top
   of it, delete this whole block — everything else keeps working.
   -------------------------------------------------------------------------- */
@media (min-width: 1000px) {

  /* The photo occupies the right-hand side only, at its natural tall shape,
     and its left edge dissolves into the page's black. */
  .hero__media {
    inset: 0 0 0 auto;                  /* pin to the right, full height */
    /* As wide as the photo can be while the WHOLE upright frame still fits on
       screen — nothing cut off the top or the bottom. The photo is 2:3, so its
       natural width is two thirds of its height; 66vh is that, and 52vw stops
       it swallowing the page on very short, wide windows. */
    width: min(52vw, 66vh);
    -webkit-mask-image: var(--dissolve-across), var(--dissolve-down);
            mask-image: var(--dissolve-across), var(--dissolve-down);
    -webkit-mask-composite: source-in;
            mask-composite: intersect;
  }
  /* "contain" rather than "cover": show the entire photograph, never crop it. */
  .hero__img { object-fit: contain; object-position: 50% 50%; }

  /* The wash now comes in from the left instead of up from the bottom. */
  .hero__wash {
    background: linear-gradient(to right,
      rgba(16, 12, 6, 0.86) 0%,
      rgba(16, 12, 6, 0.35) 36%,
      transparent 58%);
  }

  /* The words keep to the left half so they never collide with the photo. */
  .hero__text  { max-width: 38rem; }
  .hero .wordmark { font-size: clamp(3.5rem, 6.8vw, 7.5rem); }
  .hero__inner { padding-bottom: var(--space-20); }
}

/* The artist name — the big display type. Scales smoothly between phone and
   desktop: about 56px on a phone, up to 140px on a wide screen. */
.wordmark {
  font-size: clamp(3.5rem, 11vw, 8.75rem);
  letter-spacing: -0.02em;
  line-height: 0.92;
}

/* The single headline beneath the name — set in the italic Fraunces, the
   typeface's most distinctive, faintly unsettling voice. */
.headline {
  font-family: var(--font-display);     /* Fraunces */
  font-style: italic;
  font-weight: 300;
  color: var(--warm-cream);
  font-size: clamp(1.375rem, 2.8vw, 2rem);
  line-height: 1.2;
  margin-top: var(--space-4);
  max-width: 20ch;                      /* let it break to two elegant lines */
}

/* The one primary action — an underlined link, deliberately not a button. */
.listen-link {
  display: inline-block;
  margin-top: var(--space-5);
  font-family: var(--font-body);        /* Inter */
  text-transform: uppercase;
  font-size: 0.8125rem;                 /* 13px */
  letter-spacing: 0.12em;
  color: var(--warm-cream);
  padding-bottom: var(--space-1);
  border-bottom: 1px solid var(--hairline);
  transition: border-color var(--dur-fast) var(--ease-cinematic);
}
.listen-link:hover { border-color: var(--ember-lit); } /* accent on hover only */


/* ==========================================================================
   8. LISTEN — the Spotify player and the italic caption line.
   ========================================================================== */

/* The player is allowed a little more width than a prose block. */
.section--listen .col { max-width: var(--track-max); }

.spotify {
  border-radius: 12px;                  /* matches Spotify's own rounded corners */
  overflow: hidden;
}

/* The single italic line beneath the player. */
.caption {
  font-family: var(--font-display);     /* Fraunces */
  font-style: italic;
  color: var(--warm-grey);
  font-size: clamp(1.125rem, 2vw, 1.375rem);
  margin-top: var(--space-5);
  text-align: center;
}


/* ==========================================================================
   9. INTRODUCTION — the statement paragraph and Read more link.
   ========================================================================== */

.intro {
  font-family: var(--font-display);     /* Fraunces, for a literary feel */
  color: var(--warm-cream);
  font-size: clamp(1.5rem, 3.2vw, 2.125rem);
  line-height: 1.45;
}

/* Shared style for quiet underlined text links (Read more, etc.). */
.text-link {
  display: inline-block;
  margin-top: var(--space-5);
  font-family: var(--font-body);
  text-transform: uppercase;
  font-size: 0.8125rem;
  letter-spacing: 0.12em;
  color: var(--warm-cream);
  padding-bottom: var(--space-1);
  border-bottom: 1px solid var(--hairline);
  transition: border-color var(--dur-fast) var(--ease-cinematic);
}
.text-link:hover { border-color: var(--ember-lit); }


/* ==========================================================================
   10. SUBSCRIBE — the mailing-list line and the email box.
   ========================================================================== */

/* Keep the whole subscribe block to a tight, intimate width. */
.section--subscribe .col { max-width: var(--line-max); }

.mailing-line {
  font-family: var(--font-display);     /* Fraunces */
  font-style: italic;                   /* quiet, letter-like */
  color: var(--warm-cream);
  font-size: clamp(1.25rem, 2.4vw, 1.625rem);
  line-height: 1.3;
  margin-bottom: var(--space-5);
}

/* The email box is a single hairline underline — no border box, no fill. */
.subscribe-form {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 440px;
  border-bottom: 1px solid var(--hairline);
}

.subscribe-form__input {
  flex: 1;
  background: transparent;
  border: 0;
  color: var(--warm-cream);
  padding: var(--space-2) 0;
  font-size: 1rem;
}
.subscribe-form__input::placeholder { color: var(--warm-grey); opacity: 0.7; }
.subscribe-form__input:focus { outline: none; } /* keyboard focus handled globally below */

/* The send button is just the ember arrow — one of the few places the accent
   colour is allowed. */
.subscribe-form__send {
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--ember-lit);
  font-size: 1.375rem;
  line-height: 1;
  padding: 0 var(--space-1);
  transition: transform var(--dur-fast) var(--ease-cinematic);
}
.subscribe-form__send:hover { transform: translateX(3px); }

/* The small print under the box. */
.fine-print {
  margin-top: var(--space-2);
  font-size: 11px;
  opacity: 0.6;
}


/* ==========================================================================
   10b. SIGNATURE — the closing line, alone with plenty of air.
   ========================================================================== */

.section--signature {
  padding-block: 0 var(--space-16);     /* no extra gap on top — sits close to the mailing line */
  border-top: 0;                        /* no divider — reads as connected, not orphaned */
  text-align: center;
}
.signature {
  font-family: var(--font-display);     /* Fraunces */
  font-style: italic;
  font-weight: 300;
  color: var(--warm-cream);
  font-size: clamp(1.05rem, 1.8vw, 1.35rem); /* quiet — a signature, not a headline */
  letter-spacing: 0.01em;
  line-height: 1.3;
}


/* ==========================================================================
   11. FOOTER
   ========================================================================== */

.site-footer {
  border-top: 1px solid var(--hairline);
  padding-block: var(--space-12) var(--space-10);
  overflow: hidden;                     /* keeps the wide glow from causing sideways scroll */
}

/* The artist mark — the heart — sitting quietly above the footer line. */
.footer-mark-wrap {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: var(--space-8);
}

/* THE LIGHT — a soft cream glow behind the logo that fades away completely,
   so the artwork sits on light with no box and no edge anywhere. */
.footer-glow {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: clamp(300px, 48vw, 480px);
  height: clamp(300px, 48vw, 480px);
  border-radius: 50%;
  /* "closest-side" makes the fade measure to the circle's EDGE (not its corner),
     so the light is fully transparent before the edge — no rim, nothing to clip. */
  background: radial-gradient(circle closest-side,
    var(--warm-cream) 0%,
    var(--warm-cream) 30%,
    rgba(237, 230, 218, 0.72) 44%,
    rgba(237, 230, 218, 0.36) 57%,
    rgba(237, 230, 218, 0.12) 68%,
    rgba(237, 230, 218, 0) 80%);
  pointer-events: none;
}

/* The logo itself — the original artwork, unaltered, sitting in that light. */
.footer-mark {
  position: relative;                   /* sits above the glow */
  width: auto;
  height: clamp(200px, 30vw, 300px);
  border-radius: 0;
  opacity: 1;
}
.site-footer__inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr; /* copyright stays dead-centre, whatever the sides weigh */
  align-items: center;
  gap: var(--space-3);
}
.socials     { justify-self: start; }  /* social links hug the left */
.copyright   { justify-self: center; } /* centred in the footer */
.footer-work { justify-self: end; }    /* Work sits apart on the right */

/* On narrow screens, stack the three items and centre them. */
@media (max-width: 700px) {
  .site-footer__inner {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
    gap: var(--space-4);
  }
}

/* Social links — plain text wordmarks, never coloured icons. */
.socials {
  display: flex;
  flex-wrap: wrap;                      /* four names can wrap on a phone */
  gap: var(--space-2) var(--space-3);
}
.socials a,
.footer-work {
  font-family: var(--font-body);
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--warm-grey);
  transition: color var(--dur-fast) var(--ease-cinematic);
}
.socials a:hover,
.footer-work:hover { color: var(--ember-lit); }

.copyright {
  font-size: 12px;
  color: var(--warm-grey);
}


/* ==========================================================================
   12. MOTION — the fades, and the visible keyboard focus outline.
   ========================================================================== */

/* Visible focus ring for keyboard users (accessibility requirement). */
:focus-visible {
  outline: 2px solid var(--ember-lit);
  outline-offset: 4px;
}

/* Highlighting text on the page selects in ember — a quiet signature. */
::selection {
  background: var(--ember);
  color: var(--warm-cream);
}

/* --- Hero fade-in on page load ---------------------------------------
   The photo and name fade up over 1200ms; the headline and Listen link
   follow 300ms later. This runs automatically when the page loads. */
.hero__media,
.wordmark {
  animation: fade-in var(--dur-hero) var(--ease-cinematic) both;
}
.headline,
.listen-link {
  animation: fade-in var(--dur-hero) var(--ease-cinematic) both;
  animation-delay: 300ms;
}
@keyframes fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* --- Fade-up on scroll ------------------------------------------------
   Sections marked "reveal" start slightly lowered and transparent, then
   rise and fade in when scrolled into view. The ".js" switch (added by
   main.js) means that if JavaScript is off, everything simply shows —
   nothing is ever hidden from a visitor without scripts. */
.js .reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 800ms var(--ease-cinematic),
              transform 800ms var(--ease-cinematic);
}
.js .reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* --- Reduced motion ---------------------------------------------------
   If a visitor's device is set to reduce motion, turn every animation and
   transition off and make sure all content is fully visible. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
  .js .reveal {
    opacity: 1;
    transform: none;
  }
}


/* ==========================================================================
   13. INNER PAGES  (About, Work, Music, Contact, 404)
   Shared styles for every page beyond the homepage.
   ========================================================================== */

/* --- Solid header: the top bar used on inner pages (name left, menu right),
       instead of the homepage's menu that floats over the photo. --- */
.site-header--solid {
  position: static;
  display: flex;
  flex-wrap: wrap;                      /* name and menu stack on narrow phones */
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3) var(--outer-margin);
  border-bottom: 1px solid var(--hairline);
}
.brand {                                /* the name, links back to the homepage */
  font-family: var(--font-display);
  color: var(--warm-cream);
  font-size: 1.125rem;
  letter-spacing: 0.01em;
}
.nav a[aria-current="page"] { color: var(--warm-cream); } /* highlight current page */

/* --- The page body --- */
.page { padding-block: var(--space-10) var(--space-16); }
.page--center { min-height: 60vh; display: flex; align-items: center; }  /* for the 404 */

/* When a page opens with a full-width photograph, the photo starts straight
   under the menu bar — so the usual top padding is removed. */
.page--hero { padding-top: 0; }

/* --------------------------------------------------------------------------
   PAGE HERO — how About, Work, Music and Contact each open.

   It is the SAME treatment as the homepage, deliberately: one upright
   photograph standing on the right, shown WHOLE (head to feet, nothing cut),
   its edges dissolved into the page, with the page title and opening line in
   the darkness on the left. Every page therefore feels like the same night in
   the same city — unity — while each one is led by its own picture.

   It is set a little smaller than the homepage on purpose. The homepage should
   remain the biggest moment on the site.

   ONE PHOTO PER PAGE. That is a rule, not an accident.

   TO SWAP A PAGE'S PHOTO: replace the three files in /img/hero/ keeping their
   names — e.g. hero-work.jpg, hero-work@1125w.jpg, hero-work@750w.jpg.
   -------------------------------------------------------------------------- */
.page-hero {
  position: relative;
  width: 100%;
  min-height: 86vh;
  min-height: 86svh;                    /* the mobile-safe version of the same */
  display: flex;
  align-items: flex-end;
  margin-bottom: var(--space-12);
  background: var(--near-black);
}
.page-hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.page-hero__img {
  width: 100%;
  height: 100%;
  object-fit: cover;                    /* on a phone it fills the screen */
  object-position: 50% 45%;
  filter: contrast(1.03) saturate(1.02);
}
/* The darkening that keeps the words readable over the picture.
   On a phone it rises from the bottom; on a laptop it comes in from the left. */
.page-hero__wash {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to top,
    rgba(16, 12, 6, 0.93) 0%,
    rgba(16, 12, 6, 0.55) 32%,
    rgba(16, 12, 6, 0.12) 66%,
    transparent 100%);
}
.page-hero__inner {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding-inline: var(--outer-margin);
  padding-bottom: var(--space-10);
}
.page-hero .page-title { margin-bottom: var(--space-2); }
.page-hero .intro,
.page-hero .epigraph { max-width: 34rem; margin-top: var(--space-3); margin-bottom: 0; }

/* On a laptop: the photo becomes the standing panel on the right. */
@media (min-width: 1000px) {
  .page-hero {
    min-height: 88vh;
    margin-bottom: var(--space-16);
  }
  .page-hero__media {
    inset: 0 0 0 auto;
    width: min(46vw, 58vh);             /* whole frame, nothing cropped */
    -webkit-mask-image: var(--dissolve-across), var(--dissolve-down);
            mask-image: var(--dissolve-across), var(--dissolve-down);
    -webkit-mask-composite: source-in;
            mask-composite: intersect;
  }
  .page-hero__img { object-fit: contain; object-position: 50% 50%; }
  .page-hero__wash {
    background: linear-gradient(to right,
      rgba(16, 12, 6, 0.80) 0%,
      rgba(16, 12, 6, 0.30) 38%,
      transparent 60%);
  }
  .page-hero__inner { padding-bottom: var(--space-16); }
  .page-hero .page-title,
  .page-hero .intro,
  .page-hero .epigraph { max-width: 30rem; }
}
.page-title {
  font-size: clamp(2.5rem, 7vw, 4.5rem);
  letter-spacing: -0.02em;
  margin-bottom: var(--space-6);
}


/* --- Epigraph: a floating italic opening line (About, Music) --- */
.epigraph {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  color: var(--warm-cream);
  font-size: clamp(1.5rem, 3.2vw, 2.125rem);
  line-height: 1.35;
  margin-bottom: var(--space-8);
}

/* --- Long-form prose (About) — set in Inter for comfortable reading --- */
.prose { color: var(--warm-grey); }
.prose p { margin-bottom: var(--space-4); }

/* --- Pull quote: one line, in the ember accent (About) --- */
.pull-quote {
  font-family: var(--font-display);
  font-style: italic;
  color: var(--ember-lit);
  font-size: 1.6em;
  line-height: 1.3;
  margin-block: var(--space-6);
}

/* --- Work: the three pillars (Voice / Piano / Mentorship) --- */
.pillars {
  display: grid;
  grid-template-columns: 1fr;           /* stacked on mobile */
  gap: var(--space-8);
  margin-block: var(--space-10);
}
@media (min-width: 768px) {
  .pillars { grid-template-columns: repeat(3, 1fr); gap: var(--space-6); }
  .pillar + .pillar { border-left: 1px solid var(--hairline); padding-left: var(--space-6); }
}
.pillar__num {
  font-family: var(--font-display);
  color: var(--ember-lit);
  font-size: 0.9rem;
  letter-spacing: 0.1em;
  margin-bottom: var(--space-2);
}
.pillar__title { font-size: 1.5rem; margin-bottom: var(--space-2); }
.pillar__body { color: var(--warm-grey); font-size: 1rem; }

/* --- Quiet practical / commercial line (Work, Music) --- */
.practical { color: var(--warm-grey); max-width: var(--prose-max); }

/* --- Music: each track block --- */
.track {
  padding-block: var(--space-10);
  border-top: 1px solid var(--hairline);
  max-width: var(--track-max);
}
.track__num {
  font-family: var(--font-display);
  color: var(--ember-lit);
  letter-spacing: 0.1em;
  margin-bottom: var(--space-1);
}
.track__title { font-size: clamp(1.75rem, 4vw, 2.5rem); }
.track__meta {
  font-family: var(--font-display);
  font-style: italic;
  color: var(--warm-grey);
  margin-top: var(--space-1);
  margin-bottom: var(--space-4);
}
.track__player { margin-bottom: var(--space-3); }
.track__player-placeholder {
  border: 1px solid var(--hairline);
  border-radius: 12px;
  padding: var(--space-5);
  color: var(--warm-grey);
  font-size: 0.85rem;
  text-align: center;
  margin-bottom: var(--space-3);
}
.track__links a { color: var(--warm-grey); }
.track__links a:hover { color: var(--ember-lit); }

/* --- Contact: the direct email lines --- */
.contact-lines { list-style: none; padding: 0; margin-block: var(--space-6) var(--space-4); }  /* padding:0 removes the browser's hidden list indent, which was pushing the longer addresses off the edge of small phones */
.contact-lines li {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding-block: var(--space-2);
  border-bottom: 1px solid var(--hairline);
}
.contact-lines span { color: var(--warm-grey); min-width: 9rem; }
.contact-lines a { color: var(--warm-cream); border-bottom: 1px solid var(--hairline); }
.contact-lines a:hover { border-color: var(--ember-lit); }
.sync-note {
  color: var(--warm-grey);
  font-style: italic;
  font-family: var(--font-display);
  margin-bottom: var(--space-8);
}

/* --- Contact: the fallback form --- */
.contact-form { max-width: var(--line-max); }
.field { display: block; margin-bottom: var(--space-5); }
.field__label {
  display: block;
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.12em;
  color: var(--warm-grey);
  margin-bottom: var(--space-1);
}
.field input,
.field textarea {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--hairline);
  color: var(--warm-cream);
  padding: var(--space-2) 0;
  font-size: 1rem;
  resize: vertical;
}
.field input:focus,
.field textarea:focus { outline: none; border-color: var(--warm-grey); }
.contact-form__send {
  margin-top: var(--space-2);
  background: transparent;
  border: 1px solid var(--hairline);
  color: var(--warm-cream);
  padding: var(--space-2) var(--space-5);
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.12em;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-cinematic);
}
.contact-form__send:hover { border-color: var(--ember-lit); }

/* --- Inline text link (sits inside a normal sentence, not on its own line) --- */
.text-link--inline {
  display: inline;
  margin-top: 0;
  text-transform: none;
  letter-spacing: 0;
  font-family: inherit;
  font-size: inherit;
  color: var(--warm-cream);
}

/* The small accent marks glow faintly - dark, but alive. */
.track__num,
.pillar__num,
.subscribe-form__send {
  text-shadow: 0 0 5px rgba(205, 62, 62, 0.55), 0 0 18px rgba(166, 47, 47, 0.5);
}

/* HOVER GLOW - when a link is hovered, its blood-red tone gets a halo:
   dark at the core, glowing around it. */
.nav a:hover,
.socials a:hover,
.footer-work:hover,
.track__links a:hover {
  text-shadow: 0 0 5px rgba(205, 62, 62, 0.5), 0 0 16px rgba(166, 47, 47, 0.45);
}

/* Underlined links (Listen, Read more) and the contact Send button:
   the red border glows softly on hover. */
.listen-link:hover,
.text-link:hover {
  box-shadow: 0 6px 14px -6px rgba(180, 50, 50, 0.6);
}
.contact-form__send:hover {
  box-shadow: 0 0 16px -2px rgba(180, 50, 50, 0.45);
}


/* ==========================================================================
   13. HOW EACH PHOTOGRAPH BEHAVES
   --------------------------------------------------------------------------
   The five photographs do NOT all get the same treatment. Doing the same
   thing everywhere is how a design stops being a decision and becomes a
   template. Each page's behaviour is chosen from what is actually IN its
   picture:

     HOME      you under the bridge, looking UP at the light.
               The photo LAGS as you scroll — you descend past him while he
               keeps looking up. Nothing else: the light source is already in
               the frame, so adding a fake one would be a lie.

     ABOUT     the black-and-white one, looking back at you through an
               out-of-focus foreground.
               The picture RESOLVES as you read — it starts largely dissolved
               and firms up while the page explains itself. "What I can't yet
               say," becoming said. Sits on the LEFT; the words move right.

     WORK      the painted wall.
               This is the colour moment of the site, and it is PAINT — so
               light is what reveals it. A soft warm light follows the cursor
               across the wall and lifts the colour where it falls. This is
               the only page with it, which is what makes it mean something.

     MUSIC     walking away down a lit street, straight down the perspective.
               Stands CENTRED, because the picture itself is centred and
               recedes. It pushes in very slowly as you scroll — he keeps
               walking — and the recordings rise over the street behind him.

     CONTACT   dead-on eye contact.
               NOTHING MOVES. Not an oversight — it is the point. Every other
               page drifts; this one simply looks back at you. Sits on the
               LEFT, so the reply lands on the right.

   All of it is switched off for anyone whose device asks for reduced motion,
   and none of it is needed for the site to work.
   ========================================================================== */

/* --- The text block inside a page hero, so it can be moved as a unit. --- */
.page-hero__text { max-width: 34rem; }
@media (min-width: 1000px) {
  .page-hero__text { max-width: 30rem; }
}

/* --- COMPOSITION: photograph on the LEFT, words to the right. --- */
@media (min-width: 1000px) {
  .page-hero--left .page-hero__media {
    inset: 0 auto 0 0;                  /* pin left instead of right */
  }
  /* The darkening now comes in from the right, where the words are. */
  .page-hero--left .page-hero__wash {
    background: linear-gradient(to left,
      rgba(16, 12, 6, 0.80) 0%,
      rgba(16, 12, 6, 0.30) 38%,
      transparent 60%);
  }
  .page-hero--left .page-hero__text { margin-left: auto; }

  /* The reading column below follows the words, not the picture. */
  .page-hero--left ~ .wrap .col--left {
    margin-inline-start: auto;
    margin-inline-end: 0;
  }
}

/* --- COMPOSITION: photograph CENTRED (Music). The street recedes straight
       down the middle of the frame, so the frame sits in the middle too. --- */
@media (min-width: 1000px) {
  .page-hero--music .page-hero__media {
    inset: 0;
    left: 0; right: 0;
    margin-inline: auto;                /* centred without needing a transform */
    width: min(54vw, 62vh);
  }
  /* Darkened from both sides so the centred picture stands in shadow. */
  .page-hero--music .page-hero__wash {
    background:
      linear-gradient(to right, rgba(16, 12, 6, 0.72) 0%, transparent 34%),
      linear-gradient(to left,  rgba(16, 12, 6, 0.55) 0%, transparent 26%);
  }
  /* Standing centred, BOTH side edges meet the page, so both have to dissolve
     a long way — the arch wall on the left and the shutters on the right are
     mid-toned, not dark, so they show a line if the fade is short. */
  .page-hero--music .page-hero__media {
    --fade-left:  30%;
    --fade-right: 70%;
    --fade-top:   16%;
  }
}

/* --- MOTION: the drift. The script sets --drift in pixels as you scroll;
       the photograph lags behind the page instead of being nailed to it. --- */
.js .page-hero__media,
.js .hero__media {
  transform: translate3d(0, var(--drift, 0px), 0) scale(var(--push, 1));
  transform-origin: var(--origin, 50% 50%);   /* the point the picture grows from — its top edge on phones, so nothing ever uncovers */
}

/* --- INTERACTION: the light that follows the cursor (Work only).
       It is a soft warm circle in "soft-light" blend mode, which lifts the
       colour already in the paint rather than painting new colour on top.
       It fades in only once the pointer is actually over the picture, and it
       never appears on touch screens, where there is no cursor. --- */
.photo-light {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0;
  transition: opacity 600ms var(--ease-cinematic);
  mix-blend-mode: soft-light;
  background: radial-gradient(
    circle 260px at var(--mx, 50%) var(--my, 50%),
    rgba(255, 238, 208, 0.85) 0%,
    rgba(255, 226, 180, 0.35) 38%,
    transparent 72%);
}
.page-hero--work .page-hero__media { position: absolute; }
.is-lit .photo-light { opacity: 1; }

@media (hover: none), (pointer: coarse), (prefers-reduced-motion: reduce) {
  .photo-light { display: none; }
}

/* When the photograph stands on the LEFT, the edge that meets the words is
   its RIGHT edge — so that is the one that has to dissolve a long way. The
   left edge is now the screen edge and needs barely anything. (These come
   after the per-page fades above on purpose, so they win.) */
@media (min-width: 1000px) {
  .page-hero--left .page-hero__media {
    --fade-left:  10%;
    --fade-right: 64%;
  }
}


/* ==========================================================================
   14. THE SPILL — the page is LIT BY the photograph
   --------------------------------------------------------------------------
   Fading a photo's edges away stops it looking like a rectangle. It does not
   yet make the page feel like part of the picture, because the darkness
   around the photo is still just... darkness.

   So each page now takes its LIGHT from its own photograph. The colour below
   is not invented: it is the average of the brightest twelve per cent of
   pixels in that picture — the sodium lamps, the neon, the lit paint. The
   page is lit by that light the way a dark room is lit by a screen.

   Measured values (brightest 12% of each frame):
     HOME     #FFC26D   sodium amber, strongly coloured
     ABOUT    near-white — the frame is black and white, so its light is
              colourless. Faking warmth here would break the one page whose
              whole point is that it is grey. Kept neutral, and kept weak.
     WORK     #FFF5D2   the light is pale; the colour lives in the PAINT
     MUSIC    #FFDFAA   street light down the arcade
     CONTACT  #FFCF77   amber off the road below

   --spill-x follows whichever side the photograph stands on, so the glow
   comes FROM the picture rather than sitting behind the words.
   ========================================================================== */

.page--home     { --spill-rgb: 255, 194, 109; --spill-a: 0.10; --spill-x: 74%; }
.page--about    { --spill-rgb: 255, 248, 238; --spill-a: 0.05; --spill-x: 26%; }
.page--work     { --spill-rgb: 255, 245, 210; --spill-a: 0.09; --spill-x: 76%; }
.page--music    { --spill-rgb: 255, 223, 170; --spill-a: 0.10; --spill-x: 50%; }
.page--contact  { --spill-rgb: 255, 207, 119; --spill-a: 0.08; --spill-x: 26%; }

/* The glow itself. It is a background, so it paints behind everything without
   needing an extra element or any z-index juggling. */
.hero,
.page-hero {
  background-color: var(--near-black);
  background-image: radial-gradient(
    95% 72% at var(--spill-x, 74%) 44%,
    rgba(var(--spill-rgb, 255, 194, 109), var(--spill-a, 0.09)) 0%,
    rgba(var(--spill-rgb, 255, 194, 109), calc(var(--spill-a, 0.09) * 0.42)) 32%,
    rgba(var(--spill-rgb, 255, 194, 109), calc(var(--spill-a, 0.09) * 0.14)) 55%,
    transparent 78%);
}

/* THE CARRY — the page below the picture does not snap back to neutral black.
   It keeps a trace of the photograph's light and lets it die away over about
   a screenful, so there is no line where the picture's world ends.

   The first stop has to sit just BELOW the photograph, because the picture's
   own panel is solid and would otherwise hide this entirely. The page heroes
   are 88vh tall; the homepage hero is a full 100vh, so it gets its own. */
.page--hero,
.page--tall-hero { background-repeat: no-repeat; }

/* The carry never fully reaches zero any more. It thins to a floor and STAYS
   there, so the light does not stop somewhere in the middle of the page and
   leave the bottom third sitting in flat, unrelated black. */
.page--hero {
  background-image: linear-gradient(
    to bottom,
    transparent 72vh,
    rgba(var(--spill-rgb), calc(var(--spill-a) * 0.55)) 90vh,
    rgba(var(--spill-rgb), calc(var(--spill-a) * 0.22)) 130vh,
    rgba(var(--spill-rgb), calc(var(--spill-a) * 0.10)) 200vh,
    rgba(var(--spill-rgb), calc(var(--spill-a) * 0.08)) 100%);
}
.page--tall-hero {
  background-image: linear-gradient(
    to bottom,
    transparent 84vh,
    rgba(var(--spill-rgb), calc(var(--spill-a) * 0.55)) 102vh,
    rgba(var(--spill-rgb), calc(var(--spill-a) * 0.22)) 145vh,
    rgba(var(--spill-rgb), calc(var(--spill-a) * 0.10)) 220vh,
    rgba(var(--spill-rgb), calc(var(--spill-a) * 0.08)) 100%);
}

/* --------------------------------------------------------------------------
   THE FOOTER AND THE LOGO.

   First attempt at this was wrong: the footer was forced back to flat black
   so the logo would have "clean ground". That just moved the hard edge to the
   bottom of the page — the light stopped dead and the logo sat in unrelated
   darkness below it.

   The page's light now carries all the way down and arrives AT the logo. The
   faint warm pool below sits underneath the logo's own cream halo, so the
   halo rises out of the page instead of being switched on against nothing.
   The pool is kept weak on purpose: the logo is black ink, and it still needs
   its ground to be dark enough to read against.
   -------------------------------------------------------------------------- */
.site-footer {
  position: relative;
  background-image: radial-gradient(
    78% 100% at 50% 30%,
    rgba(var(--spill-rgb, 255, 194, 109), calc(var(--spill-a, 0.09) * 0.30)) 0%,
    rgba(var(--spill-rgb, 255, 194, 109), calc(var(--spill-a, 0.09) * 0.12)) 44%,
    transparent 76%);
}


/* ==========================================================================
   15. THE TWO BRIGHT ONES — Home and Work
   --------------------------------------------------------------------------
   About and Contact settle into the page most easily, and there is a reason
   that has nothing to do with taste: they are the DARKEST frames in the set.
   Contact's edges measure #151008, almost the page colour already. About is
   black and white and carries the longest fade on the site.

   Home and Work are the two BRIGHTEST frames — a lit tunnel wall and a
   vividly painted one. A bright picture against a dark page has a far bigger
   jump to cross at its edge, so the same fade that dissolves a dark photo
   completely still leaves a visible boundary on these two.

   Two things close that gap: fade them over a longer distance, and light the
   page around them harder so there is less difference to hide in the first
   place. Both are done below. Nothing about the photographs is altered.
   ========================================================================== */

.page--home .hero__media {
  --fade-left:   38%;                   /* the edge facing the words */
  --fade-right:  92%;
  --fade-top:    17%;                   /* the lit ceiling of the underpass */
  --fade-bottom: 86%;
}

@media (min-width: 1000px) {
  .page--work .page-hero__media {
    --fade-left:  36%;
    --fade-right: 87%;
    --fade-top:   21%;                  /* the pale wall along the top */
  }
}

/* A broader, softer pool of light on every page — this is also the answer to
   the side of the screen that has no picture on it feeling like dead black.
   The bright two are lit a little harder still. */
.hero,
.page-hero {
  background-image: radial-gradient(
    112% 84% at var(--spill-x, 74%) 44%,
    rgba(var(--spill-rgb, 255, 194, 109), var(--spill-a, 0.09)) 0%,
    rgba(var(--spill-rgb, 255, 194, 109), calc(var(--spill-a, 0.09) * 0.46)) 30%,
    rgba(var(--spill-rgb, 255, 194, 109), calc(var(--spill-a, 0.09) * 0.20)) 52%,
    rgba(var(--spill-rgb, 255, 194, 109), calc(var(--spill-a, 0.09) * 0.07)) 70%,
    transparent 88%);
}
.page--home { --spill-a: 0.125; }
.page--work { --spill-a: 0.115; }


/* ==========================================================================
   16. PHONES
   --------------------------------------------------------------------------
   On a phone the photograph simply fills the screen, so there is no rectangle
   to dissolve on the left and right — the picture IS the edges. Only one edge
   needs work: the bottom, where the photograph meets the rest of the page.
   Without this it stops on a hard horizontal line, which is the same "cut
   off" problem the laptop version had.

   The top is left alone deliberately: it meets the menu bar, which is already
   a deliberate edge.
   ========================================================================== */

@media (max-width: 999px) {

  .page--home .hero__media,
  .page-hero .page-hero__media {
    --fade-top: 0%;
    --fade-bottom: 82%;
    -webkit-mask-image: var(--dissolve-down);
            mask-image: var(--dissolve-down);
  }

  /* The black-and-white one has that bright out-of-focus stone low in the
     frame, so it needs to start melting earlier than the rest. */
  .page-hero--about .page-hero__media { --fade-bottom: 72%; }

  /* Contact is almost black along the bottom already. Barely touch it. */
  .page-hero--contact .page-hero__media { --fade-bottom: 90%; }

  /* The wash can ease off, because the dissolve is now doing some of the work
     of keeping the words readable. */
  .page-hero__wash {
    background: linear-gradient(to top,
      rgba(16, 12, 6, 0.90) 0%,
      rgba(16, 12, 6, 0.50) 34%,
      rgba(16, 12, 6, 0.10) 66%,
      transparent 100%);
  }

  /* The light still has to reach the logo, but a phone page is far taller
     relative to its width, so the fall-off is stretched to suit. */
  .page--hero {
    background-image: linear-gradient(
      to bottom,
      transparent 74vh,
      rgba(var(--spill-rgb), calc(var(--spill-a) * 0.55)) 92vh,
      rgba(var(--spill-rgb), calc(var(--spill-a) * 0.20)) 150vh,
      rgba(var(--spill-rgb), calc(var(--spill-a) * 0.08)) 100%);
  }
  .page--tall-hero {
    background-image: linear-gradient(
      to bottom,
      transparent 86vh,
      rgba(var(--spill-rgb), calc(var(--spill-a) * 0.55)) 104vh,
      rgba(var(--spill-rgb), calc(var(--spill-a) * 0.20)) 165vh,
      rgba(var(--spill-rgb), calc(var(--spill-a) * 0.08)) 100%);
  }
}

/* --------------------------------------------------------------------------
   TAP TARGETS ON PHONES.

   The menu is five small words by design, and that stays — but a word only
   twelve pixels tall is a miss-tap waiting to happen on a touchscreen. Adding
   space ABOVE and BELOW each link makes the tappable area far bigger without
   changing the type size, the spacing between the words, or the fact that all
   five sit on one line. Nothing looks different; it just stops fighting your
   thumb.
   -------------------------------------------------------------------------- */
@media (max-width: 999px) {
  .nav__list a {
    display: inline-block;
    padding-block: 12px;                /* 12 + 12 + the text = ~36px to hit */
  }
  .socials a,
  .footer-work {
    display: inline-block;
    padding-block: 10px;
  }
  .contact-lines a { display: inline-block; padding-block: 4px; }
}

/* --------------------------------------------------------------------------
   THE SMALLEST PHONES (about 360px and under — an iPhone SE, older Androids).

   The rule is that all five menu words stay on ONE line, never wrapping and
   never becoming a hamburger. At 320px the row was running 21px past the edge
   of the screen, so "Subscribe" was sliding off and could not be tapped. It
   was invisible rather than obviously broken, because the page is set never
   to scroll sideways.

   Closing the gaps and the side padding slightly buys the room back. The type
   size is untouched.
   -------------------------------------------------------------------------- */
@media (max-width: 360px) {
  .nav__list { gap: 8px; }
  .site-header--solid { padding-inline: var(--space-2); }
  .site-header { padding-inline: var(--space-1); }
}


/* ==========================================================================
   17. THE MENU BAR — making every page open the way the homepage does
   --------------------------------------------------------------------------
   The homepage menu floats straight over the photograph, so the page opens
   with the picture and nothing else. The inner pages did something different:
   a solid black bar with a hairline ruled under it, sitting ON TOP of the
   page rather than in it. On a phone that reads as a heavy block stuck above
   the photo — bulky, and clearly a separate object.

   Every page now does what the homepage does. The bar, its background and its
   rule are gone; the name and the menu simply sit over the picture.

   Because the menu now lies over a photograph rather than on black, a soft
   darkening is drawn across the top of every hero so the words stay readable
   whatever the picture happens to be doing up there.
   ========================================================================== */

.site-header--solid {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  background: transparent;
  border-bottom: 0;                     /* the ruled line is gone */
  padding: var(--space-3) var(--outer-margin);
}

/* The scrim: a short fall of darkness from the top edge, so the menu reads
   over a bright photograph as well as a dark one. It is deliberately short —
   just enough for the words, not a band across the picture. */
.hero__wash::before,
.page-hero__wash::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 30vh;
  pointer-events: none;
  background: linear-gradient(to bottom,
    rgba(16, 12, 6, 0.78) 0%,
    rgba(16, 12, 6, 0.42) 26%,
    rgba(16, 12, 6, 0.14) 56%,
    transparent 100%);
}

/* The 404 has no photograph behind it, so it needs room for the floating
   menu that the heroes provide by themselves. */
.page--center { padding-top: var(--space-20); }

/* --- On phones the name sits above the menu. With no bar behind them they
       are just two quiet lines of type over the picture, so they can sit
       closer together and higher up. --- */
@media (max-width: 767px) {
  .site-header--solid {
    padding: var(--space-2) var(--outer-margin);
    gap: 2px;
  }
  .brand { font-size: 1rem; }
}

/* --- THE BOTTOM. The footer had a hairline ruled across the top of it, which
       did the same thing the menu bar was doing: announced a join. The page's
       light already carries down into the footer, so the line is removed and
       the bottom of the site simply continues. --- */
.site-footer { border-top: 0; }

/* --------------------------------------------------------------------------
   ONE MENU, ONE PLACE.

   The five words were landing differently depending on the page: right-hand
   edge on the homepage, centred in a column on the inner pages. That is what
   made moving between pages feel like moving between two websites.

   They now sit in the SAME position everywhere — same distance from the top,
   same distance from the right edge, aligned with the page's own margin. The
   name, which only the inner pages carry, sits quietly above them on a phone
   and opposite them on a computer.
   -------------------------------------------------------------------------- */
.site-header,
.site-header--solid {
  padding: var(--space-3) var(--outer-margin);
}

.site-header--solid {
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

@media (max-width: 767px) {
  .site-header,
  .site-header--solid {
    padding: var(--space-3) var(--space-3);
  }
  .site-header--solid {
    flex-direction: column;
    align-items: stretch;               /* so the two rows can align to opposite edges */
    gap: 2px;
  }
  .brand { align-self: flex-start; }
  /* The menu keeps to the right on EVERY page, including this one. */
  .site-header--solid .nav__list { justify-content: flex-end; }
}


/* ==========================================================================
   18. THE FOOTER ON A PHONE — "option 3, without the dots" (his choice)
   --------------------------------------------------------------------------
   Two centred lines under the heart:

        SPOTIFY    INSTAGRAM    TIKTOK    YOUTUBE
            © 2026 Sebastian Graysen    WORK

   All four socials stay on ONE line at every phone size. There are no
   separators: the even spacing between the words does the job, exactly as it
   does on the laptop, which is what keeps the two versions feeling like the
   same site. Tried first: a two-by-two block (rejected — "it has to be one
   line") and dots between the links (rejected — less uniform with the
   laptop).

   Work shares the second line with the copyright, set apart by the SAME gap
   as the socials and kept in the small spaced capitals — so it still reads as
   its own link, not as the end of the copyright sentence.

   The laptop footer is untouched: socials left, copyright centre, Work right.
   ========================================================================== */
@media (max-width: 700px) {
  .site-footer__inner {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: baseline;
    column-gap: var(--space-3);         /* 24px — the same gap as the socials */
    row-gap: var(--space-2);
    text-align: center;
  }
  .socials {
    flex-basis: 100%;                   /* the socials take a line of their own */
    flex-wrap: nowrap;                  /* …and never break it */
    justify-content: center;
    column-gap: var(--space-3);         /* 24px, as on the laptop */
    white-space: nowrap;
  }
}

/* The smallest phones (under 375px wide): the same layout, set a size smaller
   with the gaps closed slightly, so the line of four still holds. */
@media (max-width: 374px) {
  .socials a,
  .footer-work { font-size: 10px; letter-spacing: 0.08em; }
  .socials { column-gap: 14px; }
}


/* --------------------------------------------------------------------------
   THE SUBSCRIBE BOX, AFTER THE ARROW IS PRESSED.
   The thank-you line takes the box's place, in the italic of the headline.
   The error line is small and in the accent red — the only time the site uses
   red to say something rather than to decorate.
   -------------------------------------------------------------------------- */
.subscribe-thanks {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 300;
  color: var(--warm-cream);
  font-size: clamp(1.125rem, 2vw, 1.375rem);
  margin-top: var(--space-3);
}
.subscribe-error {
  font-size: 0.85rem;
  color: var(--ember-lit);
  margin-top: var(--space-2);
}
.subscribe-form__send:disabled { opacity: 0.4; cursor: default; }


/* --------------------------------------------------------------------------
   TEXT PAGES WITHOUT A PHOTOGRAPH (Privacy).
   The menu floats at the top of every page, so a page with no picture behind
   it needs room made for the menu — the same as the 404 page.
   -------------------------------------------------------------------------- */
.page--text { padding-top: var(--space-20); }
.privacy h2 {
  font-size: clamp(1.25rem, 2.2vw, 1.5rem);
  margin-top: var(--space-6);
  margin-bottom: var(--space-2);
}
.privacy + .fine-print { margin-top: var(--space-8); }


/* --------------------------------------------------------------------------
   TWO FIXES FOR THE SUBSCRIBE BOX (28 Sep 2026, found on his phone).

   1. "Hidden" must always mean hidden. The box has its own display rule
      (display: flex), and a display rule quietly beats the browser's
      built-in meaning of "hidden" — so after signing up the box never went
      away; "You're on the list." just appeared underneath it. This one line
      makes anything marked hidden disappear, everywhere on the site.

   2. Phones and browsers paint an AUTOFILLED box (when you tap your saved
      email above the keyboard) with their own pale background — the "white
      box". These rules keep it in the site's colours instead.
   -------------------------------------------------------------------------- */
[hidden] { display: none !important; }

.subscribe-form__input {
  -webkit-appearance: none;
          appearance: none;
  border-radius: 0;
}
.subscribe-form__input:-webkit-autofill,
.subscribe-form__input:-webkit-autofill:hover,
.subscribe-form__input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--warm-cream);
  caret-color: var(--warm-cream);
  -webkit-box-shadow: 0 0 0 1000px var(--near-black) inset;
          box-shadow: 0 0 0 1000px var(--near-black) inset;
  transition: background-color 600000s 0s;   /* stops the pale fill ever fading in */
}
.subscribe-form__input:autofill {
  -webkit-text-fill-color: var(--warm-cream);
  box-shadow: 0 0 0 1000px var(--near-black) inset;
}
