/* Dellie F — "Fresh off the plate".
   The page looks like the things it sells: rounded, chunky, tinted with the colours of the real spools.
   Pictures still come in two shapes, both cut by tools/build-images.py (.frame-45 4:5, .frame-32 3:2), now with rounded corners.
   Colour names are the filaments on the shelf: Lite Orange is the one accent; Misty Blue, Peach and Ocean are section tints. */

/* ---- fonts, served from here (SIL OFL, vendor/fonts/OFL.txt) ---- */
@font-face{font-family:'Grandstander';font-style:normal;font-weight:100 900;font-display:swap;src:url(vendor/fonts/grandstander-var-vietnamese.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'Grandstander';font-style:normal;font-weight:100 900;font-display:swap;src:url(vendor/fonts/grandstander-var-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-weight:400;font-display:swap;src:url(vendor/fonts/be-vietnam-pro-400-vietnamese.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-weight:400;font-display:swap;src:url(vendor/fonts/be-vietnam-pro-400-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-weight:500;font-display:swap;src:url(vendor/fonts/be-vietnam-pro-500-vietnamese.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-weight:500;font-display:swap;src:url(vendor/fonts/be-vietnam-pro-500-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-weight:600;font-display:swap;src:url(vendor/fonts/be-vietnam-pro-600-vietnamese.woff2) format('woff2');unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
@font-face{font-family:'Be Vietnam Pro';font-style:normal;font-weight:600;font-display:swap;src:url(vendor/fonts/be-vietnam-pro-600-latin.woff2) format('woff2');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

:root{
  --ink:#1b1e26; --paper:#fafaf7; --muted:#5b5f68; --line:#dcddd6;
  --orange:#f2611f; --orange-deep:#c8470f;
  --misty:#dbe7ee; --peach:#f7e2d6; --ocean:#d6ebe9;
  --display:'Grandstander','Be Vietnam Pro',Arial,sans-serif;
  --font:'Be Vietnam Pro',Arial,sans-serif;
  --wrap:1280px;
  --gutter:clamp(16px,4.5vw,64px);           /* text to the edge of whatever it sits in */
  --edge:clamp(8px,1.4vw,20px);              /* a panel to the edge of the window */
  --r-panel:clamp(22px,3vw,40px); --r-tile:clamp(18px,1.8vw,26px); --r-photo:clamp(12px,1.3vw,18px);
  --section:clamp(56px,7vw,104px); --block:clamp(36px,4.6vw,64px); --head:clamp(24px,3vw,44px);
  --gap:clamp(12px,1.6vw,22px);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth;scroll-padding-top:90px;-webkit-text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--font);font-size:17px;line-height:1.65;-webkit-font-smoothing:antialiased}
::selection{background:var(--ink);color:var(--paper)}
img{display:block;max-width:100%}
figure,p,h1,h2,h3,ol{margin:0}
ol{padding:0;list-style:none}
button,input,textarea{font:inherit}
button{color:inherit;cursor:pointer;-webkit-tap-highlight-color:transparent}
a{color:inherit;text-decoration:none;-webkit-tap-highlight-color:transparent}
:focus-visible{outline:2.5px solid var(--orange);outline-offset:3px}
.panel-orange :focus-visible{outline-color:var(--ink)}
.panel-ink :focus-visible{outline-color:var(--paper)}
[hidden]{display:none!important}
.wrap{width:min(var(--wrap),100% - 2*var(--gutter));margin-inline:auto}
.skip{position:absolute;z-index:30;top:10px;left:16px;padding:10px 20px;border-radius:999px;background:var(--ink);color:#fff;transform:translateY(-200%)}
.skip:focus{transform:none}
.sr-only{position:absolute;left:0;top:0;width:1px;height:1px;min-height:0;margin:-1px;padding:0;border:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

/* ---- type ---- */
h1,h2,h3{font-family:var(--display);font-weight:800}
h1{font-size:clamp(40px,6.1vw,88px);line-height:.98;letter-spacing:-.03em}
h2{font-size:clamp(28px,3.9vw,56px);line-height:1.06;letter-spacing:-.02em}
h3{font-size:17px;font-weight:600;line-height:1.35;letter-spacing:-.01em}
h1 span,h2 span{display:block}
h1 span:last-child,h2 .accent{color:var(--orange)}
/* stacked Vietnamese marks need air: the heading face keeps 1.42-1.46 leading so the marks clear the line above */
html[lang=vi] h1{font-size:clamp(32px,5vw,74px);line-height:1.42;letter-spacing:-.01em}
html[lang=vi] h2{line-height:1.46;letter-spacing:0}
html[lang=vi] h3{line-height:1.55}
h1,h2,h3{text-wrap:balance}
p,figcaption,.flow-step>span{text-wrap:pretty}
.eyebrow{display:inline-flex;align-items:center;gap:8px;padding:8px 14px;border:1.5px solid var(--ink);border-radius:999px;font-size:12px;font-weight:600;line-height:1.3;letter-spacing:.1em;text-transform:uppercase}
/* one sentence per element in the markup (the two-language build needs it), one solid paragraph on the page */
.s{display:inline}
.s+.s::before{content:" "}
.para+.para{margin-top:.65em}   /* a story told in a few short paragraphs, not one lump */
.heading-side{max-width:30em;text-wrap:pretty}   /* the div makes the line boxes, so it needs this, not the inline p.s inside: keeps "…của tiệm." / "…anywhere else." off a one-word last line on a phone */

/* ---- controls ---- */
.button{display:inline-flex;gap:28px;justify-content:space-between;align-items:center;padding:15px 22px 15px 24px;min-height:56px;border:1.5px solid var(--ink);border-radius:999px;background:transparent;color:var(--ink);font-weight:600;font-size:15px;line-height:1.4;text-align:left;transition:background .18s,color .18s,border-color .18s,transform .12s}
.button span[aria-hidden]{font-size:20px;line-height:1}
.primary{background:var(--orange);border-color:var(--orange)}
.secondary{background:transparent}
@media(hover:hover) and (pointer:fine){
  .primary:hover{background:var(--ink);border-color:var(--ink);color:var(--paper)}
  .secondary:hover{background:var(--ink);color:var(--paper)}
  .panel-orange .primary:hover{background:var(--paper);border-color:var(--paper);color:var(--ink)}
}
.panel-orange .primary{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.button:active{transform:translateY(1px)}
.text-button{background:none;border:0;padding:8px 0;min-height:44px;font-size:15px;font-weight:600;line-height:1.5;text-align:left;text-decoration:underline;text-underline-offset:5px;text-decoration-thickness:1.5px}
.text-button:has(>span[aria-hidden]){text-decoration:none}
.text-button>span[data-en]{text-decoration:underline;text-underline-offset:5px;text-decoration-thickness:1.5px}
@media(hover:hover) and (pointer:fine){.text-button:hover,.text-button:hover>span[data-en]{text-decoration-color:var(--orange)}}
.text-button:active{transform:translateY(1px)}
.heading-side>.text-button,.s .text-button,p>.text-button{display:inline;min-height:0;padding:0;font-size:inherit;line-height:inherit;vertical-align:baseline}   /* inside running text the button is a link, not a 44px block: no tall line under it */
/* the ↗ leans the way it points while its control is hovered or focused */
.button>span[aria-hidden],.text-button>span[aria-hidden],.note-go{display:inline-block;transition:transform .22s cubic-bezier(.2,.7,.2,1)}
@media(hover:hover) and (pointer:fine){:is(.button,.text-button):hover>span[aria-hidden],.note-card:hover .note-go{transform:translate(2px,-2px)}}
:is(.button,.text-button):focus-visible>span[aria-hidden],.note-card:focus-visible .note-go{transform:translate(2px,-2px)}

/* ---- the image system ---- */
.frame{display:block;position:relative;width:100%;margin:0;padding:0;border:0;overflow:hidden;border-radius:var(--r-photo);background:#dcded8}
.frame>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.frame-45{aspect-ratio:4/5}
.frame-32{aspect-ratio:3/2}
figcaption{font-size:13.5px;line-height:1.55;color:var(--muted);margin-top:12px}

/* ---- header: a floating bar that stays ---- */
.header{position:sticky;top:0;z-index:20;display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:76px;padding-inline:calc(var(--edge) + 18px);background:rgba(250,250,247,.84);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.wordmark{font-family:var(--display);font-weight:800;font-size:24px;letter-spacing:-.04em;white-space:nowrap}
.header .wordmark{display:inline-flex;align-items:center;min-height:44px}
.header nav{display:flex;gap:2px;margin-inline:auto;font-size:14px;font-weight:600}
.header nav a{display:inline-flex;align-items:center;min-height:44px;padding:0 16px;border-radius:999px;transition:background .18s}
@media(hover:hover) and (pointer:fine){.header nav a:hover{background:rgba(27,30,38,.08)}}
.language{display:inline-flex;align-items:center;padding:3px;border:1.5px solid var(--ink);border-radius:999px}
.language>span{display:none}
.language a{display:inline-flex;align-items:center;justify-content:center;min-width:44px;min-height:38px;padding:8px 12px;border-radius:999px;font-size:13px;font-weight:700;color:var(--muted);transition:background .18s,color .18s}
.language a[aria-current=page]{background:var(--ink);color:var(--paper)}
@media(hover:hover) and (pointer:fine){.language a:not([aria-current=page]):hover{color:var(--ink);text-decoration:none}}

/* ---- panels: sections that are objects on the page ---- */
.panel{margin-inline:var(--edge);border-radius:var(--r-panel);padding-block:clamp(32px,4.5vw,72px)}
.panel-misty{background:var(--misty)}
.panel-peach{background:var(--peach)}
.panel-ocean{background:var(--ocean)}
.panel-orange{background:var(--orange)}
.panel-ink{background:var(--ink);color:var(--paper)}
.panel+.panel{margin-top:var(--edge)}
/* layer lines: the faint horizontal ridges of a print, on the two loud panels */
.panel-orange,.panel-ink{background-image:repeating-linear-gradient(180deg,rgba(255,255,255,.07) 0 1px,transparent 1px 7px)}

/* ---- hero: the cat is printed and painted in front of you ---- */
.print-story{padding-block:clamp(22px,3vw,40px) clamp(18px,2.2vw,30px)}
.hero{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);grid-template-areas:"title stage" "copy stage";column-gap:clamp(16px,2.4vw,40px);row-gap:clamp(14px,2vw,28px);align-items:end}
.hero h1 span{white-space:nowrap}   /* the headline is allowed to run over the empty top of the stage */
.hero-top{grid-area:title;position:relative;z-index:2;align-self:start;display:flex;flex-direction:column;align-items:flex-start;gap:clamp(16px,1.8vw,24px);padding-top:clamp(4px,1vw,14px)}
.hero .eyebrow{background:var(--orange);border-color:var(--orange)}
.hero-copy{grid-area:copy;display:flex;flex-direction:column;align-items:flex-start;gap:clamp(18px,2vw,28px);padding-bottom:clamp(28px,4vw,64px)}
.intro{font-size:clamp(17px,1.4vw,21px);line-height:1.6;max-width:22em}
.print-figure{grid-area:stage;align-self:end;min-width:0;margin:0}
.print-stage{position:relative;aspect-ratio:1.22;overflow:hidden;isolation:isolate;touch-action:pan-y;outline-offset:3px;border-radius:var(--r-tile);
  background:radial-gradient(46% 40% at 50% 57%,rgba(255,255,255,.82) 0%,rgba(255,255,255,.52) 38%,rgba(255,255,255,.14) 72%,rgba(255,255,255,0) 100%)}
  /* no box: a pool of light behind the cat, fading out well inside the stage */
.print-fallback{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
.print-canvas{position:absolute;inset:0;z-index:1;opacity:0;transition:opacity .4s ease}
.print-canvas canvas{display:block;width:100%;height:100%}
.is-live .print-canvas{opacity:1}
.is-live .print-fallback{opacity:0;transition:opacity .4s ease .1s}
.is-live .print-stage{cursor:grab}
.is-live .print-stage:active{cursor:grabbing}
/* under the stage: what is happening right now, read off the scene's own phase; then the hint and the replay */
.print-caption{display:flex;justify-content:center;align-items:center;gap:12px;min-height:44px;margin-top:2px;font-size:13.5px;color:var(--muted)}
.print-status{display:none;align-items:center;gap:10px;font-family:var(--display);font-weight:600;font-size:13px;letter-spacing:.02em;color:var(--ink)}
.print-status .dot{width:9px;height:9px;border-radius:50%;background:var(--orange);animation:pulse 1.1s ease-in-out infinite}
@keyframes pulse{50%{transform:scale(.55);opacity:.55}}
.st{display:none}
.is-live .print-stage:is([data-phase=printing],[data-phase=white],[data-phase=painting])~.print-caption .print-status{display:inline-flex}
.is-live .print-stage[data-phase=printing]~.print-caption .st-printing,
.is-live .print-stage[data-phase=white]~.print-caption .st-white,
.is-live .print-stage[data-phase=painting]~.print-caption .st-painting{display:inline}
.stage-replay{flex:none;width:44px;height:44px;display:grid;place-items:center;padding:0;border:1.5px solid var(--ink);border-radius:50%;background:transparent;color:var(--ink);transition:background .15s,color .15s,transform .3s}
@media(hover:hover) and (pointer:fine){.stage-replay:hover{background:var(--ink);color:var(--paper);transform:rotate(-40deg)}}
.stage-replay:active{transform:rotate(-40deg) scale(.92)}
:is(.stage-hint,.kit-hint,.stage-replay,.flow-replay):not([hidden]){animation:rise-in .5s cubic-bezier(.2,.7,.2,1) backwards}

/* ---- shared section heading: title left, a few words right ---- */
.section-heading{display:grid;grid-template-columns:minmax(0,7fr) minmax(0,5fr);column-gap:clamp(20px,3vw,48px);align-items:end;margin-bottom:var(--head)}
.section-heading h2{margin-top:18px}
.section-heading h2:first-child{margin-top:0}
.heading-side .text-button,.heading-side .button{margin-top:14px}
.heading-side>.text-button{margin-top:0}   /* the inline "Tell me when it’s ready" follows its sentence: the 14px was opening a gap in the paragraph */
.heading-side>.from-price{font-size:14px;color:var(--muted);margin-top:14px}
.cta-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px 22px;margin-top:20px}

/* ---- the catalogue: every piece on a tile the colour of its own filament ---- */
.collection{padding-block:var(--section)}
.products{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--gap)}
.tile{position:relative;display:flex;flex-direction:column;min-width:0;padding:9px 9px 18px;border-radius:var(--r-tile);background:var(--tint,#eeeeea);transition:transform .35s cubic-bezier(.2,.7,.2,1),box-shadow .35s cubic-bezier(.2,.7,.2,1)}
@supports (grid-template-rows:subgrid){
  .product,.product-wide{display:grid;grid-template-rows:subgrid;grid-row:span 3;row-gap:0;align-content:start}
  .note-card{grid-row:auto}
}
.product-wide{grid-column:span 2}
.product-wide .frame{aspect-ratio:auto;height:100%}   /* the wide plate fills the row the 4:5 cards define */
.tile .frame{border-radius:calc(var(--r-tile) - 7px);background:#e4e4df}
.tile h3{margin:14px 5px 0;font-size:clamp(15px,1.15vw,17px)}
.product-wide h3{font-size:clamp(17px,1.5vw,21px)}
.tile .kind{margin:5px 5px 0;font-size:13px;line-height:1.5;color:var(--muted)}
/* the price is a sticker on the photo, a touch askew, the way one is stuck on in a shop */
.tile .price{position:absolute;top:19px;right:19px;z-index:2;padding:8px 13px;border-radius:999px;background:var(--orange);color:var(--ink);font-family:var(--display);font-weight:700;font-size:12.5px;line-height:1.2;letter-spacing:.01em;white-space:nowrap;transform:rotate(-4deg);box-shadow:0 2px 0 rgba(27,30,38,.18)}
/* the heart: save a piece for later, on this device. It sits on the photo's top-left corner, opposite the price sticker */
.save{position:absolute;top:17px;left:17px;z-index:2;display:grid;place-items:center;width:44px;height:44px;padding:0;border:0;border-radius:50%;background:rgba(250,250,247,.92);color:var(--ink);box-shadow:0 2px 0 rgba(27,30,38,.14);transition:transform .2s cubic-bezier(.2,.7,.2,1),background .2s,color .2s}
.save[aria-pressed=true]{background:var(--orange);color:var(--ink)}
.save[aria-pressed=true] path{fill:currentColor}
@media(hover:hover) and (pointer:fine){.save:hover{transform:scale(1.08)}}
.save:active{transform:scale(.92)}
/* the header chip: how many are saved, and the door to the panel */
.saved-chip{display:inline-flex;align-items:center;gap:7px;min-height:40px;padding:6px 14px 6px 11px;margin-right:10px;border:1.5px solid var(--ink);border-radius:999px;background:var(--orange);font-size:13px;font-weight:700;color:var(--ink);transition:transform .2s cubic-bezier(.2,.7,.2,1)}
.saved-chip path{fill:currentColor}
.saved-chip .saved-count{font-family:var(--display);font-weight:700}
.saved-chip.is-bumping{animation:bump .4s cubic-bezier(.2,.7,.2,1)}
@keyframes bump{40%{transform:scale(1.12)}}
.product,.product-wide{cursor:pointer}
@media(hover:hover) and (pointer:fine){
  .tile:hover{transform:translateY(-5px);box-shadow:0 26px 40px -28px rgba(27,30,38,.55)}
  .tile:hover .price{transform:rotate(0)}
  button.frame>img{transition:transform .6s cubic-bezier(.2,.7,.2,1)}
  :is(.product,.product-wide):hover .frame>img,.story-row button.frame:hover>img{transform:scale(1.04)}
}
.tile .price{transition:transform .3s cubic-bezier(.2,.7,.2,1)}
/* eleven pieces fill their rows at four, three and two columns; the colour note takes a full row of its own under them */
.note-card{grid-column:1/-1;display:flex;flex-wrap:wrap;align-items:center;gap:14px 22px;width:100%;padding:clamp(16px,1.6vw,22px) clamp(18px,2vw,28px);border:1.5px dashed var(--ink);border-radius:var(--r-tile);background:var(--misty);text-align:left;font-size:clamp(15px,1.15vw,17px);line-height:1.5;color:var(--ink);transition:transform .35s cubic-bezier(.2,.7,.2,1),background .2s}
.note-card>span[data-en]{flex:1 1 20em}
.note-card .note-go{margin-left:auto}
@media(hover:hover) and (pointer:fine){.note-card:hover{transform:translateY(-5px);background:#cfdfe9}}
.note-go{font-size:18px}
.spools{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.spools i{width:18px;height:18px;border-radius:50%;background:var(--c);box-shadow:inset 0 0 0 1.5px rgba(27,30,38,.15)}

/* ---- the stories: the three that were made for one person, strung on one rail of layer lines, a lit node at each ---- */
.stories{padding-block:0 var(--section)}
.stories .section-heading{display:block}
.stories .heading-side{max-width:32em;margin-top:16px}
.rail{--rail:clamp(28px,3vw,44px);--story-lh:1.15;position:relative;padding-left:var(--rail)}
html[lang=vi] .rail{--story-lh:1.55}   /* Vietnamese titles breathe more (html[lang=vi] h3); the node follows */
.rail::before{content:"";position:absolute;left:5px;top:10px;bottom:0;width:2px;border-radius:2px;background:repeating-linear-gradient(180deg,rgba(27,30,38,.3) 0 6px,transparent 6px 11px);mask-image:linear-gradient(#000 calc(100% - 90px),transparent);-webkit-mask-image:linear-gradient(#000 calc(100% - 90px),transparent)}
.story{position:relative;display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--gap);align-items:start}
.story+.story{margin-top:var(--block)}
/* the node sits on the rail, centred on the first line of the story's title (font-size × line-height / 2); a ring of paper keeps the dashes off it */
.story::before{content:"";position:absolute;left:calc(-1*var(--rail) - 1px);top:calc(clamp(22px,2vw,30px)*var(--story-lh)/2 - 7px);width:14px;height:14px;border-radius:50%;background:var(--orange);box-shadow:0 0 0 3px var(--paper),0 0 0 4.5px rgba(242,97,31,.35),0 0 18px 4px rgba(242,97,31,.45)}
/* it lights when its story rises into view */
.reveal-ready .story::before{transform:scale(0);transition:transform .5s cubic-bezier(.2,.9,.3,1.3) .3s}
.reveal-ready .story.is-in::before{transform:none}
.story-line{grid-column:1/5;padding-right:clamp(0px,1vw,16px)}
.story-line h3{font-size:clamp(22px,2vw,30px);font-weight:700;line-height:var(--story-lh);letter-spacing:-.02em;margin-bottom:12px}
.story-row{grid-column:5/-1;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--gap)}
.story-row.two{grid-template-columns:repeat(2,minmax(0,1fr))}
.story:has(.story-row.five) .story-line{grid-column:1/-1;max-width:30em}   /* the five-picture story: the title on its own line, the pictures below it */
.story-row.five{grid-column:1/-1;grid-template-columns:repeat(6,minmax(0,1fr))}   /* three across, then two centred: room for the words under each */
.story-row.five>figure{grid-column:span 2}
.story-row.five>figure:nth-child(4){grid-column:2/4}
.story-row.five figcaption.bubble{margin:18px 2px 0;color:var(--ink);font-size:14.5px;line-height:1.55;text-wrap:pretty}   /* here the captions tell the story: one sentence each, in a speech bubble under its picture */
.story-row.one{grid-column:5/9;grid-template-columns:1fr}   /* Freud stands in a third of the row, full size */
.story .chess-note{grid-column:9/-1;align-self:start;aspect-ratio:4/5;display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:14px;padding:clamp(20px,2.4vw,34px);border-radius:var(--r-tile);background:var(--misty);font-family:var(--display);font-weight:600;font-size:clamp(17px,1.5vw,22px);line-height:1.35;letter-spacing:-.01em}
.story .chess-note .text-button{font-family:var(--font);font-size:15px}
.story-row figcaption{margin-top:11px}

/* ---- what people said after: postcards on a tinted desk. Each is their photo, their words in a speech bubble, and a
   sticker naming them and the piece; the last card is always the empty one asking for the next. The row swipes on a
   phone (scroll-snap, dots under it), and simply stands three wide on a desk that is wide enough. ---- */
.said{padding-block:clamp(36px,5vw,80px)}
.said .heading-side{max-width:24em}   /* "…Their photos, not ours." keeps its last two words together */
.postcards{position:relative}
.said-row{list-style:none;margin:0 -8px;padding:14px 8px 18px;display:grid;grid-auto-flow:column;grid-auto-columns:calc((100% - 2*var(--gap))/3);gap:var(--gap);align-items:start;overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;scrollbar-width:none;margin-block:-14px -18px}
.said-row::-webkit-scrollbar{display:none}
.postcard{position:relative;display:flex;flex-direction:column;min-width:0;padding:10px 10px 18px;border-radius:var(--r-tile);background:var(--paper);box-shadow:0 2px 0 rgba(27,30,38,.16),0 26px 40px -30px rgba(27,30,38,.5);transform:rotate(-1.3deg);scroll-snap-align:start;transition:transform .35s cubic-bezier(.2,.7,.2,1)}
.postcard:nth-child(even){transform:rotate(1.1deg)}
.review-photo{position:relative;margin:0}
.review-photo .frame{border-radius:calc(var(--r-tile) - 7px);background:#e4e4df;cursor:zoom-in}
/* the sticker is stuck across the photo's bottom edge, a touch askew, like the price stickers in the shop: the name only,
   one line, readable. What they got is the quiet line under the bubble (.review-who). */
.sticker{position:absolute;right:14px;bottom:-14px;z-index:2;margin:0;padding:8px 16px;border-radius:999px;background:var(--orange);color:var(--ink);font-family:var(--display);font-weight:700;font-size:15px;line-height:1.2;letter-spacing:.01em;white-space:nowrap;transform:rotate(-3deg);box-shadow:0 2px 0 rgba(27,30,38,.18);transition:transform .3s cubic-bezier(.2,.7,.2,1)}
/* their words, said out loud: a bubble whose tail points back at the photo */
.bubble{position:relative;margin:26px 4px 0;padding:14px 16px 15px;border-radius:18px;background:var(--peach);font-size:15px;line-height:1.6}
.bubble::before{content:"";position:absolute;top:-7px;left:26px;width:16px;height:16px;border-radius:3px;background:inherit;transform:rotate(45deg)}
.bubble p{position:relative;text-wrap:pretty}
.bubble p::before{content:"\201C"}
.bubble p::after{content:"\201D"}
.review-who{margin:12px 8px 0;font-size:13px;line-height:1.5;color:var(--muted);text-wrap:balance}
/* the empty postcard: the same card as the one beside it, missing its photo. Where the photo would be, a dashed 4:5 slot
   holds the question; our promise sits in the same peach bubble as their words; the button under it, on the card's bottom edge */
.postcard.invite{padding-bottom:16px}
.invite-slot{display:flex;flex-direction:column;justify-content:center;aspect-ratio:4/5;padding:clamp(18px,2vw,28px);border:1.5px dashed var(--ink);border-radius:calc(var(--r-tile) - 7px);background:rgba(219,231,238,.45);color:var(--ink)}
.invite-slot h3{font-size:clamp(24px,2.5vw,32px);font-weight:700;line-height:1.15;letter-spacing:-.02em;text-wrap:balance}
html[lang=vi] .invite-slot h3{line-height:1.5}
.invite .bubble{margin-bottom:18px}
.invite .button{align-self:flex-start;margin:auto 4px 0;min-height:52px;padding:12px 18px 12px 20px;gap:20px;font-size:14.5px}
/* dots, only where the row actually scrolls: the lit one follows the swipe (script.js) */
.said-dots{display:none;gap:8px;margin-top:22px;padding-left:4px}
.said-dots.is-on{display:flex}
.said-dots i{width:8px;height:8px;border-radius:50%;background:rgba(27,30,38,.22);transition:background .25s,transform .25s}
.said-dots i.is-here{background:var(--orange);transform:scale(1.25)}

/* ---- paint it yourself: the retriever sprays itself with 2, 3 or 4 colours and the price follows ---- */
.kit-section{padding-block:clamp(36px,5vw,80px)}
.kit-pictures{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--gap)}
.kit-pictures figcaption{margin-top:14px}
.kit-pictures strong{display:block;margin-bottom:2px;font-family:var(--display);font-weight:600;font-size:15px;line-height:1.35;color:var(--ink)}
.kit-demo{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);column-gap:clamp(24px,3.4vw,56px);align-items:center;margin-top:var(--block)}
.kit-figure{margin:0;min-width:0}
.kit-stage{isolation:isolate;touch-action:pan-y;outline-offset:3px;border-radius:var(--r-tile);background:radial-gradient(50% 42% at 50% 60%,rgba(255,255,255,.85) 0%,rgba(255,255,255,.5) 45%,rgba(255,255,255,0) 100%)}
.kit-still{transition:opacity .45s ease}
.kit-still-painted{opacity:0}
.kit-stage[data-phase=done]:not(.is-live) .kit-still-painted{opacity:1}
.kit-canvas{position:absolute;inset:0;z-index:1;opacity:0;transition:opacity .4s ease}
.kit-canvas canvas{display:block;width:100%;height:100%}
.kit-stage.is-live .kit-canvas{opacity:1}
.kit-stage.is-live .kit-still{opacity:0;transition:opacity .4s ease .1s}
.kit-stage.is-interactive{cursor:grab}
.kit-stage.is-interactive:active{cursor:grabbing}
.kit-caption{min-height:24px;margin-top:8px;font-size:13.5px;color:var(--muted);text-align:center}
.kit-panel h3{font-size:clamp(26px,2.9vw,42px);font-weight:800;line-height:1.06;letter-spacing:-.02em}
.kit-leads{display:block;max-width:30em;margin-top:12px}
.kit-options{display:flex;flex-wrap:wrap;gap:8px;margin-top:22px}
.kit-option{display:inline-flex;align-items:center;gap:10px;padding:10px 18px 10px 12px;min-height:48px;border:1.5px solid var(--ink);border-radius:999px;background:rgba(255,255,255,.72);font-size:14px;font-weight:600;line-height:1.4;transition:background .15s,color .15s,transform .12s}
@media(hover:hover) and (pointer:fine){.kit-option:hover{background:var(--ink);color:var(--paper)}}
.kit-option[aria-pressed=true]{background:var(--ink);color:var(--paper)}
.kit-option:active{transform:scale(.97)}
.swatches{display:inline-flex}
.swatches i{width:18px;height:18px;border-radius:50%;background:var(--c);border:1.5px solid rgba(255,255,255,.7);margin-left:-6px}
.swatches i:first-child{margin-left:0}
.kit-total{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 14px;margin-top:22px}
.kit-price{font-family:var(--display);font-weight:800;font-size:clamp(28px,3.6vw,52px);line-height:1;letter-spacing:-.02em;color:var(--orange);white-space:nowrap}
.kit-count{font-size:14px;color:var(--muted)}
.kit-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:24px}
.kit-paint-us{margin-top:26px;padding-top:18px;border-top:1.5px dashed rgba(27,30,38,.2);max-width:34em;font-size:15.5px;line-height:1.6}   /* the other way round: we paint it, your own pet from a photo */
.kit-paint-us .text-button{margin-top:4px}
.kit-proof{display:grid;grid-template-columns:minmax(0,1.875fr) minmax(0,1fr);gap:var(--gap);align-items:start;margin-top:var(--block)}
.kit-aside{grid-column:1/-1;display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 16px;margin-top:6px}

/* ---- coming soon: the service, shown as a chain rather than described ---- */
.soon{padding-block:clamp(36px,5vw,80px)}
.soon .section-heading{margin-bottom:var(--head)}
.soon-stage{position:relative;min-width:0}
.soon-flow{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(16px,2.4vw,32px)}
.flow-step{position:relative;min-width:0}
.flow-step .frame{border-radius:var(--r-tile)}
/* each tile waits under a veil the colour of the panel. Step 3 is uncovered from the bottom up, a print growing on the
   plate, with a thin orange line where the "nozzle" is; steps 1 and 2 simply lift theirs. */
.flow-step .frame::after{content:"";position:absolute;inset:0;z-index:2;background:var(--ocean);transition:opacity .55s ease;pointer-events:none}   /* the cover must not catch the drag meant for the cloud beneath it */
.flow-step.is-on .frame::after{opacity:0}
.flow-step[data-step="3"] .frame::after{transition:none;background:var(--ocean) repeating-linear-gradient(180deg,rgba(27,30,38,.05) 0 1px,transparent 1px 5px)}
.flow-step[data-step="3"].is-on .frame::after{opacity:1;animation:print-up 1.6s cubic-bezier(.4,.1,.3,1) forwards}
.flow-step[data-step="3"] .frame::before{content:"";position:absolute;left:0;right:0;bottom:0;height:3px;z-index:3;background:var(--orange);opacity:0}
.flow-step[data-step="3"].is-on .frame::before{animation:print-line 1.6s cubic-bezier(.4,.1,.3,1) forwards}
@keyframes print-up{from{clip-path:inset(0 0 0 0)}to{clip-path:inset(0 0 100% 0)}}
@keyframes print-line{0%{opacity:1;bottom:0}92%{opacity:1}100%{opacity:0;bottom:100%}}
.flow-step>span{display:block;margin-top:12px;font-size:14px;line-height:1.5;color:var(--ink);opacity:.35;transition:opacity .45s ease}
.flow-step.is-on>span{opacity:1}
.flow-step b{font-family:var(--display);font-weight:700;font-size:12px;color:var(--orange);margin-right:6px}
.flow-step+.flow-step::before{content:"";position:absolute;top:34%;left:calc(clamp(16px,2.4vw,32px) / -2);width:12px;height:12px;margin-left:-6px;border-top:2px solid var(--ink);border-right:2px solid var(--ink);transform:rotate(45deg) scale(.5);opacity:0;transition:opacity .35s ease,transform .35s cubic-bezier(.2,.8,.3,1)}
.flow-step.is-on+.flow-step::before,.flow-step.is-on::before{opacity:1;transform:rotate(45deg) scale(1)}
.idea-frame{background:#e7ece9}
.idea-photo{transition:opacity .45s ease,transform .75s cubic-bezier(.2,1.35,.35,1)}   /* the photo is put down on the table: a small tilt that settles */
.flow-step[data-mode=prompt] .idea-photo{opacity:0;transform:translateY(9%) rotate(-3deg) scale(.94)}
/* the idea is typed into a message bubble in the middle of the tile; once typed, the bubble slides down to become the
   photo's caption while the photo lands on top of it */
.idea-prompt{position:absolute;left:14px;right:14px;top:calc(100% - 14px);translate:0 -100%;margin:0;padding:11px 15px;border-radius:16px;background:rgba(250,250,247,.95);box-shadow:0 10px 26px -14px rgba(27,30,38,.55);font-size:clamp(13.5px,1.1vw,15.5px);line-height:1.45;color:var(--ink);opacity:0;transition:opacity .35s ease,top .7s cubic-bezier(.2,.8,.2,1),translate .7s cubic-bezier(.2,.8,.2,1),font-size .7s ease}
.flow-step[data-mode=prompt] .idea-prompt{top:50%;translate:0 -50%;font-size:clamp(16px,1.35vw,19px)}
/* the line shows only once it is being typed, and keeps its caret only while it is */
.idea-prompt.is-typing,.idea-prompt.is-typed{opacity:1}
.idea-caret{display:none;width:2px;height:1.05em;margin-left:2px;background:var(--orange);vertical-align:-.16em;animation:blink 1s steps(1,end) infinite}
.idea-prompt.is-typing .idea-caret{display:inline-block}
@keyframes blink{50%{opacity:0}}
.soon-figure{background:radial-gradient(62% 56% at 50% 56%,rgba(255,255,255,.7) 0%,rgba(255,255,255,0) 100%)}
.soon-canvas{position:absolute;inset:0;display:block;width:100%;height:100%;touch-action:pan-y;cursor:grab}   /* turnable by hand; up and down still scrolls on a phone */
.soon-canvas.is-dragging{cursor:grabbing}
.flow-replay{position:absolute;top:-58px;right:0;width:44px;height:44px;display:grid;place-items:center;padding:0;border:1.5px solid var(--ink);border-radius:50%;background:transparent;color:var(--ink);transition:background .15s,color .15s,transform .12s}
.flow-replay svg{transition:transform .3s}
@media(hover:hover) and (pointer:fine){.flow-replay:hover{background:var(--ink);color:var(--paper)}.flow-replay:hover svg{transform:rotate(-40deg)}}

/* ---- the two of us ---- */
.makers{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--block) var(--gap);align-items:center;padding-block:var(--section)}
.makers-portrait{grid-column:1/5}
.makers-copy{grid-column:5/-1;max-width:36em}
.makers-copy h2{margin-bottom:16px}
.makers-copy>p.name-note{display:flex;align-items:baseline;flex-wrap:wrap;gap:.4em;margin:28px 0 18px;font-family:var(--display);font-weight:700;font-size:clamp(20px,2.2vw,32px);line-height:1.2;letter-spacing:-.02em}
.name-note i{font-style:normal;font-weight:500;color:var(--muted);font-size:.75em}
.name-note b{font-weight:800;color:var(--orange)}
.makers-machine{grid-column:1/5;align-self:start}
.makers-machine h3{font-size:clamp(22px,2.2vw,30px);font-weight:700;line-height:1.15;letter-spacing:-.02em;margin-bottom:12px}
.makers-printer{grid-column:5/-1}

/* ---- closing: an orange panel, one sentence, one button ---- */
.closing{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:24px 48px;padding-block:clamp(34px,4.6vw,72px)}
.closing h2{max-width:11em;margin-bottom:10px}
.closing .s{font-size:18px}
.closing>.button{flex-shrink:0}

/* ---- footer: the name, as big as the page allows ---- */
.footer{display:grid;grid-template-columns:1fr auto;gap:8px 32px;align-items:start;padding-block:clamp(28px,4vw,56px) clamp(14px,2vw,26px)}
.footer .wordmark{display:block;font-size:20px}
.foot-brand p{margin-top:6px;font-size:14px;color:rgba(250,250,247,.7)}
.foot-links{display:flex;flex-wrap:wrap;gap:0 24px;margin-top:-7px;font-size:14.5px;font-weight:500}
.foot-links a{display:inline-flex;align-items:center;gap:.35em;min-height:44px}
@media(hover:hover) and (pointer:fine){.foot-links a:hover{text-decoration:underline;text-underline-offset:5px;text-decoration-color:var(--orange)}}
.credit{grid-column:1/-1;font-size:12.5px;color:rgba(250,250,247,.55)}
.foot-giant{grid-column:1/-1;margin-top:clamp(18px,3.6vw,44px);font-family:var(--display);font-weight:800;font-size:clamp(64px,17.5vw,250px);line-height:.86;letter-spacing:-.05em;white-space:nowrap;overflow:hidden;color:var(--paper);user-select:none}

/* ---- Zalo, one tap away on a phone (the desktop gets the QR inside the form instead) ---- */
.zalo-bubble{display:none;position:fixed;right:14px;bottom:calc(14px + env(safe-area-inset-bottom,0px));z-index:15;align-items:center;gap:8px;padding:12px 18px;border-radius:999px;background:#0068ff;color:#fff;font-weight:700;font-size:14px;box-shadow:0 12px 26px -10px rgba(0,60,160,.6)}
@media(pointer:coarse){.zalo-bubble{display:inline-flex}}
body:has(dialog[open]) .zalo-bubble{display:none}

/* ---- the two small pages: 404.html and privacy.html share this stylesheet ---- */
.lost{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,300px);gap:clamp(28px,5vw,84px);align-items:center;padding-block:var(--section)}
.lost h1{margin-bottom:clamp(22px,2.4vw,34px)}
.legal{padding-block:var(--section)}
.legal>*{max-width:36em}
.legal h1,html[lang] .legal h1{font-size:clamp(32px,4vw,56px);line-height:1.08;letter-spacing:-.02em;margin-bottom:clamp(16px,1.8vw,26px)}
html[lang=vi] .legal h1{line-height:1.4}
.legal h2{font-size:clamp(20px,1.8vw,24px);line-height:1.3;letter-spacing:-.01em;margin:var(--head) 0 12px}
.legal .cta-row{margin-top:var(--head)}

/* ---- enquiry dialog: a short real form ---- */
dialog{width:min(540px,calc(100% - 24px));max-height:calc(100dvh - 24px);padding:clamp(24px,4vw,40px);border:0;border-radius:var(--r-panel);background:var(--paper);color:var(--ink);overflow:hidden auto;box-shadow:0 40px 80px -30px rgba(27,30,38,.5)}
dialog{opacity:0;transform:translateY(14px) scale(.985);transition:opacity .22s ease,transform .28s cubic-bezier(.2,.7,.2,1)}
dialog[open]{opacity:1;transform:none}
@starting-style{dialog[open]{opacity:0;transform:translateY(14px) scale(.985)}}
dialog::backdrop{background:rgb(27 30 38/0);backdrop-filter:blur(0);transition:background .28s,backdrop-filter .28s}
dialog[open]::backdrop{background:#1b1e26a6;backdrop-filter:blur(4px)}
@starting-style{dialog[open]::backdrop{background:rgb(27 30 38/0);backdrop-filter:blur(0)}}
@supports (overlay:auto){
  dialog{transition:opacity .22s ease,transform .28s cubic-bezier(.2,.7,.2,1),overlay .28s allow-discrete,display .28s allow-discrete}
  dialog::backdrop{transition:background .28s,backdrop-filter .28s,overlay .28s allow-discrete,display .28s allow-discrete}
}
dialog .close{position:absolute;right:12px;top:12px;width:44px;height:44px;font-size:26px;line-height:1;background:none;border:0;border-radius:50%}
@media(hover:hover) and (pointer:fine){dialog .close:hover{background:rgba(27,30,38,.08)}}
.enq-about{display:flex;align-items:center;gap:14px;font-size:14.5px;color:var(--muted);padding-right:44px}
.enq-thumb{width:56px;aspect-ratio:4/5;object-fit:cover;flex:none;border-radius:12px}
.enq-about strong{color:var(--ink);font-weight:600}
dialog h2{font-size:clamp(24px,2.8vw,30px);line-height:1.15;margin:10px 0 22px}
html[lang=vi] dialog h2{line-height:1.42}
.field{margin-bottom:14px}
.field-label{display:block;font-size:14.5px;font-weight:600;line-height:1.4;margin-bottom:8px}
/* the review mode: the same dialog, the heading and the fields re-arranged around the photo (script.js sets data-mode) */
.enq-title-review{display:none}
dialog[data-mode=review] .enq-about{display:none}
dialog[data-mode=review] .contact-field{display:none}
dialog[data-mode=review] .form-privacy span[data-en]{display:none}   /* nothing to reply to here; the Privacy link stays */   /* a review is signed with a name, not a number */
dialog[data-mode=review] h2 .enq-ask{display:none}
dialog[data-mode=review] .enq-title-review{display:inline}
dialog[data-mode=review] .photo-field{margin-top:0}
dialog[data-mode=review] .photo-words strong{font-size:15px}
.enq-promise{font-size:13.5px;line-height:1.5;color:var(--muted);margin:2px 0 12px;text-wrap:pretty}
.field input,.field textarea{display:block;width:100%;border:1.5px solid #8a8e96;border-radius:16px;padding:14px 16px;background:#fff;color:var(--ink);caret-color:var(--orange);font-size:17px;line-height:1.5}
.field input{min-height:58px}
.field input.sr-only{width:1px;height:1px;min-height:0;padding:0;border:0}   /* the hidden file input must not widen the card (it made every photo form scroll sideways) */
.field input::placeholder{color:var(--muted)}
.note-toggle{font-size:14px;margin-top:4px}
.photo-field{margin-top:16px}
.photo-drop{display:flex;align-items:center;gap:14px;padding:14px 16px;border:1.5px dashed #8a8e96;border-radius:16px;background:#fff;cursor:pointer;transition:border-color .18s,background .18s}
@media(hover:hover) and (pointer:fine){.photo-drop:hover{border-color:var(--ink);background:#fdfdfb}}
.photo-field.is-over .photo-drop{border-color:var(--ink);background:#fdfdfb}
#enq-photo:focus-visible + .photo-drop{outline:2.5px solid var(--orange);outline-offset:3px}
.photo-icon{flex:none;color:var(--muted);display:grid;place-items:center}
.photo-words strong{display:block;font-size:14.5px;font-weight:600;line-height:1.4}
.photo-words>span{display:block;font-size:12.5px;line-height:1.5;color:var(--muted);margin-top:2px}
.photo-chosen{display:flex;align-items:center;gap:13px;padding:10px 12px;border:1.5px solid var(--line);border-radius:16px;background:#fff}
.photo-thumb{width:52px;height:52px;object-fit:cover;flex:none;border-radius:10px}
.photo-name{font-size:13px;line-height:1.4;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.photo-remove{margin-left:auto;font-size:13px;min-height:0;padding:0;flex:none}
.field textarea{resize:vertical;min-height:96px}
.field input:focus-visible,.field textarea:focus-visible{outline:2.5px solid var(--ink);outline-offset:0;border-color:var(--ink)}
.field [aria-invalid=true]{border-color:var(--orange);box-shadow:inset 3px 0 0 var(--orange)}
.field-hint{font-size:12.5px;color:var(--muted);margin-top:6px}
.field-error{font-size:13px;color:var(--orange-deep);margin-top:6px;font-weight:600}
.hp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0}
.send{width:100%;margin-top:4px}
.send[disabled],.send[disabled]:hover{opacity:1;background:var(--ink);border-color:var(--ink);color:var(--paper);cursor:progress}
.send[aria-busy=true] span[aria-hidden]{animation:send-nudge .9s ease-in-out infinite}
@keyframes send-nudge{50%{transform:translate(3px,-3px)}}
.form-status{font-size:14px;line-height:1.55;margin-top:12px}
.form-status:not(.is-error){position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.form-status.is-error{padding:12px 14px;border-radius:12px;border-left:3px solid var(--orange);background:#fff}
.form-privacy{font-size:12.5px;line-height:1.6;color:var(--muted);margin-top:16px}
.form-privacy a{text-decoration:underline;text-underline-offset:3px;padding-block:12px}
.enq-alt{display:flex;align-items:center;gap:16px;border-top:1.5px solid var(--line);margin-top:22px;padding-top:18px}
.enq-alt .button{flex:1;min-height:52px;padding:12px 18px;gap:18px;font-size:14.5px;display:none}
.zalo-scan{display:flex;align-items:center;gap:16px;margin:0}
.zalo-scan figcaption{font-size:14px;line-height:1.6;color:var(--muted);max-width:22em;margin:0}
.zalo-qr{width:104px;height:104px;flex:none;border:1.5px solid var(--line);border-radius:14px;background:#fff;padding:5px}
@media(pointer:coarse){.zalo-scan{display:none}.enq-alt .button{display:flex}}
.enq-done-view{display:grid;grid-template-columns:96px minmax(0,1fr);gap:6px 22px;align-items:center}
.enq-done-view:not([hidden]){animation:rise-in .4s cubic-bezier(.2,.7,.2,1) backwards}
@keyframes rise-in{from{opacity:0;transform:translateY(6px)}}
.done-face{grid-row:1/3;width:96px;height:96px;border-radius:50%;object-fit:cover;align-self:start;margin-top:4px}
.enq-done-view .done-title{margin:0 0 8px}
.enq-done-view p{max-width:26em}
.enq-done-view .cta-row{grid-column:1/-1;margin-top:20px}
.enq-done-view .done-scan{grid-column:1/-1;margin-top:18px}
@media(pointer:fine){.enq-done-view .button.zalo{display:none}}   /* on a computer the Sent card shows the QR instead of a link that only leads to another QR */
@media(max-width:560px){.enq-done-view{grid-template-columns:1fr}.done-face{grid-row:auto;width:78px;height:78px}}
.done-title:focus{outline:none}
.done-title span,.soon-flow li>span span{display:inline}
body:has(dialog[open]){overflow:hidden}
/* ---- the lightbox: a story photo, as large as the screen allows ---- */
dialog.lightbox{width:100vw;max-width:100vw;height:100dvh;max-height:100dvh;margin:0;padding:0;border:0;border-radius:0;background:transparent;box-shadow:none;place-items:center}
dialog.lightbox[open]{display:grid}   /* only while open: a closed dialog must stay display:none, or it leaves a screen-tall hole under the footer */
dialog.lightbox[open]::backdrop{background:#1b1e26e6;backdrop-filter:blur(6px)}
dialog.lightbox figure{margin:0;display:flex;flex-direction:column;align-items:center;gap:14px;max-width:min(96vw,1400px)}
dialog.lightbox img{display:block;max-width:96vw;max-height:84dvh;width:auto;height:auto;border-radius:var(--r-photo);box-shadow:0 40px 80px -30px rgba(0,0,0,.7)}
dialog.lightbox figcaption{color:var(--paper);font-size:15px;text-align:center;max-width:40em;margin:0;padding-inline:16px}
dialog.lightbox .close{position:fixed;top:calc(12px + env(safe-area-inset-top,0px));right:14px;width:48px;height:48px;border-radius:50%;background:rgba(250,250,247,.14);color:var(--paper);font-size:28px}
@media(hover:hover) and (pointer:fine){dialog.lightbox .close:hover{background:rgba(250,250,247,.28)}}
.story-row button.frame{cursor:zoom-in}
/* ---- the saved panel ---- */
#saved h2{margin:8px 0 4px}
.saved-note{font-size:13px;color:var(--muted)}
.saved-empty{margin-top:18px;padding:16px 18px;border-radius:14px;background:var(--misty);font-size:15px}
.saved-list{list-style:none;margin:14px 0 0;padding:0}
.saved-list li{display:grid;grid-template-columns:52px minmax(0,1fr) auto;gap:12px;align-items:center;padding:10px 0;border-top:1.5px solid var(--line)}
.saved-list li:last-child{border-bottom:1.5px solid var(--line)}
.saved-list img{width:52px;aspect-ratio:4/5;object-fit:cover;border-radius:10px}
.saved-list .saved-name{font-family:var(--display);font-weight:600;font-size:15px;line-height:1.3}
.saved-list .saved-kind{font-size:12.5px;line-height:1.4;color:var(--muted)}
.saved-list .saved-price{font-family:var(--display);font-weight:700;font-size:13px;margin-top:2px}
.saved-list .saved-remove{width:44px;height:44px;border:0;border-radius:50%;background:none;font-size:22px;line-height:1;color:var(--muted)}
@media(hover:hover) and (pointer:fine){.saved-list .saved-remove:hover{background:rgba(27,30,38,.08);color:var(--ink)}}
.saved-form{margin-top:18px}
/* the tag is the tick box: hollow until checked, then filled orange */
.tick{position:relative;display:flex;align-items:center;gap:10px;min-height:44px;margin-top:12px;font-size:15px;line-height:1.4;cursor:pointer}
.tick input{position:absolute;width:1px;height:1px;margin:0;opacity:0}
.tick .ic{flex:none;width:26px;height:26px;color:var(--ink);transition:color .15s}
.tick .ic circle{fill:var(--ink)}
.tick input:checked ~ .ic{color:var(--orange)} .tick input:checked ~ .ic path{fill:var(--orange)}
.tick input:focus-visible ~ .ic{outline:2.5px solid var(--orange);outline-offset:3px;border-radius:6px}
.saved-who{margin-top:8px;font-size:13px;color:var(--muted)}
.alert-row{display:flex;flex-wrap:wrap;gap:8px;margin-top:0}
.alert-row .field-hint{flex-basis:100%;order:3;margin-top:0}
.alert-row input{flex:1;min-width:0;border:1.5px solid #8a8e96;border-radius:999px;padding:12px 18px;min-height:52px;background:#fff;font-size:16px;caret-color:var(--orange)}
.alert-row input:focus-visible{outline:2.5px solid var(--ink);outline-offset:0;border-color:var(--ink)}
.alert-row .button{min-height:52px;padding:12px 18px 12px 20px;gap:14px;flex:none}
.saved-status{font-size:14px;line-height:1.55;margin-top:12px}
.saved-status:empty{display:none}
.saved-status.is-ok{padding:12px 14px;border-radius:12px;background:var(--ocean)}
.saved-status.is-error{padding:12px 14px;border-radius:12px;border-left:3px solid var(--orange);background:#fff}

/* ---- scroll-rise, only when script is running ---- */
.reveal-ready .reveal{opacity:0;translate:0 22px;transition:opacity .6s cubic-bezier(.2,.7,.2,1) var(--d,0s),translate .6s cubic-bezier(.2,.7,.2,1) var(--d,0s),transform .35s cubic-bezier(.2,.7,.2,1),box-shadow .35s cubic-bezier(.2,.7,.2,1)}
.reveal-ready .reveal.is-in{opacity:1;translate:none}
.products>.reveal:nth-child(4n+2){--d:120ms}
.products>.reveal:nth-child(4n+3){--d:180ms}
.products>.reveal:nth-child(4n+5){--d:60ms}
.kit-pictures>.reveal:nth-child(4n+2){--d:60ms}
.kit-pictures>.reveal:nth-child(4n+3){--d:120ms}
.kit-pictures>.reveal:nth-child(4n+4){--d:180ms}

/* ---- tablet ---- */
@media(max-width:1099px){
  .products{grid-template-columns:repeat(3,minmax(0,1fr))}
  .products>.reveal:nth-child(n){--d:0s}
  .products>.reveal:nth-child(3n+4){--d:60ms}
  .products>.reveal:nth-child(3n+2){--d:120ms}
  .hero{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr)}
  .print-stage{aspect-ratio:1.18}
  .story-line{grid-column:1/-1;max-width:34em}
  .story-row,.story-row.one{grid-column:1/-1}
  .story-row.one{grid-column:1/7}
  .story .chess-note{grid-column:7/-1}
  .said-row{grid-auto-columns:calc((100% - var(--gap))/2)}
  .makers-portrait{grid-column:1/6}
  .makers-copy{grid-column:6/-1}
  .makers-machine{grid-column:1/6}
  .makers-printer{grid-column:6/-1}
}

/* ---- phone ---- */
@media(max-width:760px){
  :root{--edge:6px}
  .header{min-height:64px;padding-inline:14px}
  .header nav{display:none}
  .wordmark{font-size:22px}
  .print-story{padding-block:18px 10px}
  .hero{grid-template-columns:1fr;grid-template-areas:"title" "stage" "copy";row-gap:14px}
  .hero h1 span{white-space:normal}
  .hero-top{padding-top:0}
  .hero-copy{padding-bottom:6px}
  .hero-top{gap:14px}
  .hero-copy{gap:16px;padding-bottom:6px}
  .intro{font-size:16.5px}
  .hero .button{min-height:52px;padding:12px 18px 12px 20px;gap:20px;font-size:14.5px}
  .print-stage{aspect-ratio:1.02}
  .print-figure{margin-inline:calc(-1*var(--gutter) + 6px)}
  .print-stage{aspect-ratio:1.02;border-radius:var(--r-tile)}
  .print-caption{padding-inline:var(--gutter)}
  .section-heading{grid-template-columns:1fr;gap:14px;align-items:start}
  .products{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .products>.reveal:nth-child(n),.kit-pictures>.reveal:nth-child(n){--d:0s}
  .products>.reveal:nth-child(2n+3),.kit-pictures>.reveal:nth-child(2n){--d:60ms}
  .tile{padding:7px 7px 14px}
  .tile .frame{border-radius:calc(var(--r-tile) - 6px)}
  .tile .price{top:14px;right:14px;padding:7px 11px;font-size:11.5px}
  .save{top:12px;left:12px;width:40px;height:40px}
  .save::after{content:"";position:absolute;inset:-2px}   /* 44px to the finger */
  .tile .price{max-width:calc(100% - 64px);white-space:normal;text-align:center;line-height:1.15}   /* the cups' '/ pair' wraps instead of meeting the heart */
  .saved-chip{margin-left:auto;padding:6px 12px 6px 10px}
  .saved-chip span[data-en]{display:none}
  .alert-row{flex-direction:column}
  .alert-row .field-hint{order:2}
  .alert-row .button{order:3}
  .tile h3{margin-top:11px;font-size:14.5px}
  .tile .kind{font-size:12.5px}
  .product-wide{grid-column:span 2}
  .product-wide .frame{aspect-ratio:3/2;height:auto}
  .product-wide h3{font-size:16px}
  .story{grid-template-columns:1fr;gap:20px}
  .story-line{grid-column:auto;padding:0}
  .story-row,.story-row.two,.story-row.one{grid-column:auto;grid-template-columns:1fr;row-gap:20px}
  .story-row.five{display:flex;gap:12px;overflow-x:auto;scroll-snap-type:x mandatory;margin-inline:calc(-1*var(--gutter));padding-inline:var(--gutter);scrollbar-width:none;-webkit-overflow-scrolling:touch}   /* on the phone the five steps are a filmstrip you swipe */
  .story-row.five::-webkit-scrollbar{display:none}
  .story-row.five>figure{flex:0 0 min(62%,240px);scroll-snap-align:start}
  .story .chess-note{grid-column:auto;aspect-ratio:auto;padding:20px}
  /* the postcards run to the panel's edge and swipe; the first one starts at the gutter */
  .said-row{grid-auto-columns:min(82%,340px);gap:12px;margin-inline:calc(-1*var(--gutter));padding-inline:var(--gutter);scroll-padding-inline:var(--gutter)}
  .postcard{padding:8px 8px 16px}
  .review-photo .frame{border-radius:calc(var(--r-tile) - 6px)}
  .sticker{right:12px;font-size:14px;padding:7px 14px}
  .review-who{margin-inline:6px}
  .bubble{margin:24px 2px 0;font-size:14.5px}
  .invite-slot{border-radius:calc(var(--r-tile) - 6px)}
  .invite .button{margin-inline:2px}
  .kit-pictures{grid-template-columns:repeat(2,minmax(0,1fr));gap:22px 10px}
  .kit-pictures strong{font-size:14.5px}
  .kit-demo{grid-template-columns:1fr;gap:12px}
  .kit-figure{margin-inline:calc(-1*var(--gutter) + 6px)}
  .kit-caption{min-height:0;margin-top:6px;font-size:12.5px}
  .kit-panel{display:flex;flex-direction:column}
  .kit-panel h3{order:2;margin-top:6px}
  .kit-options{order:3;margin-top:14px}
  .kit-total{order:4;margin-top:14px}
  .kit-panel .kit-leads{order:5;margin-top:18px}
  .kit-actions{order:6}
  .kit-paint-us{order:7}
  .kit-proof{grid-template-columns:1fr;gap:22px}
  .kit-proof figure:last-child{width:72%;margin-left:auto}
  /* one step under the next, each a hand's width, the arrows pointing down: the typed line has a whole row to itself */
  .soon-flow{grid-template-columns:1fr;gap:26px;justify-items:center}
  .flow-step{width:min(100%,300px)}
  .flow-step+.flow-step::before{top:-20px;left:50%;margin-left:-6px;transform:rotate(135deg) scale(.5)}
  .flow-step.is-on+.flow-step::before,.flow-step.is-on::before{transform:rotate(135deg) scale(1)}
  .flow-replay{top:-52px}
  .makers{gap:26px;align-items:start}
  .makers-portrait,.makers-copy,.makers-machine,.makers-printer{grid-column:1/-1}
  .closing{display:block}
  .closing>.button{margin-top:22px}
  .footer{grid-template-columns:1fr}
  .foot-links{margin-top:0}
  .lost{grid-template-columns:1fr}
  .lost-figure{width:min(62%,260px)}
  dialog{padding:28px 20px;border-radius:24px}
  dialog h2{font-size:25px}
  .enq-alt{display:block}.enq-alt .button{width:100%}.zalo-scan{gap:14px}
}

@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation-duration:.001ms!important;transition-duration:.001ms!important;transition-delay:0s!important}
  dialog::backdrop{transition-duration:.001ms!important}
  .reveal-ready .reveal{opacity:1;translate:none}
  .reveal-ready .story::before{transform:none}
  .send[aria-busy=true] span[aria-hidden]{animation:none}
  .print-status .dot{animation:none}
}

/* the last panel keeps its distance from the window edge too */
.panel-ink{margin-bottom:var(--edge)}
