/* ============================================================
   THE BONES FUND
   ============================================================ */

:root{
  --cream:      #F3F0E9;
  --cream-2:    #EAE5DA;
  --ink:        #0E0E0E;
  --ink-2:      #171717;
  --muted:      #6E6B64;
  --muted-dark: #8A867E;
  --red:        #B5352A;
  /* Trust green. Already existed as the success-status colour (#2E5B3B on a
     rgba(74,138,90,.12) wash); promoted to a token so the donate box can use
     the same green rather than inventing a second one. */
  --green:      #2E7A4B;
  --spotify:    #1DB954;
  --line:       rgba(14,14,14,.16);
  --line-light: rgba(243,240,233,.16);

  /* Helvetica FIRST, because that is what the merch is set in - the
     wordmark, magnets, mugs and totes are all macOS Helvetica Bold (see
     gen_merch.py). The site previously led with Helvetica Neue, a different
     typeface, so print and web did not match even on a Mac.

     Arial next: metrically identical to Helvetica, so Windows gets the same
     widths and line breaks. Liberation Sans is the same clone on Linux.
     Helvetica Neue is kept only as a late fallback. */
  --sans: Helvetica, Arial, "Liberation Sans", "Helvetica Neue", sans-serif;
  --mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, "Roboto Mono", monospace;

  --pad: clamp(20px, 5vw, 72px);
  /* max width of the content column for every section EXCEPT the hero;
     on wide screens the section gutters grow symmetrically so the page
     reads as a centred column rather than leaving dead space. Tune this
     one number to move everything in/out. */
  --content-max: 1440px;
  --ease: cubic-bezier(.16,.84,.44,1);
}

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

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

body{
  margin:0;
  background:var(--cream);
  color:var(--ink);
  font-family:var(--sans);
  font-size:16px;
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

img{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
h1,h2,h3,p,ol,figure{ margin:0; }
ol{ padding:0; list-style:none; }

::selection{ background:var(--red); color:var(--cream); }

/* film grain, echoing the artwork ------------------------------------ */
.grain{
  position:fixed; inset:-50%;
  z-index:9999; pointer-events:none; opacity:.045;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* shared bits --------------------------------------------------------- */
.kicker{
  font-family:var(--mono);
  font-size:13px; letter-spacing:.2em; text-transform:uppercase;
  color:var(--red); margin:0 0 22px;
}
.kicker--light{ color:var(--red); }

.mono-dim{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--muted);
}

.u{ border-bottom:1px solid var(--red); padding-bottom:1px; }

/* buttons ------------------------------------------------------------- */
.btn{
  display:inline-flex; align-items:center; gap:9px;
  font-family:var(--mono); font-size:11px; letter-spacing:.16em; text-transform:uppercase;
  padding:15px 26px; border-radius:100px;
  border:1px solid var(--ink); color:var(--ink);
  transition:background .35s var(--ease), color .35s var(--ease),
             border-color .35s var(--ease), transform .35s var(--ease);
  white-space:nowrap;
}
.btn:hover{ transform:translateY(-2px); }
.btn--sm{ padding:10px 20px; font-size:10px; }
.btn--sm:hover{ background:var(--ink); color:var(--cream); }
.btn--solid{ background:var(--red); border-color:var(--red); color:var(--cream); }
.btn--solid:hover{ background:var(--ink); border-color:var(--ink); }
.btn--ghost{ background:transparent; }
.btn--ghost:hover{ background:var(--ink); color:var(--cream); }
.btn--light{ background:var(--cream); border-color:var(--cream); color:var(--ink); }
.btn--light:hover{ background:var(--red); border-color:var(--red); color:var(--cream); }
.btn--outline-light{ border-color:var(--line-light); color:var(--cream); }
.btn--outline-light:hover{ background:var(--cream); color:var(--ink); border-color:var(--cream); }

.btn__play{
  width:11px; height:11px; flex:none;
  fill:var(--spotify); transition:transform .35s var(--ease);
}
.btn:hover .btn__play{ transform:scale(1.25); }

/* reveal -------------------------------------------------------------- */
.reveal{ opacity:0; transform:translateY(22px); }
.reveal.in{
  opacity:1; transform:none;
  transition:opacity .9s var(--ease), transform .9s var(--ease);
}
@media (prefers-reduced-motion:reduce){
  .reveal{ opacity:1; transform:none; }
  html{ scroll-behavior:auto; }
}

/* ============================ NAV ============================ */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:100;
  display:flex; align-items:center; justify-content:space-between;
  padding:20px var(--pad);
  /* Solid cream at rest, not transparent. Visually identical - the nav sits
     over the cream hero - but Safari tints its toolbar by sampling the fixed
     element at the top of the page, and a transparent one gave it nothing to
     sample: the toolbar sat white and switched to cream seconds later once
     Safari caught up. A definite colour here means it samples cream at first
     paint, like every other site. (Safari 26 ignores theme-color.) */
  background:var(--cream);
  mix-blend-mode:normal;
  transition:background .4s var(--ease), padding .4s var(--ease),
             border-color .4s var(--ease), color .4s var(--ease);
  border-bottom:1px solid transparent;
}
.nav.is-stuck{
  background:rgba(243,240,233,.82);
  backdrop-filter:blur(14px) saturate(140%);
  -webkit-backdrop-filter:blur(14px) saturate(140%);
  border-bottom-color:var(--line);
  padding-top:14px; padding-bottom:14px;
}
/* nav turns light while over the dark sections */
.nav.is-dark{ color:var(--cream); }
/* With the menu open the nav goes dark and sits ABOVE the black menu, so it
   must be see-through there or a cream bar would cross the top of the menu.
   Scrolled over a dark section it is also stuck, and the rule below wins. */
.nav.is-dark{ background:transparent; }
.nav.is-dark.is-stuck{
  background:rgba(14,14,14,.72); border-bottom-color:var(--line-light);
}
.nav.is-dark .btn{ border-color:var(--line-light); color:var(--cream); }
.nav.is-dark .btn--sm:hover{ background:var(--cream); color:var(--ink); border-color:var(--cream); }
.nav.is-dark .nav__burger span{ background:var(--cream); }

/* left group: hamburger + cycling stat */
.nav__left{ display:flex; align-items:center; gap:clamp(14px,1.6vw,24px); }
.nav__stat{
  font-family:var(--mono); font-size:11px; letter-spacing:.14em;
  line-height:1; white-space:nowrap;
  transition:opacity .24s var(--ease), color .24s var(--ease);
}
.nav__stat.is-donated{ color:var(--red); }      /* donations - warm */
.nav__stat.is-streams{ color:var(--spotify); }  /* streams - green */

.nav__mark{ display:flex; align-items:center; gap:9px; }
.nav__mark-play{
  width:11px; height:11px; flex:none;
  fill:var(--red); transition:transform .35s var(--ease);
}
.nav__mark:hover .nav__mark-play{ transform:scale(1.25); }
.nav__mark-word{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.2em;
  line-height:1; opacity:.85;
}

.nav__right{ display:flex; align-items:center; gap:14px; }

.nav__burger{
  display:flex;
  width:34px; height:34px; padding:0;
  background:none; border:0; cursor:pointer;
  flex-direction:column; justify-content:center; align-items:flex-start; gap:5px;
}
.nav__burger span{
  display:block; height:1.5px; width:22px; background:var(--ink);
  transition:transform .4s var(--ease), opacity .3s var(--ease);
}
/* the three lines collapse into an X */
.nav__burger[aria-expanded="true"] span:first-child{ transform:translateY(6.5px) rotate(45deg); }
.nav__burger[aria-expanded="true"] span:nth-child(2){ opacity:0; transform:scaleX(.4); }
.nav__burger[aria-expanded="true"] span:last-child{ transform:translateY(-6.5px) rotate(-45deg); }

/* menu overlay */
.menu{
  position:fixed; inset:0; z-index:99;
  background:var(--ink); color:var(--cream);
  display:flex; flex-direction:column; justify-content:space-between;
  padding:calc(86px + var(--hero-gap, 40px)) var(--pad) clamp(28px,4vh,52px);
  animation:menuIn .5s var(--ease);
}
.menu[hidden]{ display:none; }
@keyframes menuIn{ from{opacity:0; transform:translateY(-12px)} to{opacity:1; transform:none} }
.menu__links{ display:flex; flex-direction:column; gap:6px; }
.menu__links a{
  display:flex; align-items:baseline; gap:18px;
  font-size:clamp(30px,7vw,58px); font-weight:700; letter-spacing:-.035em;
  padding:clamp(8px,1vw,12px) 0; border-bottom:1px solid var(--line-light);
}
.menu__links a i{
  font-family:var(--mono); font-style:normal; font-size:11px;
  letter-spacing:.16em; color:var(--muted-dark);
}
.menu__donate{ color:var(--red); }
/* big wordmark anchoring the overlay - wraps rather than clipping */
/* real text so it matches the menu links exactly (no stretching). Sized to
   sit on one line at normal widths; the <wbr> after the @ lets it wrap to
   two lines when squeezed rather than shrinking away to nothing. */
.menu__word{
  display:block; text-decoration:none; margin:0;
  font-size:clamp(34px,6.2vw,92px); line-height:.94;
  font-weight:700; letter-spacing:-.035em; color:var(--cream);
  transition:color .4s var(--ease);
}
.menu__word:hover{ color:var(--red); }

/* email + social, grouped so `.menu`'s justify-content:space-between still
   only splits two blocks (links top, this bottom) rather than three */
.menu__foot{ display:flex; flex-direction:column; gap:10px; }
.menu__social{
  display:inline-block; width:fit-content; text-decoration:none;
  font-family:var(--mono); font-size:11px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--muted-dark);
  transition:color .4s var(--ease);
}
.menu__social:hover{ color:var(--red); }
/* no Instagram link yet - reads as real, just doesn't lie about clickable */
.menu__social.is-pending{ opacity:.6; cursor:not-allowed; }
.menu__social.is-pending:hover{ color:var(--muted-dark); }

/* ============================ HERO =========================== */
.hero{
  /* capped: on a tall enough viewport (a big monitor, or just a maximised
     wide+tall window), 100svh alone kept forcing the hero taller than its
     content - title/text/buttons and the phone both have max sizes they
     stop growing past (see their own clamps below), so past that point
     100svh was just opening a dead gap at the bottom to fill nothing. The
     content's natural height even at MAX size (title+text+buttons, or the
     phone, whichever is taller) measures ~1129px - 1150px gives a little
     headroom above that. Below 1150px viewport height this is a no-op
     (100svh is smaller and wins), so nothing changes at normal sizes. */
  min-height:min(100svh, 1150px);
  --hero-gap:clamp(30px,3.6vw,46px);   /* phone → buttons → banner */
  /* just clears the fixed header (~77px) — no more */
  padding:86px var(--pad) var(--hero-gap);
  display:flex; flex-direction:column; justify-content:space-between;
}
/* Desktop: two columns. Left stacks headline / text / CTA row; the
   phone sits in the right column and spans all three rows, so it can
   hang lower than the headline without stretching any single row. */
.hero__inner{
  flex:1;
  display:grid; grid-template-columns:1.42fr .58fr;
  /* the 4th row is a spacer: the phone spans into it, so its extra
     height lands there instead of being shared out between the three
     content rows (which would push headline/text/buttons apart) */
  grid-template-rows:auto auto auto 1fr;
  /* gap == page padding: a phone centred in the right column then gets
     equal space to the rose and to the screen edge */
  column-gap:var(--pad); row-gap:0;
  align-items:start;
}
.hero__head   { grid-column:1; grid-row:1; }
.hero__lede   { grid-column:1; grid-row:2; }
.hero__actions{ grid-column:1; grid-row:3; }
.hero__art    { grid-column:2; grid-row:1 / 5; align-self:start; }

/* headline + rose, matched in height */
.hero__head{
  display:flex; align-items:stretch;
  gap:clamp(14px,2.2vw,40px);
  margin:0 0 clamp(22px,2.6vw,34px);
}
/* the rose sits in a column with no intrinsic height, so the headline
   sets the row and the image is scaled to match it exactly */
.hero__rose{ position:relative; flex:1 1 auto; min-width:0; }
.hero__rose img{
  position:absolute; inset:0;
  width:100%; height:100%;
  object-fit:contain; object-position:center;
}

.hero__title{
  flex:none;
  font-size:clamp(76px, 12.3vw, 204px);
  line-height:.84; font-weight:700; letter-spacing:-.045em;
  margin:0;
}
.hero__title span{ display:block; }
.hero__title-fund{ position:relative; display:flex !important; align-items:flex-end; }

/* ---- red box lockup -------------------------------------------------
   PARKED 2026-08-24 (Ross: "take it back to normal - could be something
   for the future"). The CSS is kept and still works; nothing uses it. To
   bring it back, add class="boxed" to the second line of a head, e.g.
   <h2 ...>THREE WAYS<br /><span class="boxed">TO GIVE</span></h2>, and on
   the hero's .hero__title-fund span.

   The wordmark's second line sits in a red block, cream text on red.

   The box is drawn as a ::before behind the text rather than as a
   background on the span: a background would be clipped to the glyph box
   and, because the display heads run at line-height .84-.86, it would
   collide with the line above. The pseudo-element can be inset from the
   cap height instead, which keeps it clear of the line above while still
   hugging the word. */
.boxed{
  position:relative; display:inline-block;
  color:var(--cream);
  padding:0 .14em 0 .1em;
  isolation:isolate;
}
.boxed::before{
  content:""; position:absolute; z-index:-1;
  left:0; right:0;
  /* Measured against the rendered face rather than eyeballed: at the display
     line-height (.86) the cap tops land ~.076em below the span's top edge and
     the baseline ~.823em, so the block is inset just clear of both. Anything
     larger than ~.08em on top starts cutting the capitals. */
  top:.045em; bottom:.005em;
  background:var(--red);
}
/* On the hero the span is already a flex row, so the box needs to wrap the
   row rather than an inline box. */
.hero__title-fund.boxed{ display:flex !important; }

.hero__lede{
  /* spread the lede wider across the left column (was 62ch, bunched left);
     still stops short of the phone in the right column. The hero is
     deliberately excluded from the site's --content-max cap (full-bleed on
     wide monitors), but this clamp used to top out at 18px right at 1500px
     viewport width - same rate (1.2vw), just raised the ceiling so it keeps
     growing to ~1920px before flattening, instead of freezing early and
     leaving dead space in the column as it keeps widening past that. */
  max-width:80ch; font-size:clamp(15px,1.2vw,23px); line-height:1.6;
  color:#33312D; margin-bottom:0;
}
.hero__lede p{ margin:0 0 14px; }
.hero__lede p:last-child{ margin-bottom:0; }
.hero__lede b{ font-weight:700; color:var(--ink); }

.hero__actions{
  display:flex; flex-wrap:wrap; gap:12px;
  margin-top:var(--hero-gap);
  margin-bottom:0;
}

/* same fix as .hero__lede above - same growth rate (24vw), higher ceiling
   (was 360px, maxing at 1500px viewport width) so the phone keeps scaling
   with the lede text instead of freezing 400+px before it does. Height
   follows automatically via .phone's aspect-ratio, so this also closes the
   empty space that used to open up BENEATH the phone at wide viewports. */
.hero__art{ align-self:start; --phone-w:clamp(230px,24vw,460px); }

.hero__foot{
  display:flex; justify-content:space-between; gap:16px;
  padding-top:18px; border-top:1px solid var(--line);
}

/* ---------- iPhone / Spotify mockup ---------- */
.phone{
  --w: var(--phone-w, clamp(230px,21vw,310px));
  display:block; width:var(--w); margin-inline:auto;
  aspect-ratio:9/19.5; padding:calc(var(--w) * .033);
  border-radius:calc(var(--w) * .155);
  background:linear-gradient(150deg,#2b2b2b,#0b0b0b 42%,#242424);
  box-shadow:
    0 0 0 1px rgba(14,14,14,.5),
    0 40px 70px -26px rgba(14,14,14,.6),
    0 8px 20px -8px rgba(14,14,14,.35);
  position:relative;
  transition:transform .6s var(--ease), box-shadow .6s var(--ease);
}
.phone:hover{ transform:translateY(-6px); }

.phone__island{
  position:absolute; top:calc(var(--w) * .062); left:50%;
  transform:translateX(-50%); z-index:3;
  width:29%; height:calc(var(--w) * .088);
  background:#000; border-radius:100px;
}

.phone__screen{
  display:flex; flex-direction:column;
  width:100%; height:100%; overflow:hidden;
  border-radius:calc(var(--w) * .125);
  background:linear-gradient(#161616 0%, #0d0d0d 46%, #050505 100%);
  color:#fff;
  padding:calc(var(--w) * .045) calc(var(--w) * .058) calc(var(--w) * .026);
  font-size:calc(var(--w) * .042);
}

.phone__status{
  display:flex; justify-content:space-between; align-items:center;
  height:calc(var(--w) * .075); flex:none;
}
.phone__status b{ font-size:calc(var(--w) * .052); font-weight:600; letter-spacing:-.01em; }
.phone__sysicons{ width:calc(var(--w) * .155); fill:#fff; }

.phone__bar{
  display:flex; align-items:center; justify-content:space-between;
  margin-top:calc(var(--w) * .045); flex:none;
}
.phone__bar b{
  font-size:calc(var(--w) * .038); font-weight:700;
  letter-spacing:.06em; text-transform:uppercase;
}
.phone__ico{ width:calc(var(--w) * .058); height:calc(var(--w) * .058); fill:currentColor; flex:none; }
.phone__ico--sm{ width:calc(var(--w) * .05); height:calc(var(--w) * .05); opacity:.75; }

/* cover art: two sleeves on a reel that slides between them */
.phone__art{
  display:block; width:100%; aspect-ratio:1; flex:none;
  margin:calc(var(--w) * .07) 0 auto;
  border-radius:calc(var(--w) * .022);
  overflow:hidden;
  box-shadow:0 calc(var(--w)*.05) calc(var(--w)*.09) rgba(0,0,0,.55);
}
.phone__reel{
  display:flex; width:200%; height:100%;
  transform:translateX(0);
  transition:transform 1.05s cubic-bezier(.62,.02,.2,1);
}
.phone__reel.is-second{ transform:translateX(-50%); }
.phone__slide{
  position:relative; width:50%; height:100%; flex:none;
  display:block; overflow:hidden;
}
.phone__slide img{ width:100%; height:100%; object-fit:cover; }

/* DEAD 2026-08-19: the acoustic sleeve mock, an inverted negative of the
   original cover used as a stand-in before the real acoustic artwork
   existed. Replaced by a plain <img src="assets/bones-acoustic-cover.webp">
   in the hero phone mockup now that Ross has the real cover - kept here in
   case the trick is useful elsewhere, not deleted. */
.sleeve{ position:absolute; inset:0; display:block; overflow:hidden; }
.sleeve__base{
  position:absolute; inset:0;
  width:100% !important; height:100% !important; object-fit:cover;
  /* the inverted rose lands on ~125 luminance — dead on contrast()'s
     mid-grey pivot, so it wouldn't darken. Dim first to push it below
     the pivot, spread the range, then lift the paper back to white. */
  filter:invert(1) brightness(.74) contrast(2.9) brightness(1.08);
}
/* tint the paper down to the exact same concrete used on the page 03
   card (.player), so the two match precisely rather than approximately */
.sleeve::after{
  content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  mix-blend-mode:multiply;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='.16'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E"),
    radial-gradient(120% 90% at 16% 6%, rgba(255,255,255,.18), transparent 56%),
    radial-gradient(95% 75% at 86% 94%, rgba(14,14,14,.14), transparent 62%),
    linear-gradient(160deg,#B6B4AF,#A6A49F 55%,#ADABA6);
}
.sleeve__acoustic{
  z-index:2;
  position:absolute; left:0; right:0; top:88.8%;
  text-align:center; font-weight:400;
  /* same serif as the share cards on thank-you.html, which lead with Times */
  font-family:"Times New Roman", Times, Georgia, serif;
  font-size:calc(var(--w) * .0217);
  letter-spacing:.34em; text-indent:.34em;
  line-height:1; color:#141414;
}

@media (prefers-reduced-motion:reduce){
  .phone__reel{ transition:none; }
}

.phone__meta{
  display:flex; align-items:center; justify-content:space-between;
  gap:calc(var(--w) * .04); flex:none;
  margin-bottom:calc(var(--w) * .052);
}
.phone__meta-txt{ display:block; min-width:0; }
.phone__meta-txt b{
  display:block; font-size:calc(var(--w) * .072); font-weight:700;
  letter-spacing:-.02em; line-height:1.1;
  transition:opacity .26s var(--ease);
}
.phone__meta-txt i{
  display:block; font-style:normal; margin-top:calc(var(--w) * .012);
  font-size:calc(var(--w) * .05); color:#b3b3b3;
}
.phone__ico--add{ opacity:.9; }

.phone__scrub{ display:block; flex:none; }
.phone__scrub-bar{
  display:block; position:relative; height:calc(var(--w) * .0115);
  border-radius:100px; background:rgba(255,255,255,.28);
}
.phone__scrub-bar i{
  position:absolute; left:0; top:50%; width:calc(var(--w) * .026);
  aspect-ratio:1; transform:translate(-10%,-50%);
  border-radius:50%; background:#fff;
}
.phone__scrub-time{
  display:flex; justify-content:space-between;
  margin-top:calc(var(--w) * .028);
}
.phone__scrub-time b{ font-size:calc(var(--w) * .04); font-weight:500; color:#a7a7a7; }

.phone__controls{
  display:flex; align-items:center; justify-content:space-between;
  margin:calc(var(--w) * .055) 0 auto; flex:none;
}
.phone__play{
  display:grid; place-items:center; flex:none;
  width:calc(var(--w) * .175); aspect-ratio:1;
  border-radius:50%; background:#fff; color:#000;
}
.phone__play svg{ width:52%; height:52%; fill:currentColor; margin-left:4%; }

.phone__home{
  display:block; flex:none; width:34%; height:calc(var(--w) * .012);
  margin:calc(var(--w) * .045) auto 0;
  border-radius:100px; background:rgba(255,255,255,.55);
}

/* ---------- running totals, under the phone ---------- */
.tally{
  /* sits beside the buttons now, so it sizes to its own content
     rather than matching the phone above it */
  margin:0; flex:0 1 auto;
  border:1px solid var(--line); border-radius:10px;
  background:rgba(14,14,14,.028);
  padding:clamp(14px,1.6vw,20px) clamp(14px,1.6vw,20px) clamp(11px,1.2vw,14px);
}
.tally__grid{
  display:grid; grid-template-columns:1fr 1fr;
  gap:clamp(10px,1.4vw,18px);
}
.tally__item + .tally__item{
  padding-left:clamp(10px,1.4vw,18px);
  border-left:1px solid var(--line);
}
.tally__num{
  display:block;
  /* capped well below the old 32px max - at that size "£1,302.25" is
     exactly as wide as its column, no spare room at all */
  font-size:clamp(22px,2.3vw,26px); font-weight:700;
  letter-spacing:-.035em; line-height:1;
  font-variant-numeric:tabular-nums;
}
.tally__item:first-child .tally__num{ color:var(--red); }
.tally__item:last-child  .tally__num{ color:var(--spotify); }
.tally__item i{
  display:block; margin-top:7px; font-style:normal;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted);
}
.tally__note{
  margin:clamp(12px,1.4vw,16px) 0 0;
  padding-top:clamp(9px,1vw,12px); border-top:1px solid var(--line);
  font-family:var(--mono); font-size:9.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted);
}

/* ============================ TICKER ========================= */
/* partner logos. Light bar on purpose: most charity logos ship on a
   white background, and mix-blend-mode:multiply makes that white drop
   out against the cream — so transparent PNGs and boxed ones both sit
   flush, in their own brand colours. */
.ticker{
  --logo-h:clamp(34px,3.4vw,46px);    /* logo size */
  --logo-gap:clamp(72px,9vw,160px);   /* space between logos */
  background:var(--cream);
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  padding:clamp(16px,2vw,24px) 0;
  overflow:hidden;
  cursor:pointer;
}
.ticker:focus-visible{ outline:2px solid var(--red); outline-offset:-2px; }
.ticker__track{
  display:flex; width:max-content;
  animation:ticker 46s linear infinite;
  /* the animation makes this a stacking context, so the logos' multiply
     blend needs a backdrop here — without it white boxes stay white */
  background:var(--cream);
}
/* cells hug their logo, so the gap is measured between the artwork
   itself — fixed-width cells make narrow logos look further apart */
.ticker__set{
  display:flex; align-items:center;
  gap:var(--logo-gap);
  padding-right:var(--logo-gap);
}
.ticker__logo{
  display:flex; align-items:center; justify-content:center; flex:none;
  height:calc(var(--logo-h) * 1.4);   /* headroom for scaled-up logos */
}
.ticker__logo img{
  width:auto; height:auto;
  max-height:calc(var(--logo-h) * var(--s, 1));
  max-width:calc(var(--logo-h) * 2.6);
  object-fit:contain;
  mix-blend-mode:multiply;
  opacity:.88;
  transition:opacity .4s var(--ease);
}
.ticker__logo{ cursor:pointer; }
.ticker__logo:hover img{ opacity:1; }

@keyframes ticker{ to{ transform:translateX(-50%); } }
@media (prefers-reduced-motion:reduce){ .ticker__track{ animation:none; } }

/* ====================== THE SONG / PLAYER ==================== */
.record{
  background:var(--ink); color:var(--cream);
  padding:clamp(40px,5vh,64px) var(--pad) clamp(52px,7vh,88px);
  overflow:hidden;
}
/* One rhythm down the top of 03: kicker -> head -> opening line -> panel
   all sit on the same gap. They were 22px (fixed), 3.4vw and 3vw, so the
   kicker sat tight while the other two opened up with the viewport. */
.record .kicker{ margin-bottom:clamp(22px,2.6vw,34px); }
.record__head{
  font-size:clamp(46px,9vw,142px); line-height:.86;
  font-weight:700; letter-spacing:-.045em;
  margin-bottom:clamp(22px,2.6vw,34px);
}
.player{
  position:relative; color:var(--ink);
  border:1px solid rgba(14,14,14,.35); border-radius:16px;
  /* cast concrete: mid grey with a soft top light and darker pooling */
  background:
    radial-gradient(120% 90% at 16% 6%, rgba(255,255,255,.18), transparent 56%),
    radial-gradient(95% 75% at 86% 94%, rgba(14,14,14,.14), transparent 62%),
    linear-gradient(160deg,#B6B4AF,#A6A49F 55%,#ADABA6);
  padding:clamp(22px,3vw,40px);
  overflow:hidden;
}
/* the aggregate: two layers of noise at different scales */
.player::before{
  content:""; position:absolute; inset:0; pointer-events:none;
  opacity:.5; mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='.16'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
}
.player::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  opacity:.4; mix-blend-mode:soft-light;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='680' height='680'%3E%3Cfilter id='m'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.012 .017' numOctaves='3' seed='7'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='680' height='680' filter='url(%23m)'/%3E%3C/svg%3E");
}
/* content sits above the texture layers */
.player > *{ position:relative; z-index:1; }
.player__col{ min-width:0; }

/* desktop: record top-left (bigger), story text top-right, playlist
   directly below the record, streaming links full-width below all */
/* Two-column player only once there's room for it. Below this the player
   stacks (record / playlist / text / credits) full-width - which lets the
   credits spread to three columns instead of collapsing to one in a narrow
   right-hand column. Matches the hero's own collapse at 1080px so the whole
   page drops to a single column together. */
@media (min-width:1081px){
  .player{
    display:grid;
    grid-template-columns:1.12fr 0.88fr;
    grid-template-areas:
      "left     text"
      "stats    stats"
      "services services";
    column-gap:clamp(28px,4vw,56px);
    row-gap:clamp(22px,2.8vw,36px);
    /* stretch so the text column matches the (taller) record+playlist
       column, letting the credits drop to the bottom and line up with
       the playlist */
    align-items:stretch;
  }
  /* left column: record + playlist stacked tight, no grid gap between
     them - a small margin keeps the playlist just under the sleeves */
  .player .player__left{
    grid-area:left; display:flex; flex-direction:column;
  }
  .player .player__mock{ margin:0 0 clamp(16px,1.8vw,24px); }
  .player .player__playlist{ margin:0; }
  /* .player-scoped so these beat the base .rows/.services rules that
     appear later in the file (equal specificity, later source wins) */
  .player .player__blurb{
    grid-area:text; margin:0;
    display:flex; flex-direction:column;
  }
  /* push the credits to the bottom of the text column so its baseline
     sits level with the playlist below the record */
  .player .player__blurb .credits{ margin-top:auto; }
  /* Full-width row of its own, so the figures centre on the section rather
       than inside the narrower text column. */
    .player .streams{ grid-area:stats; }
    .player .services{ grid-area:services; max-width:none; margin:0; }
  .player .rows{ max-width:none; margin:0; }
}

/* at the widest sizes let the record grow a little more than the
   text column, so the sleeves read large on big screens */
@media (min-width:1180px){
  .player{ grid-template-columns:1.22fr 0.78fr; }
}

/* --- the record shot (photo) --- */
/* full interior width — its edges sit on the card padding,
   and the text below shares the same edges */
.player__mock{
  display:block; width:100%;
  margin:0 0 clamp(18px,2.2vw,28px);
}
.player__blurb{
  /* the top margin gives the story text room to breathe under the
     playlist when the layout is stacked (narrow screens); kept a tight
     range so it stays consistent across tablet/mobile rather than
     ballooning on wider stacked views. The desktop grid rule resets
     margin to 0 so it has no effect there */
  margin:clamp(24px,3vw,28px) 0 clamp(24px,3vw,36px);
}
.player__blurb p{
  font-size:clamp(14.5px,1.15vw,17px); line-height:1.65; color:#33312D;
  margin:0 0 16px;
}
.player__blurb p:last-child{ margin-bottom:0; }
.player__lead{
  font-weight:700; letter-spacing:-.015em; color:var(--ink) !important;
  font-size:clamp(16.5px,1.35vw,20px) !important;
}

/* --- track rows, on the concrete --- */
/* both rules live on .rows so the gap above the top line and the gap
   below the bottom line stay equal - a border on .services instead
   pushes the lower line an extra margin's width away from the text */
.rows{
  max-width:560px; margin:0 auto;
  border-top:1px solid rgba(14,14,14,.28);
  border-bottom:1px solid rgba(14,14,14,.28);
}
.row{
  display:flex; align-items:center; flex-wrap:wrap;
  /* column-gap keeps the play/art/text spacing; the tighter row-gap is
     the space above the wrapped preview bar - kept ~12px to match the
     padding above the tiny artwork so the bar isn't floating */
  column-gap:clamp(12px,1.6vw,18px); row-gap:10px;
  padding:12px 10px;
  transition:background .3s var(--ease);
}
/* faint divider between the two versions */
.row + .row{ border-top:1px solid rgba(14,14,14,.13); }
.row--play:hover{ background:rgba(14,14,14,.06); }

/* the play control sits where the track number used to, but flush to
   the left edge so it lines up with the paragraph text above it */
.row__play{
  flex:none; width:28px; height:28px; padding:0;
  border:0; border-radius:50%; cursor:pointer;
  display:grid; place-items:center;
  background:var(--red); color:#fff;
  transition:transform .25s var(--ease), background .25s var(--ease);
}
.row__play:hover{ transform:scale(1.08); }
.row__play svg{ width:11px; height:11px; fill:currentColor; }
.row__play .ico-pause{ display:none; }
.row.is-playing .row__play .ico-play{ display:none; }
.row.is-playing .row__play .ico-pause{ display:block; }
.row__play--ghost{
  background:rgba(14,14,14,.16); color:#514D46; cursor:default;
}
.row__play--ghost:hover{ transform:none; }

.row__art{
  position:relative; width:40px; height:40px; flex:none;
  border-radius:4px; overflow:hidden; object-fit:cover;
}
/* the acoustic sleeve is the same artwork reversed out, matching the
   treatment used on the hero phone, then tinted to the same concrete
   as the page's own card (see .row__art--acoustic-wrap::after) */
.row__art--acoustic{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  filter:invert(1) brightness(.74) contrast(2.9) brightness(1.08);
}
.row__art--acoustic-wrap::after{
  content:""; position:absolute; inset:0; pointer-events:none;
  mix-blend-mode:multiply;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='4'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='.16'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E"),
    radial-gradient(120% 90% at 16% 6%, rgba(255,255,255,.18), transparent 56%),
    radial-gradient(95% 75% at 86% 94%, rgba(14,14,14,.14), transparent 62%),
    linear-gradient(160deg,#B6B4AF,#A6A49F 55%,#ADABA6);
}
.row__txt{ flex:1; min-width:0; }
.row__txt b{
  display:block; font-size:14px; font-weight:600; letter-spacing:.02em;
  line-height:1.3;
}
.row__txt i{
  display:block; font-style:normal; margin-top:3px;
  font-family:var(--mono); font-size:10px; letter-spacing:.12em;
  text-transform:uppercase; color:#514D46;
}
.row__dur{
  flex:none; font-family:var(--mono); font-size:11px;
  letter-spacing:.1em; color:#514D46;
}
.row.is-soon{ opacity:.5; }
.row.is-soon .row__dur{ color:var(--red); opacity:1; }
.row.is-playing .row__txt b{ color:var(--red); }

/* the mini preview bar, sitting under a row's own text - indented to
   start where the title does, not the play button */
.row__bar{
  flex:1 1 100%; display:flex; align-items:center; gap:10px;
  margin-left:calc(28px + clamp(12px,1.6vw,18px));
}
.row__rail{
  flex:1; height:3px; border-radius:100px;
  background:rgba(14,14,14,.16); overflow:hidden;
}
.row__fill{
  display:block; width:0; height:100%;
  background:var(--red); transition:width .3s linear;
}
.row__time{
  flex:none; font-style:normal;
  font-family:var(--mono); font-size:10px; letter-spacing:.08em; color:#514D46;
}
.row__time i{ font-style:normal; }
.row__sep{ margin:0 3px; opacity:.5; }

/* --- live stream counter, below the story text --- */
/* Centred and set as a display figure rather than a line of text - it is the
   one live number on this page and the whole argument for streaming, so it
   gets the same weight as a section head. Bars sit above it as a mark, not
   an inline icon. */
.streams{
  display:flex; flex-direction:column; align-items:center; text-align:center;
  gap:8px;
  margin:clamp(26px,3.2vw,40px) 0 clamp(22px,2.6vw,30px);
  padding:clamp(20px,2.6vw,30px) 0;
  border-top:1px solid rgba(14,14,14,.14);
  border-bottom:1px solid rgba(14,14,14,.14);
}
.streams__ico{
  width:22px; height:22px; flex:none; fill:var(--red);
}
/* labels the pair below as the running total, not a target */
/* Both of these are <p> inside .player__blurb, whose `p` rule (0-1-1) beats
   a bare class (0-1-0) - so their sizes were silently losing to the story
   copy's 14.5px. Scoped to out-specify it. */
.streams p.streams__head{
  font-family:var(--mono); font-size:11px; letter-spacing:.2em;
  text-transform:uppercase; color:var(--red); font-weight:700;
  line-height:1.4; margin:0 0 4px;
}

/* Two figures joined by an equals, because that is the actual relationship:
   this many streams comes to about this much money. A multiplication sign
   was there before and read as a sum to be done - 310,000 x £1,000 - which
   is nonsense. */
/* Stacked at every width, not just on phones. The blurb column is ~450px and
   the count alone runs to ~330px at full size, so side by side it wrapped
   anyway - leaving the equals orphaned beside the count and half the column
   empty. Stacking is what the space actually wanted. */
.streams__pair{
  display:flex; flex-direction:column; align-items:center;
  justify-content:center; gap:clamp(10px,1.4vw,16px);
}
.streams__stat{
  display:flex; flex-direction:column; align-items:center; gap:6px;
}
/* No optical nudge any more - that offset only made sense when the two
   figures sat side by side and the equals had to find the numerals' centre. */
.streams__x{
  font-family:var(--sans); font-weight:400; color:var(--muted);
  font-size:clamp(18px,2.4vw,26px); line-height:1;
}

/* Below this the pair wraps anyway, so stack it deliberately rather than
   letting it break where it likes. The equals loses its optical nudge -
   that offset only makes sense when the two figures sit side by side. */
.streams__num{
  font-family:var(--sans); font-weight:700;
  font-size:clamp(34px,5.6vw,64px); letter-spacing:-.04em;
  color:var(--ink); font-variant-numeric:tabular-nums; line-height:1;
}
/* The stream count leads. Set at the same size as the money beside it, two
   big numerals read as two money figures - and the count is the achievement,
   the money is only an estimate derived from it. */
.streams__stat:first-of-type .streams__num{
  font-size:clamp(46px,7.4vw,80px);
}
.streams__stat:last-of-type .streams__num{
  font-size:clamp(26px,3.6vw,44px); color:#514D46;
}
.streams__label{
  font-family:var(--mono); font-size:10px; letter-spacing:.18em;
  text-transform:uppercase; color:#514D46; text-align:center;
}
/* How current the figures are. Quiet, but it has to be here: the money
   figure is an estimate and the page should say so where the figure is. */
.streams p.streams__foot{
  max-width:60ch; margin:18px auto 0;
  font-size:9.5px; line-height:1.55; color:var(--muted); text-align:center;
}

/* --- song credits, under the playlist --- */
.credits{
  margin-top:clamp(20px,2.4vw,30px);
  padding-top:clamp(16px,1.8vw,22px);
  border-top:1px solid rgba(14,14,14,.16);
  font-family:var(--mono); color:#514D46;
}
.credits .credits__head{
  font-family:var(--mono);
  font-size:9px; letter-spacing:.28em; text-transform:uppercase;
  color:#514D46; margin:0 0 clamp(12px,1.4vw,16px);
}
/* scoped with .credits so these beat the .player__blurb p rule (the
   credit lines are <p> inside the story-text block) */
.credits .credits__title{
  font-family:var(--mono);
  font-size:9.5px; font-weight:700; letter-spacing:.2em;
  text-transform:uppercase; color:var(--ink) !important; margin:0 0 6px;
  line-height:1.4;
}
.credits .credits__line{
  font-family:var(--mono);
  font-size:9.5px; letter-spacing:.05em; line-height:1.55; margin:0;
  color:#6A655D !important;
}
/* three even columns spread across the full width, all left-aligned:
   BONES under the story text on the left, BONES-ACOUSTIC in the middle,
   RELEASE on the right (evenly spaced, not right-aligned). The head sits
   left, above BONES. Collapses to a single column on phones. */
.credits__cols{
  display:grid;
  grid-template-columns:repeat(3, minmax(0, 1fr));
  gap:clamp(14px,1.6vw,26px) clamp(18px,2.4vw,40px);
}
.credits__col{ min-width:0; }
@media (max-width:520px){
  .credits__cols{ grid-template-columns:1fr; }
}

/* --- streaming service buttons --- */
.services{
  max-width:720px; margin:clamp(24px,3vw,36px) auto 0;
}
/* The secondary services, set as a quiet line rather than more pills.
   A service with no link yet is greyed in place, so the line does not
   change shape when one goes live. */
.services__more{
  margin:10px 0 0; text-align:center;
  font-family:var(--mono); font-size:10px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted);
}
.services__more[hidden]{ display:none; }
.services__more a{
  color:var(--ink); text-decoration:none;
  border-bottom:1px solid rgba(14,14,14,.3); padding-bottom:1px;
}
.services__more a:hover{ border-color:var(--ink); }
.services__more .is-soon{ opacity:.55; }

/* Two songs side by side; stacks below 700px so the chips never get too
   narrow to read. */
.services__cols{
  display:grid; gap:clamp(18px,2.4vw,32px);
  grid-template-columns:1fr;
}
@media (min-width:700px){
  .services__cols{ grid-template-columns:1fr 1fr; }
}
.services__song{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.18em;
  text-transform:uppercase; color:var(--ink);
  margin:0 0 10px; text-align:center; font-weight:600;
}
/* the qualifier is the only thing separating the two, so it carries the
   accent rather than sitting in the same ink as the title */
.services__song span{ color:var(--red); }

.services__label{
  font-family:var(--mono); font-size:10px; letter-spacing:.18em;
  text-transform:uppercase; color:#514D46; margin:0 0 12px;
  text-align:center;
}
/* Smaller chips, more per row. Six services in two-up rows wasted most of
   the width; at this size they sit three or four across and stop dominating
   the block. */
.services__grid{
  display:grid; grid-template-columns:repeat(auto-fill,minmax(112px,1fr));
  gap:7px;
}
/* Name + icon only. "Listen ↗" / "Soon" moved to a hover/■ state below so
   each chip only has to be wide enough for the service name. */
.svc{
  display:flex; align-items:center; justify-content:center; gap:7px;
  padding:9px 10px; border-radius:8px;
  border:1px solid rgba(14,14,14,.28); color:var(--ink);
  font-family:var(--sans); font-size:12px; font-weight:600; letter-spacing:-.01em;
  transition:background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
a.svc:hover{ background:var(--ink); color:var(--cream); border-color:var(--ink); }
.svc__l{ display:flex; align-items:center; gap:7px; min-width:0; }
.svc__l svg{ width:14px; height:14px; flex:none; fill:currentColor; }
/* The "Listen ↗" / "Soon" tag is redundant at this size - a live chip is
   clickable and a pending one is greyed. Hidden rather than removed so the
   markup and the renderer stay as they are. */
.svc em{ display:none; }
a.svc--spotify{ border-color:rgba(14,122,56,.6); }
a.svc--spotify em{ color:#0E7A38; }
.svc.is-soon{ opacity:.5; }

/* =========================== DONATE ========================== */
.donate{ padding:clamp(40px,5vh,64px) var(--pad) clamp(56px,8vh,100px); }
.donate__head{
  font-size:clamp(46px,9vw,142px); line-height:.86;
  font-weight:700; letter-spacing:-.045em;
  margin-bottom:clamp(24px,3vw,40px);
}
/* the "how giving works" copy under the title - wider so it fills the left
   column on desktop rather than bunching narrow on the left */
/* Full width - see the note on .merch__outro p. */
.donate__about{ max-width:none; }
/* Matches .structure__lede and .partners__intro - the paragraph directly
   under a section head reads at one size across the site. */
.donate__about p{
  font-size:clamp(15px,1.7vw,17.5px); line-height:1.65;
  color:#33312D; margin:0 0 16px;
}
.donate__about p:last-child{ margin-bottom:0; }

/* Large-gift line - deliberately quieter than the body copy above it. It's a
   route for the rare big donor, not something to compete with the main CTA. */
/* Moved out of .donate__about (2026-08-24) to sit under the donate box, so
   the selectors are no longer scoped to that column. Aligned to the box's
   own width so it reads as a footnote to it rather than loose page copy. */
/* Sits between the box and the large-gift note, same quiet register. */
.donate__after{
  max-width:46ch; margin:clamp(14px,1.8vw,18px) 0 0;
  font-size:13px; line-height:1.6; color:var(--muted);
}
.donate__large{
  grid-column:2; max-width:none;
  margin:16px 0 0; padding-top:16px;
  border-top:1px solid rgba(14,14,14,.12);
  font-size:clamp(13px,1vw,14.5px); line-height:1.6; color:#6B665B;
}
@media (max-width:900px){
  .donate__large{ grid-column:1; }
}
.donate__large a{
  color:#0E0E0E; font-weight:700; text-decoration:none;
  border-bottom:1px solid var(--red, #B5352A);
  transition:color .3s ease;
}
.donate__large a:hover{ color:var(--red, #B5352A); }

/* desktop: title + explainer on the left, donate box on the right */
@media (min-width:821px){
  .donate__grid{
    display:grid; grid-template-columns:1fr 1fr;
    column-gap:clamp(32px,5vw,80px); align-items:start;
  }
  .donate__head{ margin-bottom:clamp(28px,3vw,40px); }
  .give-box{ margin-top:0; max-width:none; }
}

/* Lifted off the cream page: a brighter, near-white ground plus a soft
   shadow, so the one thing on this page you can actually DO looks like a
   card rather than a tinted patch of the background. The green hairline at
   the top is the only colour on it besides the red CTA - it reads as
   "secure", which is exactly the reassurance needed at this step. */
.give-box{
  position:relative; overflow:hidden;
  max-width:520px; margin-top:clamp(28px,4vw,44px);
  border:1px solid rgba(14,14,14,.10); border-radius:14px;
  padding:clamp(20px,2.6vw,32px);
  background:#FDFCFA;
  box-shadow:0 1px 2px rgba(14,14,14,.04), 0 10px 30px rgba(14,14,14,.07);
}
.give-box::before{
  content:""; position:absolute; top:0; left:0; right:0; height:3px;
  background:var(--green);
}
.give-box__note{
  display:flex; gap:9px; align-items:flex-start;
  font-size:13px; line-height:1.5; color:#514D46;
  margin:0 0 clamp(20px,2.4vw,26px);
}
/* Green, not red - this line is a reassurance about Stripe, and a red dot
   next to the word "secure" reads as a warning. */
.give-box__note .dot{
  flex:none; width:6px; height:6px; margin-top:6px;
  border-radius:50%; background:var(--green);
  box-shadow:0 0 0 3px rgba(46,122,75,.14);
}
.give-box__label{
  font-family:var(--mono); font-size:10px; letter-spacing:.18em;
  text-transform:uppercase; color:var(--muted); margin:0 0 11px;
}

/* Donation currency row. Reuses .shop__curBtn for the pills themselves so
   the two switchers on the page cannot drift apart - only the container
   differs, because this one sits under a label rather than beside a
   heading. */
.give-box__cur{ display:flex; gap:6px; margin:0 0 10px; }
/* Sits directly under the currency pills, quieter than the box's own copy -
   it is reassurance for the person who went looking for it, not a headline. */
.give-box__fx{
  font-size:12px; line-height:1.5; color:var(--muted);
  margin:0 0 clamp(18px,2.2vw,24px);
}

.chips{ display:flex; flex-wrap:wrap; gap:8px; margin-bottom:16px; }
.chip{
  font-family:var(--mono); font-size:11px; letter-spacing:.08em;
  padding:10px 16px; border-radius:100px; cursor:pointer;
  border:1px solid var(--line); background:none; color:var(--ink);
  transition:background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease);
}
.chip:hover{ border-color:var(--ink); }
.chip.is-on{ background:var(--ink); border-color:var(--ink); color:var(--cream); }

/* the amount field is the focus of the box - white against the near-white
   ground, so it still reads as an input */
.amount{
  display:flex; align-items:center; gap:6px;
  border:1px solid var(--line); border-radius:10px;
  padding:14px 16px; background:var(--cream);
  transition:border-color .25s var(--ease);
}
.amount:focus-within{ border-color:var(--ink); }
.amount__cur{ font-size:26px; font-weight:700; letter-spacing:-.02em; }
.amount__field{
  flex:1; min-width:0; border:0; background:none; outline:none;
  font-family:var(--sans); font-size:26px; font-weight:700;
  letter-spacing:-.02em; color:var(--ink);
}
.give-box__hint{
  font-size:12.5px; line-height:1.5; color:var(--muted);
  margin:10px 0 clamp(20px,2.4vw,26px);
}
/* DEAD 2026-08-12: the "Where should it go?" designation dropdown and the
   "Prefer to give directly?" block were both removed from the donate box.
   Kept (not deleted) because the designation idea may come back if a pot with
   per-partner reporting is set up. Nothing renders with these classes now. */
.give-box__select{
  position:relative; border:1px solid var(--line); border-radius:10px;
  background:var(--cream); transition:border-color .25s var(--ease);
}
.give-box__select:focus-within{ border-color:var(--ink); }
/* custom chevron so the native select arrow doesn't clash */
.give-box__select::after{
  content:""; position:absolute; right:16px; top:50%; pointer-events:none;
  width:8px; height:8px; margin-top:-6px;
  border-right:2px solid var(--ink); border-bottom:2px solid var(--ink);
  transform:rotate(45deg);
}
.give-box__select select{
  appearance:none; -webkit-appearance:none;
  width:100%; border:0; background:none; outline:none; cursor:pointer;
  padding:14px 40px 14px 16px;
  font-family:var(--sans); font-size:15px; font-weight:600;
  letter-spacing:-.01em; color:var(--ink);
}

.pays-note{
  font-size:12.5px; line-height:1.5; color:var(--muted);
  margin:0 0 clamp(20px,2.4vw,26px);
}
.give-box__error{
  font-size:13px; line-height:1.5; color:var(--red);
  margin:0 0 14px;
}
.give-box__status{
  font-size:13.5px; line-height:1.5; font-weight:600;
  padding:12px 14px; border-radius:10px; margin:0 0 clamp(20px,2.4vw,26px);
}
.give-box__status--ok{ background:rgba(74,138,90,.12); color:#2E5B3B; }
.give-box__status--cancel{ background:rgba(181,53,42,.08); color:var(--red); }
.give-box__cta{ width:100%; justify-content:center; }
/* The causes link lives under the donate button, full width to match it, so
   the two read as one stacked pair: give, then see where it lands. */
.give-box__causes{
  width:100%; justify-content:center; margin-top:10px;
  border-color:var(--line); color:var(--ink);
}
.give-box__causes b{ font-weight:400; transition:transform .35s var(--ease); }
.give-box__causes:hover{ background:var(--ink); border-color:var(--ink); color:var(--cream); }
.give-box__causes:hover b{ transform:translateX(3px); }
.give-box__cta:disabled{ cursor:not-allowed; opacity:.55; }
.give-box__cta:disabled:hover{ transform:none; background:var(--red); border-color:var(--red); }

/* quiet secondary: give straight to a charity instead of the pot */
.give-direct{
  margin-top:clamp(20px,2.6vw,28px); padding-top:clamp(18px,2.2vw,24px);
  border-top:1px solid var(--line);
}
.give-direct__q{
  font-family:var(--mono); font-size:10px; letter-spacing:.18em;
  text-transform:uppercase; color:var(--muted); margin:0 0 12px;
}
.give-direct__opts{ display:grid; gap:8px; margin-bottom:14px; }
.give-direct__opt{
  display:flex; align-items:center; gap:10px;
  padding:11px 14px; border:1px solid var(--line); border-radius:10px;
  background:var(--cream); color:var(--ink); text-decoration:none;
  transition:border-color .25s var(--ease), transform .25s var(--ease);
}
.give-direct__opt:hover{ border-color:var(--ink); transform:translateY(-1px); }
.give-direct__region{
  flex:none; font-family:var(--mono); font-size:9px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--cream); background:var(--ink);
  border-radius:100px; padding:3px 9px;
}
.give-direct__name{ flex:1; font-size:14px; font-weight:600; letter-spacing:-.01em; }
.give-direct__arr{ color:var(--muted); font-size:13px; }
.give-direct__opt:hover .give-direct__arr{ color:var(--red); }
.give-direct__all{
  font-family:var(--mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted); transition:color .25s var(--ease);
}
.give-direct__all:hover{ color:var(--red); }

/* ======================== PARTNERS (05) ====================== */
.partners{
  background:var(--ink); color:var(--cream);
  padding:clamp(40px,5vh,64px) var(--pad) clamp(52px,7vh,88px);
  overflow:hidden;
}
.partners__head{
  font-size:clamp(46px,9vw,142px); line-height:.86;
  font-weight:700; letter-spacing:-.045em;
  margin-bottom:clamp(16px,2vw,22px);
}
.partners__hint{
  color:var(--muted-dark);
  margin:0;
}
/* intro copy under the section head, above the featured boxes */
.partners__intro{
  /* Full width - the cards below run the whole section, so the intro
     stopping at 78ch left a wide empty band beside it. */
  max-width:none;
  margin:0 0 clamp(26px,3.2vw,42px);
}
.partners__intro p{
  font-size:clamp(15px,1.6vw,17.5px); line-height:1.65;
  color:rgba(243,240,233,.74); margin:0 0 14px;
}
.partners__intro p:last-child{ margin-bottom:0; }

/* follow/subscribe block, moved BELOW the causes rail (2026-08-17 - was
   above it, next to the intro paragraph) */
/* pulled up closer to the rail it follows - the block was drifting away
   from the cards and reading as unrelated to them */
.partners__follow{ margin-top:clamp(24px,2.8vw,36px); max-width:78ch; }
.partners__follow > p{
  font-size:clamp(15px,1.6vw,17.5px); line-height:1.65;
  color:rgba(243,240,233,.74); margin:0 0 22px;
}
.partners__ctas{ display:flex; flex-wrap:wrap; gap:12px; margin-top:4px; }
/* red outline + a soft cream-tinted fill (not solid, not fully transparent)
   so FOLLOW/SUBSCRIBE read brighter against the dark section without being
   as loud as a solid .btn--light pill. Text is pure #fff rather than the
   site's off-white --cream - brighter/crisper against --ink at this
   weight/size. */
.partners__ctas .btn{
  background:rgba(243,240,233,.12); border-color:var(--red); color:#fff;
}
.partners__ctas .btn:hover{
  background:rgba(243,240,233,.22); border-color:var(--red); color:#fff;
}
/* FOLLOW gets its own green ring (Instagram vs. the red SUBSCRIBE/donate
   accent used everywhere else) - reuses the site's existing --spotify green
   rather than introducing a new colour */
.partners__ctas-follow{ border-color:var(--spotify) !important; }
/* neither has a destination yet - reads as the real buttons, just doesn't
   lie about being clickable */
.partners__ctas .is-pending{ opacity:.5; cursor:not-allowed; }
.partners__ctas .is-pending:hover{
  background:rgba(243,240,233,.12); color:#fff; border-color:var(--red);
  transform:none;
}
.partners__ctas-follow.is-pending:hover{ border-color:var(--spotify) !important; }

/* Only one paragraph left in this block now the mailing-list mock is gone. */
/* Has to out-specify `.partners__follow > p` (0-1-1), which sets every
   paragraph in this block to the section's 15px body size. */

/* the invitation - bolder but smaller, so it leads without shouting */
.partners__follow > p:first-of-type{
  font-size:clamp(13px,1.2vw,14.5px); line-height:1.6;
  font-weight:700; color:rgba(243,240,233,.86);
}
/* subtitle for the rail + the scroll cue, on one line */
.partners__subhead{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:16px; flex-wrap:wrap;
  margin-bottom:clamp(14px,1.8vw,20px);
}
.partners__sub{
  font-family:var(--mono);
  font-size:clamp(12px,1.3vw,15px); font-weight:500;
  letter-spacing:.16em; text-transform:uppercase;
  color:var(--cream); margin:0;
}
/* the "click to read more" cue rides along at the same size but dimmed, so
   it reads as an instruction rather than part of the heading */
.partners__cue{
  color:var(--muted-dark); font-weight:400; letter-spacing:.12em;
}
/* aligned to the content column on both edges, matching the other
   sections; the cards overflow and scroll horizontally within it */
.partners__scroll{
  display:flex; gap:clamp(12px,1.6vw,20px);
  overflow-x:auto; overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;
  padding:0 0 16px 0;
  scrollbar-width:thin;
  scrollbar-color:rgba(243,240,233,.28) transparent;
}
.partners__scroll::-webkit-scrollbar{ height:6px; }
.partners__scroll::-webkit-scrollbar-thumb{
  background:rgba(243,240,233,.26); border-radius:100px;
}
.pcard{
  flex:none; width:min(80vw,330px);
  scroll-snap-align:start;
  display:flex; flex-direction:column;
  background:var(--cream); color:var(--ink);
  border-radius:12px;
  padding:clamp(20px,2.4vw,28px);
}
/* name left, logo right, on one line */
.pcard__head{
  display:flex; align-items:center; justify-content:space-between;
  gap:14px; margin-bottom:16px;
}
.pcard__logo{ height:38px; flex:none; }
.pcard__logo img{
  height:100%; width:auto; max-width:120px; object-fit:contain;
  mix-blend-mode:multiply;
  transform-origin:right center;   /* scaled logos grow inward, not off the card */
}
.pcard h4{
  font-size:clamp(20px,2.2vw,24px); font-weight:700;
  letter-spacing:-.025em; line-height:1.1; margin:0;
}
.pcard p{ font-size:13.5px; line-height:1.6; color:#3F3C37; margin:0; }
.pcard__link{
  margin-top:auto; padding-top:18px;
  font-family:var(--mono); font-size:9.5px; line-height:1.6;
  letter-spacing:.14em; text-transform:uppercase; color:var(--red);
}
/* cards that link out to the charity's site */
a.pcard{
  text-decoration:none; color:var(--ink); cursor:pointer;
  transition:transform .3s var(--ease), box-shadow .3s var(--ease);
}
a.pcard:hover{ transform:translateY(-4px); box-shadow:0 12px 30px rgba(0,0,0,.12); }
a.pcard:hover h4{ text-decoration:underline; text-underline-offset:3px; }

/* ====================== CAUSE DETAIL PANEL =================== */
.panel{ position:fixed; inset:0; z-index:120; }
.panel__scrim{
  position:absolute; inset:0;
  background:rgba(14,14,14,.55);
  opacity:0; transition:opacity .4s var(--ease);
}
.panel.is-open .panel__scrim{ opacity:1; }

.panel__sheet{
  position:absolute; top:0; right:0; bottom:0;
  width:min(520px, 100%);
  background:var(--cream); color:var(--ink);
  overflow-y:auto; -webkit-overflow-scrolling:touch;
  padding:clamp(26px,3.4vw,48px);
  transform:translateX(100%);
  transition:transform .42s var(--ease);
  box-shadow:-20px 0 60px rgba(0,0,0,.18);
}
.panel.is-open .panel__sheet{ transform:translateX(0); }
.panel__sheet:focus{ outline:none; }

.panel__close{
  position:absolute; top:clamp(16px,2vw,24px); right:clamp(16px,2vw,24px);
  width:40px; height:40px; padding:0;
  display:inline-flex; align-items:center; justify-content:center;
  background:none; border:1px solid var(--line); border-radius:100px;
  color:var(--ink); cursor:pointer;
  transition:background .3s var(--ease), color .3s var(--ease);
}
.panel__close:hover{ background:var(--ink); color:var(--cream); }
.panel__close svg{ width:18px; height:18px; fill:none; }

.panel__logo{
  display:block; height:56px; margin-bottom:clamp(18px,2.2vw,26px);
}
/* max-width raised from 180px: with the name hidden the logo is the title,
   and a wide wordmark capped at 180px was rendering barely half height. */
.panel__logo img{
  height:100%; width:auto; max-width:260px; object-fit:contain;
  mix-blend-mode:multiply; transform-origin:left center;
}
/* TRYING IT OUT 2026-08-26: the logos are wordmarks, so the name heading
   repeats what the logo already says. Hidden visually but kept in the DOM -
   the sheet is aria-labelledby="panelName", so deleting it would leave the
   dialog unnamed for screen readers. Delete this block to bring it back. */
.panel__name{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}
.panel__name--visible{
  position:static; width:auto; height:auto; margin:0 0 clamp(14px,1.8vw,20px);
  overflow:visible; clip:auto; white-space:normal;
  font-size:clamp(26px,3.2vw,38px); font-weight:700;
  letter-spacing:-.032em; line-height:1.06; margin:0 0 clamp(14px,1.8vw,20px);
}
.panel__lead{
  font-size:15.5px; line-height:1.7; color:#3F3C37; margin:0;
}

/* Two sections - his connection, then the organisation. Separated by a rule
   rather than by labels: the copy makes it obvious which is which, and the
   micro-headings were three bits of small red text competing with the name. */
.panel__section{ margin-top:clamp(20px,2.4vw,26px); }
.panel__section + .panel__section{
  padding-top:clamp(20px,2.4vw,26px);
  border-top:1px solid var(--line);
}
/* Both sections set identically - the rule between them separates them, and
   two different body sizes in one panel read as an accident rather than a
   hierarchy. */
.panel__section--liam .panel__text{ color:#33302B; }

/* The close: a rule, a bold statement of what happens next, then the button.
   Plain text, not a link - the button under it is the thing you press. */
.panel__close-out{
  margin-top:clamp(26px,3vw,34px);
  padding-top:clamp(20px,2.4vw,26px);
  border-top:2px solid var(--ink);
}
.panel__closing{
  margin:0; font-size:clamp(16px,1.8vw,19px); line-height:1.4;
  font-weight:700; letter-spacing:-.02em; color:var(--ink); max-width:26ch;
}
.panel__close-out .panel__actions{ margin-top:clamp(14px,1.8vw,18px); }
/* second and subsequent paragraphs of a long write-up */
.panel__para{ margin-top:16px; }
.panel__block{
  margin-top:clamp(22px,2.6vw,30px);
  padding-top:clamp(18px,2.2vw,24px);
  border-top:1px solid var(--line);
}
.panel__label{
  font-family:var(--mono); font-size:9.5px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--red); margin:0 0 10px;
}
.panel__text{ font-size:15px; line-height:1.65; color:#3F3C37; margin:0; }
.panel__text + .panel__text{ margin-top:12px; }

/* Ross's own first-person account (currently only The Albion Foundation) -
   distinct from the fund's usual third-person `story`/`does` copy, so it
   gets a quiet card of its own rather than reading as more site voice. */
.panel__connection{
  margin-top:clamp(22px,2.6vw,30px);
  padding:clamp(18px,2.2vw,24px);
  background:rgba(14,14,14,.035);
  border-left:2px solid var(--red);
  border-radius:0 8px 8px 0;
}
.panel__byline{
  margin:12px 0 0;
  font-family:var(--mono); font-size:11px; letter-spacing:.06em;
  color:var(--muted); font-style:italic;
}

.panel__actions{
  display:flex; flex-direction:column; align-items:flex-start; gap:14px;
  margin-top:clamp(26px,3vw,36px);
}
.panel__cta{
  display:inline-flex; align-items:center; justify-content:center;
  font-family:var(--mono); font-size:11px; letter-spacing:.16em;
  text-transform:uppercase; text-decoration:none;
  padding:15px 30px; border-radius:100px;
  background:var(--red); border:1px solid var(--red); color:var(--cream);
  transition:background .35s var(--ease), border-color .35s var(--ease),
             transform .35s var(--ease);
}
.panel__cta:hover{
  background:var(--ink); border-color:var(--ink); transform:translateY(-2px);
}
.panel__site{
  font-family:var(--mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted); text-decoration:none;
}
.panel__site:hover{ color:var(--red); }
.panel__foot{
  margin:clamp(22px,2.6vw,30px) 0 0;
  font-size:11.5px; line-height:1.55; color:var(--muted);
}

/* phones: full-screen sheet rather than a drawer */
@media (max-width:560px){
  .panel__sheet{ width:100%; }
}
@media (prefers-reduced-motion:reduce){
  .panel__scrim, .panel__sheet{ transition:none; }
}

/* the rail cards are <button>s now (they open the panel), so reset the
   browser's button styling back to how the old <a> cards looked */
button.pcard{
  font:inherit; text-align:left; cursor:pointer;
  border:1px solid transparent; appearance:none;
}
.pcard__more{
  margin-top:14px;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--ink);
}
.pcard__more b{ transition:transform .3s var(--ease); display:inline-block; }
button.pcard:hover .pcard__more b{ transform:translateX(4px); }

/* ============================ MERCH (06) ===================== */
/* Sits between partners (ink) and the footer (cream). Given its own
   --cream-2 band so it doesn't merge into either neighbour - the page
   alternates dark/light and a plain cream here would run straight into
   the footer with no seam. */
.merch{
  /* relative + hidden: the rose watermark is absolutely positioned and
     deliberately overhangs the section's corner */
  position:relative; overflow:hidden;
  background:var(--cream-2); color:var(--ink);
  padding:clamp(40px,5vh,64px) var(--pad) clamp(52px,7vh,88px);
}
/* full-width display head, matching .partners__head / .record__head so the
   section reads like the rest of the page: kicker, big title, body below */
.merch__head{
  font-size:clamp(46px,9vw,142px); line-height:.86;
  font-weight:700; letter-spacing:-.045em;
  /* the display head runs at .86 line-height, so it needs a real gap under
     it before the controls row - at 16px the currency chips sat tight
     against the descenders */
  margin:0 0 clamp(26px,3.4vw,44px);
}
.merch__sub{
  color:var(--muted);
  margin:0 0 clamp(24px,3vw,40px);
}
/* photo left, prices right on desktop; stacked below 821 */
.merch__body{
  display:grid; grid-template-columns:1fr;
  gap:clamp(24px,3vw,48px); align-items:center;
}
@media (min-width:821px){
  .merch__body{ grid-template-columns:1.05fr .95fr; }
}
.merch__shot{
  margin:0; border-radius:14px; overflow:hidden;
  background:var(--cream);
}
.merch__shot img{ display:block; width:100%; height:auto; }
/* name .......... price, with a dotted leader that fills the gap */
.merch__list{ list-style:none; margin:0 0 clamp(20px,2.4vw,28px); padding:0; }
.merch__item{
  display:flex; align-items:baseline; gap:10px;
  padding:11px 0; border-bottom:1px solid var(--line);
}
.merch__item:first-child{ border-top:1px solid var(--line); }
.merch__name{ font-size:clamp(15px,1.6vw,18px); }
.merch__dots{
  flex:1 1 auto; height:1px; min-width:18px;
  border-bottom:1px dotted rgba(14,14,14,.32);
  transform:translateY(-3px);
}
.merch__price{
  font-family:var(--mono); font-size:clamp(14px,1.5vw,17px);
  letter-spacing:.02em; font-weight:600;
}
/* DEAD 2026-08-16: replaced by .merch__blurb below (a full descriptive
   sentence doesn't work in a small uppercase mono label). Kept in case a
   short callout like this is wanted again. */
.merch__note{
  font-family:var(--mono); font-size:11px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--red);
  margin:0 0 clamp(20px,2.4vw,28px);
}
.merch__blurb{
  font-size:14.5px; line-height:1.65; color:#3F3C37;
  margin:0 0 clamp(20px,2.4vw,28px);
}
.merch__cta{
  display:inline-flex; align-items:center; justify-content:center;
  font-family:var(--mono); font-size:11px; letter-spacing:.16em;
  text-transform:uppercase; text-decoration:none;
  padding:15px 34px; border-radius:100px;
  background:var(--red); border:1px solid var(--red); color:var(--cream);
  transition:background .35s var(--ease), border-color .35s var(--ease),
             transform .35s var(--ease);
}
.merch__cta:hover{
  background:var(--ink); border-color:var(--ink); transform:translateY(-2px);
}
/* no store yet - reads as the real button, just doesn't lie about clickable */
.merch__cta.is-pending{ opacity:.5; cursor:not-allowed; }
.merch__cta.is-pending:hover{
  background:var(--red); border-color:var(--red); transform:none;
}

/* Section 03 subheading, directly under the display head. Cream on the ink
   band, tracking loosened slightly so it reads as a caption to the title
   rather than the first line of body copy. */
/* Opening sentence, not a second headline - light weight and close to body
   size so it sets the section up rather than competing with the title. */
.record__sub{
  text-transform:uppercase;
  /* Wants to sit on one line wherever it fits, so no character cap - the
  /* Wants to sit on one line wherever it fits, so no character cap - the
     which is fine, and it fills the measure before it breaks. */
  max-width:none;
  /* no top margin - it would collapse against the head's bottom margin and
     make this one gap larger than the other two */
  margin:0 0 clamp(22px,2.6vw,34px);
  font-size:clamp(11px,1.15vw,16px); line-height:1.6; font-weight:600;
  /* No text-wrap:balance. It split the line evenly when it wrapped, so on
     a phone both halves came out short and the line read as though it was
     not using the width it had. Filling the measure and breaking late
     looks like it goes all the way across, because it does. */
  letter-spacing:.02em;
  /* grey rather than near-white: it introduces the section, it is not part
     of the headline above it */
  color:rgba(243,240,233,.52);
}

/* ---- shop grid (live from the Storefront API) ---------------------- */
.shop__status{
  font-family:var(--mono); font-size:11px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted);
  margin:0 0 clamp(20px,2.4vw,28px);
}
.shop__status[hidden]{ display:none; }

/* Horizontal rail, matching the causes scroller on 05: snap-scrolling, a
   thin visible scrollbar, and cards overhanging the right edge so it reads as
   "there is more this way". Order is shuffled on every load (see loadShop)
   so no single product is permanently the hero. */
.shop__grid{
  display:flex; gap:clamp(12px,1.6vw,20px);
  overflow-x:auto; overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;
  /* The scrollbar is painted inside this padding, so it needs enough room
     not to sit against the ADD TO BASKET buttons. On macOS it is an overlay
     and takes no layout space at all, so anything beyond this is just a gap
     before the divider below - which is what made that gap too large. */
  padding:0 0 clamp(18px,2.2vw,26px);
  scrollbar-width:thin;
  scrollbar-color:rgba(14,14,14,.26) transparent;
}
.shop__grid::-webkit-scrollbar{ height:6px; }
.shop__grid::-webkit-scrollbar-thumb{
  background:rgba(14,14,14,.24); border-radius:100px;
}
/* No card, no border - each product sits straight on the page and the
   photograph does the framing. */
.shop__hint{ margin:0; }

/* What reaches the causes. In the accent, because it is the reason the
   price is what it is - the one number on a listing worth reading twice. */
.shop__give{
  margin:5px 0 0;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--red);
}
.shop__give:empty{ display:none; }
.pdp__price .shop__give{ display:block; margin:4px 0 0; font-size:10.5px; }

/* VAT note under the rail, and the small tag beside each price. Both are
   deliberately quiet - they are a disclosure, not a selling point - but they
   have to be legible, which is the whole reason they exist. */
.shop__vat{
  margin:14px 0 0; text-align:center;
  font-family:var(--mono); font-size:10px; letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted);
}
.shop__vatTag{
  display:inline-block; margin-left:7px;
  font-family:var(--mono); font-size:9.5px; letter-spacing:.08em;
  text-transform:uppercase; color:var(--muted);
  /* sits on the price's baseline rather than riding high on it */
  vertical-align:baseline;
}
.pdp__price .shop__vatTag{ display:block; margin:5px 0 0; font-size:10px; }

/* Rail item, not a grid cell - fixed width so the row overhangs.
   Hairline red outline: enough to box each product without the weight of a
   solid card, and it puts the brand accent on the one part of the page that
   is actually shoppable. */
.shop__card{
  flex:none; width:min(62vw,236px);
  scroll-snap-align:start;
  display:flex; flex-direction:column;
}
/* Fourthwall's product shots are on white; the cream tile behind them keeps
   the section's warmth rather than punching white holes in it. */
.shop__thumb{
  position:relative; margin:0 0 10px; border-radius:9px; overflow:hidden;
  background:var(--cream-2); aspect-ratio:1/1;
}
.shop__thumb img{
  display:block; width:100%; height:100%; object-fit:cover;
  transition:transform .5s var(--ease);
}
.shop__card:hover .shop__thumb img{ transform:scale(1.03); }
.shop__name{
  font-size:13.5px; font-weight:700; line-height:1.3; margin:0 0 3px;
  padding:0 2px;
}
.shop__price{
  font-family:var(--mono); font-size:12.5px; letter-spacing:.02em;
  /* the donation line sits under this, so the gap below belongs to that
     pair - not to the space before the button */
  color:#3F3C37; margin:0 0 0; padding:0 2px;
}
/* Size/colour picker. Only rendered when a product has more than one
   variant, so single-variant products carry no redundant control. */
.shop__variants{
  display:flex; flex-wrap:wrap; gap:6px; margin:0 0 10px;
}
.shop__variant{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.08em;
  padding:6px 10px; border-radius:100px; cursor:pointer;
  background:none; border:1px solid var(--line); color:var(--ink);
  transition:background .25s var(--ease), border-color .25s var(--ease),
             color .25s var(--ease);
}
.shop__variant.is-on{
  background:var(--ink); border-color:var(--ink); color:var(--cream);
}
.shop__add{
  margin-top:auto;
  font-family:var(--mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; cursor:pointer;
  padding:10px 12px; border-radius:100px;
  background:none; border:1px solid var(--ink); color:var(--ink);
  transition:background .3s var(--ease), color .3s var(--ease);
}
.shop__add:hover{ background:var(--ink); color:var(--cream); }
.shop__add:disabled{ opacity:.55; cursor:default; }
.shop__add[hidden]{ display:none; }

/* Stepper. Replaces the button once the item is in the basket, matching its
   height and shape so the card does not jump. */
.shop__qty{
  margin-top:auto; display:flex; align-items:center; justify-content:space-between;
  padding:0 6px; border:1px solid var(--ink); border-radius:100px;
  min-height:41px;
}
.shop__qty[hidden]{ display:none; }
.shop__qtyBtn{
  width:34px; height:34px; flex:none; cursor:pointer;
  background:none; border:0; border-radius:50%; color:var(--ink);
  font-size:17px; line-height:1;
  transition:background .2s var(--ease);
}
.shop__qtyBtn:hover{ background:rgba(14,14,14,.08); }
.shop__qtyN{
  font-family:var(--mono); font-size:12.5px; font-weight:700;
  font-variant-numeric:tabular-nums;
}
.shop__fallback[hidden]{ display:none; }

/* The one line above the products - the invitation, set bold so it carries
   the section on its own rather than sitting in a block of explanation. */
/* The invitation above the products. Regular weight - at 500 it still read
   as a second headline under the display head. Allowed to run the full
   content width so it spreads on wide screens instead of stacking into a
   narrow column beside empty space. */
/* The invitation and the Fourthwall line are one pair: identical size,
   weight and colour, so they read as two sentences of the same voice
   rather than a heading and its explanation. Only the currency note under
   them stays small and grey.

   Written as `.merch__outro p.merch__claim` so it out-specifies
   `.merch__outro p` (0-1-1) on its own - the earlier version needed
   !important because a bare class loses that fight. */
/* one paragraph now, so the `+ p` half of this pair is gone */
.merch__outro p.merch__claim{
  /* the site's standard body copy, same as .player__blurb p on 03 -
     regular weight, normal reading colour, no special treatment */
  font-size:clamp(14.5px,1.15vw,17px);
  line-height:1.65; font-weight:400; color:#33312D;
  margin:0 0 16px;
}
/* Explanation, below the grid. */
/* Full width, matching the rail above it - a 64ch column left the block
   hanging in the left third of the section on wide screens. The paragraphs
   inside carry their own measure so the lines never run unreadably long. */
/* The hairline introduces the copy below it, so it sits nearer that copy
   than to the products above - but it was 78px below the buttons and only
   23px above the text, which read as the line drifting away from the rail
   rather than heading the paragraph. Both sides are now in proportion. */
.merch__outro{
  max-width:none; margin:clamp(16px,2vw,24px) 0 0;
  padding-top:clamp(24px,2.8vw,32px); border-top:1px solid var(--line);
}
/* Full width, at Ross's request - these run the width of the product rail
   above them rather than stopping short of it. Note this gives a long line
   on a wide monitor; if it ever reads as too long, the fix is two columns
   rather than putting the cap back. */
.merch__outro p{ max-width:none; }
/* Both paragraphs are housekeeping rather than pitch, so they share one
   smaller size and one colour - the split sizing made the second look like a
   footnote to the first when they are the same kind of note. */
.merch__outro p{
  font-size:12.5px; line-height:1.7; color:var(--muted); margin:0 0 10px;
}
.merch__outro-note{ padding-top:2px; }

/* currency picker (left) and scroll cue (right), on one baseline */
.shop__railhead{
  display:flex; align-items:center; justify-content:space-between;
  gap:16px; flex-wrap:wrap;
  margin:0 0 clamp(18px,2.2vw,28px);
}
.shop__cur{ display:flex; gap:4px; }
.shop__curBtn{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.12em;
  padding:7px 12px; border-radius:100px; cursor:pointer;
  background:none; border:1px solid var(--line); color:var(--muted);
  transition:background .25s var(--ease), color .25s var(--ease),
             border-color .25s var(--ease);
}
/* red rather than ink - the selected currency is the one live control in
   this section, and the brand accent marks it more clearly than another
   black pill among black pills */
.shop__curBtn.is-on{
  background:var(--red); border-color:var(--red); color:var(--cream);
}

/* the tile itself is the button that opens the detail panel */
.shop__open{
  display:block; width:100%; text-align:left; padding:0;
  background:none; border:0; cursor:pointer; color:inherit; font:inherit;
  /* Guarantees clear air before ADD TO BASKET. The button carries
     margin-top:auto to sit at the foot of an equal-height card, and auto
     resolves to nothing once the content fills - which left the donation
     line touching the button. */
  margin-bottom:14px;
}

/* ---- product detail panel ------------------------------------------ */
.pdp[hidden]{ display:none; }
/* Above .nav (100). The nav is fixed and was painting over the panel - once
   the panel went full-screen on phones that put the hamburger and the listen
   link on top of the back bar. A modal covering the screen has to cover the
   header too. */
.pdp{ position:fixed; inset:0; z-index:110; }
/* same guard as the basket drawer above */
.pdp:not(.is-open){ pointer-events:none; }
.pdp.is-open{ pointer-events:auto; }
.pdp__scrim{
  position:absolute; inset:0; background:rgba(14,14,14,.5);
  opacity:0; transition:opacity .35s var(--ease);
}
.pdp.is-open .pdp__scrim{ opacity:1; }
.pdp__panel{
  position:absolute; top:0; right:0; bottom:0;
  width:min(460px,100%); display:flex; flex-direction:column;
  background:var(--cream); color:var(--ink);
  transform:translateX(100%); transition:transform .4s var(--ease);
}
.pdp.is-open .pdp__panel{ transform:none; }
.pdp__close{
  position:absolute; top:12px; right:14px; z-index:2;
  width:34px; height:34px; border-radius:50%; cursor:pointer;
  background:rgba(243,240,233,.9); border:1px solid var(--line);
  color:var(--ink); font-size:22px; line-height:1;
  display:flex; align-items:center; justify-content:center;
}
.pdp__close-label{ display:none; }

/* Stepper in the panel footer, matching the one on the grid cards. */
/* [hidden] is display:none at browser-default weight, which an explicit
   display here beats - so without this the stepper and the add button showed
   at the same time. Same trap as .ty-card[hidden]. */
.pdp__qty[hidden]{ display:none; }
.pdp__add[hidden]{ display:none; }
.pdp__qty{
  display:flex; align-items:center; justify-content:space-between;
  gap:14px; width:100%;
  border:1px solid var(--ink); border-radius:100px; padding:6px 8px;
}
.pdp__qtyBtn{
  width:40px; height:40px; border-radius:50%; cursor:pointer;
  border:0; background:var(--ink); color:var(--cream);
  font-size:19px; line-height:1;
}
.pdp__qtyBtn:hover{ background:var(--red); }
.pdp__qtyN{
  font-family:var(--mono); font-size:15px; font-weight:700;
  min-width:2ch; text-align:center;
}

/* On a phone .pdp__panel is width:min(460px,100%), so it fills the screen -
   there is no scrim left to tap and nothing to signal this is a panel rather
   than a page. The round x also sat over the product photo at 34px, under
   the 44px touch minimum and easy to miss. Below 560px it becomes a real
   back bar instead: full width, labelled, and out of the image. */
@media (max-width:560px){
  .pdp__scroll{ padding-top:0; }
  .pdp__close{
    position:static;
    flex:none;
    width:100%; height:58px; border-radius:0;
    border:0; border-bottom:1px solid rgba(14,14,14,.18);
    background:var(--cream);
    justify-content:flex-start; gap:12px; padding:0 18px;
    font-family:var(--mono); font-size:13px; letter-spacing:.12em;
    text-transform:uppercase; font-weight:700; color:var(--red);
  }
  .pdp__close-x{ display:none; }
  .pdp__close-label{ display:inline; }
  .pdp__close::before{ content:"\2190"; font-size:19px; line-height:1; }
}
.pdp__scroll{ flex:1 1 auto; overflow-y:auto; padding:0 0 20px; }
.pdp__hero{ margin:0; background:var(--cream-2); aspect-ratio:1/1; }
.pdp__hero img{ display:block; width:100%; height:100%; object-fit:cover; }
.pdp__thumbs{
  display:flex; gap:8px; overflow-x:auto; padding:12px 22px 0;
}
.pdp__thumbs[hidden]{ display:none; }
.pdp__thumb{
  flex:0 0 auto; width:54px; height:54px; padding:0; cursor:pointer;
  border-radius:8px; overflow:hidden; background:var(--cream-2);
  border:1px solid transparent; transition:border-color .25s var(--ease);
}
.pdp__thumb.is-on{ border-color:var(--ink); }
.pdp__thumb img{ display:block; width:100%; height:100%; object-fit:cover; }
.pdp__title{
  font-size:20px; font-weight:700; letter-spacing:-.01em;
  margin:18px 22px 4px;
}
.pdp__price{
  font-family:var(--mono); font-size:15px; font-weight:600;
  margin:0 22px 14px;
}
/* the size line for single-variant listings */
.pdp__spec{
  font-family:var(--mono); font-size:10.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted);
  margin:-8px 22px 14px;
}
.pdp__spec[hidden]{ display:none; }
.pdp__variants{ display:flex; flex-wrap:wrap; gap:6px; margin:0 22px 16px; }
.pdp__variants[hidden]{ display:none; }
.pdp__desc{ margin:0 22px; font-size:14px; line-height:1.65; color:#3F3C37; }
.pdp__desc p{ margin:0 0 10px; }
.pdp__foot{ padding:16px 22px 22px; border-top:1px solid var(--line); }
.pdp__add{ width:100%; justify-content:center; }

/* ---- basket drawer ------------------------------------------------- */
.cart[hidden]{ display:none; }
.cart{ position:fixed; inset:0; z-index:90; }
/* The overlay covers the whole viewport. Closing it relies on a timer
   setting [hidden], and if that does not land the sheet stays over the page
   - fully transparent, still swallowing every click, so the store becomes
   unusable after the first add. Never let it take pointer events unless it
   is actually open. */
.cart:not(.is-open){ pointer-events:none; }
.cart.is-open{ pointer-events:auto; }
.cart__scrim{
  position:absolute; inset:0; background:rgba(14,14,14,.5);
  opacity:0; transition:opacity .35s var(--ease);
}
.cart.is-open .cart__scrim{ opacity:1; }
.cart__panel{
  position:absolute; top:0; right:0; bottom:0;
  width:min(400px,100%); display:flex; flex-direction:column;
  background:var(--cream); color:var(--ink);
  transform:translateX(100%); transition:transform .4s var(--ease);
}
.cart.is-open .cart__panel{ transform:none; }
.cart__head{
  display:flex; align-items:center; justify-content:space-between;
  padding:20px 22px; border-bottom:1px solid var(--line);
}
.cart__title{
  font-family:var(--mono); font-size:11px; letter-spacing:.18em;
  font-weight:600; margin:0;
}
.cart__close{
  background:none; border:0; cursor:pointer; color:var(--ink);
  font-size:26px; line-height:1; padding:0 4px;
}
.cart__items{ flex:1 1 auto; overflow-y:auto; padding:6px 22px; }
.cart__empty{
  font-family:var(--mono); font-size:11px; letter-spacing:.12em;
  text-transform:uppercase; color:var(--muted); padding:28px 0;
}
.cart__row{
  display:grid; grid-template-columns:56px 1fr auto; gap:12px;
  align-items:center; padding:14px 0; border-bottom:1px solid var(--line);
}
.cart__row img{
  width:56px; height:56px; object-fit:cover; border-radius:8px;
  background:var(--cream-2);
}
.cart__rowName{ font-size:13px; font-weight:700; line-height:1.3; }
.cart__rowMeta{
  font-family:var(--mono); font-size:11px; color:var(--muted); margin-top:3px;
}
.cart__remove{
  background:none; border:0; cursor:pointer; color:var(--muted);
  font-family:var(--mono); font-size:10.5px; letter-spacing:.1em;
  text-transform:uppercase; padding:4px;
}
.cart__remove:hover{ color:var(--red); }
.cart__foot{ padding:18px 22px 24px; border-top:1px solid var(--line); }
.cart__totalRow{
  display:flex; justify-content:space-between; align-items:baseline;
  font-family:var(--mono); font-size:12px; letter-spacing:.1em;
  text-transform:uppercase; margin-bottom:6px;
}
.cart__total{ font-size:16px; font-weight:600; }
.cart__note{ font-size:11.5px; color:var(--muted); margin:0 0 14px; }
.cart__cta{ width:100%; justify-content:center; }
/* A real button, not a footnote - it is the way back to the store and gets
   used more often than checkout. */
.cart__back{
  display:block; width:100%; margin-top:12px; padding:15px 0;
  background:none; border:1px solid var(--ink); border-radius:100px;
  cursor:pointer;
  font-family:var(--mono); font-size:11px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--ink);
  transition:background .3s var(--ease), color .3s var(--ease);
}
.cart__back:hover{ background:var(--ink); color:var(--cream); }

/* The same way out, pinned at the top of the drawer where it is visible
   the moment it opens. */
.cart__backTop{
  display:flex; align-items:center; gap:8px;
  width:100%; padding:14px 22px; cursor:pointer;
  background:none; border:0; border-bottom:1px solid var(--line);
  font-family:var(--mono); font-size:10.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted); text-align:left;
}
.cart__backTop:hover{ color:var(--ink); }
/* Floating basket button - only appears once something is in the basket. */
.cartFab{
  position:fixed; right:18px; bottom:18px; z-index:80;
  display:none; align-items:center; gap:8px; cursor:pointer;
  font-family:var(--mono); font-size:11px; letter-spacing:.14em;
  padding:13px 20px; border-radius:100px;
  /* red outline: it is the only route into the basket now, so it needs to
     read as the live control on the page rather than another dark pill */
  background:var(--ink); color:var(--cream); border:2px solid var(--red);
  box-shadow:0 6px 22px rgba(14,14,14,.28);
}
.cartFab.is-on{ display:inline-flex; }

/* ======================= HOW IT'S RUN (07) ==================== */
/* Ink band between the cream store and the cream footer. Reference copy:
   set narrower and quieter than the pitch sections above it. */
.structure{
  background:var(--ink); color:var(--cream);
  /* same rhythm as every other section - this was the only one starting on a
     different top padding */
  padding:clamp(40px,5vh,64px) var(--pad) clamp(52px,7vh,88px);
}
.structure__head{
  font-size:clamp(42px,8vw,124px); line-height:.86;
  font-weight:700; letter-spacing:-.045em;
  margin:0 0 clamp(22px,3vw,36px);
}
.structure__body{ max-width:none; }
.structure__lede p{
  font-size:clamp(15px,1.7vw,17.5px); line-height:1.7;
  color:rgba(243,240,233,.82); margin:0 0 12px;
}
.structure__lede b{ color:var(--cream); font-weight:700; }

/* the three mechanisms - song, donations, merch */
.structure__list{
  list-style:none; margin:clamp(26px,3.4vw,40px) 0 0; padding:0;
  display:grid; gap:0;
}
.structure__item{
  padding:18px 0; border-top:1px solid var(--line-light);
}
.structure__item:last-child{ border-bottom:1px solid var(--line-light); }
.structure__item h3{
  font-family:var(--mono); font-size:11px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--red);
  margin:0 0 8px; font-weight:600;
}
.structure__item p{
  margin:0; font-size:14.5px; line-height:1.65;
  color:rgba(243,240,233,.78);
}
/* running costs - the smallest print on the page, but it has to be here */
.structure__note{
  margin:clamp(22px,2.8vw,32px) 0 0; max-width:none;
  font-size:12.5px; line-height:1.65; color:rgba(243,240,233,.5);
}

/* every direct child of a watermarked section sits above the mark */
.cause > *:not(.cause__rose){ position:relative; z-index:1; }

/* ---- rose watermark -------------------------------------------------
   Liam's rose, used as a background mark on the cream sections. Kept very
   low-contrast: it should register as texture on the page, not as an image
   competing with the copy. Sections using it need position:relative and
   their own content lifted above it. */
.cause__rose{
  position:absolute; z-index:0; pointer-events:none;
  width:auto; opacity:.055;
  /* the drawing is pure black line art, so it needs no filter on cream */
}
.cause__rose{
  top:clamp(-40px,-3vw,0px); right:clamp(-70px,-4vw,-20px);
  height:min(120%,880px);
}
@media (max-width:820px){
  .cause__rose{ height:min(70%,520px); opacity:.045; }
}

/* ============================ CAUSE ========================== */
/* single grid so the pull quote can sit beside the title on desktop and
   drop below the body on mobile, purely by reassigning grid areas */
.cause{
  /* relative + hidden: the rose watermark is absolutely positioned and
     deliberately overhangs the section's edge */
  position:relative; overflow:hidden;
  padding:clamp(40px,5vh,64px) var(--pad) clamp(56px,8vh,100px);
  display:grid; grid-template-columns:1fr;
  grid-template-areas:
    "kicker"
    "head"
    "body"
    "pull"
    "causes"
    "actions";
}
.cause > .kicker{ grid-area:kicker; }
.cause__causes{ grid-area:causes; }
.cause__head{
  grid-area:head;
  /* two lines, always. The markup breaks after "A SONG"; the lower minimum
     here stops "FOR A CAUSE" - the longer of the two - wrapping to a third
     line on narrow screens. */
  font-size:clamp(34px,8.2vw,142px); line-height:.86;
  font-weight:700; letter-spacing:-.045em;
  text-wrap:balance;
  margin-bottom:clamp(28px,3.4vw,50px);
}
.cause__body{
  grid-area:body;
  display:grid; grid-template-columns:1fr 1fr;
  gap:0 clamp(28px,5vw,80px);   /* no row gap: paragraphs set the rhythm */
  padding-top:clamp(24px,2.6vw,34px); border-top:1px solid var(--line);
}
.cause__byline{
  grid-column:1 / -1;
  font-family:var(--mono); font-size:10.5px;
  letter-spacing:.16em; text-transform:uppercase;
  color:#8A8578; margin:0 0 clamp(22px,2.6vw,32px);
}
.cause__col p{
  font-size:clamp(15px,1.15vw,17.5px); line-height:1.7;
  color:#33312D; margin-bottom:20px;
  /* wider measure so the text spreads with the page (both single-column
     and the 2-up layout) and reads in fewer lines - less scrolling */
  max-width:66ch;
}
/* the charity list, pulled out of the running prose into its own box so
   the names are scannable rather than buried in a sentence. FULL WIDTH,
   sitting below .cause__body rather than nested in a column - it used to
   live inside the right-hand column, but its ~7 fixed rows made that column
   much taller than the left one at wide viewports, leaving a big empty gap
   beside the shorter column. Full width removes the mismatch rather than
   padding the short column out with more text. Bolder card treatment
   (border + shadow + red accent bar) than the quiet version this replaced,
   since Ross wanted it to feel more like a "special" module than a plain
   aside - each entry is a real button that opens the cause panel. */
.cause__causes{
  /* min-width:0 overrides the grid-item default (min-width:auto), which
     otherwise sizes to CONTENT's min-content width - the nested 2-up
     .cause__causes-list grid needs ~190px per column at minimum (each
     tile's fixed logo+arrow chrome plus its longest unbreakable word), and
     without this override that requirement was propagating up and forcing
     the OUTER single-column .cause grid to ~412px on mobile, blowing out
     past the 335px content box and causing page-wide horizontal scroll -
     even though the tiles visually wrap and fit fine once given the room.
     Classic CSS Grid min-width:auto gotcha; verified fixed at 375px width. */
  min-width:0;
  margin-top:clamp(30px,3.6vw,46px);
  padding:clamp(22px,2.8vw,32px);
  background:var(--cream-2);
  border-radius:14px;
  border:1px solid var(--line);
  border-left:4px solid var(--red);
  box-shadow:0 16px 40px -20px rgba(14,14,14,.25);
}
.cause__causes-label{
  font-family:var(--mono); font-size:11px; font-weight:600; letter-spacing:.18em;
  text-transform:uppercase; color:var(--red);
  margin:0 0 clamp(16px,1.8vw,20px);
}
/* a responsive grid of self-contained cards, not a single stacked column -
   now that the box spans the full content width, one column of rows would
   leave the same wasted horizontal space it used to leave vertically */
.cause__causes-list{
  list-style:none; margin:0; padding:0;
  display:grid; grid-template-columns:repeat(2, 1fr);
  gap:10px;
}
/* min-width:0 here is the actual fix for the mobile overflow bug (see the
   long comment on .cause__causes above) - that override on the OUTER box
   wasn't enough on its own. Each <li> is ALSO a grid item (of this nested
   2-up grid) and carries the SAME min-width:auto default, sized to its
   button's min-content - fixing the outer box just moved the blowout down
   one level, to these tiles overflowing the now-correctly-sized box instead
   of the box overflowing the page. Confirmed live: this is what actually
   drops document.documentElement.scrollWidth back to exactly the viewport
   width at 375px, with no overflow left anywhere. */
.cause__causes-list li{ min-width:0; }
/* phones: the base/tablet default (2-up) squeezed longer names like "The Way
   Youth Zone" or "Great Ormond Street Hospital" down to one word per line -
   a single column reads far better at this width. Matches the site's other
   ≤560px "phone" breakpoint (the merch panel's full-screen cutoff). */
@media (max-width:560px){
  .cause__causes-list{ grid-template-columns:1fr; }
}
@media (min-width:640px){
  .cause__causes-list{ grid-template-columns:repeat(3, 1fr); }
}
@media (min-width:1081px){
  .cause__causes-list{ grid-template-columns:repeat(4, 1fr); }
}

/* the row itself is a <button> (script.js) - reset browser chrome first.
   Each is its own bordered tile now (a shared border-bottom divider, as
   the old single-column version used, doesn't make sense once entries can
   sit side by side). */
.cause__causes-item{
  display:flex; align-items:flex-start; gap:12px;
  width:100%; height:100%; padding:14px;
  font:inherit; text-align:left; color:inherit;
  background:var(--cream); border:1px solid var(--line); border-radius:10px;
  appearance:none; cursor:pointer;
  transition:background .25s var(--ease), border-color .25s var(--ease);
}
.cause__causes-item:hover,
.cause__causes-item:focus-visible{
  background:var(--cream); border-color:var(--red);
}
.cause__causes-item:focus-visible{ outline:2px solid var(--red); outline-offset:2px; }

.cause__causes-logo{
  flex:none; width:38px; height:38px; border-radius:9px;
  background:var(--cream-2);
  display:flex; align-items:center; justify-content:center; overflow:hidden;
}
.cause__causes-logo img{
  max-width:68%; max-height:68%; object-fit:contain;
  mix-blend-mode:multiply;
}
.cause__causes-copy{ display:flex; flex-direction:column; gap:2px; min-width:0; flex:1; }
.cause__causes-name{
  font-weight:700; font-size:14.5px;
  letter-spacing:-.01em; color:var(--ink); line-height:1.25;
}
.cause__causes-note{ font-size:11.5px; line-height:1.4; color:var(--muted); }

.cause__causes-arrow{
  flex:none; margin-top:2px;
  color:var(--muted); font-size:14px;
  transition:transform .3s var(--ease), color .3s var(--ease);
}
.cause__causes-item:hover .cause__causes-arrow,
.cause__causes-item:focus-visible .cause__causes-arrow{
  transform:translateX(3px); color:var(--red);
}
@media (prefers-reduced-motion:reduce){
  .cause__causes-arrow{ transition:none; }
}

.cause__pull{
  grid-area:pull;
  font-family:var(--sans) !important;
  font-size:clamp(20px,2.3vw,30px) !important;
  line-height:1.28 !important; font-weight:700; letter-spacing:-.025em;
  color:var(--ink) !important; padding-left:20px;
  border-left:2px solid var(--red);
  margin-top:clamp(24px,3vw,34px) !important; margin-bottom:0 !important;
}

/* desktop: two columns. The pull quote sits in the RIGHT column, aligned
   with the body text below it and bottom-aligned to the title. On mobile
   the areas restack so the pull drops below the body text instead. */
@media (min-width:821px){
  .cause{
    grid-template-columns:1fr 1fr;
    column-gap:clamp(28px,5vw,80px);
    /* `pull` used to sit beside the head, which is why the head only had
       half the width. That line is hidden (2026-08-24), so the head was
       being squeezed for a neighbour that no longer renders - and the
       longer "FOR A CAUSE" title then wrapped to three lines.
       Each on its own row now, so this holds up whether pull comes back
       or not. */
    grid-template-areas:
      "kicker  kicker"
      "head    head"
      "pull    pull"
      "body    body"
      "causes  causes"
      "actions actions";
    align-items:start;
  }
  .cause__head{ margin-bottom:0; }
  .cause__body{ margin-top:clamp(28px,3.4vw,50px); }
  .cause__pull{
    align-self:end;
    margin:0 0 clamp(8px,1vw,16px) !important;
    max-width:42ch;
  }
}

.stats{
  display:grid; grid-template-columns:repeat(3,1fr);
  gap:20px; margin-top:clamp(34px,4vw,56px);
  padding-top:clamp(24px,2.6vw,34px); border-top:1px solid var(--line);
}
.stat b{
  display:block; font-size:clamp(40px,5.5vw,80px);
  font-weight:700; letter-spacing:-.04em; line-height:1; color:var(--red);
}
.stat b span{ font-size:.45em; vertical-align:super; letter-spacing:0; }
.stat i{
  display:block; margin-top:10px; font-style:normal;
  font-family:var(--mono); font-size:10.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted);
}

/* same row as the hero's, so the two pages match */
.cause__actions{
  grid-area:actions;
  display:flex; flex-wrap:wrap; gap:12px;
  margin-top:clamp(30px,3.6vw,46px);
}

/* ============================= GIVE ========================== */
.give{
  background:var(--ink); color:var(--cream);
  padding:clamp(40px,5vh,64px) var(--pad) clamp(56px,8vh,100px);
}
.give__head{
  font-size:clamp(46px,9vw,142px); line-height:.86;
  font-weight:700; letter-spacing:-.045em;
  margin-bottom:clamp(28px,3.4vw,50px);
}
/* three ways to give: royalties / donate / merch */
.give__grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:18px; }

.card{
  position:relative; display:flex; flex-direction:column;
  padding:clamp(28px,3.4vw,48px);
  border:1px solid var(--line-light); border-radius:4px;
  background:rgba(243,240,233,.02);
  transition:background .5s var(--ease), transform .5s var(--ease), border-color .5s var(--ease);
  min-height:clamp(230px,25vw,310px);
  overflow:hidden;
  container-type:inline-size;   /* so the art shows only when the card itself is wide */
}
/* text content sits above the decorative art */
.card h3, .card p, .card__cta{ position:relative; z-index:1; }

/* decorative outlined line-art filling the empty right side of the card;
   hidden by default, shown only when the card is wide enough to have the
   dead space (container query - independent of column count / viewport) */
.card__art{
  position:absolute; z-index:0; pointer-events:none;
  top:50%; right:clamp(24px,3vw,52px); transform:translateY(-50%);
  width:clamp(150px,17cqw,220px);
  color:var(--cream); opacity:.2;
  display:none; transition:opacity .5s var(--ease);
}
.card__art svg{
  width:100%; height:auto; display:block;
  fill:currentColor; stroke:none;
}
/* front layers get a background-coloured halo so the overlapping
   icons read as separate, stacked pictures rather than one blob */
.card__art .lift{ stroke:var(--ink); stroke-width:5; stroke-linejoin:round; paint-order:stroke; }
.card:hover .card__art{ opacity:.34; }
@container (min-width:530px){ .card__art{ display:block; } }
.card:hover{ background:rgba(243,240,233,.055); transform:translateY(-4px); border-color:rgba(243,240,233,.3); }
.card--accent{ border-color:rgba(181,53,42,.55); }
.card--accent:hover{ background:var(--red); border-color:var(--red); }
.card--spotify{ border-color:rgba(29,185,84,.5); }
.card--spotify:hover{ background:var(--spotify); border-color:var(--spotify); }
/* merch card - cream fill on hover, the inverse of the other two, so the
   three cards don't all flood the same colour */
.card--merch{ border-color:rgba(243,240,233,.42); }
.card--merch:hover{ background:var(--cream); border-color:var(--cream); color:var(--ink); }
.card h3{
  font-size:clamp(30px,3.6vw,52px); font-weight:700;
  letter-spacing:-.035em; line-height:1; margin:0 0 16px;
}
.card p{
  font-size:14.5px; line-height:1.65; color:#B7B3AA; max-width:40ch;
  transition:color .4s var(--ease);
}
.card--accent:hover p,
.card--spotify:hover p{ color:rgba(243,240,233,.92); }
.card--merch:hover p{ color:rgba(14,14,14,.78); }
.card__cta{
  display:inline-flex; align-items:center; gap:8px;
  margin-top:auto; padding-top:30px;
  font-family:var(--mono); font-size:11px; letter-spacing:.16em; text-transform:uppercase;
}
.card__cta b{ transition:transform .4s var(--ease); display:inline-block; }
.card:hover .card__cta b{ transform:translate(3px,-3px); }

/* ============================ FOOTER ========================= */
.foot{
  background:var(--cream); color:var(--ink);
  padding:clamp(28px,3.6vh,48px) var(--pad) 24px;
  overflow:hidden;
}
.foot__top{
  display:flex; justify-content:center; align-items:center;
  gap:20px 30px; flex-wrap:wrap;
  /* condensed - this row carried three buttons and a link, now just the one
     control, so it no longer needs the depth */
  padding-bottom:clamp(14px,1.8vw,22px);
}
.foot__actions{ display:flex; gap:12px; flex-wrap:wrap; }
.foot__mail{
  font-size:clamp(20px,2.6vw,38px); font-weight:700; letter-spacing:-.03em;
  border-bottom:1px solid var(--line); padding-bottom:4px;
  transition:border-color .4s var(--ease), color .4s var(--ease);
}
.foot__mail:hover{ color:var(--red); border-color:var(--red); }
.foot__totop{
  /* centred - it is the only thing left on this row, so pinning it right
     left the footer opening on an off-balance line */
  margin:0 auto;
  display:inline-flex; align-items:center; gap:8px;
  font-family:var(--mono); font-size:10.5px; letter-spacing:.16em; text-transform:uppercase;
  color:var(--muted); background:none; border:0; padding:0; cursor:pointer;
  transition:color .3s var(--ease);
}
.foot__totop:hover{ color:var(--red); }
.foot__totop span{ font-size:13px; transition:transform .3s var(--ease); }
.foot__totop:hover span{ transform:translateY(-3px); }

/* "Get in touch" label above the big email; carries the divider that used
   to sit on the wordmark, so the label + email read as one group */
.foot__cue{
  border-top:1px solid var(--line);
  padding-top:clamp(18px,2.2vw,30px);
  margin:0 0 clamp(10px,1.1vw,16px);
}
.foot__word{
  display:block; color:var(--ink);
  /* the email is longer than the old wordmark, so a smaller vw keeps it
     on one line and spread across; the cap fits it inside the capped
     content column (--content-max) on wide screens without overflowing */
  font-size:clamp(22px,6.5vw,105px); line-height:.85;
  font-weight:700; letter-spacing:-.04em;
  white-space:nowrap; margin:0 0 22px;
  transition:color .4s var(--ease);
}
.foot__word:hover{ color:var(--red); }

/* ---- section collapse ---------------------------------------------- */
/* The arrow lives on the kicker line. Inline-flex so it sits on the
   baseline of the "01 - HOW IT WORKS" text next to it. */
.sec__toggle{
  display:inline-flex; align-items:center; justify-content:center;
  width:22px; height:22px; margin-left:10px; padding:0;
  vertical-align:middle; cursor:pointer;
  background:none; border:1px solid currentColor; border-radius:50%;
  color:inherit; opacity:.55;
  transition:opacity .25s var(--ease), transform .3s var(--ease);
}
.sec__toggle:hover{ opacity:1; }
.sec__toggle svg{
  width:13px; height:13px; fill:none;
  stroke:currentColor; stroke-width:2.4;
  stroke-linecap:round; stroke-linejoin:round;
  transition:transform .3s var(--ease);
}
/* arrow points up when the section is open (click to close), down when
   folded (click to open) */
.sec__toggle[aria-expanded="true"] svg{ transform:rotate(180deg); }

.sec__fold{
  /* grid-rows 1fr -> 0fr animates to the content's natural height, which a
     max-height guess cannot do across sections this different in length.
     Exactly one child (.sec__foldInner) so there is exactly one row. */
  display:grid; grid-template-rows:1fr;
  transition:grid-template-rows .45s var(--ease), opacity .3s var(--ease);
}
.sec__foldInner{ min-height:0; overflow:hidden; }
.is-folded .sec__fold{
  grid-template-rows:0fr; opacity:0; pointer-events:none;
}
/* a folded section is just its title, so pull the padding in too */
.is-folded{ padding-bottom:clamp(20px,2.4vw,28px) !important; }
@media (prefers-reduced-motion:reduce){
  .sec__fold{ transition:none; }
}

/* Follow and mailing list, centred under the big address. */
.foot__social{
  display:flex; flex-wrap:wrap; gap:10px; justify-content:center;
  margin:clamp(22px,3vw,34px) 0 clamp(18px,2.2vw,26px);
}
/* the row now carries the footer's actions, so the top bar is just the
   back-to-top control and pushes it to the right on its own */
.foot__top--bare{ justify-content:flex-end; }
.foot__ico{
  display:inline-flex; align-items:center; gap:8px;
  padding:9px 14px; border-radius:100px;
  border:1px solid var(--line); color:var(--ink); text-decoration:none;
  font-family:var(--mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase;
  transition:background .3s var(--ease), color .3s var(--ease),
             border-color .3s var(--ease);
}
.foot__ico svg{ width:14px; height:14px; flex:none; fill:currentColor; }
.foot__ico:hover{ background:var(--ink); border-color:var(--ink); color:var(--cream); }
/* matches the site's existing treatment for links that don't exist yet */
.foot__ico.is-pending{ opacity:.45; pointer-events:none; }

/* Legal block - the smallest type on the page, above the copyright line. */
.foot__legal{
  padding-top:clamp(18px,2.2vw,24px);
  border-top:1px solid var(--line);
  margin-bottom:clamp(16px,2vw,22px);
  text-align:center;
}
.foot__legal p{
  max-width:78ch; margin:0 auto 12px;
  font-size:11.5px; line-height:1.6; color:var(--muted);
}
.foot__legal b{ color:#3F3C37; font-weight:700; }
.foot__legalNav{
  display:flex; flex-wrap:wrap; gap:16px; justify-content:center;
}
.foot__legalNav a{
  font-family:var(--mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted); text-decoration:none;
  border-bottom:1px solid rgba(14,14,14,.25); padding-bottom:2px;
}
.foot__legalNav a:hover{ color:var(--ink); border-color:var(--ink); }
.foot__legalNav a.is-pending{ opacity:.5; pointer-events:none; }

.foot__bottom{
  display:flex; justify-content:space-between; gap:14px; flex-wrap:wrap;
  padding-top:20px; border-top:1px solid var(--line);
  font-family:var(--mono); font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--muted);
}

/* =========================== RESPONSIVE ====================== */
/* ---- squeezed: phone no longer fits beside title+rose ----
   Everything becomes one centred column: title+rose (larger, filling
   the width), text spread wide, phone centred below, buttons centred. */
@media (max-width:1080px){
  .hero__inner{
    display:flex; flex-direction:column; align-items:stretch;
    gap:var(--hero-gap);
  }
  .hero__head{ margin:0; }                 /* title left, rose right, both bigger via vw */
  .hero__lede{ max-width:none; }           /* text spreads across the page */
  .hero__art{
    align-self:center; margin:0;
    --phone-w:clamp(260px,42vw,380px);     /* bigger; dead space either side is fine */
  }
  .hero__actions{ justify-content:center; }
}

@media (max-width:820px){
  .nav .btn--sm{ display:none; }

  .player__grid{ grid-template-columns:1fr; }
  .foot__contact{ text-align:left; }

  .cause__body{ grid-template-columns:1fr; }
  .give__grid{ grid-template-columns:1fr; }
  .card{ min-height:0; }
  .stats{ grid-template-columns:1fr; gap:26px; }
  .stat{ display:flex; align-items:baseline; gap:16px; }
  .stat i{ margin-top:0; }
}

@media (max-width:540px){
  .nav__stat{ display:none; }              /* keep the top bar uncluttered on phones */
  .hero__actions{ justify-content:stretch; }
  .hero__actions .btn,
  .cause__actions .btn{ flex:1; justify-content:center; }
}

/* below ~360px (e.g. the old 320px iPhone SE) the bigger title floor above
   leaves the rose almost no room in the flex row - .hero__title is flex:none
   so it always takes its full intrinsic width first, and .hero__rose (flex:1
   1 auto) gets only whatever's left. First fix (reverting just the title's
   floor here) kept the rose visible but tiny at ~62px wide; Ross's call once
   he saw it at that size - a rose that small doesn't read as a flourish, so
   hide it instead and let the title run full-width. No squeeze left to
   protect against, so the title keeps the full 76px floor at every mobile
   width now, not just 361px+. */
@media (max-width:360px){
  .hero__rose{ display:none; }
}

/* ================= CENTRED CONTENT COLUMN ==================== */
/* Every section EXCEPT the hero is capped to --content-max and centred.
   max() keeps the normal --pad gutter until the viewport is wide enough
   that centring gives a larger gutter, so laptops are unchanged and only
   wide monitors get the extra (symmetric) side margin. Placed last so the
   longhand padding-inline wins over each section's `padding` shorthand.
   The hero is deliberately left full-bleed. */
.give,
.cause,
.record,
.donate,
.partners,
.merch,
.structure,
.foot{
  padding-inline:max(var(--pad), calc((100% - var(--content-max)) / 2));
}
