/* ==========================================================================
   Daisy Surf — daisysurf.com
   © 2026 Daisy Surf. All rights reserved.
   Unauthorized copying or reproduction of this site's design, code & content
   is prohibited.

   Every colour below was sampled from Alexandra's own files by extract-brand.py —
   the ink and the daisy centre straight out of the logo, Black Sands and Coconut
   Cream off the garments in her own photographs. Nothing here was picked by eye.
   ========================================================================== */

:root{
  --ink:        #101010;   /* densest ink in her logo file */
  --sands:      #2A2A2A;   /* her Black Sands tee fabric */
  --sands-2:    #333333;
  --cream:      #F4ECE4;   /* Coconut Cream — her fabric's hue at paper luminance */
  --cream-2:    #ECDDCE;
  --cream-dim:  #D6C6B4;
  --sand:       #B8A284;   /* wet sand from her tee photo, lifted for the dark ground */
  --marigold:   #D2902D;   /* the daisy centre, exactly */
  --marigold-d: #82591C;   /* same hue, darkened until it clears 4.5:1 on both creams */
  --ocean:      #8AAEB4;   /* the water behind her in the tee photo */
  /* Added 27 Sep so every page speaks the homepage's language. Derived from her own
     measured colours: --ocean lifted to a sky, --marigold lifted to a butter. */
  --sky:        #C4DEE4;
  --sky-2:      #9FC9D2;
  --sky-d:      #2E5A63;   /* the deep end of her blue */
  --butter:     #F7E3B0;
  --butter-2:   #F0D188;
  --on-bamboo:  #5A3C10;   /* text on the lifted bamboo footer */
  /* aliases so the shared nav (site/nav.py) resolves against this stylesheet too */
  --f-d:        var(--f-display);
  --f-m:        var(--f-lab);
  --marigold-br:#D2902D;
  --sea:        #017F95;
  --sea-deep:   #0A4A56;   /* the dark band colour: her water, not black */
  --marigold-lt:#E8B057;   /* her marigold, lifted for the deep band: 5.15:1 */
  --sea-cream:  #F4F1D0;
  --wood-1:     #7A5530;   /* darkened until cream body text clears 4.5:1 */
  --wood-2:     #654527;
  --wood-3:     #8A6337;
  --crit:       #C9503A;
  --good:       #5E9A6B;

  --body-ink:   #4A423A;
  --muted-ink:  #6A6055;

  --rule:       rgba(244,236,228,.15);
  --rule-2:     rgba(244,236,228,.08);
  --rule-ink:   rgba(16,16,16,.14);

  --f-display: "Oswald", "Helvetica Neue", Impact, sans-serif;
  /* the Club face from the homepage -- see .club h2 in build-home-v2.py */
  --f-fun:     "Chewy", "Fredoka", cursive;
  --f-body:    "Figtree", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, sans-serif;
  /* the label face -- was IBM Plex Mono, see build-home-v2.py. Every eyebrow,
     spec key, price and badge on the site goes through this one name. */
  --f-lab:     "Figtree", -apple-system, system-ui, sans-serif;

  --maxw: 1200px;
  --gut: 22px;
  --hdr: 74px;

  /* her artwork, as masks so every piece can take any brand colour */
  --m-petals:  url("../img/brand/daisy-petals.png?v=10d58259");
  --m-disc:    url("../img/brand/daisy-disc.png?v=4b6d4d78");
  --m-texture: url("../img/brand/daisy-texture.png?v=9f6b710a");
  --m-word:    url("../img/brand/wordmark.png?v=75d18446");
  --m-dash:    url("../img/brand/brush-dash.png?v=094fc92b");
  --m-sweep:   url("../img/brand/brush-sweep.png?v=95bab299");

  color-scheme: dark;
}

*{ box-sizing:border-box }

html{ scroll-behavior:smooth; }
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
}

body{
  margin:0;
  background:var(--sea-deep);
  color:var(--cream);
  font-family:var(--f-body);
  font-size:17px;
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

img{ max-width:100%; height:auto; display:block;
  -webkit-user-drag:none; user-select:none; -webkit-user-select:none; -webkit-touch-callout:none; }

a{ color:var(--marigold); text-decoration-thickness:1px; text-underline-offset:3px; }
a:hover{ color:var(--cream); }

:focus-visible{ outline:3px solid var(--marigold); outline-offset:3px; border-radius:2px; }

[hidden]{ display:none !important; }

.wrap{ max-width:var(--maxw); margin:0 auto; padding-inline:var(--gut); }
.wrap-n{ max-width:820px; margin:0 auto; padding-inline:var(--gut); }

.skip{
  position:absolute; left:-9999px; top:0; z-index:200;
  background:var(--marigold); color:var(--ink); padding:12px 20px;
  font-family:var(--f-lab); font-size:13px; font-weight:600;
}
.skip:focus{ left:0; }

/* ---------- type ---------- */
h1,h2,h3,h4{
  /* 600 to match "THE COLLECTION" on the homepage -- the family was already the same,
     it was the weight that made the inner pages read lighter. */
  font-family:var(--f-display); font-weight:600; text-transform:uppercase;
  letter-spacing:.045em; line-height:1.08; margin:0; text-wrap:balance;
}
h1{ font-size:clamp(34px,6.4vw,68px); font-weight:600; }
h2{ font-size:clamp(26px,4.2vw,42px); }
h3{ font-size:clamp(18px,2.4vw,23px); }
h4{ font-size:16px; letter-spacing:.07em; }
p{ margin:0 0 16px; }

.eyebrow{
  font-family:var(--f-lab); font-size:11.5px; letter-spacing:.22em;
  text-transform:uppercase; color:var(--marigold); margin:0 0 14px; font-weight:500;
}
.eyebrow-dim{ color:var(--sand); }
.lede{ font-size:clamp(17px,2vw,20px); color:var(--cream-dim); max-width:62ch; }

/* ---------- acid-wash texture (their actual product finish) ---------- */
.acid{ position:relative; isolation:isolate; }
.acid::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background-image:url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='300' height='300'>\
<filter id='a'><feTurbulence type='fractalNoise' baseFrequency='.012 .02' numOctaves='4' seed='7'/>\
<feColorMatrix values='0 0 0 0 .55 0 0 0 0 .52 0 0 0 0 .47 0 0 0 .5 0'/></filter>\
<rect width='300' height='300' filter='url(%23a)'/></svg>");
  background-size:520px 520px;
  opacity:.5; mix-blend-mode:soft-light;
}

/* ---------- header ---------- */
.hdr{
  position:sticky; top:env(safe-area-inset-top,0px); z-index:100;
  background:rgba(16,16,16,.93);
  backdrop-filter:saturate(140%) blur(10px);
  border-bottom:1px solid var(--rule-2);
}
.hdr-in{
  max-width:var(--maxw); margin:0 auto; padding-inline:var(--gut);
  height:var(--hdr); display:flex; align-items:center; gap:18px;
}
.nav{ display:flex; gap:2px; margin-left:auto; align-items:center; }
.nav a{
  font-family:var(--f-display); font-size:14px; letter-spacing:.11em; text-transform:uppercase;
  color:var(--cream-dim); text-decoration:none; padding:9px 13px; border-radius:2px;
  transition:color .18s, background .18s;
}
.nav a:hover,.nav a[aria-current="page"]{ color:var(--marigold); background:rgba(244,236,228,.05); }
.nav a[aria-current="page"]{ color:var(--marigold); }

.burger{
  display:none; margin-left:auto; background:none; border:1px solid var(--rule);
  color:var(--cream); width:42px; height:38px; border-radius:2px; cursor:pointer;
  align-items:center; justify-content:center; padding:0;
}
.burger span{ display:block; width:18px; height:1.5px; background:currentColor; position:relative; }
.burger span::before,.burger span::after{
  content:""; position:absolute; left:0; width:18px; height:1.5px; background:currentColor;
}
.burger span::before{ top:-5.5px } .burger span::after{ top:5.5px }

/* The old dark header's mobile drawer lived here and was never removed when the bar
   moved to site/nav.py. It still matched `.nav` under 920px and set overflow-y:auto,
   which clips an absolutely positioned child to the bar's own 83px box -- so on every
   inner page the menu opened, reported display:flex and eight visible links, and was
   clipped out of existence. The DOM said open; the screen showed nothing and the
   links could not be clicked.
   Deleted, not overridden: there is no drawer any more and nothing should match. */


/* ==========================================================================
   Her mark, rebuilt from the logo file.
   Three stacked alpha masks share one box, so they always register exactly:
   the marigold disc, her dark brush texture over it, and the petals around it.
   Because they are masks and not images, the petals take whatever colour the
   surface needs — cream on ink, ink on cream — from one piece of artwork.
   ========================================================================== */
.daisy{
  position:relative; display:inline-block; flex-shrink:0;
  aspect-ratio:512/407; width:1em;
  color:var(--cream);                 /* petal colour — set this to retint */
}
.daisy::before,.daisy::after,.daisy i{
  content:""; position:absolute; inset:0;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
  -webkit-mask-size:100% 100%; mask-size:100% 100%;
}
.daisy::before{ background:var(--marigold);
  -webkit-mask-image:var(--m-disc); mask-image:var(--m-disc); }
.daisy i{ background:var(--marigold); display:block;
  -webkit-mask-image:var(--m-texture); mask-image:var(--m-texture); }
.daisy::after{ background:currentColor;
  -webkit-mask-image:var(--m-petals); mask-image:var(--m-petals); }
.sec-cream .daisy{ color:var(--ink); }

/* her brush wordmark, same trick */
.wordmark{
  display:block; aspect-ratio:604/344; width:100%;
  background:currentColor;
  -webkit-mask:var(--m-word) no-repeat center/contain;
  mask:var(--m-word) no-repeat center/contain;
}

/* the dash from under SURF in her lockup, used as a rule */
.brush-rule{
  display:block; height:9px; width:112px; background:var(--marigold);
  -webkit-mask:var(--m-dash) no-repeat left center/contain;
  mask:var(--m-dash) no-repeat left center/contain;
  margin:0 0 18px;
}
.brush-rule.c{ margin-inline:auto; -webkit-mask-position:center; mask-position:center; }
.sec-cream .brush-rule{ background:var(--marigold-d); }

/* eyebrow flanked by her dashes, the way her lockup sets "— SURF —" */
.eyebrow-brush{ display:flex; align-items:center; gap:11px;
  width:fit-content; max-width:100%; }
.eyebrow-brush::before,.eyebrow-brush::after{
  content:""; height:7px; flex:0 0 34px; background:currentColor; opacity:.85;
  -webkit-mask:var(--m-dash) no-repeat center/100% 100%;
  mask:var(--m-dash) no-repeat center/100% 100%;
}
.eyebrow-brush::after{ transform:scaleX(-1); }
.eyebrow-brush.solo::after{ display:none }

/* a large, quiet daisy watermark behind a section */
.daisy-wash{ position:relative; isolation:isolate; overflow:hidden; }
.daisy-wash > .daisy{
  position:absolute; z-index:-1; width:min(52vw,520px); pointer-events:none;
  right:-9%; top:50%; transform:translateY(-50%) rotate(-8deg); opacity:.055;
}
.sec-cream .daisy-wash > .daisy{ opacity:.075; }

/* header lockup */
.logo{ display:flex; align-items:center; gap:12px; text-decoration:none; flex-shrink:0; }
.logo .daisy{ width:40px; }
.logo .wordmark{ width:104px; color:var(--cream); }
.logo:hover .daisy{ color:var(--marigold); }
@media (max-width:420px){ .logo .wordmark{ width:88px } }

/* ---------- section join: her brush, swept across the boundary ----------
   Not a torn-paper edge — her brand's texture is brush, so the two sections meet
   on a clean line and her actual stroke is drawn over the join. The stroke is a
   mask, so the dry-brush grain and tapered ends survive. */
.sweep{
  display:block; width:100%; height:clamp(26px,4vw,46px);
  background:currentColor; margin:0; pointer-events:none;
  -webkit-mask:var(--m-sweep) no-repeat center/100% 100%;
  mask:var(--m-sweep) no-repeat center/100% 100%;
}
.sweep.flip{ transform:scaleX(-1); }
/* the sweep sits at the top of the section it brushes into, pulled up so the
   stroke straddles the join instead of sitting below it */
.sweep-wrap{ position:relative; line-height:0; overflow:hidden;
  height:clamp(26px,4vw,46px); }
.sweep-wrap > .sweep{ position:absolute; inset:auto 0 auto 0;
  top:calc(clamp(26px,4vw,46px) * -0.42); }

/* ---------- hero ---------- */
.hero{ position:relative; background:var(--sea-deep); }
.hero-media{ position:relative; min-height:clamp(440px,74vh,700px); overflow:hidden; }
.hero-media img{
  position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:50% 42%;
}
/* Side-weighted scrim.
   The darkening is pulled to the LEFT, behind the text, and to a thin band on the
   right edge — so the middle of the photograph, where the daisy on the back of the
   tee actually sits, stays open. A full-width bottom scrim was burying the one thing
   the picture is of. Verified against the real composited pixels, not the tokens. */
.hero-media::after{
  content:""; position:absolute; inset:0;
  background:
    /* the wedge that carries the text */
    linear-gradient(95deg,
      rgba(16,16,16,.95) 0%, rgba(16,16,16,.90) 30%, rgba(16,16,16,.74) 42%,
      rgba(16,16,16,.30) 52%, rgba(16,16,16,.05) 62%, rgba(16,16,16,0) 70%,
      rgba(16,16,16,.10) 90%, rgba(16,16,16,.40) 100%),
    /* just enough top and bottom to seat the header and the join */
    linear-gradient(180deg,
      rgba(16,16,16,.46) 0%, rgba(16,16,16,0) 26%,
      rgba(16,16,16,0) 66%, rgba(16,16,16,.50) 100%);
}
.hero-body{
  position:absolute; inset:auto 0 0 0; z-index:2;
  max-width:var(--maxw); margin:0 auto; padding:0 var(--gut) clamp(38px,6vw,70px);
  left:0; right:0;
}
/* a soft pool under the text block only — anchored left, gone by mid-frame */
.hero-body::before{
  content:""; position:absolute; z-index:-1; pointer-events:none;
  left:calc(var(--gut) * -1); right:38%; bottom:0; top:-90px;
  background:linear-gradient(180deg,
    rgba(16,16,16,0) 0%, rgba(16,16,16,.30) 34%, rgba(16,16,16,.46) 100%);
  -webkit-mask-image:linear-gradient(90deg, #000 0%, #000 62%, transparent 100%);
  mask-image:linear-gradient(90deg, #000 0%, #000 62%, transparent 100%);
}

/* Narrow screens crop the photo and the text runs nearly edge to edge, so a
   side-weighted wedge has nothing to hide behind. Go back to a bottom scrim there. */
@media (max-width:860px){
  .hero-media::after{
    background:linear-gradient(180deg,
      rgba(16,16,16,.52) 0%, rgba(16,16,16,.20) 26%,
      rgba(16,16,16,.58) 56%, rgba(16,16,16,.86) 80%, rgba(16,16,16,.94) 100%);
  }
  .hero-body::before{
    right:0; left:0; top:-110px;
    background:linear-gradient(180deg,
      rgba(16,16,16,0) 0%, rgba(16,16,16,.60) 20%,
      rgba(16,16,16,.86) 46%, rgba(16,16,16,.92) 100%);
    -webkit-mask-image:none; mask-image:none;
  }
}
/* The copy has to stay inside the dark wedge — if a line runs past it, it ends up
   over blown-out sand. These caps are what the wedge can actually cover. */
.hero h1{ color:#fff; text-shadow:0 2px 26px rgba(16,16,16,.65);
  max-width:min(15ch, 430px); }
.hero h1 em{ font-style:normal; color:#F0B849; }
.hero .sub{
  color:#F4EEE3; font-size:clamp(16px,2.1vw,20px); max-width:min(44ch, 430px); margin:18px 0 26px;
  text-shadow:0 1px 14px rgba(16,16,16,.8);
}
.hero .eyebrow{ color:#F3E3C4; text-shadow:0 1px 10px rgba(16,16,16,.9);
  white-space:nowrap; }
@media (max-width:860px){
  .hero h1,.hero .sub{ max-width:none; }
  .hero h1{ max-width:15ch; } .hero .sub{ max-width:44ch; }
}
@media (max-width:520px){
  .hero .eyebrow{ white-space:normal; }
  .hero .eyebrow-brush::after{ display:none; }
}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:9px;
  font-family:var(--f-display); font-size:14.5px; letter-spacing:.13em; text-transform:uppercase;
  padding:14px 28px; border-radius:2px; border:1.5px solid var(--marigold);
  background:var(--marigold); color:var(--ink); text-decoration:none; cursor:pointer;
  font-weight:500; transition:background .18s,color .18s,border-color .18s;
}
.btn:hover{ background:#EFB43F; border-color:#EFB43F; color:var(--ink); }
.btn-ghost{ background:transparent; color:var(--cream); border-color:rgba(244,236,228,.42); }
.btn-ghost:hover{ background:rgba(244,236,228,.1); color:#fff; border-color:var(--cream); }
.btn-ink{ background:var(--sea); border-color:var(--sea); color:#fff; }
.btn-ink:hover{ background:var(--marigold-d); border-color:var(--marigold-d); color:#fff; }
.btn[disabled]{ opacity:.45; cursor:not-allowed; }
.btn-row{ display:flex; flex-wrap:wrap; gap:12px; }

/* ---------- sections ---------- */
.sec{ padding-block:clamp(56px,8vw,92px); }
.sec-cream{ background:var(--cream); color:var(--ink); }
.sec-cream h1,.sec-cream h2,.sec-cream h3,.sec-cream h4{ color:var(--ink); }
.sec-cream .lede{ color:#4A423A; }
.sec-cream .eyebrow{ color:var(--marigold-d); }
.sec-cream a{ color:var(--marigold-d); }
.sec-sands{ background:var(--sea-deep); }   /* was near-black */

.sec-head{ margin-bottom:clamp(30px,4vw,46px); }
.sec-head .num{
  font-family:var(--f-lab); font-size:12px; letter-spacing:.2em; color:var(--marigold);
  display:block; margin-bottom:10px;
}
.sec-cream .sec-head .num{ color:var(--marigold-d); }

/* ---------- product grid ---------- */
/* auto-fit collapses the tracks nothing lands in, so a collection holding one
   product -- which is every collection she has right now -- stretched that single
   card across the whole page: a 980px photograph where a 300px card belongs.
   auto-fill keeps the tracks, and the one-card case gets a column of its own,
   centred, instead of a lone card stranded at the left. */
.pgrid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(252px,1fr)); gap:clamp(18px,2.4vw,30px); }
.pgrid:not(:has(> .card:nth-child(2))){
  grid-template-columns:minmax(252px,340px); justify-content:center; }
.card{ text-decoration:none; color:inherit; display:flex; flex-direction:column; }
.card-img{
  position:relative; aspect-ratio:4/5; overflow:hidden; background:var(--sky);
  /* the arch Alexandra asked for, same shape as the homepage tiles */
  border-radius:999px 999px 8px 8px;
}
.pgrid .card:nth-child(4n+2) .card-img{ background:var(--butter); }
.pgrid .card:nth-child(4n+3) .card-img{ background:var(--cream-dim); }
.pgrid .card:nth-child(4n+4) .card-img{ background:var(--sky-2); }
.card-img img{
  width:100%; height:100%; object-fit:cover;
  transition:transform .55s cubic-bezier(.2,.7,.3,1);
}
.card:hover .card-img img{ transform:scale(1.045); }
.card-tag{
  /* NOT top-left: .card-img is an arch (border-radius:999px 999px) with
     overflow:hidden, so a badge in the top corner gets sliced by the curve --
     on a phone it read as "...LEFT" with the front chopped off. The bottom
     edge is straight, so the badge is whole at every card width. */
  position:absolute; bottom:10px; left:10px; z-index:2;
  font-family:var(--f-lab); font-size:10px; letter-spacing:.14em; text-transform:uppercase;
  padding:4px 9px; border-radius:2px; background:var(--sea); color:#fff;
}
.card-tag.low{ background:var(--crit); color:#fff; }
.card-body{ padding-top:14px; display:flex; flex-direction:column; gap:4px; }
.card-name{
  font-family:var(--f-display); font-size:19px; letter-spacing:.055em; text-transform:uppercase;
  line-height:1.15;
}
.card-blurb{ font-size:14.5px; color:var(--cream-dim); line-height:1.5; }
.sec-cream .card-blurb{ color:#5B5147; }
.card-price{
  font-family:var(--f-lab); font-size:14.5px; margin-top:5px; font-variant-numeric:tabular-nums;
  color:var(--marigold);
}
.sec-cream .card-price{ color:var(--marigold-d); }

/* ---------- split story ---------- */
.split{ display:grid; grid-template-columns:1fr 1fr; gap:clamp(26px,5vw,66px); align-items:center; }
@media (max-width:860px){ .split{ grid-template-columns:1fr } }
.split-img{ border-radius:2px; overflow:hidden; aspect-ratio:4/5; }
.split-img img{ width:100%; height:100%; object-fit:cover; }

.badges{ display:flex; flex-wrap:wrap; gap:10px; margin:22px 0 0; padding:0; list-style:none; }
.badge{
  font-family:var(--f-lab); font-size:11px; letter-spacing:.14em; text-transform:uppercase;
  border:1px solid currentColor; color:var(--marigold); padding:6px 12px; border-radius:2px;
}
.sec-cream .badge{ color:var(--marigold-d); }

/* ---------- club ---------- */
/* The Club band's own rules now live at the foot of this file, ported from the
   homepage so both carry the same band. */

input,select,textarea{
  font-family:var(--f-body); font-size:16px; color:var(--cream);
  background:rgba(244,236,228,.06); border:1px solid var(--rule);
  border-radius:2px; padding:13px 15px; width:100%;
}
input::placeholder,textarea::placeholder{ color:var(--sand); }
input:focus,select:focus,textarea:focus{ border-color:var(--marigold); outline:none;
  box-shadow:0 0 0 3px rgba(224,163,43,.22); }
.sec-cream input,.sec-cream select,.sec-cream textarea{
  background:rgba(16,16,16,.045); border-color:var(--rule-ink); color:var(--ink);
}
.sec-cream input::placeholder,.sec-cream textarea::placeholder{ color:#696056; }
label{ display:block; font-family:var(--f-lab); font-size:11px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--sand); margin-bottom:7px; }
.sec-cream label{ color:#6A6055; }
.field{ margin-bottom:18px; }

/* ---------- PDP ---------- */
.pdp{ display:grid; grid-template-columns:1.06fr 1fr; gap:clamp(26px,4vw,58px); align-items:start; }
@media (max-width:900px){ .pdp{ grid-template-columns:1fr } }
.gal-main{ aspect-ratio:4/5; border-radius:2px; overflow:hidden; background:var(--sands-2); }
.gal-main img{ width:100%; height:100%; object-fit:cover; }
.gal-thumbs{ display:flex; gap:9px; margin-top:9px; flex-wrap:wrap; }
.gal-thumbs button{
  width:66px; aspect-ratio:1; padding:0; border:1.5px solid transparent; border-radius:2px;
  overflow:hidden; background:var(--sands-2); cursor:pointer;
}
.gal-thumbs button[aria-current="true"]{ border-color:var(--marigold); }
.gal-thumbs img{ width:100%; height:100%; object-fit:cover; }

.pdp-price{
  font-family:var(--f-display); font-size:30px; color:var(--marigold);
  font-variant-numeric:tabular-nums; margin:6px 0 20px; letter-spacing:.02em;
}
.optgrp{ margin-bottom:20px; }
.optgrp .lab{
  font-family:var(--f-lab); font-size:11px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--sand); margin-bottom:9px; display:flex; justify-content:space-between; gap:10px;
}
.optgrp .lab em{ font-style:normal; color:var(--cream); }
.opts{ display:flex; flex-wrap:wrap; gap:8px; }
.opt{
  font-family:var(--f-lab); font-size:13px; letter-spacing:.06em;
  min-width:52px; padding:10px 14px; border-radius:2px; cursor:pointer;
  border:1px solid var(--rule); background:transparent; color:var(--cream);
  transition:border-color .15s,background .15s,color .15s;
}
.opt:hover{ border-color:var(--cream-dim); }
.opt[aria-pressed="true"]{ background:var(--cream); color:var(--ink); border-color:var(--cream); }
.opt.out{ color:var(--sand); border-style:dashed; }
.opt.out::after{ content:" · out"; font-size:10.5px; letter-spacing:.08em; }
.opt.out[aria-pressed="true"]{ background:rgba(201,80,58,.16); color:var(--cream);
  border-color:var(--crit); border-style:solid; }
.swatch{ display:flex; align-items:center; gap:9px; }
.swatch i{ width:16px; height:16px; border-radius:50%; border:1px solid var(--rule);
  display:inline-block; flex-shrink:0; }

.stockline{
  font-family:var(--f-lab); font-size:12.5px; letter-spacing:.05em;
  display:flex; align-items:center; gap:9px; margin:0 0 18px;
}
.stockline i{ width:8px; height:8px; border-radius:50%; background:var(--good); display:inline-block; }
.stockline.out i{ background:var(--crit); }
.stockline.out{ color:#E79B87; }

/* back-in-stock — the fix for the audit's biggest conversion leak */
.bis{
  border:1px solid var(--crit); border-left-width:3px; border-radius:2px;
  background:rgba(201,80,58,.09); padding:20px; margin-bottom:20px;
}
.bis h4{ color:var(--cream); margin-bottom:8px; }
.bis p{ font-size:14.5px; color:var(--cream-dim); margin-bottom:14px; }
.bis form{ display:flex; gap:9px; flex-wrap:wrap; }
.bis input{ flex:1 1 190px; }
.bis .ok{ color:var(--good); font-family:var(--f-lab); font-size:13.5px; margin:0; }

.specs{ list-style:none; padding:0; margin:24px 0 0; border-top:1px solid var(--rule-2); }
.specs li{ display:flex; gap:16px; padding:12px 0; border-bottom:1px solid var(--rule-2); font-size:15px; }
.specs .k{ font-family:var(--f-lab); font-size:11px; letter-spacing:.13em; text-transform:uppercase;
  color:var(--sand); flex:0 0 108px; padding-top:3px; }
.specs .v{ color:var(--cream-dim); }

.acc{ border-top:1px solid var(--rule-2); }
.acc details{ border-bottom:1px solid var(--rule-2); }
.acc summary{
  cursor:pointer; padding:16px 0; font-family:var(--f-display); font-size:15px;
  letter-spacing:.07em; text-transform:uppercase; list-style:none; display:flex;
  justify-content:space-between; align-items:center; gap:12px;
}
.acc summary::-webkit-details-marker{ display:none }
.acc summary::after{ content:"+"; font-family:var(--f-lab); color:var(--marigold); font-size:18px; }
.acc details[open] summary::after{ content:"\2013"; }
.acc .acc-body{ padding:0 0 18px; color:var(--cream-dim); font-size:15px; }
.sec-cream .acc .acc-body{ color:#5B5147; }

/* ---------- tables ---------- */
.tw{ overflow-x:auto; border:1px solid var(--rule); border-radius:2px; }
table{ border-collapse:collapse; width:100%; min-width:440px; font-size:15px; }
th{
  font-family:var(--f-lab); font-size:10.5px; letter-spacing:.14em; text-transform:uppercase;
  color:var(--sand); text-align:left; padding:13px 16px; background:var(--sands-2);
  border-bottom:1px solid var(--rule); font-weight:500; white-space:nowrap;
}
td{ padding:13px 16px; border-bottom:1px solid var(--rule-2); color:var(--cream-dim);
  font-variant-numeric:tabular-nums; }
tr:last-child td{ border-bottom:0 }
.sec-cream th{ background:var(--cream-2); color:#6A6055; border-bottom-color:var(--rule-ink); }
.sec-cream td{ color:#4A423A; border-bottom-color:rgba(16,16,16,.09); }
.sec-cream .tw{ border-color:var(--rule-ink); }

/* ---------- prose ---------- */
.prose{ max-width:68ch; }
.prose p{ margin-bottom:20px; }
.prose h2{ margin:44px 0 16px; }
.prose h3{ margin:34px 0 12px; }
.prose ul,.prose ol{ margin:0 0 20px; padding-left:22px; color:var(--cream-dim); }
.sec-cream .prose ul,.sec-cream .prose ol{ color:#4A423A; }
.prose li{ margin-bottom:9px; }
.prose blockquote{
  margin:28px 0; padding:4px 0 4px 22px; border-left:3px solid var(--marigold);
  font-size:19px; color:var(--cream);
}
.sec-cream .prose blockquote{ color:var(--ink); }

/* ---------- pop-ups ---------- */
.evt{ display:grid; grid-template-columns:150px 1fr; gap:6px 24px; padding:22px 0;
  border-bottom:1px solid var(--rule-2); }
@media (max-width:640px){ .evt{ grid-template-columns:1fr } }
.evt .when{ font-family:var(--f-lab); font-size:13px; color:var(--marigold); letter-spacing:.06em; }
.evt .what{ font-family:var(--f-display); font-size:19px; letter-spacing:.05em; text-transform:uppercase; }
.evt .where{ color:var(--cream-dim); font-size:15px; }
.evt .note{ grid-column:2; color:var(--sand); font-size:14px; }
@media (max-width:640px){ .evt .note{ grid-column:1 } }

/* ---------- footer ---------- */
/* The footer's rules moved to site/footer.py, which both builders emit, so the
   homepage and the inner pages cannot drift apart again. */
.socials{ display:flex; gap:14px; }
.socials a{ font-family:var(--f-lab); font-size:12px; letter-spacing:.12em; text-transform:uppercase; }

/* ---------- announcement bar ---------- */
.ann{
  background:var(--marigold); color:var(--ink); text-align:center;
  font-family:var(--f-lab); font-size:12px; letter-spacing:.11em; text-transform:uppercase;
  padding:9px var(--gut); font-weight:500;
}
.ann a{ color:var(--ink); text-decoration:underline; }

/* ---------- review mode (?review=1) ---------- */
.rv-bar,.rv-panel{ display:none }
body.rv [data-verify]{ outline:2px dashed var(--marigold); outline-offset:3px;
  background:rgba(224,163,43,.1); }
body.rv .rv-bar{
  display:flex; position:fixed; left:0; right:0; bottom:0; z-index:190;
  background:var(--marigold); color:var(--ink); align-items:center; gap:14px; flex-wrap:wrap;
  padding:11px var(--gut); padding-bottom:calc(11px + env(safe-area-inset-bottom,0px));
  font-family:var(--f-lab); font-size:12.5px; letter-spacing:.06em;
}
body.rv .rv-bar b{ font-weight:600 }
body.rv .rv-bar button{
  margin-left:auto; background:var(--sea); color:#fff; border:0; cursor:pointer;
  font-family:var(--f-lab); font-size:12px; letter-spacing:.1em; text-transform:uppercase;
  padding:8px 15px; border-radius:2px;
}
body.rv .rv-panel[data-open="1"]{
  display:block; position:fixed; inset:auto 0 0 0; z-index:191; max-height:74vh; overflow-y:auto;
  background:var(--sands); border-top:3px solid var(--marigold);
  padding:26px var(--gut) calc(78px + env(safe-area-inset-bottom,0px));
}
.rv-panel h3{ margin-bottom:6px }
.rv-panel .rv-q{ border-top:1px solid var(--rule-2); padding:16px 0; }
.rv-panel .rv-q .id{ font-family:var(--f-lab); font-size:10.5px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--marigold); }
.rv-panel .rv-q p{ margin:6px 0 0; font-size:15px; }
.rv-panel .rv-q .why{ color:var(--sand); font-size:13.5px; }

/* ==========================================================================
   Cream-surface overrides.
   The component styles above are written for the dark "Black Sands" ground.
   Anything that also appears inside .sec-cream needs its own colours, or it
   renders cream-on-cream and disappears.
   ========================================================================== */
.sec-cream .opt{ color:var(--ink); border-color:rgba(16,16,16,.26); }
.sec-cream .opt:hover{ border-color:var(--ink); }
.sec-cream .opt[aria-pressed="true"]{ background:var(--sea); color:#fff; border-color:var(--sea); }
.sec-cream .opt.out{ color:#696056; border-color:rgba(16,16,16,.2); }
.sec-cream .opt.out[aria-pressed="true"]{ background:rgba(201,80,58,.14); color:#7E2B1A;
  border-color:var(--crit); }
.sec-cream .swatch i{ border-color:rgba(16,16,16,.28); }

.sec-cream .optgrp .lab{ color:#6A6055; }
.sec-cream .optgrp .lab em{ color:var(--ink); }
.sec-cream .pdp-price{ color:var(--marigold-d); }

.sec-cream .stockline{ color:#3F5C46; }
.sec-cream .stockline.out{ color:#8E3A26; }

.sec-cream .bis h4{ color:var(--ink); }
.sec-cream .bis p{ color:#5B5147; }
.sec-cream .bis{ background:rgba(201,80,58,.08); }

.sec-cream .specs{ border-top-color:var(--rule-ink); }
.sec-cream .specs li{ border-bottom-color:rgba(16,16,16,.1); }
.sec-cream .specs .k{ color:#6A6055; }
.sec-cream .specs .v{ color:#4A423A; }

.sec-cream .acc,.sec-cream .acc details{ border-color:rgba(16,16,16,.12); }
.sec-cream .acc summary{ color:var(--ink); }
.sec-cream .acc summary::after{ color:var(--marigold-d); }

.sec-cream .gal-main,.sec-cream .gal-thumbs button{ background:var(--cream-2); }
.sec-cream .gal-thumbs button[aria-current="true"]{ border-color:var(--ink); }

.sec-cream .card-img{ background:var(--cream-2); }
.sec-cream .card-tag{ background:var(--sea); color:#fff; }

/* .sec-cream a is more specific than .btn-* — restate button colours or links win */
.sec-cream .btn{ color:var(--ink); }
.sec-cream .btn-ink{ color:#fff; }
.sec-cream .btn-ink:hover{ color:#fff; }
.sec-cream .btn-ghost{ color:var(--ink); border-color:rgba(16,16,16,.34); }
.sec-cream .btn-ghost:hover{ background:rgba(16,16,16,.07); color:var(--ink); border-color:var(--ink); }

.sec-cream .evt{ border-bottom-color:rgba(16,16,16,.1); }
.sec-cream .evt .when{ color:var(--marigold-d); }
.sec-cream .evt .where{ color:#5B5147; }
.sec-cream .evt .note{ color:#6A6055; }

.sec-cream .badge{ color:var(--marigold-d); }
.sec-cream .sec-head .num{ color:var(--marigold-d); }

/* ---------- utility ---------- */
.mt0{margin-top:0}.mb0{margin-bottom:0}
.center{ text-align:center }
.muted{ color:var(--sand); font-size:14px; }
.sec-cream .muted{ color:#6A6055; }
.vh{ position:absolute!important; width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap }
.flow > * + *{ margin-top:18px }

/* a typeset sign-off — her name set in the display face, never a facsimile signature */
.signoff{
  font-family:var(--f-display); font-size:17px; letter-spacing:.09em; text-transform:uppercase;
  color:var(--marigold-d); margin-top:26px; padding-top:18px;
  border-top:1px solid var(--rule-ink); display:inline-block;
}
.sec-sands .signoff,.sec-cream .sec-sands .signoff{ color:var(--marigold); border-top-color:var(--rule); }

/* If a browser can't do mask-image, an unmasked element would paint as a solid
   block — worse than nothing. Hide the mark and show a typeset fallback instead.
   The accessible name lives on aria-label either way, so nothing is lost. */
.logo .wordmark-fallback{ display:none;
  font-family:var(--f-display); font-weight:600; font-size:20px; letter-spacing:.11em;
  color:var(--cream); text-transform:uppercase; line-height:1; }
@supports not ((-webkit-mask-image: url(#a)) or (mask-image: url(#a))){
  .daisy,.wordmark,.brush-rule,.sweep,.eyebrow-brush::before,.eyebrow-brush::after{ display:none; }
  .logo .wordmark-fallback{ display:block; }
  .sweep-wrap{ display:none; }
}

/* -----------------------------------------------------------------------
   Accents on the deep band.
   Her marigold measures 3.65:1 on --sea-deep, which is short for small text.
   --marigold-lt is the same hue lifted until it clears 4.5:1 (5.15:1 measured).
   Declared at the END: this stylesheet is dark-first and the component rules
   sit further down than the section, so an override beside the section loses.
   ----------------------------------------------------------------------- */
.sec-sands .eyebrow,.sec-sands .num,.sec-sands .badge,
.sec-sands a,.sec-sands .signoff{ color:var(--marigold-lt); }
.sec-sands .badge{ border-color:var(--marigold-lt); }
.sec-sands a:hover{ color:#fff; }
.sec-sands .fine{ color:var(--cream-dim); }   /* --sand was 4.02:1 here */

/* -----------------------------------------------------------------------
   Nothing small, and nothing brown, on a light ground.
   Prefixed with `body` on purpose: the rules being overridden are two-class
   selectors (.sec-cream .eyebrow, .specs .k, .sec-head .num), which outrank a
   single class no matter where it sits in the file. `body .x .y` clears them.
   The deep blue band keeps its own light text, further down.
   ----------------------------------------------------------------------- */
body .eyebrow,body .eyebrow-dim,body .num,body .sec-head .num,
body .sec-cream .eyebrow,body .sec-cream .eyebrow-dim{
  font-size:16px; letter-spacing:.13em; font-weight:500; color:var(--ink); }
body .k,body .specs .k{ font-size:15px; letter-spacing:.09em; color:var(--ink); }
body .fine,body .muted,body .stockline,body .breadcrumbs,
body .opt,body .swatch,body .optgrp .lab,body .optgrp .lab a{
  font-size:15px; color:var(--ink); }
body .socials a{ font-size:15px; }
body .skip{ font-size:15px; }
body a.size-link,body .sec-cream a.size-link{ font-size:15px; color:var(--ink); }

/* the deep blue band is dark -- its text stays light */
body .sec-sands .eyebrow,body .sec-sands .eyebrow-dim,body .sec-sands .num,
body .sec-sands .k,body .sec-sands .opt,body .sec-sands .badge,
body .sec-sands a,body .sec-sands .signoff{ color:var(--marigold-lt); }
body .sec-sands .fine,body .sec-sands .muted,
body .sec-sands .stockline{ color:var(--cream-dim); }
body .sec-sands .card-tag,body .card-tag{ color:#fff; font-size:14px; }
body .swatch{ color:inherit; }
/* the label row carries the size-guide link inside it; sizing the row sizes both */
body .optgrp .lab,body .optgrp .lab *{ font-size:15px; }

/* the collection line above a product title: her wording, at a size you can read */
body .collection-line{ font-family:var(--f-display); text-transform:uppercase;
  letter-spacing:.1em; font-size:clamp(18px,2.2vw,24px); font-weight:600;
  color:var(--ink); margin:0 0 10px; }
body .sec-sands .collection-line{ color:var(--marigold-lt); }
/* the footer carries her flower only -- no wordmark beneath it */


/* -----------------------------------------------------------------------
   Products: the money and the spec rows, 30 Sep.
   Ryan: "make the amounts black coloured and make sure fabric size colour all
   that is in black and no super skinny text." They were her marigold-dark and
   her muted ink -- brown, not black -- and set at 400 in a condensed display
   face and a mono, which is what read as skinny.

   These carry `body` AND the ground class because what they replace are
   three-class selectors (.sec-cream .specs .k, .sec-cream .pdp-price): a
   shorter selector loses to those no matter how late it sits in the file.
   The label rows used to stop at 500 because IBM Plex Mono was only loaded at
   400 and 500 and a 600 would have been faked. They are Figtree now, which is
   loaded to 600, so the price carries the same weight as the one on the product
   page -- which is what "no super skinny text" asked for in the first place.
   ----------------------------------------------------------------------- */
body .pdp-price,body .sec-cream .pdp-price{ color:var(--ink); font-weight:600; }
body .card-price,body .sec-cream .card-price{ color:var(--ink); font-weight:600;
  font-size:15.5px; }
body .optgrp .lab,body .optgrp .lab em,body .sec-cream .optgrp .lab,
body .specs .k,body .sec-cream .specs .k,
body .opt,body .sec-cream .opt{ color:var(--ink); font-weight:500; }
body .specs .v,body .sec-cream .specs .v,
body .stockline,body .sec-cream .stockline{ color:var(--ink); font-weight:500; }
body .acc summary,body .sec-cream .acc summary{ font-weight:500; }
/* the status still reads at a glance -- the dot keeps the colour the words gave up */
body .stockline i{ width:10px; height:10px; }

/* the deep blue band is dark: its text stays light, at the same weights */
body .sec-sands .card-price,body .sec-sands .pdp-price,
body .sec-sands .optgrp .lab,body .sec-sands .optgrp .lab em,
body .sec-sands .specs .k,body .sec-sands .opt{ color:var(--marigold-lt); }
body .sec-sands .specs .v,body .sec-sands .stockline{ color:var(--cream-dim); }

/* -----------------------------------------------------------------------
   The primary button, 30 Sep. Ryan: "should this be so dark? I think she'd
   want pastel yellow." It was her marigold at full strength -- a solid tan
   slab on the cream. Her butter is the pastel of that same hue and is already
   in the palette.

   A pastel fill on a cream page is 1.27:1 against it, which is not enough for
   a control to show its own edge (WCAG 1.4.11 asks 3:1), so the button keeps a
   real border in --marigold-d: 5.27:1 on the cream, 4.17:1 on the fill. The
   label stays ink at 13:1.

   :not() on the two variants on purpose -- .btn-ink and .btn-ghost are single
   classes and would lose to anything longer, and their colours are their own.
   ----------------------------------------------------------------------- */
body .btn:not(.btn-ghost):not(.btn-ink),
body .sec-cream .btn:not(.btn-ghost):not(.btn-ink){
  background:var(--butter-2); border:2px solid var(--marigold-d); color:var(--ink); }
body .btn:not(.btn-ghost):not(.btn-ink):hover,
body .sec-cream .btn:not(.btn-ghost):not(.btn-ink):hover{
  background:var(--marigold-lt); border-color:var(--marigold-d); color:var(--ink); }
/* .45 on a pastel took the label under 4.5:1 -- say "off" with the border and a
   muted-but-legible ink instead of by fading the whole control out */
body .btn[disabled]{ opacity:1; background:var(--cream-2); border-style:dashed;
  color:var(--muted-ink); }

/* -----------------------------------------------------------------------
   Product spec keys, 30 Sep. Ryan: "make this text the same as the
   'The Collection' text." FABRIC / SIZE / DETAIL / MADE were IBM Plex Mono
   at 15px; they now carry the same declaration as .collection-line above —
   same family, weight, tracking and clamp — so the two read as one voice.

   The key column has to grow with them: at 24px Oswald with .1em tracking
   "FABRIC" is ~130px and the old 108px column wrapped it.
   Specificity: .sec-cream .specs .k is three classes and outranks anything
   shorter wherever it sits, so these carry `body` and the ground class.
   ----------------------------------------------------------------------- */
body .specs .k,body .sec-cream .specs .k{
  font-family:var(--f-display); text-transform:uppercase; letter-spacing:.1em;
  font-size:clamp(18px,2.2vw,24px); font-weight:600; color:var(--ink);
  flex:0 0 clamp(120px,15vw,164px); padding-top:0; }
body .specs .v,body .sec-cream .specs .v{ padding-top:3px; }
@media (max-width:560px){
  body .specs li{ flex-direction:column; gap:2px; }
  body .specs .k,body .sec-cream .specs .k{ flex:0 0 auto; }
}
body .sec-sands .specs .k{ color:var(--marigold-lt); }

/* -----------------------------------------------------------------------
   Product card titles, 30 Sep. "TEES - OG COLLECTION" was reading brown on
   the cream — the card is an <a>, so it was inheriting the link colour
   rather than stating one. Ink, like every other title on the page.
   The deep blue band keeps its own light text.
   ----------------------------------------------------------------------- */
body .card-name,body .sec-cream .card-name,body a.card .card-name{ color:var(--ink); }
body .sec-sands .card-name{ color:var(--marigold-lt); }

/* -----------------------------------------------------------------------
   The kicker above a page title ("Tees" over SURF TEES), 30 Sep.
   It was --marigold-d at 16px: brown, and small against a 64px heading.
   Ink and 20px. `.sec-cream .num` is two classes and outranked the earlier
   `body .num`, which is why that one never took.
   ----------------------------------------------------------------------- */
body .num,body .sec-cream .num,body .sec-head .num,body .sec-cream .sec-head .num,
body .eyebrow,body .sec-cream .eyebrow{
  color:var(--ink); font-size:clamp(17px,1.7vw,20px); font-weight:600;
  letter-spacing:.14em; }
body .sec-sands .num,body .sec-sands .eyebrow{ color:var(--marigold-lt); }

/* an option that cannot be bought should not behave as though it can */
body .opt[disabled],body .opt[aria-disabled="true"]{ cursor:not-allowed; opacity:1; }

/* -----------------------------------------------------------------------
   The About page, built to Alexandra's own sketch (30 Sep). She drew it:
   a yellow strapline under the hero, her brand copy on cream, her curl
   waves, then her story with the collage film beside it and three badges
   underneath.
   ----------------------------------------------------------------------- */
.strapline{ background:var(--butter-2); color:var(--ink); text-align:center;
  padding:clamp(16px,2.4vw,26px) var(--gut,20px); }
.strapline p{ margin:0 auto; max-width:46ch; font-family:var(--f-display);
  text-transform:uppercase; letter-spacing:.1em; font-weight:600;
  font-size:clamp(15px,2vw,21px); line-height:1.35; }

.story-with-film{ display:grid; grid-template-columns:minmax(0,300px) minmax(0,1fr);
  gap:clamp(22px,3.5vw,44px); align-items:start; max-width:none; }
.story-with-film .film{ position:sticky; top:96px; }
.collage{ width:100%; height:auto; display:block; border-radius:3px;
  background:#fff; box-shadow:0 14px 34px rgba(16,16,16,.16); }
@media (max-width:820px){
  .story-with-film{ grid-template-columns:1fr; }
  .story-with-film .film{ position:static; max-width:320px; margin:0 auto; }
}
/* Woman-owned · Veteran-owned · Est 2026, the way she boxed them */
.creds{ list-style:none; display:flex; flex-wrap:wrap; gap:10px; padding:0;
  margin:26px 0 0; }
.creds li{ font-family:var(--f-lab); font-size:13.5px; letter-spacing:.14em;
  text-transform:uppercase; border:1.6px solid var(--marigold-d); border-radius:99px;
  padding:7px 15px; color:var(--ink); }
.sec-sands .creds li{ color:var(--marigold-lt); border-color:var(--marigold-lt); }

/* -----------------------------------------------------------------------
   The About hero, brighter at the top, 30 Sep.
   It carried 46% black across the whole top edge purely so a see-through
   header could sit on it. Ryan wants that gone and the picture open.
   The header goes solid on this page instead, which is what the darkening
   was buying, and then nothing needs to be laid over the top of her photo
   at all. The wedge behind the heading stays — that one is carrying text.
   ----------------------------------------------------------------------- */
.hero-lit .hero-media::after{
  background:
    linear-gradient(95deg,
      rgba(16,16,16,.95) 0%, rgba(16,16,16,.90) 30%, rgba(16,16,16,.74) 42%,
      rgba(16,16,16,.30) 52%, rgba(16,16,16,.05) 62%, rgba(16,16,16,0) 70%,
      rgba(16,16,16,.10) 90%, rgba(16,16,16,.40) 100%),
    linear-gradient(180deg,
      rgba(16,16,16,0) 0%, rgba(16,16,16,0) 66%, rgba(16,16,16,.50) 100%);
}
@media (max-width:760px){
  .hero-lit .hero-media::after{
    background:linear-gradient(180deg,
      rgba(16,16,16,0) 0%, rgba(16,16,16,.18) 40%, rgba(16,16,16,.62) 100%);
  }
}
/* the bar that the top scrim used to seat */
body:has(.hero-lit) .nav{ background:rgba(251,245,237,.96);
  backdrop-filter:blur(8px); box-shadow:0 1px 0 var(--rule); }
body:has(.hero-lit) .nav .links a,
body:has(.hero-lit) .nav .icon,
body:has(.hero-lit) .nav .burger{ color:var(--ink); text-shadow:none; filter:none; }
body:has(.hero-lit) .nav .navmark .on-video{ display:none; }
body:has(.hero-lit) .nav .navmark .on-cream{ display:block; }
body:has(.hero-lit) .nav.up{ transform:none; }

/* -----------------------------------------------------------------------
   About, 30 Sep: the heading off the photograph entirely.
   It sat on a wedge that ran to 95% black down the left-hand side, purely
   so white type could live there — which is a lot of darkness to spend on
   two words. The title is set on cream above the picture now, the way the
   collection pages already do it, and the photograph carries no scrim at
   all: her own colour, full width, top to bottom.
   ----------------------------------------------------------------------- */
.page-head{ padding:calc(clamp(30px,5vw,56px) + 84px) 0 clamp(22px,3.4vw,34px); }
/* +84px: the bar is position:fixed, and this block is the first thing on the page,
   so without it the eyebrow sits underneath the header. Every other page begins
   with a hero the bar is meant to float over. */
.page-head h1{ margin:6px 0 0; font-size:clamp(34px,6vw,64px); color:var(--ink); }
.hero-plain .hero-media::after{ background:none; }
.hero-plain .hero-media img{ object-position:50% 38%; }
@media (max-width:760px){
  .hero-plain .hero-media::after{ background:none; }
}

/* -----------------------------------------------------------------------
   The option label row, 30 Sep.
   It was justify-content:space-between with the size-guide link buried in
   the label's own text, so the row read "Size Size guide" hard left and
   threw the chosen value to the far right, where a size reads as a stray
   letter rather than as an answer. Label and value now sit together as a
   pair; the guide is a link of its own, pushed right, with a real hit area.
   ----------------------------------------------------------------------- */
body .optgrp .lab{ display:flex; align-items:baseline; gap:8px;
  justify-content:flex-start; flex-wrap:wrap; }
body .optgrp .lab .lab-k::after{ content:":"; }
body .optgrp .lab em{ font-style:normal; font-weight:600; color:var(--ink); }
body .sec-sands .optgrp .lab em{ color:var(--marigold-lt); }
body .optgrp .lab .size-link{ margin-left:auto; text-decoration:underline;
  text-underline-offset:3px; padding:4px 0; color:var(--ink); }
body .sec-sands .optgrp .lab .size-link{ color:var(--marigold-lt); }
body .optgrp .lab .size-link:focus-visible{ outline:3px solid var(--marigold-br);
  outline-offset:3px; border-radius:2px; }

/* -----------------------------------------------------------------------
   Product gallery, 30 Sep. The frame was 4:5 with object-fit:cover, which
   is fine for a portrait photograph and ruinous for anything wider. Her
   flat shots are two tees side by side at 1.80 — in a 0.80 frame, cover
   showed 44% of the picture, so a customer saw one shirt, cut in half.
   Measured across her set: 44%, 46%, 53%, 60%, 60%, 63%, 63%.

   A square frame and `contain` instead: nothing is ever cropped, whatever
   shape she shoots next, and both orientations waste a similar amount of
   room. The thumbnails keep `cover` — at 66px a crop is the right call.
   ----------------------------------------------------------------------- */
body .gal-main{ aspect-ratio:1/1; background:var(--cream-2); }
body .sec-cream .gal-main{ background:var(--cream-2); }
body .sec-sands .gal-main{ background:var(--sands-2); }
body .gal-main img{ object-fit:contain; }

/* -----------------------------------------------------------------------
   Breathing room inside the gallery frame, 30 Sep.
   `contain` stops a picture being cropped, but it does not stop one that
   bleeds to its own edge from looking cropped: her studio flats have a
   garment touching all four sides of the file (measured: 0px margin top,
   bottom, left and right), so they filled the frame corner to corner and
   read as cut off.

   Padding the frame floats every photograph in the middle with a clear
   margin, whatever shape it is and whatever she sends next. The padding is
   the frame's own colour, so a lifestyle shot just sits slightly smaller
   rather than gaining a visible border.
   ----------------------------------------------------------------------- */
body .gal-main img{ padding:6%; box-sizing:border-box; }
body .gal-thumbs button img{ padding:5%; box-sizing:border-box; object-fit:contain; }

/* -----------------------------------------------------------------------
   Main product image — centring and padding, 30 Sep.

   The frame was a square panel in --cream-2 with the picture contained
   inside a 6% inset. The inset is uniform, but the LETTERBOX is not, and
   the panel painted it: her photographs run from 0.56 to 1.50, so measured
   against the reserved box the gap to the picture was

       tote-2   0.57   side 93px   top 23px     (4.0x)
       tote     0.75   side 64px   top 23px     (2.8x)
       tee flat 1.00   side 23px   top 23px
       towel    1.50   side 23px   top 78px     (3.4x)

   -- a tinted band up to four times wider on one axis than the other, and
   the bag itself down to 44% of the frame. Swiping the gallery, the picture
   jumped size and the box around it never did.

   So the panel now wraps the picture instead of the picture sitting in the
   panel. The box keeps aspect-ratio:1/1, so the space reserved is unchanged
   and nothing on the page shifts as you swipe; the image is absolutely
   centred inside it and carries the panel on its own background, which
   makes the padding literally the same number on all four sides of every
   photograph -- 13px at this width, measured, for all four above. What is
   left over is page, not a band.

   inset:0 + margin:auto rather than a flex/grid centre: a percentage
   max-height does not resolve on a grid item here, and the 0.57 shots
   overflowed the box by 70% of its height. Measured that, then fixed it.

   Nothing is cropped or stretched -- width and height stay auto under both
   max constraints, so the ratio is the browser's to keep, and object-fit
   still contains. The thumbnails are untouched.
   ----------------------------------------------------------------------- */
body .gal-main,
body .sec-cream .gal-main,
body .sec-sands .gal-main{ position:relative; background:transparent; }

body .gal-main img{
  position:absolute; inset:0; margin:auto;
  width:auto; height:auto; max-width:100%; max-height:100%;
  object-fit:contain; object-position:center;
  /* a percentage padding resolves against the frame's width on all four
     sides, so one value really is the same gap top, bottom, left, right */
  padding:clamp(10px,3.4%,22px); box-sizing:border-box;
  background:var(--cream-2); border-radius:2px;
}
body .sec-sands .gal-main img{ background:var(--sands-2); }

/* -----------------------------------------------------------------------
   About page: her ALOHA board, and the strapline band.  1 Oct.

   The board replaces the towel photograph at the top of the page -- her own
   layout sketch puts it there. It is a painting, so it is contained rather
   than cropped: at 1.78 in a 3.3-wide banner, cover would have taken
   "DAISY SURF" off the top and "CHASE YOUR ADVENTURE" off the bottom, which
   is most of what it says.
   ----------------------------------------------------------------------- */
/* +84px, the same allowance .page-head carries: the bar is position:fixed and
   this band is now the first thing on the page, so without it the top of the
   sign -- "DAISY SURF" -- sits underneath the header. It was 46px under it. */
.plate-band{ padding:calc(clamp(26px,4vw,52px) + 84px) var(--gut,20px)
  clamp(26px,4vw,52px); }
.plate-band figure{ margin:0 auto; max-width:1000px; }
.plate-band img{
  display:block; width:100%; height:auto;          /* its own 16:9, never cropped */
  border-radius:4px;
}

/* The strapline was a static block two lines deep. It is now the same device as
   the blue band on the homepage: one line, moving. Two identical runs sit side
   by side and the pair slides -50%, so it loops with no seam -- and the phrase
   repeats inside each run, because one short sentence twice is narrower than a
   desktop viewport and the gap would cross the screen.

   Height: 13px of padding on a 15px line, against clamp(16px,2.4vw,26px) on a
   line that wrapped to two -- about a third of what it was.

   The real sentence stays in the page for a screen reader; the moving copy is
   aria-hidden so it is not read four times over. */
.strapline{ padding:0; overflow:hidden; }
.strapline .st-run{ display:flex; width:max-content; animation:st-slide 48s linear infinite; }
.strapline .st-run span{
  font-family:var(--f-display); text-transform:uppercase; letter-spacing:.1em;
  font-weight:600; font-size:15px; line-height:1; padding:13px 0;
  white-space:nowrap; color:var(--ink);
}
@keyframes st-slide{ from{ transform:translateX(0) } to{ transform:translateX(-50%) } }
@media (prefers-reduced-motion:reduce){ .strapline .st-run{ animation:none } }

/* -----------------------------------------------------------------------
   "Aloha, I'm Alexandra", 1 Oct. Her name moves onto its own line under the
   greeting, and the heading is set in the Club face from the foot of the
   homepage. Chewy ships at 400 only, so it is lighter than the 600 Oswald it
   replaces without having to ask for a weight that does not exist.
   ----------------------------------------------------------------------- */
.hi-alex{ font-family:var(--f-fun); font-weight:400; letter-spacing:.01em;
  line-height:1.02; }

/* -----------------------------------------------------------------------
   Daisy Surf Club, on every page.  1 Oct.

   The homepage had her sea-blue band with the stickers; every other page got
   a plain dark panel headed "First access, before it's public". Ryan asked
   for the one band throughout, so this is the homepage's own CSS, ported
   from build-home-v2.py. The two are deliberately the same rules, keyed to
   the same class names, so a change to one is a change you can carry across
   by reading it.

   build-site.py emits it from footer(), not from each page's body, which is
   why there is no page that can be written without it.
   ----------------------------------------------------------------------- */
.club{ background:var(--sea); padding:74px 0 80px; position:relative;
  overflow:hidden; text-align:center; }
/* Her stickers sit at the margins, behind the panel, and go away on a phone
   where there is no margin for them to sit in. `translate` rather than
   `transform` for the drift, so each keeps the angle it was pinned at. */
.club .sc{ position:absolute; display:block; height:auto; z-index:1;
  pointer-events:none; filter:drop-shadow(0 8px 18px rgba(4,40,48,.30));
  animation:bob 9s ease-in-out infinite alternate; }
.club .s1{ top:9%; left:5.2%; width:104px; rotate:-12deg }        /* surfboard */
.club .s2{ top:8%; right:4%; width:86px; rotate:11deg; animation-delay:1.1s }
.club .s3{ bottom:26%; right:17%; width:76px; rotate:7deg; animation-delay:2.2s }
.club .s4{ bottom:6%; right:3%; width:118px; rotate:-9deg; animation-delay:.6s }
.club .s5{ bottom:11%; left:10%; width:92px; rotate:5deg; animation-delay:1.7s }
@keyframes bob{ from{ translate:0 -5px } to{ translate:0 6px } }
@media (prefers-reduced-motion:reduce){ .club .sc{ animation:none } }
@media (max-width:980px){ .club .sc{ display:none } }

.club-in{ position:relative; z-index:2; max-width:640px; margin:0 auto; }
.club h2{ font-family:var(--f-fun); font-weight:400; text-transform:uppercase;
  letter-spacing:.01em; font-size:clamp(42px,8vw,78px); color:var(--sea-cream);
  line-height:.98; text-align:center; }
.club p{ margin:16px auto 0; max-width:46ch; color:#fff; }
.club form{ display:flex; gap:10px; justify-content:center; margin-top:24px;
  flex-wrap:wrap; max-width:none; }
.club input{ flex:1 1 280px; max-width:360px; font:inherit; font-size:16px;
  padding:14px 16px; border:2px solid var(--sea-cream); border-radius:2px;
  background:#fff; color:var(--ink); }
.club input:focus-visible{ outline:3px solid var(--marigold); outline-offset:1px; }
.club button{ font-family:var(--f-display); text-transform:uppercase;
  letter-spacing:.1em; font-size:14px; font-weight:500; padding:14px 30px;
  background:var(--sea-cream); color:var(--ink); border:2px solid var(--sea-cream);
  border-radius:2px; cursor:pointer; }
.club button:hover{ background:#fff; border-color:#fff; color:var(--ink); }
.club button:focus-visible{ outline:3px solid var(--marigold-d); outline-offset:2px; }
/* .92 alpha measured 4.23:1 on her water; full white is 4.70 */
.club .small{ font-size:14px; color:#fff; margin-top:12px; }

/* -----------------------------------------------------------------------
   Product page, from Alexandra's list of 1 Oct.

   White ground, a light-yellow mount round the photograph, and her light
   pastel blue on the selected size and colour.

   The section keeps .sec-cream so that every light-ground rule written for
   it still applies -- the ink headings, the darker lede, the option borders.
   Only the ground itself changes, which is the whole of what she asked for;
   swapping the class instead would have taken the text colours with it.
   ----------------------------------------------------------------------- */
body .pdp-sec{ background:#fff; }
/* the mount round the picture, light yellow instead of the cream it was */
body .pdp-sec .gal-main img,
body .pdp-sec .sec-cream .gal-main img{ background:var(--butter); }
body .pdp-sec .gal-thumbs button{ background:var(--butter); }
/* Selected size / colour: her light pastel blue. Ink on it measures 13.52:1,
   where the white that sat on her teal would have been 2.1:1 on this. */
body .pdp-sec .opt[aria-pressed="true"],
body .pdp-sec.sec-cream .opt[aria-pressed="true"]{
  background:var(--sky); color:var(--ink); border-color:var(--sky-2,#9FC9D2);
}

/* -----------------------------------------------------------------------
   The scrolling strip, to Alexandra's note of 1 Oct: her wording, the Club's
   face, cream-light-yellow type on a blue block.

   Her two colours together do not work. Cream-light-yellow (#F4F1D0) on light
   pastel blue (#C4DEE4) measures 1.23:1, where large text needs 3:1 -- the
   words would have been very nearly invisible on the block. Her TEXT colour is
   kept exactly and the block goes a few steps deeper into the same blue, which
   measures 6.65:1 and matches the Club band at the foot of every page, so it
   still reads as hers. The alternatives are in the message that came with this.
   ----------------------------------------------------------------------- */
body .strapline{ background:var(--sky-d,#2E5A63); }
body .strapline .st-run span{
  font-family:var(--f-fun); font-weight:400; letter-spacing:.02em;
  font-size:17px; color:var(--sea-cream);
}

/* The About page's badges, same note: body face, sentence case, no tracking.
   Keeping the pill, losing the label styling that set it apart from the copy. */
body .badge{
  font-family:var(--f-body,var(--f-b)); font-size:14px; letter-spacing:0;
  text-transform:none; border-radius:99px; padding:6px 14px;
}

/* -----------------------------------------------------------------------
   Her postcard, on the About page.  1 Oct.

   The words are part of the picture -- it is her own hand-lettered artwork of
   the same five paragraphs that are in site/data.py, checked against them word
   for word. Text inside an image cannot be read by Google, selected, or spoken
   by a screen reader, so the real paragraphs stay in the page alongside it.

   They are hidden where the postcard is big enough to read and shown where it
   is not: at 760px the card is under 500px wide and its lettering falls below
   9px, which is nobody's idea of readable. Below that breakpoint the card stays
   as the picture it is and the story is set underneath in real type.
   ----------------------------------------------------------------------- */
.postcard{ margin:30px auto 0; max-width:820px; }
.postcard img{ display:block; width:100%; height:auto; border-radius:3px; }
.postcard-words{
  position:absolute; width:1px; height:1px; overflow:hidden;
  clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
}
@media (max-width:760px){
  .postcard-words{
    position:static; width:auto; height:auto; overflow:visible;
    clip:auto; clip-path:none; white-space:normal; margin-top:30px;
  }
}

/* -----------------------------------------------------------------------
   The women-owned panel on the About page.  1 Oct.
   Centred and measured, the motto in the Club face, her badges along the
   foot. What this replaced was a left-aligned paragraph floating in a band
   with 120px of nothing under it, and a second band below that holding four
   badges in 250px of mostly empty cream.
   ----------------------------------------------------------------------- */
.statement .wrap-n{ text-align:center; max-width:780px; }
.statement .brush-rule{ margin-left:auto; margin-right:auto; }
.statement h2{ margin:14px 0 0; font-size:clamp(28px,4.4vw,50px); }
.statement p{ margin:18px auto 0; max-width:56ch; }
.statement .statement-line{
  font-family:var(--f-fun); font-weight:400; letter-spacing:.01em; line-height:1.12;
  font-size:clamp(23px,3.1vw,34px); color:var(--sea-cream); margin-top:30px;
}
.statement .badges{ justify-content:center; margin-top:32px; }
/* cream on her water, like the Club band -- the marigold the badges carry on
   cream drops too far on this ground */
.statement .badge{ color:var(--sea-cream); border-color:rgba(244,241,208,.45); }

/* Belt and braces. Every other review rule is scoped to .rv-panel, so when a broken
   build left .rv-q orphaned at body level nothing hid it and internal copy rendered on
   the live site. This catches the orphan WITHOUT hiding the real questions inside the
   panel -- an orphan is always a direct child of <body>, a real one never is. */
body > .rv-q{ display:none !important; }

/* ---------------------------------------------------------------------------
   FIRST SECTION MUST CLEAR THE FIXED TOP BAR
   The bar is position:fixed and 72px tall, so it paints OVER the start of
   <main>. `.sec` top padding is fluid -- clamp(56px,8vw,92px) -- and on a phone
   8vw is only 30px, so it lands on the 56px floor: 16px LESS than the bar. The
   breadcrumb is the first thing in main, so its top was sliced clean off on
   every page. Desktop escaped only by luck (8vw = 82px at 1024px), which is why
   it reads fine on a laptop and wrong on a phone -- exactly as Alexandra found.
   max() keeps the fluid scale but puts a floor under it that the bar cannot
   reach. Same idea as .plate-band's "+ 84px" on the About page.
   The homepage is deliberately exempt: its hero is full-bleed under a
   transparent bar, which is the intended design.
   --------------------------------------------------------------------------- */
main > .sec:first-child{ padding-top:max(clamp(56px,8vw,92px), 88px); }

/* ---------------------------------------------------------------------------
   Alexandra's notes, 16 Oct 2026.
   --------------------------------------------------------------------------- */

/* "On the Shop page change the background to white" (and the same on Contact).
   Added ALONGSIDE .sec-cream rather than replacing it: that class also sets the
   ink, link, label and field colours this content needs, and only the background
   is meant to change. Sits after .sec-cream so it wins at equal specificity. */
.sec-white{ background:#fff; }

/* "Change the product image border to the same light yellow as the shop the drop
   button" -- that button is var(--butter). The border goes on an element that is
   already overflow:hidden with the arch radius, so it follows the arch. */
.card-img{ border:2px solid var(--butter); }

/* "Make sure the add to bag button is that same light yellow. And either remove
   the border around that button or make it black." Taking the second option: the
   fill is --butter now (matching the hero button exactly), and a pastel fill on a
   cream page is only 1.27:1 against it, so a control with no border of its own
   would fail WCAG 1.4.11's 3:1. Ink gives 13:1 and is one of the two she offered. */
body .btn:not(.btn-ghost):not(.btn-ink),
body .sec-cream .btn:not(.btn-ghost):not(.btn-ink){
  background:var(--butter); border:2px solid var(--ink); color:var(--ink);
}
body .btn:not(.btn-ghost):not(.btn-ink):hover,
body .sec-cream .btn:not(.btn-ghost):not(.btn-ink):hover{
  background:var(--butter-2); border-color:var(--ink);
}
