/* Shop (12 Sep 2026) – on top of ../page.css. Editorial: big type, big photographs, asymmetric grids, one idea a screen.
   Sand ground like every other page (Nuo, 12 Sep); colour comes from the cans themselves.

   THE FOUR MOTIONS, AND WHERE EACH LIVES
     scroll-driven hero   .shero is position:sticky at the top of #app, so the rest of the page (.curtain) slides up over
                          it like a sheet. shop.js reads the scroll and writes `translate` on the two headline lines
                          (they part), and `rotate`/`scale`/`translate` on the photograph (it turns and recedes).
                          Individual transform properties, so they compose with page.css's `rise` keyframe on the
                          spans inside the lines instead of replacing it.
     3D cans              .can carries the tilt on `transform` (shop.js) and a specular highlight on .ph::after that
                          follows the cursor through --mx/--my. Fine pointers only; a touch presses (:active).
     marquee              .ticker's .row is moved by shop.js on `transform`, base speed plus scroll velocity. Hover
                          pauses it (WCAG 2.2.2 - a moving line must be pausable).
     snap rail            .rail is a scroll-snap flex row; the card nearest its centre is .on and its label colour is
                          written to the section's --c, which color-mix() tints into the sand.
   prefers-reduced-motion: the hero is a normal block, nothing transforms, the ticker stands still, everything is
   simply visible. shop.js checks the same query and runs none of the handlers. */

/* STICKY NEEDS THE VIEWPORT TO BE THE SCROLLER. page.css sets body{overflow-x:hidden}, which quietly makes the BODY a
   scroll container (overflow-y computes to auto) - so a position:sticky child sticks to the body's scrollport, which
   never moves, and the hero scrolled away like any block (measured 12 Sep 2026: hero top -1290px at scrollY 1290).
   overflow-x:clip clips the same overflow and creates no scroll container, so the hero pins to the real viewport. */
body{overflow-x:clip}
/* the nav on a sand hero: solid (dark type) from the first pixel, but without page.css's bar until the page has moved */
.nav.solid.clear{background:transparent;box-shadow:none}

/* ---------- hero ---------- */
.shero{position:sticky;top:0;z-index:0;height:100svh;min-height:640px;padding:calc(var(--nav) + 20px) var(--pad) 40px;display:grid;grid-template-columns:1.15fr 1fr;gap:40px;align-items:end;background:var(--sand);overflow:hidden}
.shero .txt{padding-bottom:12px}
.shero .k{margin-bottom:22px;opacity:0;animation:fade .8s .2s var(--ease) forwards}
/* typed Title Case, set in caps here (Writing Conventions §9A.7: the caps headline is a typographic instruction) */
.shero h1{font-size:clamp(46px,7.6vw,128px);line-height:.92;letter-spacing:-0.035em;font-family:var(--head);font-weight:400;text-transform:uppercase}
.shero h1 .l{display:block;overflow:hidden;padding-bottom:.06em;margin-bottom:-.06em;will-change:translate}
.shero h1 .l span{display:inline-block;transform:translateY(112%);animation:rise 1s var(--ease) forwards}
.shero h1 .l:nth-child(2) span{animation-delay:.12s}
.shero .sub{max-width:46ch;font-size:17px;line-height:1.5;color:#2b2926;margin-top:26px;opacity:0;animation:fade 1s .55s var(--ease) forwards;text-wrap:pretty}
.shero .acts{display:flex;gap:12px;flex-wrap:wrap;margin-top:28px;opacity:0;animation:fade 1s .7s var(--ease) forwards}
.shero .pic{position:relative;aspect-ratio:1;width:min(100%,calc(100svh - var(--nav) - 100px));justify-self:end;align-self:center;border-radius:22px;overflow:hidden;background:#F3CBA6;box-shadow:0 50px 90px -40px rgba(0,0,0,.28);transform-origin:50% 60%;will-change:transform,translate,rotate,scale,opacity}
.shero .pic img{width:100%;height:100%;object-fit:cover;display:block}
.shero .cue{position:absolute;left:50%;bottom:18px;transform:translateX(-50%);width:20px;height:20px;animation:bob 2s ease-in-out infinite;opacity:.7}

/* the sheet that slides over the pinned hero; the footer rides inside it so nothing paints under the hero */
.curtain{position:relative;z-index:2;background:var(--sand);box-shadow:0 -24px 60px -30px rgba(0,0,0,.22)}

/* the ticker strip's rules were deleted on 23 Sep 2026 (Nuo: "prue hates these strips, delete them everywhere!") */

/* ---------- sections ---------- */
.sh{padding:110px var(--pad) 50px}
.sh .hd{align-items:flex-end;margin-bottom:40px}
.sh .hd h2{font-size:clamp(34px,4.2vw,64px);margin:0;letter-spacing:-0.03em}
.sh .hd p{max-width:46ch;font-size:17px;line-height:1.5;color:#2b2926;text-wrap:pretty}
.sh .hd .side{display:flex;flex-direction:column;gap:18px;align-items:flex-start}
.kick{font-family:var(--head);text-transform:uppercase;font-size:12px;letter-spacing:.08em;color:#3f3c39;margin-bottom:14px}
/* a phrase that must not split across lines (Nuo, 12 Sep 2026: "move Whole to the next line", "move an to the next
   line") - nowrap rather than a <br>, so it drops as a unit where it does not fit and stays put where it does */
.nb{white-space:nowrap}
.more{font-family:var(--head);font-size:14px;display:inline-flex;gap:6px;align-items:center}
.more i,.buy i{font-style:normal;display:inline-block;transition:translate .3s var(--ease)}
@media (hover:hover){.more:hover i,.buy:hover i{translate:4px 0}}
/* min-height 28px: a 14px inline link is 21px tall, under the 24px tap floor (measured at 390px, 12 Sep 2026) */
.buy{font-family:var(--head);font-size:14px;display:inline-flex;gap:6px;align-items:center;min-height:28px;background:linear-gradient(currentColor,currentColor) no-repeat 0 100%/0 1px;transition:background-size .35s var(--ease)}
.more{min-height:28px}
@media (hover:hover){.buy:hover,.buy:focus-visible{background-size:100% 1px}}
.pr{font-family:var(--head);font-size:20px;letter-spacing:-0.01em;display:flex;align-items:baseline;gap:6px;flex-wrap:wrap}
.pr small{font-family:var(--body);font-size:13px;color:#3f3c39;letter-spacing:0}
.chip{position:absolute;top:12px;left:12px;z-index:2;background:#E6DDD7;color:var(--ink);font-family:var(--head);font-size:11px;letter-spacing:.08em;text-transform:uppercase;padding:6px 10px;border-radius:999px;white-space:nowrap}
.chip.soft{background:rgba(242,236,233,.92);color:var(--ink)}

/* one entrance per card, on the individual properties so the tilt's `transform` is never fought */
.rv{opacity:0;translate:0 26px;transition:opacity .7s var(--ease),translate .7s var(--ease);transition-delay:var(--d,0s)}
.rv.in{opacity:1;translate:0 0}

/* ---------- the cans: a snap rail whose active can colours the section ---------- */
.cans{--c:var(--sand);padding:110px 0 60px;background:color-mix(in oklab,var(--c) 26%,var(--sand));transition:background-color .8s var(--ease)}
@supports not (background:color-mix(in oklab,red 10%,blue)){.cans{background:var(--sand)}}
.cans .hd{padding:0 var(--pad)}
.railnav{display:flex;gap:8px}
.railnav button{width:44px;height:44px;border-radius:999px;border:1.5px solid rgba(0,0,0,.35);background:transparent;font-size:20px;line-height:1;display:grid;place-items:center;transition:background .2s,color .2s,border-color .2s}
@media (hover:hover){.railnav button:hover{background:var(--ink);color:var(--sand);border-color:var(--ink)}}
.railnav button:disabled{opacity:.3;pointer-events:none}
.rail{display:flex;gap:18px;overflow-x:auto;scroll-snap-type:x mandatory;scroll-padding:0 var(--pad);padding:14px var(--pad) 34px;scrollbar-width:none;-webkit-overflow-scrolling:touch;cursor:grab;outline-offset:-3px}
.rail::-webkit-scrollbar{display:none}
.rail.drag{cursor:grabbing;scroll-snap-type:none}
.rail::after{content:"";flex:0 0 calc(var(--pad) - 18px)}   /* the last card can still snap to the left edge */
.can{flex:0 0 clamp(264px,25vw,340px);scroll-snap-align:start;background:#fff;border-radius:18px;overflow:hidden;position:relative;transform-style:preserve-3d;will-change:transform;transition:transform .55s var(--ease),box-shadow .55s var(--ease);box-shadow:0 12px 30px -18px rgba(0,0,0,.18)}
.can.tilting{transition:transform .09s linear,box-shadow .55s var(--ease)}
.can.on{box-shadow:0 34px 70px -28px rgba(0,0,0,.3)}
.can .ph{position:relative;aspect-ratio:4/3;overflow:hidden;background:#efe9e4}
.can .ph img{width:100%;height:100%;object-fit:cover;transform:scale(1.02);transition:transform .9s var(--ease),filter .5s}
@media (hover:hover){.can:hover .ph img{transform:scale(1.07)}}
/* the highlight: a soft white disc under the cursor, blended so the can reads as lit rather than painted */
.can .ph::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .35s;mix-blend-mode:soft-light;background:radial-gradient(circle at var(--mx,50%) var(--my,50%),rgba(255,255,255,.9),rgba(255,255,255,0) 52%)}
@media (hover:hover){.can:hover .ph::after{opacity:1}}
.can.out .ph img{filter:saturate(.25) brightness(1.04)}
.can .bd{padding:18px 20px 20px}
.can h3{font-size:22px;margin-bottom:6px;letter-spacing:-0.02em}
.nt{font-size:14px;color:#3f3c39;line-height:1.4}
.nt b{font-weight:500;color:var(--ink)}
.vr{display:flex;gap:6px;flex-wrap:wrap;margin-top:12px}
.vr span{font-family:var(--head);font-size:11px;text-transform:uppercase;letter-spacing:.06em;padding:4px 9px;border:1px solid rgba(0,0,0,.18);border-radius:999px;line-height:1.2}
.vr span.na{opacity:.38;text-decoration:line-through}
.gauges{display:grid;grid-template-columns:1fr 1fr;gap:7px 18px;margin-top:14px}
.g{display:flex;justify-content:space-between;align-items:center;gap:8px;font-family:var(--head);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:#3f3c39}
.g .bar{display:flex;gap:2px}
.g .bar i{width:10px;height:4px;border-radius:2px;background:rgba(0,0,0,.13)}
.g .bar i.on{background:var(--c,var(--ink))}
.g .bar i.half{background:linear-gradient(90deg,var(--c,var(--ink)) 50%,rgba(0,0,0,.13) 50%)}
.can .g .bar i.on,.can .g .bar i.half{--c:var(--cc)}   /* the can's own colour, set inline; not the section's tint */
.ft{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-top:16px;padding-top:14px;border-top:1px solid rgba(0,0,0,.1)}
@media (pointer:coarse){.can:active,.bag:active,.lbox:active,.hitem:active{transform:scale(.985)}}

/* ---------- bags & pods: one tall lead, four squares ---------- */
.bgrid{display:grid;grid-template-columns:1.25fr 1fr 1fr;gap:18px}
.bag{background:#fff;border-radius:18px;overflow:hidden;position:relative;display:flex;flex-direction:column}
.bag.lead{grid-row:1/3}
.bag .ph{position:relative;aspect-ratio:1;overflow:hidden;background:#efe9e4}
.bag.lead .ph{aspect-ratio:auto;flex:1;min-height:420px}
.bag .ph img{width:100%;height:100%;object-fit:cover;transform:scale(1.02);transition:transform .9s var(--ease),filter .5s}
@media (hover:hover){.bag:hover .ph img{transform:scale(1.06)}}
.bag.out .ph img{filter:saturate(.25) brightness(1.04)}
.bag .bd{padding:18px 20px 20px}
.bag h3{font-size:22px;margin-bottom:6px;letter-spacing:-0.02em}
.bag.lead h3{font-size:clamp(26px,2.4vw,34px)}
.bag .vr span{border-color:rgba(0,0,0,.14)}

/* ---------- subscribe: the black band ---------- */
.subs{background:var(--ink);color:var(--sand);padding:100px var(--pad);display:grid;grid-template-columns:1.1fr 1fr;gap:40px;align-items:center}
.subs h2{font-size:clamp(40px,5.6vw,88px);letter-spacing:-0.035em;line-height:.95;margin:0}
.subs .kick{color:rgba(242,236,233,.7)}
.subs p{font-size:18px;line-height:1.5;color:rgba(242,236,233,.85);max-width:44ch;margin-bottom:26px;text-wrap:pretty}
@media (hover:hover){.subs .pill.light:hover{background:var(--sand);border-color:var(--sand);color:var(--ink)}}

/* ---------- Radio Lamington: three portrait boxes ---------- */
.boxes .hd .side{max-width:46ch}
.bxgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.lbox{background:#fff;border-radius:18px;overflow:hidden;position:relative}
.lbox .ph{position:relative;aspect-ratio:4/5;overflow:hidden;background:#efe9e4}
.lbox .ph img{width:100%;height:100%;object-fit:cover;transform:scale(1.02);transition:transform .9s var(--ease),filter .5s}
@media (hover:hover){.lbox:hover .ph img{transform:scale(1.06)}}
.lbox.out .ph img{filter:saturate(.35)}
.lbox .bd{padding:18px 20px 20px}
.lbox h3{font-size:20px;letter-spacing:-0.02em;margin-bottom:6px}

/* ---------- the collaborations: two editorial features ---------- */
.art{padding-bottom:30px}
.feat{display:grid;grid-template-columns:1.1fr 1fr;gap:56px;align-items:center;padding:40px 0}
.feat + .feat{border-top:1px solid rgba(0,0,0,.1);padding-top:80px;margin-top:20px}
.feat .copy h2{font-size:clamp(34px,4.2vw,64px);letter-spacing:-0.03em;margin-bottom:18px;line-height:.98}
.feat .copy p{font-size:17px;line-height:1.55;color:#2b2926;max-width:52ch;margin-bottom:16px;text-wrap:pretty}
.feat .copy .pr{font-size:24px;margin:10px 0 18px}
/* the artist lock-up above the tea set's heading: sized by HEIGHT, width auto (the stacked signature / X / DAISY. is
   about 2:1); the safety zone the deck asks for - the x-height of DAISY above and below - is the margin. With the
   file present the text kicker is hidden; when it 404s shop.js drops .haslk and the kicker shows instead. */
.lockup{margin-bottom:22px}   /* ~ the x-height of DAISY at this size */
.lockup img.lk{display:block;height:76px;width:auto}
.lockup.haslk .kick{display:none}
.lockup .kick{margin-bottom:0}
/* the tea set: one large photograph with the second stepped over its corner */
.stack{position:relative;padding:0 12% 12% 0}
.stack img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:18px;display:block}
.stack img + img{position:absolute;right:0;bottom:0;width:46%;aspect-ratio:4/5;border-radius:14px;box-shadow:0 30px 60px -20px rgba(0,0,0,.3);border:6px solid var(--sand)}
/* HELLO: three items in a row, the copy beside them */
.feat.rev{grid-template-columns:1fr 1.25fr}
.hgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
.hitem{background:#fff;border-radius:16px;overflow:hidden;position:relative;display:flex;flex-direction:column}
.hitem .ph{aspect-ratio:1;overflow:hidden;background:#efe9e4}
.hitem .ph img{width:100%;height:100%;object-fit:cover;transform:scale(1.02);transition:transform .9s var(--ease)}
@media (hover:hover){.hitem:hover .ph img{transform:scale(1.06)}}
.hitem .bd{padding:14px 16px 16px;display:flex;flex-direction:column;flex:1}
.hitem h3{font-size:17px;letter-spacing:-0.02em;margin-bottom:4px}
.hitem .ed{font-family:var(--head);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:#3f3c39}
.hitem .vr{margin-top:10px}.hitem .vr span{padding:3px 7px}   /* the size chips keep the 11px floor - a size is a value a reader takes */
.hitem .ft{margin-top:auto;padding-top:12px}
.hitem .pr{font-size:18px}

/* ---------- vouchers: the dust-blue band ---------- */
.gift{background:#A9D8EA;color:var(--ink);padding:110px var(--pad);display:grid;grid-template-columns:1.2fr 1fr;gap:40px;align-items:end}
.gift h2{font-size:clamp(44px,7vw,112px);letter-spacing:-0.035em;line-height:.92;margin:0}
.gift p{font-size:18px;line-height:1.5;max-width:40ch;margin-bottom:26px;text-wrap:pretty}
.gift .kick{color:rgba(0,0,0,.65)}

.fine{padding:26px var(--pad) 40px;font-size:13px;color:#5a5754;max-width:70ch}

/* ---------- phone ---------- */
@media (max-width:1100px){
  .bgrid{grid-template-columns:1fr 1fr}.bag.lead{grid-row:auto;grid-column:1/-1}.bag.lead .ph{aspect-ratio:16/10;min-height:0}
  .bxgrid{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:860px){
  .shero{min-height:560px;grid-template-columns:1fr;grid-template-rows:auto 1fr;gap:18px;padding-top:calc(var(--nav) + 12px);padding-bottom:64px;align-items:start}
  .shero .pic{order:-1;width:min(100%,48svh);justify-self:start;align-self:start;border-radius:16px}
  .shero .txt{padding-bottom:0;align-self:end}
  .shero .k{margin-bottom:12px}.shero .sub{margin-top:14px;font-size:15px}.shero .acts{margin-top:18px}
  .sh{padding:64px var(--pad) 30px}.cans{padding:64px 0 30px}.sh .hd{margin-bottom:24px}
  .railnav{display:none}                                  /* a phone swipes */
  .can{flex-basis:78vw}
  .bgrid{grid-template-columns:1fr}.bag.lead .ph{aspect-ratio:1}
  .subs{grid-template-columns:1fr;padding:64px var(--pad);gap:22px}
  .bxgrid{grid-template-columns:1fr}.lbox .ph{aspect-ratio:16/10}
  .feat,.feat.rev{grid-template-columns:1fr;gap:28px;padding:20px 0}.feat + .feat{padding-top:44px}
  .feat.rev .copy{order:-1}
  .hgrid{grid-template-columns:1fr;gap:10px}
  .hitem{flex-direction:row;align-items:stretch}.hitem .ph{flex:0 0 112px;aspect-ratio:auto}.hitem .bd{padding:12px 14px}
  .gift{grid-template-columns:1fr;padding:64px var(--pad);gap:20px}
  .stack{padding:0 10% 10% 0}
}
@media (prefers-reduced-motion:reduce){
  .shero{position:relative}
  .shero .k,.shero .sub,.shero .acts,.shero .cue{animation:none;opacity:1}
  .shero h1 .l span{animation:none;transform:none}
  .rv{opacity:1;translate:0 0;transition:none}
  .can,.can .ph img,.bag .ph img,.lbox .ph img,.hitem .ph img,.more i,.buy i,.cans{transition:none}
  .can .ph::after{display:none}
}

/* SMALLER ON DESKTOP (Prue's review, 19 Oct 2026: "one clean coffee-subscription page, smaller on desktop") - the hero no longer
   fills the screen: it takes its content's height, the photograph is held to 520px and the word SHOP to 88px. */
@media (min-width:861px){
  .shero{height:auto;min-height:0;padding:calc(var(--nav) + 64px) var(--pad) 72px;align-items:center}
  .shero h1{font-size:clamp(46px,5.2vw,88px)!important}
  .shero .pic{width:min(100%,520px)}
}
