/* 熊會點 Uncle Foodie — landing page
   World: a Taiwanese 小吃店 order slip. White slip paper with red and green print on a
   green formica table. Print is red ink + green rules; everything 熊伯 writes
   is graphite pencil in one stroke weight. One red seal. */

:root {
  --table: #17553C;
  --table-deep: #10432E;
  --table-950: #0A2C1E;
  --on-table: #F2ECDF;
  --on-table-dim: #B8CDBF;

  --slip: #F8F6F1;
  --slip-2: #DAD5CB;
  --kraft: #C9AA80;
  --yellow: #F6E07A;
  --yellow-2: #E6C94F;

  --red: #C42F2A;
  --red-deep: #9C231F;
  --green-ink: #1F5C41;
  --green-rule: rgba(44, 116, 84, .45);

  --graphite: #36373C;
  --ink: #1E1F23;
  --ink-2: #5B3F3A;
  --paper: #FFFFFF;

  /* Latin letters, digits and Latin punctuation come from Noto Sans; Chinese falls through to Noto Sans TC. */
  --f-print: "Noto Sans", "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", sans-serif;
  --f-pencil: "Iansui", "Kaiti TC", "BiauKai", cursive;
  --f-body: "Noto Sans", "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", sans-serif;
  --f-ja: "Yuji Syuku", "Hiragino Mincho ProN", "Yu Mincho", serif;

  --gutter: clamp(16px, 4vw, 48px);
  --pad-h: 60px;
  --ease-out: cubic-bezier(.16, 1, .3, 1);

  --grain: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='p'><feTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .3  0 0 0 0 .2  0 0 0 0 .2  0 0 0 .09 0'/></filter><rect width='100%' height='100%' filter='url(%23p)'/></svg>");
  --fibre: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='40'><filter id='f'><feTurbulence type='fractalNoise' baseFrequency='.012 .9' numOctaves='2' seed='4'/><feColorMatrix values='0 0 0 0 .55  0 0 0 0 .5  0 0 0 0 .38  0 0 0 .55 0'/></filter><rect width='100%' height='100%' filter='url(%23f)'/></svg>");
  --tape-mask: conic-gradient(from 225deg at 100% 50%, #000 90deg, #0000 0) 0 0 / 4px 6px repeat-y,
               conic-gradient(from 45deg at 0 50%, #000 90deg, #0000 0) 100% 0 / 4px 6px repeat-y,
               linear-gradient(#000 0 0) 50% 0 / calc(100% - 8px) 100% no-repeat;
  --speckle: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='s'><feTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='1' seed='3' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 .95  0 0 0 0 .97  0 0 0 0 .93  9 0 0 0 -5.6'/></filter><rect width='100%' height='100%' filter='url(%23s)' opacity='.22'/></svg>");
}

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

html { -webkit-text-size-adjust: 100%; scroll-padding-top: var(--pad-h); scrollbar-color: var(--table) var(--table-950); }

body {
  margin: 0;
  background: var(--table);
  color: var(--on-table);
  font: 400 1rem/1.7 var(--f-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}

img { display: block; max-width: 100%; height: auto; }
h1, h2, h3, p, ul, ol, dl, dd, figure { margin: 0; padding: 0; }
p { text-wrap: pretty; }
h2 { text-wrap: balance; }
.h1-print, .h1-hand { text-wrap: balance; }
/* Keeps a phrase's last word whole: CJK otherwise breaks between any two characters (查好/了, 念不/出來). */
.nw { white-space: nowrap; }
ul, ol { list-style: none; }
a { color: inherit; }
button { font: inherit; color: inherit; }
table { border-collapse: collapse; }

::selection { background: var(--red); color: #fff; }
:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; border-radius: 3px; }
::-webkit-scrollbar { width: 12px; height: 10px; }
::-webkit-scrollbar-track { background: var(--table-950); }
::-webkit-scrollbar-thumb { background: var(--table); border-radius: 99px; border: 3px solid var(--table-950); }

.sr { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip {
  position: fixed; left: 12px; top: 12px; z-index: 200;
  padding: 8px 14px; background: #fff; color: var(--ink); border-radius: 4px;
  transform: translateY(-160%); transition: transform .2s var(--ease-out);
}
.skip:focus { transform: none; }

/* One pencil. Every mark 熊伯 makes shares this. */
.pencil { font-family: var(--f-pencil); font-weight: 400; color: var(--graphite); }
.tick path,
.circle path,
.wave path {
  fill: none; stroke: var(--graphite);
  stroke-width: 2.8; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1; stroke-dashoffset: 0;
  filter: url(#graphite);
}
/* Small ticks keep the pencil wobble but skip the grain, which breaks them into stipple at this size. */
.tick path {
  filter: url(#pencil-line);
}

/* Perforated tear line between copies */
.perf { position: relative; }
.perf::before {
  content: ""; position: absolute; left: 0; right: 0; top: -6px; height: 12px; z-index: 4;
  background: radial-gradient(circle 3.5px at 9px 6px, var(--table-950) 96%, transparent) 0 0 / 18px 12px repeat-x;
  pointer-events: none;
}

/* ---------- Pad (nav) ---------- */
.pad {
  position: fixed; inset: 0 0 auto; z-index: 100;
  height: var(--pad-h);
  display: flex; align-items: center; justify-content: space-between;
  padding-inline: var(--gutter);
  background: var(--table-950);
  box-shadow: 0 8px 18px -12px rgba(0,0,0,.7);
}
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; }
.brand img { width: 36px; height: 36px; border-radius: 50%; object-fit: cover; }
.brand-zh { font: 900 1.2rem/1 var(--f-print); letter-spacing: .08em; }
.brand-en { font: 500 .78rem/1 var(--f-body); color: var(--on-table-dim); letter-spacing: .04em; }
.pad-actions { display: flex; align-items: center; gap: 14px; }
.lang { display: flex; border: 1px solid rgba(242,236,223,.25); border-radius: 99px; padding: 3px; }
.lang button {
  min-width: 40px; min-height: 32px; padding: 0 10px;
  border: 0; border-radius: 99px; background: transparent; cursor: pointer;
  font: 500 .85rem/1 var(--f-body); color: var(--on-table-dim);
  transition: background .25s var(--ease-out), color .25s;
}
.lang button[aria-pressed="true"] { background: var(--on-table); color: var(--table-950); }
.lang button:hover:not([aria-pressed="true"]) { color: var(--on-table); }
.pad-cta {
  display: inline-flex; align-items: center; min-height: 36px; padding: 0 16px;
  border-radius: 99px; background: var(--slip); color: var(--ink); text-decoration: none;
  font: 700 .9rem/1 var(--f-body);
  transition: background .25s, transform .25s var(--ease-out);
}
.pad-cta:hover { background: #fff; transform: translateY(-1px); }

/* ---------- Slip (shared) ---------- */
.slip {
  position: relative;
  background-color: var(--slip);
  background-image: var(--grain);
  color: var(--ink);
  padding: clamp(20px, 2vw, 30px) clamp(18px, 3vw, 46px) clamp(18px, 2vw, 26px);
  box-shadow: 0 34px 50px -30px rgba(0,0,0,.7), 0 2px 4px rgba(0,0,0,.12);
  -webkit-mask: radial-gradient(circle 3.4px at 50% 0, transparent 96%, #000) 0 0 / 12px 100% repeat-x;
          mask: radial-gradient(circle 3.4px at 50% 0, transparent 96%, #000) 0 0 / 12px 100% repeat-x;
}
.slip-head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 16px;
  padding-bottom: 10px;
  color: var(--red);
}
.slip-kind { display: flex; align-items: baseline; gap: 12px; }
.slip-kind span { font: 900 clamp(1.5rem, 2.2vw, 2.1rem)/1 var(--f-print); letter-spacing: .42em; }
.slip-kind small { font: 500 .7rem/1 var(--f-body); letter-spacing: .24em; color: var(--red-deep); }
.slip-no { font: 500 .8rem/1 var(--f-body); letter-spacing: .06em; color: var(--red-deep); }
.slip-no span { margin-left: 4px; font: 900 1.5rem/1 var(--f-print); font-variant-numeric: tabular-nums; letter-spacing: .08em; }


.h1-print, .h1-hand { display: block; }
.h1-print { font: 900 clamp(2.1rem, 3.7vw, 3.8rem)/1.15 var(--f-print); color: var(--red); letter-spacing: .02em; }
.h1-hand { margin-top: 2px; font-size: clamp(2.3rem, 4.2vw, 4.3rem); line-height: 1.1; transform: rotate(-1.5deg); transform-origin: 0 50%; }
.hero-copy { margin: 0 0 clamp(28px, 5vh, 52px) 6px; }
.hero-copy .h1-print, .hero-copy .h1-hand { color: var(--on-table); }
.hero-copy .h1-print { font-size: clamp(2.4rem, 4.4vw, 4.4rem); }
/* Latin runs longer than CJK at the same size; let the English lede use the full column so it stays on one line. */
html[lang="en"] .hero-copy .lede { max-width: none; }
/* Desktop: the note rises beside the lede, so the lede stops short of it. */
@media (min-width: 1081px) {
  .hero-copy .lede, html[lang="en"] .hero-copy .lede { max-width: min(48em, calc(100% - 270px + var(--cta-over))); }
  /* The English pencil line is a third wider than the Chinese; a touch smaller keeps it clear of the note. */
  html[lang="en"] .hero-copy .h1-hand { font-size: clamp(2.1rem, 3.5vw, 3.7rem); }
}
/* White, not the dim table tint: the table's light speckle would drop a dimmer colour below 4.5:1. */
.lede { margin-top: clamp(10px, 1.6vh, 16px); max-width: 40em; font-size: clamp(1rem, 1.15vw, 1.1rem); line-height: 1.75; color: #fff; }

/* Hero menu: two columns on a wide slip, filled column by column like the 90-second sheet; one column on a narrow slip. */
.slip--hero { container-type: inline-size; }
.hmenu-head, .hmenu { display: grid; grid-template-columns: 1fr 1fr; column-gap: 34px; }
.hmenu-head { margin-top: clamp(8px, 1.4vh, 14px); border-top: 2px solid var(--green-ink); }
.hmenu-head p {
  display: flex; justify-content: space-between; padding: 9px 2px 9px 35px;
  border-bottom: 1px solid var(--green-ink);
  font: 700 .95rem/1 var(--f-body); letter-spacing: .14em; color: var(--green-ink);
}
.hmenu { grid-template-rows: repeat(4, auto); grid-auto-flow: column; }
.hrow {
  display: grid; grid-template-columns: 21px minmax(0, 1fr) auto; column-gap: 14px; align-items: start;
  padding: 13px 2px; border-bottom: 1px solid var(--green-rule);
}
.hrow .box { margin-top: 1px; }
.hcell { min-width: 0; font: 700 1rem/1.35 var(--f-body); color: var(--ink); }
.h-price { font: 700 .95rem/1.4 var(--f-body); font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right; }
@container (max-width: 620px) {
  .hmenu-head, .hmenu { grid-template-columns: 1fr; }
  .hmenu { grid-template-rows: none; grid-auto-flow: row; }
  .hmenu-head p + p { display: none; }
}
.hname { position: relative; display: inline-flex; flex-wrap: wrap; align-items: center; column-gap: 16px; row-gap: 10px; }
.h-orig { position: absolute; left: 0; top: -1px; white-space: nowrap; font: 400 1.12rem/1.3 var(--f-ja); color: var(--ink); }
.h-desc { display: block; margin: 11px 0 2px; font: 400 .88rem/1.35 var(--f-body); color: var(--ink-2); }
/* The reason runs under the price too: line 2 spans the whole row. */
.hrow .h-desc { grid-column: 2 / -1; }

.box {
  position: relative; display: inline-block; vertical-align: middle;
  width: 21px; height: 21px; border: 1.5px solid var(--green-ink); background: rgba(255,255,255,.18);
}
.tick { position: absolute; left: -3px; top: -11px; width: 34px; height: 34px; overflow: visible; }
.circled, .flagged { position: relative; display: inline-block; }
.circle { position: absolute; left: -12px; top: -8px; width: calc(100% + 24px); height: calc(100% + 16px); overflow: visible; pointer-events: none; }
.wave { position: absolute; left: -2px; top: calc(100% - 2px); width: calc(100% + 4px); height: 9px; overflow: visible; pointer-events: none; }

.badge { display: block; border-radius: 9px; transition: transform .35s var(--ease-out); }
.badge:hover { transform: translateY(-2px); }
.badge img { height: 48px; width: auto; }

/* ---------- Hero ---------- */
.hero {
  position: relative; overflow: hidden;
  min-height: 100svh;
  display: flex; align-items: center;
  padding: calc(var(--pad-h) + clamp(36px, 7vh, 80px)) var(--gutter) clamp(32px, 6vh, 64px);
  background-color: var(--table);
  background-image: var(--speckle);
}
.hero-main {
  position: relative; z-index: 2;
  --ml: clamp(0px, 3vw, 64px);
  /* The note pokes --cta-over past the menu's right edge and must stop 20px short of 熊伯, whose hat, face and
     shoulder start ~12% into his image (bear-h × .533 wide, 2vw off the right edge): the menu ends there minus the overhang. */
  --cta-over: clamp(30px, 16vw - 180px, 110px);
  width: min(100%, 66vw, 960px, calc(100% + var(--gutter) - var(--ml) - var(--bear-h) * .469 + 2vw - 20px - var(--cta-over)));
  margin-left: var(--ml);
}
.slip-anchor { position: relative; }
.slip--hero { transform: rotate(-1.1deg); }
.hero { --bear-h: min(96svh, 66vw, 1000px); }
.peek { position: absolute; z-index: 1; right: -2vw; bottom: -6svh; }
.peek img {
  height: var(--bear-h); width: auto;
  filter: drop-shadow(-18px 24px 30px rgba(0,0,0,.4));
}

/* Download note stuck on the menu's top-right corner */
.hero-cta {
  position: absolute; z-index: 3;
  /* Bottom edge 56px into the menu: over the empty corner beside 菜單, clear of the column headers. */
  right: calc(-1 * var(--cta-over)); bottom: calc(100% - 56px);
  display: grid; justify-items: start; gap: 12px;
  max-width: 240px;
  padding: 18px 20px 20px;
  background-color: var(--slip); background-image: var(--grain);
  box-shadow: 0 22px 30px -16px rgba(0,0,0,.6);
  transform: rotate(3deg);
}
.hero-cta::before {
  content: ""; position: absolute; left: 50%; top: -10px; width: 74px; height: 20px; margin-left: -37px;
  background: rgba(238,229,201,.82) var(--fibre); -webkit-mask: var(--tape-mask); mask: var(--tape-mask); transform: rotate(-4deg);
}
.hero-cta-title { font: 900 clamp(1.3rem, 1.8vw, 1.7rem)/1.2 var(--f-print); color: var(--red); letter-spacing: .04em; text-wrap: balance; }
/* English runs long: a size that keeps the note two lines tall, so it does not climb into the headline. */
html[lang="en"] .hero-cta-title { font-size: 1rem; letter-spacing: 0; white-space: nowrap; }
.badge--big img { height: 60px; }

/* ---------- Japanese menu sheet (shared by No-slip and Ninety) ---------- */
.sheet {
  position: relative;
  background: #fff; color: var(--ink);
  border-radius: 10px;
  padding-bottom: 14px;
  box-shadow: 0 30px 50px -26px rgba(0,0,0,.6), inset 0 0 0 1px rgba(0,0,0,.06);
  overflow: hidden;
}
.sheet::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit; opacity: var(--sheen, 1);
  background: linear-gradient(118deg, transparent 30%, rgba(255,255,255,.45) 38%, transparent 46%);
  mix-blend-mode: soft-light;
}
.sheet-head { position: relative; display: grid; margin-bottom: 6px; }
.sheet-head > * { grid-area: 1 / 1; }
.sh-th {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 14px 22px 12px; background: var(--red); color: #fff;
}
.sh-th b { font: 400 1.45rem/1.2 var(--f-ja); letter-spacing: .06em; }
.sh-th small { font: 400 .95rem/1.2 var(--f-ja); opacity: .92; }
.sh-slip {
  display: flex; align-items: flex-end; justify-content: space-between;
  margin: 0 22px; padding: 16px 0 10px; border-bottom: 2px solid var(--red); color: var(--red);
  opacity: 0;
}
.sheet-rows { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: repeat(7, auto); grid-auto-flow: column; column-gap: 26px; padding: 0 22px; }
.row {
  position: relative;
  display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 10px;
  min-height: 42px; padding: 6px 2px;
  border-bottom: 1px dashed #D9DCE1;
}
/* Line 1: box, name, 熊伯's pill right beside the name, price at the edge. Line 2: what the dish is. */
.sheet--live .row { grid-template-columns: auto minmax(0, 1fr) auto; row-gap: 3px; }
/* Name and pill share a wrapping line: a long English name pushes the pill under it instead of off the sheet. */
.row-head { display: flex; flex-wrap: wrap; align-items: center; column-gap: 16px; row-gap: 10px; min-width: 0; }
.sheet--live .desc { grid-column: 2 / -1; grid-row: 2; }
.desc { font: 400 .8rem/1.4 var(--f-body); color: var(--ink-2); opacity: 0; text-wrap: pretty; }
/* Circles and waves reach ~7px below the name; keep them off the description. */
.sheet--live .row--pick, .sheet--live .row--skip { row-gap: 7px; }
.row .box { opacity: 0; }
.row-name { position: relative; display: grid; justify-self: start; }
.row-name > .orig, .row-name > .tr { grid-area: 1 / 1; align-self: center; }
.orig { font: 400 1.02rem/1.3 var(--f-ja); }
.tr { font: 700 .95rem/1.3 var(--f-body); opacity: 0; }
.pill {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 3px 8px 3px 7px; border-radius: 99px;
  font: 700 .84rem/1.2 var(--f-body); white-space: nowrap;
  opacity: 0;
}
.pill svg { width: 12px; height: 12px; fill: currentColor; flex: none; }
.pill--pick { color: #556B4E; background: #E9F0E6; }
.pill--skip { color: #B03636; background: #FBE9E7; }
.sheet-rows { position: relative; }
.scan { position: absolute; left: 14px; right: 14px; top: 0; height: 42px; border-radius: 4px; background: rgba(255,255,255,.5); opacity: 0; pointer-events: none; }
.row-price { font: 700 .95rem/1 var(--f-body); font-variant-numeric: tabular-nums; min-width: 2.8em; text-align: right; white-space: nowrap; }
.row .circle path, .row .wave path { stroke-dashoffset: 1; opacity: 0; }
.sheet--live .orig, .sheet--live .tr { white-space: nowrap; }
/* The original fades out before the translation lands, so it must not hold the column open afterwards. */
.sheet--live .row-name > .orig { position: absolute; left: 0; top: 50%; translate: 0 -50%; }
html[lang="en"] .sheet--live .tr { white-space: normal; }
html[lang="en"] .sheet--live .tr { font-size: .9rem; }
html[lang="en"] .sheet--live .row--pick .tr { white-space: nowrap; }
.sheet--live .orig { font-size: .92rem; }

/* ---------- 00:00 No slip ---------- */
.noslip {
  --ink-2: #4A3726;
  --noslip-pad: clamp(100px, 15vh, 170px);
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(36px, 5vw, 88px);
  align-items: start;
  padding: var(--noslip-pad) var(--gutter);
  overflow: clip;
  background-color: var(--kraft);
  background-image: var(--grain);
  color: #2B1D12;
}
.noslip-copy { max-width: 560px; justify-self: end; }
.noslip h2 { font: 900 clamp(2rem, 3.6vw, 3.4rem)/1.25 var(--f-print); color: #2B1D12; text-wrap: balance; }
.noslip-lede { margin-top: 22px; max-width: 30em; font-size: clamp(1rem, 1.2vw, 1.12rem); color: var(--ink-2); }

/* 熊伯 cut out on the kraft (no frame), so the three framed photos alone read as the evidence. */
/* Large and cut off by the section's bottom edge: his steam runs off the page. */
/* Desktop: well in from the left edge and always cut off by the section's bottom edge, even when the photo
   column is the taller one (the copy column stretches and 熊伯 is pushed to its foot). */
/* width: 100% keeps the copy inside its column; without it the bear's fixed width + margin made the column
   wider than the grid track on 1081–1660px screens, and justify-self: end pushed the headline off the left edge. */
.noslip-copy { align-self: stretch; display: flex; flex-direction: column; width: 100%; }
@media (min-width: 1081px) { .noslip-lede { margin-bottom: 28px; } }
.steam-bear { width: clamp(300px, 28vw, 420px); margin: auto 0 calc(-1 * var(--noslip-pad)) clamp(40px, 13vw, 200px); }
.steam-bear img { width: 100%; height: auto; filter: drop-shadow(0 14px 18px rgba(60,40,20,.18)); }

/* Three real photos, one per worry. Photos lying on the table, no tape. */
.pains { position: relative; z-index: 1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(16px, 2vw, 30px); width: 100%; max-width: 720px; align-items: start; margin-top: clamp(24px, 4vw, 64px); }
.pain figure { padding: 8px 8px 16px; background: #fff; box-shadow: 0 18px 28px -14px rgba(0,0,0,.5); }
.pain img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.pain figcaption { padding: 12px 6px 0; }
.pain b { display: block; font: 900 1.3rem/1.25 var(--f-print); color: var(--red-deep); }
.pain figcaption > span { display: block; margin-top: 6px; font-size: .95rem; line-height: 1.6; color: var(--ink); }
.pain--a { transform: rotate(-2.5deg); margin-top: 48px; }
.pain--b { transform: rotate(1.8deg); }
.pain--c { transform: rotate(-1.2deg); margin-top: 84px; }
.pain--a img { object-position: 40% 50%; }
.pain--c img { object-position: 58% 50%; }

/* ---------- 00:05 → 01:30 Ninety ---------- */
/* GSAP pins this section with the pixel width it measured last. After a resize (or a DevTools device switch) that stale
   width can be wider than the screen; a mobile layout viewport then grows to fit it, re-measures, and stays too wide.
   Capping both the spacer and the section at their container keeps the page at the screen's width no matter what. */
.pin-spacer { width: auto !important; max-width: 100% !important; }
.ninety { max-width: 100% !important; }
/* No speckle here: its light flecks drop the dim phase copy to ~3:1 at the fleck pixels (WCAG G18 measures beside each glyph). */
.ninety {
  overflow: clip;
  background-color: var(--table);
}
.ninety-pin {
  height: 100svh; max-width: 1440px; margin: 0 auto;
  display: grid; grid-template-columns: minmax(300px, 5fr) minmax(0, 7fr);
  gap: clamp(28px, 4vw, 72px); align-items: center;
  padding: calc(var(--pad-h) + 28px) var(--gutter) 32px;
}
.ninety-copy h2 { font: 900 clamp(1.8rem, 2.9vw, 2.8rem)/1.25 var(--f-print); text-wrap: balance; word-break: keep-all; }
.clock {
  margin: clamp(14px, 3vh, 30px) 0 clamp(18px, 3.4vh, 34px);
  font: 700 clamp(3.4rem, 7vw, 6rem)/1 var(--f-body);
  font-variant-numeric: tabular-nums; letter-spacing: -.02em; color: var(--on-table);
}
.phases { display: grid; gap: clamp(8px, 1.6vh, 16px); }
.phase { display: grid; grid-template-columns: 1fr; transition: opacity .45s var(--ease-out); }
.phase.is-active { opacity: 1; }
/* The big clock already shows the time, so each beat's timestamp is for screen readers only. */
.phase-t { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.phase h3 { font: 700 1.15rem/1.5 var(--f-body); color: #B4CDBE; transition: color .45s, font-size .35s var(--ease-out); }
.phase.is-active h3 { color: #fff; }
.phase p { font-size: .95rem; line-height: 1.65; color: #B4CDBE; max-width: 21em; transition: color .45s; }
/* The current beat reads as one unit: description in the title's white, a little air between them. */
.phase.is-active p { color: #fff; margin-top: 6px; }
/* Desktop: like phones, only the current beat shows (the big clock is the timeline), set larger,
   its title one clear step (~1.3x) above its description; it stays clear of 熊伯 on the right. */
@media (min-width: 721px) {
  .ninety:not(.is-static) .phase h3, .phase.is-active h3 { font-size: clamp(1.3rem, 1.6vw, 1.5rem); line-height: 1.35; }
  .ninety:not(.is-static) .phase p, .phase.is-active p { font-size: clamp(1.02rem, 1.2vw, 1.14rem); max-width: 24em; }
}
/* Beats share one grid cell and only the current one is visible: the list is as tall as its tallest beat
   at any width, language or font state, so nothing below it can be overlapped. */
.ninety:not(.is-static) .phase { grid-area: 1 / 1; opacity: 0; }
.ninety:not(.is-static) .phase.is-active { opacity: 1; }
.ninety-note { margin-top: clamp(14px, 2.4vh, 24px); font-size: .78rem; line-height: 1.5; color: #B4CDBE; }

.ninety-stage { position: relative; height: min(78svh, 720px); display: grid; place-items: center; }
.sheet-wrap { position: relative; width: min(100%, 720px); container-type: inline-size; }
/* Two columns only when each column can hold name + pill + price; otherwise one column of the key rows. */
/* Roomier rows wherever the pinned scene has the height; phones keep tighter rows so the sheet fits one screen. */
@media (min-width: 721px) and (min-height: 700px) {
  .sheet--live .row { min-height: 52px; padding-block: 9px; }
}
@media (max-width: 720px) and (min-height: 761px) {
  .sheet--live .row { min-height: 0; padding-block: 7px; }
}
/* Phones: the description line costs height, so it is set small and tight; the 時間為示意 note must stay on screen. */
@media (max-width: 720px) {
  .sheet--live .row { row-gap: 1px; }
  /* Marks drawn a little tighter on phones, with just enough room under them for the description. */
  .sheet--live .row--pick, .sheet--live .row--skip { row-gap: 5px; }
  .sheet--live .circle { top: -5px; height: calc(100% + 10px); }
  .sheet--live .wave { height: 7px; }
  .desc { font-size: .74rem; line-height: 1.3; }
}
/* Short phones (iPhone SE) only have room for five dishes: every pick and warning stays, the plain dishes go. */
@media (max-width: 720px) and (max-height: 760px) {
  .sheet--live .row { min-height: 0; padding-block: 6px; }
  .sheet--live .row--extra { display: none; }
  .desc { font-size: .7rem; }
  /* English menu names run longer in Noto Sans; a touch smaller keeps the scene inside an iPhone SE screen. */
  html[lang="en"] .sheet--live .tr { font-size: .8rem; }
}
@container (max-width: 679px) {
  .sheet--live .sheet-rows { grid-template-columns: 1fr; grid-template-rows: none; grid-auto-flow: row; }
  .sheet--live .row--minor { display: none; }
}
.sheet--live { width: 100%; }
/* The camera frame hugs the sheet itself, at any height. */
.viewfinder { position: absolute; inset: -16px; pointer-events: none; opacity: 0; }
.viewfinder i { position: absolute; width: 44px; height: 44px; border: 0 solid #fff; }
.viewfinder i:nth-child(1) { left: 0; top: 0; border-width: 4px 0 0 4px; }
.viewfinder i:nth-child(2) { right: 0; top: 0; border-width: 4px 4px 0 0; }
.viewfinder i:nth-child(3) { left: 0; bottom: 0; border-width: 0 0 4px 4px; }
.viewfinder i:nth-child(4) { right: 0; bottom: 0; border-width: 0 4px 4px 0; }
.flash { position: absolute; inset: -60px; z-index: 5; background: #fff; opacity: 0; pointer-events: none; }
.ninety-copy { position: relative; }
.clock-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
/* Desktop and tablet: 熊伯 behind the menu's lower-left corner, the menu overlapping him a little. Phones: by the clock. */
.reader-desk {
  --rd-w: clamp(170px, 15vw, 240px);
  position: absolute; z-index: 0; width: var(--rd-w); height: auto;
  right: calc(100% - var(--rd-w) * .14); bottom: calc(var(--rd-w) * -.3);
  filter: drop-shadow(0 16px 20px rgba(0,0,0,.28));
}
.sheet--live { z-index: 1; }
@media (min-width: 721px) { .clock-row .reader { display: none; } }
/* Tablet: the copy column is narrow, so 熊伯 is smaller and sits lower, below the timing note, cut off by the section edge. */
@media (min-width: 721px) and (max-width: 1080px) { .reader-desk { --rd-w: 150px; bottom: calc(var(--rd-w) * -.62); } }
@media (max-width: 720px) { .reader-desk { display: none; } }
.ninety-copy { --reader-w: clamp(150px, 12vw, 200px); }
/* 熊伯 cut out (no frame) and always at the table, reading along; his faded lower edge tucks over the first beats. */
.reader {
  position: relative; z-index: 2; flex: 0 0 auto;
  width: var(--reader-w); height: auto; margin: 10px 0 calc(var(--reader-w) * -.62) 0;
  filter: drop-shadow(0 16px 20px rgba(0,0,0,.28));
}

.seal {
  position: absolute; z-index: 6;
  display: grid; place-items: center;
  writing-mode: vertical-rl;
  width: 92px; height: 92px; padding: 6px;
  border: 4px solid var(--red); border-radius: 6px;
  color: var(--red);
  font: 900 1.32rem/1 var(--f-print); letter-spacing: .04em; white-space: nowrap;
  transform: rotate(-9deg);
  opacity: .9;
  -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='m'><feTurbulence type='fractalNoise' baseFrequency='.7' numOctaves='2' seed='11'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 -2.2 2.1'/></filter><rect width='100%' height='100%' filter='url(%23m)'/></svg>");
          mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='m'><feTurbulence type='fractalNoise' baseFrequency='.7' numOctaves='2' seed='11'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 -2.2 2.1'/></filter><rect width='100%' height='100%' filter='url(%23m)'/></svg>");
}

/* ---------- Real app · kitchen ticket rail ---------- */
.real {
  --ink-2: #4A3726;
  padding: clamp(100px, 15vh, 160px) 0 clamp(80px, 11vh, 120px);
  /* The ticket width math uses 100vw, which counts a classic (Windows) scrollbar; clip the few extra px so the page can't shift sideways. */
  overflow-x: clip;
  background-color: var(--kraft);
  background-image: var(--grain);
  color: var(--ink);
}
.real-head { max-width: 1400px; margin: 0 auto; padding: 0 var(--gutter); }
.real-head h2 { font: 900 clamp(2rem, 3.6vw, 3.4rem)/1.25 var(--f-print); color: #2B1D12; text-wrap: balance; }
.real-head p { margin-top: 18px; max-width: 34em; font-size: clamp(1rem, 1.2vw, 1.12rem); color: var(--ink-2); }
.real-track {
  margin-top: clamp(48px, 8vh, 80px);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter);
  scrollbar-width: thin; scrollbar-color: rgba(43,29,18,.4) transparent;
  /* A horizontal scroller clips vertically too, so leave room under the tickets for their drop shadow
     (16px offset + 18px blur, plus the tilt), then pull the extra height back so the section spacing is unchanged. */
  padding-bottom: 56px; margin-bottom: -38px;
  cursor: grab;
}
.real-track.is-dragging { cursor: grabbing; scroll-snap-type: none; }
.real-track.is-dragging img { pointer-events: none; }
/* At least as wide as the screen, so the rod always runs edge to edge; the tickets start in line with the heading. */
.rail-row {
  position: relative; display: flex; gap: clamp(26px, 3vw, 48px); width: max-content; min-width: 100%;
  padding: 34px max(var(--gutter), calc((100vw - 1400px) / 2)) 0;
}
/* Tablet and up, where three tickets fit: the tickets and the heading share one centre line (the rods still run edge to edge).
   Phones keep everything left-aligned, where each rail scrolls. */
@media (min-width: 721px) {
  /* Three tickets always fit here, so the rail is not a scroller: a ticket swung past the edge (hover wiggle, drag)
     must not make it scrollable, which would snap the whole rail sideways. Shadows can overflow freely. */
  .real-track { overflow: visible; scroll-snap-type: none; }
  .rail-row { justify-content: center; }
  /* A ticket is as wide as its screenshot; longer (English) captions wrap under it instead of pushing the rail past the screen. */
  .ticket { width: min-content; }
  .real-head { text-align: center; }
  .real-head p { margin-inline: auto; }
}
/* The second rail hangs just below the first (the first one's shadow room overlaps this gap). */
.real-track + .real-track { margin-top: clamp(4px, 1.5vh, 16px); }
.rail-row::before {
  content: ""; position: absolute; left: 0; right: 0; top: 20px; height: 8px;
  border-radius: 4px; background: var(--graphite);
}
.ticket {
  position: relative; display: grid; justify-items: stretch;
  scroll-snap-align: start;
  transform-origin: 50% -14px;
  filter: drop-shadow(0 16px 18px rgba(90,30,30,.28));
}
.ticket:nth-child(odd) { rotate: -1.4deg; }
.ticket:nth-child(even) { rotate: 1.2deg; }
/* Draggable along the rod on tablet and up: horizontal drags move the ticket, vertical ones still scroll the page. */
@media (min-width: 721px) {
  .ticket { cursor: grab; touch-action: pan-y; user-select: none; -webkit-user-select: none; }
  .ticket img { -webkit-user-drag: none; pointer-events: none; }
  .ticket.is-sliding { cursor: grabbing; z-index: 2; }
}
.clip {
  position: absolute; z-index: 2; top: -20px; left: 50%; width: 40px; height: 28px; margin-left: -20px;
  border-radius: 3px 3px 5px 5px; background: var(--graphite);
}
.clip::after { content: ""; position: absolute; left: 8px; right: 8px; bottom: 6px; height: 3px; border-radius: 2px; background: var(--slip); }
.ticket-paper {
  padding: 16px 14px 12px;
  background-color: #fff; background-image: var(--grain);
  -webkit-mask: radial-gradient(circle 3.4px at 50% 0, transparent 96%, #000) 0 0 / 12px 100% repeat-x;
          mask: radial-gradient(circle 3.4px at 50% 0, transparent 96%, #000) 0 0 / 12px 100% repeat-x;
}
.ticket-head {
  display: flex; justify-content: space-between; gap: 10px;
  padding-bottom: 6px; margin-bottom: 10px; border-bottom: 1.5px solid var(--red);
  font: 500 .72rem/1 var(--f-body); letter-spacing: .12em; color: var(--red-deep);
}
.ticket-head span:last-child { font: 900 .85rem/1 var(--f-print); letter-spacing: .04em; }
.shot { width: clamp(230px, 19vw, 280px); }
/* Tablet and up: three tickets per rail always fit the screen (on wide screens this never bites). */
@media (min-width: 721px) { .shot { width: min(clamp(230px, 19vw, 280px), calc((100vw - 2 * var(--gutter) - 2 * clamp(26px, 3vw, 48px)) / 3 - 30px)); } }
.shot img { border-radius: 10px; aspect-ratio: 640 / 1391; object-fit: cover; box-shadow: inset 0 0 0 1px rgba(0,0,0,.1); outline: 1px solid rgba(0,0,0,.12); outline-offset: -1px; }
.ticket figcaption {
  padding: 4px 14px 14px;
  background-color: #fff; background-image: var(--grain); color: var(--ink);
  border-top: 1px dashed var(--slip-2);
  text-align: left;
}
.ticket figcaption b { display: block; padding-top: 8px; font: 900 1.05rem/1.3 var(--f-print); }
/* App-screen captions describe the app, not 熊伯, so they use the body face; a little air between title and line. */
.ticket figcaption span { display: block; margin-top: 6px; font: 400 .95rem/1.5 var(--f-body); color: var(--ink-2); }

/* ---------- House rules · yellow copy ---------- */
.rules {
  padding: clamp(100px, 15vh, 160px) var(--gutter);
  background-color: var(--table);
  background-image: var(--speckle);
  color: var(--ink);
}
.rules-form { max-width: 980px; margin: 0 auto; }
.slip--rules { transform: rotate(-.6deg); }
.rule-list { margin-top: clamp(14px, 2vh, 22px); border-top: 2px solid var(--green-ink); }
.rule {
  display: grid; grid-template-columns: 2.4em minmax(0, 1fr) auto; align-items: center; gap: 14px;
  padding: clamp(12px, 1.8vh, 18px) 4px; border-bottom: 1px solid var(--green-rule);
}
.rule-no { font: 900 1.1rem/1 var(--f-print); color: var(--green-ink); text-align: center; }
.rule-text { display: grid; gap: 2px; }
.rule-text b { font: 700 clamp(1.15rem, 1.7vw, 1.45rem)/1.35 var(--f-print); }
.rule-text > span { font: 400 clamp(.95rem, 1.15vw, 1.05rem)/1.6 var(--f-body); color: var(--ink-2); }
.rule .box { width: 26px; height: 26px; }
.rule .tick { width: 40px; height: 40px; left: -4px; top: -14px; }
/* Same pencil as everywhere 熊伯 writes; the copy is told by the 存根 stamp and the torn top sheet, not by a blue ink. */
.rule-text b { color: var(--ink); }
.rules-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px 32px; padding-bottom: 14px; }
.rules-head h2 { font: 900 clamp(2rem, 3.6vw, 3.4rem)/1.2 var(--f-print); color: var(--red); letter-spacing: .1em; }

/* FAQ: printed on the same yellow copy, under the house rules */
.faq-sec {
  --ink-2: #4B4E55;
  padding: clamp(96px, 14vh, 150px) var(--gutter);
  background-color: #F3F2EE; background-image: var(--grain);
  color: var(--ink);
}
.faq-wrap { max-width: 980px; margin: 0 auto; }
.faq-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px 32px; padding-bottom: 14px; margin-bottom: 4px; border-bottom: 2px solid var(--ink); }
.faq-head h2 { font: 900 clamp(2rem, 3.6vw, 3.4rem)/1.2 var(--f-print); letter-spacing: .1em; }
.faq-head p { max-width: 24em; color: var(--ink-2); font-size: clamp(1rem, 1.2vw, 1.12rem); }
.faq-item { border-bottom: 1px solid rgba(30,31,35,.18); }
.faq-item summary {
  position: relative; display: block; cursor: pointer; list-style: none;
  padding: clamp(22px, 3.2vh, 30px) 44px clamp(22px, 3.2vh, 30px) 2px;
  font: 700 clamp(1.1rem, 1.6vw, 1.35rem)/1.4 var(--f-print); color: var(--ink);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::before, .faq-item summary::after {
  content: ""; position: absolute; right: 12px; top: 50%; width: 16px; height: 2px; margin-top: -1px;
  background: var(--red); transition: transform .3s var(--ease-out);
}
.faq-item summary::after { transform: rotate(90deg); }
.faq-item[open] summary::after { transform: rotate(0); }
.faq-item summary:hover { color: var(--red); }
/* Answers run the full width of the list; "pretty" only rebalances the last lines so none ends on a lone character. */
.faq-item p { padding: 0 2px 28px; font-size: clamp(1rem, 1.2vw, 1.08rem); line-height: 1.75; color: var(--ink-2); text-wrap: pretty; }

/* ---------- Send ---------- */
.send {
  position: relative;
  display: grid; place-items: center;
  padding: clamp(110px, 16vh, 180px) var(--gutter) clamp(110px, 16vh, 170px);
  background-color: var(--table);
  background-image: var(--speckle);
  overflow: hidden;
}
.send-pad { position: relative; z-index: 2; width: min(100%, 760px); }
/* The rest of the pad the last slip is torn from: glued binding, stacked sheet edges, perforated bottom. */
.pad-stub {
  height: 44px; margin: 0 3px -1px;
  background:
    linear-gradient(180deg, #6E2A22 0 11px, transparent 11px),
    repeating-linear-gradient(180deg, transparent 0 6px, rgba(150,70,60,.18) 6px 7px, transparent 7px 11px),
    repeating-linear-gradient(180deg, var(--slip) 0 3px, #D9D3C7 3px 4px, var(--slip) 4px 8px, #E4DFD5 8px 9px);
  box-shadow: 0 10px 16px -12px rgba(0,0,0,.6);
  -webkit-mask: radial-gradient(circle 3.4px at 50% 100%, transparent 96%, #000) 0 0 / 12px 100% repeat-x;
          mask: radial-gradient(circle 3.4px at 50% 100%, transparent 96%, #000) 0 0 / 12px 100% repeat-x;
}
.slip--send { width: 100%; transform: rotate(1deg) translateY(16px); }
/* The finale: one big line, one big button, and on desktop a QR to scan with the phone. */
/* The headline now opens the slip; keep it clear of the 熊會點 seal in the corner. */
/* Only the first line shares its row with the seal; the pencil line uses the full width and never breaks. */
.slip--send { container-type: inline-size; }
.slip--send .h1-print { padding-right: 110px; }
.send-actions { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-top: clamp(24px, 3.6vh, 36px); padding-top: clamp(20px, 3vh, 28px); border-top: 1px solid var(--green-rule); }
.slip--send .h1-print { font-size: clamp(2.4rem, 4.6vw, 4.4rem); }
.slip--send .h1-hand { font-size: min(clamp(2.6rem, 5vw, 4.8rem), 11.6cqi); white-space: nowrap; }
html[lang="en"] .slip--send .h1-hand { font-size: min(clamp(2.6rem, 5vw, 4.8rem), 10.2cqi); }
/* Desktop and tablet: the stamp sits top-right, so the one-line headline also stops short of it. */
@media (min-width: 721px) {
  .slip--send .h1-hand { font-size: min(clamp(2.6rem, 5vw, 4.8rem), calc((100cqi - 124px) / 8.4)); }
  html[lang="en"] .slip--send .h1-hand { font-size: min(clamp(2.6rem, 5vw, 4.8rem), calc((100cqi - 124px) / 9.4)); }
}
.send-qr[hidden] { display: none; }
.send-qr { display: grid; justify-items: center; gap: 8px; margin: 0; }
.qr-box { width: clamp(132px, 12vw, 168px); padding: 10px; background: #fff; border: 1.5px dashed var(--green-ink); }
.qr-box svg { display: block; width: 100%; height: auto; }
.qr-box svg path, .qr-box svg rect[fill="black"], .qr-box svg rect:not([fill="white"]) { fill: var(--ink); }
.send-qr figcaption { font-size: 1.05rem; transform: rotate(-2deg); }
.slip--send .seal { position: absolute; right: clamp(18px, 3vw, 40px); top: clamp(14px, 2vw, 26px); }
.js .slip--send { transform: none; }
/* Last slip: headline, then one ruled action row. Nothing else competes with the download. */
/* 熊伯 at his stove, cut out (no frame), standing on the table to the right of the last slip. */
/* Centred in the margin right of the slip (the margin is (100vw - 760px) / 2), sized to leave air on both sides. */
.kitchen-bear {
  --kb-w: clamp(200px, calc((100vw - 760px) / 2 - 64px), 320px);
  position: absolute; z-index: 1; margin: 0;
  right: calc((100vw - 760px) / 4 - var(--kb-w) / 2); top: 50%;
  width: var(--kb-w);
  transform: translateY(-46%);
}
.kitchen-bear img { width: 100%; height: auto; filter: drop-shadow(0 18px 22px rgba(0,0,0,.35)); }

/* ---------- Stub (footer) ---------- */
.stub {
  display: grid; grid-template-columns: auto 1fr auto; gap: clamp(24px, 5vw, 72px); align-items: start;
  padding: clamp(48px, 8vh, 72px) var(--gutter) 40px;
  background: var(--table-950); color: var(--on-table-dim);
}
.stub-brand { display: flex; align-items: center; gap: 14px; }
.stub-brand img { width: 56px; height: 56px; border-radius: 50%; object-fit: cover; }
.stub-brand b { display: block; font: 900 1.5rem/1.1 var(--f-print); color: var(--on-table); letter-spacing: .08em; }
.stub-brand span { font-size: .85rem; }
.stub-info { display: grid; grid-template-columns: repeat(3, auto); gap: 8px 40px; justify-content: start; }
.stub-info dt { font: 500 .78rem/1.4 var(--f-body); letter-spacing: .1em; }
.stub-info dd { font: 400 1.05rem/1.5 var(--f-body); color: var(--on-table); }
.stub a { text-decoration-color: rgba(242,236,223,.35); text-underline-offset: 4px; }
.stub a:hover { color: #fff; text-decoration-color: var(--on-table); }
.stub-legal { display: grid; gap: 6px; text-align: right; font-size: .85rem; }
.stub-legal p:first-child { display: flex; gap: 18px; justify-content: flex-end; }

/* Without a side margin, 熊伯 steps below the slip instead. */
@media (max-width: 1260px) {
  .kitchen-bear { position: relative; right: auto; top: auto; transform: none; width: clamp(200px, 40vw, 260px); margin-top: 36px; }
}


/* ---------- Tablet ---------- */
@media (max-width: 1080px) {
  .hero-main { width: min(100%, 74vw); margin-left: 0; --ml: 0px; }
  .hero-cta { max-width: none; }
  .hero { flex-wrap: wrap; align-content: center; gap: 28px; }
  .hero-cta { position: relative; right: auto; bottom: auto; width: fit-content; margin-top: 28px; transform: rotate(-1.5deg); }
  .peek img { height: min(70svh, 60vw); }
  .noslip { grid-template-columns: 1fr; }
  .noslip-copy { justify-self: start; }
  .pains { justify-self: center; }
  .ninety-copy { --reader-w: 112px; }
  .stub { grid-template-columns: 1fr; }
  .stub-legal { text-align: left; }
  .stub-legal p:first-child { justify-content: flex-start; }
}

/* Tablet: one column, so the three photos come straight after the lede and 熊伯 closes the section below them. */
@media (min-width: 721px) and (max-width: 1080px) {
  .noslip { row-gap: 0; }
  .noslip-copy { display: contents; }
  .noslip h2 { order: 1; }
  .noslip-lede { order: 2; max-width: 36em; }
  .pains { order: 3; margin-top: 48px; }
  .steam-bear { order: 4; justify-self: center; width: clamp(280px, 46vw, 420px); margin: 48px 0 calc(-1 * var(--noslip-pad)); }
}

/* ---------- Phone ---------- */
@media (max-width: 720px) {
  :root { --pad-h: 56px; }
  .brand-en { display: none; }
  .pad-cta { padding: 0 12px; font-size: .82rem; }

  .hero { display: block; padding-top: calc(var(--pad-h) + 36px); padding-bottom: 40px; }
  .hero-cta { margin-top: 26px; }
  .hero-main { width: 100%; }
  .hero-copy { max-width: 60%; margin: 0 0 24px; }
  .slip--hero { transform: rotate(-.6deg); }
  .peek { top: calc(var(--pad-h) + 4px); right: -14px; bottom: auto; }
  .peek img { height: 300px; }
  .slip-kind span { letter-spacing: .3em; }
  .slip-kind small { display: none; }
  .h1-print { font-size: clamp(1.9rem, 8.6vw, 2.4rem); }
  .h1-hand { font-size: clamp(2.1rem, 9.4vw, 2.6rem); }
  .h-desc { font-size: .82rem; }
  .hrow { column-gap: 11px; padding-block: 11px; }
  .hcell { font-size: .95rem; }
  .h-price { font-size: .9rem; }

  .noslip { --noslip-pad: 88px; padding-block: 88px 96px; }
  /* Phone: 熊伯 peeks out from behind the first card; each worry is a photo-left, words-right card. */
  .steam-bear { --sb-w: 48vw; width: var(--sb-w); margin: 20px auto calc(var(--sb-w) * -.45); }
  .pains { position: relative; z-index: 1; }
  .pains { grid-template-columns: 1fr; gap: 18px; margin-top: 12px; }
  .pain--a, .pain--c { margin-top: 0; }
  .pain--a, .pain--b, .pain--c { transform: none; }
  .pain figure { display: grid; grid-template-columns: 42% minmax(0, 1fr); gap: 14px; align-items: center; padding: 8px; }
  .pain img { aspect-ratio: 1; }
  .pain figcaption { padding: 0; }
  .pain b { font-size: 1.25rem; }
  .pain figcaption > span { font-size: 1rem; }

  .sh-th { padding: 12px 16px 10px; }
  .sh-th b { font-size: 1.2rem; }
  .sh-slip { margin: 0 16px; }
  .sheet-rows { grid-template-columns: 1fr; grid-template-rows: none; grid-auto-flow: row; padding: 0 16px; }
  .row { min-height: 33px; padding: 3px 2px; gap: 8px; }
  .orig, .tr, .row-price { font-size: .9rem; }
  .row--minor { display: none; }
  .pill { font-size: .72rem; padding: 2px 7px 2px 6px; }
  .pill svg { width: 10px; height: 10px; }

  .ninety-pin {
    grid-template-columns: 1fr; grid-template-rows: auto 1fr;
    /* Start, not centre: a centred column taller than the screen would slide up under the header.
       The copy row takes the rest of the screen: clock and step sit lower, the timing note sits at the bottom. */
    align-content: stretch; align-items: start; gap: 12px;
    padding: calc(var(--pad-h) + 24px) var(--gutter) 12px;
  }
  .ninety-copy { order: 2; align-self: stretch; display: flex; flex-direction: column; }
  .ninety-copy .clock-row { margin-top: auto; }
  .ninety-copy h2 { display: none; }
  .clock { font-size: 2.3rem; margin: 0 0 12px; align-self: flex-end; }
  .phase h3 { font-size: 1.2rem; line-height: 1.4; }
  .phase p { font-size: .95rem; }
  .phase-t { display: none; }
  .ninety-stage { order: 1; height: auto; }
  .viewfinder { inset: -9px; }
  .viewfinder i { width: 28px; height: 28px; }
  /* 熊伯 takes a real share of the right half; the one visible beat keeps the rest. */
  .ninety-copy { --reader-w: clamp(124px, 36vw, 230px); }
  /* Phones: 熊伯 stands beside the clock and reaches down beside the step; the step and note keep clear of him. */
  .clock-row .reader { margin: 0 0 calc(var(--reader-w) * -.75) 0; }
  .ninety:not(.is-static) .phase, .ninety-note { margin-right: calc(var(--reader-w) + 4px); }
  .phases { margin-bottom: 12px; }
  .ninety-note { margin-top: auto; }
  .phase p { max-width: none; }
  .seal { width: 72px; height: 72px; font-size: 1.2rem; border-width: 3px; }

  .shot { width: 248px; }
  .rule { grid-template-columns: 1.6em minmax(0, 1fr) auto; gap: 8px; }
  .rule-text b { font-size: 1.08rem; }

  .slip--send { --tear-x: 0px; --tear-r: .5deg; transform: none; }
  /* Phones: the stamp moves to the empty corner beside the App Store badge, clear of the one-line headline. */
  .slip--send .seal { top: auto; bottom: clamp(16px, 4vw, 24px); }
  .slip--send .h1-print { padding-right: 0; }
  .send-qr { display: none; }
  .stub-info { grid-template-columns: 1fr; }
}

/* ---------- Short phones (e.g. iPhone SE): the pinned scene must fit one screen ---------- */
@media (max-width: 720px) and (max-height: 760px) {
  .ninety-pin { gap: 8px; padding-top: calc(var(--pad-h) + 20px); padding-bottom: 6px; }
  .sh-th { padding: 9px 14px 8px; }
  .sh-slip { padding: 10px 0 7px; }
  .sh-slip .slip-kind span { font-size: 1.3rem; }
  .sh-slip .slip-no span { font-size: 1.25rem; }
  .row { min-height: 29px; padding: 2px; }
  .orig, .tr, .row-price { font-size: .84rem; }
  .clock { font-size: 2rem; }
  .phase h3 { font-size: 1.08rem; }
  .phase p { font-size: .86rem; line-height: 1.55; }
  .ninety-copy { --reader-w: clamp(104px, 30vw, 150px); }
  .ninety-note { margin-top: 8px; }
}

/* ---------- Static (reduced motion / no pin) ---------- */
.ninety.is-static .ninety-pin { height: auto; min-height: 100svh; }
.ninety.is-static .phase { opacity: 1; }
.ninety.is-static .phase + .phase { margin-top: 10px; }
/* Every beat shows at once here, so 熊伯 must not sit beside the copy. Tablet and up: he drops under the menu,
   which overlaps his head a little. Phones: he stays by the clock instead of reaching down beside the beats. */
@media (min-width: 721px) {
  .ninety.is-static .ninety-stage { height: auto; }
  .ninety.is-static .sheet-wrap { display: flex; flex-direction: column; }
  .ninety.is-static .reader-desk { position: relative; order: 1; right: auto; bottom: auto; margin-top: calc(var(--rd-w) * -.3); }
}
@media (max-width: 720px) { .ninety.is-static .clock-row .reader { margin-bottom: 0; } }

.no-js .tr { opacity: 1; }
.no-js .orig { opacity: 0; }

/* Animation library failed to load: the slip as the timeline's last frame leaves it. */
.no-gsap .sheet { --sheen: 0; background: #F8F6F1; border-radius: 0; }
.no-gsap .sh-th, .no-gsap .orig { opacity: 0; }
.no-gsap .sh-slip, .no-gsap .row .box, .no-gsap .tr, .no-gsap .desc, .no-gsap .pill { opacity: 1; }
.no-gsap .row .circle path, .no-gsap .row .wave path { opacity: 1; stroke-dashoffset: 0; }
.no-gsap .row:not(.row--pick):not(.row--skip) :is(.tr, .row-price) { color: #6E4E49; }

@media (prefers-reduced-motion: reduce) {
  /* Zero the delays too, so every pencil mark and note is on the slip from the first paint. */
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; animation-delay: 0s !important; transition-delay: 0s !important; }
}

/* ---------- Motion: one pencil, one seal ---------- */
@keyframes draw { 0% { stroke-dashoffset: 1; opacity: 0; } 1% { opacity: 1; } 100% { stroke-dashoffset: 0; opacity: 1; } }
@keyframes write { from { opacity: 0; transform: translateY(3px) rotate(-1.5deg); } }
/* Transform only: the slip is the LCP element, so it must be visible from the first frame. */
@keyframes slip-in { from { transform: translateY(-48px) rotate(-4deg); } }
@keyframes peek-in { from { opacity: 0; transform: translateX(110px); } }
@keyframes stamp {
  0% { opacity: 0; transform: scale(1.9) rotate(-22deg); }
  80% { opacity: .9; transform: scale(.97) rotate(-9deg); }
  100% { opacity: .9; transform: scale(1) rotate(-9deg); }
}

.slip--hero { animation: slip-in 1s var(--ease-out) .1s both; }
.peek { animation: peek-in 1.1s var(--ease-out) .55s both; }
/* The last beat: once the menu is translated and every pick and warning is marked (~4.3s), the download note
   is stuck on: it drops in, presses down, settles. The whole hero is still done inside five seconds (WCAG 2.2.2).
   Individual translate/scale properties, so the note keeps its own rotate() at every width. */
@keyframes note-stick {
  0% { opacity: 0; translate: 0 -28px; scale: 1.08; }
  55% { opacity: 1; translate: 0 3px; scale: .985; }
  100% { opacity: 1; translate: 0 0; scale: 1; }
}
.hero-cta { animation: note-stick .55s cubic-bezier(.3,.7,.3,1) 4.35s both; }
/* The answer is written with the question, not after a pause: no empty line between headline and lede. */
.hero .h1-hand { animation: write .45s ease-out .1s both; }
.hero .circle path, .hero .wave path { animation: draw .45s cubic-bezier(.5,0,.3,1) both; }
@keyframes jp-out { to { opacity: 0; transform: translateY(-5px); } }
@keyframes tr-in { from { opacity: 0; transform: translateY(5px); } }
@keyframes pop { from { opacity: 0; transform: scale(.8); } to { opacity: 1; transform: none; } }
/* Plays once and is done by ~4.5s (under WCAG 2.2.2's five seconds): Japanese row by row into Chinese, then each mark with its pill and reason. */
.hero .h-orig { animation: jp-out .3s ease-in both; }
.hero .h-tr, .hero .h-desc { animation: tr-in .35s var(--ease-out) both; }
.hero .hname .pill { animation: pop .3s cubic-bezier(.3,1.6,.5,1) both; }
.hero .hrow:nth-child(1) .h-orig { animation-delay: 1.40s; } .hero .hrow:nth-child(1) .h-tr { animation-delay: 1.55s; }
.hero .hrow:nth-child(2) .h-orig { animation-delay: 1.55s; } .hero .hrow:nth-child(2) .h-tr { animation-delay: 1.70s; }
.hero .hrow:nth-child(3) .h-orig { animation-delay: 1.70s; } .hero .hrow:nth-child(3) .h-tr { animation-delay: 1.85s; }
.hero .hrow:nth-child(4) .h-orig { animation-delay: 1.85s; } .hero .hrow:nth-child(4) .h-tr { animation-delay: 2.00s; }
.hero .hrow:nth-child(5) .h-orig { animation-delay: 2.00s; } .hero .hrow:nth-child(5) .h-tr { animation-delay: 2.15s; }
.hero .hrow:nth-child(6) .h-orig { animation-delay: 2.15s; } .hero .hrow:nth-child(6) .h-tr { animation-delay: 2.30s; }
.hero .hrow:nth-child(7) .h-orig { animation-delay: 2.30s; } .hero .hrow:nth-child(7) .h-tr { animation-delay: 2.45s; }
.hero .hrow:nth-child(1) .circle path { animation-delay: 2.75s; } .hero .hrow:nth-child(1) .pill { animation-delay: 2.95s; } .hero .hrow:nth-child(1) .h-desc { animation-delay: 3.05s; }
.hero .hrow:nth-child(4) .circle path { animation-delay: 3.00s; } .hero .hrow:nth-child(4) .pill { animation-delay: 3.20s; } .hero .hrow:nth-child(4) .h-desc { animation-delay: 3.30s; }
.hero .hrow:nth-child(6) .circle path { animation-delay: 3.25s; } .hero .hrow:nth-child(6) .pill { animation-delay: 3.45s; } .hero .hrow:nth-child(6) .h-desc { animation-delay: 3.55s; }
.hero .hrow:nth-child(3) .wave path { animation-delay: 3.55s; } .hero .hrow:nth-child(3) .pill { animation-delay: 3.75s; } .hero .hrow:nth-child(3) .h-desc { animation-delay: 3.85s; }
.hero .hrow:nth-child(7) .wave path { animation-delay: 3.80s; } .hero .hrow:nth-child(7) .pill { animation-delay: 4.00s; } .hero .hrow:nth-child(7) .h-desc { animation-delay: 4.10s; }


.js .seal--send { opacity: 0; }
.js .slip--send.is-in .seal--send { animation: stamp .42s cubic-bezier(.55,0,.8,.2) .95s both; }
@keyframes tear-off {
  0% { transform: none; }
  35% { transform: translateY(-4px) rotate(-1.2deg); }
  100% { transform: translate(var(--tear-x, 6px), 18px) rotate(var(--tear-r, 1.2deg)); }
}
.js .slip--send.is-in { animation: tear-off .75s cubic-bezier(.3,.7,.2,1) .15s both; }


/* 熊伯 ticks each rule as it comes into view (two-row stagger). */
.js .rule .tick path { stroke-dashoffset: 1; opacity: 0; transition: stroke-dashoffset .5s cubic-bezier(.5,0,.3,1) calc(var(--i, 0) * 160ms + 200ms), opacity 0s linear calc(var(--i, 0) * 160ms + 200ms); }
.js .rule.is-in .tick path { stroke-dashoffset: 0; opacity: 1; }
