/* INFI demo deck — dark, cobalt-forward, continuous with the 3D room in act one. */
:root{
  --ink:#05070f;--ink2:#0a0e1d;--glass:rgba(22,30,64,.55);
  --line:rgba(157,177,255,.16);--line2:rgba(157,177,255,.34);
  --paper:#eef2ff;--mute:rgba(233,238,255,.82);--dim:rgba(233,238,255,.62);
  --blue:#2f5dff;--blue2:#4f78ff;--sky:#9db1ff;--amber:#ffb547;--ok:#3ddc97;--green:#3ddc97;
  --display:'Clash Display',ui-sans-serif,system-ui,sans-serif;
  --body:'General Sans',ui-sans-serif,system-ui,-apple-system,sans-serif;
  --ease:cubic-bezier(.16,1,.3,1);
  --top:64px;
}
*{box-sizing:border-box}
[hidden]{display:none!important}
html,body{margin:0;height:100%}
body{background:var(--ink);color:var(--paper);font:400 16px/1.5 var(--body);-webkit-font-smoothing:antialiased;overflow:hidden}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;padding:0}
input{font:inherit;color:inherit}
h1,h2,h3{margin:0;font-family:var(--display);font-weight:700;letter-spacing:-.02em;line-height:1.02}
.eyebrow{margin:0 0 10px;font:700 11px/1 var(--body);letter-spacing:.22em;text-transform:uppercase;color:var(--sky)}
.eyebrow--sm{font-size:10px;margin-bottom:10px;color:var(--dim)}
.eyebrow--sm b{color:var(--sky)}
.h1{font-size:clamp(38px,5.2vw,74px);letter-spacing:-.03em}
.h2{font-size:clamp(30px,3.6vw,52px)}
.lede{margin:14px 0 0;max-width:54ch;font-size:clamp(15px,1.15vw,18px);color:var(--mute)}
:focus-visible{outline:2px solid var(--sky);outline-offset:3px}
.btn{display:inline-flex;align-items:center;gap:8px;padding:12px 18px;border-radius:999px;font:600 14px/1 var(--body);transition:transform .35s var(--ease),background .25s,border-color .25s}
.btn--blue{background:var(--blue);color:#fff;box-shadow:0 10px 30px -12px rgba(47,93,255,.8)}
.btn--blue:hover{background:var(--blue2);transform:translateY(-1px)}
.btn--ghost{border:1px solid var(--line2);color:var(--paper)}
.btn--ghost:hover{border-color:var(--sky)}
.btn--sm{padding:9px 14px;font-size:13px}

/* ---------- header: brand, business type, pager ---------- */
.top{position:fixed;inset:0 0 auto 0;height:var(--top);z-index:46;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 clamp(16px,2.5vw,36px);pointer-events:none}
.top>*{pointer-events:auto}
.top::before{content:"";position:absolute;inset:0 0 -28px 0;background:linear-gradient(var(--ink) 55%,transparent);opacity:0;transition:opacity .4s;z-index:-1;pointer-events:none}
body:not([data-act="platform"]) .top::before,body.setup-on .top::before{opacity:1}
.brand{display:block;font:700 22px/1 var(--display);letter-spacing:.02em;color:#fff;text-decoration:none}
.brand img{height:22px;display:block}
.pager{display:flex;align-items:center;gap:8px}
.pager__t{display:flex;flex-direction:column;align-items:flex-end;gap:3px;margin-right:8px;line-height:1.1}
.pager__n{font:600 11px/1 var(--body);letter-spacing:.14em;color:var(--dim)}
.pager__name{font:600 14px/1.2 var(--display);letter-spacing:-.01em}
.pager__b{width:44px;height:44px;border-radius:50%;display:grid;place-items:center;background:var(--glass);border:1px solid var(--line);backdrop-filter:blur(14px) saturate(160%);-webkit-backdrop-filter:blur(14px) saturate(160%);transition:background .25s,transform .35s var(--ease),opacity .25s}
.pager__b svg{width:20px;height:20px}
.pager__b:hover{background:rgba(47,93,255,.4)}
.pager__b:active{transform:scale(.94)}
.pager__b:disabled{opacity:.3;cursor:default}

/* ---------- acts: one on screen at a time ---------- */
.deck{position:relative;height:100%}
.act{position:absolute;inset:0;opacity:0;visibility:hidden;transform:scale(.985);transition:opacity .6s var(--ease),transform .6s var(--ease),visibility 0s linear .6s}
.act.is-on{opacity:1;visibility:visible;transform:none;transition-delay:0s,0s,0s}
.act--wheel,.act--plan{overflow:auto;padding:calc(var(--top) + 8px) clamp(16px,3vw,48px) 40px}
.act--plan{padding-bottom:16px}

/* ---------- act one: the room ---------- */
.act--scene{background:var(--ink) url(/img/hero3d-poster-dark.webp) center/cover no-repeat}
.scene{position:absolute;inset:0;width:100%;height:100%;border:0;display:block;background:transparent}
/* width:fit-content matters — the room reserves this element's BOX so no product label hides
   under it, and a full-width block reserved a third of the stage the text never used */
.scene__cap{position:absolute;left:clamp(16px,3vw,48px);top:calc(var(--top) + clamp(8px,2.5vh,28px));width:fit-content;max-width:min(520px,56vw);z-index:2;pointer-events:none;transition:opacity .4s,transform .5s var(--ease)}
@media(max-width:1560px){.scene__cap{max-width:min(430px,42vw)}}
/* The caption scales with WIDTH, the room is bounded by HEIGHT — on a 1440x900 laptop the two
   fought and the caption's reserved box ate 45% of the stage. Bring it down on short viewports. */
@media(max-height:940px){
  .scene__cap{max-width:min(390px,38vw)}
  /* 33px keeps "One POS. One guest." on the one line the <br> intends — 36 broke it to three */
  .scene__cap .h1{font-size:clamp(25px,2.3vw,33px)}
  .scene__cap .lede{margin-top:8px;font-size:14px}
  .scene__cap .ease{font-size:12.5px}
}
@media(max-height:820px){
  .scene__cap{max-width:min(345px,34vw)}
  .scene__cap .h1{font-size:clamp(23px,2vw,29px)}
  .scene__cap .lede{font-size:13.5px}
}
body.card-open .scene__cap{opacity:0;transform:translateY(-10px)}
/* sits at the foot of the room, level with the GROW rail it drives — out of the caption, whose
   box the scene reserves, so it can't push the room further away */
.scene__grow{position:absolute;left:clamp(16px,3vw,48px);bottom:96px;z-index:2;
  transition:opacity .4s,transform .5s var(--ease)}
body.card-open .scene__grow{opacity:0;transform:translateY(-10px);pointer-events:none}
@media(max-height:820px){.scene__grow{bottom:84px}}
/* on a phone the rail wraps to two rows and the room is centred — the button centres with it.
   margin-left, not translateX, so the card-open transform stays free to move it vertically. */
@media(max-width:900px){.scene__grow{bottom:196px;left:50%;margin-left:-84px}}
.scene__cap .h1{font-size:clamp(28px,3.2vw,46px)}
.scene__cap .lede{margin-top:10px;max-width:44ch;font-size:clamp(14px,1.05vw,16px)}
.tag{margin:14px 0 0;font:600 15px/1 var(--display);color:var(--sky)}
.ease{margin:12px 0 0;max-width:46ch;font-size:13.5px;line-height:1.5;color:var(--dim);border-left:2px solid var(--line2);padding-left:11px}
.scene__hint{position:absolute;right:clamp(16px,3vw,48px);bottom:22px;margin:0;font:500 11px/1 var(--body);letter-spacing:.06em;color:var(--dim);z-index:2;pointer-events:none;transition:opacity .4s}
body.card-open .scene__hint{opacity:0}

/* ---------- act two: the flywheel ---------- */
.wheel-wrap{max-width:1360px;margin:0 auto;min-height:100%;display:flex;flex-direction:column}
.wheel-grid{flex:1;display:grid;grid-template-columns:minmax(0,1fr) minmax(500px,640px);gap:clamp(18px,2.4vw,34px);align-items:stretch;padding-top:4px}
.wheel{position:relative;width:100%;max-width:720px;margin:0 auto;align-self:center;--heat:0}
.wheel svg{width:100%;height:auto;display:block;overflow:visible}
.ring-track{fill:none;stroke:var(--line);stroke-width:1}
.ring-glow{fill:none;stroke:var(--blue);stroke-width:14;opacity:calc(var(--heat)*.5);transition:opacity .8s}
.flow path{fill:none;stroke:var(--sky);stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;opacity:calc(.28 + var(--heat)*.55);transition:opacity .8s}
.arc{fill:none;stroke:var(--blue);stroke-width:5;stroke-linecap:round;opacity:0;transition:stroke-dashoffset .9s var(--ease),opacity .3s}
.arc.is-lit{opacity:1}
.hub-glow{fill:var(--blue);opacity:calc(.08 + var(--heat)*.28);transition:opacity .8s}
.hub{fill:#070a19;stroke:var(--line2);stroke-width:1.5}
.art>g{transition:opacity .5s var(--ease),transform .6s var(--ease);transform-origin:100px 100px;transform-box:fill-box}
.art .a-truck,.art .a-sitdown,.art .a-court,.art .a-arena{opacity:0;transform:translateY(6px)}
body[data-mode="truck"] .art .a-truck,
body[data-mode="sitdown"] .art .a-sitdown,
body[data-mode="court"] .art .a-court,
body[data-mode="arena"] .art .a-arena{opacity:1;transform:none}
body:not([data-mode="qsr"]) .art .a-qsr{opacity:0;transform:translateY(-6px)}
.art .st{stroke:var(--sky);stroke-opacity:.75;stroke-width:2;fill:#0e1330}
.art .dk{fill:#0b1a4d}
.art .bl{fill:var(--blue)}
.art .ln{stroke:var(--line2);stroke-width:1.5;fill:none}
.art .lamp{fill:var(--amber)}
.art .scr{fill:var(--blue);filter:url(#fGlow)}
.pill rect{fill:rgba(47,93,255,.14);stroke:rgba(157,177,255,.35)}
.pill__v{font:600 19px var(--display);fill:var(--paper)}
.pill__l{font:600 9.5px var(--body);letter-spacing:.18em;text-transform:uppercase;fill:var(--dim)}
.node{cursor:pointer;outline:none}
.node__halo{fill:var(--blue);opacity:0;transition:opacity .4s}
.node.is-lit .node__halo{opacity:.22}
.node:hover .node__halo,.node:focus-visible .node__halo{opacity:.14}
.node.is-lit:hover .node__halo{opacity:.3}
.node:focus-visible .node__bg{stroke:#fff}
.node__bg{fill:#0b1024;stroke:var(--line2);stroke-width:2;transition:fill .35s,stroke .35s}
.node.is-gap .node__bg{stroke:var(--amber);stroke-dasharray:5 4}
.node.is-gap.is-lit .node__bg{stroke:var(--sky);stroke-dasharray:none}
.node.is-lit .node__bg{fill:var(--blue);stroke:var(--sky)}
.node__ic path,.node__ic circle,.node__ic rect{fill:none;stroke:var(--sky);stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round;transition:stroke .35s}
.node.is-lit .node__ic path,.node.is-lit .node__ic circle,.node.is-lit .node__ic rect{stroke:#fff}
.node__n{font:700 10.5px var(--body);letter-spacing:.2em;fill:var(--dim)}
.node__l{font:600 17px var(--display);letter-spacing:-.01em;fill:var(--mute);transition:fill .35s}
.node__ls{display:none;font:600 30px var(--display);letter-spacing:-.01em;fill:var(--mute);transition:fill .35s}
.node.is-lit .node__ls{fill:var(--paper)}
.node.is-lit .node__l{fill:var(--paper)}
.speed{display:flex;align-items:center;justify-content:center;gap:6px;margin-top:4px;font:600 10.5px/1 var(--body);letter-spacing:.18em;text-transform:uppercase;color:var(--dim)}
.speed span{margin-right:8px}
.speed i{width:26px;height:4px;border-radius:2px;background:var(--line2);transition:background .4s,box-shadow .4s}
.speed i.is-on{background:var(--blue);box-shadow:0 0 12px rgba(47,93,255,.8)}
.stage-panel{display:flex;flex-direction:column;background:var(--glass);border:1px solid var(--line);border-radius:22px;padding:clamp(20px,2.2vw,30px);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}
.stage-panel.is-idle{align-self:start}
.sp__h{font-size:clamp(24px,2.3vw,32px);margin:2px 0 0}
.sp__body{margin:0;color:var(--mute);font-size:15.5px;line-height:1.6}
.stats{flex:1;min-height:0;display:grid;grid-template-columns:1fr 1fr;grid-auto-rows:1fr;align-content:start;gap:10px;margin-top:18px}
.stats--2{grid-template-columns:1fr}
.stat{max-height:320px}
.stats--4 .stat{max-height:272px}  /* four up, the screen inside is what sets a useful card height */
/* the picture fills the card and the number sits on top of it, held legible by a gradient scrim */
.stat{position:relative;display:block;border-radius:16px;overflow:hidden;min-height:132px;
  background:#080d1c;border:1px solid var(--line);
  animation:rack .95s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--i,0)*60ms)}
.stat__img{position:absolute;inset:0;display:block;overflow:hidden}
.stat__shot{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;
  filter:brightness(.68) contrast(1.04) saturate(.96);
  transition:transform .9s var(--ease),filter .6s var(--ease)}
.stat:hover .stat__shot{transform:scale(1.04);filter:brightness(.82) contrast(1.04) saturate(1)}
.stat__img::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,rgba(4,6,14,.96) 0%,rgba(4,6,14,.92) 34%,rgba(4,6,14,.66) 66%,rgba(4,6,14,.34) 100%)}
/* a phone screen can't be cropped to a wide band and stay readable, so the card is still filled edge to
   edge — by a blurred copy of the shot — and the screen itself stands sharp on top of it, whole */
.stat--tall .stat__img{display:flex;align-items:center;justify-content:flex-end;padding:10px 12px}
.stat__bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center top;
  transform:scale(1.3);filter:blur(30px) brightness(.3) saturate(1.2)}
.stat--tall .stat__shot{position:relative;z-index:2;inset:auto;width:auto;height:auto;
  max-width:54%;max-height:100%;object-fit:contain;
  border-radius:10px;border:1px solid rgba(157,177,255,.22);box-shadow:0 16px 40px rgba(0,0,0,.62);
  filter:brightness(.97) saturate(1)}
.stat--tall:hover .stat__shot{transform:translateY(-4px) scale(1.03);filter:brightness(1.04) saturate(1.04)}
.stat--tall .stat__img::after{z-index:1;
  background:linear-gradient(100deg,rgba(4,6,14,.9) 0%,rgba(4,6,14,.74) 42%,rgba(4,6,14,.2) 78%,rgba(4,6,14,0) 100%)}
.stat__t{position:relative;display:block;z-index:3;padding:20px 22px;min-width:0}
.stat--tall .stat__t{max-width:calc(48% - 26px)}
.stat--tall .stat__l{max-width:100%}  /* the 19ch cap must not out-reach the column the screen leaves */
/* four to a panel leaves each card half as wide — the number has to come down with it */
.stats--4 .stat__n b{font-size:clamp(30px,3vw,42px)}
.stats--4 .stat__n b.is-long{font-size:clamp(17px,1.6vw,20px)}
.stats--4 .stat__t{padding:17px 18px}
.stats--4 .stat__l{font-size:12.5px}
.stat__n{display:flex;flex-wrap:wrap;align-items:center;gap:6px 13px}
.stat__n b{font:700 clamp(38px,4vw,52px)/1 var(--display);letter-spacing:-.035em;color:#fff;
  font-variant-numeric:tabular-nums;text-shadow:0 2px 24px rgba(4,6,14,.9)}
.stat__n b.is-long{font-size:clamp(26px,2.8vw,36px);letter-spacing:-.025em}
.stat__n b{white-space:nowrap}  /* a range like +15–30% must never break across the en dash */
.stat__l{display:block;margin-top:9px;font-size:13.5px;line-height:1.45;color:var(--paper);max-width:19ch;
  text-shadow:0 1px 14px rgba(4,6,14,.95)}
.stat--loop .stat__n b{color:var(--sky)}
/* growth draws itself: a rising line that sketches in with the card */
.rise{flex:none;display:block;width:56px;height:28px}
.rise svg{width:100%;height:100%;overflow:visible}
.rise polyline{fill:none;stroke:var(--ok);stroke-width:3;stroke-linecap:round;stroke-linejoin:round;
  filter:drop-shadow(0 0 7px rgba(61,220,151,.55));
  stroke-dasharray:var(--len,90);stroke-dashoffset:var(--len,90);
  animation:draw .95s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--i,0)*60ms + 240ms)}
.rise polyline.head{--len:26;animation-delay:calc(var(--i,0)*60ms + 620ms)}
@keyframes draw{to{stroke-dashoffset:0}}
.stats__src{margin:11px 0 0;font:500 11.5px/1 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--dim)}
.stage-panel .chips{margin-top:14px;margin-bottom:0}
.stage-panel .assume{margin-top:18px}
.sp__body b{color:var(--paper)}
.sp__gap{margin:14px 0 0;padding:10px 12px;border-radius:12px;background:rgba(255,181,71,.1);border:1px solid rgba(255,181,71,.3);color:var(--paper);font-size:13.5px;font-weight:500}
.sp__note{margin:14px 0 0;padding:10px 12px;border-radius:12px;background:rgba(255,181,71,.08);border:1px solid rgba(255,181,71,.25);color:var(--mute);font-size:13.5px}
.sp__row{display:flex;gap:10px;align-items:center;margin-top:16px;flex-wrap:wrap}
.sp__hint{font-size:12.5px;color:var(--dim)}
.chips{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 14px}
.chip{display:inline-block;padding:6px 10px;border-radius:999px;font:600 11.5px/1 var(--body);letter-spacing:.06em;text-transform:uppercase;color:var(--sky);background:rgba(47,93,255,.14);border:1px solid rgba(157,177,255,.25)}
.proof{display:flex;gap:16px;align-items:center;margin-top:18px;padding:16px 18px;border-radius:16px;background:rgba(5,7,15,.5);border:1px solid var(--line)}
.proof__n{font:700 clamp(30px,3vw,42px)/1 var(--display);letter-spacing:-.03em;color:#fff;white-space:nowrap}
.proof__t{display:flex;flex-direction:column;gap:2px;font-size:13.5px;color:var(--mute)}
.proof__t b{color:var(--paper);font-weight:600}
.proof__t span{font-size:12px;color:var(--dim)}
.assume{display:flex;align-items:center;gap:8px;margin-top:16px;font-size:13px;color:var(--dim)}
.assume input{width:60px;padding:6px 8px;border-radius:8px;background:rgba(5,7,15,.6);border:1px solid var(--line2);text-align:right;font-variant-numeric:tabular-nums}

/* ---------- the stage panel's own anatomy: what the stage IS, above what it earns ---------- */
.sp__sub{margin:9px 0 0;font:600 13px/1.4 var(--body);letter-spacing:.01em;color:var(--sky)}
.how{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin-top:16px}
.how__c{display:flex;align-items:center;gap:9px;padding:12px 13px;border-radius:13px;
  background:rgba(5,7,15,.42);border:1px solid var(--line);
  animation:rack .8s var(--ease) both;animation-delay:calc(var(--i,0)*70ms)}
.how__c b{font:600 14px/1.25 var(--display);letter-spacing:-.01em;color:var(--paper)}
/* the agent's own card: halo + listening beam from the design system. ai.accent (#6B8CFF in
   the dark theme) is the agent's colour and nothing else's — the card tint is the same hue at
   low alpha so the beam reads as belonging to it, not as another brand accent. */
.how__c--ai{position:relative;border-color:rgba(107,140,255,.42);
  background:linear-gradient(150deg,rgba(107,140,255,.15),rgba(5,7,15,.5))}
.how__c--ai>.neon{position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:0}
.how__c--ai>b{position:relative;z-index:1}
.how__c--ai infi-ai-halo{position:relative;z-index:1;flex:none;width:22px;height:22px;color:var(--paper)}
/* the same agent, said in words, on the surfaces that actually run a model (drawer + plan expand) */
.aix{position:relative;display:flex;align-items:flex-start;gap:12px;
  padding:14px 16px!important;border-top:0!important;border-radius:16px;
  border:1px solid rgba(107,140,255,.42);
  background:linear-gradient(150deg,rgba(107,140,255,.15),rgba(5,7,15,.5))}
.aix>.neon{position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:0}
.aix infi-ai-halo{position:relative;z-index:1;flex:none;width:26px;height:26px;color:var(--paper)}
.aix__t{position:relative;z-index:1;display:flex;flex-direction:column;gap:3px}
.aix__t b{font:700 10.5px/1 var(--body);letter-spacing:.2em;text-transform:uppercase;color:#9db1ff}
.aix__t span{font-size:13.5px;line-height:1.5;color:var(--paper)}
/* the setup tiles carry the mark only — that overlay lives in the DOM all meeting, so no beam */
.tile__ic--ai{background:rgba(107,140,255,.16);border-color:rgba(107,140,255,.4)}
.tile__ic--ai infi-ai-halo{width:22px;height:22px;color:var(--paper)}
.how__ic{display:block;width:21px;height:21px}
.how .ic,.q .ic{display:block;width:21px;height:21px}
.how .ic path,.how .ic circle,.how .ic rect{fill:none;stroke:var(--sky);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
/* the sentences a hungry person 500m away actually types */
.qrow{display:flex;flex-wrap:wrap;gap:7px;margin-top:13px}
.q{display:inline-flex;align-items:center;gap:7px;padding:7px 13px 7px 11px;border-radius:999px;
  background:rgba(5,7,15,.55);border:1px solid var(--line2);font:500 13px/1 var(--body);color:var(--paper);
  animation:rack .7s var(--ease) both;animation-delay:calc(var(--i,0)*60ms + 140ms)}
.q .ic{width:14px;height:14px;flex:none}
.q .ic path,.q .ic circle{fill:none;stroke:var(--dim);stroke-width:2;stroke-linecap:round}
.q--ai{background:rgba(47,93,255,.15);border-color:rgba(157,177,255,.42);color:#fff}
.q--ai .ic path{fill:var(--sky);stroke:none}
.q--ai i{font:600 9.5px/1 var(--body);font-style:normal;letter-spacing:.16em;text-transform:uppercase;color:var(--sky)}
/* stage 02: the two words that separate a digital order from a spoken one */
.why{margin-top:14px;padding:12px 14px;border-radius:14px;background:rgba(47,93,255,.1);border:1px solid rgba(47,93,255,.32)}
.why__p{margin:0;font-size:12.8px;line-height:1.5;color:var(--mute)}
.why__p+.why__p{margin-top:8px}
.why__p b{color:#fff;font-weight:700}
.sp__fine{margin:12px 0 0;font-size:11.5px;line-height:1.45;color:var(--dim)}

/* ---------- THE FINALE: the wheel gets out of the way and the store fills up ----------
   Every animation here hangs off .is-on / .is-w2 / .is-w3, so leaving the page (an act is only
   visibility:hidden) removes them rather than leaving keyframes burning behind a hidden layer. */
@media(min-width:1101px){
  .act--wheel.is-fin .wheel-grid{grid-template-columns:minmax(0,1fr) minmax(380px,440px)}
  .act--wheel.is-fin .wheel{max-width:1000px}
}
.wheel #wheelSvg,.wheel .speed{transition:opacity .7s var(--ease),transform 1s var(--ease)}
.act--wheel.is-fin #wheelSvg{opacity:0;transform:scale(.93);pointer-events:none}
.act--wheel.is-fin .speed{opacity:0}
.fin{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;--lit:0;
  opacity:0;visibility:hidden;transform:scale(.94);
  transition:opacity .9s var(--ease),transform 1.2s var(--ease),visibility 0s linear .9s}
.fin.is-on{opacity:1;visibility:visible;transform:none;transition-delay:.18s,.18s,0s}
.fin__svg{width:100%;height:auto;max-height:100%;display:block;overflow:visible}
.fin__halo{fill:var(--blue);opacity:calc(.1 + var(--lit)*.26);transition:opacity .5s}
.fin__pool{fill:var(--amber);opacity:calc(.05 + var(--lit)*.09);transition:opacity .5s}
.fin__ground{stroke:var(--line2);stroke-width:1.5;fill:none}
.fin .art .scr,.fin .art .lamp{opacity:calc(.45 + var(--lit)*.55)}
/* the guests */
.pp{opacity:0}
.pp__h{fill:var(--sky);opacity:.92}
.pp__s{fill:none;stroke:var(--sky);stroke-width:3.2;stroke-linecap:round;opacity:.82}
.pp__g{fill:var(--blue);opacity:.8}
.fin .pp[data-w="2"],.fin .pp[data-w="3"],.fin .bill[data-w="2"],.fin .bill[data-w="3"]{display:none}
.fin.is-w2 .pp[data-w="2"],.fin.is-w3 .pp[data-w="3"],
.fin.is-w2 .bill[data-w="2"],.fin.is-w3 .bill[data-w="3"]{display:block}
.fin.is-on .pp{animation:walkIn var(--dur,4.4s) linear var(--d,0s) infinite both}
.fin.is-on .pp__b{animation:bob .54s ease-in-out infinite}
@keyframes walkIn{
  0%{transform:translate(var(--x0),var(--y)) scale(var(--s));opacity:0}
  9%{opacity:1} 90%{opacity:1}
  100%{transform:translate(var(--x1),var(--y)) scale(var(--s));opacity:0}
}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-2.5px)}}
/* the money */
.bill{opacity:0}
.bill rect{fill:#0b1730;stroke:var(--ok);stroke-width:1.6}
.bill circle{fill:none;stroke:var(--ok);stroke-width:1.1;opacity:.6}
.bill text{font:700 11px/1 var(--display);fill:var(--ok)}
.fin.is-on .bill{animation:billUp var(--dur,3.8s) ease-out var(--d,0s) infinite both}
@keyframes billUp{
  0%{transform:translate(var(--x),10px) rotate(0) scale(.5);opacity:0}
  18%{opacity:.95} 82%{opacity:.95}
  100%{transform:translate(calc(var(--x)*1.14),-214px) rotate(var(--r)) scale(1.04);opacity:0}
}
.cash{opacity:0;transform:translateY(9px);transition:opacity .5s var(--ease),transform .6s var(--ease)}
.cash.is-on{opacity:1;transform:none}
.cash rect{fill:#0b1730;stroke:var(--ok);stroke-width:1.5}
.fin__stackL{font:700 9px var(--body);letter-spacing:.2em;fill:var(--dim)}
/* the readout, in the panel: their own two numbers, before and after */
.fh{margin-top:20px;display:flex;flex-direction:column;gap:9px}
.fh__r{display:flex;align-items:baseline;justify-content:space-between;gap:14px;padding:12px 15px;border-radius:14px;
  background:rgba(5,7,15,.45);border:1px solid var(--line);
  animation:rack .9s var(--ease) both;animation-delay:calc(var(--i,0)*90ms + 200ms)}
.fh__l{font:600 12.5px/1 var(--body);color:var(--mute)}
.fh__n{display:flex;align-items:baseline;gap:9px}
.fh__b{font:500 14px/1 var(--body);font-style:normal;color:var(--dim);font-variant-numeric:tabular-nums}
.fh__a{width:19px;height:10px;flex:none;align-self:center}
.fh__a path{fill:none;stroke:var(--sky);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.fh__v{font:700 clamp(21px,2vw,27px)/1 var(--display);letter-spacing:-.025em;color:#fff;font-variant-numeric:tabular-nums}
.fh__d{margin:3px 0 0;padding:13px 15px;border-radius:14px;text-align:center;
  background:linear-gradient(150deg,rgba(61,220,151,.18),rgba(61,220,151,.05));border:1px solid rgba(61,220,151,.4);
  font:600 13.5px/1.5 var(--body);color:var(--paper);animation:rack 1s var(--ease) both;animation-delay:.62s}
.fh__d b{font:700 19px/1 var(--display);letter-spacing:-.02em;color:var(--ok)}
@media(max-width:1100px){.fin{position:relative;inset:auto;width:100%}
  .act--wheel.is-fin #wheelSvg{display:none}}
@media(prefers-reduced-motion:reduce){
  .fin,.fin.is-on .pp,.fin.is-on .pp__b,.fin.is-on .bill,.how__c,.q,.fh__r,.fh__d{animation:none!important;transition:none!important}
  .fin.is-on .pp{opacity:1;transform:translate(calc(var(--x0)*.34),var(--y)) scale(var(--s))}
  .fin.is-on .bill{opacity:.85;transform:translate(var(--x),-120px) rotate(var(--r)) scale(1)}
}

/* A laptop is 900 tall, and the panel now carries three surfaces, the searches and the proof.
   Everything the stage panel gained shrinks a notch there so the buttons stay above the fold. */
@media(max-height:940px){
  .sp__sub{margin-top:7px;font-size:12.5px}
  .how{margin-top:12px;gap:7px}
  .how__c{padding:10px 11px;gap:8px}
  .how__c b{font-size:13.2px}
  .how__ic,.how .ic{width:18px;height:18px}
  .why{margin-top:11px;padding:10px 12px}
  .why__p{font-size:12.2px;line-height:1.45}
  .why__p+.why__p{margin-top:6px}
  .qrow{margin-top:10px;gap:6px}
  .q{padding:6px 11px 6px 9px;font-size:12.2px}
  /* the proof cards are the one block that can give height back: they crop, the copy can't */
  .stats{margin-top:12px;max-height:40vh}
  .stat{min-height:108px}
  .stats--4 .stat{max-height:212px}
  .stats--4 .stat__t{padding:14px 15px}
  .sp__fine{margin-top:10px;font-size:11px}
  .fh{margin-top:14px;gap:7px}
  .fh__r{padding:10px 13px}
  .fh__v{font-size:clamp(19px,1.8vw,23px)}
  .fh__d{padding:11px 13px;font-size:12.8px}
  .fh__d b{font-size:17px}
}

/* ---------- the branded-app wall, in the loyalty drawer ---------- */
/* both halves get ONE height: the drawer is 620 wide and the plan's expand is 900, and without
   a cap the icon wall grew until the before/after argument fell below the fold */
.apw__duo{display:grid;grid-template-columns:1.4fr 1fr;gap:10px;align-items:stretch;--h:clamp(188px,26vh,252px)}
.apw figure{margin:0;display:flex;flex-direction:column;gap:9px}
.apw figcaption{font-size:11.5px;line-height:1.4;color:var(--dim)}
.apw__g{height:var(--h);display:flex;flex-wrap:wrap;align-content:center;justify-content:center;gap:9px;
  padding:14px;border-radius:16px;overflow:hidden;
  background:radial-gradient(120% 120% at 30% 0,rgba(47,93,255,.18),rgba(5,7,15,.6));border:1px solid var(--line)}
.apw__g img{display:block;width:clamp(44px,17%,68px);height:auto;aspect-ratio:1;object-fit:cover;border-radius:23%;
  border:1px solid rgba(255,255,255,.1);box-shadow:0 6px 14px -8px rgba(0,0,0,.9);
  animation:rack .8s var(--ease) both;animation-delay:calc(var(--i,0)*45ms)}
/* the screenshot is a tall phone screen: show the top of it, cropped to the wall's height */
.apw__ph>span{height:var(--h);display:block;overflow:hidden;border-radius:16px;border:1px solid var(--line2);background:#080d1c}
.apw__ph img{display:block;width:100%;height:100%;object-fit:cover;object-position:center top}
.apw__note{margin:14px 0 0;font-size:13px;line-height:1.55;color:var(--mute)}
@media(max-width:560px){.apw__duo{grid-template-columns:1fr}}

/* ---------- controls shared by the setup page and the plan ---------- */
.seg{display:flex;align-items:center;gap:3px;padding:3px;border-radius:999px;background:rgba(5,7,15,.5);border:1px solid var(--line)}
.seg button{padding:8px 13px;border-radius:999px;font:600 12.5px/1 var(--body);color:var(--mute);white-space:nowrap;transition:background .25s,color .25s}
.seg button:hover{color:var(--paper)}
.seg button.is-on{background:var(--blue);color:#fff}
.tiles{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;align-items:start}
.tile{display:flex;flex-direction:column;gap:10px;padding:16px;border-radius:16px;background:rgba(5,7,15,.42);border:1px solid var(--line);transition:border-color .3s,box-shadow .3s}
.tile.is-add{border-color:rgba(47,93,255,.7);box-shadow:0 0 0 1px rgba(47,93,255,.28)}
.tile.is-switch{border-color:rgba(157,177,255,.55)}
.tile.is-keep{border-color:rgba(61,220,151,.5)}
.tile__top{display:flex;gap:12px;align-items:flex-start}
.tile__ic{flex:none;width:38px;height:38px;border-radius:11px;display:grid;place-items:center;background:rgba(47,93,255,.14);border:1px solid rgba(157,177,255,.22)}
.tile__ic svg{width:22px;height:22px;display:block}
.tile__ic path,.tile__ic circle,.tile__ic rect{fill:none;stroke:var(--sky);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.tile__name{font-size:17px;letter-spacing:-.01em}
.tile__infi{margin:3px 0 0;font:700 10px/1 var(--body);letter-spacing:.18em;text-transform:uppercase;color:var(--sky)}
.tile__status{margin:0;font-size:13px;color:var(--dim);min-height:20px}
.tile__status b{color:var(--paper);font-weight:600}
.tile__ch{display:flex;gap:6px}
.pill-b{flex:1;padding:9px 10px;border-radius:999px;border:1px solid var(--line2);font:600 12.5px/1 var(--body);color:var(--mute);transition:background .25s,color .25s,border-color .25s}
.pill-b:hover{border-color:var(--sky);color:var(--paper)}
.pill-b.is-on{background:var(--blue);border-color:var(--blue);color:#fff}
.chips--pick{margin:0}
.chip--b{cursor:pointer;text-transform:none;letter-spacing:0;font-size:12px;font-weight:500;color:var(--mute);background:rgba(5,7,15,.4);transition:background .2s,color .2s,border-color .2s}
.chip--b:hover{border-color:var(--sky);color:var(--paper)}
.chip--b.is-on{background:rgba(47,93,255,.35);border-color:var(--sky);color:#fff}
.tile__go{margin-top:auto;width:100%;padding:10px 0 0;border-top:1px solid var(--line);text-align:left;font:600 13px/1 var(--body);color:var(--sky);transition:color .2s}
.tile__go:hover{color:#fff}
.sum{position:sticky;bottom:0;margin-top:auto;display:flex;flex-wrap:wrap;gap:8px 22px;align-items:center;padding:14px 20px;border-radius:18px;background:rgba(10,14,29,.9);border:1px solid var(--line2);backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);box-shadow:0 -10px 40px -20px rgba(0,0,0,.8)}
.sum__k{font-size:13.5px;color:var(--mute)}
.sum__k b{font:700 20px/1 var(--display);color:var(--paper);margin-right:5px}
.sum__k--big b{color:#fff;font-size:26px}
.sum__pos{font-size:13px;color:var(--dim);flex:1;min-width:220px}
.sum__empty{font-size:14px;color:var(--dim)}

/* ---------- act three: the plan, as cards you can see ----------
   Motion borrowed from the INFI motion library, measured values kept:
   · blur-focus-in  (Tier 1, obys.agency) — cards rack into focus on arrival: blur 16→0,
     scale 1.06→1, 1.1s cubic-bezier(.16,1,.3,1), 60ms stagger
   · flip-shared-element (index.studio) — a card morphs into its detail: 0.65s power2.inOut
     family = cubic-bezier(.45,0,.55,1); body content fades in 0.25s into the flip
   · cursor-label-follow (Cuberto mouse-follower) — lerp 0.14, 0.3s fade, expo-out    */
.plan-wrap{max-width:1300px;margin:0 auto;display:flex;flex-direction:column;gap:16px;min-height:100%}
.plan-head{display:block}
.plan-head .lede{max-width:56ch;margin-top:8px}
.plan-body{display:flex;flex-direction:column;gap:22px;padding-bottom:22px}
.plan-cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(266px,1fr));gap:13px}

.pcard{position:relative;display:flex;flex-direction:column;text-align:left;border-radius:17px;overflow:hidden;
  background:var(--glass);border:1px solid var(--line);
  transition:transform .55s var(--ease),border-color .3s,box-shadow .5s var(--ease)}
.pcard:hover,.pcard:focus-visible{transform:translateY(-5px);
  border-top-color:var(--line2);border-right-color:var(--line2);border-bottom-color:var(--line2);
  box-shadow:0 28px 62px -32px rgba(0,0,0,.9);outline:none}
.pcard:focus-visible{border-top-color:var(--sky);border-right-color:var(--sky);border-bottom-color:var(--sky)}
.pcard--add{border-left:3px solid var(--blue)}
.pcard--switch{border-left:3px solid var(--sky)}
.pcard--keep{border-left:3px solid var(--ok)}
.pcard--off{border-left:3px solid var(--amber)}
/* the group add-on is not one of the five stages — a dashed edge says extra without inventing a colour */
.pcard--group{border-left:3px dashed var(--sky)}
.pcard--group .pcard__chip{background:rgba(157,177,255,.2);border-color:var(--line2);color:var(--paper)}
.pcard__media{position:relative;aspect-ratio:16/10;overflow:hidden;background:#080d1c}
.pcard__media img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top center;
  transition:transform 1s var(--ease),opacity .6s var(--ease)}
.pcard:hover .pcard__media img{transform:scale(1.045)}
.pcard__b{z-index:2}
.pcard:hover .pcard__b,.pcard:focus-visible .pcard__b{opacity:0}
.pcard__media::after{content:"";position:absolute;inset:auto 0 0 0;height:56%;z-index:3;pointer-events:none;
  background:linear-gradient(transparent,rgba(5,7,15,.88))}
.pcard--off .pcard__media img{filter:grayscale(1) brightness(.6)}
.pcard__chip{position:absolute;top:9px;right:9px;z-index:4;padding:5px 10px;border-radius:999px;
  font:700 9.5px/1 var(--body);letter-spacing:.14em;text-transform:uppercase;
  background:rgba(5,7,15,.76);border:1px solid var(--line2);color:var(--paper);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.pcard--add .pcard__chip{background:var(--blue);border-color:var(--blue);color:#fff}
.pcard--switch .pcard__chip{background:var(--sky);border-color:transparent;color:#0a0e1d}
.pcard--keep .pcard__chip{background:rgba(26,143,92,.9);border-color:transparent;color:#fff}
.pcard--off .pcard__chip{background:rgba(255,181,71,.9);border-color:transparent;color:#20160a}
.pcard__swap{position:absolute;left:10px;bottom:9px;z-index:4;padding:5px 10px;border-radius:999px;
  font:600 10.5px/1 var(--body);letter-spacing:.04em;color:var(--paper);
  background:rgba(5,7,15,.72);border:1px solid var(--line2);
  backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);transition:opacity .35s}
.pcard:hover .pcard__swap{opacity:0}
.pcard__body{display:flex;flex-direction:column;gap:3px;padding:13px 15px 15px;flex:1}
.pcard__top{display:flex;gap:10px;align-items:flex-start}
.pcard__top>span:last-child{min-width:0}
.pcard__ic{flex:none;width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
  background:rgba(47,93,255,.14);border:1px solid rgba(157,177,255,.22)}
.pcard__ic svg{width:17px;height:17px;display:block}
.pcard__ic path,.pcard__ic circle,.pcard__ic rect{fill:none;stroke:var(--sky);stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.pcard--off .pcard__ic{background:rgba(255,181,71,.12);border-color:rgba(255,181,71,.28)}
.pcard--off .pcard__ic path,.pcard--off .pcard__ic circle,.pcard--off .pcard__ic rect{stroke:var(--amber)}
.pcard__nm{display:block;font:700 16px/1.25 var(--display);letter-spacing:-.01em;color:var(--paper)}
.pcard__sub{display:block;margin-top:4px;font-size:12.5px;line-height:1.45;color:var(--mute)}
.pcard__sub b{color:var(--paper);font-weight:600}
.pcard__v{margin-top:auto;padding-top:11px;display:flex;align-items:baseline;gap:6px}
.pcard__v b{font:700 26px/1 var(--display);letter-spacing:-.03em;color:#fff;font-variant-numeric:tabular-nums}
.pcard__v span{font-size:11.5px;color:var(--dim)}
.pcard__v--dash b{color:var(--dim);font-size:22px}
/* the go-live time is a phrase, not a figure — it must not wear the big tabular number face */
.pcard__v--time b{font-size:19px;letter-spacing:-.02em;color:var(--paper)}
/* a card with nothing to put in the value slot just ends after its copy — the go-live estimate
   used to live here and the deck no longer quotes one */
.pcard__v--note{margin-top:auto;padding-top:11px}
.pcard__v--note span{font-size:11.5px;color:var(--dim)}

/* cards rack into focus on arrival, left to right */
.act--plan.is-on .pcard{animation:rack 1.1s cubic-bezier(.16,1,.3,1) both;animation-delay:calc(var(--i,0)*60ms)}
@keyframes rack{from{opacity:0;filter:blur(16px);transform:translateY(10px) scale(1.06)}
  to{opacity:1;filter:blur(0);transform:none}}

/* a card morphs into its detail; the rest of the grid defocuses behind it */
/* The panel itself no longer scrolls — its body does. That keeps the close button, which is
   positioned against the panel, pinned in the corner instead of scrolling away with the content
   on a long card. The panel is given an explicit height in openExpand, so the column resolves. */
.expand{position:fixed;z-index:58;overflow:hidden;display:flex;flex-direction:column;
  border-radius:17px;background:var(--ink2);
  border:1px solid var(--line2);box-shadow:0 40px 110px -40px rgba(0,0,0,.9);padding:clamp(20px,2.6vw,34px);
  transform-origin:top left;will-change:transform}
.expand__in{flex:1;min-height:0;overflow:auto;opacity:0;transition:opacity .4s var(--ease) .25s;
  scrollbar-width:thin}
.expand.is-ready .expand__in{opacity:1}
body.expand-on .plan-body,body.expand-on .plan-head,body.expand-on .sum{filter:blur(4px) saturate(.85);opacity:.45;transition:filter .5s var(--ease),opacity .5s var(--ease)}
body.expand-on .act--plan.is-on .pcard{animation:none}
.expand__x{position:absolute;top:14px;right:14px;z-index:6;width:38px;height:38px;border-radius:50%;
  border:1px solid var(--line2);background:rgba(10,14,29,.82);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  font-size:21px;line-height:1;display:grid;place-items:center;color:var(--paper)}
.plan-empty{padding:26px 22px;border-radius:16px;border:1px dashed var(--line2);color:var(--mute);font-size:15px;text-align:center}
.plan-empty button{color:var(--sky);font-weight:600;text-decoration:underline;text-underline-offset:3px}

/* a labelled pill trailing the pointer, fine pointers only */
.clf{position:fixed;left:0;top:0;z-index:70;pointer-events:none;opacity:0;
  padding:7px 15px;border-radius:999px;background:var(--paper);color:var(--ink);
  font:600 12px/1 var(--body);white-space:nowrap;
  transition:opacity .3s cubic-bezier(.16,1,.3,1);will-change:transform}
.clf.is-on{opacity:1}
body.expand-on .clf{opacity:0!important}  /* the pill belongs to the grid, not to the panel over it */
@media(hover:none),(pointer:coarse){.clf{display:none!important}}
/* a short laptop can't hold four tall cards in a column — pair them up rather than cut them off */
@media(max-height:940px){
  .wheel-head .h2{font-size:clamp(26px,2.6vw,36px)}
  .stat{min-height:112px}
  .stat__n b{font-size:clamp(32px,3.2vw,40px)}
  .stat__n b.is-long{font-size:clamp(23px,2.3vw,29px)}
  .stats--4 .stat__n b{font-size:clamp(27px,2.6vw,34px)}
  .stats--4 .stat__n b.is-long{font-size:clamp(17px,1.6vw,20px)}
  .stat__t{padding:17px 19px}
  .stat__l{margin-top:8px;font-size:13px}
  .stats{gap:8px;margin-top:14px}
  .stage-panel{padding:18px 20px}
  /* the plan is one run of up to eight cards now — on a laptop it should still be one slide */
  .plan-head .h2{font-size:clamp(26px,2.6vw,36px)}
  .plan-head .lede{font-size:14px;margin-top:6px}
  .plan-wrap{gap:12px}
  .plan-body{padding-bottom:12px}
  .plan-cards{gap:10px}
  .pcard__media{aspect-ratio:16/9}
  .pcard__body{padding:10px 14px 12px}
}
@media(max-height:800px){
  .stats{gap:8px}
  .stat{min-height:100px}
  .stat__n b{font-size:clamp(26px,2.6vw,32px)}
  .stats--4 .stat__n b{font-size:clamp(23px,2.2vw,28px)}
  .stats--4 .stat__n b.is-long{font-size:clamp(15px,1.45vw,18px)}
  .stat__t,.stats--4 .stat__t{padding:14px 15px}
  .stat__l{font-size:12px;max-width:20ch}
  .rise{width:42px;height:22px}
  .stat__img::after{background:linear-gradient(100deg,rgba(4,6,14,.96) 0%,rgba(4,6,14,.92) 52%,rgba(4,6,14,.5) 100%)}
  /* a 768–800px screen still has to hold all eight cards: narrower tracks make the media
     shorter, which is the only lever big enough to save a whole row of height */
  .plan-cards{grid-template-columns:repeat(auto-fill,minmax(224px,1fr));gap:9px}
  .plan-head .h2{font-size:clamp(22px,2.2vw,30px)}
  .plan-head .lede{font-size:13.5px;margin-top:6px}
  .pcard__body{padding:9px 12px 11px}
  .pcard__nm{font-size:14.5px}
}
@media(prefers-reduced-motion:reduce){.clf{display:none!important}
  .act--plan.is-on .pcard{animation:none}
  .expand{transition:none}}

/* ---------- setup: the page you fill in before the meeting ---------- */
.setup{position:fixed;inset:0;z-index:45;overflow:auto;background:var(--ink);opacity:0;visibility:hidden;
  padding:calc(var(--top) + 16px) clamp(16px,3vw,48px) 108px;transition:opacity .4s var(--ease),visibility 0s linear .4s}
body.setup-on .setup{opacity:1;visibility:visible;transition-delay:0s,0s}
body.setup-on .pager__t,body.setup-on #prev,body.setup-on #next{display:none}
body:not(.setup-on) .start-btn{display:none}
.start-btn{flex:none}
.pager__b--setup svg,.pager__b--script svg{width:19px;height:19px}
.pager__b--script{text-decoration:none}
body.setup-on .pager__b--script{display:none}
body.setup-on .pager__b--setup{background:var(--blue);border-color:var(--blue)}
.setup-wrap{max-width:1000px;margin:0 auto;display:flex;flex-direction:column;gap:16px}
.setup-head{margin-bottom:2px}
.setup-head .lede{max-width:66ch}
.kick{margin:0 0 10px;font:700 11px/1 var(--body);letter-spacing:.22em;text-transform:uppercase;color:var(--sky)}
.card{background:var(--glass);border:1px solid var(--line);border-radius:18px;padding:clamp(18px,2.2vw,26px);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.card__h{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;font-size:20px;margin:0 0 6px}
.card__n{font:600 11px/1 var(--body);letter-spacing:.2em;color:var(--dim);font-variant-numeric:tabular-nums}
.card__hint{font:500 12.5px/1 var(--body);letter-spacing:0;color:var(--sky)}
.hint{margin:0 0 14px;font-size:13.5px;color:var(--dim);max-width:72ch}
.row{display:flex;flex-wrap:wrap;gap:18px 26px;margin-top:12px}
.grp{display:flex;flex-direction:column;gap:7px;min-width:0}
.grp__l{font:700 10.5px/1 var(--body);letter-spacing:.18em;text-transform:uppercase;color:var(--dim)}
.grp__l i{font-style:normal;letter-spacing:.02em;text-transform:none;font-weight:500;color:var(--dim);opacity:.7;margin-left:8px}
.grp--wide{flex:1 1 100%}
.seg--wrap{flex-wrap:wrap}
.fields{display:flex;flex-wrap:wrap;gap:10px;margin-top:12px}
.fld{display:flex;align-items:center;gap:7px;padding:8px 14px;border-radius:12px;background:rgba(5,7,15,.5);border:1px solid var(--line);font:600 12.5px/1 var(--body);color:var(--dim);cursor:text}
.fld i{font-style:normal;color:var(--paper)}
.fld input{background:none;border:0;padding:4px 0;width:92px;font:600 15px/1 var(--body);color:var(--paper);font-variant-numeric:tabular-nums;text-align:right;outline:none}
.fld--wide input{width:220px;text-align:left}
.fld input::-webkit-outer-spin-button,.fld input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.fld input[type=number]{-moz-appearance:textfield;appearance:textfield}
.fld:focus-within{border-color:var(--sky)}
.setup-foot{position:sticky;bottom:-92px;display:flex;flex-wrap:wrap;gap:10px 20px;align-items:center;margin-top:6px;
  padding:14px 20px;border-radius:18px;background:rgba(10,14,29,.92);border:1px solid var(--line2);
  backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);box-shadow:0 -10px 40px -20px rgba(0,0,0,.8)}
.setup-foot__t{flex:1;min-width:220px;font-size:13.5px;color:var(--mute)}
.setup-foot__t b{color:var(--paper)}
.setup-foot__link{flex-basis:100%;font:500 12px/1.5 var(--body);color:var(--dim);word-break:break-all}

/* ---------- comparison drawer ---------- */
/* ---------- the versus crest above every a-vs-b in the deck ----------
   Our side carries the real INFI mark; the other side is a monogram in our own type unless an
   official file exists at /img/brand/<slug>.webp, in which case it takes over by itself. */
.vsh{position:relative;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:10px;
  margin:0 0 14px;padding:15px 16px;border-radius:18px;overflow:hidden;
  background:linear-gradient(90deg,rgba(5,7,15,.62) 18%,rgba(47,93,255,.2));border:1px solid var(--line2)}
.vsh::before{content:"";position:absolute;left:14px;right:14px;top:50%;height:1px;z-index:0;
  background:linear-gradient(90deg,transparent,var(--line2),transparent)}
.vsh__s{position:relative;z-index:1;display:flex;align-items:center;gap:10px;min-width:0}
.vsh__s--r{flex-direction:row-reverse;text-align:right}
.vsh__m{position:relative;flex:none;width:44px;height:44px;border-radius:13px;display:grid;place-items:center;
  background:#0b1024;border:1px solid var(--line2);overflow:hidden}
.vsh__m>i{font:700 15px/1 var(--display);font-style:normal;letter-spacing:.02em;color:var(--mute)}
.vsh__m>img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;padding:7px;
  background:inherit;border-radius:inherit}
.vsh__m--infi{background:rgba(47,93,255,.2);border-color:rgba(157,177,255,.5);
  box-shadow:0 0 0 1px rgba(47,93,255,.28),0 10px 26px -14px rgba(47,93,255,.95)}
.vsh__t{display:flex;min-width:0}
.vsh__t b{font:700 16px/1.15 var(--display);letter-spacing:-.015em;color:var(--mute);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vsh__s.is-ours .vsh__t b{color:#fff}
.vsh__v{position:relative;z-index:1;width:36px;height:36px;border-radius:50%;display:grid;place-items:center;
  background:var(--ink);border:1px solid rgba(157,177,255,.45);box-shadow:0 0 0 5px rgba(5,7,15,.75);
  font:700 10.5px/1 var(--body);letter-spacing:.1em;text-transform:uppercase;color:var(--sky)}
@media(max-width:560px){.vsh{grid-template-columns:1fr auto 1fr;padding:10px}
  .vsh__t b{font-size:12.5px}.vsh__m{width:32px;height:32px}}
/* the register page runs the same crest, but that head sits inside a narrow rail */
.pvs-head{display:block;font-size:13px}
.pvs-head .vsh{margin-bottom:0;background:rgba(5,7,15,.45)}

.ba{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.ba__c{padding:14px 15px;border-radius:12px;border:1px solid var(--line)}
.ba__c--b{background:rgba(5,7,15,.45)}
.ba__c--a{background:rgba(47,93,255,.09);border-color:rgba(47,93,255,.4)}
.ba__c .eyebrow--sm{margin-bottom:9px}
.ba__c--a .eyebrow--sm{color:var(--sky)}
.ba__c--a .eyebrow--sm b{color:#fff}
.ba__from{margin:9px 0 0;font-size:12.5px;color:var(--dim)}
.bul--b li{color:var(--mute)}
.bul--b li::before{background:var(--line2);box-shadow:none}
.bul--warn li::before{background:var(--amber);box-shadow:0 0 9px rgba(255,181,71,.6)}
.see{margin:0 0 9px;font-size:14px;color:var(--mute)}
.shots{display:flex;flex-direction:column;gap:10px}
/* two matched pairs read as two rows of before -> after, not one long column */
.shots--4{display:grid;grid-template-columns:1fr 1fr;gap:10px}
@media(max-width:820px){.shots--4{grid-template-columns:1fr}}
.shot{display:block;position:relative;border-radius:12px;overflow:hidden;border:1px solid var(--line2);
  background:rgba(5,7,15,.5);text-decoration:none;transition:border-color .2s,transform .35s var(--ease)}
.shot:hover,.shot:focus-visible{border-color:var(--sky);transform:translateY(-1px)}
.shot img{display:block;width:100%;height:auto}
.shot__none{display:block;padding:26px 16px;text-align:center;color:var(--mute);font-size:14px}
.shot__t{position:absolute;left:10px;bottom:10px;padding:5px 11px;border-radius:999px;
  background:rgba(5,7,15,.82);border:1px solid var(--line2);color:var(--paper);
  font:600 12px/1 var(--body);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
.posline--cost{background:rgba(255,181,71,.09);border-color:rgba(255,181,71,.28)}
.posline--ease{background:transparent;border:0;border-left:2px solid var(--line2);border-radius:0;padding:2px 0 2px 11px;color:var(--dim);font-size:13px}
.deadnote{margin:0 0 20px;padding:13px 15px;border-radius:12px;background:rgba(255,181,71,.1);border:1px solid rgba(255,181,71,.32);color:var(--paper);font-size:14.5px;line-height:1.55}
/* why a card is on the plan at all — a note, not a warning, so it drops the amber */
.deadnote--why{margin:18px 0 0;background:rgba(157,177,255,.07);border-color:var(--line2);color:var(--mute);font-size:12.5px}
.lede--sm{margin:10px 0 16px;max-width:none;font-size:15px;line-height:1.55}
/* the setup hint that says what a second location unlocks */
.fhint{margin:10px 0 0;font-size:12.5px;line-height:1.5;color:var(--sky);opacity:.85}

.scrim{position:fixed;inset:0;background:rgba(5,7,15,.55);opacity:0;pointer-events:none;transition:opacity .4s;z-index:50}
.scrim.is-on{opacity:1;pointer-events:auto}
.drawer{position:fixed;top:0;right:0;bottom:0;width:min(620px,100vw);z-index:60;overflow:auto;padding:clamp(24px,3vw,40px);background:var(--ink2);border-left:1px solid var(--line2);transform:translateX(102%);transition:transform .6s var(--ease);box-shadow:-30px 0 80px -30px rgba(0,0,0,.8)}
.drawer.is-open{transform:none}
.drawer__x{position:absolute;top:16px;right:16px;width:40px;height:40px;border-radius:50%;border:1px solid var(--line2);font-size:22px;line-height:1;display:grid;place-items:center}
.drawer__h{font-size:clamp(26px,2.4vw,34px);margin:4px 0 12px;padding-right:44px}
.drawer__h .vs{font:500 13px var(--body);color:var(--dim);margin:0 8px;vertical-align:middle;letter-spacing:.14em;text-transform:uppercase}
.drawer__lede{margin:0 0 24px;color:var(--mute);font-size:15.5px;line-height:1.6}
.drawer section{margin:0 0 24px;padding-top:20px;border-top:1px solid var(--line)}
.bul{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:10px}
.bul li{position:relative;padding-left:22px;font-size:15px;line-height:1.5;color:var(--paper)}
.bul li::before{content:"";position:absolute;left:0;top:8px;width:10px;height:10px;border-radius:50%;background:var(--blue);box-shadow:0 0 10px rgba(47,93,255,.8)}
.roi__n{font:700 clamp(34px,3.4vw,46px)/1 var(--display);letter-spacing:-.03em;color:#fff}
.roi__n span{font:500 14px var(--body);color:var(--dim);margin-left:8px;letter-spacing:0}
.roi__n--dash{color:var(--dim)}
.roi__why{margin:8px 0 0;font-size:14px;color:var(--mute);line-height:1.55}
.roi__base{margin:10px 0 0;font-size:12px;color:var(--dim)}
.steps{margin:0;padding:0 0 0 22px;display:flex;flex-direction:column;gap:8px;font-size:14.5px;color:var(--mute);line-height:1.5}
.steps li::marker{color:var(--sky);font-weight:700}
.posline{margin:14px 0 0;padding:12px 14px;border-radius:12px;background:rgba(47,93,255,.1);border:1px solid rgba(157,177,255,.22);font-size:13.5px;line-height:1.55;color:var(--mute)}
.posline b{color:var(--paper)}
.drawer__foot{display:flex;gap:10px;padding-top:6px}

/* The expand panel reuses the drawer's detail markup but never inherited its section rhythm, so
   every step of the card ran flush into the next one. The kiosk card reads as a sequence —
   hardware, then the comparison, then the money — and a sequence needs the rules between it. */
.expand__in section{margin:0 0 22px;padding-top:18px;border-top:1px solid var(--line)}
.expand__in>section:first-of-type{padding-top:8px;border-top:0}

/* ---------- Nutrition & Dietary — the feature of the month, inside the kiosk and online cards.
   The deck's only video. The figure has to cap it: the kiosk clip is 824x1198 portrait and would
   run ~1300px tall in the expand dialog if it were allowed to fill its column. ---------- */
.nd__in{display:grid;gap:clamp(13px,1.8vw,20px);align-items:center}
.nd__in--tall{grid-template-columns:minmax(0,200px) minmax(0,1fr)}
.nd__f{margin:0;border-radius:14px;overflow:hidden;line-height:0;background:#0a0e1d;
  border:1px solid var(--line2);box-shadow:0 22px 48px -28px rgba(0,0,0,.85)}
.nd__f video{display:block;width:100%;height:auto}
.nd__f--light{background:#fff}
.nd__t{margin:0 0 11px;font:600 16.5px/1.3 var(--display);letter-spacing:-.01em;color:var(--paper)}
.nd__c .bul li{font-size:14px}
.nd__note{margin:12px 0 0;padding-left:11px;border-left:2px solid var(--line2);
  font-size:11.5px;line-height:1.5;color:var(--dim)}
@media(max-width:620px){
  .nd__in--tall{grid-template-columns:1fr}
  .nd__in--tall .nd__f{max-width:240px;margin-inline:auto}
}

/* ---------- a published case study, shown rather than told ---------- */
.cs__shots{display:grid;gap:9px}
.cs__shots--2{grid-template-columns:1fr 1fr}
.cs__shots--3{grid-template-columns:1fr 1fr 1fr}
.cs__shots figure{margin:0;position:relative;border-radius:13px;overflow:hidden;border:1px solid var(--line);background:#080d1c}
.cs__shots img{display:block;width:100%;height:clamp(152px,22vh,208px);object-fit:cover;object-position:top center}
/* three-up tiles sit at roughly the source aspect, so a dashboard is not cropped in half */
.cs__shots--3 img{height:clamp(118px,17.5vh,164px)}
.cs__shots--2 img{height:clamp(176px,26vh,242px)}
.cs__shots figcaption{position:absolute;left:0;right:0;bottom:0;padding:26px 11px 9px;
  font-size:11.5px;line-height:1.35;color:var(--mute);background:linear-gradient(transparent,rgba(5,7,15,.92))}
.cs__frame{margin:13px 0 0;font:600 12.5px/1 var(--body);letter-spacing:.02em;color:var(--sky)}
.cs__big{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;margin-top:10px}
.cs__big div{padding:13px 14px;border-radius:13px;border:1px solid rgba(47,93,255,.4);background:rgba(47,93,255,.1)}
.cs__big b{display:block;font:700 clamp(23px,2.4vw,31px)/1 var(--display);letter-spacing:-.03em;color:#fff}
.cs__big span{display:block;margin-top:5px;font-size:11.5px;line-height:1.35;color:var(--mute)}
.cs__rows{display:grid;grid-template-columns:repeat(4,1fr);gap:9px;margin-top:9px}
.cs__rows div{padding:11px 12px;border-radius:12px;border:1px solid var(--line);background:rgba(5,7,15,.5)}
.cs__rows b{display:block;font:600 14.5px/1.2 var(--body);color:var(--paper)}
.cs__rows span{display:block;margin-top:4px;font-size:11px;line-height:1.35;color:var(--dim)}
.cs__foot{display:flex;flex-wrap:wrap;gap:10px;align-items:baseline;justify-content:space-between;margin:11px 0 0}
.cs__foot i{font-style:italic;font-size:12px;color:var(--dim)}
.cs__foot a{font:600 12px/1 var(--body);color:var(--sky);text-decoration:none;border-bottom:1px solid transparent}
.cs__foot a:hover{border-bottom-color:var(--sky)}
@media(max-width:660px){
  .cs__shots--3,.cs__big{grid-template-columns:1fr 1fr}
  .cs__rows{grid-template-columns:1fr 1fr}
}

/* ---------- the kiosk hardware card: the machine, before the argument about the machine ---------- */
/* one plate, one photograph: INFI's own product cutout on a lit ground next to the thing in a real
   room. Both units are portrait, so the plate column stays the narrower one — a tall object in a
   wide box is mostly box. */
.kh__duo{display:grid;grid-template-columns:1.4fr .62fr;gap:9px}
.kh:not(.kh--truck) .kh__duo{grid-template-columns:.62fr 1.4fr}
.kh__stage{margin:0;position:relative;border-radius:14px;overflow:hidden;border:1px solid var(--line);background:#080d1c}
.kh__stage img{display:block;width:100%;height:clamp(224px,34vh,338px);object-fit:cover;object-position:center 46%}
.kh__stage--wet{border-color:rgba(47,93,255,.45)}
.kh__stage--cut{background:radial-gradient(68% 72% at 50% 44%,rgba(79,120,255,.26),rgba(5,7,15,0) 72%),#0b1020}
.kh__stage--cut img{object-fit:contain;padding:10px 10px 28px}
.kh__stage figcaption{position:absolute;left:0;right:0;bottom:0;padding:30px 13px 10px;
  font-size:12px;line-height:1.4;color:var(--mute);background:linear-gradient(transparent,rgba(5,7,15,.92))}
.kh__tags{display:flex;flex-wrap:wrap;gap:7px;margin:13px 0 0}
.kh__tags span{padding:7px 13px;border-radius:999px;border:1px solid var(--line2);
  background:rgba(47,93,255,.11);font:600 12px/1 var(--body);color:var(--paper)}
.kh__note{margin:11px 0 0;font-size:12px;color:var(--dim)}
@media(max-width:660px){
  .kh__duo{grid-template-columns:1fr}
  .kh__stage img{height:clamp(170px,24vh,230px)}
}

/* ---------- responsive + motion ---------- */
@media(max-width:1100px){
  .tiles{grid-template-columns:repeat(2,minmax(0,1fr))}
  .wheel-grid{grid-template-columns:1fr;align-items:start}
  .wheel{max-width:640px}
}
@media(max-width:820px){.ba{grid-template-columns:1fr}}
@media(max-width:640px){
  .tiles{grid-template-columns:1fr}
  .setup-foot{position:static}
  .fld--wide input{width:100%}
  .pager__t{display:none}
  .brand img{height:18px}
  .h1{font-size:34px}
  .scene__cap{max-width:calc(100vw - 32px)}
  .scene__hint{display:none}
  .sum{position:static}
  .node__l{display:none}.node__ls{display:block}
  .node__n{font-size:17px}
  .pill__v{font-size:30px}.pill__l{font-size:14px}
  .speed{margin-top:14px}
}
@media(prefers-reduced-motion:reduce){
  .act,.drawer,.scrim{transition:none}
  .arc{transition:opacity .2s}
}

/* ---------- the group picture: three islands on Square, one network on INFI ----------
   Drawn rather than photographed, so it carries no third-party marks: the card is a shape of
   our own and the stores are nobody's logo. The ✗ / ✓ pair IS the argument — everything else
   on the panel is a footnote to it. */
.gcn{margin:0 0 6px;display:grid;gap:10px}
.gcn__svg{display:block;width:100%;height:auto;padding:8px 6px;border-radius:16px;
  background:rgba(10,14,29,.5);border:1px solid var(--line2)}
.gcn__t{fill:var(--paper);font:600 17px/1 var(--display);letter-spacing:-.01em}
.gcn__l{fill:var(--dim);font:600 11.5px/1 var(--body);letter-spacing:.08em;text-transform:uppercase}
.gcn__cap{fill:var(--mute);font:400 13px/1.35 var(--body)}
.gcn__badge{fill:none;stroke-width:1.5}
.gcn__x{fill:none;stroke:var(--amber);stroke-width:2;stroke-linecap:round}
.gcn__ok{fill:none;stroke:var(--ok);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.gcn__isle{fill:rgba(255,255,255,.015);stroke:var(--line2);stroke-width:1;stroke-dasharray:4 5}
.gcn__shop{fill:none;stroke:var(--dim);stroke-width:1.6;stroke-linejoin:round}
.gcn__div{stroke:var(--line2);stroke-width:1;stroke-dasharray:2 7}
.gcn__card--dead rect:first-child{fill:#1b2033}
.gcn__card--dead .gcn__stripe{fill:#0d1120}
.gcn__card--dead .gcn__ribbon{stroke:#2b3252;stroke-width:2}
.gcn__card--live rect:first-child{fill:url(#gcnG)}
.gcn__card--live .gcn__stripe{fill:rgba(5,7,15,.5)}
.gcn__card--live .gcn__ribbon{stroke:rgba(255,255,255,.85);stroke-width:2.5}
.gcn__mesh{fill:none;stroke:var(--sky);stroke-width:1;opacity:.2;stroke-dasharray:3 6}
.gcn__spoke{stroke:var(--blue);stroke-width:2;opacity:.8}
.gcn__node{fill:var(--ink2);stroke:var(--sky);stroke-width:1.5}
.gcn__halo{fill:rgba(47,93,255,.1)}
/* the hub is INFI Connect; each store keeps its own POS out on the ring */
.gcn__hub{fill:rgba(47,93,255,.22);stroke:var(--blue);stroke-width:1.5}
.gcn__hubm{fill:#fff;font:700 21px/1 var(--display);letter-spacing:.06em}
.gcn__hubt{fill:var(--sky);font:700 9.5px/1 var(--body);letter-spacing:.24em}
.gcn__chip{fill:rgba(10,14,29,.9);stroke:var(--line2);stroke-width:1}
.gcn__chipt{fill:var(--mute);font:600 11px/1 var(--body);letter-spacing:.04em}
.gcn__travel{fill:none;stroke:var(--sky);stroke-width:1.5;opacity:.5;stroke-dasharray:4 6}
.gcn__tickbg{fill:var(--ink)}
.gcn__note{margin:0;font-size:12.5px;line-height:1.5;color:var(--mute)}
.gcn__guard{margin:13px 0 0;padding-left:11px;border-left:2px solid var(--line2);
  font-size:12.5px;line-height:1.5;color:var(--dim)}

/* ---------- the product screen every plan line opens with ----------
   One figure fills the width; two sit side by side on a shared height so a tall phone
   screen and a wide page don't read as a mistake. */
.psh{display:grid;gap:10px;margin:0 0 6px}
.psh--duo{grid-template-columns:1fr 1fr}
.psh--pair{grid-template-columns:1.9fr 1fr}
.psh figure{margin:0;border-radius:14px;overflow:hidden;border:1px solid rgba(157,177,255,.18);
  background:#0a0e1d;box-shadow:0 24px 60px -40px rgba(0,0,0,.9)}
.psh img{display:block;width:100%;height:clamp(190px,26vh,260px);object-fit:cover;object-position:top center}
.psh figure.is-tall{background:#070b16}
.psh figure.is-tall img{object-fit:contain;padding:8px}
/* phone screens are portrait: give them room and contain them, never crop a band out */
.psh--phones figure{background:#070b16;display:flex;align-items:center;justify-content:center}
.psh--phones img{height:clamp(300px,40vh,400px);object-fit:contain;width:auto;max-width:100%}
.psh__cap{grid-column:1/-1;margin:0;font-size:12.5px;line-height:1.5;color:var(--mute)}
@media (max-width:640px){.psh--duo{grid-template-columns:1fr}}

/* ---------- the listing preview, inside the Google drawer ---------------------
   A business-listing preview in INFI's own design language. It follows the
   information architecture every merchant recognises — photos, name, rating,
   category, hours, actions, then the rows a listing carries — because that is
   what makes the before/after legible. It is not a reproduction of any other
   company's interface, and carries no third-party marks. Sized for the 620px
   drawer: one column, no viewport-relative type. */
.lst{display:grid;gap:12px;margin:2px 0 8px}
.lst-toggle,.vsx-toggle{display:inline-flex;gap:4px;padding:4px;justify-self:start;
  border:1px solid rgba(157,177,255,.26);border-radius:999px;background:rgba(10,14,29,.6)}
.lst-t,.vsx-t{border:0;background:0;color:var(--sky);font:600 13px/1 var(--body);letter-spacing:.01em;
  padding:9px 16px;border-radius:999px;cursor:pointer;transition:background .25s,color .25s}
.lst-t.is-on,.vsx-t.is-on{background:var(--blue);color:#fff}
.lst-card{background:var(--glass);border:1px solid rgba(157,177,255,.2);border-radius:18px;overflow:hidden;
  backdrop-filter:blur(14px);box-shadow:0 30px 70px -40px rgba(0,0,0,.9)}
.lst-shots{display:grid;grid-template-columns:2fr 1fr 1fr;gap:3px;height:clamp(130px,26vw,176px);background:rgba(5,7,15,.6)}
.lst-shots--2{grid-template-columns:2fr 1fr}
.lst-shots figure{margin:0;position:relative;overflow:hidden;background:#0a0e1d}
.lst-shots img{width:100%;height:100%;object-fit:cover;display:block;
  transition:opacity .5s var(--ease),filter .5s var(--ease)}
.lst-shots .is-stale img{filter:grayscale(.7) brightness(.55) blur(.4px)}
.lst-shots figcaption{position:absolute;left:8px;bottom:8px;font:600 10px/1 var(--body);letter-spacing:.09em;
  text-transform:uppercase;padding:5px 8px;border-radius:999px;background:rgba(5,7,15,.76);color:var(--sky)}
.lst-main{padding:16px 18px}
.lst-name{margin:0 0 6px;font:700 22px/1.15 var(--head);letter-spacing:-.01em}
.lst-meta{margin:0 0 4px;display:flex;align-items:center;gap:8px;font-size:14px;color:var(--paper)}
.lst-stars{letter-spacing:2px;color:var(--amber)}
.lst-dot{opacity:.45}
.lst-addr,.lst-open{margin:0 0 4px;font-size:14px;opacity:.72}
.lst-open b{color:var(--ok);font-weight:600}
.lst-open.is-unknown b{color:var(--amber)}
.lst-actions{display:flex;flex-wrap:wrap;gap:8px;margin:14px 0 6px}
.lst-act{font:600 12px/1 var(--body);padding:9px 14px;border-radius:999px;
  border:1px solid rgba(157,177,255,.28);color:var(--sky);opacity:.55;transition:opacity .35s,border-color .35s,color .35s}
.lst-act.is-key{border-color:var(--blue);color:#fff;background:rgba(47,93,255,.24);opacity:1}
.lst-act.is-live{opacity:1;border-color:rgba(61,220,151,.5);color:var(--ok)}
.lst-rows{margin:12px 0 0;padding:12px 0 0;border-top:1px solid rgba(157,177,255,.14);display:grid;gap:9px}
.lst-rows div{display:grid;grid-template-columns:104px 1fr;gap:10px;align-items:baseline}
.lst-rows dt{font:600 11px/1.4 var(--body);letter-spacing:.08em;text-transform:uppercase;color:var(--sky);opacity:.72}
.lst-rows dd{margin:0;font-size:14px;line-height:1.45}
.lst-rows dd.is-thin{opacity:.5}
.lst-rows dd.is-rich{color:#fff}
.lst-side__t{margin:6px 0 0;font:600 11px/1 var(--body);letter-spacing:.1em;text-transform:uppercase;color:var(--sky);opacity:.72}
.lst-why{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.lst-why li{display:grid;grid-template-columns:18px 1fr;gap:10px;padding:11px 13px;border-radius:12px;
  background:rgba(10,14,29,.55);border:1px solid rgba(157,177,255,.14);opacity:.4;
  transition:opacity .45s var(--ease),border-color .45s,transform .45s var(--ease);transform:translateY(4px)}
.lst-why li.is-on{opacity:1;border-color:rgba(61,220,151,.34);transform:none}
.lst-why i{font-style:normal;color:var(--ok);font-size:13px;line-height:1.5}
.lst-why b{display:block;font:600 13px/1.4 var(--body)}
.lst-why span{font-size:12.5px;line-height:1.5;opacity:.72}
.lst-why em{display:block;margin-top:4px;font-style:normal;font-size:11px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--sky);opacity:.8}
.lst-proof{display:flex;align-items:baseline;gap:9px;flex-wrap:wrap;padding:13px 15px;border-radius:12px;
  background:rgba(47,93,255,.14);border:1px solid rgba(47,93,255,.3)}
.lst-proof b{font:700 22px/1 var(--head);color:#fff}
.lst-proof span{font-size:13px}
.lst-proof i{font-style:normal;font-size:11px;opacity:.6;width:100%}
.lst-note{margin:0;font-size:11.5px;line-height:1.5;opacity:.45}
.lst-counters{display:flex;gap:8px;flex-wrap:wrap}
.lst-c{border:1px solid rgba(157,177,255,.24);background:rgba(10,14,29,.5);color:var(--sky);
  font:600 12px/1 var(--body);padding:9px 13px;border-radius:999px;cursor:pointer;transition:background .25s,border-color .25s,color .25s}
.lst-c.is-on{background:rgba(47,93,255,.28);border-color:var(--blue);color:#fff}

/* ---------- ACT: open, then grow (conditional — no register yet) --------------
   Two panels and one comparison, carrying the whole argument without a paragraph:
   the register runs the store, INFI grows it, and an all-in-one charges more for
   both halves. Numbered 01 / 02 because the order is the point — how the store
   opens first, how it grows second. */
.act--pos{overflow:auto;background:radial-gradient(1100px 620px at 78% -12%,rgba(47,93,255,.2),transparent 62%),var(--ink)}
.pos-wrap{min-height:100%;display:flex;flex-direction:column;justify-content:center;gap:clamp(14px,2.4vh,30px);
  padding:clamp(72px,9vh,100px) clamp(20px,4vw,64px) clamp(18px,3vh,34px);max-width:1440px;margin:0 auto;width:100%}
.pos-head{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;flex-wrap:wrap}
.pos-head .h2{font-size:clamp(26px,3.1vw,44px)}
.pos-head .beat{color:var(--sky)}
.pos-toggle{display:inline-flex;gap:4px;padding:4px;border:1px solid rgba(157,177,255,.26);border-radius:999px;background:rgba(10,14,29,.6)}
.pos-t{color:var(--sky);font:600 13px/1 var(--body);padding:9px 16px;border-radius:999px;transition:background .25s,color .25s}
.pos-t.is-on{background:var(--blue);color:#fff}
.pos-body{display:grid;gap:clamp(16px,2.2vw,30px);
  grid-template-columns:minmax(0,1fr) minmax(290px,380px);align-items:start;min-height:0}
.pos-stack{display:flex;flex-direction:column;gap:clamp(12px,1.8vh,22px)}

/* the pair: register + INFI, with the operator between them */
.pos-pair{display:grid;grid-template-columns:minmax(0,1fr) 40px minmax(0,1fr);align-items:stretch;gap:0}
.pos-op{align-self:center;text-align:center;font:400 30px/1 var(--display);color:var(--sky);opacity:.8}
.ppan{background:var(--glass);border:1px solid var(--line);border-radius:18px;padding:clamp(15px,1.7vw,22px);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);box-shadow:0 30px 70px -44px rgba(0,0,0,.9)}
.ppan--infi{border-color:rgba(47,93,255,.42);background:linear-gradient(180deg,rgba(47,93,255,.16),rgba(22,30,64,.5))}
.ppan__k{display:flex;align-items:center;gap:9px;margin:0 0 10px;
  font:700 10.5px/1 var(--body);letter-spacing:.2em;text-transform:uppercase;color:var(--sky)}
.ppan__k i{font-style:normal;display:grid;place-items:center;width:24px;height:24px;border-radius:50%;
  background:rgba(47,93,255,.24);border:1px solid rgba(157,177,255,.34);font-size:11px;letter-spacing:0}
.ppan--infi .ppan__k i{background:var(--blue);border-color:transparent;color:#fff}
.ppan__h{font-size:clamp(22px,2.2vw,30px)}
.ppan__b{margin:6px 0 0;font-size:12.5px;line-height:1.5;color:var(--sky);opacity:.85}
.ppan__l{list-style:none;margin:14px 0 0;padding:0;display:grid;gap:clamp(9px,1.4vh,15px)}
.ppan__l li{display:grid;grid-template-columns:32px minmax(0,1fr);gap:11px;align-items:start}
.ppan__l b{display:block;font:600 14px/1.35 var(--body);color:var(--paper)}
.ppan__l em{display:block;font-style:normal;font-size:12.5px;line-height:1.45;color:var(--mute);opacity:.8}
.ppan__ic,.ppan__L{width:32px;height:32px;border-radius:10px;display:grid;place-items:center;
  border:1px solid var(--line2);background:rgba(10,14,29,.6)}
.ppan__ic svg{width:18px;height:18px;fill:none;stroke:var(--sky);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.ppan__L{font:700 14px/1 var(--display);color:#fff;background:var(--blue);border-color:transparent;
  box-shadow:0 8px 20px -10px rgba(47,93,255,.9)}
.ppan__fit{margin:14px 0 0;padding-left:11px;border-left:2px solid var(--line2);
  font-size:12.5px;line-height:1.5;color:var(--dim)}

/* the sum of the two panels, said once */
.pos-eq{display:flex;align-items:center;gap:12px;margin:0;padding:13px 18px;border-radius:14px;
  background:rgba(47,93,255,.13);border:1px solid rgba(47,93,255,.3);
  font:600 clamp(15px,1.5vw,20px)/1.25 var(--display);letter-spacing:-.01em;color:#fff}
.pos-eq i{font-style:normal;font-size:24px;color:var(--sky);opacity:.8}

/* and what the same ground costs from one vendor */
.pos-vs{background:rgba(10,14,29,.6);border:1px solid var(--line);border-radius:18px;
  padding:clamp(14px,1.6vw,20px);display:flex;flex-direction:column;gap:12px;max-height:100%;overflow:auto}
.pvs-head{display:flex;align-items:baseline;gap:8px;flex-wrap:wrap;font-size:13px}
.pvs-head b{font:600 13.5px/1.2 var(--body);color:#fff}
.pvs-head i{font-style:normal;font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--dim)}
.pvs-head span{color:var(--dim)}
.pvs{margin:0;display:grid;gap:clamp(10px,1.3vh,15px)}
.pvs>div{display:grid;gap:4px;padding-top:10px;border-top:1px solid var(--line)}
.pvs>div:first-child{padding-top:0;border-top:0}
.pvs dt{font:700 10px/1 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--sky);opacity:.7}
.pvs dd{margin:0;display:grid;grid-template-columns:16px minmax(0,1fr);gap:8px;align-items:start;
  font-size:13px;line-height:1.4}
.pvs dd svg{width:15px;height:15px;margin-top:2px;fill:none;stroke-width:2.4;stroke-linecap:round}
.pvs .is-a{color:var(--paper)}
.pvs .is-a svg{stroke:var(--ok)}
.pvs .is-b{color:var(--dim)}
.pvs .is-b svg{stroke:rgba(255,181,71,.8)}

/* the sequence underneath: two steps to open, two to grow — the page's logic as a strip */
.pos-flow{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(8px,1vw,14px)}
.pf{position:relative;padding:14px 16px;border-radius:14px;border:1px solid var(--line);
  background:rgba(10,14,29,.55)}
.pf--grow{border-color:rgba(47,93,255,.4);background:linear-gradient(180deg,rgba(47,93,255,.14),rgba(10,14,29,.5))}
/* the arrow between steps, drawn on the gap rather than in the flow */
.pf+.pf::before{content:"";position:absolute;left:calc(clamp(8px,1vw,14px)*-1 - 1px);top:50%;width:clamp(8px,1vw,14px);
  height:1px;background:var(--line2)}
.pf+.pf::after{content:"";position:absolute;left:-7px;top:50%;width:6px;height:6px;
  border-top:1.5px solid var(--sky);border-right:1.5px solid var(--sky);transform:translateY(-50%) rotate(45deg);opacity:.75}
.pf__n{display:inline-grid;place-items:center;width:20px;height:20px;border-radius:50%;margin-bottom:8px;
  font:700 10.5px/1 var(--body);color:var(--sky);border:1px solid var(--line2);background:rgba(5,7,15,.5)}
.pf--grow .pf__n{background:var(--blue);border-color:transparent;color:#fff}
.pf b{display:block;font:600 14px/1.3 var(--body);color:var(--paper)}
.pf em{display:block;margin-top:3px;font-style:normal;font-size:12px;line-height:1.4;color:var(--mute);opacity:.78}
.pos-foot{margin:0;font-size:11.5px;line-height:1.55;color:var(--dim);max-width:104ch}

@media(max-width:1180px){
  .pos-body{grid-template-columns:1fr}
  .pos-vs{max-height:none}
}
@media(max-width:1180px){.pos-flow{grid-template-columns:repeat(2,minmax(0,1fr))}.pf:nth-child(3)::before,.pf:nth-child(3)::after{display:none}}
@media(max-width:820px){
  .pos-pair{grid-template-columns:1fr;gap:8px}
  .pos-op{padding:2px 0}
  .pos-flow{grid-template-columns:1fr}
  .pf+.pf::before,.pf+.pf::after{display:none}
}

/* ================= INFI DISPLAY demo — a board inside the plan card =================
   Reproduces the shipped `bubble-grid` template: circular art, name, category, price rows with
   size labels, sold-out at 0.4 opacity with the price struck through, accent bar at the foot.
   `--acc` is the concept's own brand colour, set inline per board. */
.dd{display:block}
.dd__bar{display:flex;flex-wrap:wrap;gap:10px;align-items:center;justify-content:space-between;margin:10px 0 12px}
.seg--sm{display:inline-flex;gap:2px;padding:3px;border-radius:999px;background:rgba(9,13,28,.6);border:1px solid var(--line)}
.seg--sm button{padding:6px 13px;border-radius:999px;border:0;background:transparent;cursor:pointer;
  font:600 12.5px/1 var(--body);color:var(--mute);transition:background .2s,color .2s}
.seg--sm button.is-on{background:var(--blue);color:#fff}
.dd__cpts{display:flex;flex-wrap:wrap;gap:6px}
.dd__cpts button{padding:6px 11px;border-radius:999px;cursor:pointer;font:600 12px/1 var(--body);
  color:var(--dim);background:transparent;border:1px solid var(--line);transition:.2s}
.dd__cpts button:hover{color:var(--paper);border-color:var(--line2)}
.dd__cpts button.is-on{color:#fff;border-color:rgba(157,177,255,.5);background:rgba(47,93,255,.16)}

/* the TV: a 16:9 screen in a thin bezel, because that is what it is */
.dd__tv{position:relative;border-radius:14px;padding:9px;background:linear-gradient(180deg,#171c2c,#0a0d18);
  border:1px solid rgba(157,177,255,.16);box-shadow:0 22px 50px -24px rgba(0,0,0,.9)}
.dd__screen{position:relative;aspect-ratio:16/9;border-radius:7px;overflow:hidden;background:#05070f}
.bd{position:absolute;inset:0;display:flex;flex-direction:column;
  background:radial-gradient(ellipse at 78% 8%,rgba(255,255,255,.06),transparent 58%),
             radial-gradient(ellipse at 12% 96%,rgba(255,255,255,.05),transparent 52%),#0a0e1a;
  container-type:inline-size}
.bd__top{flex:none;display:flex;align-items:center;justify-content:space-between;padding:1.8cqw 3cqw 0}
.bd__name{font:700 2.5cqw/1 var(--display);letter-spacing:-.02em;color:#fff}
.bd__live{display:inline-flex;align-items:center;gap:.7cqw;font:600 1.15cqw/1 var(--body);
  letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.66)}
.bd__live i{width:.6cqw;height:.6cqw;border-radius:50%;background:var(--ok);box-shadow:0 0 0 .25cqw rgba(61,220,151,.25)}
.bd__promo{flex:none;margin:1cqw 3cqw 0;padding:.8cqw 1.4cqw;border-radius:.9cqw;display:flex;align-items:baseline;gap:1cqw;
  background:linear-gradient(100deg,color-mix(in srgb,var(--acc) 80%,#000),color-mix(in srgb,var(--acc) 42%,#0a0e1a));
  animation:ddPromo .5s cubic-bezier(.16,1,.3,1) both}
@keyframes ddPromo{from{opacity:0;transform:translateY(-.8cqw)}to{opacity:1;transform:none}}
.bd__promo b{font:700 1.9cqw/1 var(--display);color:#fff;letter-spacing:-.01em}
/* rows hug their content and the block centres — with the category line gone, 1fr rows left a
   dead gap between every name and its price */
.bd__grid--bubble{flex:1;min-height:0;overflow:hidden;display:grid;grid-template-columns:repeat(6,1fr);
  grid-auto-rows:auto;gap:2cqw 1cqw;padding:1.2cqw 3cqw;align-content:center}
.bd__bar{flex:none;height:.55cqw;background:linear-gradient(90deg,var(--acc),color-mix(in srgb,var(--acc) 30%,transparent))}
/* one item lifts at a time — the template's own spotlight */
.bb{display:flex;flex-direction:column;align-items:center;text-align:center;min-width:0;min-height:0;
  transition:opacity .5s ease,transform .5s cubic-bezier(.16,1,.3,1);opacity:.66}
.bb.is-spot{opacity:1;transform:translateY(-.5cqw)}
/* fixed share, never flex-grow: growing the art with the leftover space made every card's
   circle a different size depending on whether its name wrapped to two lines */
.bb__art{position:relative;flex:none;width:80%;aspect-ratio:1;border-radius:50%;
  overflow:hidden;margin-bottom:.55cqw;background:#11162a;box-shadow:0 .8cqw 2cqw -.8cqw rgba(0,0,0,.85)}
.bb__art img{width:100%;height:100%;object-fit:cover;display:block}
.bb__n{flex:none;height:5.4cqw;font:700 1.5cqw/1.2 var(--display);color:#fff;letter-spacing:-.01em;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
/* the shipped rule: secondary text is 0.78x the item font */
.bb__p{flex:none;display:block;width:100%;margin-top:.45cqw}
.bb__r{display:flex;justify-content:space-between;align-items:baseline;font-size:1.32cqw;padding:.18cqw 0}
.bb__r+.bb__r{border-top:1px dashed rgba(255,255,255,.14)}
.bb__r--one{justify-content:flex-end}   /* one price and no size label — it still hangs right */
.bb__r i{font-style:normal;font-weight:600;color:var(--acc);letter-spacing:.04em}
.bb__r b{font-weight:600;color:rgba(255,255,255,.92)}
.bb.is-out{opacity:.4}
.bb.is-out .bb__r b{text-decoration:line-through}
.bb__out{position:absolute;inset:auto 0 0;padding:.5cqw 0;background:rgba(6,9,18,.82);
  font:700 1.05cqw/1 var(--body);letter-spacing:.14em;text-transform:uppercase;color:#fff;text-align:center}

/* order-ready — the cds.infi.us screen: Ready, then Preparing */
.bd--ready{padding:2.6cqw 3.2cqw 1.8cqw}
.ob{flex:1;min-height:0;display:grid;grid-template-columns:1.35fr 1fr;gap:3.2cqw}
.ob__col{display:flex;flex-direction:column;min-height:0}
.ob__t{flex:none;margin:0 0 1.2cqw;font:700 2.2cqw/1 var(--display);letter-spacing:-.02em;color:rgba(255,255,255,.4);
  border-bottom:1px solid rgba(255,255,255,.12);padding-bottom:.9cqw}
.ob__col--on .ob__t{color:var(--acc);border-bottom-color:color-mix(in srgb,var(--acc) 45%,transparent)}
.ob__n{flex:1;min-height:0;display:grid;grid-template-columns:1fr 1fr;gap:.6cqw 1cqw;align-content:center}
.ob__n span{font:700 4.2cqw/1.1 var(--display);letter-spacing:-.035em;color:rgba(255,255,255,.3);
  font-variant-numeric:tabular-nums}
.ob__col--on .ob__n span{color:#fff}
.ob__col--on .ob__n span.is-new{animation:ddUp .7s cubic-bezier(.16,1,.3,1) both}
@keyframes ddUp{from{opacity:0;transform:translateX(-1.4cqw) scale(.9)}to{opacity:1;transform:none}}
.ob__n em{font-style:normal;color:rgba(255,255,255,.18);font-size:3cqw}
.ob__f{flex:none;margin:1.6cqw 0 0;font:600 1.1cqw/1 var(--body);letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.3)}

.dd__ctl{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}
/* five words, not five paragraphs — the presenter says the rest */
.dd__sell{list-style:none;margin:16px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.dd__sell li{padding:9px 15px;border-radius:999px;border:1px solid var(--line);background:rgba(5,7,15,.4);
  font:700 13px/1 var(--display);letter-spacing:-.01em;color:var(--paper)}
@media(max-width:820px){.bd__grid--bubble{grid-template-columns:repeat(4,1fr)}}

/* ---- template 2: Pizza Grid — headline over brand-colour columns, the photo overhanging ---- */
.bd--pizza{background:#0a0a0a;padding:0}
.pz__head{flex:none;margin:0;padding:1.6cqw 2cqw .9cqw;text-align:center;
  font:800 5cqw/.92 var(--display);letter-spacing:-.05em;text-transform:uppercase;color:#fff}
.bd--pizza .bd__promo{margin:0 2cqw .6cqw}
.bd__grid--pizza{flex:1;min-height:0;display:grid;grid-template-columns:repeat(6,1fr);gap:.22cqw;
  background:#0a0a0a;overflow:hidden}
.pz{position:relative;min-width:0;display:flex;flex-direction:column;
  background:#0a0a0a;transition:opacity .5s ease;opacity:.94}
.pz.is-spot{opacity:1}
/* the red card starts at the circle's centre, so the top half of the photo sits on black */
/* The card starts at the CIRCLE'S CENTRE, so the photo's top half sits on black — that is the
   template's signature. Six columns with a .22cqw gap: column = (100-1.1)/6 cqw, radius = half. */
.pz::after{content:"";position:absolute;left:0;right:0;top:8.24cqw;bottom:0;background:var(--acc);z-index:0}
.pz__art{position:relative;z-index:1;width:100%;aspect-ratio:1;border-radius:50%;overflow:hidden;
  background:#15151a;box-shadow:0 .6cqw 2.4cqw rgba(0,0,0,.55)}
.pz__art img{width:100%;height:100%;object-fit:cover;display:block}
.pz__n{position:relative;z-index:1;padding:.9cqw .9cqw 0;
  font:800 1.9cqw/1.1 var(--display);letter-spacing:-.02em;color:#141414;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pz__p{position:relative;z-index:1;margin-top:auto;padding:0 .9cqw 1.1cqw;display:flex;flex-direction:column;gap:.25cqw}
.pz__r{display:flex;align-items:baseline;justify-content:space-between;gap:.6cqw}
.pz__r i{font-style:normal;font:700 1.1cqw/1 var(--body);letter-spacing:.06em;color:rgba(255,255,255,.8)}
.pz__r b{font:800 2.2cqw/1 var(--display);letter-spacing:-.01em;color:#fff}
.pz.is-out .pz__art img{filter:grayscale(1) brightness(.55)}
.pz.is-out .pz__n,.pz.is-out .pz__r b{opacity:.55}
.pz__out{position:absolute;z-index:2;left:50%;bottom:14%;transform:translateX(-50%);
  padding:.4cqw 1cqw;border-radius:999px;background:rgba(10,10,10,.82);border:1px solid rgba(255,255,255,.22);
  font:700 .95cqw/1 var(--body);letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.88);white-space:nowrap}

/* ---- template 3: Chalkboard — Caveat headings, Kalam items, ruled columns, corner ticks ---- */
.bd--chalk{background:
  radial-gradient(ellipse at 50% 0%,rgba(255,255,255,.05),transparent 60%),
  radial-gradient(ellipse at 20% 100%,rgba(255,255,255,.035),transparent 55%),#0f1216;
  padding:2.2cqw 2.6cqw}
.ck__c{position:absolute;width:2cqw;height:2cqw;border:0 solid rgba(245,242,236,.45);opacity:.6}
.ck__c--tl{top:1.2cqw;left:1.4cqw;border-top-width:1.4px;border-left-width:1.4px}
.ck__c--tr{top:1.2cqw;right:1.4cqw;border-top-width:1.4px;border-right-width:1.4px}
.ck__c--bl{bottom:1.2cqw;left:1.4cqw;border-bottom-width:1.4px;border-left-width:1.4px}
.ck__c--br{bottom:1.2cqw;right:1.4cqw;border-bottom-width:1.4px;border-right-width:1.4px}
.bd__chalk{flex:1;min-height:0;overflow:hidden;display:grid;grid-template-columns:repeat(4,1fr);
  align-content:start}
.ck__g{min-width:0;padding:0 1.8cqw;border-left:1px solid rgba(245,242,236,.13);text-align:center}
.ck__g:first-child{border-left:0}
.ck__ic{display:flex;width:4.6cqw;height:4.6cqw;margin:0 auto;border-radius:50%;
  border:1.4px solid rgba(245,242,236,.5);align-items:center;justify-content:center;color:rgba(245,242,236,.85)}
.ck__ic svg{width:2.4cqw;height:2.4cqw}
.ck__h{margin:.7cqw 0 .1cqw;font:700 4.4cqw/.9 'Caveat',var(--display),cursive;letter-spacing:0;
  color:rgba(245,242,236,.96);text-transform:capitalize}
.ck__rule{display:block;width:62%;height:1cqw;margin:0 auto 1.1cqw;color:rgba(245,242,236,.55)}
.ck__list{text-align:left}
.ck{display:grid;grid-template-columns:1fr auto;align-items:baseline;gap:.8cqw;padding:.3cqw 0}
.ck__n{font:700 1.45cqw/1.25 'Kalam',var(--body),cursive;text-transform:uppercase;letter-spacing:.2px;
  color:rgba(245,242,236,.92);min-width:0}
.ck__p{font:700 1.45cqw/1.25 'Kalam',var(--body),cursive;color:rgba(245,242,236,.92);
  font-variant-numeric:tabular-nums;white-space:nowrap}
/* the shipped rule: a sold-out row dims and strikes the NAME, never the price */
.ck.is-out{opacity:.72}
.ck.is-out .ck__n{text-decoration:line-through}

/* ---- "Runs on" — the hardware answer as hardware, not a sentence ---- */
.ron{display:grid;grid-template-columns:1fr 1fr 1.25fr;gap:10px;align-items:stretch}
.ron__c{display:flex;align-items:center;justify-content:center;min-height:86px;padding:14px 16px;
  border-radius:13px;border:1px solid var(--line);background:rgba(5,7,15,.45)}
.ron__c img{height:var(--h,38px);width:auto;max-width:100%;object-fit:contain;display:block}
/* the stick is a photograph, so it fills its tile instead of sitting in the middle like a mark */
.ron__c--shot{padding:0;overflow:hidden;background:#0a0d18}
.ron__c--shot img{height:100%;width:100%;object-fit:cover;object-position:center}
@media(max-width:820px){.ron{grid-template-columns:1fr 1fr}.ron__c--shot{grid-column:1/-1;min-height:120px}}

/* ---------- ACT: one change, everywhere ----------
   Left, the one thing an owner changes. Right, every surface it lands on — lit when it is part
   of the flow, dim when it is not, and outlined when it is where the change STARTED. Titles only. */
.act--eco{display:flex;padding:calc(var(--top) + 2.4vh) clamp(16px,3vw,44px) 2.6vh}
.eco-wrap{width:min(1440px,100%);margin:0 auto;display:flex;flex-direction:column;min-height:0}
.eco-head{margin-bottom:clamp(10px,1.6vh,18px)}

/* the seven things an owner changes — the map answers whichever one is lit */
.eco-flows{list-style:none;margin:0 0 clamp(10px,1.8vh,20px);padding:0;display:flex;flex-wrap:wrap;gap:7px}
.ecf{display:flex;align-items:center;gap:9px;padding:8px 14px 8px 9px;border-radius:999px;cursor:pointer;
  border:1px solid var(--line);background:rgba(5,7,15,.42);color:var(--mute);
  transition:border-color .35s,background .35s,color .35s,transform .5s var(--ease)}
.ecf:hover{border-color:var(--line2);color:var(--paper)}
.ecf b{font:700 clamp(13px,1.02vw,16px)/1.2 var(--display);letter-spacing:-.015em}
.ecf__n{flex:none;width:21px;height:21px;border-radius:50%;display:grid;place-items:center;
  font:700 11px/1 var(--body);background:rgba(157,177,255,.12);color:var(--dim)}
.ecf.is-on{border-color:rgba(47,93,255,.6);background:rgba(47,93,255,.16);color:#fff;transform:translateY(-2px)}
.ecf.is-on .ecf__n{background:var(--blue);color:#fff}

/* ---------- the map: their register in the middle, what INFI runs on the ring ----------
   Nothing is labelled INFI on purpose — the layer BETWEEN the hub and the ring is INFI, so the
   wiring carries the idea instead of a ninth box competing with the eight real surfaces. */
.eco-map{position:relative;flex:1;min-height:0}
.ecosvg{position:absolute;inset:0;display:block;overflow:visible}
/* the atmosphere the whole thing sits in — slow, never still, never in the way */
.ecoaura{position:absolute;left:50%;top:50%;width:min(62%,700px);aspect-ratio:2.05/1;
  transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;
  background:radial-gradient(closest-side,rgba(79,120,255,.34),rgba(47,93,255,.12) 55%,transparent 82%);
  animation:ecoBreathe 9s var(--ease) infinite}
@keyframes ecoBreathe{0%,100%{opacity:.62;transform:translate(-50%,-50%) scale(.95)}
  50%{opacity:1;transform:translate(-50%,-50%) scale(1.06)}}
/* one circuit every surface sits on — they are on the same loop, not eight separate purchases */
/* the circuit every surface sits on, drawn solid so the ring reads as ONE thing at a glance,
   with the moving dashes as a second pass on top of it */
.ecofield{stroke:none}   /* fill 在标签上给，见 app.js —— CSS 里的 url(#…) 会相对样式表解析 */
.ecoloop{fill:none;stroke:rgba(157,177,255,.3);stroke-width:1.2}
.ecoloop--run{fill:none;stroke:rgba(190,208,255,.7);stroke-width:1.6;stroke-dasharray:.007 .028;
  filter:drop-shadow(0 0 5px rgba(140,170,255,.6));animation:ecoCirc 26s linear infinite}
@keyframes ecoCirc{to{stroke-dashoffset:-.35}}
/* the layer between the register and the surfaces. This is INFI — which is why it is wiring
   and glow, and never a ninth card with a name on it. */
.ecoband{fill:none;stroke:rgba(120,150,255,.42);stroke-width:5;opacity:.5;filter:blur(3px)}
.ecoring{fill:none;stroke:rgba(160,185,255,.8);stroke-width:2;stroke-dasharray:.01 .014;
  transition:stroke .5s,opacity .5s,filter .5s;opacity:1;
  filter:drop-shadow(0 0 6px rgba(90,120,255,.55));animation:ecoCirc2 14s linear infinite}
@keyframes ecoCirc2{to{stroke-dashoffset:.3}}
.ecoin{fill:none;stroke:rgba(120,148,255,.2);stroke-width:1;stroke-dasharray:.004 .022;
  animation:ecoCirc 20s linear infinite reverse}
.ecoring.is-live{stroke:rgba(61,220,151,.9);opacity:1;filter:drop-shadow(0 0 7px rgba(61,220,151,.5))}
.ecorb{fill:rgba(170,190,255,.92);filter:drop-shadow(0 0 6px rgba(120,150,255,.85))}
.ecorb--in{fill:rgba(61,220,151,.8);filter:drop-shadow(0 0 6px rgba(61,220,151,.6))}
/* every spoke carries a slow trickle even when nothing is selected */
.ecsp{fill:none;stroke:rgba(157,177,255,.5);stroke-width:1.4;opacity:.9;stroke-dasharray:.02 .05;
  animation:ecoTrickle 7s linear infinite;animation-delay:calc(var(--i,0)*-1.1s)}
@keyframes ecoTrickle{to{stroke-dashoffset:-.35}}
.ecw{fill:none;stroke:var(--blue);stroke-width:2.4;stroke-linecap:round;
  filter:drop-shadow(0 0 6px rgba(47,93,255,.55));transition:stroke-dashoffset .62s var(--ease)}
.ecw--in{stroke:var(--ok);filter:drop-shadow(0 0 6px rgba(61,220,151,.5))}
/* a two-way link is told apart by its packets — one each way — not by a colour of its own */
.ecpk{fill:#fff;filter:drop-shadow(0 0 7px rgba(47,93,255,.95))}

.ecohub,.ecs{position:absolute;transform:translate(-50%,-50%);box-sizing:border-box}
.ecs{width:152px;min-height:64px;display:flex;flex-direction:column;align-items:flex-start;gap:7px;
  padding:11px 13px;border-radius:14px;border:1px solid var(--line);background:rgba(7,9,18,.92);
  opacity:.58;filter:saturate(.7);
  transition:opacity .5s var(--ease),border-color .5s,background .5s,transform .55s var(--ease),filter .5s}
.ecs b{font:700 clamp(13px,1vw,15.5px)/1.2 var(--display);letter-spacing:-.015em;color:var(--paper)}
.ecs__ic{width:30px;height:30px;border-radius:9px;display:grid;place-items:center;
  background:rgba(157,177,255,.1);border:1px solid var(--line);transition:background .5s,border-color .5s}
.ecs__ic svg{width:17px;height:17px;fill:none;stroke:var(--sky);stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round;transition:stroke .5s}
.ecs.is-lit{opacity:1;filter:none;border-color:rgba(47,93,255,.5);background:rgba(16,26,62,.96);
  transform:translate(-50%,-50%) scale(1.045)}
.ecs.is-lit .ecs__ic{background:rgba(47,93,255,.22);border-color:rgba(47,93,255,.5)}
.ecs.is-src,.ecohub.is-src{opacity:1;filter:none;border-color:rgba(61,220,151,.55);background:rgba(8,32,25,.95)}
.ecs.is-src .ecs__ic,.ecohub.is-src .ecs__ic{background:rgba(61,220,151,.16);border-color:rgba(61,220,151,.5)}
.ecs.is-src .ecs__ic svg,.ecohub.is-src .ecs__ic svg{stroke:var(--ok)}

/* the hub is always their own register — never INFI */
.ecohub{left:50%;top:50%;width:178px;min-height:76px;display:flex;flex-direction:column;gap:6px;
  padding:12px 15px;border-radius:17px;border:1px solid var(--line2);
  background:linear-gradient(180deg,rgba(18,22,44,.98),rgba(8,10,20,.98));
  box-shadow:0 18px 46px rgba(0,0,0,.5);transition:border-color .5s,box-shadow .5s,transform .55s var(--ease)}
.ecohub b{font:700 clamp(16px,1.35vw,21px)/1.1 var(--display);letter-spacing:-.02em;color:#fff}
.ecohub i{font:600 10.5px/1 var(--body);letter-spacing:.14em;text-transform:uppercase;color:var(--dim);font-style:normal}
.ecohub.is-lit{border-color:rgba(47,93,255,.6);box-shadow:0 18px 46px rgba(0,0,0,.5),0 0 0 3px rgba(47,93,255,.14)}
.ecohub__ring{position:absolute;inset:-2px;border-radius:19px;border:1.5px solid rgba(61,220,151,.75);
  opacity:0;pointer-events:none}
.ecohub.is-pulse .ecohub__ring{animation:ecoRip 1.5s var(--ease) 2}
@keyframes ecoRip{0%{opacity:.9;transform:scale(1)}70%{opacity:0;transform:scale(1.42)}100%{opacity:0;transform:scale(1.42)}}

/* entrance — the map assembles: hub settles, spokes draw, cards land 60ms apart */
.eco-map.is-in .ecohub{animation:ecoHub .72s cubic-bezier(.34,1.5,.5,1) both}
.eco-map.is-in .ecoring{animation:ecoIris .9s var(--ease) both .1s}
.eco-map.is-in .ecsp{animation:ecoDraw .8s var(--ease) both calc(var(--i,0)*60ms + 160ms),
  ecoTrickle 7s linear infinite calc(var(--i,0)*60ms + 1s)}
.eco-map.is-in .ecs{animation:ecoLand .7s cubic-bezier(.34,1.42,.5,1) both;
  animation-delay:calc(var(--i,0)*60ms + 300ms)}
@keyframes ecoHub{from{opacity:0;transform:translate(-50%,-50%) scale(.82)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}
@keyframes ecoIris{from{opacity:0;transform:scale(.8);transform-origin:center}to{opacity:.75;transform:scale(1)}}
@keyframes ecoDraw{from{stroke-dasharray:1;stroke-dashoffset:1}to{stroke-dasharray:1;stroke-dashoffset:0}}
@keyframes ecoLand{from{opacity:0;transform:translate(-50%,-50%) scale(.86)}
  to{opacity:.58;transform:translate(-50%,-50%) scale(1)}}
.eco-map.is-in .ecs.is-lit{animation:none}
.eco-map.is-in .ecs.is-src{animation:none}

@media(max-width:900px){
  .ecs{width:120px;min-height:56px;padding:9px 10px}
  .ecohub{width:140px;min-height:64px}
}
@media(prefers-reduced-motion:reduce){
  .eco-map.is-in .ecohub,.eco-map.is-in .ecoring,.eco-map.is-in .ecsp,.eco-map.is-in .ecs,
  .ecoaura,.ecoloop--run,.ecoring,.ecoin,.ecsp{animation:none}
  .ecw{transition:none}
  .ecpk,.ecorb{display:none}
}

/* ---------- INFI vs theirs, one artifact in two states (shares the listing's toggle) ---------- */
.vsx{display:block}
.vsx .vsx-toggle{margin:10px 0 12px}
.vsx-body{display:block}
.vsa{border:1px solid rgba(157,177,255,.2);border-radius:16px;padding:15px 16px 16px;
  background:var(--glass);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  box-shadow:0 26px 60px -40px rgba(0,0,0,.9);transition:border-color .3s var(--ease),background .3s var(--ease)}
.vsa.is-after{border-color:rgba(47,93,255,.45);background:rgba(47,93,255,.09)}
.vsa__t{margin:0 0 12px;font:600 13px/1.3 var(--body);color:var(--paper)}
.vsa.is-before .vsa__t{color:var(--mute)}
.vsa__rows{display:grid;gap:8px}
.vsa__r{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  padding:10px 12px;border-radius:11px;border:1px solid var(--line);background:rgba(5,7,15,.45)}
.vsa__r b{font:600 13.5px/1.25 var(--body);color:var(--paper)}
.vsa__r span{font:500 12.5px/1.25 var(--body);text-align:right;color:var(--mute)}
.vsa__r.is-ok{border-color:rgba(61,220,151,.4);background:rgba(61,220,151,.09)}
.vsa__r.is-ok span{color:var(--ok)}
.vsa__r.is-bad span{color:var(--amber)}
.vsa__r.is-dim b,.vsa__r.is-dim span{color:var(--dim)}

/* a rail of tickets reads as a rail: four narrow slips side by side, not a stacked list */
.vsa--rail .vsa__rows{grid-template-columns:repeat(4,1fr);gap:9px}
.vsa--rail .vsa__r{flex-direction:column;align-items:flex-start;gap:5px;min-height:74px}
.vsa--rail .vsa__r span{text-align:left}
/* the money frame puts the figure where an owner looks for it, and lands on the last row */
.vsa--money .vsa__r span{font:700 15px/1.2 var(--display);letter-spacing:-.02em}
.vsa--money .vsa__r:last-child{border-width:2px}
.vsa--money .vsa__r:last-child span{font-size:19px}
.vsx-bul{margin-top:13px}
.vsx-note{margin:11px 0 0;font-size:11.5px;line-height:1.5;color:var(--dim)}
@media(max-width:620px){
  .vsa--rail .vsa__rows{grid-template-columns:1fr 1fr}
}

/* the website card shows the two states as photographs where we hold them */
.vsa--shot{padding:0;overflow:hidden}
.vsa__shot{margin:0;position:relative;line-height:0}
.vsa__shot img{display:block;width:100%;height:clamp(200px,30vh,318px);object-fit:cover;object-position:top center}
.vsa__shot figcaption{position:absolute;left:0;right:0;bottom:0;padding:28px 13px 10px;line-height:1.35;
  font-size:12px;color:var(--mute);background:linear-gradient(transparent,rgba(5,7,15,.92))}
