/* Kaffedex pages — the same frosted-glass system as the home and the DOCKK
   pages (Funnel Display, grain over the field, frost tiles, the pinned scroll
   story), with Kaffedex's own orange as the one lit colour and a coffee-poured
   field instead of the Horizon.
   Product shots are real captures CUT DOWN to the part that matters (the
   answer, the calibration, the card's tiles, the label), never whole phones.
   One stylesheet, no scripts, no inline styles (octolabo.app's CSP). */

@font-face {
  font-family: "Funnel Display";
  src: url("/fonts/FunnelDisplay.ttf") format("truetype");
  font-weight: 300 800;
  font-display: swap;
}

:root {
  color-scheme: dark;
  --ink: #f5eee4;
  --ink-2: #d8cabb;
  --ink-3: #ab9a8a;
  --ground: #120b08;         /* espresso */
  --signal: #d26b1c;          /* Kaffedex orange */
  --signal-hi: #e8803a;
  --signal-ink: #1b0d03;
  --live: #4fd18b;
  --paper: #f6f2ea;           /* the label sheet */
  --frost-bg: rgba(30, 19, 13, .56);
  --frost-hi: rgba(255, 240, 220, .12);
  --frost-edge: rgba(255, 240, 220, .08);
  --frost-shadow: 0 24px 60px rgba(10, 5, 2, .4);
  /* a screen segment: the app's own paper, a hairline, a long soft shadow */
  --seg-shadow: 0 0 0 1px rgba(255, 245, 230, .16), 0 2px 6px rgba(10, 5, 2, .25), 0 40px 90px rgba(10, 5, 2, .55);
  --display: "Funnel Display", -apple-system, "Helvetica Neue", sans-serif;
  --ui: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI Variable Text", "Segoe UI", "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
  --ease: cubic-bezier(.22, .8, .22, 1);
  --r-tile: 24px;
  --r-card: 18px;
}

* { box-sizing: border-box; }
html { background: var(--ground); scroll-padding-top: 24px; }
body {
  margin: 0;
  color: var(--ink);
  font: 16px/1.6 var(--ui);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
  /* The field, poured like a latte: espresso at the top, dark chocolate
     under the headline, milk and foam under the hero collage, caramel and
     mocha under the statement, back to espresso; grain over everything. */
  background:
    url("/assets/grain.png"),
    linear-gradient(180deg, #120b08 0, #170e0a 380px, #3a2316 560px, #7a4e30 780px,
      #b8906a 940px, #d7b994 1040px, #a86d42 1150px, #6b3a1e 1280px, #2a1810 1600px, #120b08 1980px);
  background-repeat: repeat, no-repeat;
}
img { max-width: 100%; height: auto; display: block; }
picture { display: block; }
a { color: #ffb27d; }
a:hover { color: #ffd2b3; }
:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; border-radius: 6px; }

.shell { max-width: 1120px; margin: 0 auto; padding: 0 20px 72px; display: grid; gap: 88px; }

/* ---------- top bar ---------- */
.topbar { display: flex; align-items: center; gap: 16px; padding: 20px 0 0; }
.wordmark { display: inline-flex; align-items: center; gap: 10px; color: var(--ink); text-decoration: none; font: 500 18px/1 var(--display); letter-spacing: -.01em; }
.wordmark img { width: 28px; height: 28px; border-radius: 7px; }
.wordmark a { display: inline-flex; color: inherit; text-decoration: none; }
.wordmark .studio img { outline: 1px solid rgba(255,255,255,.1); outline-offset: -1px; }
.topbar .spacer { flex: 1; }
.topbar a.quiet { color: var(--ink-2); text-decoration: none; font-size: 14px; }
.topbar a.quiet:hover { color: var(--ink); }

/* ---------- type ---------- */
h1, h2, h3 { font-family: var(--display); font-weight: 500; letter-spacing: -.02em; margin: 0; text-wrap: balance; }
h1 { font-size: clamp(44px, 8vw, 88px); line-height: 1; letter-spacing: -.035em; }
h2 { font-size: clamp(30px, 4.4vw, 48px); line-height: 1.06; }
h3 { font-size: 21px; line-height: 1.2; }
p { margin: 0; }
.eyebrow { font: 600 12px/1.3 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.lede { font-size: clamp(17px, 2vw, 20px); color: var(--ink-2); max-width: 60ch; }
.copy { color: var(--ink-2); max-width: 62ch; }
.note { font: 600 12px/1.4 var(--mono); letter-spacing: .05em; text-transform: uppercase; color: var(--ink-3); }

/* ---------- pieces ---------- */
.frost {
  border-radius: var(--r-tile);
  background: var(--frost-bg);
  -webkit-backdrop-filter: blur(28px) saturate(1.6);
  backdrop-filter: blur(28px) saturate(1.6);
  box-shadow: inset 0 1px 0 var(--frost-hi), inset 0 0 0 1px var(--frost-edge), var(--frost-shadow);
}
.pill { display: inline-flex; align-items: center; gap: 8px; height: 30px; padding: 0 13px; border-radius: 999px; font: 600 11px/1 var(--mono); letter-spacing: .05em; text-transform: uppercase; color: var(--ink-2); box-shadow: inset 0 0 0 1px rgba(255,255,255,.2); white-space: nowrap; }
.pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--signal); }
.pill.live .dot { background: var(--live); }
.pill.lit { color: #fff; box-shadow: inset 0 1px 0 rgba(255,255,255,.3); background: linear-gradient(120deg, rgba(210,107,28,.95), rgba(160,58,20,.92) 60%, rgba(74,32,16,.92)); }
.pill.lit .dot { background: #fff; }

.button { display: inline-flex; align-items: center; justify-content: center; min-height: 46px; padding: 0 22px; border-radius: 999px; font: 600 15px/1 var(--ui); text-decoration: none; background: var(--signal); color: var(--signal-ink); }
.button:hover { background: var(--signal-hi); color: var(--signal-ink); }
.button.ghost { background: rgba(255,255,255,.08); color: var(--ink); box-shadow: inset 0 0 0 1px rgba(255,255,255,.16); }
.button.ghost:hover { background: rgba(255,255,255,.14); color: var(--ink); }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }

/* ---------- hero ---------- */
.hero { display: grid; gap: 28px; padding-top: 48px; }
.hero-head { display: flex; flex-wrap: wrap; align-items: center; gap: 24px; }
.hero-head .icon { width: 112px; height: 112px; border-radius: 26px; box-shadow: 0 20px 50px rgba(0,0,0,.45); }
.hero-head .titles { display: grid; gap: 12px; justify-items: start; }

/* the collage: three segments of real captures, overlapping like things
   left on the bar. Positions are percentages of the stage, so it scales. */
.collage { position: relative; aspect-ratio: 1080 / 640; margin-top: 16px; --lift-a: -28px; --lift-c: -70px; --lift-l: -96px; }
.collage .z { position: absolute; }
.collage img { width: 100%; height: auto; }
.z-answer { left: 1%; top: 7%; width: 56%; }
.z-answer img { border-radius: 26px; box-shadow: var(--seg-shadow); }
.z-card { right: 4%; top: 0; width: 29%; rotate: 5deg; }
.z-card img { filter: drop-shadow(0 34px 44px rgba(10, 5, 2, .55)); }
.z-label { left: 37%; top: 63%; width: 31%; rotate: -4deg; }
.z-label img { border-radius: 2px; box-shadow: 0 1px 2px rgba(0,0,0,.2), 0 26px 50px rgba(10, 5, 2, .5); }

/* ---------- sections ---------- */
.section { display: grid; gap: 22px; }
.section > header { display: grid; gap: 12px; }
.section > header .pill { justify-self: start; }
.split { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr)); gap: 12px; }
.tile { padding: 24px; display: grid; gap: 10px; align-content: start; }
.tile p { color: var(--ink-2); font-size: 15px; }
.tile.lit { color: #fff; background: linear-gradient(135deg, rgba(210,107,28,.9), rgba(160,58,20,.88) 60%, rgba(74,32,16,.9)); }
.tile.lit p { color: rgba(255,255,255,.9); }
.bento { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); gap: 12px; }
.bento .pill { justify-self: start; }
.bento .tile { min-height: 170px; align-content: space-between; }

.shot { border-radius: 14px; overflow: hidden; box-shadow: 0 0 0 1px rgba(255,255,255,.1), 0 40px 100px rgba(0,0,0,.55); }
figure { margin: 0; }

/* ---------- recipe cards: the whole card, its details flying in beside it ----------
   Static (no scroll timelines / reduced motion): the card with its three
   enlarged details already in place. The motion block pins the card and flies
   the details in from the side and from below; a ring marks each one's spot
   on the card (rects = the crops' exact boxes inside the 1020×1790 capture). */
.assemble { position: relative; }
.assemble-stage { display: grid; place-items: center; padding: 24px 0 8px; }
.build { position: relative; display: grid; grid-template-columns: auto auto; gap: 64px; align-items: center; }
/* a clay glow under the card, the colour of its frame */
.build::before { content: ""; position: absolute; z-index: -1; left: -24%; top: -12%; width: 76%; height: 124%;
  background: radial-gradient(closest-side, rgba(196, 112, 92, .3), rgba(196, 112, 92, 0)); pointer-events: none; }
.build-card { position: relative; width: min(400px, calc((100vh - 140px) * 1020 / 1790)); rotate: -3deg; }
.build-base img { width: 100%; filter: drop-shadow(0 40px 56px rgba(10, 5, 2, .6)); }
.ring, .pin { position: absolute; }
.r-art { left: 3.33%; top: 15.64%; width: 93.33%; height: 26.26%; }
.r-specs { left: 3.33%; top: 50.73%; width: 93.33%; height: 27.37%; }
.r-qr { left: 3.14%; top: 84.8%; width: 94.9%; height: 13.41%; }
.ring { opacity: 0; border-radius: 12px; box-shadow: 0 0 0 2px var(--signal), 0 0 28px rgba(232, 128, 58, .6); }
.pin { right: -12px; translate: 0 -50%; box-shadow: 0 0 0 4px rgba(210, 107, 28, .25), 0 6px 14px rgba(0,0,0,.4); }
.pin-art { top: 28.8%; }
.pin-specs { top: 64.4%; }
.pin-qr { top: 91.5%; }
.details { width: min(460px, calc((100vh - 170px) * .62)); margin: 0; padding: 0; list-style: none; display: grid; gap: 18px; }
.details li { display: grid; gap: 10px; }
.details img { width: 100%; border-radius: 14px; box-shadow: var(--seg-shadow); }
.details p { display: flex; gap: 10px; align-items: flex-start; color: var(--ink-2); font-size: 14px; line-height: 1.5; }
.details b { color: var(--ink); font-weight: 600; }
.pin, .num { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; flex: none;
  background: var(--signal); color: #fff; font: 700 11px/1 var(--mono); }
.details .num { width: 22px; height: 22px; font-size: 10px; }

.deck { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 32px; align-items: end; padding: 32px 32px 0; overflow: hidden; }
.deck-copy { display: grid; gap: 12px; justify-items: start; align-self: center; padding-bottom: 32px; }
.deck-copy p { color: var(--ink-2); font-size: 15px; max-width: 44ch; }
.deck-shot img { width: 100%; height: 440px; object-fit: cover; object-position: 50% 0; border-radius: 22px 22px 0 0; box-shadow: var(--seg-shadow); }

/* ---------- printables: a label sheet, one sticker lifted off ---------- */
.sheet-stage { position: relative; width: min(100%, 720px); margin: 8px auto 0; padding: 40px 0 24px; --k: .76; --fold: 40px; }
.sheet-stage::before { content: ""; position: absolute; z-index: -1; inset: -18% -30%;
  background: radial-gradient(closest-side, rgba(220, 180, 130, .2), rgba(220, 180, 130, 0)); pointer-events: none; }
.sheet { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; padding: 36px 32px 22px; rotate: -2deg;
  background: var(--paper); border-radius: 4px;
  box-shadow: inset 0 0 0 1px rgba(60, 40, 20, .06), 0 2px 4px rgba(10, 5, 2, .2), 0 44px 100px rgba(10, 5, 2, .55); }
.slot { outline: 1px dashed rgba(60, 40, 20, .2); outline-offset: 5px; }
.slot img { width: 100%; box-shadow: 0 0 0 .5px rgba(0,0,0,.06); }
/* the backing paper left where the first sticker came off */
.slot.peeled { display: block; aspect-ratio: 591 / 338; border-radius: 2px;
  background: linear-gradient(160deg, #ebe5d8, #e1dacb); box-shadow: inset 0 1px 3px rgba(60, 40, 20, .14); }
.sheet-foot { grid-column: 1 / -1; padding-top: 8px; text-align: right; font: 600 10px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: #9a9184; }
/* the lifted sticker: bigger than its slot, a folded corner, a real shadow */
.peel { position: absolute; left: 32px; top: 76px; width: 58%; transform-origin: 0 0;
  translate: -11% -32%; rotate: -7deg;
  filter: drop-shadow(0 2px 3px rgba(0,0,0,.2)) drop-shadow(0 30px 40px rgba(10, 5, 2, .5)); }
.peel img { width: 100%; clip-path: polygon(0 0, 100% 0, 100% calc(100% - var(--fold)), calc(100% - var(--fold)) 100%, 0 100%); }
.peel::after { content: ""; position: absolute; right: 0; bottom: 0; width: var(--fold); height: var(--fold);
  background: linear-gradient(315deg, transparent 50%, #d9d2c4 50%, #f4f0e8 100%); }

/* ---------- pricing ---------- */
.prices { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: 12px; }
.price { padding: 24px; display: grid; gap: 8px; align-content: start; }
.price .amount { font: 400 34px/1.05 var(--display); letter-spacing: -.03em; }
.price p { color: var(--ink-2); font-size: 15px; }
.price.lit { background: rgba(210, 107, 28, .92); color: var(--signal-ink); box-shadow: inset 0 1px 0 rgba(255,220,190,.9), var(--frost-shadow); }
.price.lit .eyebrow, .price.lit p { color: #3a1a06; }

/* ---------- faq ---------- */
.faq { display: grid; gap: 10px; }
.faq details { padding: 4px 22px; border-radius: var(--r-card); }
.faq summary { cursor: pointer; padding: 16px 0; font-weight: 600; list-style: none; display: flex; justify-content: space-between; gap: 16px; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font: 400 22px/1 var(--display); color: var(--ink-3); flex: none; }
.faq details[open] summary::after { content: "–"; }
.faq details p { color: var(--ink-2); padding-bottom: 18px; }

/* ---------- contact / support ---------- */
.cta { padding: 32px; display: grid; gap: 16px; justify-items: start; }
.form { display: grid; gap: 14px; width: 100%; max-width: 560px; justify-items: start; }
.field { display: grid; gap: 6px; width: 100%; }
.field label { font: 600 12px/1.3 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
.field input, .field textarea {
  width: 100%; padding: 12px 14px; border: 0; border-radius: 12px; resize: vertical;
  background: rgba(255,255,255,.07); box-shadow: inset 0 0 0 1px rgba(255,255,255,.14);
  color: var(--ink); font: 15px/1.5 var(--ui);
}
.field input::placeholder, .field textarea::placeholder { color: var(--ink-3); }
.field input:focus, .field textarea:focus { outline: none; box-shadow: inset 0 0 0 1.5px var(--signal); }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form-alt { color: var(--ink-3); font-size: 14px; }

/* ---------- prose pages ---------- */
.prose { max-width: 760px; display: grid; gap: 14px; padding: 32px; }
.prose h1 { font-size: clamp(36px, 6vw, 56px); }
.prose h2 { font-size: 24px; margin-top: 18px; }
.prose p, .prose li { color: var(--ink-2); }
.prose ul { margin: 0; padding-left: 22px; display: grid; gap: 6px; }
.meta { font: 500 13px/1.3 var(--mono); color: var(--ink-3); }

/* ---------- footer ---------- */
.footer { display: flex; flex-wrap: wrap; gap: 12px 24px; align-items: center; color: var(--ink-3); font-size: 14px; border-top: 1px solid rgba(255,255,255,.1); padding-top: 24px; }
.footer .spacer { flex: 1; }
.footer a { color: var(--ink-2); text-decoration: none; }
.footer a:hover { color: var(--ink); }

/* ---------- statement line ---------- */
.statement { padding: 40px 0 8px; }
.statement p { font: 500 clamp(40px, 7.4vw, 104px)/1.02 var(--display); letter-spacing: -.04em; max-width: 14ch; }

/* ---------- the pinned feature story ----------
   Static first: without scroll-driven animation it reads top to bottom,
   steps as cards with the first segment showing. */
.story { position: relative; margin: 72px 0; }
.story-stage {
  max-width: 1240px; margin: 0 auto; padding: 0 20px;
  display: grid; grid-template-columns: minmax(280px, 5fr) minmax(0, 6fr); gap: 48px; align-items: center;
}
.story-copy { display: grid; gap: 18px; }
.story-steps { margin: 0; padding: 0; list-style: none; display: grid; gap: 14px; counter-reset: step; }
.story-steps li { counter-increment: step; padding: 14px 16px 14px 52px; position: relative; border-radius: 16px;
  color: var(--ink-2); font-size: 15px; background: rgba(255,240,220,.04); box-shadow: inset 0 0 0 1px rgba(255,240,220,.07); }
.story-steps li::before { content: counter(step, decimal-leading-zero); position: absolute; left: 16px; top: 15px;
  font: 600 12px/1.4 var(--mono); color: var(--ink-3); }
.story-steps b { color: var(--ink); font-weight: 600; display: block; margin-bottom: 2px; }
/* landscape segments, all stacked in one cell and centred in it */
.story-media { display: grid; place-items: center; }
.story-media picture { grid-area: 1 / 1; width: 100%; }
.story-media img { width: 100%; border-radius: 26px; box-shadow: var(--seg-shadow); }
.story-media img:not(.m1) { visibility: hidden; }   /* static: show the first only */
/* each step's own segment: phones only, where it sits right under its text */
.story-steps .shot { display: none; }

@media (max-width: 860px) {
  .story-stage { grid-template-columns: 1fr; gap: 20px; }
  .story-steps li { font-size: 14px; }
  /* no room to pin the steps beside a picture: each step carries its
     segment instead, and the shared stage goes */
  .story-media { display: none; }
  .story-steps .shot { display: block; width: calc(100% + 36px); max-width: none; margin: 14px 0 4px -36px;
    border-radius: 16px; box-shadow: 0 0 0 1px rgba(255,255,255,.12), 0 18px 40px rgba(0,0,0,.45); }

  .build { grid-template-columns: 1fr; gap: 40px; justify-items: center; }
  .build::before { left: -20%; width: 140%; height: 50%; }
  .build-card { width: min(74vw, 360px); }
  .details { width: 100%; gap: 28px; }
  .pin { right: -10px; }
  .deck { grid-template-columns: 1fr; gap: 8px; padding: 24px 24px 0; }
  .deck-copy { padding-bottom: 8px; }
  .deck-shot img { height: 340px; }
}

@media (max-width: 640px) {
  .shell { gap: 64px; }
  .topbar { gap: 14px; }
  .topbar a.wide { display: none; }
  .hero-head .icon { width: 84px; height: 84px; border-radius: 20px; }
  /* phones: a taller stage, the answer across the top (never covered),
     the label and the card stepping down below it */
  .collage { aspect-ratio: 10 / 12.6; --lift-a: -10px; --lift-c: -28px; --lift-l: -22px; }
  .z-answer { left: 0; top: 2%; width: 80%; }
  .z-answer img { border-radius: 16px; }
  .z-card { right: 1%; top: 43%; width: 40%; }
  .z-label { left: 3%; top: 57%; width: 58%; }
  .tile, .price, .cta, .prose { padding: 20px; }
  .sheet-stage { --k: .7; --fold: 24px; padding-top: 36px; }
  .sheet { gap: 10px; padding: 22px 16px 16px; }
  .slot { outline-offset: 3px; }
  .sheet-foot { font-size: 8px; }
  .peel { left: 16px; top: 58px; width: 62%; translate: -8% -34%; }
}
@media (prefers-reduced-transparency: reduce) {
  .frost { -webkit-backdrop-filter: none; backdrop-filter: none; background: #221610; }
}

/* ----------------------------------------------------------------------
   Motion. First paint: CSS animations. Scroll: scroll-driven, CSS only
   (Safari 26+, Chrome 115+); everything reads fine without it. */
@media (prefers-reduced-motion: no-preference) {
  .intro { animation: intro .8s var(--ease) both; }
  .intro-2 { animation-delay: .08s; }
  .intro-3 { animation-delay: .16s; }
  .intro-4 { animation-delay: .24s; }
  @keyframes intro { from { opacity: 0; transform: translateY(18px); } }

  /* the collage lands piece by piece, each one settling from a closer zoom */
  .collage .z { animation: settle 1s var(--ease) both; }
  .collage .z-answer { animation-delay: .3s; }
  .collage .z-card { animation-delay: .46s; }
  .collage .z-label { animation-delay: .62s; }
  @keyframes settle { from { opacity: 0; scale: 1.14; } }

  @supports (animation-timeline: view()) {
    /* hero: as you start scrolling the pieces drift apart, the card and the
       label lifting toward you */
    .collage .z { animation: settle 1s var(--ease) both, drift linear both;
      animation-timeline: auto, scroll(root); animation-range: normal, 0px 760px; }
    .collage .z-answer { animation-name: settle, drift-answer; animation-delay: .3s, 0s; }
    .collage .z-card { animation-name: settle, drift-card; animation-delay: .46s, 0s; }
    .collage .z-label { animation-name: settle, drift-label; animation-delay: .62s, 0s; }
    @keyframes drift-answer { to { transform: translateY(var(--lift-a)); } }
    @keyframes drift-card { from { transform: translateY(24px); } to { transform: translateY(var(--lift-c)) rotate(-3deg) scale(1.04); } }
    @keyframes drift-label { from { transform: translateY(16px); } to { transform: translateY(var(--lift-l)) rotate(-3deg) scale(1.1); } }

    .reveal { animation: rise linear both; animation-timeline: view(); animation-range: entry 0% cover 28%; }
    .split .reveal:nth-child(2), .bento .reveal:nth-child(3n+2), .prices .reveal:nth-child(2) { animation-range: entry 8% cover 32%; }
    .split .reveal:nth-child(3), .bento .reveal:nth-child(3n) { animation-range: entry 16% cover 36%; }
    @keyframes rise { from { opacity: 0; transform: translateY(48px) scale(.97); } to { opacity: 1; transform: none; } }

    /* the card: pinned for two screens while its details fly in, enlarged,
       from the right and from below, and land beside it; as each lands, a
       ring lights on the part of the card it shows */
    .assemble { height: 300vh; view-timeline-name: --assemble; }
    .assemble-stage { position: sticky; top: 0; height: 100vh; padding: 0; }
    .details li, .ring { animation: linear both; animation-timeline: --assemble; }
    .details .d-art { animation-name: in-right; animation-range: contain 4% contain 28%; }
    .details .d-specs { animation-name: in-below; animation-range: contain 30% contain 54%; }
    .details .d-qr { animation-name: in-below-right; animation-range: contain 56% contain 80%; }
    .r-art { animation-name: ring; animation-range: contain 20% contain 40%; }
    .r-specs { animation-name: ring; animation-range: contain 46% contain 66%; }
    .r-qr { animation-name: ring; animation-range: contain 72% contain 92%; }
    @keyframes in-right { from { opacity: 0; transform: translateX(70%) rotate(5deg) scale(1.15); } 30% { opacity: 1; } }
    @keyframes in-below { from { opacity: 0; transform: translateY(120%) rotate(-4deg) scale(1.15); } 30% { opacity: 1; } }
    @keyframes in-below-right { from { opacity: 0; transform: translate(40%, 260%) rotate(4deg) scale(1.15); } 30% { opacity: 1; } }
    @keyframes ring { 0% { opacity: 0; } 30%, 65% { opacity: 1; } 100% { opacity: 0; } }

    /* the label sheet: each sticker flies onto its slot, then the first one
       peels back off and comes up close */
    .sheet-stage { view-timeline-name: --sheet; }
    .sheet > picture.slot { animation: linear both; animation-timeline: --sheet; }
    .sheet > picture.slot:nth-child(2) { animation-name: stick-right; animation-range: cover 12% cover 32%; }
    .sheet > picture.slot:nth-child(3) { animation-name: stick-left; animation-range: cover 18% cover 38%; }
    .sheet > picture.slot:nth-child(4) { animation-name: stick-up; animation-range: cover 24% cover 44%; }
    @keyframes stick-right { from { opacity: 0; transform: translate(80%, -40%) rotate(16deg) scale(1.35); } 35% { opacity: 1; } }
    @keyframes stick-left { from { opacity: 0; transform: translate(-90%, 30%) rotate(-14deg) scale(1.35); } 35% { opacity: 1; } }
    @keyframes stick-up { from { opacity: 0; transform: translate(10%, 150%) rotate(10deg) scale(1.35); } 35% { opacity: 1; } }

    /* the label: sits in its slot, then peels off and comes up close */
    /* label 1 lands in its slot first (transform), then peels (translate /
       rotate / scale): separate properties, so the two animations compose */
    .peel { animation: stick-first linear both, peel linear both; animation-timeline: --sheet, --sheet;
      animation-range: cover 6% cover 26%, cover 44% cover 58%; }
    @keyframes stick-first { from { opacity: 0; transform: translate(-70%, -60%) rotate(-14deg) scale(1.3); } 35% { opacity: 1; } }
    @keyframes peel {
      from { translate: 0 0; rotate: -2deg; scale: var(--k);
        filter: drop-shadow(0 0 0 rgba(0,0,0,0)) drop-shadow(0 0 0 rgba(10, 5, 2, 0)); }
    }

    .statement { view-timeline-name: --statement; }
    .statement span { opacity: .12; animation: word linear both; animation-timeline: --statement; }
    .statement span:nth-child(1) { animation-range: cover 18% cover 28%; }
    .statement span:nth-child(2) { animation-range: cover 24% cover 34%; }
    .statement span:nth-child(3) { animation-range: cover 30% cover 40%; }
    .statement span:nth-child(4) { animation-range: cover 36% cover 46%; }
    .statement span:nth-child(5) { animation-range: cover 42% cover 52%; }
    .statement span:nth-child(6) { animation-range: cover 48% cover 58%; }
    @keyframes word { to { opacity: 1; } }

    /* the story: pinned for four screens; each step lights its line and
       swaps the segment, neighbours overlapping by 4% so they cross-fade */
    .story { height: 420vh; view-timeline-name: --story; margin: 0; }
    .story-stage { position: sticky; top: 0; height: 100vh; }
    .story-media img:not(.m1) { visibility: visible; }
    .story-media img { opacity: 0; animation: shot linear both; animation-timeline: --story; }
    .story-steps li { opacity: .38; animation: step linear both; animation-timeline: --story; }
    .story-media .m1, .story-steps li:nth-child(1) { animation-range: contain 0% contain 27%; }
    .story-media .m2, .story-steps li:nth-child(2) { animation-range: contain 23% contain 52%; }
    .story-media .m3, .story-steps li:nth-child(3) { animation-range: contain 48% contain 77%; }
    .story-media .m4, .story-steps li:nth-child(4) { animation-range: contain 73% contain 100%; }
    .story-media .m1 { animation-name: shot-first; }
    .story-media .m4 { animation-name: shot-last; }
    .story-steps li:nth-child(1) { animation-name: step-first; }
    .story-steps li:nth-child(4) { animation-name: step-last; }
    /* each segment arrives a little too close and pulls back into focus */
    @keyframes shot {
      0% { opacity: 0; transform: translateY(40px) scale(1.1); }
      15%, 85% { opacity: 1; transform: none; }
      100% { opacity: 0; transform: translateY(-40px) scale(.95); }
    }
    @keyframes shot-first { 0%, 85% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(-40px) scale(.95); } }
    @keyframes shot-last { 0% { opacity: 0; transform: translateY(40px) scale(1.1); } 15%, 100% { opacity: 1; transform: none; } }
    @keyframes step {
      0% { opacity: .38; }
      15%, 85% { opacity: 1; background: rgba(210, 107, 28, .14); box-shadow: inset 0 0 0 1px rgba(232, 140, 70, .55); }
      100% { opacity: .38; }
    }
    @keyframes step-first { 0%, 85% { opacity: 1; background: rgba(210, 107, 28, .14); box-shadow: inset 0 0 0 1px rgba(232, 140, 70, .55); } 100% { opacity: .38; } }
    @keyframes step-last { 0% { opacity: .38; } 15%, 100% { opacity: 1; background: rgba(210, 107, 28, .14); box-shadow: inset 0 0 0 1px rgba(232, 140, 70, .55); } }
  }
}

@media (max-width: 860px) and (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    /* phones: the story scrolls as plain cards, not pinned */
    .story { height: auto; margin: 72px 0; }
    .story-stage { position: static; height: auto; }
    .story-steps li { opacity: 1; animation: none; }
    /* phones: nothing pins; each detail flies in as it scrolls into view */
    .assemble { height: auto; }
    .assemble-stage { position: static; height: auto; padding: 16px 0 0; }
    .details li { animation-timeline: view(); }
    .details .d-art, .details .d-specs, .details .d-qr { animation-range: entry 0% cover 32%; }
    .details .d-art { animation-name: in-right; }
    .details .d-specs { animation-name: in-left; }
    .details .d-qr { animation-name: in-below; }
    @keyframes in-left { from { opacity: 0; transform: translateX(-70%) rotate(-5deg) scale(1.15); } 30% { opacity: 1; } }
    .ring { animation: none; }
  }
}
