/* ═══════════════════════════════════════════════════════════════════════════════════════════
   th-demo.css — /instant-demo and /demos.

   Loaded ALONGSIDE th.css, never instead of it. Every class here is a new namespace
   (.dq*, .dbuilt*, .dpick*, .dfs*, .dsite*, .dinfo*) so nothing can collide with th.css's
   marketing vocabulary — the mistake CLAUDE.md records as "importing one into the other
   explodes every screen".

   Brand: VOID / MINT / PAPER. Satoshi 900 headings, Switzer body, Cabinet numerals. No gold,
   no blue, no rounded icon tiles, no drop shadows on .rw text. Separators are the 1px GAP of a
   hairline grid, never a border.

   MOBILE IS THE DESIGN, not a breakpoint. Duval, 2026-08-12: "on mobile they need to answer
   the questionnaire and it needs to be made really easy." So: one question per screen, 64px+
   tap targets, a nav bar pinned to the bottom of the viewport, and nothing that needs two
   hands. The desktop layout is the same machine with the preview brought alongside.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* ══════════ 01 · PAGE HEAD ══════════
   A compact hero. The site's full .s-hero is a 100vh stadium, and on a page whose job is to get
   a thumb into question one it would push the first question two screens down. */
.dhero{position:relative;overflow:hidden;background:var(--void);
  padding:clamp(92px,13vh,140px) var(--pad) clamp(26px,4vh,44px)}
.dhero__fx{position:absolute;inset:0;pointer-events:none}
.dhero__in{position:relative;z-index:2;max-width:var(--maxw);margin:0 auto;text-align:center}
.dhero__p{margin:1.3rem auto 0;max-width:54ch;font-size:clamp(1rem,1.5vw,1.18rem);
  line-height:1.55;color:rgba(255,255,255,.58)}
.dhero__pills{margin-top:1.6rem;display:flex;flex-wrap:wrap;gap:.5rem;justify-content:center}

/* ══════════ 02 · THE QUESTIONNAIRE ══════════ */
/* The deep bottom padding exists to clear the nav bar that is FIXED to the bottom of a phone
   viewport. From 900px the bar returns to the flow, so on a laptop that padding is pure dead
   space between the last option and the next section — 234px of it, measured. */
.dq{position:relative;background:var(--void);padding:0 var(--pad) clamp(120px,16vh,150px)}
@media(min-width:900px){.dq{padding-bottom:clamp(56px,7vh,90px)}}
.dq__in{max-width:1180px;margin:0 auto}

/* progress — a hairline rail, mint fill. The label names the step so the visitor always knows
   how much is left; "Step 2 of 4" alone tells you the count but not the shape. */
.dqrail{margin-bottom:clamp(1.8rem,3.6vw,2.8rem)}
.dqrail__bar{height:2px;background:var(--line);border-radius:2px;overflow:hidden}
.dqrail__bar i{display:block;height:100%;width:0;background:var(--mint);
  box-shadow:0 0 18px rgba(79,216,166,.5);transition:width .55s var(--e-out)}
.dqrail__lbl{margin-top:.75rem;font-size:.72rem;font-weight:600;letter-spacing:.22em;
  text-transform:uppercase;color:rgba(255,255,255,.34)}
.dqrail__lbl b{color:var(--mint)}
.dqrail__lbl span{color:rgba(255,255,255,.62);text-transform:none;letter-spacing:.02em;font-weight:500}

/* one question per screen */
.dqstep[hidden]{display:none}
.dqstep{animation:dqIn .42s var(--e-out) both}
@keyframes dqIn{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.dqstep{animation:none}}
.dqstep__h{font-family:'Satoshi',ui-sans-serif,system-ui,sans-serif;font-weight:900;
  font-size:clamp(1.85rem,4.4vw,3.1rem);letter-spacing:-.045em;line-height:1.02;color:#fff}
/* The heading is given tabindex="-1" and focused when the step changes, so a screen reader
   announces the new question. A visible ring around a heading tells a sighted visitor nothing
   and reads as a rendering fault — it drew a green box around the whole H2 in the first render
   of this page. Focus is still moved; it just is not painted. */
.dqstep__h:focus{outline:none}
.dqstep__p{margin:.9rem 0 0;max-width:56ch;font-size:clamp(.95rem,1.35vw,1.08rem);
  line-height:1.55;color:rgba(255,255,255,.5)}
.dqstep__head{margin-bottom:clamp(1.5rem,3vw,2.2rem)}

/* ── option grid — the brand's hairline grid: the separator IS the gap ────────────────────── */
.dqopts{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:var(--rad);overflow:hidden}
.dqopts--2{grid-template-columns:1fr}
.dqopts--3{grid-template-columns:1fr}
@media(min-width:720px){
  .dqopts--2{grid-template-columns:repeat(2,1fr)}
  .dqopts--3{grid-template-columns:repeat(2,1fr)}
}
@media(min-width:1040px){.dqopts--3{grid-template-columns:repeat(3,1fr)}}

.dqopt{position:relative;display:block;width:100%;text-align:left;border:0;cursor:pointer;
  background:var(--ink);color:inherit;font:inherit;
  padding:clamp(1.05rem,2vw,1.4rem) clamp(1.1rem,2vw,1.5rem) clamp(1.15rem,2.2vw,1.5rem);
  min-height:76px;overflow:hidden;transition:background .3s var(--e-soft)}
.dqopt:hover{background:var(--ink-2)}
.dqopt:focus-visible{outline:2px solid var(--mint);outline-offset:-3px}
/* the oversized ghost index numeral, bled into the top-right corner */
.dqopt__n{position:absolute;top:-.28em;right:.06em;font-family:'Cabinet Grotesk','Satoshi',ui-sans-serif,sans-serif;
  font-weight:900;font-size:clamp(3.4rem,7vw,4.6rem);line-height:1;letter-spacing:-.05em;
  color:rgba(255,255,255,.05);pointer-events:none;user-select:none;transition:color .35s}
.dqopt__t{display:flex;align-items:center;gap:.6rem;font-family:'Satoshi',ui-sans-serif,sans-serif;
  font-weight:900;font-size:clamp(1rem,1.7vw,1.16rem);letter-spacing:-.02em;color:#fff}
.dqopt__g{display:inline-flex;flex:0 0 auto;color:var(--mint);line-height:0}
.dqopt__g svg{width:19px;height:19px}
.dqopt__d{margin-top:.42rem;font-size:.86rem;line-height:1.5;color:rgba(255,255,255,.48);
  max-width:42ch;position:relative;z-index:1}
/* the mint rule that grows along the bottom edge */
.dqopt::after{content:"";position:absolute;left:0;bottom:0;height:2px;width:0;background:var(--mint);
  transition:width .45s var(--e-out)}
.dqopt:hover::after{width:36%}
.dqopt.is-on{background:var(--ink-3)}
.dqopt.is-on::after{width:100%}
.dqopt.is-on .dqopt__n{color:rgba(79,216,166,.16)}
.dqopt__tick{position:absolute;top:.9rem;right:.9rem;width:24px;height:24px;border-radius:50%;
  background:var(--mint);color:#00170E;display:none;align-items:center;justify-content:center;z-index:2}
.dqopt__tick svg{width:14px;height:14px}
.dqopt.is-on .dqopt__tick{display:flex;animation:dqTick .3s var(--e-back) both}
@keyframes dqTick{from{transform:scale(.4);opacity:0}to{transform:none;opacity:1}}

/* ── swatches (the look question) ─────────────────────────────────────────────────────────── */
.dqtone{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:var(--rad);overflow:hidden;margin-bottom:1px}
.dqtone__b{position:relative;border:0;cursor:pointer;font:inherit;padding:1.1rem 1.2rem 1.2rem;
  background:var(--ink);color:#fff;text-align:left;transition:background .3s var(--e-soft)}
.dqtone__b:hover{background:var(--ink-2)}
.dqtone__b.is-on{background:var(--ink-3)}
.dqtone__b:focus-visible{outline:2px solid var(--mint);outline-offset:-3px}
.dqtone__sw{display:block;height:46px;border-radius:12px;border:1px solid var(--line-2);margin-bottom:.7rem}
.dqtone__b[data-v="dark"] .dqtone__sw{background:linear-gradient(150deg,#161b1a,#07100c)}
.dqtone__b[data-v="light"] .dqtone__sw{background:linear-gradient(150deg,#ffffff,#e7edea)}
.dqtone__n{font-family:'Satoshi',ui-sans-serif,sans-serif;font-weight:900;font-size:1rem;letter-spacing:-.02em}
.dqtone__d{margin-top:.2rem;font-size:.8rem;color:rgba(255,255,255,.46);line-height:1.45}
.dqtone__b::after{content:"";position:absolute;left:0;bottom:0;height:2px;width:0;background:var(--mint);
  transition:width .45s var(--e-out)}
.dqtone__b.is-on::after{width:100%}

.dqcols{display:flex;flex-wrap:wrap;gap:10px;margin-top:1.3rem}
.dqcol{position:relative;width:52px;height:52px;border-radius:14px;border:2px solid transparent;
  cursor:pointer;padding:0;transition:transform .25s var(--e-back),border-color .25s}
.dqcol:hover{transform:translateY(-3px)}
.dqcol.is-on{border-color:#fff}
.dqcol:focus-visible{outline:2px solid var(--mint);outline-offset:3px}
.dqcol__i{position:absolute;inset:3px;border-radius:9px}

/* ── text fields ──────────────────────────────────────────────────────────────────────────── */
.dqfields{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:var(--rad);overflow:hidden}
@media(min-width:720px){.dqfields--2{grid-template-columns:1fr 1fr}}
.dqf{background:var(--ink-2);padding:1.05rem 1.2rem 1.15rem;display:flex;flex-direction:column;gap:.5rem}
.dqf__l{font-size:.78rem;font-weight:600;letter-spacing:.02em;color:rgba(255,255,255,.62)}
.dqf__i{width:100%;background:var(--ink-3);border:1px solid var(--line-2);border-radius:12px;
  color:#fff;font-family:'Satoshi',ui-sans-serif,system-ui,sans-serif;font-weight:700;
  font-size:1.15rem;letter-spacing:-.015em;padding:.65rem .85rem}
.dqf__i::placeholder{color:rgba(255,255,255,.26);font-weight:500}
.dqf__i:focus{outline:none;border-color:var(--mint);box-shadow:0 0 0 3px rgba(79,216,166,.16)}
.dqf__h{font-size:.74rem;color:rgba(255,255,255,.4);line-height:1.45}

/* ── nav — pinned to the bottom of the VIEWPORT on a phone ────────────────────────────────
   A questionnaire whose Continue button is below the fold makes the visitor scroll past the
   options they have just been asked to read. On a phone the bar floats; from 900px up it sits
   back in the flow where there is room for it. */
.dqnav{position:fixed;left:0;right:0;bottom:0;z-index:30;display:flex;gap:.7rem;align-items:center;
  padding:.8rem var(--pad) calc(.8rem + env(safe-area-inset-bottom));
  background:linear-gradient(0deg,rgba(0,0,0,.97) 60%,rgba(0,0,0,0));
  border-top:1px solid var(--line)}
.dqnav__sp{flex:1}
.dqnav .btn{white-space:nowrap}
/* 🚨 `hidden` LOSES to a display rule. th.css sets `.btn{display:inline-flex}` and an author
   declaration beats the UA stylesheet's `[hidden]{display:none}`, so `back.hidden = true` on
   step one changed nothing and every visitor saw a Back button on the first question with
   nowhere to go back to. Caught in the live phone render, not by any assertion.
   Same for the bar itself, which is display:flex here. */
.dqnav[hidden],
.dqnav__back[hidden]{display:none}
@media(min-width:900px){
  .dqnav{position:static;padding:clamp(1.6rem,3vw,2.4rem) 0 0;background:none;border-top:0}
}
/* 🚨 MEASURED, not predicted. Driving the questionnaire at 390×844 with Playwright, the
   Continue button could not be clicked at all: the site's OWN chat bubble (#ddb, fixed at
   right:14px bottom:14px, 58px across) sits exactly on top of the right-hand end of the pinned
   nav bar, and Playwright reported it intercepting every click for 30 seconds. A visitor's
   thumb would have opened our sales chat instead of answering question two, on every phone.
   `th-dq` is set by th-demo.js on these two pages only, and lifts the bubble clear of the bar
   rather than hiding it — this is a high-intent page and the bubble is a real lead path.
   Above 900px the nav returns to the flow and there is nothing to clear. */
@media(max-width:899px){
  body.th-dq .ddb{bottom:calc(86px + env(safe-area-inset-bottom))}
}
.dqerr{margin-top:1rem;font-size:.86rem;color:#ffb4b4;line-height:1.5}
.dqerr[hidden]{display:none}

/* ══════════ 03 · THE BUILT RESULT (instant demo) ══════════ */
.dbuilt[hidden]{display:none}
.dbuilt{animation:dqIn .5s var(--e-out) both}
.dbuilt__grid{display:grid;gap:clamp(1.4rem,3vw,2.4rem);align-items:start}
@media(min-width:960px){.dbuilt__grid{grid-template-columns:1fr .82fr}}
.dbuilt__h{font-family:'Satoshi',ui-sans-serif,sans-serif;font-weight:900;
  font-size:clamp(2rem,4.6vw,3.3rem);letter-spacing:-.05em;line-height:1;color:#fff}
.dbuilt__p{margin:1rem 0 0;max-width:52ch;font-size:clamp(.96rem,1.4vw,1.1rem);
  line-height:1.55;color:rgba(255,255,255,.55)}
.dbuilt__chips{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:1.4rem}
.dbchip{display:inline-flex;align-items:center;gap:.5rem;padding:.5rem .85rem;border-radius:100px;
  border:1px solid var(--line-2);font-size:.82rem;color:rgba(255,255,255,.78);background:rgba(255,255,255,.02)}
.dbchip i{width:12px;height:12px;border-radius:4px;flex:0 0 auto;display:block}
.dbuilt__cta{display:flex;flex-wrap:wrap;gap:.7rem;margin-top:clamp(1.6rem,3vw,2.2rem)}

/* the little "on a phone" mock, so something is visible the second the last answer lands */
.dmini{background:var(--ink);border:1px solid var(--line);border-radius:var(--rad);overflow:hidden}
.dmini__bar{display:flex;align-items:center;gap:.45rem;padding:.7rem .9rem;border-bottom:1px solid var(--line)}
.dmini__dot{width:9px;height:9px;border-radius:50%;background:rgba(255,255,255,.13)}
.dmini__url{margin-left:.5rem;font-size:.72rem;color:rgba(255,255,255,.3);letter-spacing:.02em}
.dmini__stage{position:relative;height:360px;overflow:hidden}
.dmini__stage[data-tone="light"]{background:#fff}
.dmini__stage[data-tone="dark"]{background:#0b0f0e}
.dmini__slot{position:absolute;inset:0}
.dmini__cap{padding:.85rem .95rem;border-top:1px solid var(--line);font-size:.76rem;
  color:rgba(255,255,255,.4);line-height:1.45}

/* ══════════ 04 · THE TWO PICKS (/demos) ══════════ */
.dpicks[hidden]{display:none}
.dpicks{animation:dqIn .5s var(--e-out) both}
.dpicks__grid{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:var(--rad);overflow:hidden}
@media(min-width:820px){.dpicks__grid{grid-template-columns:1fr 1fr}}
.dpick{position:relative;background:var(--ink);padding:clamp(1.3rem,2.6vw,2rem);
  display:flex;flex-direction:column;gap:.85rem;overflow:hidden}
.dpick__top{display:flex;align-items:center;gap:.8rem}
.dpick__mono{width:46px;height:46px;border-radius:14px;flex:0 0 auto;display:flex;
  align-items:center;justify-content:center;font-family:'Cabinet Grotesk','Satoshi',sans-serif;
  font-weight:900;font-size:1.25rem;color:#fff}
.dpick__n{font-family:'Satoshi',ui-sans-serif,sans-serif;font-weight:900;font-size:1.12rem;
  letter-spacing:-.025em;color:#fff;line-height:1.15}
.dpick__s{font-size:.78rem;color:rgba(255,255,255,.42);margin-top:.15rem}
.dpick__why{font-size:.88rem;line-height:1.55;color:rgba(255,255,255,.62)}
.dpick__why b{color:var(--mint);font-weight:700}
.dpick__caps{display:flex;flex-wrap:wrap;gap:.4rem}
.dcap{display:inline-block;padding:.34rem .68rem;border-radius:100px;border:1px solid var(--line-2);
  font-size:.74rem;color:rgba(255,255,255,.6)}
.dpick__cta{margin-top:auto;padding-top:.5rem}
.dpick__rule{position:absolute;left:0;bottom:0;height:2px;width:0;transition:width .5s var(--e-out)}
.dpick:hover .dpick__rule{width:100%}

/* the full roster, for anyone the questionnaire did not land on */
.dall{margin-top:clamp(2.2rem,4.5vw,3.4rem)}
.dall__h{font-size:.72rem;font-weight:600;letter-spacing:.22em;text-transform:uppercase;
  color:rgba(255,255,255,.34);margin-bottom:1rem}
.dall__grid{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:var(--rad);overflow:hidden;grid-template-columns:repeat(2,1fr)}
@media(min-width:700px){.dall__grid{grid-template-columns:repeat(3,1fr)}}
@media(min-width:1060px){.dall__grid{grid-template-columns:repeat(5,1fr)}}
.dallb{background:var(--ink);border:0;cursor:pointer;font:inherit;color:#fff;text-align:left;
  padding:.95rem 1rem 1.05rem;display:flex;flex-direction:column;gap:.3rem;min-height:84px;
  transition:background .3s var(--e-soft)}
.dallb:hover{background:var(--ink-2)}
.dallb:focus-visible{outline:2px solid var(--mint);outline-offset:-3px}
.dallb__d{width:10px;height:10px;border-radius:50%;margin-bottom:.15rem}
.dallb__n{font-family:'Satoshi',ui-sans-serif,sans-serif;font-weight:900;font-size:.9rem;
  letter-spacing:-.02em;line-height:1.2}
.dallb__s{font-size:.72rem;color:rgba(255,255,255,.4)}

/* ══════════ 05 · FULL SCREEN ══════════
   Duval: "when they click on that button it must take over their entire screen, there must be
   an exit button on the left but the website chatbot must be on the right".

   The widget runtime pins .dd-host to the VIEWPORT at z-index 2147483600, so the backdrop has
   to sit under that number and the exit bar above it. Those two z-indexes are the whole
   contract; everything else is paint. */
.dfs{position:fixed;inset:0;z-index:2147483500;display:none}
.dfs.is-open{display:block;animation:dfsIn .38s var(--e-out) both}
@keyframes dfsIn{from{opacity:0}to{opacity:1}}
@media(prefers-reduced-motion:reduce){.dfs.is-open{animation:none}}

/* The bar is CHROME — it belongs to the demo, not to the pretend website underneath. It gets
   its own surface and a hairline so it reads as a toolbar over a page, the way a browser bar
   does. Without that the exit button sat exactly where the fake site's logo is and the hint
   text ran through the fake nav links, which looked like a rendering fault rather than a
   deliberate frame. The mock site starts BELOW it for the same reason. */
.dfs__bar{position:fixed;top:0;left:0;right:0;z-index:2147483640;display:flex;align-items:center;
  gap:.8rem;height:calc(58px + env(safe-area-inset-top));padding:0 clamp(12px,3vw,22px);
  padding-top:env(safe-area-inset-top)}
.dfs[data-tone="dark"] .dfs__bar{background:rgba(6,10,9,.92);border-bottom:1px solid rgba(255,255,255,.09);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
.dfs[data-tone="light"] .dfs__bar{background:rgba(255,255,255,.92);border-bottom:1px solid rgba(2,36,25,.1);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
.dfs__hint{font-size:.78rem;letter-spacing:.02em;line-height:1.3;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media(max-width:640px){.dfs__hint{display:none}}

/* the exit control has to be legible on BOTH a black and a white backdrop, so it carries its
   own tone rather than inheriting one. Never a bare × — a naked glyph in the corner of a
   takeover reads as decoration and people hunt for the way out. */
.dfsx{display:inline-flex;align-items:center;gap:.55rem;border:0;cursor:pointer;
  font-family:'Switzer',ui-sans-serif,system-ui,sans-serif;font-weight:600;font-size:.88rem;
  padding:.55rem .55rem .55rem 1rem;border-radius:100px;height:44px;
  transition:transform .25s var(--e-back),background .25s}
.dfsx__c{width:30px;height:30px;border-radius:50%;display:inline-flex;align-items:center;
  justify-content:center;transition:transform .3s var(--e-back)}
.dfsx__c svg{width:15px;height:15px}
.dfsx:hover .dfsx__c{transform:translate(-3px,0) scale(1.06)}
.dfsx:focus-visible{outline:2px solid var(--mint);outline-offset:3px}
.dfs[data-tone="dark"] .dfsx{background:rgba(255,255,255,.1);color:#fff;
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}
.dfs[data-tone="dark"] .dfsx:hover{background:rgba(255,255,255,.17)}
.dfs[data-tone="dark"] .dfsx__c{background:#fff;color:#000}
.dfs[data-tone="dark"] .dfs__hint{color:rgba(255,255,255,.5)}
.dfs[data-tone="light"] .dfsx{background:rgba(2,36,25,.08);color:var(--on-paper);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}
.dfs[data-tone="light"] .dfsx:hover{background:rgba(2,36,25,.15)}
.dfs[data-tone="light"] .dfsx__c{background:var(--on-paper);color:#fff}
.dfs[data-tone="light"] .dfs__hint{color:var(--paper-soft)}

/* ── the mock website behind the chat ─────────────────────────────────────────────────────
   Duval: "the background behind the website chatbot chat should say 'your website' with a
   black or white background depending on their theme colours."
   It says exactly that, and it is built like a website rather than being an empty panel with a
   caption — a bare colour field would make the widget look like it is floating in a dialog,
   which is the one thing this screen has to disprove. Nothing here is interactive; the whole
   backdrop is aria-hidden so a screen reader never walks a fake navigation. */
.dsite{position:absolute;inset:0;overflow:hidden;user-select:none}
.dsite[data-tone="dark"]{background:#000;color:#fff}
.dsite[data-tone="light"]{background:#fff;color:var(--on-paper)}
.dsite__nav{position:absolute;top:calc(58px + env(safe-area-inset-top));left:0;right:0;height:60px;
  display:flex;align-items:center;gap:1.4rem;padding:0 clamp(14px,4vw,44px)}
.dsite[data-tone="dark"] .dsite__nav{border-bottom:1px solid rgba(255,255,255,.07)}
.dsite[data-tone="light"] .dsite__nav{border-bottom:1px solid rgba(2,36,25,.08)}
.dsite__logo{width:104px;height:13px;border-radius:6px;opacity:.22;background:currentColor}
.dsite__nl{width:52px;height:8px;border-radius:4px;opacity:.14;background:currentColor}
@media(max-width:680px){.dsite__nl{display:none}}
.dsite__btn{margin-left:auto;width:84px;height:30px;border-radius:100px;opacity:.18;background:currentColor}

.dsite__mid{position:absolute;left:0;right:0;bottom:54px;top:calc(118px + env(safe-area-inset-top));
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:0 clamp(16px,5vw,60px);text-align:center}
.dsite__eyebrow{font-size:.68rem;font-weight:600;letter-spacing:.26em;text-transform:uppercase;
  opacity:.34;margin-bottom:1.1rem}
/* nowrap + 11vw put "Your website" 160px past the right edge of a 1440 viewport and straight
   under the chat panel. It is the one line on this screen that has to be readable. */
.dsite__wm{font-family:'Cabinet Grotesk','Satoshi',ui-sans-serif,sans-serif;font-weight:900;
  font-size:clamp(2rem,6.4vw,5.2rem);line-height:.92;letter-spacing:-.05em;opacity:.16;
  margin:0;white-space:nowrap;max-width:100%}
.dsite__sub{margin-top:1.2rem;font-size:clamp(.82rem,1.35vw,1rem);opacity:.32;max-width:44ch;line-height:1.5}
.dsite__blocks{display:flex;gap:12px;margin-top:clamp(1.6rem,3.4vw,2.6rem);width:100%;
  max-width:760px;justify-content:center}
.dsite__blk{flex:1;max-width:230px;height:clamp(58px,9vh,96px);border-radius:14px;opacity:.075;background:currentColor}
/* From the width at which the chat becomes a floating panel on the right, the backdrop is
   centred in what is LEFT of the screen rather than in the whole of it — otherwise the
   headline is centred behind the panel that is covering it. */
@media(min-width:1100px){
  .dsite__mid{right:430px}
  .dsite__blocks{max-width:600px}
}
@media(max-width:560px){.dsite__blk:nth-child(3){display:none}}
/* ── phones ──────────────────────────────────────────────────────────────────────────────
   The chat opens nearly full height on a phone, so a vertically-centred backdrop is simply
   behind it: the first render of this screen showed a black rectangle and nothing else, on the
   one requirement Duval spelled out. The backdrop moves to the top of the free strip and the
   chat is capped so that strip exists. */
@media(max-width:699px){
  .dsite__nav{height:40px}
  .dsite__mid{justify-content:flex-start;padding-top:1.1rem;bottom:auto;height:auto;
    top:calc(98px + env(safe-area-inset-top))}
  .dsite__wm{font-size:clamp(1.9rem,9.4vw,3rem)}
  .dsite__sub{margin-top:.6rem;font-size:.78rem;max-width:34ch}
  .dsite__blocks{display:none}
  .dsite__eyebrow{margin-bottom:.6rem;font-size:.62rem}
}
.dsite__foot{position:absolute;left:0;right:0;bottom:0;height:54px;display:flex;align-items:center;
  padding:0 clamp(14px,4vw,44px);gap:1rem}
.dsite[data-tone="dark"] .dsite__foot{border-top:1px solid rgba(255,255,255,.07)}
.dsite[data-tone="light"] .dsite__foot{border-top:1px solid rgba(2,36,25,.08)}
.dsite__fl{width:64px;height:8px;border-radius:4px;opacity:.1;background:currentColor}

/* ── the widget's own geometry, inside the takeover ────────────────────────────────────────
   On a phone the runtime opens the chat at max-height:85vh with bottom:78px, which leaves
   about 49px above it on a 844px screen — the exit bar would sit on the chat header. Capping
   the height buys a clean 72px strip. The runtime's rule carries !important, so this one has
   to as well; the extra class gives it the specificity to win. */
/* max() so a short phone keeps a usable chat: on an 844px screen this is 534px of chat and a
   242px strip for the backdrop; on a 667px SE it is a 347px chat rather than a 357px one. */
body.dfs-on .dd-window{max-height:max(320px,calc(100vh - 310px))!important}
@media(min-width:700px){
  body.dfs-on .dd-window{max-height:min(620px,calc(100vh - 190px))!important}
}
/* the site's OWN chatbot must not be in the picture — two launchers in one corner, one of
   them ours, is exactly the "two brands, never mixed" mistake. th.css already hides .ddb
   behind body.is-locked, which the shell sets. This is the belt to that braces. */
body.dfs-on .ddb{opacity:0!important;pointer-events:none!important}

/* ── 🚨 A PRODUCT BUG, PATCHED HERE AND ONLY HERE ─────────────────────────────────────────
   MEASURED on the LIVE widget (not on our markup): at 390px wide, sending "book me in" to the
   real Luxe bot produces a bubble 76px across and 58px TALL — three lines for three short
   words — and "Saturday" breaks as "Saturd/ay". Every client's chatbot does this on a phone.

   The cause is in the shared widget-render.css:
       .dd-msg-row{max-width:90%}                       (bounded by .dd-body — correct)
       .dd-row-client{align-self:flex-end}              (so the row shrinks to fit)
       @media(max-width:480px){ .dd-msg{max-width:84%} } (84% of the shrink-wrapped row)
   The percentage resolves against a width that is itself derived from the text, so a short
   message can never occupy the width it needs. The bubble is already bounded by the row; it
   does not need a second percentage cap inside it.

   ⚠ NOT fixed at the source tonight, deliberately. widget-render.css is loaded by every paying
   client's site, and its deploy script — DD AI structure/widget-render/_deploy.py — uploads the
   copy sitting next to itself, which is 50,674 bytes dated 2026-05-25 against a LIVE file of
   60,296 bytes dated 2026-08-11. Running it would roll the renderer back two and a half months
   on every client. That is the "deploy source was BEHIND live" trap, and it needs its own job
   with its own verification, not a 2am one-liner. The one-line fix, for whoever does it:
       @media(max-width:480px){ .dd-msg{max-width:100%} }
   Scoped to our own full-screen shell here so the demos read correctly in the meantime. */
.dfs .dd-msg{max-width:100%}

/* the three-message cap */
.dfscap{position:fixed;left:50%;transform:translateX(-50%);bottom:clamp(14px,3vh,26px);
  z-index:2147483640;max-width:min(560px,calc(100vw - 28px));width:max-content;
  display:none;align-items:center;gap:.9rem;padding:.7rem .8rem .7rem 1.1rem;border-radius:100px;
  background:rgba(0,0,0,.86);border:1px solid var(--line-2);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  animation:dqIn .4s var(--e-out) both}
.dfscap.is-on{display:flex}
.dfscap__t{font-size:.82rem;line-height:1.35;color:rgba(255,255,255,.72)}
.dfscap__t b{color:#fff;font-weight:700}
@media(max-width:640px){
  .dfscap{left:12px;right:12px;transform:none;width:auto;max-width:none;border-radius:20px;
    flex-direction:column;align-items:stretch;gap:.6rem;padding:.9rem}
  .dfscap__t{text-align:center}
  .dfscap .btn{width:100%;justify-content:center}
}

/* ══════════ 06 · INFORMATION — enough, and not one line more ══════════ */
.dinfo{background:var(--void);padding:clamp(70px,10vh,130px) var(--pad)}
.dinfo__in{max-width:var(--maxw);margin:0 auto}
.dinfo__grid{display:grid;gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:var(--rad);overflow:hidden;margin-top:clamp(1.8rem,3.6vw,2.6rem)}
@media(min-width:760px){.dinfo__grid{grid-template-columns:repeat(3,1fr)}}
.dinfo__c{position:relative;background:var(--void);padding:clamp(1.3rem,2.6vw,2rem);overflow:hidden}
.dinfo__n{position:absolute;top:-.3em;right:.04em;font-family:'Cabinet Grotesk','Satoshi',sans-serif;
  font-weight:900;font-size:clamp(3.6rem,7vw,5.2rem);line-height:1;color:rgba(255,255,255,.05);
  pointer-events:none}
.dinfo__g{color:var(--mint);line-height:0;display:inline-flex;margin-bottom:.9rem}
.dinfo__g svg{width:22px;height:22px}
.dinfo__t{font-family:'Satoshi',ui-sans-serif,sans-serif;font-weight:900;font-size:1.1rem;
  letter-spacing:-.025em;color:#fff}
.dinfo__d{margin-top:.5rem;font-size:.9rem;line-height:1.6;color:rgba(255,255,255,.48);max-width:38ch}
.dinfo__c::after{content:"";position:absolute;left:0;bottom:0;height:2px;width:0;background:var(--mint);
  transition:width .5s var(--e-out)}
.dinfo__c:hover::after{width:100%}
.dinfo__foot{margin-top:clamp(1.6rem,3vw,2.2rem);display:flex;flex-wrap:wrap;gap:.7rem;align-items:center}
.dinfo__note{font-size:.82rem;color:rgba(255,255,255,.4);line-height:1.5;max-width:60ch}

/* noscript — these two pages ARE the interaction; say so rather than showing a dead shell */
.dnojs{max-width:60ch;margin:clamp(90px,14vh,150px) auto;padding:0 var(--pad);
  color:rgba(255,255,255,.7);font-size:1rem;line-height:1.6}
.dnojs a{color:var(--mint);text-decoration:underline;text-underline-offset:3px}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   DDAI-DEMO-WALL-V1 (2026-08-24) — THE WALL, THE TRADE FILTER AND THE PLAN SEGMENT

   Measured at 390x844 before this section existed: the hero ran 474px, the first question began
   at 531px and was itself 889px tall. A visitor scrolled about a screen and a half before they
   could press Continue, to be shown two of ten bots. The bots are the page now.

   Mobile is the design, not a breakpoint — same rule the rest of this file is written to.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

/* the wall replaces the questionnaire, so the padding that cleared the pinned Continue bar is
   dead space until the guided route is opened. th-demo.js toggles .is-wall with the route. */
@media(max-width:899px){ .dq.is-wall{padding-bottom:clamp(44px,7vh,74px)} }

.dwall[hidden]{display:none}
.dwall{animation:dqIn .5s var(--e-out) both;padding-top:clamp(1.2rem,3vw,2rem)}
.dwall__bar{display:flex;flex-direction:column;gap:.9rem;margin-bottom:.9rem}
@media(min-width:960px){
  .dwall__bar{flex-direction:row;align-items:center;justify-content:space-between;gap:1.4rem}
}

/* ── the trade filter ── one row, scrolls sideways on a phone, never wraps to three lines ── */
.dwall__f{display:flex;gap:.45rem;overflow-x:auto;-webkit-overflow-scrolling:touch;
  scroll-snap-type:x proximity;padding-bottom:.3rem;margin:0 calc(var(--pad) * -1);
  padding-left:var(--pad);padding-right:var(--pad)}
@media(min-width:960px){.dwall__f{margin:0;padding-left:0;padding-right:0;flex-wrap:wrap;overflow:visible}}
.dwall__f::-webkit-scrollbar{height:0}
.dfil{flex:0 0 auto;scroll-snap-align:start;min-height:40px;padding:.55rem 1rem;border-radius:999px;
  border:1px solid var(--line);background:transparent;color:rgba(255,255,255,.62);
  font-family:'Switzer',ui-sans-serif,system-ui,sans-serif;font-weight:600;font-size:.83rem;
  cursor:pointer;white-space:nowrap;transition:color .2s,border-color .2s,background .2s}
.dfil:hover{color:#fff;border-color:var(--line-2)}
.dfil.is-on{background:var(--mint);border-color:var(--mint);color:var(--on-mint)}
.dfil:focus-visible{outline:2px solid var(--mint);outline-offset:2px}

/* ── the plan segment ── the whole tier difference is one string in the config, so this is a
      preview control, not a claim: simplifyForTier() in the renderer does the stripping ── */
.dwall__t{display:flex;align-items:center;gap:.6rem;flex-wrap:wrap}
.dwall__tl{font-size:.7rem;font-weight:600;letter-spacing:.22em;text-transform:uppercase;
  color:rgba(255,255,255,.34)}
.dtier{display:inline-flex;gap:2px;padding:3px;border:1px solid var(--line);border-radius:999px;
  background:rgba(255,255,255,.02)}
.dtier button{min-height:36px;padding:.42rem .82rem;border:0;border-radius:999px;background:transparent;
  color:rgba(255,255,255,.55);font-family:'Switzer',ui-sans-serif,system-ui,sans-serif;
  font-weight:600;font-size:.8rem;cursor:pointer;white-space:nowrap;transition:color .2s,background .2s}
.dtier button:hover{color:#fff}
.dtier button.is-on{background:var(--mint);color:var(--on-mint)}
.dtier button:focus-visible{outline:2px solid var(--mint);outline-offset:2px}
.dtier--sm button{min-height:32px;padding:.32rem .62rem;font-size:.74rem}
.dwall__note{margin:0 0 1.2rem;font-size:.84rem;line-height:1.55;color:rgba(255,255,255,.5);
  max-width:74ch}
.dwall__note b{color:var(--mint);font-weight:700}

/* ── the grid ── the hairline pattern the rest of the brand uses: the gap IS the separator ── */
.dwall__grid{grid-template-columns:1fr}
@media(min-width:640px){.dwall__grid{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1060px){.dwall__grid{grid-template-columns:repeat(3,1fr)}}

/* 🚨 THE LAST ROW LOOKED LIKE A CARD THAT FAILED TO LOAD.
   `.cards` paints the CONTAINER in --line and lets each card paint over it, so the gap between
   two cards is the separator. That is right until a row is short: ten bots in three columns
   leaves two empty cells, and at 1440 those rendered as one large --line block two thirds of
   the width — brighter than the cards around it, and indistinguishable from a loading state.
   Seen in a screenshot; no check could have caught it, because every rule was doing exactly
   what it says.
   So the container is painted --void (the page's own ground, so an empty cell is simply
   nothing) and the hairlines move onto the cards: adjacent cards each cast 1px into the 1px
   gap, which reads as the same single hairline it always did. Scoped to this grid only —
   `.cards` is shared by the whole site and full rows there have no empty cells to show. */
.dwall__grid{background:var(--void)}
.dwall__grid > .dwc{box-shadow:0 0 0 1px var(--line)}
.dwc{position:relative;overflow:hidden;background:var(--ink);border:0;cursor:pointer;font:inherit;
  color:#fff;text-align:left;display:flex;flex-direction:column;gap:.7rem;
  padding:clamp(1.1rem,2.4vw,1.5rem);transition:background .25s}
.dwc:hover{background:var(--ink-2)}
.dwc:focus-visible{outline:2px solid var(--mint);outline-offset:-3px}
.dwc__top{display:flex;align-items:center;gap:.75rem}
.dwc__mono{width:42px;height:42px;border-radius:13px;flex:0 0 auto;display:flex;align-items:center;
  justify-content:center;font-family:'Satoshi',ui-sans-serif,sans-serif;font-weight:900;
  font-size:1.05rem;color:#02120c}
.dwc__names{min-width:0;display:flex;flex-direction:column}
.dwc__n{font-family:'Satoshi',ui-sans-serif,sans-serif;font-weight:900;font-size:1.02rem;
  letter-spacing:-.02em;line-height:1.15}
.dwc__s{font-size:.75rem;color:rgba(255,255,255,.42);margin-top:.18rem}
.dwc__why{margin:0;font-size:.86rem;line-height:1.55;color:rgba(255,255,255,.58)}
.dwc__caps{display:flex;flex-wrap:wrap;gap:.35rem}
.dwc__go{margin-top:auto;padding-top:.35rem;display:flex;align-items:center;gap:.5rem;
  color:var(--mint);font-weight:700;font-size:.8rem}
.dwc__goc{width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center}
.dwc__goc svg{width:14px;height:14px}
.dwc__gol{transition:transform .3s var(--e-out)}
.dwc:hover .dwc__gol{transform:translateX(2px)}
.dwc__rule{position:absolute;left:0;bottom:0;height:2px;width:0;transition:width .5s var(--e-out)}
.dwc:hover .dwc__rule{width:100%}
.dwall__none{grid-column:1/-1;background:var(--ink);margin:0;padding:clamp(1.4rem,3vw,2rem);
  font-size:.9rem;color:rgba(255,255,255,.55)}

/* ── the guided route, still one tap away ── */
.dwall__q,.dpicks__back{margin:clamp(1.3rem,3vw,2rem) 0 0;text-align:center}
.dwall__qb{min-height:44px;display:inline-flex;align-items:center;gap:.5rem;padding:.6rem 1.1rem;
  border:1px solid var(--line);border-radius:999px;background:transparent;color:rgba(255,255,255,.62);
  font-family:'Switzer',ui-sans-serif,system-ui,sans-serif;font-weight:600;font-size:.85rem;cursor:pointer;
  transition:color .2s,border-color .2s}
.dwall__qb:hover{color:#fff;border-color:var(--line-2)}
.dwall__qb:focus-visible{outline:2px solid var(--mint);outline-offset:2px}
.dwall__qa{width:16px;height:16px;display:inline-flex;align-items:center;justify-content:center}
.dwall__qa svg{width:14px;height:14px}

/* ── the plan segment inside the takeover ─────────────────────────────────────────────────
      Hidden below 560px on purpose: the exit control is the one thing on that bar that must
      never be crowded, and the wall's own segment is two taps away. Nothing is lost — the
      plan chosen on the wall is the plan the takeover opens at. */
.dfs__tools{margin-left:auto;display:flex;align-items:center}
.dfs__tier{display:flex;align-items:center;gap:.5rem}
.dfs__tierl{font-size:.66rem;font-weight:600;letter-spacing:.2em;text-transform:uppercase;
  color:rgba(255,255,255,.36)}
@media(max-width:560px){.dfs__tools{display:none}}

/* ── the hero, on a phone ─────────────────────────────────────────────────────────────────
   Measured 2026-08-24 at 390x844: 474px of hero before the first bot. The crumb repeats the
   nav a thumb-length above it, and the three meta pills repeat the h1 and the sub-line under
   it — so both are decoration at this width by §21's own test, and nothing they say is the
   only place it is said. Nothing above 700px changes. */
@media(max-width:700px){
  .dhero{padding-top:clamp(72px,10vh,96px);padding-bottom:clamp(14px,2.4vh,22px)}
  .dhero .crumb{display:none}
  .dhero__pills{display:none}
  .dhero__p{margin-top:.9rem;font-size:.95rem;line-height:1.5}
}

/* ── the card, on a phone ─────────────────────────────────────────────────────────────────
   Ten one-column cards is a long page. The capability chips are a scanning aid for a grid you
   are comparing across; in a single column you are reading one card at a time and the sentence
   above them already says it. Kept from 480px up, where two cards sit side by side. */
@media(max-width:479px){
  .dwc__caps{display:none}
  .dwc{gap:.55rem}
}
.dwall__near{grid-column:1/-1;background:var(--void);margin:0;padding:.9rem 0 .2rem;
  font-size:.7rem;font-weight:600;letter-spacing:.22em;text-transform:uppercase;
  color:rgba(255,255,255,.32)}

/* 🚨 THE PLAN SEGMENT WAS WHITE ON WHITE ─────────────────────────────────────────────────
   The takeover bar takes the tone of the bot inside it, and half the demo roster is light —
   Luxe Hair Studio, BrightSmile Dental, Revive Physio, SunHarvest Solar. `.dtier` was written
   for the void background of the wall, so on those four the label and three of the four plan
   buttons rendered at rgba(255,255,255,.55) on a bar that is rgba(255,255,255,.92). Measured,
   not guessed: only the active pill (mint) was visible, so the control read as a badge saying
   "Pro+" rather than a segment you could press.
   Every rule below is scoped to the takeover; the wall's own segment is unaffected. */
.dfs[data-tone="light"] .dfs__tierl{color:var(--paper-soft)}
.dfs[data-tone="light"] .dtier{border-color:rgba(2,36,25,.14);background:rgba(2,36,25,.03)}
.dfs[data-tone="light"] .dtier button{color:rgba(2,36,25,.62)}
.dfs[data-tone="light"] .dtier button:hover{color:var(--on-paper)}
.dfs[data-tone="light"] .dtier button.is-on{background:var(--on-paper);color:#fff}

/* ═══════════════════════════════════════════════════════════════════════════════════════════
   DDAI-IDEMO-V3 (2026-08-24) — THE TRADE PICKER AND THE TWO DEMO LEVELS

   Four questions became two screens. The trade is 41 real options, which is far too many for
   tiles and exactly right for a box you type into; the plan is two cards, because the whole
   point is that a visitor chooses which of the two demos they are being shown.
   ═══════════════════════════════════════════════════════════════════════════════════════════ */

.dqpick{position:relative;display:block;margin-top:clamp(1rem,2.4vw,1.5rem)}
.dqpick__box{position:relative}
.dqpick__i{padding-right:46px}
.dqpick__x{position:absolute;right:6px;top:50%;transform:translateY(-50%);width:34px;height:34px;
  display:inline-flex;align-items:center;justify-content:center;border:0;border-radius:999px;
  background:transparent;color:rgba(255,255,255,.5);cursor:pointer;transition:color .2s,background .2s}
.dqpick__x:hover{color:#fff;background:rgba(255,255,255,.07)}
.dqpick__x:focus-visible{outline:2px solid var(--mint);outline-offset:2px}
.dqpick__x svg{width:15px;height:15px}
.dqpick__x[hidden]{display:none}
.dqpick__l{position:absolute;left:0;right:0;z-index:8;margin:.35rem 0 0;padding:.3rem;list-style:none;
  max-height:min(46vh,320px);overflow-y:auto;-webkit-overflow-scrolling:touch;
  background:var(--ink-2);border:1px solid var(--line-2);border-radius:16px;
  box-shadow:0 26px 60px -24px #000}
.dqpick__l[hidden]{display:none}
.dqpick__o{min-height:44px;display:flex;align-items:center;padding:.6rem .85rem;border-radius:11px;
  font-size:.92rem;color:rgba(255,255,255,.78);cursor:pointer}
.dqpick__o:hover,.dqpick__o.is-on{background:rgba(79,216,166,.14);color:#fff}
.dqpick__none{padding:.75rem .85rem;font-size:.86rem;color:rgba(255,255,255,.45)}

/* ── the two demos ── */
.dqlvl{margin-top:clamp(1.3rem,3vw,2rem)}
.dqlvl__l{display:block;margin-bottom:.7rem;font-size:.7rem;font-weight:600;letter-spacing:.22em;
  text-transform:uppercase;color:rgba(255,255,255,.34)}
.dqopt__b{position:absolute;top:.7rem;right:.7rem;padding:.2rem .55rem;border-radius:999px;
  background:var(--mint);color:var(--on-mint);font-size:.62rem;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase}
.dqlvl--built{margin-top:clamp(1.1rem,2.4vw,1.5rem)}
.dbuilt__lvl{margin:.7rem 0 0;font-size:.84rem;line-height:1.55;color:rgba(255,255,255,.5);max-width:52ch}
.dbuilt__lvl b{color:var(--mint);font-weight:700}
.dbuilt__cta{align-items:center}

/* the ghost index numeral must not sit under the badge */
.dqopt__b + .dqopt__t{padding-right:0}
@media(max-width:520px){
  .dqopt__b{position:static;display:inline-block;margin-bottom:.5rem}
}

/* ══════════ 09 · DDAI-IDEMO-ONE (2026-09-03) — the one-screen builder ══════════
   Duval: "the website chatbot generate demo page could be made 100 times better easyier and
   prettier especialy the output". No steps, no rail, no Continue: the form on the left, the
   REAL widget on the right in a browser frame (th.css .dev — shared with the product pages),
   rebuilt on every change. Under 700px the frame becomes a phone under the form.
   ⚠ .dstage__slot carries its own absolute inset with !important: the runtime's own
     `.dd-render-slot{position:relative}` otherwise wins the tie (it loads later) and the slot
     is 0px tall — measured on the live page, that was the empty preview. */
.dq--one{padding-top:clamp(.6rem,2vw,1.6rem)}
.done{display:grid;gap:clamp(1.6rem,3.4vw,3rem);align-items:start}
@media(min-width:960px){.done{grid-template-columns:.86fr 1.14fr}}
.done__form{display:flex;flex-direction:column;gap:clamp(1rem,2vw,1.4rem)}
.done__trade{margin-top:0}
.dtiles{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);border:1px solid var(--line);
  border-radius:var(--rad);overflow:hidden;margin:.7rem 0 .8rem}
@media(max-width:520px){.dtiles{grid-template-columns:repeat(3,1fr)}}
.dtile{position:relative;background:var(--ink);border:0;color:rgba(255,255,255,.78);cursor:pointer;font:inherit;
  font-family:'Switzer',ui-sans-serif,system-ui,sans-serif;font-weight:600;font-size:.76rem;letter-spacing:-.005em;
  min-height:74px;padding:.75rem .4rem;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.4rem;
  text-align:center;transition:background .25s var(--e-soft),color .25s}
.dtile:hover{background:var(--ink-2);color:#fff}
.dtile.is-on{background:var(--ink-3);color:#fff;box-shadow:inset 0 0 0 1px var(--mint)}
.dtile:focus-visible{outline:2px solid var(--mint);outline-offset:-3px}
.dtile__g{width:30px;height:30px;border-radius:50%;display:grid;place-items:center;background:rgba(52,245,173,.1);color:var(--mint)}
.dtile__g svg{width:14px;height:14px}
.dtile.is-on .dtile__g{background:var(--mint);color:#02241A}
.done__look{display:grid;grid-template-columns:auto 1fr;gap:1rem;align-items:center}
@media(max-width:520px){.done__look{grid-template-columns:1fr}}
.dqtone--sm{margin:0;border-radius:14px}
.dqtone--sm .dqtone__b{padding:.55rem .6rem .6rem;display:flex;align-items:center;gap:.6rem;min-width:110px}
.dqtone--sm .dqtone__sw{height:26px;width:34px;margin:0;border-radius:8px;flex:none}
.dqtone--sm .dqtone__n{font-size:.86rem}
.done__look .dqcols{margin-top:0}
.done__look .dqcol{width:40px;height:40px;border-radius:11px}
.done__look .dqcol__i{border-radius:7px}
.done__form .dqlvl{margin-top:0}
/* the stage */
.done__stage{position:relative}
@media(min-width:960px){.done__stage{position:sticky;top:84px}}
.dstage{position:relative;perspective:1600px;perspective-origin:30% 40%}
.dstage__desk{position:relative;aspect-ratio:16/11.5;transform:rotateY(-5deg) rotateX(1.5deg);transform-origin:50% 50%;
  transition:transform .8s var(--e-soft)}
.dstage:hover .dstage__desk,.dstage:focus-within .dstage__desk{transform:none}
.dstage__desk .dev__screen{font-size:clamp(7px,.72vw,10px)}
.dstage__site{position:absolute;inset:0;z-index:1}
.dstage[data-tone="light"] .dev__screen{background:#fff}
.dstage__slot{position:absolute !important;inset:0 !important;height:100% !important;z-index:2}
/* the widget's own preview mode draws a full-width window; in a browser frame it sits where a
   real widget sits — bottom right, not over the whole site. 3-class selectors beat the runtime's
   2-class !important rules. */
.dstage__desk .dd-render-slot .dd-window{width:min(50%,360px) !important;height:calc(100% - 56px) !important;max-height:calc(100% - 56px) !important;
  right:12px !important;bottom:48px !important;left:auto !important;top:auto !important;border-radius:16px !important}
.dstage__desk .dd-render-slot .dd-button{bottom:6px !important;right:12px !important;transform:scale(.8);transform-origin:100% 100%}
.dstage__desk .dd-render-slot .dd-popup{right:12px !important;bottom:56px !important}
.dstage__phone{display:none;position:relative;left:auto;bottom:auto;width:min(66%,250px);margin:0 auto;transform:none;aspect-ratio:9/19.2}
.dstage__phone .dev__screen{font-size:clamp(9px,2.9vw,11.5px)}
.dstage__cap{margin:1.1rem 0 0;font-size:.84rem;line-height:1.55;color:rgba(255,255,255,.5)}
.dstage__cap b{color:#fff;font-weight:700}
.done__stage .dbuilt__cta{margin-top:1.2rem}
@media(max-width:700px){
  .dstage{perspective:none}
  .dstage__desk{display:none}
  .dstage__phone{display:block;width:min(58%,220px)}
  /* the RESULT first on a phone — Duval: "especially the output" — then the form under it */
  .done__stage{order:-1;margin-top:0}
  .dstage__cap{text-align:center;font-size:.8rem}
  .done__stage .dbuilt__cta{justify-content:center}
}
@media(prefers-reduced-motion:reduce){.dstage__desk{transform:none;transition:none}}

/* the takeover's stand-in, when it is the visitor's own site (siteNode) rather than the bars */
.dsite--real .dsite__nav,.dsite--real .dsite__mid,.dsite--real .dsite__foot{display:none}
.dsite__real{position:absolute;left:0;right:0;top:calc(58px + env(safe-area-inset-top));bottom:0;font-size:clamp(10px,1.05vw,15px)}
.dsite__real .msite__hero{max-width:min(62%,60ch)}
.dsite__real .msite__hero p{margin-top:1em}
.dsite__real .msite__cards{margin-top:auto}
@media(max-width:700px){.dsite__real{font-size:clamp(9px,2.6vw,11px)}.dsite__real .msite__hero{max-width:none}}

/* ══════════ 10 · DDAI-DEMOS-FRAMES (2026-09-03) — the wall card is a phone with the bot in it ══════════ */
.dwc{cursor:default}
.dwc__frame{position:relative;width:100%;aspect-ratio:9/15.2;margin:.25rem 0 .1rem;border-radius:26px;overflow:hidden;
  background:#050807;border:1px solid rgba(255,255,255,.18);box-shadow:inset 0 0 0 3px #0A0E0C,0 30px 60px -40px rgba(0,0,0,.9)}
.dwc__frame[data-tone="light"]{background:#fff}
.dwc__notch{position:absolute;top:9px;left:50%;translate:-50% 0;width:34%;height:16px;border-radius:999px;background:#000;z-index:3}
.dwc__frame[data-tone="light"] .dwc__notch{background:#0A0E0C}
.dwc__screen{position:absolute;inset:3px;border-radius:23px;overflow:hidden}
/* the runtime's preview mode sets the slot position:relative with no height; the inset wins */
.dwc__slot{position:absolute !important;inset:0 !important;height:100% !important;pointer-events:none}
.dwc__slot .dd-window{top:36px !important;height:auto !important;max-height:none !important}
.dwc__tap{position:absolute;inset:0;z-index:4;background:none;border:0;cursor:pointer;border-radius:26px}
.dwc__tap:focus-visible{outline:2px solid var(--mint);outline-offset:2px}
.dwc__go{display:flex;align-items:center;gap:.5rem;margin-top:auto;padding:.35rem 0 0;border:0;background:none;
  color:var(--mint);font:inherit;font-weight:700;font-size:.8rem;cursor:pointer;text-align:left}
.dwc__go:focus-visible{outline:2px solid var(--mint);outline-offset:3px;border-radius:6px}
.dwc:hover .dwc__frame{border-color:rgba(255,255,255,.3)}
@media(max-width:639px){
  .dwall__grid{grid-template-columns:1fr 1fr}
  .dwc{padding:.75rem;gap:.5rem}
  .dwc__why,.dwc__caps{display:none}
  .dwc__mono{width:32px;height:32px;border-radius:10px;font-size:.9rem}
  .dwc__n{font-size:.86rem}
  .dwc__s{font-size:.68rem}
  .dwc__frame{aspect-ratio:9/14;border-radius:18px}
  .dwc__screen{border-radius:15px}
  .dwc__notch{height:12px;width:32%}
  .dwc__go{font-size:.74rem}
}

/* ═══ DDAI-DEMO-PAPER-V9 — generated by _demo_retone.js, do not edit by hand ═══ */
/* 92 rules generated from the 48 KB base on 2026-09-13 */
.dq[data-tone=paper]{background:var(--paper)}
[data-tone=paper] .dqrail__bar i{box-shadow:0 0 18px rgba(79,216,166,0.30)}
[data-tone=paper] .dqrail__lbl{color:rgba(4,36,25,.62)}
[data-tone=paper] .dqrail__lbl b{color:var(--emerald-ink)}
[data-tone=paper] .dqrail__lbl span{color:var(--paper-soft)}
[data-tone=paper] .dqstep__h{color:var(--on-paper)}
[data-tone=paper] .dqstep__p{color:var(--paper-soft)}
[data-tone=paper] .dqopt{background:#fff}
[data-tone=paper] .dqopt:hover{background:var(--paper-2)}
[data-tone=paper] .dqopt:focus-visible{outline:2px solid var(--emerald-ink)}
[data-tone=paper] .dqopt__n{color:var(--ghost)}
[data-tone=paper] .dqopt__t{color:var(--on-paper)}
[data-tone=paper] .dqopt__g{color:var(--emerald-ink)}
[data-tone=paper] .dqopt__d{color:rgba(4,36,25,.62)}
[data-tone=paper] .dqopt.is-on{background:#fff}
[data-tone=paper] .dqopt.is-on .dqopt__n{color:var(--emerald-ink)}
[data-tone=paper] .dqtone__b{background:#fff;color:var(--on-paper)}
[data-tone=paper] .dqtone__b:hover{background:var(--paper-2)}
[data-tone=paper] .dqtone__b.is-on{background:#fff}
[data-tone=paper] .dqtone__b:focus-visible{outline:2px solid var(--emerald-ink)}
[data-tone=paper] .dqtone__d{color:rgba(4,36,25,.62)}
[data-tone=paper] .dqcol.is-on{border-color:var(--on-paper)}
[data-tone=paper] .dqcol:focus-visible{outline:2px solid var(--emerald-ink)}
[data-tone=paper] .dqf{background:var(--paper-2)}
[data-tone=paper] .dqf__l{color:var(--paper-soft)}
[data-tone=paper] .dqf__i{background:#fff;color:var(--on-paper)}
[data-tone=paper] .dqf__i::placeholder{color:rgba(4,36,25,.62)}
[data-tone=paper] .dqf__i:focus{border-color:var(--emerald-ink);box-shadow:0 0 0 3px rgba(79,216,166,0.10)}
[data-tone=paper] .dqf__h{color:rgba(4,36,25,.62)}
[data-tone=paper] .dqnav{background:linear-gradient(0deg,rgba(242,247,244,.97) 60%,rgba(242,247,244,0))}
[data-tone=paper] .dqerr{color:#B42318}
[data-tone=paper] .dbuilt__h{color:var(--on-paper)}
[data-tone=paper] .dbuilt__p{color:var(--paper-soft)}
[data-tone=paper] .dbchip{color:var(--paper-soft);background:rgba(2,36,25,0.032)}
[data-tone=paper] .dmini{background:#fff}
[data-tone=paper] .dmini__dot{background:rgba(2,36,25,0.120)}
[data-tone=paper] .dmini__url{color:rgba(4,36,25,.62)}
[data-tone=paper] .dmini__cap{color:rgba(4,36,25,.62)}
[data-tone=paper] .dpick{background:#fff}
[data-tone=paper] .dpick__mono{color:var(--on-paper)}
[data-tone=paper] .dpick__n{color:var(--on-paper)}
[data-tone=paper] .dpick__s{color:rgba(4,36,25,.62)}
[data-tone=paper] .dpick__why{color:var(--paper-soft)}
[data-tone=paper] .dpick__why b{color:var(--emerald-ink)}
[data-tone=paper] .dcap{color:var(--paper-soft)}
[data-tone=paper] .dall__h{color:rgba(4,36,25,.62)}
[data-tone=paper] .dallb{background:#fff;color:var(--on-paper)}
[data-tone=paper] .dallb:hover{background:var(--paper-2)}
[data-tone=paper] .dallb:focus-visible{outline:2px solid var(--emerald-ink)}
[data-tone=paper] .dallb__s{color:rgba(4,36,25,.62)}
[data-tone=paper] .dfil{color:var(--paper-soft)}
[data-tone=paper] .dfil:hover{color:var(--on-paper)}
[data-tone=paper] .dfil.is-on{border-color:var(--emerald-ink)}
[data-tone=paper] .dfil:focus-visible{outline:2px solid var(--emerald-ink)}
[data-tone=paper] .dwall__tl{color:rgba(4,36,25,.62)}
[data-tone=paper] .dtier{background:rgba(2,36,25,0.032)}
[data-tone=paper] .dtier button{color:var(--paper-soft)}
[data-tone=paper] .dtier button:hover{color:var(--on-paper)}
[data-tone=paper] .dtier button:focus-visible{outline:2px solid var(--emerald-ink)}
[data-tone=paper] .dwall__note{color:var(--paper-soft)}
[data-tone=paper] .dwall__note b{color:var(--emerald-ink)}
[data-tone=paper] .dwall__grid{background:var(--paper)}
[data-tone=paper] .dwc{background:#fff;color:var(--on-paper)}
[data-tone=paper] .dwc:hover{background:var(--paper-2)}
[data-tone=paper] .dwc:focus-visible{outline:2px solid var(--emerald-ink)}
[data-tone=paper] .dwc__s{color:rgba(4,36,25,.62)}
[data-tone=paper] .dwc__why{color:var(--paper-soft)}
[data-tone=paper] .dwc__go{color:var(--emerald-ink)}
[data-tone=paper] .dwall__none{background:#fff;color:var(--paper-soft)}
[data-tone=paper] .dwall__qb{color:var(--paper-soft)}
[data-tone=paper] .dwall__qb:hover{color:var(--on-paper)}
[data-tone=paper] .dwall__qb:focus-visible{outline:2px solid var(--emerald-ink)}
[data-tone=paper] .dwall__near{background:var(--paper);color:rgba(4,36,25,.62)}
[data-tone=paper] .dqpick__x{color:var(--paper-soft)}
[data-tone=paper] .dqpick__x:hover{color:var(--on-paper);background:rgba(2,36,25,0.112)}
[data-tone=paper] .dqpick__x:focus-visible{outline:2px solid var(--emerald-ink)}
[data-tone=paper] .dqpick__l{background:var(--paper-2);box-shadow:0 26px 60px -24px rgba(2,36,25,.22)}
[data-tone=paper] .dqpick__o{color:var(--paper-soft)}
[data-tone=paper] .dqpick__o:hover,[data-tone=paper] .dqpick__o.is-on{color:var(--on-paper)}
[data-tone=paper] .dqpick__none{color:rgba(4,36,25,.62)}
[data-tone=paper] .dqlvl__l{color:rgba(4,36,25,.62)}
[data-tone=paper] .dbuilt__lvl{color:var(--paper-soft)}
[data-tone=paper] .dbuilt__lvl b{color:var(--emerald-ink)}
[data-tone=paper] .dtile{background:#fff;color:var(--paper-soft)}
[data-tone=paper] .dtile:hover{background:var(--paper-2);color:var(--on-paper)}
[data-tone=paper] .dtile.is-on{background:#fff;color:var(--on-paper);box-shadow:inset 0 0 0 1px var(--emerald-ink)}
[data-tone=paper] .dtile:focus-visible{outline:2px solid var(--emerald-ink)}
[data-tone=paper] .dtile__g{color:var(--emerald-ink)}
[data-tone=paper] .dstage__cap{color:var(--paper-soft)}
[data-tone=paper] .dstage__cap b{color:var(--on-paper)}
[data-tone=paper] .dwc__go{color:var(--emerald-ink)}
[data-tone=paper] .dwc__go:focus-visible{outline:2px solid var(--emerald-ink)}
/* ── by hand (V9): the ground, the chosen states, the fields, the wall, the deep chapter ── */
.dq[data-tone=paper],.dq--one[data-tone=paper]{background:var(--paper);color:var(--on-paper)}
/* the chosen option / swatch / tile: an emerald edge on white — the ink-3 lift is invisible on paper */
[data-tone=paper] .dqopt.is-on,[data-tone=paper] .dqtone__b.is-on,[data-tone=paper] .dtile.is-on{background:#fff;box-shadow:inset 0 0 0 1px var(--emerald-ink)}
[data-tone=paper] .dqtone__b[data-v="light"] .dqtone__sw{border-color:var(--line-ink-2)}
/* fields: white on paper, dark ink, an emerald focus */
[data-tone=paper] .dqf{background:var(--paper)}
[data-tone=paper] .dqf__i{background:#fff;color:var(--on-paper);border-color:var(--line-ink-2)}
[data-tone=paper] .dqf__i::placeholder{color:rgba(4,36,25,.42)}
[data-tone=paper] .dqf__i:focus{border-color:var(--emerald-ink);box-shadow:0 0 0 3px rgba(79,216,166,.25)}
/* the trade list: a white sheet */
[data-tone=paper] .dqpick__l{background:#fff;border-color:var(--line-ink-2);box-shadow:0 26px 60px -24px rgba(2,36,25,.35)}
/* the phone's pinned Continue bar: a paper scrim, not a black one; back in the flow from 900px */
[data-tone=paper] .dqnav{background:linear-gradient(0deg,rgba(242,247,244,.97) 60%,rgba(242,247,244,0));border-top-color:var(--line-ink)}
@media(min-width:900px){[data-tone=paper] .dqnav{background:none;border-top:0}}
/* the wall: the page's own ground behind an empty cell (the "card that failed to load" trap) */
[data-tone=paper] .dwall__grid,[data-tone=paper] .dwall__near{background:var(--paper)}
[data-tone=paper] .dwall__grid > .dwc{box-shadow:0 0 0 1px var(--line-ink)}
/* the phone on a white card: a soft ink shadow instead of a white hairline */
[data-tone=paper] .dwc__frame{border-color:rgba(2,36,25,.12);box-shadow:inset 0 0 0 3px #0A0E0C,0 24px 50px -34px rgba(2,36,25,.45)}
[data-tone=paper] .dwc:hover .dwc__frame{border-color:rgba(2,36,25,.22)}
/* the stage caption under the browser frame */
[data-tone=paper] .dstage__cap{color:var(--paper-soft)} [data-tone=paper] .dstage__cap b{color:var(--on-paper)}
/* the CHOSEN filter chip and plan pill are mint fills: their ink is on-mint, and it must outrank the
   generated ".dfil / .dtier button" inks above (same specificity, later in the sheet — contrastcheck
   measured 3.69:1 on "All 10" and "Pro+" before this line) */
[data-tone=paper] .dfil.is-on,[data-tone=paper] .dtier button.is-on{color:var(--on-mint)}
/* every micro label at 12 px or more, and every plan pill a 40 px tap (_audit4's floors) */
[data-tone=paper] .dqf__h,[data-tone=paper] .dcap,[data-tone=paper] .dqlvl__l,[data-tone=paper] .dwall__tl,[data-tone=paper] .dqrail__lbl,[data-tone=paper] .dallb__s,[data-tone=paper] .dmini__url,[data-tone=paper] .dall__h{font-size:.76rem}
[data-tone=paper] .dtier button{min-height:40px}
@media(max-width:639px){[data-tone=paper] .dwc__s{font-size:.76rem}}
/* the info chapter: DEEP — the page's consequences on the spine's dark green; its faint inks lifted */
.dinfo[data-tone=deep]{background:linear-gradient(168deg,#0A4A34 0%,var(--deep) 48%,#042A1E 100%)}
[data-tone=deep] .dinfo__c{background:var(--card)}
[data-tone=deep] .dinfo__grid{background:var(--line);border-color:var(--line)}
[data-tone=deep] .dinfo__d{color:rgba(255,255,255,.72)}
[data-tone=deep] .dinfo__note{color:rgba(255,255,255,.66)}
/* ═══ /DDAI-DEMO-PAPER-V9 ═══ */
