/* ============================================================
   Kismat Cookies — design system
   Palette: bone & ember
   ============================================================ */
:root{
  /* Dark roast — the same family as the light palette, one step further into
     the bake. Both themes now come off the one fortune-cookie photograph:
     #DBCDB2 sand  #3D2814 chocolate  #6F481E brown  #906938 caramel
     #A78258 tan   #B09F84 greige     #D9B687 wheat  */
  --base:#211407;
  --bg:#2E1D0C;
  --surface:#45301A;
  --text:#F0E3CC;
  --muted:#C4A87F;
  --line:#8A6739;
  --line-soft:#45301A;
  --accent:#D9B687;
  --accent-soft:#6F481E;
  --ink:#211407;
  --gradient:linear-gradient(36.97deg,#F5EAD6 10.09%,#D9B687 82%,#906938 140%);
  --nav-h:84px;
  --ease:cubic-bezier(.075,.82,.165,1);
  --container:1440px;
  --gutter:16px;
  /* rgb triplets so scrims and washes can be themed */
  --scrim:33,20,7;
  --text-rgb:240,227,204;
  --cookie-edge:transparent;
  --cookie-edge-w:0;
  --btn-deep:#150C03; --ink-on-deep:#F0E3CC;
  --on-gradient:#211407; --on-gradient-rgb:33,20,7;
  --veil:24,14,5; --aura:255,214,140;
  --moment-ink:#D8CDB4;   /* the veil is dark in every palette, so this never inverts */
  --glow-top-1:#4A3116; --glow-top-2:#2E1D0C;
  --glow-bot-1:#3E2911; --glow-bot-2:#211407;
}

/* --- Warm mode: sampled from a photograph of the real thing -----------------
   Every value below is lifted from the fortune-cookie photo: the sand of the
   plate, the chocolate of a baked edge, the browns and tans between.
   #DBCDB2 #3D2814 #6F481E #906938 #A78258 #B09F84 #D9B687

   Flat, with no gradient anywhere on the page. Two notes on what that costs.
   The white slips need a hairline, because white on this sand is 1.40:1 and
   they would read as holes. And the golden cookie is 1.01:1 on it — invisible —
   which is fine only because the cookie appears nowhere except the moment,
   whose veil stays dark. */
[data-theme="warm"]{
  --base:#D3C3A4;
  --bg:#DBCDB2;
  --surface:#EDE4D4;
  --text:#3D2814;
  --muted:#6F481E;
  --line:#906938;
  --line-soft:#C6B597;
  --accent:#6F481E;
  --accent-soft:#C6B597;
  --ink:#EDE4D4;
  --gradient:linear-gradient(0deg,#F2EBDE 0%,#F2EBDE 100%);
  --scrim:219,205,178;
  --text-rgb:61,40,20;
  --cookie-edge:transparent;
  --cookie-edge-w:0;
  --btn-deep:#2A1B0D; --ink-on-deep:#EDE4D4;
  --on-gradient:#3D2814; --on-gradient-rgb:61,40,20;
  --veil:36,26,16; --aura:255,205,120;
  --moment-ink:#DFCFAE;
  --glow-top-1:#DBCDB2; --glow-top-2:#DBCDB2;
  --glow-bot-1:#D3C3A4; --glow-bot-2:#D3C3A4;
}
[data-theme="warm"] body{background:var(--bg)}
[data-theme="warm"] .underlay{background:var(--base)}
[data-theme="warm"] .site-header.is-stuck{background:rgba(219,205,178,.88)}

/* white on this sand is 1.40:1 — the slips need an edge */
[data-theme="warm"] .paper--fortune{border:1px solid #A78258}
[data-theme="warm"] .paper{box-shadow:0 10px 26px rgba(61,40,20,.18)}
[data-theme="warm"] .spec .paper{box-shadow:0 22px 44px rgba(61,40,20,.22)}
[data-theme="warm"] .slip-card{box-shadow:0 30px 70px rgba(61,40,20,.26)}
[data-theme="warm"] .biscuit__half{filter:drop-shadow(0 16px 24px rgba(61,40,20,.34))}

/* the wash between palettes; added for a beat, then removed */
html.theme-shifting,html.theme-shifting *{
  transition:background-color .9s ease,background-image .9s ease,color .9s ease,
             border-color .9s ease,fill .9s ease,stroke .9s ease,box-shadow .9s ease !important}
@media (min-width:768px){ :root{ --gutter:48px; } }

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{-webkit-text-size-adjust:100%}
html.lenis,html.lenis body{height:auto}
.lenis.lenis-smooth{scroll-behavior:auto !important}
.lenis.lenis-stopped{overflow:hidden}

body{
  background:var(--bg);
  color:var(--text);
  font-family:"Plus Jakarta Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  font-weight:400;font-size:16px;line-height:1.4;letter-spacing:.01em;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img,svg{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
ul{list-style:none}
button,input,textarea{font:inherit;color:inherit}
::selection{background:var(--accent);color:var(--ink)}

.container{width:100%;max-width:var(--container);margin-inline:auto;padding-inline:var(--gutter)}

/* ---------- type ---------- */
h1,h2,h3,h4,.title,.h1,.h2,.h4{font-family:"Plus Jakarta Sans",sans-serif;font-weight:700;letter-spacing:-.025em}
.title,.h1{font-size:clamp(27px,6.2vw,50px);line-height:1;letter-spacing:-.02em}
.h2{font-size:clamp(32px,7vw,80px);line-height:1;letter-spacing:-.02em}
.h4{font-size:clamp(26px,5.4vw,45px);line-height:1.3;letter-spacing:-.02em}
.body-m-140{font-size:16px;font-weight:300;line-height:1.4;letter-spacing:.01em}
.text-muted{color:var(--muted)}
.eyebrow{font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}

/* slip type — the printed-fortune voice */
.slip{font-family:Georgia,"Times New Roman",serif;font-style:italic;line-height:1.35;color:var(--text)}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;align-items:center;gap:6px;height:42px;padding:0 20px;
  border-radius:100px;border:1px solid transparent;
  background:var(--text);color:var(--ink);
  font-size:16px;font-weight:400;line-height:1;white-space:nowrap;cursor:pointer;
  transition:background .4s var(--ease),color .4s var(--ease),border-color .4s var(--ease);
}
.btn svg{flex:none}
.btn:hover{background:#fff;color:var(--ink)}
.btn--outline{background:transparent;border-color:var(--line);color:var(--text)}
.btn--outline:hover{background:rgba(var(--text-rgb),.08);color:var(--text);border-color:var(--text)}
.btn--ember{background:var(--ink);color:var(--text)}
.btn--ember:hover{background:var(--btn-deep);color:var(--ink-on-deep)}
.btn--ghost{background:rgba(var(--scrim),.65);border:0;color:var(--text)}
.btn--dark{background:var(--ink);color:var(--text)}
.btn--dark:hover{background:var(--btn-deep);color:var(--ink-on-deep)}
.btn--lg{height:52px;padding:0 28px;font-size:18px}

/* ---------- skip link ---------- */
.skip-link{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.skip-link:focus{position:fixed;left:50%;translate:-50% 0;top:12px;z-index:200;
  width:auto;height:auto;margin:0;overflow:visible;clip:auto;clip-path:none;
  background:var(--text);color:var(--ink);padding:10px 18px;border-radius:100px;font-size:14px}

/* ---------- background ---------- */
.underlay{position:fixed;inset:0;z-index:-10;background:var(--base);pointer-events:none}
.underlay::before,.underlay::after{content:"";position:absolute;left:0;right:0;height:74vh}
.underlay::before{top:0;background:radial-gradient(120% 92% at 50% 0%,var(--glow-top-1) 0%,var(--glow-top-2) 44%,transparent 74%)}
.underlay::after{bottom:0;background:radial-gradient(120% 92% at 50% 100%,var(--glow-bot-1) 0%,var(--glow-bot-2) 46%,transparent 76%)}
.grain{position:fixed;inset:0;z-index:-9;pointer-events:none;opacity:.2;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/></filter><rect width='160' height='160' filter='url(%23n)' opacity='.5'/></svg>")}

/* ============================================================
   HEADER
   ============================================================ */
.site-header{position:fixed;inset:0 0 auto;z-index:120;height:var(--nav-h);display:flex;align-items:center;
  transition:background .4s var(--ease),backdrop-filter .4s var(--ease)}
.site-header.is-stuck{background:rgba(var(--scrim),.78);backdrop-filter:blur(14px)}
.site-header .container{display:flex;align-items:center;justify-content:space-between;gap:24px}
.brand{display:flex;align-items:center;gap:10px;font-family:"Plus Jakarta Sans",sans-serif;font-weight:700;letter-spacing:-.02em;font-size:21px;
  letter-spacing:-.02em;color:var(--text)}
.brand svg{width:23px;height:21px;color:var(--text)}
.nav{display:none}
.nav ul{display:flex;align-items:center;gap:28px}
.nav a{font-size:15px;font-weight:300;position:relative;padding:4px 0;opacity:.92;transition:opacity .3s}
.nav a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--accent);
  transform:scaleX(0);transform-origin:right;transition:transform .45s var(--ease)}
.nav a:hover{opacity:1}
.nav a:hover::after,.nav a[aria-current="page"]::after{transform:scaleX(1);transform-origin:left}

.nav-toggle{display:flex;flex-direction:column;justify-content:center;gap:5px;width:44px;height:44px;
  align-items:flex-end;background:none;border:0;cursor:pointer}
.nav-toggle span{display:block;height:1.5px;width:24px;background:var(--text);border-radius:2px;
  transition:transform .4s var(--ease),width .4s var(--ease)}
.nav-toggle span:last-child{width:16px}
.header-cta{display:none}
@media (min-width:1024px){
  .nav{display:flex}
  .nav-toggle{display:none}
  .header-cta{display:inline-flex}
}
body.menu-open .nav-toggle span:first-child{transform:translateY(6.5px) rotate(45deg)}
body.menu-open .nav-toggle span:last-child{transform:translateY(-6.5px) rotate(-45deg);width:24px}

.mobile-menu{position:fixed;inset:0;z-index:110;background:var(--bg);
  display:flex;flex-direction:column;justify-content:center;padding:var(--nav-h) var(--gutter) 40px;
  clip-path:inset(0 0 100% 0);transition:clip-path .7s var(--ease);pointer-events:none}
body.menu-open .mobile-menu{clip-path:inset(0 0 0 0);pointer-events:auto}
.mobile-menu ul{display:flex;flex-direction:column;gap:8px}
.mobile-menu a{font-family:"Plus Jakarta Sans",sans-serif;font-size:clamp(30px,9vw,46px);line-height:1.25;letter-spacing:-.02em;
  opacity:0;transform:translateY(20px);transition:opacity .5s var(--ease),transform .5s var(--ease)}
body.menu-open .mobile-menu a{opacity:1;transform:none}
body.menu-open .mobile-menu li:nth-child(1) a{transition-delay:.14s}
body.menu-open .mobile-menu li:nth-child(2) a{transition-delay:.2s}
body.menu-open .mobile-menu li:nth-child(3) a{transition-delay:.26s}
body.menu-open .mobile-menu li:nth-child(4) a{transition-delay:.32s}
body.menu-open .mobile-menu li:nth-child(5) a{transition-delay:.38s}

/* ============================================================
   HERO
   ============================================================ */
/* 300vh put ~2,300px of decorative sequence between the visitor and the
   first real sentence. 200vh halves that and the scrubbed timeline just
   plays over a shorter distance. */
.home-hero{position:relative;width:100%;height:200vh}
.hero-pin{position:sticky;top:0;height:100vh;height:100svh;width:100%;overflow:hidden;
  display:flex;align-items:center;justify-content:center}

.hero-frame{position:absolute;border:1px solid var(--line);border-radius:48px;pointer-events:none;
  left:50%;top:50%;translate:-50% -50%;height:56vh;opacity:0;
  /* Never narrower than the 820px text column it frames, never wider than the screen. */
  width:min(calc(100vw - 24px),900px)}
.hero-frame--b{width:min(calc(100vw - 6px),1100px);height:70vh;border-radius:56px}

.hero-title-wrap{position:relative;z-index:10;text-align:center;padding-inline:32px;width:100%;
  display:flex;flex-direction:column;align-items:center}
.hero-title{max-width:820px;margin-inline:auto}
.hero-title .char{display:inline-block;opacity:0;will-change:transform,opacity}
.hero-title .word{white-space:nowrap;display:inline-block}
.hero-sub{margin-top:24px;max-width:440px;opacity:.9}
.hero-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:12px;margin-top:40px}
@media (min-width:768px){.hero-actions{gap:24px}}

/* wish marquee */
.marquee{position:absolute;left:0;right:0;bottom:56px;z-index:6;overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent)}
.marquee__track{display:flex;width:max-content;align-items:center;animation:marquee 60s linear infinite}
.marquee:hover .marquee__track{animation-play-state:paused}
@keyframes marquee{to{transform:translateX(-50%)}}
.marquee .slip{font-size:16px;color:var(--muted);white-space:nowrap;padding-inline:28px;transition:color .4s}
@media (min-width:768px){.marquee .slip{font-size:19px;padding-inline:40px}}
.marquee .slip:hover{color:var(--text)}
.marquee .sep{flex:none;width:15px;height:14px;color:var(--muted);opacity:.5}

/* stage two: drifting wall of wishes */
.hero-grid{position:absolute;inset:0;z-index:2;overflow:hidden;opacity:0;visibility:hidden}
.grid-wrapper{position:absolute;left:50%;top:50%;translate:-50% -50%;
  display:flex;flex-direction:column;gap:24px;width:auto}
.grid-row{display:flex;gap:24px;will-change:transform}
.tile{flex:none;width:236px;height:236px;border:1px solid var(--line);border-radius:28px;
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:9px;
  padding:22px;background:rgba(var(--text-rgb),.015)}
@media (min-width:768px){.tile{width:300px;height:300px;border-radius:32px;padding:30px;gap:11px}}

/* The two pieces of the unit: the fortune, and the sponsor strip that
   finishes it. Both are printed paper, so both sit on white by default. */
.paper{width:100%;border-radius:2px;padding:11px 12px;text-align:center;
  box-shadow:0 6px 16px rgba(0,0,0,.34)}
@media (min-width:768px){.paper{padding:13px 14px}}
.paper--fortune{background:#F4F2ED;color:#15130F}
.paper--fortune p{font-family:"Plus Jakarta Sans",sans-serif;font-weight:400;font-size:11.5px;line-height:1.35}
.paper__nums{display:block;margin-top:6px;font-size:8.5px;letter-spacing:.06em;color:#5C5850}
@media (min-width:768px){
  .paper--fortune p{font-size:13px}
  .paper__nums{font-size:9.5px;margin-top:7px}
}
.paper--ad{background:var(--ad-bg);color:var(--ad-fg);
  display:flex;align-items:center;justify-content:space-between;gap:8px;text-align:left}
.paper--ad .qr{flex:none;opacity:.85;color:var(--ad-fg)}
.paper__tag{font-family:"Plus Jakarta Sans",sans-serif;font-weight:400;font-size:11px;line-height:1.25;flex:1;min-width:0}
@media (min-width:768px){.paper__tag{font-size:12.5px}}
.paper__id{display:flex;flex-direction:column;align-items:flex-end;gap:1px;flex:none;text-align:right}
.paper__id b{font-family:"Plus Jakarta Sans",sans-serif;font-weight:700;font-size:12px;letter-spacing:-.01em;line-height:1.1}
.paper__id em{font-style:normal;font-size:7.5px;letter-spacing:.02em;opacity:.8;line-height:1.1}
@media (min-width:768px){.paper__id b{font-size:14px}.paper__id em{font-size:8.5px}}

.hero-grid__copy{position:absolute;z-index:10;left:50%;top:68%;translate:-50% -50%;width:100%;max-width:290px}
@media (min-width:1024px){.hero-grid__copy{left:55%;top:50%;translate:0 -50%;max-width:380px}}
.hero-grid__copy p{font-size:clamp(18px,1.8vw,22px);font-weight:300;line-height:1.3}
.hero-grid__copy .actions{display:flex;align-items:center;gap:24px;margin-top:32px}
.hero-grid__note{display:block;margin-top:10px;font-size:12px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);opacity:.6}
.hero-grid::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(46% 62% at 62% 50%,rgba(var(--scrim),.92) 0%,rgba(var(--scrim),.6) 55%,transparent 100%),
    radial-gradient(120% 96% at 50% 50%,transparent 34%,rgba(var(--scrim),.68) 76%,var(--base) 100%)}
@media (max-width:1023px){
  /* Copy is centred rather than side-anchored below 1024, so centre what sits
     under it too, and darken the wall enough to read against. */
  .hero-grid__copy{text-align:center;max-width:340px;padding-inline:20px}
  .hero-grid__copy .actions{justify-content:center}
  .hero-grid::after{
    background:
      radial-gradient(70% 34% at 50% 68%,rgba(var(--scrim),.94) 0%,rgba(var(--scrim),.7) 60%,transparent 100%),
      linear-gradient(180deg,rgba(var(--scrim),.55) 0%,rgba(var(--scrim),.2) 22%,rgba(var(--scrim),.9) 62%,var(--base) 100%)}
}

.keep-scrolling{position:absolute;left:50%;translate:-50% 0;bottom:29px;z-index:12;opacity:0;pointer-events:none}
.scroll-cue{display:inline-flex;align-items:center;gap:8px}
.scroll-cue svg{animation:bob 1.8s var(--ease) infinite}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(3px)}}

/* ============================================================
   SECTIONS
   ============================================================ */
.section{position:relative;width:100%;padding:96px 0}
@media (min-width:768px){.section{padding:150px 0}}
.section--tight{padding:72px 0}
.section__head{max-width:760px;margin-bottom:64px}
.section__head.is-centered{margin-inline:auto;text-align:center}
.section__head h2{margin-bottom:20px;line-height:1.25}
.section__head p{color:var(--muted);font-size:clamp(16px,1.6vw,19px);max-width:560px}
.section__head.is-centered p{margin-inline:auto}
.section__head .eyebrow{margin-bottom:20px}

/* ---------- why it works ---------- */
.reasons{display:grid;gap:16px}
@media (min-width:768px){.reasons{grid-template-columns:repeat(2,1fr);gap:24px}}
.reason{position:relative;border:1px solid var(--line);border-radius:32px;padding:32px;
  display:flex;flex-direction:column;gap:16px;overflow:hidden;
  transition:border-color .5s var(--ease),transform .5s var(--ease)}
@media (min-width:768px){.reason{padding:40px}}
.reason:hover{border-color:var(--text);transform:translateY(-3px)}
.reason__n{font-family:"Plus Jakarta Sans",sans-serif;font-size:14px;letter-spacing:.14em;color:var(--accent)}
.reason h3{font-size:clamp(22px,2.4vw,30px);line-height:1.2;letter-spacing:-.01em}
.reason p{color:var(--muted);font-size:16px;line-height:1.55;max-width:46ch}

/* ---------- formats ---------- */
.formats{display:grid;gap:16px}
@media (min-width:768px){.formats{grid-template-columns:repeat(2,1fr);gap:24px}}
@media (min-width:1200px){.formats{grid-template-columns:repeat(3,1fr)}}
.formats > li{display:flex}
.format{flex:1;position:relative;display:flex;flex-direction:column;justify-content:flex-start;gap:16px;
  border:1px solid var(--line);border-radius:32px;padding:28px;min-height:248px;overflow:hidden;
  transition:border-color .5s var(--ease),transform .5s var(--ease)}
.format__bg{position:absolute;inset:0;background-image:var(--gradient);opacity:0;
  transition:opacity .5s var(--ease)}
.format > *:not(.format__bg){position:relative;z-index:1}
.format .meta{font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
  transition:color .5s var(--ease)}
.format h3{font-family:"Plus Jakarta Sans",sans-serif;font-weight:700;font-size:25px;line-height:1.2;letter-spacing:-.025em;margin-top:12px;
  transition:color .5s var(--ease)}
.format p{color:var(--muted);font-size:15px;line-height:1.55;transition:color .5s var(--ease)}
.format .know{display:inline-flex;align-items:center;gap:6px;font-size:15px;margin-top:20px;
  transition:color .5s var(--ease)}
.format .know svg{color:var(--accent);transition:color .5s var(--ease)}
.format:hover{border-color:rgba(var(--on-gradient-rgb),.22);transform:translateY(-4px)}
.format:focus-visible{border-color:rgba(var(--on-gradient-rgb),.34);transform:translateY(-4px)}
.format:hover .format__bg,.format:focus-visible .format__bg{opacity:1}
.format:hover .meta,.format:hover h3,.format:hover p,.format:hover .know,.format:hover .know svg,
.format:focus-visible .meta,.format:focus-visible h3,.format:focus-visible p,
.format:focus-visible .know,.format:focus-visible .know svg{color:var(--on-gradient)}

/* A photograph in the wall, sized like a slip tile so the two intermix. */
.tile--photo{padding:0;overflow:hidden;position:relative;display:block}
.tile--photo img{width:100%;height:100%;object-fit:cover;display:block}
.tile__credit{position:absolute;left:8px;bottom:7px;font-size:9px;letter-spacing:.05em;
  color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.7);opacity:.85}

/* --- case studies -------------------------------------------------------- */
.cases{list-style:none;margin:0;padding:0;display:grid;gap:20px}
@media (min-width:900px){.cases{grid-template-columns:repeat(2,1fr);gap:24px}}

.case{border:1px solid var(--line);border-radius:28px;padding:30px 28px;
  display:flex;flex-direction:column;gap:14px}
.case__head{display:flex;align-items:baseline;justify-content:space-between;gap:14px;flex-wrap:wrap}
.case__brand{font-weight:800;font-size:19px;letter-spacing:-.02em}
.case__where{font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.case__title{font-weight:700;font-size:clamp(20px,2.2vw,25px);line-height:1.22;letter-spacing:-.025em;margin:0}
.case__body{color:var(--muted);font-size:15.5px;line-height:1.55;margin:0}

.case__stats{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin:6px 0 0;
  padding-top:18px;border-top:1px solid var(--line-soft)}
.case__stats dt{font-weight:800;font-size:clamp(19px,2.2vw,24px);line-height:1.05;
  letter-spacing:-.03em;color:var(--accent)}
.case__stats dd{margin:6px 0 0;font-size:12.5px;line-height:1.35;color:var(--muted)}

/* whoever actually ran it — never us, and never hidden */
.case__by{margin:2px 0 0;font-size:12px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted);opacity:.8}

.cases__note{margin-top:26px;font-size:14px;line-height:1.6;color:var(--muted);max-width:70ch}
.cases__note a{color:var(--text);text-decoration:underline;text-underline-offset:3px}

@media (max-width:520px){
  .case{padding:24px 20px;border-radius:24px}
  .case__stats{grid-template-columns:1fr 1fr;gap:12px}
}

/* ---------- the unit: a slip you can look at ---------- */
.unit{display:grid;gap:48px;align-items:center}
@media (min-width:1024px){.unit{grid-template-columns:1fr minmax(0,520px);gap:80px}}
/* A single printed slip, shown flat (formats / why-it-works). */
.slip-card{position:relative;background:var(--gradient);color:var(--on-gradient);border-radius:18px;
  padding:38px 30px 28px;text-align:center;box-shadow:0 30px 70px rgba(0,0,0,.45);
  transform:rotate(-1.6deg);transition:transform .6s var(--ease)}
.slip-card:hover{transform:rotate(0deg) scale(1.02)}
.slip-card .slip{font-size:clamp(19px,2.4vw,26px);color:var(--on-gradient)}
.slip-card .brandline{margin-top:22px;padding-top:16px;border-top:1px solid rgba(var(--on-gradient-rgb),.24);
  font-family:"Plus Jakarta Sans",sans-serif;font-style:normal;font-weight:700;font-size:12px;letter-spacing:.15em;
  text-transform:uppercase;color:rgba(var(--on-gradient-rgb),.66)}
.slip-card .nums{display:block;margin-top:8px;font-size:12px;letter-spacing:.16em;
  color:rgba(var(--on-gradient-rgb),.55)}

/* --- the unit ------------------------------------------------------------
   The slip on its own. It used to float over a cracked cookie, which cropped
   both and explained neither; the cookie already has the fortune moment and
   the wall, so here the printed slip is the whole subject. */
.spec{display:flex;flex-direction:column;gap:8px;width:min(100%,420px);
  margin-inline:auto;transform:rotate(-1.4deg);transition:transform .6s var(--ease)}
.spec:hover{transform:rotate(0deg)}
.spec .paper{box-shadow:0 26px 52px rgba(0,0,0,.42)}
.spec .paper--fortune{padding:30px 24px 22px}
.spec .paper--fortune p{font-size:clamp(16px,2.1vw,20px);line-height:1.35}
.spec .paper__nums{font-size:clamp(12px,1.5vw,13.5px);margin-top:11px}
.spec .paper--ad{padding:15px 17px}
.spec .paper__tag{font-size:clamp(12px,1.5vw,13.5px)}
.spec .paper__id b{font-size:clamp(13.5px,1.7vw,15.5px)}
.spec .paper__id em{font-size:clamp(10px,1.2vw,11.5px)}

/* ============================================================
   THE CRACKER — a fortune cookie breaking open
   One 8s loop: the cookie sits, splits, the slip rises and is read,
   then it resets. Held still until scrolled into view, and skipped
   entirely for anyone who asked for reduced motion.
   ============================================================ */
.cracker{--crack-x:98px;--crack-y:60px;
  position:relative;width:100%;aspect-ratio:4/3;max-height:440px;
  display:flex;align-items:center;justify-content:center;
  perspective:1000px;perspective-origin:50% 45%}
.cracker__stage{position:relative;width:min(100%,420px);height:100%;
  transform-style:preserve-3d;display:flex;align-items:center;justify-content:center}

/* Real footage, when a file is dropped into assets/media/. */
.cracker.has-video{perspective:none}
.cracker__video{width:100%;height:100%;object-fit:contain;display:block}

/* --- the biscuit (named to avoid colliding with .cookie, the consent bar) --- */
.biscuit{position:absolute;left:50%;top:50%;translate:-50% -50%;
  width:min(88%,318px);aspect-ratio:300/250;transform-style:preserve-3d;z-index:2}
.biscuit__half{position:absolute;inset:0;width:100%;height:100%;
  transform-origin:50% 46%;filter:drop-shadow(0 16px 24px rgba(0,0,0,.45))}
/* fills are SVG gradients — CSS only adds the drop shadow */

/* --- the slip: the same two-piece unit that fills the hero wall --- */
.fortune-slip{position:absolute;z-index:4;width:min(84%,300px);
  display:flex;flex-direction:column;gap:7px;
  opacity:0;transform:translateY(-4px) scale(.66) rotate(-2deg)}
.fortune-slip .paper{box-shadow:0 14px 32px rgba(0,0,0,.5)}
.fortune-slip .paper--fortune p{font-size:13px}
.fortune-slip .paper__nums{font-size:11px}
@media (min-width:768px){
  .fortune-slip .paper--fortune p{font-size:14.5px}
  .fortune-slip .paper__nums{font-size:10.5px}
}

/* --- crumbs --- */
.biscuit__crumb{position:absolute;left:50%;top:56%;width:9px;height:7px;border-radius:2px 3px 2px 3px;
  background:linear-gradient(150deg,#F3D296,#D2913F);opacity:0;z-index:3;
  box-shadow:0 2px 4px rgba(0,0,0,.35)}
.biscuit__crumb:nth-of-type(2){width:6px;height:5px}
.biscuit__crumb:nth-of-type(3){width:11px;height:8px}
.biscuit__crumb:nth-of-type(4){width:5px;height:5px}
.biscuit__crumb:nth-of-type(5){width:8px;height:6px}

/* --- the loop, only once in view --- */
.cracker.is-in .biscuit__half--l{animation:crack-left 8s var(--ease) infinite}
.cracker.is-in .biscuit__half--r{animation:crack-right 8s var(--ease) infinite}
.cracker.is-in .fortune-slip{animation:slip-rise 8s var(--ease) infinite}
.cracker.is-in .biscuit__crumb:nth-of-type(1){animation:crumb 8s var(--ease) infinite;--cx:-58px;--cy:44px}
.cracker.is-in .biscuit__crumb:nth-of-type(2){animation:crumb 8s var(--ease) infinite;--cx:52px;--cy:52px}
.cracker.is-in .biscuit__crumb:nth-of-type(3){animation:crumb 8s var(--ease) infinite;--cx:-30px;--cy:64px}
.cracker.is-in .biscuit__crumb:nth-of-type(4){animation:crumb 8s var(--ease) infinite;--cx:28px;--cy:70px}
.cracker.is-in .biscuit__crumb:nth-of-type(5){animation:crumb 8s var(--ease) infinite;--cx:6px;--cy:82px}

@keyframes crack-left{
  0%,14%   {transform:translate3d(0,0,0) rotate(0deg) rotateY(0deg)}
  17%      {transform:translate3d(-2px,0,0) rotate(-1.5deg) rotateY(0deg)}
  20%      {transform:translate3d(2px,0,0) rotate(1deg) rotateY(0deg)}
  34%,74%  {transform:translate3d(calc(var(--crack-x) * -1),var(--crack-y),-30px) rotate(-19deg) rotateY(22deg)}
  92%,100% {transform:translate3d(0,0,0) rotate(0deg) rotateY(0deg)}
}
@keyframes crack-right{
  0%,14%   {transform:translate3d(0,0,0) rotate(0deg) rotateY(0deg)}
  17%      {transform:translate3d(2px,0,0) rotate(1.5deg) rotateY(0deg)}
  20%      {transform:translate3d(-2px,0,0) rotate(-1deg) rotateY(0deg)}
  34%,74%  {transform:translate3d(var(--crack-x),var(--crack-y),-30px) rotate(19deg) rotateY(-22deg)}
  92%,100% {transform:translate3d(0,0,0) rotate(0deg) rotateY(0deg)}
}
@keyframes slip-rise{
  0%,18%   {opacity:0;transform:translateY(-4px) scale(.66) rotate(-2deg)}
  38%      {opacity:1;transform:translateY(-34px) scale(1) rotate(-1.5deg)}
  70%      {opacity:1;transform:translateY(-38px) scale(1) rotate(-1.5deg)}
  84%,100% {opacity:0;transform:translateY(-6px) scale(.68) rotate(-2deg)}
}
@keyframes crumb{
  0%,16%  {opacity:0;transform:translate(0,0) scale(.6)}
  22%     {opacity:.85;transform:translate(calc(var(--cx) * .35),calc(var(--cy) * -.2)) scale(1)}
  46%     {opacity:0;transform:translate(var(--cx),var(--cy)) scale(.7)}
  100%    {opacity:0;transform:translate(var(--cx),var(--cy)) scale(.7)}
}

/* Static, already-open state when motion is unwelcome. */
@media (prefers-reduced-motion:reduce){
  .cracker .biscuit__half--l{transform:translate3d(calc(var(--crack-x) * -1),var(--crack-y),0) rotate(-19deg)}
  .cracker .biscuit__half--r{transform:translate3d(var(--crack-x),var(--crack-y),0) rotate(19deg)}
  .cracker .fortune-slip{opacity:1;transform:translateY(-34px) scale(1) rotate(-1.5deg)}
  .cracker .biscuit__crumb{opacity:0}
  .cracker.is-in .biscuit__half--l,.cracker.is-in .biscuit__half--r,
  .cracker.is-in .fortune-slip,.cracker.is-in .biscuit__crumb{animation:none}
}

/* ---------- stat / target strip ---------- */
/* Three figures, given the room to actually land. The numbers were set at
   body-adjacent sizes and read as captions; at this scale they carry the
   section, and the rules between them do the separating instead of gaps. */
.targets{border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:68px 0}
.targets__grid{display:grid;gap:0}
@media (min-width:768px){
  .targets__grid{grid-template-columns:repeat(3,1fr)}
  .target{padding:4px 44px}
  .target + .target{border-left:1px solid var(--line-soft)}
  .target:first-child{padding-left:0}
  .target:last-child{padding-right:0}
}
.target .num{font-family:"Plus Jakarta Sans",sans-serif;font-weight:800;
  font-size:clamp(54px,7.4vw,92px);line-height:.92;letter-spacing:-.05em;color:var(--accent)}
.target .label{margin-top:16px;color:var(--muted);font-size:16px;line-height:1.5;max-width:250px}

/* ---------- journal ---------- */

/* ---------- closing ---------- */
.closing{padding:96px 0 120px;text-align:center}
@media (min-width:768px){.closing{padding:150px 0 180px}}
.closing h2{margin-bottom:16px}
.closing p{color:var(--muted);margin-bottom:40px;font-size:clamp(18px,2vw,22px)}
.closing .btn{margin-inline:auto}

/* ---------- footer ---------- */
.site-footer{border-top:1px solid var(--line);padding:64px 0 40px}
.footer-grid{display:grid;gap:48px}
@media (min-width:768px){.footer-grid{grid-template-columns:1.4fr 1fr 1fr;gap:32px}}
.site-footer h2{font-size:16px;font-family:"Plus Jakarta Sans",sans-serif;font-weight:500;margin-bottom:20px}
.site-footer ul{display:flex;flex-direction:column;gap:12px}
.site-footer a{font-size:15px;color:var(--muted);transition:color .3s}
.site-footer a:hover{color:var(--text)}
.footer-mail{font-family:"Plus Jakarta Sans",sans-serif;font-size:clamp(22px,3vw,34px);letter-spacing:-.02em;
  color:var(--text) !important;display:inline-block}
.footer-mail:hover{color:var(--accent) !important}
.footer-bottom{margin-top:64px;padding-top:24px;border-top:1px solid var(--line);
  display:flex;flex-wrap:wrap;gap:16px 32px;align-items:center;justify-content:space-between;
  font-size:14px;color:var(--muted)}
.footer-bottom ul{flex-direction:row;gap:24px;flex-wrap:wrap}
.footer-bottom a{font-size:14px}

/* ---------- sticky cta ---------- */
.sticky-cta{position:fixed;left:16px;right:16px;bottom:16px;z-index:100;
  background:var(--text);color:var(--ink);border-radius:16px;
  display:flex;align-items:center;gap:16px;padding:14px 16px;
  transform:translateY(160%);transition:transform .7s var(--ease);box-shadow:0 18px 50px rgba(0,0,0,.5)}
@media (min-width:768px){.sticky-cta{padding:16px 20px;border-radius:20px;left:24px;right:24px}}
.sticky-cta.is-visible{transform:none}
.sticky-cta.is-dismissed{transform:translateY(160%) !important}
.sticky-cta h3{font-family:"Plus Jakarta Sans",sans-serif;font-weight:600;font-size:clamp(17px,2.2vw,28px);
  color:var(--ink);line-height:1.3}
.sticky-cta p{display:none;color:#4A6B5C;font-size:16px}
@media (min-width:768px){.sticky-cta p{display:block}}
.sticky-cta .spacer{margin-left:auto}
.sticky-cta .btn{background:var(--ink);color:var(--text)}
.sticky-cta .btn:hover{background:var(--btn-deep);color:var(--ink-on-deep)}
.sticky-close{position:absolute;top:-46px;right:0;width:32px;height:32px;border-radius:100px;
  border:1px solid var(--line);background:rgba(var(--scrim),.85);color:var(--text);
  display:flex;align-items:center;justify-content:center;cursor:pointer;transition:.3s}
.sticky-close:hover{background:var(--text);color:var(--ink)}

/* ---------- cookie ---------- */
.cookie{position:fixed;left:16px;right:16px;bottom:16px;z-index:130;max-width:680px;
  background:var(--text);color:var(--ink);border-radius:16px;padding:18px;
  display:flex;flex-direction:column;gap:16px;box-shadow:0 18px 50px rgba(0,0,0,.5);
  transform:translateY(180%);transition:transform .7s var(--ease)}
@media (min-width:768px){.cookie{flex-direction:row;align-items:center;gap:24px;padding:16px 20px;left:24px}}
.cookie.is-visible{transform:none}
.cookie p{font-size:13px;line-height:1.45;color:#274438}
.cookie__actions{display:flex;align-items:center;gap:10px;flex:none}
.cookie__actions .btn{height:38px;font-size:15px}
.cookie__actions .link{font-size:15px;text-decoration:underline;text-underline-offset:3px;cursor:pointer;
  background:none;border:0;color:var(--ink)}

.modal{position:fixed;inset:0;z-index:140;display:none;align-items:center;justify-content:center;padding:16px}
.modal.is-open{display:flex}
.modal__scrim{position:absolute;inset:0;background:rgba(var(--scrim),.78);backdrop-filter:blur(4px)}
.modal__panel{position:relative;background:var(--text);color:var(--ink);border-radius:20px;
  width:100%;max-width:560px;max-height:86vh;overflow:auto;padding:28px}
.modal__panel h2{font-size:24px;margin-bottom:8px}
.modal__panel > p{font-size:14px;color:#3E5C4E;margin-bottom:24px}
.pref{display:flex;gap:16px;padding:16px 0;border-top:1px solid #B9D6C3}
.pref__body h3{font-family:"Plus Jakarta Sans",sans-serif;font-weight:500;font-size:15px;margin-bottom:4px}
.pref__body p{font-size:13px;color:#4A6B5C;line-height:1.45}
.switch{position:relative;flex:none;width:44px;height:26px;margin-left:auto}
.switch input{position:absolute;opacity:0;width:100%;height:100%;margin:0;cursor:pointer}
.switch i{position:absolute;inset:0;background:#B9D6C3;border-radius:100px;transition:.3s;pointer-events:none}
.switch i::after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;
  background:#fff;transition:.3s}
.switch input:checked + i{background:var(--ink)}
.switch input:checked + i::after{transform:translateX(18px)}
.switch input:disabled + i{opacity:.55}
.modal__actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:24px;padding-top:20px;border-top:1px solid #B9D6C3}
.modal__close{position:absolute;top:16px;right:16px;width:32px;height:32px;border-radius:100px;
  border:1px solid #B9D6C3;background:none;cursor:pointer;display:flex;align-items:center;justify-content:center}

/* ---------- inner pages ---------- */
.page-hero{padding:calc(var(--nav-h) + 72px) 0 56px}
@media (min-width:768px){.page-hero{padding:calc(var(--nav-h) + 140px) 0 80px}}
.page-hero h1{max-width:1000px;line-height:1.15}
.page-hero p{margin-top:24px;max-width:600px;color:var(--muted);font-size:clamp(16px,1.6vw,20px)}

/* ---------- contact ---------- */
.contact-grid{display:grid;gap:48px;padding-bottom:120px}
@media (min-width:1024px){.contact-grid{grid-template-columns:1fr minmax(0,620px);gap:80px}}
.form{display:grid;gap:24px}
.field{display:flex;flex-direction:column;gap:8px}
.field label{font-size:14px;color:var(--muted)}
.field input,.field textarea{background:transparent;border:0;border-bottom:1px solid var(--line);
  padding:12px 0;font-size:17px;font-weight:300;transition:border-color .35s var(--ease)}
.field textarea{resize:vertical;min-height:110px}
.field input:focus,.field textarea:focus{outline:none;border-color:var(--text)}
.field .error{font-size:13px;color:#F2A6A6;display:none}
.field.is-invalid input,.field.is-invalid textarea{border-color:#F2A6A6}
.field.is-invalid .error{display:block}
.honeypot{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form-success{border:1px solid var(--line);border-radius:24px;padding:28px;display:none}
.form-success.is-visible{display:block}
.form-success--error{border-color:#F2A6A6}
.form-success--error h3{color:#F2A6A6}
.form-success h3{font-size:26px;margin-bottom:8px}
.form-success p{color:var(--muted)}

/* ============================================================
   MOBILE PASS
   ============================================================ */
@media (max-width:767px){
  /* The decorative frames are sized in vw, so on a phone they ended up
     narrower than the text they are meant to contain. Give them the width
     of the screen instead. */
  .hero-frame{height:62vh;border-radius:36px}
  .hero-frame--b{height:72vh;border-radius:40px}
  /* The wall is background texture, not something to read. At 236px the
     slips cropped mid-card and looked broken; smaller they tile properly
     and sit behind the copy instead of fighting it. */
  /* Scoped to .tile: these sizes are for the wall, which is texture. The same
     component is real, readable content in the unit section and the moment, so
     it must not inherit 7px type there. */
  .tile{width:150px;height:150px;border-radius:18px;padding:13px;gap:6px}
  .tile .paper{padding:7px 7px;box-shadow:0 3px 9px rgba(0,0,0,.3)}
  .tile .paper--fortune p{font-size:8px;line-height:1.3}
  .tile .paper__nums{font-size:6px;margin-top:3px}
  .tile .paper--ad{gap:5px}
  .tile .paper--ad .qr{width:15px;height:15px}
  .tile .paper__tag{font-size:7.5px;line-height:1.2}
  .tile .paper__id b{font-size:8px}
  .tile .paper__id em{font-size:5.5px}
  .grid-row{gap:14px}
  .grid-wrapper{gap:14px}
  .keep-scrolling{bottom:20px}

  /* Footer and utility links sat at 19-21px tall. Padding gives them a
     thumb-sized target without changing how they look. */
  .site-footer a,.footer-bottom a,.theme-back{display:inline-block;padding:9px 0}
  .footer-mail{padding:9px 0}   /* also the one in the contact sidebar */
  .cookie .link{padding:10px 4px}
  .brand{padding:4px 0}

  .hero-title-wrap{padding-inline:22px}
  .hero-sub{max-width:32ch;margin-top:18px}
  .hero-actions{margin-top:30px}
  .marquee{bottom:36px}

  /* Tighter vertical rhythm — the desktop spacing left large dead zones. */
  .section{padding:72px 0}
  .section--tight{padding:56px 0}
  .section__head{margin-bottom:36px}
  .page-hero{padding:calc(var(--nav-h) + 48px) 0 36px}
  .page-hero p{margin-top:18px}
  .closing{padding:72px 0 88px}
  .unit{gap:32px}
  .targets{padding:44px 0}
  .targets__grid{gap:0}
  .target + .target{border-top:1px solid var(--line-soft);margin-top:30px;padding-top:30px}
  .target .label{font-size:15.5px;max-width:none}

  /* Reasons and formats become horizontal, snapping scrollers on a phone.
     Stacked they ran to several screens each; this keeps them to one, and the
     part-visible next card is the affordance that there is more. */
  .reasons,.formats{
    display:flex;flex-wrap:nowrap;gap:12px;
    overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
    /* bleed past the container so cards reach the screen edge */
    margin-inline:calc(var(--gutter) * -1);
    padding:2px var(--gutter) 10px;
    scrollbar-width:none;
  }
  .reasons::-webkit-scrollbar,.formats::-webkit-scrollbar{display:none}
  .reasons:focus-visible,.formats:focus-visible{outline:2px solid var(--accent);outline-offset:4px}
  .reasons > *,.formats > li{flex:0 0 84%;scroll-snap-align:start}
  .reason{height:auto}

  /* Cards sized by their content rather than a fixed height, so the title
     and body stop being pushed to opposite ends of an empty box. */
  .format{min-height:0;gap:18px;padding:24px}
  .format h3{font-size:22px;margin-top:10px}
  .format .know{margin-top:14px}
  .reason{padding:26px;gap:12px}
  .reason h3{font-size:22px}
  .slip-card{padding:32px 24px}
  .cracker{--crack-x:64px;--crack-y:44px;aspect-ratio:1/1;max-height:330px}
  .biscuit{width:min(80%,235px)}
  .fortune-slip{width:min(88%,255px)}

  /* Consent bar was eating a third of the screen. */
  .cookie{padding:14px;gap:12px;border-radius:14px}
  .cookie p{font-size:12px;line-height:1.45}
  .cookie__actions{gap:8px}
  .cookie__actions .btn{height:34px;font-size:14px;padding:0 15px}
  .cookie__actions .link{font-size:14px}
  .sticky-cta{padding:12px 14px;border-radius:14px}
  .sticky-cta .btn{height:38px;font-size:15px;padding:0 16px}
  .modal__panel{padding:22px}
  .site-footer{padding:48px 0 32px}
  .footer-grid{gap:36px}
  .footer-bottom{margin-top:44px}
}

/* ============================================================
   STATIC HERO FALLBACK
   No scroll animation (reduced motion, or GSAP unavailable), so the two
   hero stages stack down the page instead of overlaying one another.
   ============================================================ */
.home-hero.is-static{height:auto}
.home-hero.is-static .hero-pin{position:relative;height:auto;overflow:visible;
  flex-direction:column;gap:72px;padding:calc(var(--nav-h) + 72px) 0 0}
.home-hero.is-static .hero-frame,
.home-hero.is-static .keep-scrolling{display:none}
.home-hero.is-static .hero-title-wrap{position:relative}
.home-hero.is-static .hero-title .char{opacity:1}
.home-hero.is-static .marquee{position:relative;bottom:auto;width:100%}
.home-hero.is-static .hero-grid{position:relative;inset:auto;width:100%;height:520px;
  opacity:1;visibility:visible}
.home-hero.is-static .grid-wrapper{scale:1}
.home-hero.is-static .hero-grid__copy{left:50%;top:50%;translate:-50% -50%;
  max-width:420px;text-align:center}
.home-hero.is-static .hero-grid__copy .actions{justify-content:center}

/* ---------- reveal ---------- */
.reveal{opacity:0;transform:translateY(24px);transition:opacity .9s var(--ease),transform .9s var(--ease)}
.reveal.is-in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}
  .reveal{opacity:1;transform:none}
  .hero-title .char{opacity:1 !important;transform:none !important}
}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:4px}

/* ============ the fortune moment ============================================
   A one-time interruption: the cookie arrives centre-screen, the visitor
   cracks it, reads the line, and the palette turns over behind them. Shown
   once per visitor and dismissible at any point — it must never be a wall. */
.moment{position:fixed;inset:0;z-index:120;display:grid;place-items:center;
  opacity:0;pointer-events:none;transition:opacity .5s var(--ease)}
.moment.is-in{opacity:1;pointer-events:auto}
/* The moment is lit from the middle: the page is veiled so the cookie becomes
   the only light source, rather than sitting on a flat wash of the page colour. */
.moment__scrim{position:absolute;inset:0;z-index:0;
  background:
    radial-gradient(closest-side at 50% 44%,rgba(var(--aura),.22) 0%,rgba(var(--aura),.08) 46%,transparent 74%),
    radial-gradient(132% 100% at 50% 44%,rgba(var(--veil),.74) 0%,rgba(var(--veil),.96) 56%,rgba(var(--veil),.995) 100%);
  backdrop-filter:blur(8px) saturate(.92)}

/* the bloom behind the cookie, which swells as it opens */
.moment__aura{position:absolute;left:50%;top:52%;translate:-50% -50%;z-index:0;
  width:340%;aspect-ratio:1;pointer-events:none;
  background:
    radial-gradient(closest-side,rgba(var(--aura),.46) 0%,rgba(var(--aura),.20) 22%,rgba(var(--aura),.07) 44%,transparent 68%);
  opacity:.85;animation:aura-breathe 6.5s ease-in-out infinite;
  transition:opacity 1.2s var(--ease)}
/* a tighter core so the cookie sits in light rather than in front of it */
.moment__aura::after{content:"";position:absolute;left:50%;top:50%;translate:-50% -50%;
  width:42%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(closest-side,rgba(var(--aura),.55),rgba(var(--aura),.18) 55%,transparent 78%)}
@keyframes aura-breathe{0%,100%{transform:scale(1)}50%{transform:scale(1.09)}}
.moment.is-open .moment__aura{opacity:1;animation-duration:4.5s}

/* one ring, once, at the moment it gives */
.moment__cookie::after{content:"";position:absolute;left:50%;top:52%;translate:-50% -50%;
  width:70%;aspect-ratio:1;border-radius:50%;pointer-events:none;z-index:0;
  border:1px solid rgba(var(--aura),.55);opacity:0}
.moment.is-open .moment__cookie::after{animation:aura-ring 1.5s var(--ease) .1s forwards}
@keyframes aura-ring{
  0%{opacity:.75;transform:translate(-50%,-50%) scale(.5)}
  100%{opacity:0;transform:translate(-50%,-50%) scale(3.4)}
}

/* --- night sky ------------------------------------------------------------
   Stars sit above the veil so they read as light rather than as dust, each
   twinkling on its own clock so the field never pulses together. */
.moment__sky{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.star{position:absolute;left:var(--x);top:var(--y);width:var(--s);height:var(--s);
  border-radius:50%;background:rgb(var(--aura));
  box-shadow:0 0 5px rgba(var(--aura),.9),0 0 12px rgba(var(--aura),.45);
  opacity:var(--o);animation:twinkle var(--t) ease-in-out var(--d) infinite}
@keyframes twinkle{
  0%,100%{opacity:calc(var(--o) * .3);transform:scale(.8)}
  50%{opacity:var(--o);transform:scale(1)}
}

/* two wishes crossing, rarely */
.shoot{position:absolute;width:120px;height:1.5px;border-radius:2px;opacity:0;
  background:linear-gradient(90deg,transparent,rgba(var(--aura),.95),transparent);
  filter:drop-shadow(0 0 5px rgba(var(--aura),.8))}
.shoot--a{top:16%;left:-12%;animation:shoot 13s ease-in 3s infinite}
.shoot--b{top:62%;left:-12%;animation:shoot 17s ease-in 9.5s infinite}
@keyframes shoot{
  0%{opacity:0;transform:translate(0,0) rotate(14deg)}
  3%{opacity:1}
  11%{opacity:0;transform:translate(128vw,30vh) rotate(14deg)}
  100%{opacity:0;transform:translate(128vw,30vh) rotate(14deg)}
}

/* motes rising through the sky, brighter than before */
.moment__motes{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.mote{position:absolute;left:var(--x);bottom:14%;width:var(--s);height:var(--s);border-radius:50%;
  background:rgb(var(--aura));box-shadow:0 0 7px rgba(var(--aura),.75);opacity:0;
  animation:mote-rise var(--t) linear var(--d) infinite}
@keyframes mote-rise{
  0%{transform:translateY(40px) scale(.5);opacity:0}
  12%{opacity:1}
  70%{opacity:.7}
  100%{transform:translateY(-46vh) scale(1);opacity:0}
}
/* backdrop-filter makes the scrim a stacking context, so the panel needs to
   say out loud that it sits above it. */
.moment__inner{position:relative;z-index:1;text-align:center;padding:24px;
  display:flex;flex-direction:column;align-items:center;gap:0}

/* The fortune keeps the column it always had; the stage around it is what
   makes room for the film. Because the stage is centred, the film growing
   from zero width on the right walks the fortune to the left by itself —
   one transition rather than two that have to agree with each other. */
.moment__stage{display:flex;align-items:center;justify-content:center}
.moment__fortune{display:flex;flex-direction:column;align-items:center;
  flex:0 0 auto}

.moment__eyebrow{font-size:12px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;
  color:var(--moment-ink);margin:0 0 -30px}

.moment__cookie{background:none;border:0;padding:0;cursor:pointer;
  width:min(64vw,244px);aspect-ratio:300/250;position:relative;
  transition:transform .4s var(--ease)}
/* No focus box around the cookie — a rectangle around a round object looks
   like a mistake. It glows instead, which reads on a pointer and a keyboard
   alike and still marks focus clearly. */
.moment__cookie{outline:none}
.moment__cookie .biscuit__half{transition:filter .45s var(--ease)}
.moment__cookie:hover{transform:scale(1.04)}
.moment__cookie:hover .biscuit__half,
.moment__cookie:focus-visible .biscuit__half{
  filter:drop-shadow(0 0 16px rgba(255,214,120,.5)) drop-shadow(0 0 42px rgba(255,190,80,.34))
         drop-shadow(0 16px 24px rgba(0,0,0,.45))}
.moment__cookie:focus-visible{transform:scale(1.04)}
.moment .biscuit{position:absolute;inset:0;width:100%;height:100%;translate:0 0;left:0;top:0}

/* a slow breath while it waits to be tapped */
@keyframes moment-idle{0%,100%{transform:translateY(0) rotate(-1deg)}50%{transform:translateY(-7px) rotate(1deg)}}
.moment:not(.is-open) .biscuit{animation:moment-idle 3.4s ease-in-out infinite}

/* the crack: one shot, forwards, no loop */
@keyframes moment-left{to{transform:translate3d(-78px,-6px,0) rotate(-26deg);opacity:1}}
@keyframes moment-right{to{transform:translate3d(78px,-6px,0) rotate(26deg);opacity:1}}
.moment.is-open .biscuit{animation:none}
.moment.is-open .biscuit__half--l{animation:moment-left .85s var(--ease) forwards}
.moment.is-open .biscuit__half--r{animation:moment-right .85s var(--ease) forwards}
.moment.is-open .moment__cookie{pointer-events:none}
.moment.is-open .biscuit__crumb{animation:crumb 1.1s var(--ease) forwards}

.moment__hint{font-size:14px;font-weight:500;color:var(--moment-ink);margin-top:-26px;
  transition:opacity .3s}
.moment.is-open .moment__hint{opacity:0;height:0;margin:0;overflow:hidden}

.moment__slip{width:min(86vw,330px);display:flex;flex-direction:column;gap:6px;
  height:0;margin:0;overflow:hidden;
  opacity:0;transform:translateY(14px) scale(.94);
  transition:opacity .7s var(--ease) .45s,transform .7s var(--ease) .45s}
.moment.is-open .moment__slip{height:auto;margin-top:6px;overflow:visible;opacity:1;transform:none}
.moment__slip .paper{box-shadow:0 16px 34px rgba(0,0,0,.5)}
/* one line, whatever the screen — the type shrinks rather than the line wrapping */
.moment__slip .paper--fortune p{white-space:nowrap;font-size:clamp(12px,3.6vw,15px)}
.moment__slip .paper__nums{font-size:clamp(12px,3.2vw,13px)}
.moment__slip .paper__tag{font-size:clamp(12px,3.2vw,13.5px)}
.moment__slip .paper__id b{font-size:clamp(11.5px,3.2vw,13px)}

/* --- the film beside the fortune -------------------------------------------
   Only ever laid out once the video has decoded a frame (`has-film`, set in
   site.js), so a missing or broken file leaves the moment as the single
   centred column it has always been rather than an empty frame. */
.moment__film{--film-w:min(34vw,400px,50vh);   /* 50vh, because it stands 1.25x its own width */
  display:none;flex:0 0 auto;margin-left:0;
  width:0;opacity:0;pointer-events:none;
  transform:translateX(-30px) scale(.94);
  transition:width .9s var(--ease),margin-left .9s var(--ease),
             transform .9s var(--ease),opacity .55s var(--ease) .3s}
.moment.has-film .moment__film{display:block}
.moment.has-film.is-open .moment__film{
  width:var(--film-w);margin-left:clamp(20px,3.2vw,44px);
  opacity:1;transform:none;pointer-events:auto}

/* Held at its full width throughout, so the frame never squashes while the
   wrapper is still opening — the wrapper clips nothing, it just has no width
   yet, and the opacity delay covers the overhang. */
.moment__video{display:block;width:var(--film-w);aspect-ratio:4/5;
  object-fit:cover;border-radius:16px;background:rgba(0,0,0,.35);
  box-shadow:0 24px 52px rgba(0,0,0,.55),0 0 0 1px rgba(var(--aura),.20) inset}

.moment__caption{width:var(--film-w);margin:12px 0 0;font-size:12.5px;
  letter-spacing:.03em;line-height:1.45;color:var(--moment-ink);opacity:.75}

/* Phones stack it under the slip and shrink it, because a 4:5 frame at any
   real width next to the cookie will not fit a phone viewport. Height snaps
   rather than eases, the same as the slip above it does. */
@media (max-width:860px){
  /* The stack can genuinely outrun a short phone, so let the overlay scroll.
     `safe` matters: plain centring would push the top of the panel off the
     top edge with no way back to it. Desktop needs none of this — the 50vh
     cap above guarantees the two columns fit. */
  .moment{place-items:safe center;overflow-y:auto}
  .moment__stage{flex-direction:column}
  .moment__film{--film-w:min(48vw,186px,26vh);
    width:auto;height:0;margin-left:0;overflow:hidden;
    transform:translateY(-16px) scale(.94);
    transition:transform .7s var(--ease),opacity .5s var(--ease) .3s}
  .moment.has-film.is-open .moment__film{
    width:auto;height:auto;margin:14px 0 0;overflow:visible}
}

.moment__close{height:0;margin:0;padding:0;overflow:hidden;background:none;border:0;cursor:pointer;
  font-size:13px;letter-spacing:.06em;color:var(--moment-ink);text-decoration:underline;
  text-underline-offset:4px;opacity:0;transition:opacity .5s var(--ease) 1.1s}
.moment.is-open .moment__close{height:auto;margin-top:14px;padding:10px 16px;overflow:visible;opacity:1}
.moment__close:hover{color:#FFF6E4}

/* a way back while both palettes exist */
.theme-back{display:none;background:none;border:0;cursor:pointer;font:inherit;
  font-size:13px;color:var(--muted);text-decoration:underline;text-underline-offset:4px}
[data-theme="warm"] .theme-back{display:inline}
.theme-back:hover{color:var(--text)}

@media (prefers-reduced-motion:reduce){
  .mote{animation:none;opacity:.4}
  .star{animation:none}
  .shoot{display:none}
  .moment__aura{animation:none;transition:none}
  .moment.is-open .moment__cookie::after{animation:none;opacity:0}
  .moment:not(.is-open) .biscuit{animation:none}
  .moment.is-open .biscuit__half--l{animation:none;transform:translate3d(-78px,-6px,0) rotate(-26deg)}
  .moment.is-open .biscuit__half--r{animation:none;transform:translate3d(78px,-6px,0) rotate(26deg)}
  .moment.is-open .biscuit__crumb{opacity:0}
  .moment__slip{transition-duration:.01ms}
  .moment__film{transition-duration:.01ms;transform:none}
  html.theme-shifting,html.theme-shifting *{transition-duration:.01ms !important}
}
