/*
 * Masthead template styles. Not in app/globals.css: this file is
 * linked by components/templates/masthead/ShopTemplate.tsx through <TemplateStylesheet>, so only pages using the
 * template download it. Moved out of globals.css with its rules in their
 * original order.
 */

/* ==========================================================================
   Masthead template
   Ported from loop-agency.framer.website — see docs/loop-agency-brief.md.
   The section names, set huge, are the navigation, and the section's image
   sits on top of them. Everything else is mono labels, whitespace, and images
   at their own proportions.

   No cards anywhere. No panel behind an image, no padding, no radius, no fixed
   aspect ratio. That absence is the layout — it is why the artwork is the only
   thing on the page with any weight.

   The reference is pure black and white. Hardcoding that would override each
   artist's colorway, so the palette below derives from --foreground and
   --background instead: identical composition, the artist's own colours.
   ========================================================================== */
.masthead-root {
  font-family: var(--font-geist-mono), ui-monospace, SFMono-Regular, monospace;
  font-size: 14px;
  letter-spacing: -0.03em;
  line-height: 1.6;

  /* The idle state of the big lettering. Mixed out of --muted rather than
     --foreground: an artist who sets a sub text colour gets a pale version of
     *that* for the names they are not on, instead of the grey a 12% mix of
     black and white lands on whatever colour they picked. */
  --lettering-idle: color-mix(in srgb, var(--muted) 35%, var(--background));
  --rule: color-mix(in srgb, var(--foreground) 20%, var(--background));

  /* The reference's measures: a 580px column with body text set narrower
     inside it, and a 270px item in the two-column lists. */
  --column: 580px;
  --measure: 373px;
  --item: 270px;
  /* The flash shop only: three columns of artwork plus their gutters. */
  --wide: 1160px;
}

/* --- Letter-stack roll ---------------------------------------------------
   Two copies of every character, the second parked one line down; hover slides
   both up by exactly one line. `clip-path: inset(0 -8px)` rather than
   `overflow: hidden` so the clip is vertical only and tight tracking doesn't
   shave the sidebearings off wide glyphs. */
.masthead-root .roll {
  display: inline-block;
}

.masthead-root .roll-track {
  display: inline-flex;
}

.masthead-root .roll-char {
  position: relative;
  display: inline-block;
  clip-path: inset(0 -8px);
  /* The clip-path above is what the duplicate *looks* clipped by, but a
     clip-path is paint only: the copy parked at `top: 100%` still counts as
     scrollable overflow, and that overflow propagates up to the nearest
     scroller. Every rolled label was therefore adding a line of phantom scroll
     height to whatever contained it — enough to make the flash filter rail a
     scroll container it had no visible reason to be, and to trap the wheel
     there. `clip` rather than `hidden` because clip does not make a scroll
     container of its own, and on the y axis only so the 8px of horizontal
     bleed the tracking needs is still allowed through. */
  overflow-y: clip;
  overflow-x: visible;
}

.masthead-root .roll-a,
.masthead-root .roll-b {
  display: inline-block;
  transition: transform 380ms var(--ease-out);
  /* The stagger walks left to right, which is what makes it read as a roll
     rather than every letter swapping at once. */
  transition-delay: calc(var(--i, 0) * var(--stagger, 0.018s));
}

.masthead-root .roll-b {
  position: absolute;
  top: 100%;
  left: 0;
}

.masthead-root a:hover .roll-a,
.masthead-root a:hover .roll-b,
.masthead-root button:hover .roll-a,
.masthead-root button:hover .roll-b,
.masthead-root a:focus-visible .roll-a,
.masthead-root a:focus-visible .roll-b,
.masthead-root summary:hover .roll-a,
.masthead-root summary:hover .roll-b {
  transform: translateY(-100%);
}

/* --- Shared type ---------------------------------------------------------
   Three faces, one job each: Anton for anything oversized, Bebas one step down
   for titles, mono for everything that is a label rather than a name. */
.masthead-root .masthead-eyebrow {
  font-size: 14px;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  color: var(--muted);
}

.masthead-empty {
  padding: 5rem 0;
  text-align: center;
  color: var(--muted);
}

/* --- Nav ----------------------------------------------------------------- */
.masthead-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.5rem 1.25rem;
  text-transform: uppercase;

  /* Opaque rather than blended. The bar used to be `mix-blend-mode: difference`
     over white lettering, which reads beautifully against the landing but turns
     to mush over the flash grid and the portrait crops, where the wordmark sits
     on whatever colour a photograph happens to put under it. No rule under it:
     the ground alone is enough separation, and a line there would read as a
     second edge above the ruled columns the page is already full of. */
  background: var(--background);
  color: var(--foreground);
}

@media (min-width: 640px) {
  .masthead-nav {
    padding: 1.75rem 2rem;
  }
}

.masthead-wordmark {
  font-weight: 700;
}

.masthead-menu-button {
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}

.masthead-overlay {
  position: fixed;
  inset: 0;
  z-index: 35;
  display: grid;
  place-items: center;
  background: var(--background);
  opacity: 0;
  visibility: hidden;
  transition:
    opacity 300ms var(--ease-out),
    visibility 0s linear 300ms;
}

.masthead-overlay[data-open="true"] {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

.masthead-overlay-list {
  display: grid;
  gap: 0.25rem;
  text-align: center;
}

.masthead-overlay-link {
  font-family: var(--font-anton), Impact, sans-serif;
  font-size: clamp(2.5rem, 9vw, 5.5rem);
  line-height: 0.95;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

/* The overlay centres a single grid item, so the login sits in that flow
   rather than pinned to the foot — pinning it would put it under the phone
   browser's own chrome. */
.masthead-overlay-login {
  margin-top: 2.5rem;
  display: block;
  text-align: center;
  font-size: 14px;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  color: var(--muted);
}

.masthead-overlay-login:hover {
  color: var(--foreground);
}

/* --- The index -----------------------------------------------------------
   The names hold still and the page scrolls past them. A zero-height sticky
   layer paints the whole screen — lettering left, picture right — and a track
   of empty slots behind it supplies the scroll length, one slot per section.
   Whichever slot is crossing the viewport's midline is the active name. */
.masthead-index {
  position: relative;
  /* One slot of scroll per name, plus the screen the lettering itself occupies.
     That trailing screen is what lets the pin release: the frame holds until
     the last name has been read, and then the whole section scrolls up and off
     like any other block. */
  height: calc(var(--slots, 4) * 70svh + 100svh);
}

.masthead-index-sticky {
  position: sticky;
  top: 0;
  height: 100svh;
  z-index: 1;
}

.masthead-index-frame {
  height: 100%;
  display: grid;
  align-items: center;
  gap: 2rem;
  padding: 7rem 1.25rem 5rem;
}

@media (min-width: 900px) {
  .masthead-index-frame {
    /* Lettering takes the room it needs; the picture takes the right-hand
       column and hangs from one axis whatever its width. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 250px);
    gap: 3rem;
    padding-inline: 2.5rem;
  }
}

.masthead-index-list {
  display: grid;
  /* The names are apart, not stacked: at this size a tight leading reads as
     one block of texture rather than as five separate destinations. */
  gap: clamp(1rem, 4vh, 2.75rem);
  width: 100%;
  text-align: center;
}

@media (min-width: 900px) {
  .masthead-index-list {
    text-align: left;
  }
}

.masthead-word {
  display: block;
  font-family: var(--font-anton), Impact, sans-serif;
  /* Two caps, and the smaller wins. The first is the type size the composition
     wants; the second is what a stack of `--words` names can actually be
     without running off the bottom of a short window, which the first has no
     way to know. */
  font-size: min(
    clamp(2.75rem, 10vw, 8rem),
    calc((100svh - 13rem) / var(--words, 4) - 2.25rem)
  );
  line-height: 1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--lettering-idle);
  transition:
    color 260ms var(--ease-out),
    opacity 260ms var(--ease-out);
}

/* Scroll and hover set the same state, so the name the page is on reads
   exactly like the name under the pointer. */
.masthead-word[data-active="true"],
.masthead-word:hover,
.masthead-word:focus-visible {
  color: var(--foreground);
}

/* The names not being read recede, so the live one and its image read as one
   object. */
.masthead-word[data-dimmed="true"] {
  opacity: 0.55;
}

.masthead-index-stage {
  display: grid;
  place-items: center;
  pointer-events: none;
}

@media (min-width: 900px) {
  .masthead-index-stage {
    justify-items: end;
  }
}

.masthead-index-img {
  /* Every image occupies the same cell, so they hang from one axis and
     swapping between them never moves the picture. */
  grid-area: 1 / 1;
  height: auto;
  /* The 220–250 band. The width attribute varies inside it, so the sections
     differ in proportion without any of them growing past 250.

     Deliberately no `width: auto`: that would drop back to the intrinsic size,
     which is zero for an image that hasn't decoded yet, and each one would
     collapse to a point in the corner. The width attribute is the design. */
  max-width: min(250px, 100%);
  object-fit: cover;
  opacity: 0;
  /* Closed to a point at the centre; the active one opens from there. Never a
     pixelation or dither — the artwork is fully painted the whole time and only
     the window onto it grows. */
  clip-path: inset(50% 50% 50% 50%);
  transition:
    opacity 420ms var(--ease-out),
    clip-path 620ms var(--ease-out);
}

.masthead-index-img[data-active="true"] {
  opacity: 1;
  clip-path: inset(0% 0% 0% 0%);
}

/* REQUEST's slot holds a shrunk copy of the request page rather than a
   photograph. It sizes itself like the images beside it — the width the
   composition gave this section, at the 4:5 they are drawn to. */
.masthead-index-peek {
  width: var(--peek-width, 235px);
  aspect-ratio: 4 / 5;
  max-width: min(250px, 100%);
}

/* The scrubber. Nothing is drawn here; it exists to be scrolled through. It
   stops one screen short of the section's end, so the last name is reached
   while the frame is still pinned rather than as it is leaving. */
.masthead-index-track {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: calc(100% - 100svh);
}

.masthead-index-slot {
  height: calc(100% / var(--slots, 4));
}

/* --- Column layouts ------------------------------------------------------
   The reference centres a 580px column and lets the side margins stay empty.
   The flash shop is the exception: three columns of artwork need the width. */

.masthead-wide {
  max-width: var(--wide);
  margin-inline: auto;
  padding: 0 1.25rem 6rem;
}

.masthead-tab-head {
  padding: 8rem 1.25rem 3rem;
  max-width: var(--column);
  margin-inline: auto;
}

.masthead-tab-head[data-wide="true"] {
  max-width: var(--wide);
}

.masthead-tab-title {
  font-family: var(--font-anton), Impact, sans-serif;
  font-size: clamp(2.5rem, 8vw, 6rem);
  line-height: 0.95;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

/* --- Filters ------------------------------------------------------------
   The catalog template's layout: rail and designs are one grid, so the rail
   holds its own track and no artwork is ever underneath it. It sticks while
   the designs scroll past, and collapsing it hands the track back.

   On a phone there is no track to hold, so it becomes a button at the bottom
   of the screen — appearing only once the page has been scrolled, so it never
   covers the designs before anyone is browsing — opening the list as a flat
   sheet. Flat: this template has no cards, so it gets a hairline and an opaque
   ground rather than a radius and a shadow. */
.masthead-flash {
  display: grid;
  gap: 2rem 2.5rem;
}

@media (min-width: 900px) {
  .masthead-flash {
    grid-template-columns: minmax(12rem, 15rem) 1fr;
  }

  .masthead-flash[data-rail="hidden"] {
    grid-template-columns: auto 1fr;
  }

  .masthead-rail-col {
    /* Sticky inside a grid needs the item to stop stretching, or there is no
       spare track for it to move within. */
    position: sticky;
    top: 7rem;
    align-self: start;
    max-height: calc(100svh - 9rem);
    overflow-y: auto;
    /* No `overscroll-behavior: contain` here. This is a column in the page, not
       a sheet over it: when a long gallery list reaches its end the wheel
       should carry on down the page, the way it does over every other part of
       it. Containing it meant a trackpad stopped dead over the rail while the
       scrollbar still worked. The mobile rail below is a real overlay and does
       still contain its scroll. */
  }
}

.masthead-rail-toggle {
  display: none;
}

@media (min-width: 900px) {
  .masthead-rail-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
    cursor: pointer;
    color: var(--muted);
    text-transform: uppercase;
    transition: color 200ms var(--ease-out);
  }

  .masthead-rail-toggle:hover {
    color: var(--foreground);
  }

  .masthead-rail-toggle span[data-flipped="true"] {
    display: inline-block;
    transform: rotate(180deg);
  }
}

.masthead-rail-list {
  display: grid;
  gap: 0.25rem;
}

.masthead-filter {
  display: flex;
  width: 100%;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  cursor: pointer;
  color: var(--muted);
  text-align: left;
  text-transform: uppercase;
  transition: color 200ms var(--ease-out);
}

.masthead-filter[aria-current="true"],
.masthead-filter:hover {
  color: var(--foreground);
}

.masthead-filter-count {
  flex: none;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}

/* --- Filter, narrow screens --------------------------------------------- */
@media (max-width: 899px) {
  /* Laid out at all times and gated with `visibility` rather than toggled with
     `display`, which cannot be transitioned. `visibility: hidden` still takes
     it out of the tab order and the accessibility tree while shut. */
  .masthead-rail {
    position: fixed;
    inset: auto 1rem 5rem 1rem;
    z-index: 40;
    max-height: 60svh;
    overflow-y: auto;
    overscroll-behavior: contain;
    background: var(--background);
    border: 1px solid var(--rule);
    padding: 1.25rem;
    opacity: 0;
    visibility: hidden;
    /* Rises from the direction of the button that opened it. */
    transform: translate3d(0, 0.5rem, 0);
    transition:
      opacity 260ms var(--ease-out),
      transform 260ms var(--ease-out),
      visibility 0s linear 260ms;
  }

  .masthead-rail[data-open="true"] {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s;
  }
}

.masthead-filter-fab {
  position: fixed;
  right: 1rem;
  bottom: 1.25rem;
  z-index: 41;
  padding: 0.75rem 1.25rem;
  cursor: pointer;
  background: var(--foreground);
  color: var(--background);
  text-transform: uppercase;
  opacity: 0;
  visibility: hidden;
  transform: translate3d(0, 0.5rem, 0);
  transition:
    opacity 260ms var(--ease-out),
    transform 260ms var(--ease-out),
    visibility 0s linear 260ms;
}

.masthead-filter-fab[data-visible="true"] {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition-delay: 0s;
}

/* Phone affordance only — the rail is already on screen above this width.
   Declared after the base rule so it wins on equal specificity. */
@media (min-width: 900px) {
  .masthead-filter-fab {
    display: none;
  }
}

/* --- Entries (flash shop) ------------------------------------------------ */
.masthead-entries {
  /* Columns rather than a grid: nothing here needs to line up row by row, and
     letting the images keep their own heights is what staggers the columns. */
  columns: 3;
  column-gap: 32px;
}

/* Below this the rail has taken a track out of the row, so three columns of
   artwork no longer have the width to be worth looking at. */
@media (max-width: 1200px) {
  .masthead-entries {
    columns: 2;
  }
}

/* Two columns on a phone, not one. One column turned an 87-design shop into a
   54,000px page — around sixty screens, where every flick mounted twelve more
   designs and the end never arrived. Halving that is worth more here than the
   extra width each design gets, because the visitor is scanning for something
   to book rather than studying one sheet: the detail view is where a design is
   looked at properly. The type that rides with the narrower column is set
   below, after the rules it has to override. */
@media (max-width: 700px) {
  .masthead-entries {
    columns: 2;
    column-gap: 16px;
  }

  .masthead-entry {
    margin-bottom: 2.25rem;
  }
}

.masthead-entry {
  break-inside: avoid;
  margin-bottom: 3.5rem;
  display: grid;
  gap: 0.25rem;
}

.masthead-entry-media {
  position: relative;
  margin-bottom: 0.75rem;
}

.masthead-entry-hit {
  display: block;
  width: 100%;
  cursor: pointer;
}

/* No panel, no padding, no radius, no fixed ratio — the image is the object. */
.masthead-entry-img {
  display: block;
  width: 100%;
  height: auto;
}

/* --- Image reveal --------------------------------------------------------
   The roll, applied to a picture: the artwork is fully painted the whole time
   and the clip opens off its bottom edge while the image lifts the last few
   pixels into place. Never a pixelation or a dither. */
/* 760ms with a 70ms-per-column delay meant the third column of every row took
   the best part of a second to arrive, and a visitor scrolling a long flash
   list spends that second looking at empty space. The opening is the same
   shape, taken at a pace that keeps up with the scroll. */
.masthead-reveal {
  transition:
    clip-path 480ms var(--ease-out),
    transform 480ms var(--ease-out);
  /* The same left-to-right walk the letter roll uses, across the columns. */
  transition-delay: calc(var(--i, 0) * 40ms);
}

/* Only an armed wrapper is hidden, and only script arms one — so a picture can
   never be left invisible by an observer that didn't fire, a script that
   didn't run, or a tab that was in the background. */
.masthead-reveal[data-armed="true"] {
  clip-path: inset(100% 0 0 0);
  transform: translate3d(0, 1.25rem, 0);
}

.masthead-reveal[data-armed="true"][data-shown="true"] {
  clip-path: inset(0 0 0 0);
  transform: none;
}

.masthead-entry-save {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 1;
}

.masthead-entry-meta {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  text-transform: uppercase;
  color: var(--muted);
}

/* Name left, the booking action hard right on the same line. */
.masthead-entry-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.masthead-entry-title {
  font-family: var(--font-bebas-neue), Impact, sans-serif;
  font-size: 32px;
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.masthead-entry-blurb {
  text-transform: uppercase;
  color: var(--muted);
}

/* The one filled element in the template, because it is the one thing on the
   page that is a transaction. Flat: solid fill, square corners, no shadow. */
.masthead-book {
  flex: none;
  cursor: pointer;
  background: var(--foreground);
  color: var(--background);
  padding: 0.5rem 1rem;
  text-transform: uppercase;
  transition: opacity 200ms var(--ease-out);
}

.masthead-book:hover,
.masthead-book:focus-visible {
  opacity: 0.75;
}


/* Phone type for the two-column grid above. It lives here, below the rules it
   overrides, because these selectors are the same specificity: a media query
   adds none, so declared order is the only thing deciding which one lands. */
@media (max-width: 700px) {
  .masthead-entry-meta {
    gap: 0.5rem;
  }

  .masthead-entry-title {
    font-size: 22px;
  }

  .masthead-entry-foot {
    gap: 0.5rem;
  }

  .masthead-book {
    padding: 0.375rem 0.625rem;
  }
}

.masthead-more {
  display: flex;
  justify-content: center;
  padding-top: 1rem;
}

/* --- Masonry (tattoos) --------------------------------------------------- */
.masthead-masonry {
  /* Three, and two on a phone. Same reasoning as the flash shop above: a
     gallery of healed work is scanned, not studied, and one column made a
     phone scroll through it forever.

     No step down at 1200px, unlike .masthead-entries. That step is there
     because the flash shop's filter rail takes a track out of the row at that
     width; this grid has no rail, so three columns keep their width all the
     way to the phone breakpoint. */
  columns: 3;
  column-gap: 32px;
}

@media (max-width: 700px) {
  .masthead-masonry {
    columns: 2;
    column-gap: 16px;
  }

  .masthead-masonry-img {
    margin-bottom: 16px;
  }
}

.masthead-masonry-img {
  display: block;
  width: 100%;
  height: auto;
  /* This grid holds the artist's own uploads as well as their Instagram, and
     an upload can be any shape at all — one tall enough is most of a column on
     its own. Capped and contained rather than cropped, which is the same
     treatment catalog and editorial give these. */
  max-height: 34rem;
  object-fit: contain;
  break-inside: avoid;
  margin-bottom: 40px;
}

/* --- Article (info) ------------------------------------------------------
   The reference's two-rail read: labels and the standfirst out in the left
   margin, the article itself in the centre column with a narrower measure. */
.masthead-article {
  display: grid;
  gap: 2rem;
  padding: 8rem 1.25rem 6rem;
}

@media (min-width: 1000px) {
  .masthead-article {
    grid-template-columns: var(--item) var(--column);
    justify-content: center;
    gap: 40px;
  }
}

.masthead-article-rail {
  align-self: start;
}

@media (min-width: 1000px) {
  .masthead-article-rail {
    position: sticky;
    top: 8rem;
    align-self: start;
    display: grid;
    gap: 1.5rem;
    height: max-content;
  }
}

/* One label the whole way down, swapping as each section is reached. It is set
   in the lettering rather than in the label mono, so the margin carries the
   page's voice instead of a caption. */
.masthead-rail-sticky {
  display: none;
}

@media (min-width: 1000px) {
  .masthead-rail-sticky {
    display: block;
    overflow: hidden;
  }
}

.masthead-rail-current {
  font-family: var(--font-anton), Impact, sans-serif;
  font-size: clamp(1.75rem, 3vw, 2.75rem);
  line-height: 1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  /* Arrives from below as the outgoing one is replaced — the roll's direction,
     applied to a whole word. */
  animation: masthead-rail-in 460ms var(--ease-out) both;
}

@keyframes masthead-rail-in {
  from {
    opacity: 0;
    transform: translate3d(0, 100%, 0);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.masthead-standfirst {
  text-transform: uppercase;
  color: var(--muted);
}

.masthead-article-main {
  display: grid;
  gap: 1rem;
  min-width: 0;
}

.masthead-article-title {
  font-family: var(--font-anton), Impact, sans-serif;
  font-size: clamp(3rem, 8vw, 6rem);
  line-height: 0.92;
  letter-spacing: -0.02em;
  text-transform: uppercase;
}

.masthead-article-img {
  display: block;
  width: 100%;
  height: auto;
  margin: 2rem 0;
}

/* Body copy is deliberately narrower than the column it sits in. */
.masthead-measure {
  max-width: var(--measure);
  display: grid;
  gap: 1.25rem;
  text-transform: uppercase;
  color: var(--muted);
}

.masthead-policy {
  display: grid;
  gap: 0.75rem;
  padding-top: 2rem;
}

.masthead-policy-item {
  display: grid;
  gap: 0.5rem;
}

.masthead-policy-title {
  font-family: var(--font-bebas-neue), Impact, sans-serif;
  font-size: 32px;
  line-height: 1.2;
  letter-spacing: -0.02em;
  text-transform: none;
  color: var(--foreground);
}

.masthead-article-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  padding-top: 2rem;
  text-transform: uppercase;
  color: var(--foreground);
}

/* --- Question menu -------------------------------------------------------
   The point of the reference's version is what it leaves out: no borders, no
   dividers, no boxed chevrons. Rows separate on 8px of gap alone. */
.masthead-questions {
  max-width: var(--column);
  margin-inline: auto;
  padding: 3rem 1.25rem 6rem;
  display: grid;
  gap: 1.5rem;
  justify-items: start;
}

.masthead-faq {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}

.masthead-question > summary {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 40px;
  cursor: pointer;
  list-style: none;
}

.masthead-question > summary::-webkit-details-marker {
  display: none;
}

/* Bebas Neue rather than Anton. Both are caps-only faces — Bebas has no
   lowercase at all, so the reference's `text-transform: none` here changes
   nothing visually — but Bebas is much narrower and lighter than Anton, and
   that alone is what stops the questions reading as another slab of the same
   display type. */
.masthead-question-text {
  font-family: var(--font-bebas-neue), Impact, sans-serif;
  font-size: 26px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-transform: none;
}

.masthead-question-mark {
  flex: none;
  font-size: 20px;
  line-height: 1.4;
  transition: transform 300ms var(--ease-out);
}

.masthead-question[open] .masthead-question-mark {
  transform: rotate(45deg);
}

/* Animating `grid-template-rows` from 0fr to 1fr means the panel's height is
   never measured, so the whole section stays a server component and works with
   JS off. The child needs `overflow: hidden` for the collapsed track to clip it.

   Chosen over transitioning `height: auto` on `::details-content`, which is
   tidier markup but needs `interpolate-size: allow-keywords` — Chrome-only for
   now, so Safari and Firefox would snap open with no animation at all. */
.masthead-question-panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 320ms var(--ease-out);
}

.masthead-question[open] .masthead-question-panel {
  grid-template-rows: 1fr;
}

.masthead-question-panel > div {
  overflow: hidden;
}

.masthead-question-panel p {
  padding-top: 0.75rem;
  text-transform: uppercase;
  color: var(--muted);
}

/* --- Footer under the page ----------------------------------------------
   The footer is pinned to the bottom of the viewport the whole time at z-index
   0; the content above it is opaque at z-index 1 and covers it until its last
   pixels scroll past. No measurement, no animation, and it degrades to an
   ordinary footer anywhere `sticky` doesn't apply.

   The reference does this by scrolling an inner container over a fixed footer.
   We can't — Lenis and ScrollTrigger both drive window scroll, and moving the
   page into an `overflow-y: auto` box would leave every trigger measuring
   against the wrong scroller. */
.masthead-shell {
  position: relative;
  z-index: 1;
  background: var(--background);
}

.masthead-footer {
  z-index: 0;
  background: var(--background);
  padding: 0 1.25rem 2rem;
}

/* The reveal only ever shows the bottom screenful of the footer, so it is
   applied only once FooterFit has measured that the whole footer fits in one.
   Otherwise this stays an ordinary footer at the end of the page — which
   scrolls to in full, which is the point. */
.masthead-footer[data-fits="true"] {
  position: sticky;
  bottom: 0;
}

@media (min-width: 640px) {
  .masthead-footer {
    padding-inline: 2rem;
  }
}

.masthead-footer-inner {
  display: grid;
  gap: 1.5rem;
}

/* The wordmark is shown whole, set to the width of its row.
   The row used to be a fixed-height crop with the type size chosen by a clamp,
   and at laptop widths the clamp resolved much larger than the crop — so the
   artist's name lost its cap tops to one edge and its baseline to the other.

   Neither number can be right on its own, because the width the name wants
   depends on how many letters are in it. So the size is measured instead: see
   FooterFit, which fits the word to `clientWidth` and caps the result at
   `--mark-max-height`. The declarations here are what shows before that
   measurement lands, and the ceiling it reads. */
.masthead-footer-mark {
  /* The ceiling on the row, and the reason a short name isn't set as tall as
     the screen. Written once as a custom property, because both the pre-measure
     `font-size` below and this `max-height` need it — and mirrored onto a real
     property because that is the form FooterFit can read back. Asking
     `getComputedStyle` for the custom property returns the literal `clamp(...)`
     source text, which is not a number; asking it for `max-height` returns
     pixels. The `max-height` is also a genuine guard in its own right. */
  --mark-max-height: clamp(4rem, 34svh, 15rem);
  max-height: var(--mark-max-height);
  /* A last-resort guard only: at the measured size nothing reaches this. */
  overflow: hidden;
}

.masthead-footer-mark span {
  display: block;
  /* Shrink to the width of the word. A full-width block would report its own
     row back as `scrollWidth`, and the fit would measure the word against
     itself and never grow. */
  width: max-content;
  font-family: var(--font-anton), Impact, sans-serif;
  /* Overwritten by FooterFit. Sized off the same two limits so the pre-measure
     paint is close to the final one and the mark doesn't visibly resize. */
  font-size: min(clamp(3rem, 18vw, 14rem), var(--mark-max-height));
  /* Must never wrap: the mark is one line, and a second line would push the
     rule and the columns below it off the screen the footer has to fit in. */
  white-space: nowrap;
  /* Anton's caps occupy 0.006em–0.88em of a 0.9 line box, so this shows the
     whole glyph with almost no slack above or below. FooterFit divides by the
     same number to turn `--mark-max-height` into a type size — change one and
     change the other. */
  line-height: 0.9;
  letter-spacing: -0.03em;
  text-transform: uppercase;
}

.masthead-rule {
  border: 0;
  border-top: 1px solid var(--rule);
}

.masthead-footer-cols {
  display: grid;
  gap: 1.5rem;
  text-transform: uppercase;
}

@media (min-width: 768px) {
  .masthead-footer-cols {
    grid-template-columns: 1.4fr 1fr 1fr;
  }
}

.masthead-footer-list {
  display: grid;
  gap: 0.25rem;
}

.masthead-footer-legal {
  padding-top: 1rem;
  color: var(--muted);
}

/* --- Reduced motion ------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .masthead-root .roll-a,
  .masthead-root .roll-b,
  .masthead-root .masthead-word,
  .masthead-index-img,
  .masthead-reveal,
  .masthead-rail,
  .masthead-filter-fab,
  .masthead-question-mark,
  .masthead-question-panel,
  .masthead-overlay {
    transition: none;
  }

  /* The picture is simply there, at full size, un-clipped. */
  .masthead-reveal {
    clip-path: none;
    transform: none;
  }

  .masthead-rail-current {
    animation: none;
  }

  /* Without the wipe the image simply appears, still on the same centre. */
  .masthead-index-img[data-active="true"] {
    clip-path: none;
  }

  .masthead-root a:hover .roll-a,
  .masthead-root a:hover .roll-b,
  .masthead-root button:hover .roll-a,
  .masthead-root button:hover .roll-b,
  .masthead-root summary:hover .roll-a,
  .masthead-root summary:hover .roll-b {
    transform: none;
  }

  .masthead-root a:hover .roll,
  .masthead-root button:hover .roll,
  .masthead-root summary:hover .roll {
    text-decoration: underline;
  }
}
