/* Linkrra Landing — Dark theme, pure CSS, < 50KB gzipped */
:root{
  --bg:#050608;--bg2:#0a0b0f;--card:#0d0e13;--card2:#0a0b10;
  --line:#1c1d24;--line2:#15161b;
  --ink:#f3f4f7;--mut:#8f929c;--mut2:#5c5e67;
  --acc:#5b86ff;--acc2:#7aa2ff;--teal:#16b89a;--gold:#e0a83c;--red:#e85d6c;--green:#3ed598;
  --purple:#a855f7;--purple2:#c084fc;
  --grad1:linear-gradient(135deg,#5b86ff 0%,#a855f7 100%);
  --grad2:linear-gradient(135deg,#7aa2ff 0%,#c084fc 100%);
  --grad-bg:radial-gradient(ellipse at top,color-mix(in srgb, var(--ink) 3%, transparent) 0%,transparent 60%);
  --radius:16px;--radius-sm:10px;
  --maxw:1080px;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}

/* === APP SHELL (ChatGPT/Gemini-style entry) === */
.app-shell{display:flex;min-height:100vh;position:relative;z-index:1}
.sidebar{
  width:260px;flex:0 0 260px;background:var(--bg2);border-right:1px solid var(--line);
  padding:20px 14px;display:flex;flex-direction:column;gap:4px;
  /* Mobile drawer: the menu is taller than many viewports (brand + links +
   * recents + products). Without its own scroll the bottom items — Build,
   * Docs, the footer — get clipped behind the browser bar. */
  overflow-y:auto;overscroll-behavior:contain;
}
.sidebar-brand{display:flex;align-items:center;gap:8px;font-weight:700;font-size:16px;padding:8px 10px 20px}
/* The X on a recents row must never collide with the brand or the edge:
   a 30px square hit area (Apple's floor is 44px, 30px is the pragmatic
   compromise inside a 13px row), visually centered, with breathing room
   from the row edge. */
@media (max-width:900px){
  .sidebar-brand{padding:10px 10px 22px}
}
/* The mark, not a dot. Until 2026-08-19 this header rendered a gradient circle —
   the company's actual logo (the node glyph the main site uses) appeared nowhere
   on this property. The SVG inherits currentColor so it reads on both themes. */
.sidebar-brand .brand-mark{display:inline-flex;color:var(--ink);flex:none}
.sidebar-brand .brand-mark svg{display:block}
.sidebar-brand .brand-word{font-weight:500;letter-spacing:-.01em}
.sidebar-brand .brand-word b{font-weight:700}
/* Kept so an older cached page does not render a stray unstyled span. */
.sidebar-brand .dot{width:10px;height:10px;border-radius:50%;background:var(--grad1);display:inline-block}
.sidebar-link{
  display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:var(--radius-sm);
  color:var(--mut);font-size:14px;font-weight:500;transition:background .15s,color .15s;
}
.sidebar-link:hover{background:var(--card);color:var(--ink)}
.sidebar-link .ic{font-size:16px;width:20px;text-align:center}
.sidebar-spacer{flex:1}
.sidebar-foot{border-top:1px solid var(--line);padding-top:12px;margin-top:8px}
.app-main{flex:1;min-width:0;display:flex;flex-direction:column}
.app-topbar{display:flex;justify-content:flex-end;align-items:center;gap:10px;padding:18px 28px}
/* Below 900px the sidebar (and with it, the only brand mark on the page)
   goes off-canvas, leaving the topbar as a hamburger and two buttons floating
   on an empty background — the page reads as unbranded, not just collapsed.
   Hidden on desktop, where the sidebar already carries the brand. */
.topbar-brand{display:none;align-items:center;gap:7px;font-weight:700;font-size:15px;color:var(--ink);margin-right:auto}
.topbar-brand .brand-mark{display:inline-flex;color:var(--ink);flex:none}
.topbar-brand .brand-mark svg{display:block}
.topbar-brand .brand-word{font-weight:500;letter-spacing:-.01em}
.topbar-brand .brand-word b{font-weight:700}
@media (max-width:900px){.topbar-brand{display:flex}}
.app-hero{
  flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;
  padding:40px 20px 60px;text-align:center;min-height:70vh;
}
.app-hero-mark{
  width:56px;height:56px;border-radius:50%;background:var(--grad1);margin-bottom:24px;
  box-shadow:none;
}
.app-hero h1{font-size:clamp(28px,4.2vw,42px);font-weight:800;letter-spacing:-.03em;margin-bottom:28px}
/* Models-first landing (T-1139): the catalog itself is the hero, so it needs
   to start near the top and breathe, not sit centered in 70vh like the old
   single-line chat prompt did. */
.app-hero-models{justify-content:flex-start;min-height:0;padding-top:48px;width:100%}
.app-hero-models h1{margin-bottom:10px}
.app-hero-sub{font-size:15px;color:var(--mut);max-width:560px;margin-bottom:28px}
.app-hero-models .models-grid{margin-bottom:22px}
.app-input-form{
  width:100%;max-width:680px;display:flex;align-items:center;gap:10px;
  background:var(--card);border:1px solid var(--line);border-radius:28px;
  padding:8px 8px 8px 22px;
}
.app-input-form:focus-within{border-color:var(--acc)}
.app-input-form input,.app-input-form textarea{
  flex:1;background:transparent;border:0;outline:0;color:var(--ink);font-size:15px;
  font-family:inherit;padding:10px 0;
}
.app-input-form textarea{
  resize:none;max-height:200px;line-height:1.4;overflow-y:auto;
}
.app-input-form input::placeholder,.app-input-form textarea::placeholder{color:var(--mut2)}
.app-input-form button{
  width:40px;height:40px;border-radius:50%;border:0;background:var(--grad1);color:#fff;
  font-size:16px;cursor:pointer;flex:0 0 auto;display:flex;align-items:center;justify-content:center;
  transition:opacity .15s;
}
.app-input-form button:hover{opacity:.88}
.app-chips{display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin-top:22px;max-width:680px}
.chip{
  display:inline-flex;align-items:center;gap:7px;
  background:var(--card);border:1px solid var(--line);color:var(--mut);border-radius:999px;
  padding:9px 16px;font-size:13px;font-weight:600;cursor:pointer;font-family:inherit;
  transition:border-color .15s,color .15s;
}
.chip:hover{border-color:var(--acc);color:var(--ink)}
.chip svg{flex:0 0 auto}
.sidebar-link .ic svg{display:block}
.step-icon svg{display:inline-block}
/* collapsible sidebar (desktop) */
.sidebar-toggle{
  display:none;align-items:center;justify-content:center;margin-right:auto;
  background:none;border:1px solid var(--line);border-radius:var(--radius-sm);
  color:var(--mut);cursor:pointer;padding:7px;line-height:0;
  transition:color .15s,border-color .15s,background .15s;
}
.sidebar-toggle:hover{color:var(--ink);border-color:var(--acc);background:var(--card)}
.sidebar-toggle svg{display:block}
@media (min-width:901px){
  .sidebar-toggle{display:inline-flex}
  .sidebar{transition:width .2s ease,flex-basis .2s ease,padding .2s ease,border-color .2s ease}
  html.sidebar-collapsed .sidebar{
    width:0;flex:0 0 0;padding-left:0;padding-right:0;border-right-color:transparent;overflow:hidden;
  }
}
@media (max-width:900px){
  .sidebar{
    position:fixed;left:0;top:0;bottom:0;transform:translateX(-100%);transition:transform .2s;z-index:100;
    padding-top:max(20px,env(safe-area-inset-top));
    padding-bottom:max(20px,env(safe-area-inset-bottom));
  }
  .sidebar.open{transform:translateX(0)}
  .app-topbar{padding-left:60px;padding-top:max(18px,env(safe-area-inset-top))}

  /* iOS Safari zooms the whole page when a focused field is under 16px, and
   * it does not zoom back out. That is why the layout "jumps and stops being
   * centered" the moment you tap the chat box — not a layout bug, a font-size
   * one. 16px is the threshold, so every field gets it on small screens. */
  input,select,textarea,.app-input-form input{font-size:16px}
}

/* Tapping beside an open drawer must close it. */
.sidebar-backdrop{
  position:fixed;inset:0;background:rgba(0,0,0,.5);z-index:99;
  opacity:0;transition:opacity .2s;
}
.sidebar-backdrop.show{opacity:1}
@media (min-width:901px){.sidebar-backdrop{display:none}}

/* === PAY AS YOU GO === */
.payg{border:1px solid var(--line);border-radius:var(--radius);background:var(--card);padding:28px}
.payg-head h2{font-size:22px;font-weight:800;letter-spacing:-.02em;margin-bottom:6px}
.payg-head p{color:var(--mut);font-size:14px}
.payg-body{display:flex;gap:32px;flex-wrap:wrap;margin-top:22px;align-items:flex-start}
.payg-rate{flex:1 1 240px;min-width:220px}
.payg-rate-num{font-size:clamp(26px,3.4vw,34px);font-weight:800;letter-spacing:-.03em;line-height:1.2}
.payg-per{font-size:14px;font-weight:600;color:var(--mut);letter-spacing:0}
.payg-rate-note{font-size:12.5px;color:var(--mut2);margin-top:10px;line-height:1.55;max-width:34ch}
.payg-buy{flex:1 1 280px;min-width:260px}
.payg-label{display:block;font-size:12px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--mut2);margin-bottom:8px}
.payg-amounts{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:10px}
.payg-amount{
  background:var(--card2);border:1px solid var(--line);color:var(--mut);border-radius:999px;
  padding:8px 16px;font-size:13px;font-weight:700;cursor:pointer;font-family:inherit;
  transition:border-color .15s,color .15s;
}
.payg-amount:hover{color:var(--ink)}
.payg-amount.is-selected{border-color:var(--acc);color:var(--ink)}
.payg-input{
  /* 16px is the iOS Safari zoom-on-focus threshold — below it, tapping this
     field zooms the whole page in on every mobile visit. */
  width:100%;padding:12px 14px;border-radius:var(--radius-sm);border:1px solid var(--line);
  background:var(--bg2);color:var(--ink);font-size:16px;font-family:inherit;
}
.payg-input:focus{outline:0;border-color:var(--acc)}
.payg-gets{font-size:13.5px;color:var(--mut);margin:10px 0 14px;min-height:20px}
.payg-gets strong{color:var(--ink)}
.payg-cta{width:100%;justify-content:center}
.payg-cta[disabled]{opacity:.55;cursor:not-allowed}
.payg-status{font-size:13px;margin-top:10px;min-height:18px;color:var(--mut)}
.payg-status.is-error{color:var(--red)}
.payg-facts{list-style:none;margin-top:24px;padding-top:20px;border-top:1px solid var(--line);
  display:grid;gap:8px}
.payg-facts li{font-size:13px;color:var(--mut);padding-left:18px;position:relative}
.payg-facts li::before{content:'';position:absolute;left:0;top:8px;width:6px;height:6px;
  border-radius:50%;background:var(--acc);opacity:.7}

/* === SIGN IN === */
.signin-card{
  width:100%;max-width:400px;border:1px solid var(--line);border-radius:var(--radius);
  background:var(--card);padding:32px;text-align:center;
}
.google-btn{
  display:flex;align-items:center;justify-content:center;gap:10px;width:100%;
  padding:12px 18px;border-radius:var(--radius-sm);border:1px solid var(--line);
  background:var(--ink);color:var(--bg);font-size:15px;font-weight:700;font-family:inherit;
  cursor:pointer;transition:opacity .15s;
}
.google-btn:hover{opacity:.9;color:var(--bg)}
.google-btn svg{flex:0 0 auto}
/* Sign in with Apple. Apple's Human Interface Guidelines require its button to
   be no less prominent than any other sign-in option, so it shares the exact
   geometry of the Google button and differs only in fill. */
.apple-btn{
  display:flex;align-items:center;justify-content:center;gap:10px;width:100%;
  padding:12px 18px;border-radius:var(--radius-sm);border:1px solid var(--ink);
  background:var(--bg);color:var(--ink);font-size:15px;font-weight:700;font-family:inherit;
  cursor:pointer;transition:opacity .15s;margin-top:10px;
}
.apple-btn:hover{opacity:.85;color:var(--ink)}
.apple-btn svg{flex:0 0 auto}
/* Both buttons set display:flex, which beats the [hidden] attribute — so a
   provider the server does not have (Apple, today) was drawn anyway and led to
   a 503. The attribute has to win. */
.google-btn[hidden],.apple-btn[hidden]{display:none}
.google-btn:focus-visible,.apple-btn:focus-visible{outline:2px solid var(--acc);outline-offset:2px}
.signin-card .signin-title{
  font-family:var(--font-display);font-size:24px;font-weight:600;letter-spacing:-.02em;
  line-height:1.2;margin:0 0 8px;
}
.signin-sub{color:var(--mut);font-size:14px;line-height:1.5;margin:0 0 24px}
.signin-note{font-size:12.5px;color:var(--mut2);margin-top:16px;line-height:1.6}
.signin-credit{color:var(--mut);margin-top:14px}
.signin-note-alt{border-top:1px solid var(--line);padding-top:16px;margin-top:20px}
/* The card sits a fixed distance under the top bar on both pages that show it.
   Centring it in .app-main put it low and against the fold on a short window,
   because .app-main is as tall as the sidebar, not as tall as the viewport. */
.app-hero.signin-hero{justify-content:flex-start;min-height:0;padding:clamp(40px,10vh,120px) 20px 60px}
/* account.html, signed out: the sign-in card is the page. (-8px: the section
   above it already contributes 8px, so both pages land on the same line.) */
.acct-signin{display:flex;justify-content:center;padding:calc(clamp(48px,14vh,140px) - 8px) 0 0}
/* Account states must remain exclusive even when component layouts use flex. */
#acctSignedOut[hidden],#acctSignedIn[hidden],#acctLoadState[hidden],#keyReveal[hidden],
#acctRetry[hidden],#acctKeysRetry[hidden]{display:none!important}
.acct-load-state{max-width:760px;padding:24px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card)}
.acct-load-state p{margin:0;color:var(--mut);line-height:1.6}
.acct-load-state .btn-lg{margin-top:16px}
.signin-error{
  font-size:13px;color:var(--red);border:1px solid var(--red);border-radius:var(--radius-sm);
  padding:10px 12px;margin-bottom:18px;display:none;
}

/* login.html only — scoped to .signin-wrap/.signin-intro/.signin-eyebrow/
   .signin-feats/.signin-trust, none of which account.html's card uses, so
   account.html's signed-out layout is untouched by anything below. */
.signin-wrap{
  display:flex;align-items:center;justify-content:center;gap:64px;width:100%;max-width:900px;
}
.signin-eyebrow{
  font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--mut2);margin:0 0 10px;
}
.signin-card .signin-eyebrow{text-align:center}
/* Desktop-only context panel so the card isn't the only thing on a wide
   screen with nothing to explain what it's for. Mirrors (doesn't repeat
   verbatim) the card's own trust copy, so neither reads redundant.
   Same 981px split used elsewhere for mine/desktop cross-fade (.bc-mine). */
.signin-intro{display:none;max-width:360px;text-align:left}
.signin-intro-title{
  font-family:var(--font-display);font-weight:600;letter-spacing:-.02em;
  font-size:clamp(26px,2.6vw,32px);line-height:1.25;margin:0 0 20px;color:var(--ink);
  text-wrap:balance;
}
.signin-feats{list-style:none;display:grid;gap:14px}
.signin-feats li{display:flex;align-items:flex-start;gap:10px;font-size:14px;color:var(--mut);line-height:1.45}
.signin-feats svg{flex:none;margin-top:2px;color:var(--mut2)}
@media (min-width:981px){
  .signin-intro{display:block}
  .app-hero.signin-hero{padding-top:clamp(56px,14vh,140px)}
}
.signin-trust{
  display:flex;align-items:flex-start;gap:7px;font-size:12.5px;color:var(--mut);
  line-height:1.6;margin-top:18px;text-align:left;
}
.signin-trust svg{flex:none;margin-top:2px;opacity:.8}
/* Below ~360px "Continue with Google/Apple" wraps to two lines at the
   default 15px/32px-padding sizing — tighten both so it stays on one line
   down to a 320px viewport. */
@media (max-width:360px){
  .signin-card{padding:24px 18px}
  .google-btn,.apple-btn{font-size:14px;padding:12px 10px}
}
.account-chip{
  display:inline-flex;align-items:center;gap:8px;padding:6px 12px 6px 6px;border-radius:999px;
  border:1px solid var(--line);background:var(--card);color:var(--ink);font-size:13px;font-weight:600;
}
.account-chip img{width:24px;height:24px;border-radius:50%;display:block}

/* === SUBPAGE CONTENT (pricing/models/miners/how-it-works/register) === */
.app-content{flex:1;padding:0 0 60px}
.subpage-head{padding:56px 28px 8px;max-width:720px}
.subpage-head h1{font-size:clamp(26px,4vw,34px);font-weight:800;letter-spacing:-.02em;margin-bottom:10px}
.subpage-head p{font-size:15px;color:var(--mut)}
body{
  font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;
  background:var(--bg);color:var(--ink);line-height:1.6;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
body::before{content:'';position:fixed;inset:0;background:var(--grad-bg);pointer-events:none;z-index:0}
a{color:var(--acc2);text-decoration:none}
a:hover{color:var(--ink)}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px;position:relative;z-index:1}

/* === HEADER === */
header{
  position:sticky;top:0;z-index:50;
  background:color-mix(in srgb, var(--bg) 82%, transparent);backdrop-filter:blur(14px);
  border-bottom:1px solid var(--line);
}
header .wrap{display:flex;align-items:center;justify-content:space-between;height:60px}
.brand{font-weight:700;font-size:18px;letter-spacing:-.02em;display:flex;align-items:center;gap:8px}
.brand .dot{width:10px;height:10px;border-radius:50%;background:var(--ink);display:inline-block}
.brand small{color:var(--mut);font-weight:400;font-size:12px}
.nav-links{display:flex;align-items:center;gap:24px}
.nav-links a{font-size:14px;color:var(--mut);transition:color .15s}
.nav-links a:hover{color:var(--ink)}
.nav-cta{
  background:var(--grad1);color:#fff!important;padding:8px 18px;border-radius:var(--radius-sm);
  font-weight:600;font-size:13px;transition:opacity .15s;
}
.nav-cta:hover{opacity:.88}
.mobile-toggle{display:none;background:none;border:0;cursor:pointer;padding:6px}
/* The bars-into-X hamburger. The button draws the brand mark now (see "THE
   MARK IS THE MENU" at the end of this file) — these rules are kept only so a
   page still cached from before that change renders a button instead of three
   invisible spans, and every one of them is scoped away from .brand-mark. The
   :not() is not cosmetic: `.mobile-toggle.open span:nth-child(1)` outranks a
   plain `.mobile-toggle .brand-mark`, so without it the mark was rotated 45deg
   the moment the drawer opened — the X, drawn with the logo. */
.mobile-toggle span:not(.brand-mark){display:block;width:22px;height:2px;background:var(--ink);border-radius:2px;transition:.2s}
.mobile-toggle span:not(.brand-mark)+span:not(.brand-mark){margin-top:5px}
.mobile-toggle.open span:not(.brand-mark):nth-child(1){transform:translateY(7px) rotate(45deg)}
.mobile-toggle.open span:not(.brand-mark):nth-child(2){opacity:0}
.mobile-toggle.open span:not(.brand-mark):nth-child(3){transform:translateY(-7px) rotate(-45deg)}

/* === HERO === */
.hero{padding:100px 0 80px;text-align:center;position:relative}
.hero-eyebrow{
  display:inline-flex;align-items:center;gap:8px;
  background:rgba(168,85,247,.1);border:1px solid rgba(168,85,247,.25);
  padding:6px 16px;border-radius:999px;font-size:12px;color:var(--purple2);
  font-weight:600;margin-bottom:24px;letter-spacing:.02em;
}
.hero h1{
  font-size:clamp(36px,6vw,64px);font-weight:800;letter-spacing:-.03em;line-height:1.05;
  margin-bottom:20px;
}
.hero h1 .gradient{background:var(--grad2);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.hero p.sub{font-size:clamp(16px,2.5vw,20px);color:var(--mut);max-width:560px;margin:0 auto 36px}
.hero-cta{display:flex;gap:14px;justify-content:center;flex-wrap:wrap}
.btn-lg{
  display:inline-flex;align-items:center;gap:8px;
  padding:14px 28px;border-radius:var(--radius-sm);font-size:15px;font-weight:700;
  transition:transform .12s,opacity .15s;cursor:pointer;border:0;font-family:inherit;
}
.btn-lg:active{transform:scale(.97)}
.btn-primary-lg{background:var(--grad1);color:#fff}
.btn-primary-lg:hover{opacity:.9}
.btn-ghost-lg{background:transparent;border:1px solid var(--line);color:var(--ink)}
.btn-ghost-lg:hover{border-color:var(--acc)}

/* Minimal topbar pills — thin, quiet, matches a chat-app header rather than a marketing CTA */
.topbar-btn{
  display:inline-flex;align-items:center;padding:8px 18px;border-radius:999px;
  font-size:13px;font-weight:600;font-family:inherit;cursor:pointer;transition:opacity .15s,background .15s;
}
.topbar-btn-ghost{background:transparent;border:1px solid var(--line);color:var(--ink)}
.topbar-btn-ghost:hover{border-color:var(--mut)}
.topbar-btn-solid{background:var(--ink);border:1px solid var(--ink);color:var(--bg)}
.topbar-btn-solid:hover{opacity:.85}

/* Hero stats */
.hero-stats{
  display:flex;gap:40px;justify-content:center;margin-top:56px;flex-wrap:wrap;
}
.hero-stat{text-align:center}
.hero-stat .num{font-size:30px;font-weight:800;letter-spacing:-.02em}
.hero-stat .num.gradient{background:var(--grad2);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.hero-stat .label{font-size:12px;color:var(--mut2);text-transform:uppercase;letter-spacing:.06em;margin-top:4px}

/* === SECTIONS === */
.section{padding:80px 0}
.section-head{text-align:center;margin-bottom:48px}
.section-head h2{font-size:clamp(26px,4vw,38px);font-weight:800;letter-spacing:-.02em;margin-bottom:10px}
.section-head p{font-size:15px;color:var(--mut);max-width:520px;margin:0 auto}

/* === HOW IT WORKS === */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
.step{
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:32px 24px;text-align:center;position:relative;transition:border-color .2s,transform .2s;
}
.step:hover{border-color:var(--acc);transform:translateY(-3px)}
.step-num{
  width:40px;height:40px;border-radius:50%;background:var(--grad1);color:#fff;
  font-weight:700;font-size:16px;display:flex;align-items:center;justify-content:center;
  margin:0 auto 20px;
}
.step-icon{font-size:32px;margin-bottom:16px}
.step h3{font-size:17px;font-weight:700;margin-bottom:8px}
.step p{font-size:14px;color:var(--mut)}

/* === PERSONA PICKER === */
.persona-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
.persona-card{
  display:block;background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:32px 24px;transition:border-color .2s,transform .2s,background .2s;
}
.persona-card:hover{border-color:var(--acc);transform:translateY(-3px);background:var(--card2)}
.persona-icon{font-size:34px;margin-bottom:16px}
.persona-card h3{font-size:18px;font-weight:700;margin-bottom:8px;color:var(--ink)}
.persona-card p{font-size:14px;color:var(--mut);margin-bottom:16px}
.persona-link{font-size:13px;font-weight:700;color:var(--acc2)}
@media (max-width:820px){.persona-grid{grid-template-columns:1fr}}

/* === COMPATIBILITY BADGE === */
.compat{
  display:flex;align-items:center;justify-content:center;gap:12px;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:20px 32px;margin:0 auto;max-width:640px;text-align:center;
}
.compat .check{
  width:32px;height:32px;border-radius:50%;background:rgba(62,213,152,.12);
  display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;
}
.compat-text{font-size:15px}
.compat-text strong{display:block;font-size:16px;margin-bottom:2px}
.compat-text span{color:var(--mut);font-size:13px}
.compat code{
  background:var(--bg);border:1px solid var(--line);border-radius:6px;
  padding:2px 8px;font-family:'SF Mono',Menlo,Consolas,monospace;font-size:12px;color:var(--acc2);
}

/* === PRICING === */
.billing-toggle{
  display:flex;align-items:center;justify-content:center;gap:14px;margin-bottom:36px;
}
.billing-toggle span{font-size:14px;color:var(--mut);transition:color .2s}
.billing-toggle span.active{color:var(--ink);font-weight:600}
.toggle-switch{
  position:relative;width:48px;height:26px;background:var(--card);border:1px solid var(--line);
  border-radius:999px;cursor:pointer;transition:background .2s;
}
.toggle-switch::after{
  content:'';position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:50%;
  background:var(--mut);transition:transform .2s,background .2s;
}
.toggle-switch.yearly::after{transform:translateX(22px);background:var(--acc)}
.toggle-switch.yearly{background:color-mix(in srgb, var(--ink) 15%, transparent)}
.save-badge{font-size:11px;color:var(--green);font-weight:600}

/* Billing term picker — three terms, so a two-state switch no longer fits. */
.term-segs{
  display:flex;justify-content:center;gap:4px;margin:0 auto 10px;padding:4px;
  background:var(--card);border:1px solid var(--line);border-radius:999px;width:max-content;max-width:100%;
  flex-wrap:wrap;
}
.term-seg{
  background:none;border:0;border-radius:999px;padding:8px 16px;cursor:pointer;
  font:inherit;font-size:14px;color:var(--mut);transition:background .2s,color .2s;
}
.term-seg:hover{color:var(--ink)}
.term-seg.active{background:color-mix(in srgb, var(--ink) 12%, transparent);color:var(--ink);font-weight:600}
.term-pitch{text-align:center;font-size:13px;color:var(--mut2);margin:0 auto 30px;max-width:560px}
/* Checkout feedback under the plan grid. Deliberately NOT .term-pitch — the
   term switch hides every .term-pitch that is not the active term, which would
   silently swallow an error the customer needs to read. */
.plan-status{text-align:center;font-size:13px;color:var(--mut2);margin:18px auto 0;max-width:560px}
.plan-status.is-error{color:var(--err,#e5484d)}

.pricing-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:14px}
@media(max-width:900px){.pricing-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.pricing-grid{grid-template-columns:1fr}}
.plan{
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:28px 20px;display:flex;flex-direction:column;position:relative;transition:border-color .2s,transform .2s;
}
.plan:hover{transform:translateY(-3px)}
.plan.popular{border-color:var(--acc);background:var(--card)}
.plan .popular-tag{
  position:absolute;top:-12px;left:50%;transform:translateX(-50%);
  background:var(--grad1);color:#fff;font-size:10px;font-weight:700;
  padding:4px 14px;border-radius:999px;letter-spacing:.05em;text-transform:uppercase;white-space:nowrap;
}
.plan-name{font-size:15px;font-weight:700;margin-bottom:6px}
.plan-tagline{font-size:12px;color:var(--mut2);margin-bottom:18px;min-height:32px}
.plan-price{display:flex;align-items:baseline;gap:4px;margin-bottom:4px}
.plan-price .amount{font-size:32px;font-weight:800;letter-spacing:-.03em}
.plan-price .period{font-size:13px;color:var(--mut)}
.plan-billed{font-size:11px;color:var(--mut2);margin-bottom:20px}
.plan-billed .yearly-price{color:var(--green)}
.plan-cta{
  display:block;text-align:center;padding:10px;border-radius:var(--radius-sm);
  font-size:13px;font-weight:600;margin-bottom:20px;transition:.15s;
}
.plan-cta.primary{background:var(--grad1);color:#fff}
.plan-cta.primary:hover{opacity:.9}
.plan-cta.secondary{background:transparent;border:1px solid var(--line);color:var(--ink)}
.plan-cta.secondary:hover{border-color:var(--acc)}
.plan-features{list-style:none;font-size:12px;color:var(--mut);flex:1}
.plan-features li{padding:5px 0;display:flex;align-items:flex-start;gap:6px}
.plan-features li::before{content:'✓';color:var(--green);font-weight:700;flex-shrink:0}

/* === MODEL CATALOG — card grid (T-1139, models-first redesign) === */
.model-filter-bar{margin-bottom:14px;max-width:320px}
.model-filter-bar input{
  width:100%;background:var(--card);border:1px solid var(--line);color:var(--ink);
  border-radius:999px;padding:9px 16px;font-size:13px;font-family:inherit;
}
.model-filter-bar input::placeholder{color:var(--mut2)}
.model-filter-bar input:focus{outline:none;border-color:var(--acc)}

.models-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:14px;
  text-align:left;max-width:var(--maxw);width:100%;margin:0 auto;
}
.model-card{
  display:flex;flex-direction:column;gap:10px;background:var(--card);border:1px solid var(--line);
  border-radius:var(--radius);padding:18px;transition:border-color .15s,transform .15s;
}
.model-card:hover{border-color:var(--line2);transform:translateY(-1px)}
.model-card.model-card-hidden{display:none}
.model-card-top{display:flex;align-items:center;gap:8px}
.provider-logo{
  flex:none;width:26px;height:26px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;
  background:var(--card2);border:1px solid var(--line);color:var(--ink);
  font-family:var(--font-display);font-weight:600;font-size:10.5px;letter-spacing:-.02em;
}
.provider-logo svg{width:14px;height:14px;flex:none}
.provider-logo[data-vendor="synap"] svg{width:15px;height:15px}
/* Our own mark: solid black-and-white, not the grey vendor chip (Jimmie 2026-10-31). */
.provider-logo[data-vendor="synap"]{background:var(--ink);border-color:var(--ink);color:var(--bg)}
/* Vendor marks in their real brand colours, app-icon style (Jimmie 2026-10-31, T-1242):
   colour marks sit on a white chip, black-and-white marks on a black chip, in both themes. */
.provider-logo[data-vendor="google"],.provider-logo[data-vendor="meta"],
.provider-logo[data-vendor="qwen"],.provider-logo[data-vendor="deepseek"]{background:#fff;border-color:#e3e3e8}
.provider-logo[data-vendor="qwen"]{color:#615CED}
.provider-logo[data-vendor="deepseek"]{color:#4D6BFE}
.provider-logo[data-vendor="openai"],.provider-logo[data-vendor="zai"],
.provider-logo[data-vendor="moonshot"]{background:#000;border-color:#2a2b33;color:#fff}
.model-card-vendor{font-size:11.5px;color:var(--mut);font-weight:500}
.model-card-tag{
  margin-left:auto;font-size:10px;padding:2px 8px;border-radius:999px;font-weight:600;
  background:color-mix(in srgb, var(--green) 14%, transparent);color:var(--green);
}
.model-card-tag-plan{background:color-mix(in srgb, var(--gold) 16%, transparent);color:var(--gold)}
.model-card-name{
  font-family:'SF Mono',Menlo,Monaco,Consolas,monospace;font-size:14.5px;font-weight:600;color:var(--ink);
  word-break:break-word;
}
.model-card-job{font-size:12.5px;color:var(--mut);font-weight:600}
.model-card-note{font-size:12.5px;color:var(--mut2);line-height:1.5;flex:1}
.model-card-price{display:flex;gap:18px;padding-top:4px;border-top:1px solid var(--line2)}
.model-card-price div{display:flex;flex-direction:column}
.model-card-price span{font-family:Fraunces,serif;font-weight:600;font-size:16px;color:var(--ink)}
.model-card-price small{font-size:10.5px;color:var(--mut2)}
.model-card-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:4px}
.model-card-secure{
  display:inline-flex;align-items:center;gap:5px;font-size:10px;font-weight:500;letter-spacing:.08em;
  text-transform:uppercase;color:var(--mut2);
}
.model-card-secure svg{width:11px;height:11px;flex:none;opacity:.75}
/* T-1139 follow-up (Jimmie, 2026-10-28): the funnel should push toward
   buying, not toward trying — a visitor who buys is worth more to us than
   one who just tries the model. "Get your API key" carries the stronger
   style (bold, accent) and sits above; "Test this model" is now the quiet
   secondary action. */
.model-card-cta{
  font-size:11.5px;font-weight:500;color:var(--mut2);white-space:nowrap;transition:color .15s;
}
.model-card-cta:hover{color:var(--ink)}
.model-card-api{
  display:block;font-size:13.5px;font-weight:700;color:var(--acc2);text-decoration:none;transition:color .15s;
}
.model-card-api:hover{color:var(--ink)}
@media (max-width:620px){
  .models-grid{grid-template-columns:1fr}
}

/* === MINERS === */
.miners-section{background:var(--bg2);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.miners-grid{display:grid;grid-template-columns:1fr 1fr;gap:40px;align-items:center}
@media(max-width:768px){.miners-grid{grid-template-columns:1fr}}
.miners-content h2{font-size:clamp(24px,4vw,34px);font-weight:800;letter-spacing:-.02em;margin-bottom:14px}
.miners-content p{font-size:15px;color:var(--mut);margin-bottom:24px}
.miners-content .miner-cta{margin-bottom:28px}
.earnings-table{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
.earnings-table table{width:100%;border-collapse:collapse;font-size:13px}
.earnings-table th{background:var(--card2);text-align:left;padding:10px 14px;color:var(--mut);font-weight:600;font-size:11px;letter-spacing:.04em;text-transform:uppercase}
.earnings-table td{border-top:1px solid var(--line2);padding:12px 14px}
.earnings-table .gpu-name{font-weight:600}
.earnings-table .est{color:var(--green);font-weight:700}

/* === FOOTER === */
footer{border-top:1px solid var(--line);padding:48px 0 32px;margin-top:0}
.footer-grid{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:32px;margin-bottom:32px}
@media(max-width:640px){.footer-grid{grid-template-columns:1fr 1fr}}
.footer-brand .brand{margin-bottom:12px}
.footer-brand p{font-size:13px;color:var(--mut);max-width:280px}
.footer-col h4{font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;color:var(--mut2);margin-bottom:14px}
.footer-col a{display:block;font-size:13px;color:var(--mut);padding:4px 0;transition:color .15s}
.footer-col a:hover{color:var(--ink)}
.footer-bottom{
  border-top:1px solid var(--line);padding-top:20px;
  display:flex;justify-content:space-between;align-items:center;font-size:12px;color:var(--mut2);flex-wrap:wrap;gap:8px;
}

/* === ANIMATIONS === */
.reveal{opacity:0;transform:translateY(24px);transition:opacity .5s ease,transform .5s ease}
.reveal.visible{opacity:1;transform:translateY(0)}
.reveal-delay-1{transition-delay:.08s}
.reveal-delay-2{transition-delay:.16s}
.reveal-delay-3{transition-delay:.24s}
.reveal-delay-4{transition-delay:.32s}

/* === RESPONSIVE === */
@media(max-width:768px){
  .nav-links{display:none;position:absolute;top:60px;left:0;right:0;flex-direction:column;background:var(--bg2);border-bottom:1px solid var(--line);padding:16px 24px;gap:16px}
  .nav-links.open{display:flex}
  .nav-links.open a{font-size:15px}
  .mobile-toggle{display:block}
  .steps{grid-template-columns:1fr}
  .hero{padding:60px 0 50px}
  .section{padding:56px 0}
  .hero-stats{gap:24px}
  .compat{flex-direction:column;text-align:center;gap:10px}
}
@media(max-width:480px){
  .hero-stats{gap:16px}
  .hero-stat .num{font-size:24px}
}

/* === THANK YOU PAGE === */
.thankyou{min-height:70vh;display:flex;align-items:center;justify-content:center;text-align:center}
.thankyou-box{
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:48px 36px;max-width:520px;
}
.thankyou-box .check-circle{
  width:64px;height:64px;border-radius:50%;background:rgba(62,213,152,.12);
  display:flex;align-items:center;justify-content:center;font-size:30px;margin:0 auto 24px;
}
.thankyou-box h1{font-size:28px;font-weight:800;margin-bottom:10px}
.thankyou-box p{font-size:15px;color:var(--mut);margin-bottom:28px}
.next-steps{text-align:left;margin-bottom:28px}
.next-steps li{list-style:none;padding:8px 0;font-size:14px;color:var(--mut);display:flex;align-items:flex-start;gap:10px}
.next-steps li .step-num-sm{
  width:22px;height:22px;border-radius:50%;background:var(--grad1);color:#fff;
  font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:1px;
}
.thankyou-box .btn-lg{margin-top:4px}

/* ============================================================
   LINKRRA BRAND LAYER v2 — "research lab" finish (2026-08-11):
   near-black ground, one quiet ambient highlight instead of three
   saturated color blobs, monochrome CTAs, wireframe orb hero mark.
   Sidebar structure/content unchanged.
   ============================================================ */
:root{--font-display:'Fraunces','Frank Ruhl Libre',Georgia,'Times New Roman',serif}
body{background:radial-gradient(900px 560px at 50% -8%,color-mix(in srgb, var(--ink) 5%, transparent),transparent 62%),radial-gradient(1000px 700px at 90% 90%,color-mix(in srgb, var(--ink) 4%, transparent),transparent 60%),var(--bg)}

.bgfx{position:fixed;inset:0;overflow:hidden;z-index:0;pointer-events:none}
#net{position:absolute;inset:0;width:100%;height:100%;z-index:1;pointer-events:none;opacity:.55}
.blob{position:absolute;border-radius:50%;filter:blur(120px);opacity:.1;z-index:0;pointer-events:none}
.blob.b1{width:640px;height:640px;background:#3d4a6b;top:-200px;right:-160px;animation:lr-drift1 26s ease-in-out infinite}
.blob.b2{width:460px;height:460px;background:#2c2f3a;top:820px;left:-160px;opacity:.16;animation:lr-drift2 30s ease-in-out infinite}
.blob.b3{width:420px;height:420px;background:#39415e;top:1550px;right:-100px;opacity:.08;animation:lr-drift3 27s ease-in-out infinite}
@keyframes lr-drift1{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(-70px,50px) scale(1.12)}}
@keyframes lr-drift2{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(80px,-55px) scale(1.1)}}
@keyframes lr-drift3{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(-55px,-45px) scale(1.14)}}
@media(prefers-reduced-motion:reduce){.blob{animation:none!important}}
/* keep the sidebar/content readable above the constellation canvas */
.app-shell{position:relative;z-index:2}
.sidebar{background:var(--bg)}
.sidebar-brand{color:var(--ink)}
.sidebar-brand .dot{background:var(--ink)}
.brand{color:var(--ink)}

/* Fraunces display headline, matching the linkrra.com hero treatment */
.app-hero h1{font-family:var(--font-display);font-weight:600;letter-spacing:-.02em}
.app-hero h1 .g{font-style:italic;font-weight:500;color:var(--mut)}
.lr-page-head h1,.subpage-head h1{font-family:var(--font-display);font-weight:600;letter-spacing:-.02em}

/* wireframe orb — replaces the flat gradient dot as the hero mark */
.app-hero-mark{width:auto;height:auto;background:none;box-shadow:none;margin-bottom:8px;opacity:.9}
.app-hero-mark svg{display:block;animation:lr-orb-spin 40s linear infinite}
@keyframes lr-orb-spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){.app-hero-mark svg{animation:none}}

/* monochrome CTAs — quiet outline / solid off-white, no color glow.
   Applies site-wide (pricing/miners/register/etc.) so every primary
   button reads as one system instead of homepage-only. */
.topbar-btn-solid,.btn-primary-lg,.plan-cta.primary,.nav-cta{box-shadow:none}
.topbar-btn-solid,.btn-primary-lg,.plan-cta.primary,.nav-cta{background:var(--ink)!important;border-color:var(--ink);color:var(--bg)!important}
.topbar-btn-solid:hover,.btn-primary-lg:hover,.plan-cta.primary:hover,.nav-cta:hover{filter:brightness(.92);opacity:1;transform:none}
.topbar-btn-ghost:hover{border-color:var(--mut);background:color-mix(in srgb, var(--ink) 4%, transparent)}
.app-input-form{box-shadow:0 1px 2px rgba(0,0,0,.4),0 18px 40px rgba(0,0,0,.45);backdrop-filter:blur(8px);border-color:var(--line)}
.app-input-form:focus-within{border-color:var(--mut)}
.app-input-form button{background:var(--ink);color:var(--bg);box-shadow:none}
.app-input-form button:hover{opacity:.85}
.chip:hover{border-color:var(--mut);background:color-mix(in srgb, var(--ink) 4%, transparent);color:var(--ink)}

/* quiet the "most popular" plan + step-number accents to match */
.plan.popular{border-color:var(--mut);background:var(--card)}
.plan .popular-tag{background:var(--ink);color:var(--bg)}
.step-num,.next-steps li .step-num-sm{background:var(--ink);color:var(--bg)}
.hero-eyebrow{background:color-mix(in srgb, var(--ink) 5%, transparent);border-color:var(--line);color:var(--mut)}

/* ============================================================
   LIGHT MODE (2026-08-12) — toggle via html[data-theme="light"],
   set by the inline head script (reads localStorage) and flipped
   by #themeToggle (app.js). Every rule elsewhere reads these same
   custom properties, so this block is the entire light theme.
   ============================================================ */
/* Tuned 2026-08-20: the ground was too bright and the second tier too pale, so the
   page glared and the hierarchy went flat — the dark theme reads better precisely
   because its steps are further apart. The ground drops off pure white, cards stay
   the lightest surface (so they still lift off it), lines darken enough to be seen,
   and both muted tiers move up. Every value below was measured, not eyeballed —
   contrast against the ground (#eeeef1): ink 16.7:1, mut 6.8:1, mut2 4.4:1,
   teal 4.6:1, gold 4.8:1, red 5.3:1, green 4.5:1. The accent colours were darkened
   for the same reason: at their old values none of them cleared 4.5:1 on a light
   ground, so a teal or gold label was decoration rather than text. */
html[data-theme="light"]{
  --bg:#eeeef1;--bg2:#fbfbfc;--card:#ffffff;--card2:#e9e9ed;
  --line:#d6d7dd;--line2:#e3e3e8;
  --ink:#0d0e13;--mut:#4f515a;--mut2:#6c6e78;
  --acc:#0d0e13;--acc2:#3f414a;
  --teal:#0a7a66;--gold:#8f5e06;--red:#bc2135;--green:#0b7d53;
}
html[data-theme="light"] .blob{opacity:.05}
html[data-theme="light"] .blob.b2{opacity:.08}
html[data-theme="light"] .blob.b3{opacity:.04}
html[data-theme="light"] .app-input-form{box-shadow:0 1px 2px rgba(0,0,0,.06),0 18px 40px rgba(0,0,0,.08)}

/* theme toggle button (sun/moon), placed in .app-topbar / header nav */
.theme-toggle{
  width:36px;height:36px;flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;
  border-radius:999px;border:1px solid var(--line);background:transparent;color:var(--ink);
  cursor:pointer;transition:border-color .15s,background .15s;padding:0;
}
.theme-toggle:hover{border-color:var(--mut);background:color-mix(in srgb, var(--ink) 4%, transparent)}
.theme-toggle .icon-moon{display:none}
html[data-theme="light"] .theme-toggle .icon-sun{display:none}
html[data-theme="light"] .theme-toggle .icon-moon{display:inline-flex}

/* === CHAT (/ai/chat.html) === */
.chat-wrap{flex:1;display:flex;flex-direction:column;min-height:0;padding:0 20px 20px}
.chat-thread{
  flex:1;overflow-y:auto;width:100%;max-width:900px;margin:0 auto;
  display:flex;flex-direction:column;gap:20px;padding:10px 0 24px;
}
.chat-empty{margin:auto;text-align:center;color:var(--mut);max-width:520px}
.chat-empty h1{font-size:clamp(24px,3.4vw,34px);letter-spacing:-.02em;color:var(--ink);margin-bottom:10px}
.chat-empty p{font-size:14px;line-height:1.6}
.chat-suggestions{display:flex;flex-wrap:wrap;gap:8px;justify-content:center;margin-top:22px}
.chat-suggestions button{
  background:var(--card);border:1px solid var(--line);color:var(--mut);
  border-radius:999px;padding:9px 15px;font:inherit;font-size:13px;cursor:pointer;
  transition:border-color .15s,color .15s;
}
.chat-suggestions button:hover{border-color:var(--mut2);color:var(--ink)}
.msg{display:flex;gap:12px;align-items:flex-start;line-height:1.65;font-size:15px}
.msg .who{
  flex:0 0 26px;height:26px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-size:11px;font-weight:700;margin-top:2px;
}
.msg.user .who{background:var(--card);border:1px solid var(--line);color:var(--mut)}
.msg.bot .who{background:var(--grad1);color:#fff}
.msg .body{flex:1;min-width:0;white-space:pre-wrap;word-wrap:break-word;color:var(--ink)}
.msg.err .body{color:var(--red)}
.msg .body .cursor{display:inline-block;width:7px;height:15px;background:var(--mut);
  vertical-align:-2px;animation:lr-blink 1s steps(2) infinite}
@keyframes lr-blink{50%{opacity:0}}
.chat-composer{width:100%;max-width:760px;margin:0 auto}
.chat-note{
  max-width:760px;margin:8px auto 0;text-align:center;font-size:12px;color:var(--mut2);
}
.chat-note a{color:var(--mut);text-decoration:underline}

/* The upgrade card in the chat thread. It reads as an offer, not as the red
   error style the rest of the failure paths use — running out of a free
   allowance is the product working, not breaking. */
.msg.upsell .body{
  border:1px solid var(--line);border-radius:14px;padding:14px 16px;
  background:linear-gradient(180deg,rgba(125,165,255,.10),transparent);
  white-space:normal
}
.upsell-head{font-weight:600;margin-bottom:4px}
.upsell-reason{color:var(--mut2);font-size:13px;margin-bottom:12px}
.upsell-cta{
  display:inline-block;padding:9px 18px;border-radius:999px;
  background:var(--grad1);color:#fff;text-decoration:none;font-size:14px;font-weight:600
}
.upsell-cta:hover{opacity:.92}
@media(max-width:900px){
  .chat-wrap{padding:0 12px 12px}
  .chat-thread{max-width:none}
  .chat-composer,.chat-composer-wrap{max-width:none}
  .chat-note{max-width:none}
  .chat-empty{max-width:none;padding:0 6px}
}
/* 100vh is a lie on a phone: iOS measures it against the viewport WITHOUT the
 * Safari toolbars, so a 100vh page that also hides its overflow puts the
 * composer and the message counter underneath the browser chrome, where they
 * cannot be reached or scrolled to. dvh is the height that actually exists;
 * the vh line stays first as the fallback for browsers that lack it. */
.app-shell.chat-mode{height:100vh;height:100dvh;min-height:0;overflow:hidden}
.app-shell.chat-mode .app-main{min-height:0}
.app-shell.chat-mode .app-topbar{padding-bottom:8px}
.app-shell.chat-mode .chat-wrap{padding-bottom:max(20px,env(safe-area-inset-bottom))}
.chat-code{
  background:var(--bg2);border:1px solid var(--line);border-radius:var(--radius-sm);
  padding:12px 14px;margin:10px 0;overflow-x:auto;position:relative;
  font-family:'SF Mono',Menlo,Consolas,monospace;font-size:12.5px;line-height:1.6;
  color:var(--acc2);white-space:pre;
}
.chat-code-copy{
  position:absolute;top:6px;inset-inline-end:8px;background:var(--bg);border:1px solid var(--line);
  color:var(--mut);border-radius:999px;padding:2px 10px;font:inherit;font-size:11px;
  letter-spacing:.03em;cursor:pointer;white-space:nowrap;
}
.chat-code-copy:hover{color:var(--ink);border-color:var(--mut2)}
/* Syntax highlighting is a generic, per-token classifier (see highlightCode in
   chat.js) rather than a real per-language grammar — these five colors are
   all it needs, reusing the existing accent palette instead of inventing new
   hex values just for code. */
.chat-code .hl-kw{color:var(--red)}
.chat-code .hl-str{color:var(--green)}
.chat-code .hl-num{color:var(--gold)}
.chat-code .hl-fn{color:var(--teal)}
.chat-code .hl-com{color:var(--mut2);font-style:italic}

/* ============================================================
   ACCOUNT (2026-08-16) — the signed-in surface.
   Signing in with no way to sign out is a trap, and a buyer who
   cannot see the balance attached to their own Google account has
   no reason to believe the purchase landed. Both live here.
   ============================================================ */
.account-menu{position:relative;display:inline-flex}
.account-chip{
  display:inline-flex;align-items:center;gap:8px;padding:6px 12px 6px 6px;border-radius:999px;
  border:1px solid var(--line);background:var(--card);color:var(--ink);font:inherit;font-size:13px;
  font-weight:600;cursor:pointer;max-width:220px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;
}
.account-chip:hover{border-color:var(--mut)}
.account-chip img{width:24px;height:24px;border-radius:50%;flex:0 0 auto}
.account-pop{
  position:absolute;top:calc(100% + 8px);right:0;z-index:120;min-width:220px;padding:6px;
  border-radius:14px;border:1px solid var(--line);background:var(--bg2);
  box-shadow:0 12px 40px rgba(0,0,0,.35);
}
.account-pop-who{padding:8px 10px 10px;font-size:12px;color:var(--mut);border-bottom:1px solid var(--line);margin-bottom:4px;overflow:hidden;text-overflow:ellipsis}
.account-pop-item{
  display:block;width:100%;text-align:left;padding:9px 10px;border:0;border-radius:9px;
  background:transparent;color:var(--ink);font:inherit;font-size:13px;cursor:pointer;text-decoration:none;
}
.account-pop-item:hover{background:var(--card)}
.account-pop-item.danger{color:var(--red)}

.acct-who{color:var(--mut)}
.acct-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:14px;margin-bottom:34px}
.acct-card{border:1px solid var(--line);background:var(--card);border-radius:16px;padding:18px 20px}
.acct-card h2{margin:0 0 6px;font-size:18px}
.acct-label{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--mut)}
.acct-figure{font-family:var(--font-display);font-size:32px;font-weight:600;margin:8px 0 4px}
.acct-sub{font-size:12px;color:var(--mut)}
.acct-h2{font-family:var(--font-display);font-weight:600;font-size:22px;margin:34px 0 6px}

/* Plan cards on the account page. Compact on purpose — this is the upgrade
   shelf, not the pricing page; the full comparison lives at /ai/pricing.html. */
.acct-plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:12px;margin:14px 0 6px}
.acct-plan{
  background:var(--card);border:1px solid var(--line);border-radius:14px;padding:16px;
  display:flex;flex-direction:column;gap:4px
}
.acct-plan.is-popular{border-color:rgba(125,165,255,.5)}
.acct-plan.is-current{border-color:var(--ink);opacity:.85}
.acct-plan-name{font-weight:600}
.acct-plan-price{font-family:var(--font-display);font-size:20px}
.acct-plan-sub{color:var(--mut2);font-size:12px;margin-bottom:10px}
.acct-plan-cta{
  margin-top:auto;padding:8px 14px;border-radius:999px;border:1px solid var(--line);
  background:var(--grad1);color:#fff;font-size:13px;font-weight:600;cursor:pointer;font-family:inherit
}
.acct-plan-cta:disabled{opacity:.6;cursor:default}
.acct-plan-current{margin-top:auto;font-size:12px;color:var(--mut2)}
.acct-buy{margin-top:14px}
.acct-amounts{display:flex;flex-wrap:wrap;gap:10px;margin-bottom:14px}
.acct-amount{
  display:flex;flex-direction:column;align-items:flex-start;gap:2px;min-width:104px;
  padding:12px 16px;border-radius:14px;border:1px solid var(--line);background:var(--card);
  color:var(--ink);font:inherit;font-size:16px;font-weight:600;cursor:pointer;
}
.acct-amount span{font-size:11px;font-weight:500;color:var(--mut)}
.acct-amount:hover{border-color:var(--mut)}
.acct-amount.selected{border-color:var(--ink);background:color-mix(in srgb, var(--ink) 6%, transparent)}
.acct-custom{display:flex;flex-direction:column;gap:6px;max-width:220px;margin-bottom:16px;font-size:12px;color:var(--mut)}
.acct-custom input{
  padding:11px 14px;border-radius:12px;border:1px solid var(--line);background:var(--card);
  color:var(--ink);font:inherit;font-size:15px;
}
.acct-status{margin-top:10px;font-size:13px;color:var(--mut);word-break:break-all}
.acct-status.is-error{color:var(--red)}
.acct-h3{font-family:var(--font-display);font-weight:600;font-size:17px;margin:28px 0 2px}
/* Cancelling is deliberately findable and deliberately quiet: a customer who
   cannot find it disputes the charge instead, and a loud one invites the
   thought. */
.acct-cancel{
  background:none;border:1px solid var(--line);color:var(--mut);border-radius:999px;
  padding:7px 14px;font-size:13px;cursor:pointer;font-family:inherit
}
.acct-cancel:hover{color:var(--ink)}
.acct-cancel-note{font-size:12px;margin-left:10px}
.acct-table-wrap{overflow-x:auto;border:1px solid var(--line);border-radius:16px;margin-top:10px}
.acct-table{width:100%;border-collapse:collapse;font-size:14px}
.acct-table th{
  text-align:left;padding:12px 16px;font-size:11px;letter-spacing:.08em;text-transform:uppercase;
  color:var(--mut);border-bottom:1px solid var(--line);font-weight:600;
}
.acct-table td{padding:12px 16px;border-bottom:1px solid var(--line2);color:var(--ink)}
.acct-table tr:last-child td{border-bottom:0}
.acct-table td.mut{color:var(--mut)}
.acct-foot{margin-top:40px;padding-top:20px;border-top:1px solid var(--line)}
.acct-signout{
  padding:10px 18px;border-radius:999px;border:1px solid var(--line);background:transparent;
  color:var(--red);font:inherit;font-size:13px;font-weight:600;cursor:pointer;
}
.acct-signout:hover{border-color:var(--red)}
.acct-revoke{
  padding:6px 12px;border-radius:999px;border:1px solid var(--line);background:transparent;
  color:var(--red);font:inherit;font-size:12px;font-weight:600;cursor:pointer;
}
.acct-revoke:hover{border-color:var(--red)}
.acct-revoke:disabled{opacity:.5;cursor:default}
.acct-table tr.is-revoked td{opacity:.5;text-decoration:line-through}
.acct-table tr.is-revoked td:last-child{text-decoration:none}
.acct-actions{white-space:nowrap;display:flex;gap:8px;align-items:center}
.acct-delete{
  padding:6px 12px;border-radius:999px;border:1px solid var(--red);background:transparent;
  color:var(--red);font:inherit;font-size:12px;font-weight:600;cursor:pointer;
}
.acct-delete:hover{background:color-mix(in srgb, var(--red) 10%, transparent)}
.acct-delete:disabled{opacity:.5;cursor:default}

/* payment methods + TON transfer panel (2026-08-16) */
.acct-methods{display:flex;flex-wrap:wrap;gap:10px;margin:6px 0 18px}
.acct-method{
  flex:1 1 160px;display:flex;flex-direction:column;gap:3px;align-items:flex-start;text-align:left;
  padding:12px 16px;border-radius:14px;border:1px solid var(--line);background:var(--card);
  color:var(--ink);font:inherit;cursor:pointer;
}
.acct-method:hover:not(:disabled){border-color:var(--mut)}
.acct-method.selected{border-color:var(--ink);background:color-mix(in srgb, var(--ink) 6%, transparent)}
.acct-method.unavailable{opacity:.55;cursor:not-allowed}
.acct-method-name{font-size:15px;font-weight:600}
.acct-method-hint{font-size:11px;color:var(--mut);line-height:1.35}
.acct-ton{margin-top:22px;padding:20px;border:1px solid var(--line);border-radius:16px;background:var(--card)}
.acct-ton h3{margin:0 0 6px;font-family:var(--font-display);font-weight:600;font-size:18px}
.acct-field{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:10px 0;border-bottom:1px solid var(--line2);
}
.acct-field:last-of-type{border-bottom:0}
.acct-field span{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--mut);min-width:74px}
.acct-field code{
  flex:1 1 200px;font-size:12px;word-break:break-all;color:var(--ink);
  background:color-mix(in srgb, var(--ink) 5%, transparent);padding:8px 10px;border-radius:8px;
}
.acct-copy{
  padding:6px 12px;border-radius:999px;border:1px solid var(--line);background:transparent;
  color:var(--ink);font:inherit;font-size:12px;font-weight:600;cursor:pointer;
}
.acct-copy:hover{border-color:var(--mut)}

/* A plaintext API key exists only in the create response. Keep it beside the
   action that created it; persistent, visible and never blocking the account. */
.key-reveal[hidden]{display:none}
.key-reveal{
  max-width:760px;margin-top:14px;padding:16px;border:1px solid color-mix(in srgb,var(--acc) 35%,var(--line));
  border-radius:10px;background:color-mix(in srgb,var(--acc) 5%,var(--card));
}
.key-reveal-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:5px}
.key-reveal-head strong{font-size:14px}
.key-reveal-head span{color:var(--mut);font-size:10px;font-weight:700;letter-spacing:.08em;text-transform:uppercase}
.key-reveal-head-actions{display:flex;align-items:center;gap:9px}
.key-reveal-close{
  width:44px;height:44px;flex-shrink:0;display:grid;place-items:center;border:0;border-radius:6px;touch-action:manipulation;
  background:transparent;color:var(--mut);font-size:22px;line-height:1;cursor:pointer;
}
.key-reveal-close:hover{background:color-mix(in srgb,var(--ink) 7%,transparent);color:var(--ink)}
.key-reveal>p{margin:0 0 12px;color:var(--mut);font-size:12.5px;line-height:1.5}
.key-reveal-value{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:stretch}
.key-reveal-value code{
  display:flex;align-items:center;min-width:0;padding:11px 12px;border:1px solid var(--line);
  border-radius:7px;background:var(--bg);color:var(--ink);font:12px/1.5 'SF Mono',Menlo,monospace;
  overflow-wrap:anywhere;user-select:all;
}
.key-reveal>.acct-status{margin:9px 0 0}
.key-reveal-value code:focus-visible,.key-reveal button:focus-visible{
  outline:2px solid var(--acc);outline-offset:3px;
}
.key-reveal-value button{min-height:44px;touch-action:manipulation}
@media(max-width:560px){
  .key-reveal{padding:14px}
  .key-reveal-value{grid-template-columns:1fr}
  .key-reveal-value .btn-lg{width:100%}
}
.acct-ton-actions{display:flex;flex-wrap:wrap;gap:10px;margin-top:16px}
.acct-ton-actions .btn-lg{flex:1 1 160px;text-align:center}
.acct-ton-alt{margin-top:12px;font-size:12px;color:var(--mut)}
.acct-ton-alt a{color:var(--ink)}
.acct-ton-summary{margin:14px 0 0;font-size:13px;color:var(--mut)}
/* The by-hand details are deliberately quiet: present for the wallet we did
   not anticipate, never the first thing the eye lands on. */
.acct-ton-manual{margin-top:16px;border-top:1px solid var(--line2);padding-top:12px}
.acct-ton-manual summary{
  font-size:12px;color:var(--mut);cursor:pointer;list-style:none;
}
.acct-ton-manual summary::-webkit-details-marker{display:none}
.acct-ton-manual summary::before{content:"+ ";font-weight:600}
.acct-ton-manual[open] summary::before{content:"– "}
.acct-ton-manual summary:hover{color:var(--ink)}
.acct-ton-manual[open] summary{margin-bottom:6px}
.acct-prl-qr{display:block;margin:16px auto 4px;border-radius:12px;background:#fff;padding:8px}

.sidebar-label{font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--mut);opacity:.6;padding:14px 12px 6px}
.sidebar-collapsed .sidebar-label{opacity:0;height:0;padding:0;overflow:hidden}

/* "Soon" marker — a product listed next to the ones that are self-serve, but
   whose flow still ends with a person doing the work, is a promise the nav is
   making on its own. The two that end in /ai/api/intake (All in, Automate) say
   so in the nav and again in their own heading, rather than only on the last
   screen after someone has tapped through. Quiet on purpose: this is an honest
   label, not a marketing badge, so it must not out-shout the live products. */
.sidebar-link .soon{
  margin-left:auto;font-size:9.5px;font-weight:700;letter-spacing:.07em;text-transform:uppercase;
  color:var(--mut2);border:1px solid var(--line);border-radius:999px;padding:2px 7px;line-height:1.5;flex:none;
}
.sidebar-collapsed .sidebar-link .soon{display:none}
.subpage-head .soon-tag{
  display:inline-flex;align-items:center;gap:6px;margin-bottom:12px;
  font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;
  color:var(--mut);border:1px solid var(--line);border-radius:999px;padding:4px 11px;
}
.subpage-head .soon-tag::before{content:'';width:5px;height:5px;border-radius:50%;background:var(--gold);flex:none}
.subpage-head .soon-note{margin-top:10px;font-size:13.5px;color:var(--mut2)}

.allin-embed{display:flex;flex-direction:column;height:100%;min-height:0;padding:0}
.allin-bar{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
  padding:14px 22px;border-bottom:1px solid var(--line)}
.allin-bar strong{font-size:15px;font-weight:700;color:var(--ink);margin-right:10px}
.allin-bar span{font-size:13px;color:var(--mut)}
.allin-bar-actions{display:flex;gap:8px}
.allin-frame{flex:1;min-height:70vh;width:100%;border:0;display:block;background:var(--bg)}

.conn-head{margin-bottom:22px}
.conn-head h2{font-size:20px;font-weight:700;margin-bottom:6px}
.conn-head p{font-size:14px;color:var(--mut);max-width:60ch}
.conn-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
.conn-tile{display:flex;flex-direction:column;gap:4px;padding:16px 18px;border:1px solid var(--line);
  border-radius:14px;background:var(--card);text-decoration:none;transition:.16s}
.conn-tile:hover{border-color:var(--acc);background:var(--card2);transform:translateY(-2px)}
.conn-name{font-size:15px;font-weight:700;color:var(--ink)}
.conn-sub{font-size:12.5px;color:var(--mut)}
.conn-go{font-size:12px;font-weight:700;color:var(--acc2);margin-top:8px}
.conn-foot{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
  margin-top:32px;padding:18px 20px;border:1px solid var(--line);border-radius:14px;background:var(--card)}
.conn-foot strong{display:block;font-size:15px;color:var(--ink)}
.conn-foot span{font-size:13px;color:var(--mut)}
@media (max-width:1100px){.conn-grid{grid-template-columns:repeat(3,1fr)}}
@media (max-width:820px){.conn-grid{grid-template-columns:repeat(2,1fr)}}
@media (max-width:520px){.conn-grid{grid-template-columns:1fr}}

/* ── Agent builder (/ai/agents.html) ─────────────────────────────────────────
   A conversation on the left, the agent it is producing on the right. Not a form:
   a business owner should never have to translate their own business into fields
   like "system prompt" — they describe the business and watch the agent appear. */
.builder{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,420px);gap:24px;
  align-items:start;margin-top:26px}
@media(max-width:980px){.builder{grid-template-columns:1fr}}

.builder-chat{display:flex;flex-direction:column;height:min(620px,72vh);
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
/* On a phone this was a 620px box inside a page that also scrolled — two
   scrollbars fighting, and a composer that could be anywhere. The builder is
   the page here: it takes the real viewport (dvh, so the iOS URL bar does not
   steal the send button) and the page behind it stops scrolling underneath. */
@media(max-width:980px){
  .builder{margin-top:14px;gap:16px}
    /* Room for the note under the composer: at 172px it sat exactly one line
     below the fold, which reads as a cut-off card rather than a hint. */
  .builder-chat{height:calc(100dvh - 200px);min-height:392px}
  .subpage-head{padding:22px 20px 4px}
  .subpage-head h1{margin-bottom:6px}
  .subpage-head p{font-size:13.5px;line-height:1.55}
  .builder-live{position:static}
}
.bc-head{display:flex;align-items:center;gap:11px;padding:15px 18px;border-bottom:1px solid var(--line2)}
.bc-head strong{display:block;font-size:14.5px}
.bc-head small{display:block;color:var(--mut);font-size:12.5px;margin-top:1px}
.bc-dot{width:9px;height:9px;border-radius:50%;background:var(--grad1);flex:0 0 9px}
.bc-log{flex:1;overflow-y:auto;padding:18px;display:flex;flex-direction:column;gap:12px}
.bc-msg{max-width:82%;padding:11px 15px;border-radius:15px;font-size:14.5px;line-height:1.55;
  white-space:pre-wrap;word-wrap:break-word;unicode-bidi:plaintext}
.bc-msg.them{background:var(--card2);border:1px solid var(--line);align-self:flex-start;border-bottom-left-radius:5px}
.bc-msg.me{background:var(--acc);color:#fff;align-self:flex-end;border-bottom-right-radius:5px}
.bc-msg.think{color:var(--mut);background:transparent;border:0;padding:2px 6px;font-size:13.5px}
.bc-chips{display:flex;flex-wrap:wrap;gap:7px;padding:0 18px 12px}
.bc-chips button{background:transparent;border:1px solid var(--line);border-radius:999px;
  padding:7px 13px;font-size:12.5px;color:var(--mut);cursor:pointer;text-align:start}
.bc-chips button:hover{border-color:var(--acc);color:var(--ink)}

/* The opening picker. It occupies the same column the conversation will, so the
   builder does not visibly jump when the taps hand over to typing. Targets are
   48px+ because this is used on a phone standing in a shop, and the whole thing
   is monochrome by rule — the page has exactly one accent, the ink itself. */
/* Bar and step centre together as one block — via auto margins, NOT
   justify-content:center. Centring a flex column clips the top of anything
   taller than the box and leaves it unreachable; the eight-item step scrolled
   in already cut off at its own question. Auto margins collapse instead. */
.bc-picker{flex:1;overflow-y:auto;padding:20px 20px 8px;display:flex;flex-direction:column}
.bc-bar{margin-top:auto}
.bc-picker>.bc-step{margin-bottom:auto}
.bc-bar{display:flex;align-items:center;gap:12px;margin-bottom:20px;min-height:26px;flex:0 0 auto}
.bc-back{
  display:inline-flex;align-items:center;gap:5px;background:none;border:0;padding:0;
  color:var(--mut);font:inherit;font-size:12.5px;cursor:pointer;transition:color .15s;
}
.bc-back:hover{color:var(--ink)}
.bc-back[hidden]{display:none}
.bc-steps{display:flex;gap:5px;margin-inline-start:auto}
.bc-pip{width:20px;height:2px;border-radius:2px;background:var(--line);transition:background .25s}
.bc-pip.done{background:var(--mut2)}
.bc-pip.on{background:var(--ink)}
.bc-stepno{font-size:11px;letter-spacing:.07em;text-transform:uppercase;color:var(--mut2)}

.bc-step h4{
  margin:0 0 5px;font-family:var(--font-display);font-weight:600;
  font-size:21px;letter-spacing:-.02em;line-height:1.25;
}
.bc-hint{margin:0 0 16px;font-size:12.5px;color:var(--mut);line-height:1.5}
.bc-step.in{animation:bc-step-in .28s cubic-bezier(.22,.7,.3,1) both}
@keyframes bc-step-in{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){.bc-step.in{animation:none}}

.bc-opts{display:flex;flex-direction:column;gap:8px}
.bc-opts-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
@media(max-width:1200px){.bc-opts-grid{grid-template-columns:1fr}}
.bc-opt{
  position:relative;display:flex;align-items:center;gap:12px;width:100%;text-align:start;
  cursor:pointer;background:var(--card2);border:1px solid var(--line);border-radius:14px;
  padding:12px 14px;min-height:56px;color:var(--ink);font:inherit;
  transition:border-color .15s,background .15s,transform .12s;
}
.bc-opt:hover{border-color:var(--mut2);background:color-mix(in srgb, var(--ink) 3%, var(--card2))}
.bc-opt:active{transform:scale(.99)}
.bc-opt:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.bc-opt-ic{
  flex:0 0 34px;height:34px;display:grid;place-items:center;border-radius:10px;
  border:1px solid var(--line);background:var(--card);color:var(--mut);
}
.bc-opt-ic svg{width:17px;height:17px;display:block}
.bc-opt:hover .bc-opt-ic,.bc-opt.on .bc-opt-ic{color:var(--ink);border-color:var(--mut2)}
.bc-opt-txt{flex:1;min-width:0}
.bc-opt-txt b{display:block;font-size:14px;font-weight:600;letter-spacing:-.01em}
.bc-opt-txt small{display:block;color:var(--mut);font-size:12px;margin-top:2px}
.bc-go{flex:0 0 16px;color:var(--mut2);opacity:0;transition:opacity .15s,transform .15s;transform:translateX(-3px)}
.bc-go svg{width:16px;height:16px;display:block}
.bc-opt:hover .bc-go{opacity:1;transform:none}

/* Multi-select needs to look chosen without colour: a filled tick and an ink
   border do it, and they survive both themes and a colour-blind viewer. */
.bc-tick{
  flex:0 0 20px;height:20px;display:grid;place-items:center;border-radius:6px;
  border:1px solid var(--line);color:transparent;transition:border-color .15s,background .15s,color .15s;
}
.bc-tick svg{width:12px;height:12px;display:block}
.bc-opt.on{border-color:var(--ink);background:color-mix(in srgb, var(--ink) 5%, var(--card2))}
.bc-opt.on .bc-tick{background:var(--ink);border-color:var(--ink);color:var(--bg)}
/* Which one the agent is built around, stated rather than implied by tap order. */
.bc-opt[data-rank]::after{
  content:attr(data-rank);position:absolute;top:-7px;inset-inline-end:12px;
  background:var(--ink);color:var(--bg);border-radius:999px;padding:1px 7px;
  font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;
}

.bc-foot{padding:4px 20px 18px}
.bc-foot[hidden]{display:none}
.bc-next{
  width:100%;min-height:48px;border:1px solid var(--ink);border-radius:12px;
  background:var(--ink);color:var(--bg);font:inherit;font-size:14px;font-weight:600;cursor:pointer;
  transition:filter .15s,opacity .15s;
}
.bc-next:hover{filter:brightness(.92)}
.bc-next[disabled]{opacity:.35;cursor:default;filter:none}
.bc-note{margin:0;padding:0 16px 14px;font-size:11.5px;color:var(--mut2);line-height:1.5}
/* The builder's own marks follow the site's monochrome rule, the same way the
   sidebar brand dot already does — a purple gradient here was the only colour
   on an otherwise ink-and-paper screen. (.bl-avatar is overridden at the end of
   this file, after its own declaration.) */
.bc-dot{background:var(--ink)}
/* `display:flex` beats the `hidden` attribute, so both of these stayed on screen
   while claiming to be hidden — the empty log kept half the card and squashed
   the picker into a strip. Anything in this pane that toggles must say so. */
/* Every block in this pane sets its own `display`, and `display` beats the
   `hidden` attribute. Forgetting one is not cosmetic: the picker stayed on
   screen underneath the conversation after the taps were done. */
.bc-log[hidden],.bc-in[hidden],.bc-picker[hidden],.bc-step[hidden],.bc-foot[hidden]{display:none}
.bc-in{display:flex;gap:9px;padding:13px 15px;border-top:1px solid var(--line2)}
.bc-in input{flex:1;min-width:0;background:var(--card2);border:1px solid var(--line);unicode-bidi:plaintext;
  border-radius:11px;padding:12px 14px;font-family:inherit;font-size:14.5px;color:var(--ink);outline:0}
.bc-in input:focus{border-color:var(--acc)}
.bc-in button{flex:0 0 44px;height:44px;border:0;border-radius:11px;background:var(--acc);color:#fff;
  cursor:pointer;display:grid;place-items:center}
.bc-in button[disabled]{opacity:.45;cursor:default}

.builder-live{position:sticky;top:84px;display:flex;flex-direction:column;gap:16px}
.bl-card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:18px}
.bl-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.bl-id{display:flex;align-items:center;gap:11px;min-width:0}
.bl-avatar{width:38px;height:38px;flex:0 0 38px;border-radius:11px;background:var(--grad1);color:#fff;
  display:grid;place-items:center;font-weight:700;font-size:16px;text-transform:uppercase}
.bl-id strong{display:block;font-size:15px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bl-id small{display:block;color:var(--mut);font-size:12.5px;margin-top:2px}
.bl-state{flex:0 0 auto;font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--mut);
  border:1px solid var(--line);border-radius:999px;padding:4px 10px}
.bl-state.live{color:var(--green);border-color:color-mix(in srgb, var(--green) 45%, transparent)}
.bl-facts{display:grid;gap:8px;margin:16px 0 6px}
.bl-fact{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  border-top:1px solid var(--line2);padding-top:8px}
.bl-fact span{font-size:11.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--mut2);flex:0 0 auto}
.bl-fact b{font-size:13.5px;font-weight:500;text-align:end;color:var(--ink);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bl-preview{margin-top:16px}
.bl-preview #agent-demo:empty{height:0}
.bl-actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px}
.bl-actions .btn-lg{padding:11px 20px;font-size:14px}
.bl-actions .btn-lg[disabled]{opacity:.45;cursor:default}
.bl-actions[hidden]{display:none}

/* ── Agent Studio (/ai/agents.html) ───────────────────────────────────────────
   Build form and live preview sit side by side so a change and its consequence
   are visible at once — the product is "describe it and watch it answer", and a
   separate preview page would break that loop. */
.studio-grid{display:grid;grid-template-columns:1fr 420px;gap:28px;align-items:start;margin-top:22px}
@media(max-width:900px){.studio-grid{grid-template-columns:1fr}.studio-preview{position:static}}
.studio-form .fieldrow{margin-bottom:14px}
.studio-form .fieldrow.two{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.studio-form label,.fieldlabel{display:block;font-size:12px;letter-spacing:.04em;text-transform:uppercase;
  color:var(--mut);margin-bottom:6px}
.studio-form input,.studio-form select,.studio-form textarea{width:100%;padding:11px 13px;font-family:inherit;
  font-size:14px;border-radius:10px;border:1px solid var(--line);background:var(--card2);
  color:var(--ink);outline:0;-webkit-appearance:none;appearance:none}
.studio-form select{background-image:none}
.studio-form input[type=color]{padding:4px;height:44px}
.studio-form textarea{resize:vertical;line-height:1.55}
.studio-form input:focus,.studio-form select:focus,.studio-form textarea:focus{border-color:var(--acc)}
.fieldhint{font-size:12.5px;color:var(--mut);margin:6px 0 0;line-height:1.55}
.checkrow{display:flex!important;align-items:center;gap:8px;font-size:13.5px;text-transform:none;
  letter-spacing:0;color:var(--ink);margin-top:10px}
.checkrow input{width:auto!important}
.studio-more{margin:6px 0 16px;border-top:1px solid var(--line);padding-top:12px}
.studio-more summary{cursor:pointer;font-size:13.5px;color:var(--mut);margin-bottom:12px}
.studio-actions{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-top:8px}
.btn-ghost-sm{display:inline-block;padding:9px 16px;border-radius:9px;font-size:13.5px;font-weight:600;
  cursor:pointer;text-decoration:none;border:1px solid var(--line);background:transparent;
  color:var(--ink)}
.btn-ghost-sm:hover{border-color:var(--acc)}
.studio-msg{font-size:13px;color:var(--mut)}
.studio-msg.ok{color:var(--green)}.studio-msg.err{color:var(--red)}
.my-agents{margin-top:24px;border-top:1px solid var(--line);padding-top:16px}
.my-agents .agent-row{display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:10px 13px;border:1px solid var(--line);border-radius:10px;margin-bottom:8px;
  cursor:pointer;font-size:14px}
.my-agents .agent-row:hover{border-color:var(--mut2)}
.my-agents .agent-row-id{flex:1;min-width:0;cursor:pointer}
.agent-trash{
  flex:0 0 32px;height:32px;display:grid;place-items:center;border-radius:9px;
  border:1px solid var(--line);background:transparent;color:var(--mut2);cursor:pointer;
  transition:color .15s,border-color .15s;
}
.agent-trash:hover{color:var(--red);border-color:color-mix(in srgb, var(--red) 45%, transparent)}
/* The confirm replaces the row rather than floating over it, so there is never
   a question about WHICH agent is being deleted. */
.agent-row.confirming{border-color:color-mix(in srgb, var(--red) 45%, transparent)}
.agent-confirm{display:flex;align-items:center;gap:8px;flex-wrap:wrap;width:100%}
.agent-confirm span{flex:1 1 180px;font-size:12.5px;color:var(--mut)}
.agent-confirm button{border-radius:999px;padding:6px 14px;font:inherit;font-size:12.5px;
  font-weight:600;cursor:pointer;border:1px solid var(--line);background:transparent;color:var(--ink)}
.agent-confirm .agent-del{background:var(--red);border-color:var(--red);color:#fff}
.agent-confirm .agent-del[disabled]{opacity:.5;cursor:default}
.my-agents .agent-row small{display:block;color:var(--mut);font-size:12px;margin-top:2px}
.studio-preview{position:sticky;top:88px}
.embed-tabs{display:flex;gap:8px;flex-wrap:wrap;margin:18px 0 12px}
.embed-tabs button{padding:8px 15px;border-radius:9px;font-size:13px;cursor:pointer;
  border:1px solid var(--line);background:transparent;color:var(--mut)}
.embed-tabs button.on{border-color:var(--acc);color:var(--ink)}
.embed-code{background:var(--card2);border:1px solid var(--line);border-radius:10px;
  padding:14px;overflow:auto;font-size:12.5px;line-height:1.6;white-space:pre-wrap;word-break:break-word;
  color:var(--ink)}

/* Placed last on purpose: .bl-avatar is declared further up, so an override
   written beside the picker rules lost to it and the tile stayed purple. */
.bl-avatar{background:var(--ink);color:var(--bg)}

/* Placed last, after `.bc-bar{margin-top:auto}` in the picker section — written
   beside the mobile layout it lost to a later rule with equal specificity, the
   same way the avatar override did. On a phone the question is top-aligned:
   vertical centring in a tall card left a field of white above it.
   And the live panel does not occupy a phone screen with a card of dashes. */
@media(max-width:980px){
  /* In build mode the card starts directly under the top bar, so centring the
     step in it is symmetric rather than the "white band above the question" the
     old stacked layout produced. Auto margins, so a long list still scrolls
     from its own top. */
  .bc-bar{margin-top:auto}
  /* Hide only the empty draft CARD — not the section, which also holds "Your
     agents". Hiding the whole thing made a phone owner's saved agents, and the
     delete button on them, unreachable. */
  .builder-live.is-empty .bl-card{display:none}
  /* Outside a card on a phone, this list had no gutter of its own and its
     label sat flush against the screen edge. */
  .my-agents{padding-inline:16px}
}

/* ── Build mode (agents.html on a phone) ─────────────────────────────────────
   The complaint that produced this: "too much sliding the screen up and down".
   It was true. The page was a marketing header, then a builder card, then the
   saved-agent list — three stacked things on a 390px screen, so every step of a
   three-tap flow meant scrolling to find the next one.

   Here the builder IS the page: the shell is exactly one viewport tall, nothing
   lives below it, and the only thing that scrolls is the list of options inside
   the card. The saved agents move into a sheet reachable from the card header,
   because a list that only matters occasionally should not push the work
   off-screen permanently. Desktop is untouched — it has the room. */
@media(max-width:980px){
  .app-shell.build-mode{height:100vh;height:100dvh;min-height:0;overflow:hidden}
  .app-shell.build-mode .app-main{min-height:0;overflow:hidden}
  .app-shell.build-mode .app-topbar{padding:10px 16px 6px}
  .app-shell.build-mode .app-content{
    flex:1;min-height:0;display:flex;flex-direction:column;padding:0 12px 10px;overflow:hidden;
  }
  /* The headline is a promise to a first-time visitor; it does not need to be
     re-read on every step, and on a phone it was costing a third of the screen. */
  .app-shell.build-mode .subpage-head{display:none}
  .app-shell.build-mode .builder{flex:1;min-height:0;margin-top:0;display:flex;flex-direction:column}
  .app-shell.build-mode .builder-chat{flex:1;min-height:0;height:auto}
  .app-shell.build-mode .builder-live{display:contents}

  /* Saved agents: a sheet over the builder, not a block under it. */
  .app-shell.build-mode .my-agents{
    position:fixed;inset-inline:0;bottom:0;z-index:120;margin:0;padding:16px 16px max(18px,env(safe-area-inset-bottom));
    background:var(--card);border-top:1px solid var(--line);border-radius:18px 18px 0 0;
    box-shadow:0 -18px 50px rgba(0,0,0,.28);
    transform:translateY(101%);transition:transform .24s cubic-bezier(.22,.7,.3,1);
    max-height:70dvh;overflow-y:auto;
  }
  .app-shell.build-mode .my-agents.open{transform:none}
  .app-shell.build-mode .my-agents[hidden]{display:block}
  @media(prefers-reduced-motion:reduce){.app-shell.build-mode .my-agents{transition:none}}
  .sheet-backdrop{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:119;opacity:0;
    transition:opacity .2s;pointer-events:none}
  .sheet-backdrop.show{opacity:1;pointer-events:auto}
}

/* The saved-agents control in the builder header. */
.bc-mine{
  margin-inline-start:auto;display:inline-flex;align-items:center;gap:6px;
  border:1px solid var(--line);border-radius:999px;background:transparent;color:var(--mut);
  padding:6px 12px;font:inherit;font-size:12.5px;font-weight:600;cursor:pointer;
  transition:color .15s,border-color .15s;
}
.bc-mine:hover{color:var(--ink);border-color:var(--mut2)}
.bc-mine[hidden]{display:none}
.bc-head{align-items:center}
@media(min-width:981px){.bc-mine{display:none}}


/* Legal pages. Long-form prose needs a measure and air; the rest of the site
   is cards and grids and would make a policy unreadable. */
.legal{max-width:720px}
.legal h2{font-family:var(--font-display);font-weight:600;font-size:19px;margin:30px 0 8px}
.legal p{color:var(--mut);font-size:15px;line-height:1.7;margin:0 0 10px}
.legal a{color:var(--ink)}
.legal-updated{font-size:13px;color:var(--mut2);border-bottom:1px solid var(--line);padding-bottom:14px}

.sidebar-legal{font-size:12px;color:var(--mut2);margin:12px 0 0;padding-left:12px;line-height:1.85}
.sidebar-legal a{color:var(--mut2);text-decoration:none}
.sidebar-legal a:hover{color:var(--ink)}

.acct-invite{display:flex;gap:10px;margin-top:12px;flex-wrap:wrap}
.acct-invite .payg-input{flex:1;min-width:220px}
.acct-seat-remove{background:none;border:none;color:var(--mut2);cursor:pointer;font-family:inherit;font-size:13px}
.acct-seat-remove:hover{color:var(--ink)}

.renew-note{text-align:center;font-size:12.5px;color:var(--mut2);max-width:640px;margin:22px auto 0;line-height:1.6}
.renew-note a{color:var(--mut2)}

/* Thirty days of spend, as bars. Deliberately not a charting library: the
   question is "am I using what I pay for", and that is answered by shape. */
.usage-bars{display:flex;align-items:flex-end;gap:3px;height:70px;margin-top:12px}
.usage-bar{flex:1;min-width:3px;background:var(--grad1);border-radius:3px 3px 0 0;opacity:.85}
.usage-bar.is-empty{background:var(--line);opacity:.5;height:2px}

/* Chat toolbar: conversations on the left, model on the right. Scrolls
   horizontally on a phone rather than wrapping into a second row that would
   eat the thread. */
.chat-bar{display:flex;align-items:center;gap:8px;padding:8px 0 10px;flex-wrap:nowrap;overflow-x:auto}
.chat-newbtn{
  flex:none;background:none;border:1px solid var(--line);color:var(--ink);border-radius:999px;
  padding:6px 13px;font-size:13px;cursor:pointer;font-family:inherit
}
.chat-newbtn:hover{background:var(--card)}
.chat-convs{display:flex;gap:6px;flex:1;min-width:0;overflow-x:auto;scrollbar-width:none}
.chat-convs::-webkit-scrollbar{display:none}
.chat-conv{
  flex:none;display:flex;align-items:center;gap:6px;background:var(--card);border:1px solid var(--line);
  border-radius:999px;padding:5px 10px;font-size:12.5px;color:var(--mut);cursor:pointer;max-width:190px
}
.chat-conv.is-active{color:var(--ink);border-color:var(--ink)}
.chat-conv-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chat-conv-x{border:none;background:none;color:var(--mut2);cursor:pointer;font-size:14px;line-height:1;padding:0}
.chat-conv-x:hover{color:var(--ink)}
.chat-modelwrap{flex:none;display:flex;align-items:center;gap:6px}
.chat-modelwrap-label{font-size:12px;color:var(--mut2)}
.chat-model{
  background:var(--card);border:1px solid var(--line);color:var(--ink);border-radius:999px;
  padding:6px 10px;font-size:12.5px;font-family:inherit;max-width:210px
}

.msg-model,.msg-sources{font-size:11.5px;color:var(--mut2);margin:4px 0 0 42px}
.msg-model.is-sub{color:#d9a441}
.msg-sources a{color:var(--mut2);text-decoration:underline;text-underline-offset:2px}
.msg-sources a:hover{color:var(--ink)}

/* Recent chats in the nav. Same shape as a sidebar link so the drawer reads as
   one list, not two designs stacked. */
/* The New chat pill sits at the foot of the drawer and stays there while the
   Recents list scrolls — starting a new chat must never require scrolling past
   the old ones. */
.sidebar-newchat{
  position:sticky;bottom:12px;align-self:center;
  margin:14px 12px 12px;padding:11px 22px;
  background:var(--ink);color:var(--bg);border:none;border-radius:999px;
  font-size:14px;font-weight:600;font-family:inherit;cursor:pointer;
  box-shadow:0 6px 20px rgba(0,0,0,.35)
}
.sidebar-newchat:hover{opacity:.9}
.sidebar-convs{display:flex;flex-direction:column;gap:1px;max-height:38vh;overflow-y:auto;padding:2px 0}
.sidebar-conv{
  display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:8px;
  color:var(--mut);font-size:13px;cursor:pointer
}
.sidebar-conv:hover{background:var(--card);color:var(--ink)}
.sidebar-conv.is-active{color:var(--ink);background:var(--card)}
.sidebar-conv-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}
.sidebar-conv-x,.sidebar-conv-edit{
  border:none;background:none;color:var(--mut2);cursor:pointer;
  font-size:16px;line-height:1;
  flex:none;width:30px;height:30px;margin:-6px -4px -6px 0;
  display:inline-flex;align-items:center;justify-content:center;border-radius:8px
}
.sidebar-conv-edit{font-size:13px}
.sidebar-conv-x:hover,.sidebar-conv-edit:hover{color:var(--ink);background:rgba(127,127,127,.14)}
/* Replaces the title span while renaming — same box, same font, so nothing
   in the row reflows the moment you click the pencil. */
.sidebar-conv-title-edit{
  flex:1;min-width:0;font:inherit;font-size:13px;color:var(--ink);
  background:var(--bg2);border:1px solid var(--acc2);border-radius:6px;
  padding:1px 6px;margin:-2px 0
}
/* Search sits above Recents, only while the list is expanded — the toggle
   already hides both together (chat.js keeps their `hidden` in lockstep). */
.sidebar-conv-search{
  width:calc(100% - 16px);margin:0 8px 6px;padding:6px 10px;font:inherit;font-size:13px;
  color:var(--ink);background:var(--bg2);border:1px solid var(--line);border-radius:8px
}
.sidebar-conv-search:focus{outline:none;border-color:var(--mut2)}
.sidebar-conv-search::placeholder{color:var(--mut2)}
/* Thumb-size on touch: a 30px invisible square is still hard to hit; give
   the visual × a ghost background only where it counts — on tap. */
@media (max-width:900px){
  .sidebar-conv{padding:11px 10px}
  .sidebar-conv-x,.sidebar-conv-edit{width:36px;height:36px;margin:0 -6px 0 0;font-size:17px}
  .sidebar-convs{padding-top:6px}
}

/* Docs page: config a reader can paste, so the code blocks are the content and
   get the room to prove it. */
.doc h2{font-family:var(--font-display);font-weight:600;font-size:21px;margin:38px 0 6px}
.doc h3{font-weight:600;font-size:14px;color:var(--mut);margin:22px 0 6px;letter-spacing:.01em}
.doc-code{
  background:var(--card);border:1px solid var(--line);border-radius:12px;
  padding:14px 16px;overflow-x:auto;margin:0
}
.doc-code code{font-size:13px;line-height:1.65;color:var(--ink);white-space:pre;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
.doc code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px}
.doc-beta{
  font-size:11px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;
  color:var(--gold);border:1px solid var(--gold);border-radius:999px;padding:2px 8px;
  vertical-align:middle;margin-left:8px
}

/* === PRODUCT FLOWS (voice, speed-to-lead, automate, build, all in) ==========
   Each product page is a click path that ends in a real thing, so the flow card
   is the page's centre of gravity, not a widget under a pitch. It reuses the
   studio picker's option cards (.bc-opt and friends) on purpose — a second
   visual language for the same gesture would read as two products.
   NOTE: keep this block LAST in the file. Three separate bugs on 2026-08-17 came
   from mobile overrides losing to later rules of equal specificity. */
.pf{margin:0 auto;max-width:720px;width:100%}
.pf-card{
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:22px 22px 20px;display:flex;flex-direction:column;gap:0;
}
.pf-bar{display:flex;align-items:center;gap:12px;margin-bottom:18px;min-height:26px}
.pf-body{min-height:180px}
.pf-step h4{margin-bottom:6px}
.pf-opts{display:grid;grid-template-columns:1fr 1fr;gap:8px}
@media(max-width:640px){.pf-opts{grid-template-columns:1fr}}
.pf-foot{margin-top:18px}

/* The one place typing is unavoidable. It gets room rather than being squeezed
   in under the taps, because a cramped field reads as an afterthought. */
.pf-form{display:flex;flex-direction:column;gap:14px}
.pf-field{display:flex;flex-direction:column;gap:6px}
.pf-field-label{font-size:12.5px;font-weight:600;color:var(--mut)}
.pf-field input,.pf-field textarea{
  background:var(--card2);border:1px solid var(--line);border-radius:12px;
  padding:12px 14px;color:var(--ink);font:inherit;font-size:14.5px;width:100%;
  transition:border-color .15s;resize:vertical;
}
.pf-field input:focus,.pf-field textarea:focus{outline:none;border-color:var(--mut2)}
.pf-field input::placeholder,.pf-field textarea::placeholder{color:var(--mut2)}
.pf-field-hint{font-size:11.5px;color:var(--mut2);line-height:1.5}
.pf-check{display:flex;align-items:flex-start;gap:10px;cursor:pointer}
.pf-check input{width:18px;height:18px;flex:0 0 18px;margin-top:1px;accent-color:var(--ink)}
.pf-check-txt{font-size:12.5px;color:var(--mut);line-height:1.55}
.pf-check-txt a{color:var(--ink);text-decoration:underline}

.pf-working{display:flex;align-items:center;gap:12px;padding:26px 2px;color:var(--mut);font-size:14px}
.pf-spin{
  width:17px;height:17px;flex:none;border-radius:50%;
  border:2px solid var(--line);border-top-color:var(--ink);animation:pf-spin .7s linear infinite;
}
@keyframes pf-spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){.pf-spin{animation-duration:2.4s}}

.pf-done{
  width:34px;height:34px;border-radius:50%;display:grid;place-items:center;margin-bottom:12px;
  background:var(--ink);color:var(--bg);
}
.pf-done svg{width:18px;height:18px}
.pf-answer{
  background:var(--card2);border:1px solid var(--line);border-left:2px solid var(--mut2);
  border-radius:12px;padding:13px 15px;margin:0 0 16px;
  font-size:13.5px;line-height:1.65;color:var(--mut);white-space:pre-wrap;
}
[dir="rtl"] .pf-answer,.pf-answer[dir="auto"]:dir(rtl){border-left:1px solid var(--line);border-right:2px solid var(--mut2)}
/* The result is a list of things to do next, so each one is a row you can hit,
   not a paragraph with links buried in it. */
.pf-act{
  display:flex;align-items:center;gap:12px;width:100%;text-align:start;margin-bottom:8px;
  background:var(--card2);border:1px solid var(--line);border-radius:14px;
  padding:12px 14px;min-height:56px;color:var(--ink);font:inherit;cursor:pointer;
  transition:border-color .15s,background .15s;
}
.pf-act:hover{border-color:var(--mut2);background:color-mix(in srgb, var(--ink) 3%, var(--card2))}
.pf-act.is-primary{border-color:var(--ink)}
.pf-act-txt{flex:1;min-width:0}
.pf-act-txt b{display:block;font-size:14px;font-weight:600}
.pf-act-txt small{display:block;font-size:12px;color:var(--mut);margin-top:2px}
.pf-act-go{font-size:12px;font-weight:600;color:var(--mut);flex:none}
.pf-act:hover .pf-act-go{color:var(--ink)}
.pf-note{margin:14px 0 0;font-size:12px;color:var(--mut2);line-height:1.6}
.pf-again{
  margin-top:14px;background:none;border:0;padding:0;color:var(--mut);
  font:inherit;font-size:12.5px;text-decoration:underline;cursor:pointer;
}
.pf-again:hover{color:var(--ink)}

/* Under the flow, not above it: the three claims are context for a decision the
   visitor is already making with their thumbs. */
.pf-below{margin-top:34px}

/* On a phone the flow must not turn into a page you scroll to find the next
   step — that was the complaint the studio picker already earned. The card owns
   one screen: the step scrolls inside it, the counter and the Continue button
   never leave the viewport, and everything else on the page sits below the fold
   where it belongs. */
@media(max-width:640px){
  .pf-card{padding:16px 15px 15px}
  .pf-body{max-height:50dvh;min-height:180px;overflow-y:auto;overscroll-behavior:contain;
    -webkit-overflow-scrolling:touch}
  .pf-step h4{font-size:19px}
  .pf-act{padding:11px 13px}
}
@media(max-width:640px){
  /* The result is the payoff, not a step: capping it hid the honest note about what
     did and did not happen, which is the last thing that should scroll out of reach. */
  .pf-card.is-done .pf-body{max-height:none;overflow:visible}
  /* A row cut in half by the inner scroll reads as a rendering fault. The fade says
     "there is more" on purpose. */
  .pf-card:not(.is-done) .pf-body{
    -webkit-mask-image:linear-gradient(to bottom,#000 calc(100% - 26px),transparent);
    mask-image:linear-gradient(to bottom,#000 calc(100% - 26px),transparent);
  }
  .pf-card:not(.is-done) .pf-body.is-end{-webkit-mask-image:none;mask-image:none}
}

/* === MODEL PICKER ON THE COMPOSER =========================================
   Moved off the conversations toolbar: the model applies to the message being
   typed, so it belongs to the box you type in. Opens upward, because it lives
   at the bottom of the screen. Keep after the .chat-* block above. */
.chat-composer-wrap{width:100%;max-width:760px;margin:0 auto;position:relative}
.chat-composer-wrap .chat-composer{max-width:none}
.chat-modelpick{position:relative;margin-top:8px;display:flex}
.chat-modelbtn{
  display:inline-flex;align-items:center;gap:7px;background:var(--card);
  border:1px solid var(--line);border-radius:999px;padding:6px 12px 6px 10px;
  color:var(--ink);font:inherit;font-size:12.5px;cursor:pointer;
  transition:border-color .15s,background .15s;
}
.chat-modelbtn:hover{border-color:var(--mut2)}
.chat-modelbtn-ic{display:inline-flex;color:var(--mut)}
.chat-modelbtn-ic svg{width:15px;height:15px;display:block}
.chat-modelbtn-chev{width:13px;height:13px;color:var(--mut2);transition:transform .18s}
.chat-modelbtn[aria-expanded="true"] .chat-modelbtn-chev{transform:rotate(180deg)}

.chat-modelmenu{
  position:absolute;bottom:calc(100% + 8px);inset-inline-start:0;z-index:60;
  width:min(340px,calc(100vw - 32px));max-height:min(420px,60vh);overflow-y:auto;
  background:var(--card);border:1px solid var(--line);border-radius:14px;padding:6px;
  box-shadow:0 18px 46px rgba(0,0,0,.5);
}
html[data-theme="light"] .chat-modelmenu{box-shadow:0 18px 46px rgba(0,0,0,.12)}
.chat-modelmenu[hidden]{display:none}
.chat-modelmenu-label{
  font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--mut2);
  padding:12px 10px 6px;border-top:1px solid var(--line2);margin-top:6px;
}
.chat-modelopt{
  display:flex;align-items:center;gap:10px;width:100%;text-align:start;
  background:none;border:0;border-radius:10px;padding:9px 10px;color:var(--ink);
  font:inherit;cursor:pointer;
}
.chat-modelopt:hover{background:var(--card2)}
.chat-modelopt-txt{flex:1;min-width:0}
.chat-modelopt-txt b{display:block;font-size:13.5px;font-weight:600}
.chat-modelopt-txt small{display:block;font-size:11.5px;color:var(--mut);margin-top:1px}
.chat-modelopt-tick{flex:0 0 15px;color:transparent}
.chat-modelopt-tick svg{width:15px;height:15px;display:block}
.chat-modelopt.is-on .chat-modelopt-tick{color:var(--ink)}

/* === RENDERED ANSWERS =====================================================
   Model output is markdown and often Hebrew. Both were shown raw: literal **
   on screen, and a right-to-left paragraph laid out left-to-right so every
   dash and question mark landed on the wrong side. The renderer now emits real
   blocks, each carrying dir="auto" — per paragraph, because one thread holds
   both languages. This block styles them; keep it after the .msg rules. */
.msg .body.is-rich{white-space:normal}
.msg .body.is-rich > *:first-child{margin-top:0}
.msg .body.is-rich > *:last-child{margin-bottom:0}
.msg .body.is-rich p{margin:0 0 11px;line-height:1.68}
.msg .body.is-rich h3{
  font-family:var(--font-display);font-weight:600;font-size:17.5px;
  letter-spacing:-.01em;margin:18px 0 7px;line-height:1.35;
}
.msg .body.is-rich h4{font-weight:650;font-size:14.5px;margin:15px 0 6px;color:var(--ink)}
.msg .body.is-rich ul,.msg .body.is-rich ol{margin:0 0 11px;padding-inline-start:22px}
.msg .body.is-rich li{margin:0 0 5px;line-height:1.62}
.msg .body.is-rich li::marker{color:var(--mut2)}
.msg .body.is-rich blockquote{
  margin:0 0 11px;padding:2px 0 2px 13px;border-inline-start:2px solid var(--line);color:var(--mut);
}
/* border-inline-start already flips for an RTL block, so a Hebrew quote is
   marked on its own side without a second rule. */
.msg .body.is-rich hr{border:0;border-top:1px solid var(--line2);margin:16px 0}
.msg .body.is-rich strong{font-weight:650}
.msg .body.is-rich code{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12.8px;
  background:var(--card2);border:1px solid var(--line2);border-radius:6px;padding:1px 5px;
  unicode-bidi:isolate;   /* an identifier must not be re-ordered by a Hebrew sentence */
}
.msg .body.is-rich a{color:var(--ink);text-decoration:underline;text-underline-offset:2px}
.msg .body.is-rich a:hover{color:var(--acc2)}
.msg .body.is-rich .chat-code{margin:0 0 12px;direction:ltr;text-align:start}
.msg .body.is-rich .chat-code code{background:none;border:0;padding:0}
/* The answer stamp follows the answer's own side, not the page's. */
.msg-model,.msg-sources{unicode-bidi:isolate}
/* The row mirrors with the language (see dirOf in chat.js), so every offset here
   has to be logical rather than left/right — otherwise the avatar gap and the
   model stamp stay pinned to the left of a right-to-left answer. */
.msg-model,.msg-sources{margin:4px 0 0;margin-inline-start:42px}
/* "1." must not be re-ordered into ".1" by the surrounding Hebrew. */
.msg .body.is-rich li::marker{unicode-bidi:isolate}
/* The stamp is a third child of a flex row, so it sat on the same line as the
   answer's first paragraph — on the left in an English thread, and stranded far
   from the text once the row mirrored. It gets its own line under the body. */
.msg{flex-wrap:wrap}
.msg-model,.msg-sources{flex:0 0 100%;order:3}
/* The paid tier is visible to everyone and tappable by everyone — a locked row
   that does nothing teaches nothing, so it goes to the plans page. */
.chat-modelopt.is-locked .chat-modelopt-txt b{color:var(--mut)}
.chat-modeltag{
  flex:none;font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--bg);background:var(--ink);border-radius:999px;padding:2px 7px;
}

/* The bar under the chat: what model this message uses, and which thread you
   are in. Recents used to sit in a strip ABOVE the thread — the first thing on
   a phone screen was a list of old chats, above the one you came to read — and
   in the nav drawer, which is closed. Under the composer they are one thumb
   away and never in front of the conversation. */
.chat-tools{
  display:flex;align-items:center;gap:8px;margin-top:8px;
  overflow-x:auto;scrollbar-width:none;position:relative;
}
.chat-tools::-webkit-scrollbar{display:none}
.chat-tools .chat-modelpick{flex:none;position:static}
.chat-tools .chat-newbtn{flex:none;padding:6px 12px;font-size:12.5px}
.chat-tools .chat-convs{display:flex;gap:6px;flex:1;min-width:0;overflow:visible}
/* The menu is positioned against the composer wrapper, not the scrolling row —
   inside an overflow-x container it would be clipped the moment it opened. */
.chat-composer-wrap{position:relative}
.chat-composer-wrap .chat-modelmenu{position:absolute;bottom:calc(100% + 46px);inset-inline-start:0}

/* Recents was labelled and empty. The list is a flex child of the sidebar
   column, and with no flex-basis a tall nav squeezed it to zero height — the
   chats were rendered into a box 0px high. It keeps its own height now. */
.sidebar-convs{flex:none}
/* New chat reads as the first row of the nav rather than a pill floating over
   the footer links, which is where it was landing on a short window. */
.sidebar-newrow{width:100%;background:none;border:0;font:inherit;font-size:14px;
  font-weight:500;text-align:start;cursor:pointer}

/* === THE THREAD, REBUILT ===================================================
   "Still does not sit as nicely as ChatGPT" — and the reason was structural,
   not decorative. Every turn was an avatar circle plus a run of plain text, so
   both sides of the conversation looked identical and nothing marked where one
   speaker stopped. The shape every good assistant converged on is: the person's
   words in a bubble on one side, the assistant's answer as plain prose across
   the column with no avatar at all — the answer IS the page, and giving it a
   badge makes it look like a chat widget.
   Keep this block last; it deliberately overrides the .msg rules above. */
.chat-thread{gap:26px;padding-bottom:32px}

.msg{display:block;flex-wrap:nowrap;line-height:1.7;font-size:15.5px}
.msg .who{display:none}                 /* no avatars on either side */

/* The visitor's turn: a bubble, always on the trailing side, whatever language
   it is in — a Hebrew message flips its TEXT, not its side, otherwise the two
   speakers swap places mid-thread and the eye loses the pattern. */
.msg.user{display:flex;justify-content:flex-end}
.msg.user .body{
  background:var(--card);border:1px solid var(--line);border-radius:18px;
  padding:10px 15px;max-width:78%;width:auto;flex:0 1 auto;
}
html[data-theme="light"] .msg.user .body{background:color-mix(in srgb, var(--ink) 4%, var(--card))}

/* The answer: no bubble, no badge, the full width of the column. */
.msg.bot .body{max-width:100%}
.msg.err .body{
  background:color-mix(in srgb, var(--red) 10%, transparent);
  border:1px solid color-mix(in srgb, var(--red) 35%, transparent);
  border-radius:14px;padding:11px 14px;
}
.msg-model,.msg-sources{margin:6px 0 0;margin-inline-start:0;font-size:11px}

@media(max-width:640px){
  .chat-thread{gap:22px}
  .msg{font-size:15px}
  .msg.user .body{max-width:88%}
}
/* The ROW is layout, not text: it stays left-to-right so the person's bubble is
   always on the same side of the thread. Without this, a Hebrew turn made the
   row RTL and flex-end put the bubble on the LEFT — the two speakers swapped
   sides mid-conversation. Every text element inside still carries its own dir. */
.msg{direction:ltr}
/* The stamp carries its own dir (set from the answer), so start-alignment puts
   it under the side the answer actually sits on. */
.msg-model,.msg-sources{text-align:start}

/* === COMPOSER ATTACHMENTS ================================================= */
.chat-iconbtn{
  flex:none;width:34px;height:34px;border-radius:50%;border:1px solid var(--line);
  background:none;color:var(--mut);display:grid;place-items:center;cursor:pointer;
  transition:color .15s,border-color .15s;
}
.chat-iconbtn svg{width:17px;height:17px}
.chat-iconbtn:hover{color:var(--ink);border-color:var(--mut2)}
/* Recording is a state you must not be able to miss. */
.chat-iconbtn.is-recording{color:#fff;background:var(--red);border-color:var(--red);animation:rec-pulse 1.2s ease-in-out infinite}
@keyframes rec-pulse{50%{box-shadow:0 0 0 6px color-mix(in srgb, var(--red) 25%, transparent)}}
@media(prefers-reduced-motion:reduce){.chat-iconbtn.is-recording{animation:none}}

.chat-attach-strip{
  max-width:760px;margin:0 auto 8px;display:flex;gap:8px;flex-wrap:wrap;width:100%;
}
.chat-attchip{
  position:relative;display:inline-flex;align-items:center;gap:6px;
  background:var(--card);border:1px solid var(--line);border-radius:10px;padding:4px;
}
.chat-attchip img{width:52px;height:52px;object-fit:cover;border-radius:7px;display:block}
.chat-attchip-name{font-size:12px;color:var(--ink);padding:6px 4px;max-width:180px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.chat-attchip button{
  position:absolute;top:-7px;inset-inline-end:-7px;width:18px;height:18px;border-radius:50%;
  border:none;background:var(--ink);color:var(--bg);font-size:12px;line-height:1;cursor:pointer;
}

/* Inside the sent bubble */
.msg-images{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
.msg-images img{max-width:180px;max-height:180px;border-radius:10px;display:block}
.msg-filetag{font-size:12px;color:var(--mut);margin-top:6px}

/* === 2026-08-19 readability pass — "everything a step bigger".
   Small text and 34px round targets are a desktop habit that fails on a
   phone. One block, at the end, so it wins. */
.chat-thread{font-size:17px}
.msg{font-size:17px;line-height:1.7}
.msg .body{font-size:17px}
.msg-model,.msg-sources{font-size:12.5px;margin-left:46px}
.app-input-form input,.app-input-form textarea{font-size:17px;padding:13px 0}
.app-input-form button{width:46px;height:46px}
.chat-iconbtn{width:46px;height:46px}
.chat-iconbtn svg{width:20px;height:20px}
.chat-modelbtn{font-size:14.5px;padding:9px 16px 9px 13px}
.chat-modelbtn-ic svg{width:17px;height:17px}
.chat-modelbtn-chev{width:15px;height:15px}
.chat-modelopt{padding:12px 14px}
.chat-modelopt-txt b{font-size:15px}
.chat-modelopt-txt small{font-size:12.5px;margin-top:2px}
.chat-modelmenu-label{font-size:12px}
.chat-attach-strip .chip{font-size:13.5px}
@media(max-width:640px){
  .chat-thread{font-size:18px}
  .msg,.msg .body{font-size:18px}
  .app-input-form input,.app-input-form textarea{font-size:18px}
  .chat-modelopt-txt b{font-size:16px}
  .chat-modelopt-txt small{font-size:13px}
  .chat-modelbtn{font-size:15px}
  .chat-modelmenu{max-height:min(440px,62vh)}
}

/* 2026-08-19 21:32 — the mobile menu bug: the menu opened but the message
   thread painted OVER it (elementFromPoint at menu center hit .chat-thread),
   so tapping "more models" showed nothing. The menu must outrank everything
   in the chat pane, including the mobile composer sheet (z-120). */
.chat-composer-wrap{z-index:130}
.chat-composer-wrap .chat-modelmenu{z-index:131}
.chat-modelmenu{z-index:131}

/* 21:36 — THE mobile model-menu bug, root cause found: .chat-tools has
   overflow-x:auto, which clips everything that escapes the row — and the
   model menu opens UPWARD, outside it. The menu opened, was fully rendered,
   and was completely invisible. Anchor it to .chat-modelpick and stop
   clipping. (Desktop worked only because its layout left headroom.) */
.chat-tools{overflow-x:visible;overflow-y:visible}
.chat-tools .chat-modelpick{position:relative;flex:none}

/* 21:37 — sidebar readability pass. The rail and everything in it were
   desktop-sized (14px links, 260px width). One block, end of file, wins. */
.sidebar{width:300px;flex:0 0 300px;padding:22px 16px}
.sidebar-brand{font-size:18px;padding:8px 10px 22px}
.sidebar-brand .brand-mark svg{width:24px;height:24px}
.sidebar-link{font-size:16px;padding:13px 14px;gap:12px}
.sidebar-link .ic{font-size:18px;width:22px}
.sidebar-foot{font-size:14px}
.chat-newbtn{font-size:15px;padding:11px 16px}
.chat-tools .chat-newbtn{font-size:14.5px;padding:8px 14px}
.chat-modelwrap-label{font-size:13.5px}
.side-convs-label,.convs-label,.chat-side-label{font-size:13px}
.side-convs button,.chat-side-item,.sidebar .conv-item{font-size:15px}
@media(max-width:900px){
  .sidebar{width:min(320px,86vw);flex:0 0 min(320px,86vw)}
  .sidebar-link{font-size:17px;padding:15px 16px}
  .sidebar-brand{font-size:19px}
}

/* --- Plan term picker (prepaid month/quarter/year, no auto-renewal) --- */
.acct-plan-terms{display:flex;gap:6px;margin:10px 0 4px;flex-wrap:wrap}
.acct-term{font:600 13px/1 var(--font-sans,inherit);padding:8px 12px;border:1px solid var(--brd,#2a3244);border-radius:9px;background:transparent;color:var(--mut,#9aa7bd);cursor:pointer}
.acct-term.selected{background:var(--acc,#3b82f6);border-color:var(--acc,#3b82f6);color:#fff}
.acct-plan-total{font-size:13px;color:var(--mut2,#7b8aa3);margin:2px 0 6px}

/* === COMPOSER: THE FOUR CONTROLS MUST FIT A PHONE ==========================
   Measured 2026-08-20 at 390px: the form was 362px wide and the Send button's
   right edge sat at 401px — 25px outside its own container. The cause is the
   oldest flexbox trap there is: a
   flex item will not shrink below its MIN-CONTENT width, and an <input>'s
   min-content comes from its default size attribute (~20 characters). So the
   text field refused to give up ~200px and pushed Send off the edge.
   min-width:0 is the fix; the tighter mobile metrics are what make four
   controls read as comfortable rather than merely legal. */
.app-input-form input,.app-input-form textarea{min-width:0}
@media(max-width:640px){
  .app-input-form{padding:6px 6px 6px 10px;gap:6px}
  .app-input-form input,.app-input-form textarea{font-size:16px;padding:9px 0}  /* 16px: iOS zooms below it */
  .app-input-form button{width:36px;height:36px}
  .chat-iconbtn{width:32px;height:32px}
  .chat-iconbtn svg{width:16px;height:16px}
}

/* === THE DRAWER IS THE TOP OF THE STACK ===================================
   Photographed 2026-08-20 01:13: with the nav drawer open, the composer pill
   and the model pill floated ON TOP of it. Cause: .chat-composer-wrap was given
   z-index:130 so the model menu could escape its scrolling row — and 130 beats
   the drawer's 100 and the backdrop's 99. A modal surface must outrank every
   page control, so the drawer and its backdrop move above them, and the toggle
   moves above the drawer so it can still be tapped to close.
   !important on the toggle because its z-index is an inline style in the
   template of every page here, and inline beats a stylesheet. */
@media(max-width:900px){
  .sidebar{z-index:200}
  .sidebar-backdrop{z-index:199}
  .mobile-toggle{z-index:201 !important}
}

/* === TAP TARGETS AND SCROLL AFFORDANCE ====================================
   Swept all 18 /ai pages at 390 and 1280 on 2026-08-20. Desktop came back
   clean; on the phone two things were real.

   The menu button measured 34x28. Apple's own guidance is 44x44, and this is
   the single control every page depends on. Padding, not icon size — the three
   bars stay the same weight, the hit area grows around them. */
@media(max-width:900px){
  .mobile-toggle{padding:12px;display:grid;place-content:center;min-width:44px;min-height:44px}
}
/* The model catalogue is a 640px table inside a scroller. It DOES scroll — but
   on a phone nothing said so, and a table that runs off the edge reads as
   broken rather than swipeable. A fade on the trailing edge is the whole fix. */
@media(max-width:900px){
  .models-wrap{-webkit-overflow-scrolling:touch;position:relative}
  .models-wrap::after{
    content:'';position:absolute;top:0;bottom:0;inset-inline-end:0;width:26px;pointer-events:none;
    background:linear-gradient(to left,var(--bg),transparent);
  }
  [dir="rtl"] .models-wrap::after{background:linear-gradient(to right,var(--bg),transparent)}
}

/* === VOICE DEMO: "Maya calls you" =========================================
   The one thing on this page that proves the product in ten seconds, so it sits
   above the setup flow and looks like the offer it is. Same ink-and-paper rules
   as the rest of /ai: one accent, line icons, Fraunces on the heading. */
.vd{
  max-width:720px;margin:0 auto 28px;background:var(--card);border:1px solid var(--line);
  border-radius:var(--radius);padding:22px;
}
.vd-head{display:flex;gap:14px;align-items:flex-start;margin-bottom:18px}
.vd-ring{
  flex:none;width:40px;height:40px;border-radius:50%;display:grid;place-items:center;
  border:1px solid var(--line);color:var(--ink);
}
.vd-ring svg{width:19px;height:19px}
.vd-head h2{font-family:var(--font-display);font-weight:600;font-size:21px;letter-spacing:-.02em;margin:0 0 4px}
.vd-head p{margin:0;font-size:13.5px;line-height:1.6;color:var(--mut)}
.vd-form{display:flex;flex-direction:column;gap:12px}
.vd-field{display:flex;flex-direction:column;gap:6px}
.vd-field>span{font-size:12.5px;font-weight:600;color:var(--mut)}
.vd-field input,.vd-field select{
  background:var(--card2);border:1px solid var(--line);border-radius:12px;padding:12px 14px;
  color:var(--ink);font:inherit;font-size:15px;width:100%;min-width:0;
}
.vd-field input:focus,.vd-field select:focus{outline:none;border-color:var(--mut2)}
.vd-row{display:flex;gap:12px;align-items:flex-end}
.vd-field-sm{flex:0 0 40%}
.vd-call{
  flex:1;min-height:48px;border:1px solid var(--ink);border-radius:12px;background:var(--ink);
  color:var(--bg);font:inherit;font-size:15px;font-weight:600;cursor:pointer;transition:filter .15s;
}
.vd-call:hover{filter:brightness(.92)}
.vd-call[disabled]{opacity:.55;cursor:default}
.vd-note{margin:14px 0 0;font-size:12.5px;line-height:1.6;color:var(--mut2)}
.vd-note.is-ok{color:var(--ink)}
.vd-note.is-warn{color:var(--red)}
@media(max-width:640px){
  .vd{padding:18px 16px}
  .vd-head h2{font-size:19px}
  .vd-row{flex-direction:column;align-items:stretch}
  .vd-field-sm{flex:none}
  .vd-field input,.vd-field select{font-size:16px}  /* iOS zooms below 16px */
  .vd-call{min-height:50px}
}

/* === THE ORB: tap to talk =================================================
   The bubble is the demo. It is the one place on /ai that gets motion, because
   the motion IS the message — idle it breathes, connecting it pulses faster,
   live it holds a steady ring. Monochrome like everything else here; the state
   is carried by the ring, never by colour alone. */
.vd-orbwrap{display:flex;flex-direction:column;align-items:center;text-align:center;padding:6px 0 4px}
.vd-orb{
  position:relative;width:132px;height:132px;border-radius:50%;border:0;padding:0;cursor:pointer;
  background:none;display:grid;place-items:center;
}
.vd-orb-core{
  width:100%;height:100%;border-radius:50%;
  background:radial-gradient(circle at 32% 30%, color-mix(in srgb, var(--ink) 22%, var(--card2)), var(--card2) 68%);
  border:1px solid var(--line);
  box-shadow:0 10px 40px rgba(0,0,0,.35), inset 0 1px 0 color-mix(in srgb, var(--ink) 10%, transparent);
  animation:orb-breathe 4s ease-in-out infinite;
}
.vd-orb-ring{
  position:absolute;inset:-8px;border-radius:50%;border:1px solid var(--line);opacity:.6;
}
.vd-orb:hover .vd-orb-core{border-color:var(--mut2)}
.vd-orb:focus-visible{outline:2px solid var(--ink);outline-offset:6px;border-radius:50%}
.vd-orb.is-connecting .vd-orb-ring{animation:orb-pulse 1s ease-out infinite;border-color:var(--mut2)}
.vd-orb.is-live .vd-orb-core{
  border-color:var(--ink);
  box-shadow:0 0 0 3px color-mix(in srgb, var(--ink) 14%, transparent), 0 10px 40px rgba(0,0,0,.35);
  animation:orb-breathe 2.2s ease-in-out infinite;
}
.vd-orb.is-live .vd-orb-ring{animation:orb-pulse 2.2s ease-out infinite;border-color:var(--ink)}
@keyframes orb-breathe{50%{transform:scale(1.035)}}
@keyframes orb-pulse{0%{transform:scale(1);opacity:.6}100%{transform:scale(1.28);opacity:0}}
@media(prefers-reduced-motion:reduce){
  .vd-orb-core,.vd-orb-ring{animation:none !important}
}
.vd-orb-hint{
  display:inline-flex;align-items:center;gap:7px;margin:16px 0 0;
  font-size:14px;font-weight:600;color:var(--ink);
}
.vd-orb-hint svg{width:14px;height:14px;flex:none;color:var(--mut)}
.vd-orb-hint.is-live svg{color:var(--ink)}
.vd-orb-sub{margin:8px 0 0;font-size:12.5px;line-height:1.6;color:var(--mut);max-width:44ch}

/* The seam between the two demos: talk now, or be called. */
.vd-sep{display:flex;align-items:center;gap:12px;margin:22px 0 18px;color:var(--mut2);font-size:11.5px;
  letter-spacing:.06em;text-transform:uppercase}
.vd-sep::before,.vd-sep::after{content:'';flex:1;height:1px;background:var(--line)}
@media(max-width:640px){
  .vd-orb{width:112px;height:112px}
  .vd-orb-sub{font-size:12px}
}

/* === THE VOICE HERO: the orb IS the page ==================================
   The orb is the centre of the page, not a feature. So it
   stops being a widget inside a card and becomes the hero — first thing on
   screen, centred, holding the fold on its own. Everything else on the page is
   demoted below it: the phone form, the setup flow, the three claims. */
.vhero{
  min-height:min(72vh,560px);display:flex;flex-direction:column;align-items:center;
  justify-content:center;text-align:center;padding:24px 0 8px;gap:0;
}
.vhero .vd-orb{width:200px;height:200px}
.vhero-title{
  font-family:var(--font-display);font-weight:600;letter-spacing:-.02em;
  font-size:clamp(30px,5vw,44px);margin:28px 0 0;line-height:1.1;
}
.vhero-hint{
  display:inline-flex;align-items:center;gap:8px;margin:14px 0 0;
  font-size:15px;font-weight:600;color:var(--ink);
}
.vhero-hint svg{width:15px;height:15px;flex:none;color:var(--mut)}
.vhero-hint.is-live svg{color:var(--ink)}
.vhero-sub{margin:12px auto 0;max-width:52ch;font-size:14px;line-height:1.65;color:var(--mut)}
/* A second ring, only on the hero: at this size one ring reads thin. */
.vd-orb-ring2{inset:-18px;opacity:.35}
.vd-orb.is-connecting .vd-orb-ring2,.vd-orb.is-live .vd-orb-ring2{animation:orb-pulse 2.6s ease-out .4s infinite}

/* The phone panel is now the quieter half of the page. */
.vd-secondary{background:none;border:0;padding:0;max-width:560px}
.vd-secondary .vd-sep{margin-top:6px}

@media(max-width:640px){
  .vhero{min-height:58vh;padding:12px 0 4px}
  .vhero .vd-orb{width:158px;height:158px}
  .vhero-title{margin-top:22px}
  .vhero-sub{font-size:13.5px}
}

/* The country code is a control, not a memory test. */
.vd-phone{display:flex;gap:8px;align-items:stretch}
.vd-phone select{flex:0 0 128px;width:128px}
.vd-phone input{flex:1;min-width:0}
.vd-e164{display:block;margin-top:6px;font-size:12px;color:var(--mut2);font-variant-numeric:tabular-nums}
.vd-e164.is-bad{color:var(--red)}
@media(max-width:640px){.vd-phone select{flex:0 0 112px;width:112px}}

/* --- Speak/copy buttons on answers (chat voice mode, the mouth) --- */
.msg-actions{display:flex;gap:8px;margin-top:8px}
.msg-speak,.msg-copy{background:none;border:1px solid var(--line);color:var(--mut);border-radius:999px;
  padding:3px 12px;font:inherit;font-size:11.5px;letter-spacing:.03em;cursor:pointer}
.msg-speak:hover,.msg-copy:hover{color:var(--ink);border-color:var(--mut2)}
.msg-speak.is-on{color:var(--acc);border-color:var(--acc)}
.msg-copy:disabled{color:var(--acc);border-color:var(--acc);cursor:default}

/* --- Follow-up chips under an answer: the model's own fenced block, turned
   into clickable next questions instead of raw text (chat.js addFollowups).
   No avatar in the current thread layout (see "THE THREAD, REBUILT" above),
   so — like .msg-actions right below — this needs no inline-start offset. */
.msg-followups{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 0}
.msg-followup{
  background:none;border:1px solid var(--line);color:var(--mut);border-radius:999px;
  padding:5px 13px;font:inherit;font-size:12.5px;cursor:pointer;text-align:start;max-width:100%
}
.msg-followup:hover{color:var(--ink);border-color:var(--mut2)}

/* --- Retry on a failed answer --- */
.msg-retry{background:none;border:1px solid var(--line);color:var(--mut);border-radius:999px;
  padding:2px 12px;font:inherit;font-size:11.5px;letter-spacing:.03em;cursor:pointer;
  margin-top:6px;display:inline-block}
.msg-retry:hover{color:var(--ink);border-color:var(--mut2)}

/* --- Send button doubles as Stop while a reply is streaming --- */
.app-input-form button#chatSend.is-stop{background:var(--ink);color:var(--bg)}

/* === BUILD: the site builder is a pane of the shell ======================
   The shell becomes exactly one viewport tall, the flow steps aside, and the
   builder frame takes the content area. Sidebar and top bar stay where they
   are — the visitor never leaves Synap to edit their site. */
.app-shell.site-open{height:100vh;height:100dvh;min-height:0;overflow:hidden}
.app-shell.site-open .app-main{min-height:0}
.app-shell.site-open .app-content{display:none}
.pf-site{flex:1 1 auto;min-height:0;width:100%;border:0;border-top:1px solid var(--line);display:block;background:var(--bg)}
.pf-resume{display:inline-flex;align-items:center;gap:6px;margin:0 0 14px;padding:8px 14px;border:1px solid var(--line);
  border-radius:999px;background:var(--card);color:var(--ink);font-size:13.5px;font-weight:500;text-decoration:none}
.pf-resume:hover{border-color:var(--mut2)}

/* === TALK (/ai/talk.html) — full-screen voice, in Linkrra clothes === */
.app-shell.talk-mode{height:100vh;height:100dvh;overflow:hidden}
.app-main.talk-stage{position:relative;display:flex;flex-direction:column;align-items:center;
  justify-content:center;cursor:pointer;-webkit-tap-highlight-color:transparent;min-height:0}
/* Topbar floats above the centered orb instead of sharing its flex box —
   otherwise justify-content:center on .talk-stage would pull the orb up to
   make room for it. Sidebar/theme/account controls stay reachable without
   disturbing the centered "tap to talk" layout. */
.talk-stage .app-topbar{position:absolute;top:0;left:0;right:0;z-index:5}
.talk-center{display:flex;flex-direction:column;align-items:center;gap:26px;width:100%;
  max-width:680px;padding:0 20px;pointer-events:none}
.talk-center *{pointer-events:auto}
/* The orb is a Linkrra hologram — the site's nodes-and-lines constellation
   wrapped on a sphere, drawn and animated by talk.js. The canvas overhangs the
   box so the halo has room to breathe without pushing the hint text away. */
.talk-orb{width:224px;height:224px;position:relative;flex:0 0 auto}
.talk-orb .talk-orb-canvas{position:absolute;left:50%;top:50%;width:190%;height:190%;
  transform:translate(-50%,-50%);display:block;pointer-events:none}
@media(max-width:600px){.talk-orb{width:184px;height:184px}}
.talk-hint{font-size:14.5px;color:var(--mut);letter-spacing:.02em;text-align:center}
.talk-transcript{width:100%;max-height:36vh;overflow-y:auto;display:flex;flex-direction:column;gap:8px;
  -webkit-mask-image:linear-gradient(transparent,#000 18%);mask-image:linear-gradient(transparent,#000 18%)}
.talk-line{font-size:14.5px;line-height:1.55;padding:8px 14px;border-radius:14px;max-width:86%}
.talk-line.user{align-self:flex-end;background:var(--card);border:1px solid var(--line);color:var(--ink)}
.talk-line.bot{align-self:flex-start;color:var(--mut);white-space:pre-wrap}
.talk-controls{position:absolute;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;
  gap:14px;padding:0 20px max(20px,env(safe-area-inset-bottom))}
.talk-btn{background:var(--card);border:1px solid var(--line);color:var(--mut);border-radius:999px;
  padding:10px 22px;font:inherit;font-size:14px;cursor:pointer}
.talk-btn:hover{color:var(--ink);border-color:var(--mut2)}
.talk-main{background:var(--grad1);color:#fff;border:none;font-weight:600}
.talk-main:hover{opacity:.92;color:#fff}
.talk-entry{text-align:center;margin:6px 0 2px}
.talk-link{display:inline-flex;align-items:center;gap:6px;color:var(--mut);font-size:13px;
  text-decoration:none;border:1px solid var(--line);border-radius:999px;padding:6px 14px}
.talk-link:hover{color:var(--ink);border-color:var(--mut2)}

/* Recents collapsed behind a toggle: history is a lookup, not navigation —
   it must not eat the whole sidebar before Models/Account are reachable. */
.recents-toggle{display:flex;width:calc(100% - 16px);margin:14px 8px 2px;padding:8px 10px;
  background:none;border:0;cursor:pointer;align-items:center;justify-content:space-between;
  font:inherit;color:var(--mut);text-transform:uppercase;letter-spacing:.08em;font-size:11px;font-weight:700}
.recents-toggle:hover{color:var(--ink)}
.recents-toggle .sidebar-caret{transition:transform .15s ease;opacity:.6}
.recents-toggle[aria-expanded="true"] .sidebar-caret{transform:rotate(90deg)}
.sidebar-convs{max-height:none}

/* Bigger corner toggle (mobile): 2026-08-22 — the 22px hamburger read as a
   stray mark, not a button, and reviewers called it "too small". 44px hit
   area, 26px bars. */
@media (max-width:900px){
  .mobile-toggle{padding:10px;margin-left:-2px}
  .mobile-toggle span:not(.brand-mark){width:26px;height:2.5px}
  .mobile-toggle span:not(.brand-mark)+span:not(.brand-mark){margin-top:6px}
}

/* The chat shell breaks to drawer mode at 900px, but the corner toggle only
   appeared below 768px — between 769 and 900 (large phones landscape, small
   tablets) the drawer was unreachable: no button at all. The chat page's
   toggle follows the chat page's breakpoint. */
@media (max-width:900px){
  .app-shell.chat-mode .mobile-toggle{display:block}
}

/* `hidden` loses to `display:flex` — the UA stylesheet's display:none is
   author-overridable, and .sidebar-convs IS display:flex. With chats on the
   account the "collapsed by default" Recents rendered fully open on mobile,
   and the toggle did nothing visible. An explicit rule restores the meaning
   of the attribute. */
.sidebar-convs[hidden]{display:none}

/* Price-leader banner. */
.price-lead{
  display:flex;align-items:center;gap:22px;flex-wrap:wrap;
  background:var(--card);border:1px solid var(--line);
  border-radius:var(--radius);padding:20px 24px;margin-bottom:22px;
}
.price-lead-tag{
  flex:none;font-size:10.5px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--mut2);
}
.price-lead-main{flex:1 1 280px;min-width:0}
.price-lead-model{
  font-family:'SF Mono',Menlo,Monaco,Consolas,monospace;
  font-size:13px;color:var(--ink);word-break:break-all;
}
.price-lead-price{
  font-family:Fraunces,serif;font-weight:600;
  font-size:clamp(22px,3.4vw,30px);color:var(--ink);
  letter-spacing:-.01em;line-height:1.15;margin-top:4px;
}
.price-lead-price span{font-size:.5em;font-weight:500;color:var(--mut)}
.price-lead-vs{
  flex:none;display:flex;flex-direction:column;gap:4px;
  padding-left:22px;border-left:1px solid var(--line);
  font-size:12.5px;color:var(--mut);
}
.price-lead-vs b{color:var(--ink);font-weight:600}
.price-lead-note{
  flex:1 1 100%;font-size:12px;color:var(--mut2);
  margin:0;line-height:1.5;
}
@media (max-width:620px){
  .price-lead{gap:14px;padding:18px}
  .price-lead-vs{padding-left:0;border-left:0;padding-top:12px;border-top:1px solid var(--line);flex:1 1 100%}
}

/* Zero-data-retention badge — the privacy guarantee is enforced in
   gateway/openrouter-proxy.js (zdr:true + data_collection:deny on every
   forwarded call); this badge is the customer-visible face of that.
   <details>/<summary> so the comparison panel needs no JS and no dead
   href (it used to link to a "models#privacy" anchor that doesn't exist). */
.models-buy-cta{margin-top:18px}
.models-buy-note{margin:8px 0 0;font-size:12px;color:var(--mut2)}
.zdr-details{position:relative;display:inline-block;margin-top:10px}
.zdr-details summary{list-style:none;cursor:pointer}
.zdr-details summary::-webkit-details-marker{display:none}
.zdr-badge{
  display:inline-flex;align-items:center;gap:6px;
  padding:0;border:0;background:none;
  color:var(--mut);font-size:11px;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;
  transition:color .18s ease;
}
.zdr-badge:hover{color:var(--ink)}
.zdr-badge svg{flex:none;width:12px;height:12px;opacity:.75}
.zdr-panel{
  position:absolute;top:calc(100% + 8px);left:0;z-index:120;
  width:320px;max-width:min(320px,calc(100vw - 48px));
  padding:16px 18px;border-radius:14px;border:1px solid var(--line);background:var(--bg2);
  box-shadow:0 12px 40px rgba(0,0,0,.35);
  font-size:12.5px;line-height:1.55;color:var(--mut);text-transform:none;letter-spacing:0;
}
.zdr-panel p{margin:0 0 10px}
.zdr-panel ul{margin:0 0 10px;padding-left:18px}
.zdr-panel li{margin-bottom:6px}
.zdr-panel li:last-child{margin-bottom:0}
.zdr-panel p:last-child{margin-bottom:0}
.zdr-panel strong{color:var(--ink)}
@media (max-width:480px){.zdr-panel{left:auto;right:0}}

/* SYNAP teaser — quiet one-line note, no numbers. T-1010: points at the live Pool
   (it used to promise "earn usage credits — coming soon", which is not the plan).
   Full detail lives at the hidden pool.linkrra.com/synap preview until
   roadmap Phase 3 (post-attorney sign-off). */
.synap-teaser{
  display:inline-flex;align-items:center;gap:6px;
  margin-top:12px;padding:0;border:0;background:none;
  color:var(--mut2);font-size:12px;font-weight:500;text-transform:none;letter-spacing:0;
}
.synap-teaser svg{flex:none;width:12px;height:12px;opacity:.75}
.synap-teaser a{color:inherit;text-decoration:underline;text-underline-offset:2px}
.synap-teaser a:hover{color:var(--ink)}

/* === THE MARK IS THE MENU (2026-09-30) ====================================
   On mobile the hamburger's X landed on top of the Synap mark the moment the
   drawer opened — the one thing that should always be readable was being
   crossed out by its own menu button. So: no X at all. The mark itself opens
   and closes the drawer.

   That only reads right if exactly ONE mark is on screen. Two used to be:
   the topbar's (drawer closed) and the sidebar header's (drawer open). Both
   are hidden here on mobile and the fixed button is parked where either one
   stood, so the logo does not move when the drawer opens — it simply becomes
   the drawer's own header mark, and tapping it again closes.

   The numbers are measured at 390px in WebKit, not guessed: the sidebar mark
   sat centred on (38, 45.2) and the topbar word on y 47.8. left:16 + top:24
   with 10px padding puts the 24px mark at x 26..50, y 34..58 — centre
   (38, 46), within ~1.5px of both anchors. Backdrop tap and Escape still
   close the drawer (setupMobileNav in app.js), so losing the X costs no way
   out. */

/* The three bars are gone from the markup, but their rules are not: the base
   `.mobile-toggle span` is a 22x2 bar and `.mobile-toggle.open span:nth-child`
   still rotates the first child 45deg — which is now the mark. Both have to be
   undone, and the .open rule outranks a plain `.mobile-toggle .brand-mark`,
   so the reset carries the same weight and sits later in the file. */
.mobile-toggle .brand-mark,
.mobile-toggle.open .brand-mark{
  display:inline-flex;width:auto;height:auto;margin:0;background:none;border-radius:0;
  transform:none;opacity:1;color:var(--ink);
  transition:transform .15s ease,opacity .15s ease;
}
.mobile-toggle .brand-mark svg{display:block}
.mobile-toggle.open .brand-mark{opacity:.88}
.mobile-toggle:active .brand-mark,
.mobile-toggle.open:active .brand-mark{transform:scale(.94)}

@media (max-width:900px){
  /* top/left are inline attributes in every page's template, and inline beats
     a stylesheet — !important is the only way in, same as the z-index rule
     further up this file. */
  .mobile-toggle{
    top:15px !important;left:16px !important;margin-left:0;padding:10px;
    min-width:44px;min-height:44px;display:grid;place-content:center;
  }
  /* The two marks the button now stands in for. Their words stay where they
     were horizontally — with the mark gone the flex gap collapses, so the
     drawer's word is held at x 60 by padding, level with the topbar's, 10px
     to the right of the button's mark.

     padding-top:0 on the drawer header is what makes the single position
     possible: it lifts "Synap" from centre y 45.2 to 37.2, which is where the
     topbar's word already sits (37.4). One mark, one place, both states. */
  .topbar-brand .brand-mark{display:none}
  .sidebar-brand .brand-mark{display:none}
  .sidebar-brand{padding-top:0;padding-left:44px}

  /* T-1261: the button is position:fixed, so it stays while the page scrolls
     under it — and with no surface of its own the mark landed ON the type.
     Jimmie's phone (2026-11-01) showed it reading as "G✳IDES" over the /guides
     kicker, one line under the H1. It is a control, so it gets a control's
     surface: a translucent chip with the same hairline and radius as every
     other chip here, blurring whatever scrolls beneath it. */
  .mobile-toggle{
    background:color-mix(in srgb, var(--bg) 82%, transparent);
    border:1px solid var(--line);border-radius:12px;
    -webkit-backdrop-filter:saturate(1.4) blur(10px);backdrop-filter:saturate(1.4) blur(10px);
    padding:9px;
  }
  .mobile-toggle.open{background:transparent;border-color:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}
  .mobile-toggle:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
}

/* T-1025: free-tier offer under the homepage H1. Text is server-rendered from the
   live free-tier config (lib/free-tier-offer.js). Monochrome, one ink CTA, same pill
   language as the topbar — the offer reads as the headline's second line, not an ad. */
.app-hero h1:has(+ .free-offer){margin-bottom:14px}
.free-offer{
  display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:12px 16px;
  margin:0 auto 28px;max-width:680px;
}
.free-offer-text{color:var(--mut);font-size:16px;line-height:1.5;text-wrap:balance}
.free-offer-text strong{color:var(--ink);font-weight:700}
.free-offer-cta{
  display:inline-flex;align-items:center;min-height:44px;padding:10px 22px;border-radius:999px;touch-action:manipulation;
  background:var(--ink);border:1px solid var(--ink);color:var(--bg);
  font-size:14px;font-weight:700;text-decoration:none;transition:opacity .15s;
}
.free-offer-cta:hover{opacity:.85;color:var(--bg)}
.free-offer-cta:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
@media (max-width:600px){.free-offer-text{font-size:15px}}

/* T-1238 home: proof micro-line + "first call" block. Quiet, monochrome, after the
   model grid so the cards stay the focal point. Lines on this block are claims
   checked against live behaviour on 2026-10-31 (anon chat, guest checkout, $10
   PAYG minimum, purchased credits do not expire, free tier in economics.json). */
.hero-proof{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 0;margin:-14px 0 26px;font-size:11px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--mut2)}
.hero-proof span+span::before{content:"\00B7";margin:0 .9em;opacity:.8}
@media (max-width:600px){.hero-proof{gap:6px 16px}.hero-proof span+span::before{content:none}}
.start{width:100%;max-width:880px;margin:56px auto 8px;padding-top:40px;border-top:1px solid var(--line);text-align:left}
.start h2{font-family:var(--font-display);font-weight:600;letter-spacing:-.02em;font-size:clamp(22px,3vw,30px);line-height:1.2;margin:0 0 24px;text-wrap:balance}
.start-steps{list-style:none;margin:0 0 20px;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.start-steps li{display:flex;flex-direction:column;gap:4px;padding:16px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card)}
.start-steps b{font-size:14px;font-weight:600;color:var(--ink)}
.start-steps li > span:last-child{font-size:13.5px;line-height:1.5;color:var(--mut)}
.start-n{font-family:'SF Mono',Menlo,Consolas,monospace;font-size:11px;letter-spacing:.08em;color:var(--mut2)}
.start-code{position:relative}
.start-code pre{margin:0;background:var(--bg2);border:1px solid var(--line);border-radius:var(--radius-sm);padding:16px 18px;overflow-x:auto;font-family:'SF Mono',Menlo,Consolas,monospace;font-size:13px;line-height:1.6;color:var(--ink);white-space:pre}
.start-code .chat-code-copy{top:10px;min-height:28px}
.start-cta{display:flex;align-items:center;gap:18px;flex-wrap:wrap;margin-top:20px}
.start-btn{display:inline-flex;align-items:center;min-height:44px;padding:10px 22px;border-radius:999px;background:var(--ink);border:1px solid var(--ink);color:var(--bg);font-size:14px;font-weight:700;text-decoration:none;transition:opacity .15s;touch-action:manipulation}
.start-btn:hover{opacity:.85;color:var(--bg)}
.start-btn:focus-visible,.start-link:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.start-link{font-size:13.5px;color:var(--mut);text-decoration:none;transition:color .15s}
.start-link:hover{color:var(--ink)}
.start-free{margin:14px 0 0;font-size:12.5px;color:var(--mut2)}
@media (max-width:700px){.start-steps{grid-template-columns:1fr}.start{margin-top:40px;padding-top:32px}}
@media (max-width:700px){.start-steps li{padding:12px 14px}.start-code pre{font-size:12px;padding:14px;padding-top:44px}}
.start-code .chat-code-copy:focus-visible{outline:2px solid var(--ink);outline-offset:2px}

/* T-1243: topbar pills never wrap. At 390px on pool.linkrra.com/ai the longer
   "Linkrra" lockup squeezed "Log in" / "Sign up free" onto two lines each. */
.topbar-btn{white-space:nowrap;flex:none}
@media (max-width:420px){
  .app-topbar{gap:6px;padding-right:14px}
  .topbar-btn{padding:8px 12px}
}

/* T-1243: payment methods under the home "first call" steps. Each rail was checked
   live on 2026-10-31 (billing/health purchasable, ton/info enabled + live rate,
   x402/info settlementReady + a settled payment in the log). */
.start-pay{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:0 0 20px;font-size:12.5px;color:var(--mut2)}
.start-pay-l{font-weight:600;letter-spacing:.08em;text-transform:uppercase;font-size:11px;margin-right:2px}
.pay-chip{color:var(--ink);font-size:13px;font-weight:600}
.pay-chip+.pay-chip::before{content:"\00B7";margin-right:8px;color:var(--mut2);font-weight:400}
.start-pay-note{margin-left:8px}
@media (max-width:600px){.start-pay-note{flex-basis:100%;margin-left:0}}

/* T-1243: public status page. States come from the live API (status.js);
   colour is never the only signal — every dot sits next to its word. */
.status-wrap{max-width:720px;padding:8px 28px 0}
.status-banner{display:grid;grid-template-columns:auto minmax(0,1fr) auto;align-items:center;gap:4px 12px;padding:16px 18px;border:1px solid var(--line);border-radius:var(--radius-sm);background:var(--card);margin:8px 0 36px}
.status-banner-text{font-family:var(--font-display);font-weight:600;font-size:18px;letter-spacing:-.01em;color:var(--ink)}
.status-checked{font-size:12px;color:var(--mut2);font-variant-numeric:tabular-nums}
.status-sec{margin:0 0 32px}
.status-sec h2{font-family:var(--font-display);font-weight:600;font-size:20px;letter-spacing:-.01em;margin:0 0 6px}
.status-sub{font-size:13.5px;color:var(--mut);margin:0 0 14px;line-height:1.55}
.status-list{list-style:none;margin:0;padding:0;border:1px solid var(--line);border-radius:var(--radius-sm);overflow:hidden}
.status-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:13px 16px;background:var(--card)}
.status-row+.status-row{border-top:1px solid var(--line)}
.status-name{display:flex;flex-direction:column;gap:2px;min-width:0}
.status-name b{font-family:'SF Mono',Menlo,Consolas,monospace;font-size:13.5px;font-weight:600;color:var(--ink);overflow-wrap:anywhere}
.status-name span{font-size:12.5px;color:var(--mut2)}
.status-pill{display:inline-flex;align-items:center;gap:7px;flex:none;font-size:12.5px;font-weight:600;color:var(--ink)}
.status-dot{width:8px;height:8px;border-radius:50%;background:var(--mut2);flex:none;align-self:center}
[data-state="up"] > .status-dot,[data-state="up"] .status-pill .status-dot{background:var(--green)}
[data-state="down"] > .status-dot,[data-state="down"] .status-pill .status-dot{background:var(--red)}
[data-state="partial"] > .status-dot{background:var(--gold)}
[data-state="unknown"] .status-pill{color:var(--mut)}
.status-foot{font-size:12.5px;color:var(--mut2);line-height:1.7;margin:0 0 24px}
.status-foot code{font-size:11.5px;color:var(--mut)}
.status-foot a{color:var(--mut)}
@media (max-width:600px){.status-wrap{padding:8px 18px 0}.status-head{padding-left:18px;padding-right:18px}.status-checked{grid-column:2}.status-banner-text{font-size:17px;line-height:1.3}}

/* T-1242 (2026-11-01): search-intent pages (model API pages, vs pages, guides, /free)
   and the free-tier entry points. Quiet by design: micro-labels and underlined text
   links, no new colours, nothing competing with the hero's focal path. */
/* Reading surfaces stay quiet; the decorative network belongs on discovery pages. */
.docs-page .bgfx,.account-page .bgfx{display:none}
.model-card-note,.model-card-price small,.model-card-foot a,.signin-note,.plan-tagline,.plan-billed{color:var(--mut)}
.account-page .key-reveal{border-color:var(--line);background:var(--card)}
.account-page .key-reveal>p{font-size:14px;line-height:1.6}
.account-page #keys{scroll-margin-top:76px}
@media(max-width:420px){
  .account-page .topbar-brand{display:none}
  .account-page .account-menu{min-width:0;max-width:110px}
  .account-page .account-chip{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
}
.hero-api-actions{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:12px;margin:20px 0 12px}
.hero-api-actions .btn-lg{display:inline-flex;align-items:center;justify-content:center;min-height:44px}
.hero-trial-link{display:inline-flex;align-items:center;min-height:44px;padding:8px 12px;color:var(--ink);text-underline-offset:4px}
.hero-trial-link:hover{text-decoration:underline}
.hero-api-note{margin:0 0 28px;color:var(--mut);font-size:13px;line-height:1.6}
.hero-api-note a{color:var(--ink);text-decoration:underline;text-underline-offset:3px}
.hero-api-actions a:focus-visible,.hero-api-note a:focus-visible{outline:2px solid var(--ink);outline-offset:4px;border-radius:4px}
@media(max-width:768px){
  #modelFilter,#paygKey,#keyLoginInput,#keyRecoverEmail{font-size:16px!important}
  #chatInput,#vdPhone,.vd-field input,.vd-field select,
  #acctSignedIn input,#acctSignedIn select,#acctSignedIn textarea{font-size:16px}
}
.hero-free{margin:-12px 0 26px;text-align:center;font-size:13.5px}
.hero-free a{color:var(--ink);text-decoration:underline;text-decoration-color:var(--mut2);text-underline-offset:4px;transition:text-decoration-color .15s}
.hero-free a:hover{text-decoration-color:var(--ink)}
.hero-free a:focus-visible,.subpage-free a:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:4px}
.subpage-free{margin-top:12px;font-size:14px;color:var(--mut)}
.subpage-free a{color:var(--ink);text-decoration:underline;text-decoration-color:var(--mut2);text-underline-offset:4px}
.seo-kicker{font-size:11px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--mut2);margin-bottom:12px}
.subpage-head h1 code{font-size:.8em}
.seo-facts td:first-child{color:var(--mut);width:34%;font-size:13px}
.seo-facts td{vertical-align:top;line-height:1.55}
.legal .seo-list{margin:4px 0 12px;padding-left:20px;color:var(--mut);font-size:15px;line-height:1.75}
.legal p.seo-claim{color:var(--ink);font-size:14.5px;margin-top:14px}
.legal p.seo-src,.seo-src{font-size:12.5px;color:var(--mut2);line-height:1.6}
.seo-claim .seo-src{display:block;margin-top:2px}
.legal .seo-src a{color:var(--mut)}
.seo-cta{margin:24px 0 6px}
.seo-links{display:flex;flex-wrap:wrap;gap:8px 18px;margin:6px 0 0;padding:0;list-style:none;font-size:14px}
.legal .seo-links a,.seo-links a{color:var(--mut);text-decoration:none;display:inline-block;padding:4px 0}
.legal .seo-links a:hover,.seo-links a:hover{color:var(--ink)}
.seo-links-center{justify-content:center;margin-top:14px;font-size:12.5px}
.model-card-name a{color:inherit;text-decoration:none}
.model-card-name a:hover{text-decoration:underline;text-underline-offset:3px}
.legal a.start-btn,.legal a.start-btn:hover{color:var(--bg)}
.legal a.start-link{color:var(--mut)}
.legal a.start-link:hover{color:var(--ink)}
.seo-kicker+h1,.hero-free a{text-wrap:balance}
.seo-facts td,.seo-facts + * td,.acct-table td{font-variant-numeric:tabular-nums}
.seo-links a:focus-visible,.legal p.seo-src a:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:4px}

/* === Guides hub: video gallery (T-GUIDES-20261101) ===
   Synap monochrome: grey hairline cards, white ink, Fraunces names, one quiet mono
   length label. Vendor marks as app-icon chips, same rule as the model cards. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.guides-section{padding:12px 0 72px}
/* --- T-1286 guides hub: five tiles, one line each, no players on the index --- */
.guides-wrap{max-width:calc(var(--maxw) + 56px);padding:0 28px}
.guide-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(248px,1fr));gap:18px}
.guide-card{display:flex;flex-direction:column;min-width:0;background:var(--card);border:1px solid var(--line);
  border-radius:var(--radius);overflow:hidden;text-decoration:none;touch-action:manipulation;
  transition:border-color .15s,transform .15s}
.guide-card:hover,.guide-card:focus-visible{border-color:var(--mut2);transform:translateY(-2px)}
.guide-card:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.guide-media{position:relative;display:block;aspect-ratio:16/9;background:#050608;border-bottom:1px solid var(--line)}
.guide-media img{display:block;width:100%;height:100%;object-fit:cover}
.guide-play{position:absolute;left:12px;bottom:12px;display:inline-flex;align-items:center;gap:6px;
  padding:5px 11px 5px 9px;border-radius:999px;background:rgba(243,244,247,.94);color:#050608;
  font-size:11.5px;font-weight:600;line-height:1;font-variant-numeric:tabular-nums}
.guide-body{display:flex;flex-direction:column;gap:6px;padding:14px 16px 16px;flex:1}
.guide-head{display:flex;align-items:center;gap:9px;min-width:0}
.guide-t{font-family:var(--font-display);font-weight:600;font-size:17px;letter-spacing:-.015em;line-height:1.2;color:var(--ink)}
.guide-line{font-size:13.5px;line-height:1.55;color:var(--mut);text-wrap:pretty}
.guide-meta{margin-top:auto;padding-top:6px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:11px;letter-spacing:.05em;color:var(--mut2)}
.guide-logo{flex:none;width:28px;height:28px;border-radius:8px;display:inline-flex;align-items:center;
  justify-content:center;border:1px solid #2a2b33;background:#000;color:#fff;overflow:hidden}
.guide-logo svg{width:15px;height:15px;display:block}
.guide-logo-txt{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:10.5px;font-weight:600;
  line-height:1;letter-spacing:.02em;font-variant-numeric:tabular-nums}
.guide-logo[data-logo="claude"]{background:#fff;border-color:#e3e3e8;color:#D97757}
.guide-logo[data-logo="langchain"]{background:#fff;border-color:#e3e3e8;color:#1C3C3C}
.guide-logo[data-logo="kilo"]{background:#FFDD00;border-color:#FFDD00;color:#000}
.guide-logo[data-logo="kilo"] svg{width:17px;height:17px}
.guide-logo[data-logo="n8n"]{background:#fff;border-color:#e3e3e8;color:#EA4B71}
.guide-logo[data-logo="n8n"] svg{width:17px;height:17px}
.guides-sub{font-family:var(--font-display);font-weight:600;font-size:18px;letter-spacing:-.01em;margin:44px 0 14px}
/* T-1297: the first group is now headed too, so it must not start 44px down. */
.guides-wrap > .guides-sub:first-child{margin-top:0}
/* Two grids in one section (coding tools with and without a video) read as one group. */
.guide-grid + .guide-grid{margin-top:18px}
.guide-grid-text{grid-template-columns:repeat(auto-fill,minmax(248px,1fr))}
@media (prefers-reduced-motion:reduce){.guide-card{transition:none}}
@media (max-width:980px){.guides-wrap{padding:0 20px}.guides-section{padding:8px 0 56px}}
@media (max-width:560px){.guide-grid{grid-template-columns:minmax(0,1fr);gap:14px}.guides-sub{margin-top:32px}}

/* --- T-1286 guide page: H1, one line, the video, then three numbered steps --- */
.gd-head{max-width:788px}
.gd-meta{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;letter-spacing:.03em;
  color:var(--mut2);margin:12px 0 0}
.gd-section{padding:8px 0 64px}
.gd-wrap{max-width:788px;margin:0;padding:0 28px}
.gd-video{margin:0 0 40px}
.gd-video video{display:block;width:100%;height:auto;border-radius:14px;border:1px solid var(--line);background:#050608}
.gd-steps{list-style:none;margin:0;padding:0;display:grid;gap:36px}
.gd-steps > li{display:grid;grid-template-columns:40px minmax(0,1fr);gap:18px;align-items:start;scroll-margin-top:90px}
.gd-n{display:flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:999px;
  border:1px solid var(--acc);color:var(--acc);font-family:var(--font-display);font-weight:600;
  font-size:17px;line-height:1;font-variant-numeric:tabular-nums}
.gd-step-body{min-width:0}
.gd-steps h2{font-family:var(--font-display);font-weight:600;letter-spacing:-.015em;font-size:21px;
  line-height:1.25;margin:5px 0 8px;text-wrap:balance}
.gd-steps p{margin:0;font-size:15px;line-height:1.65;color:var(--mut);text-wrap:pretty}
.gd-steps p + .gd-code{margin-top:14px}
.gd-steps h2 + .gd-code{margin-top:4px}
.gd-code pre{font-size:13.5px}
.gd-code .chat-code-copy{min-height:36px;padding:0 14px;touch-action:manipulation}
.gd-other .seo-links a{display:inline-flex;align-items:center;min-height:44px}
.gd-notes{margin:48px 0 0;border-top:1px solid var(--line);padding-top:6px}
.gd-notes > summary{cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;
  gap:10px;min-height:48px;font-size:14.5px;font-weight:600;color:var(--ink)}
.gd-notes > summary::-webkit-details-marker{display:none}
.gd-notes > summary::after{content:"+";font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-weight:400;font-size:16px;color:var(--mut)}
.gd-notes[open] > summary::after{content:"\2013"}
.gd-notes > summary:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:6px}
.gd-notes-body{padding:4px 0 10px}
.gd-notes-body p{margin:0 0 12px;font-size:13.5px;line-height:1.7;color:var(--mut)}
.gd-notes-body p:last-child{margin-bottom:0}
.gd-other{margin:40px 0 0;border-top:1px solid var(--line);padding-top:22px}
.gd-other h2{font-family:var(--font-display);font-weight:600;font-size:17px;letter-spacing:-.01em;margin:0 0 10px}
/* T-1297: /guides/choosing-a-model is a table, so it gets one between the steps
   and the notes. The wrapper scrolls on a phone instead of widening the page. */
.gd-table{margin:46px 0 0;border-top:1px solid var(--line);padding-top:10px}
.gd-table h2{font-family:var(--font-display);font-weight:600;font-size:20px;letter-spacing:-.015em;margin:26px 0 6px}
.gd-table h2:first-child{margin-top:8px}
.gd-table > p{margin:0;font-size:14px;line-height:1.6;color:var(--mut);text-wrap:pretty}
.gd-table .seo-src{margin-top:16px;font-size:12.5px}
.gd-table .acct-table{font-size:13.5px}
/* The reading column is 788px and a six-column price table wants ~760 at the
   shell's padding, so this one trades cell padding for the JSON column. */
.gd-table .acct-table th,.gd-table .acct-table td{padding:11px 11px;white-space:nowrap}
.gd-table .acct-table td:nth-child(2){white-space:normal;min-width:144px}
.gd-table .acct-table td code{font-size:12.5px}
@media (max-width:1000px){.gd-wrap{padding:0 20px}}
@media (max-width:620px){
  .gd-steps{gap:30px}
  .gd-steps > li{grid-template-columns:32px minmax(0,1fr);gap:14px}
  .gd-n{width:30px;height:30px;font-size:14px}
  .gd-steps h2{font-size:19px;margin-top:2px}
  .gd-video{margin-bottom:32px}
  .gd-code pre{font-size:12px;padding-top:58px}
  .gd-code .chat-code-copy{min-height:44px;padding:0 18px}
}
