/* ==========================================================================
   Public shell — the shared look of every page outside the dashboard.

   This is the stylesheet the homepage was built with, lifted out verbatim so
   the marketing pages, the SEO landing pages and the legal pages all render
   from one source instead of drifting apart. Page-specific rules belong in the
   page, not here.

   Depends on css/tokens.css for the palette.
   ========================================================================== */
/* ==========================================================================
   Motion is used to explain, not to decorate:
     · the aurora drifts, so the page feels live rather than printed
     · counters count up, so the numbers register as real measurements
     · cards lift and tilt toward the cursor, so the surface feels physical
     · the platform strip scrolls by itself, showing breadth without a wall
   Everything is disabled under prefers-reduced-motion.
   ========================================================================== */

/* --glass / --glass-line / --glow / --glow-2 now live in css/tokens.css so the
   dashboard, which does not load this file, can use the same surfaces. */

*{box-sizing:border-box}
/* .or and .gbtn set an explicit display, which beats the user-agent rule for
   [hidden]. Without this the recovery panel could not hide them. */
[hidden]{display:none !important}
html{scroll-behavior:smooth}
body{margin:0;background:var(--color-bg);color:var(--color-text);
  font-family:'Inter',system-ui,sans-serif;line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden}
h1,h2,h3{margin:0;letter-spacing:-.032em;line-height:1.12}
p{margin:0}
a{color:inherit}

/* ---------- drifting aurora ---------- */
.aurora{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.aurora i{position:absolute;display:block;border-radius:50%;filter:blur(90px);opacity:.30}
.aurora i:nth-child(1){width:620px;height:620px;left:-160px;top:-180px;
  background:radial-gradient(circle,var(--glow),transparent 65%);animation:drift1 26s ease-in-out infinite}
.aurora i:nth-child(2){width:520px;height:520px;right:-140px;top:60px;
  background:radial-gradient(circle,var(--glow-2),transparent 65%);animation:drift2 32s ease-in-out infinite}
.aurora i:nth-child(3){width:460px;height:460px;left:36%;top:420px;
  background:radial-gradient(circle,var(--glow),transparent 68%);animation:drift3 38s ease-in-out infinite;opacity:.18}
@keyframes drift1{0%,100%{transform:translate(0,0)}50%{transform:translate(120px,90px)}}
@keyframes drift2{0%,100%{transform:translate(0,0)}50%{transform:translate(-110px,120px)}}
@keyframes drift3{0%,100%{transform:translate(0,0) scale(1)}50%{transform:translate(80px,-70px) scale(1.15)}}

.page{position:relative;z-index:1}
.wrap{max-width:1220px;margin:0 auto;padding:0 26px}

/* ---------- floating nav pill ---------- */
.nav{position:sticky;top:14px;z-index:40;margin:14px auto 0;max-width:1220px;padding:0 26px}
.nav-in{position:relative;display:flex;align-items:center;gap:22px;height:62px;padding:0 10px 0 20px;
  border-radius:999px;background:var(--glass);
  -webkit-backdrop-filter:blur(18px) saturate(160%);backdrop-filter:blur(18px) saturate(160%);
  box-shadow:0 12px 44px rgba(0,0,0,.34)}
/* hairline that catches the accent at both ends, like the sign-in card */
.nav-in::before{content:'';position:absolute;inset:0;border-radius:999px;padding:1px;
  background:linear-gradient(120deg,color-mix(in srgb,var(--glow) 55%,transparent),
    var(--glass-line) 38%,var(--glass-line) 62%,color-mix(in srgb,var(--glow-2) 45%,transparent));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;pointer-events:none}

/* the mark stands in for the B, so the wordmark reads BOTZZZ773 */
/* line-height:1 makes the maths predictable: with it, the cap height of the
   letters is centred in the text box, so centring the mark's ink on the same
   axis is all that is needed. */
.brand{display:flex;align-items:center;line-height:1;font-weight:800;font-size:21px;
  letter-spacing:-.03em;text-decoration:none;color:var(--color-text)}
/* Sized and nudged so the mark sits on the same baseline as the letters and
   matches their cap height -- it has to read as the B of BOTZZZ773, not as an
   icon parked next to a word. The square viewBox carries its own padding, so
   the box is a little taller than the caps to compensate. */
/* The glyph fills only 22→88 x and 12→80 y of its 100×100 box, so the box has
   to be bigger than the ink you actually see. Sized so the drawn mark is 1.25×
   the cap height -- a mark standing in for a letter has to overshoot, because
   its thin stroke reads lighter than the 800-weight text beside it.
   1.35em is not a guess: measured on the rendered font, the baseline sits
   0.9048em below the text box top and the cap is 0.7143em, and since the mark
   is the tallest item it sets the flex line height. Solving 0.80H = (H-1)/2 +
   0.9048 puts the ink's bottom edge exactly on the baseline with no nudge --
   an earlier translateY() was what kept pulling it off. The negative margins
   cancel the box's empty sides so it kerns against the O. */
.brand img{width:1.35em;height:1.35em;margin:0 -.14em 0 -.30em;
  filter:drop-shadow(0 0 10px color-mix(in srgb,var(--glow) 45%,transparent));
  transition:transform .35s cubic-bezier(.2,.8,.2,1),filter .35s}
.brand:hover img{transform:rotate(-8deg) scale(1.06);
  filter:drop-shadow(0 0 16px color-mix(in srgb,var(--glow) 70%,transparent))}
.brand .word{position:relative}

/* links: a pill slides in behind the hovered item */
.lk{display:flex;align-items:center;gap:2px;margin-left:auto}
.lk a{position:relative;padding:9px 15px;border-radius:999px;text-decoration:none;
  font-size:13.5px;font-weight:600;color:var(--color-text-muted);
  transition:color .25s}
.lk a::before{content:'';position:absolute;inset:0;border-radius:999px;background:var(--glass);
  opacity:0;transform:scale(.86);transition:opacity .25s,transform .25s cubic-bezier(.2,.8,.2,1)}
.lk a:hover{color:var(--color-text)}
.lk a:hover::before{opacity:1;transform:none}
.lk a span{position:relative}
/* a thin accent underline grows from the middle */
.lk a::after{content:'';position:absolute;left:50%;bottom:5px;width:0;height:2px;border-radius:2px;
  background:linear-gradient(90deg,var(--glow),var(--glow-2));
  transform:translateX(-50%);transition:width .3s cubic-bezier(.2,.8,.2,1)}
.lk a:hover::after{width:18px}

/* ---------- theme switch ----------
   Sits at the head of the link group, so it reads as part of the nav rather
   than a second call to action next to Sign up. */
.themesw{position:relative;display:inline-flex;align-items:center;justify-content:space-between;
  flex:none;width:44px;height:22px;padding:0 4px;margin-right:8px;cursor:pointer;
  border:1px solid var(--glass-line);border-radius:999px;background:var(--glass);
  color:var(--color-text-muted);transition:border-color .2s,color .2s}
.themesw:hover{border-color:color-mix(in srgb,var(--glow) 45%,transparent);color:var(--color-text)}
.themesw:focus-visible{outline:2px solid var(--glow);outline-offset:2px}
.themesw svg{position:relative;z-index:1;pointer-events:none}
/* the thumb slides between the two icons */
.themesw-thumb{position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;
  background:linear-gradient(135deg,var(--btn-grad-from),var(--btn-grad-to));
  transition:transform .28s cubic-bezier(.2,.8,.2,1)}
:root[data-theme="light"] .themesw-thumb{transform:translateX(22px)}

.nav .cta{position:relative;overflow:hidden;white-space:nowrap;padding:10px 22px;border-radius:999px;border:0;cursor:pointer;
  font:inherit;font-size:13.5px;font-weight:700;color:#fff;
  background:linear-gradient(135deg,var(--btn-grad-from),var(--btn-grad-to));
  box-shadow:0 6px 22px color-mix(in srgb,var(--glow) 42%,transparent);
  transition:transform .25s,box-shadow .25s}
/* a light sweeps across the button on hover */
.nav .cta::after{content:'';position:absolute;top:0;left:-70%;width:45%;height:100%;
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.38),transparent);
  transform:skewX(-18deg);transition:left .55s cubic-bezier(.2,.8,.2,1)}
.nav .cta:hover{transform:translateY(-1px);box-shadow:0 12px 32px color-mix(in srgb,var(--glow) 62%,transparent)}
.nav .cta:hover::after{left:120%}

/* ---------- hero ---------- */
.hero{display:grid;grid-template-columns:minmax(0,1.06fr) minmax(0,.94fr);gap:56px;
  align-items:center;padding:64px 0 44px}
.eyebrow{display:inline-flex;align-items:center;gap:8px;padding:6px 14px;border-radius:999px;
  border:1px solid var(--glass-line);background:var(--glass);
  font-size:11.5px;font-weight:700;letter-spacing:.09em;color:var(--color-text-secondary);margin-bottom:20px}
.pulse{width:7px;height:7px;border-radius:50%;background:var(--glow-2);
  box-shadow:0 0 0 0 color-mix(in srgb,var(--glow-2) 70%,transparent);animation:pulse 2.2s infinite}
@keyframes pulse{70%{box-shadow:0 0 0 9px transparent}100%{box-shadow:0 0 0 0 transparent}}
h1{font-size:clamp(32px,4vw,52px);font-weight:800;margin-bottom:18px}
h1 .g{background:linear-gradient(120deg,var(--glow),var(--glow-2));-webkit-background-clip:text;
  background-clip:text;color:transparent}
.pitch{color:var(--color-text-secondary);font-size:16.5px;margin-bottom:24px;max-width:52ch}
.chips{display:flex;flex-wrap:wrap;gap:9px;margin-bottom:30px}
.chip{display:inline-flex;align-items:center;gap:7px;padding:7px 14px;border-radius:999px;
  border:1px solid var(--glass-line);background:var(--glass);font-size:12.5px;color:var(--color-text-secondary)}
.chip svg{color:var(--glow-2)}
.hero-btns{display:flex;gap:11px}
.b-glow{padding:13px 26px;border-radius:999px;border:0;cursor:pointer;font:inherit;font-size:14.5px;font-weight:700;
  color:#fff;background:linear-gradient(135deg,var(--btn-grad-from),var(--btn-grad-to));
  box-shadow:0 8px 28px color-mix(in srgb,var(--glow) 45%,transparent);transition:.25s}
.b-glow:hover{transform:translateY(-2px);box-shadow:0 14px 38px color-mix(in srgb,var(--glow) 62%,transparent)}
.b-glass{padding:13px 24px;border-radius:999px;cursor:pointer;font:inherit;font-size:14.5px;font-weight:700;
  border:1px solid var(--glass-line);background:var(--glass);color:var(--color-text);transition:.25s}
.b-glass:hover{transform:translateY(-2px)}

/* glass sign-in card, tilts toward the cursor */
.auth{position:relative;border-radius:22px;padding:26px;
  border:1px solid var(--glass-line);background:var(--glass);-webkit-backdrop-filter:blur(22px) saturate(160%);;backdrop-filter:blur(22px) saturate(160%);
  box-shadow:0 30px 70px rgba(0,0,0,.35);
  transform-style:preserve-3d;transition:transform .18s ease-out}
.auth::before{content:'';position:absolute;inset:-1px;border-radius:22px;padding:1px;
  background:linear-gradient(135deg,color-mix(in srgb,var(--glow) 55%,transparent),transparent 45%,color-mix(in srgb,var(--glow-2) 45%,transparent));
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask-composite:exclude;pointer-events:none}
.auth h2{font-size:17px;font-weight:700;margin-bottom:4px}
.auth .sub{font-size:13px;color:var(--color-text-muted);margin-bottom:18px}
.auth label{display:block;font-size:12px;font-weight:600;color:var(--color-text-secondary);margin-bottom:6px}
.auth input{width:100%;padding:12px 14px;font:inherit;font-size:14px;margin-bottom:13px;
  background:var(--color-input-bg);color:var(--color-text);
  border:1px solid var(--glass-line);border-radius:12px;transition:.2s}
.auth input:focus{outline:none;border-color:var(--glow);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--glow) 22%,transparent)}
.fp{display:block;text-align:right;font-size:12px;color:var(--color-text-muted);margin:-5px 0 14px;text-decoration:none}
.auth .b-glow,.auth .b-glass{width:100%;margin-top:0}
.auth .b-glass{margin-top:9px}
.auth .foot{margin-top:14px;font-size:13px;color:var(--color-text-muted);text-align:center}
.auth .foot a{color:var(--color-text);font-weight:600}

/* ---------- self-scrolling platform strip ---------- */
.marquee{position:relative;overflow:hidden;padding:16px 0;margin:8px 0 60px;
  border-top:1px solid var(--glass-line);border-bottom:1px solid var(--glass-line)}
.marquee::before,.marquee::after{content:'';position:absolute;top:0;bottom:0;width:120px;z-index:2;pointer-events:none}
.marquee::before{left:0;background:linear-gradient(90deg,var(--color-bg),transparent)}
.marquee::after{right:0;background:linear-gradient(270deg,var(--color-bg),transparent)}
/* No gap here on purpose: with gap, the space between the two copies is
   counted once but translateX(-50%) assumes it is counted twice, so every
   loop jumped by half a gap. Each item carries its own trailing margin
   instead, which makes half the track exactly one copy wide. */
.track{display:flex;width:max-content;animation:slide var(--dur,30s) linear infinite}
.marquee:hover .track{animation-play-state:paused}
@keyframes slide{to{transform:translateX(-50%)}}
.mi{display:flex;align-items:center;gap:10px;margin-right:12px;padding:10px 18px;border-radius:999px;
  border:1px solid var(--glass-line);background:var(--glass);white-space:nowrap;font-size:13.5px;font-weight:600}
.mi img{width:20px;height:20px}
.mi span{color:var(--color-text-muted);font-weight:500;font-size:12.5px}

/* ---------- reveal on scroll ---------- */
/* Sections fade in as they are scrolled to. The hidden starting state is
   scoped to html.js, which is set by a one-line script in the head — so if
   JavaScript fails or never runs, the page renders fully visible instead of
   blank. Everything below the fold depends on this. */
html.js .rv{opacity:0;transform:translateY(22px);transition:opacity .7s cubic-bezier(.2,.8,.2,1),transform .7s cubic-bezier(.2,.8,.2,1)}
html.js .rv.in{opacity:1;transform:none}

/* ---------- sections ---------- */
.sec{padding:66px 0}
.tag{display:inline-block;font-size:11px;font-weight:700;letter-spacing:.13em;color:var(--color-text-muted);margin-bottom:12px}
.sec h2{font-size:clamp(24px,2.7vw,34px);font-weight:800;margin-bottom:12px}
.sec .lead{color:var(--color-text-muted);font-size:15.5px;margin-bottom:34px;max-width:62ch}
.center{text-align:center}
.center .lead{margin-left:auto;margin-right:auto}

.nums{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
.num{padding:24px;border-radius:18px;border:1px solid var(--glass-line);background:var(--glass);
text-align:center;transition:.28s}
.num:hover{transform:translateY(-4px);border-color:color-mix(in srgb,var(--glow) 45%,transparent)}
.num b{display:block;font-size:30px;font-weight:800;letter-spacing:-.03em}
.num span{font-size:12.5px;color:var(--color-text-muted)}

.grid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
.card{padding:24px;border-radius:18px;border:1px solid var(--glass-line);background:var(--glass);
transition:.28s;position:relative;overflow:hidden}
.card::after{content:'';position:absolute;inset:0;opacity:0;transition:.3s;pointer-events:none;
  background:radial-gradient(340px circle at var(--mx,50%) var(--my,0%),color-mix(in srgb,var(--glow) 16%,transparent),transparent 70%)}
.card:hover{transform:translateY(-5px);border-color:color-mix(in srgb,var(--glow) 40%,transparent)}
.card:hover::after{opacity:1}
.card .ic{width:44px;height:44px;border-radius:13px;display:grid;place-items:center;margin-bottom:14px;
  background:linear-gradient(135deg,color-mix(in srgb,var(--glow) 22%,transparent),color-mix(in srgb,var(--glow-2) 16%,transparent));
  color:var(--color-text)}
.card h3{font-size:16px;font-weight:700;margin-bottom:6px}
.card p{font-size:14px;color:var(--color-text-muted)}

/* steps spine */
.spine{position:relative;padding-left:36px;max-width:760px}
.spine::before{content:'';position:absolute;left:12px;top:8px;bottom:8px;width:2px;border-radius:2px;
  background:linear-gradient(180deg,var(--glow),var(--glow-2))}
.sp{position:relative;padding-bottom:26px}
.sp:last-child{padding-bottom:0}
.sp::before{content:'';position:absolute;left:-30px;top:6px;width:10px;height:10px;border-radius:50%;
  background:var(--glow);box-shadow:0 0 0 5px var(--color-bg),0 0 16px var(--glow)}
.sp h3{font-size:16px;font-weight:700;margin-bottom:4px}
.sp p{font-size:14px;color:var(--color-text-muted)}

/* platforms */
/* the nav pill is sticky, so anchor jumps have to stop short of it */
section[id],header[id],.auth[id]{scroll-margin-top:96px}

.plats{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
/* The whole card is a link to that platform's landing page, so it needs the
   underline and inherited-colour resets a block element would not need. */
.pl{display:block;padding:20px;border-radius:18px;border:1px solid var(--glass-line);background:var(--glass);
text-decoration:none;color:inherit;transition:.28s}
.pl:hover{transform:translateY(-4px);border-color:color-mix(in srgb,var(--glow) 40%,transparent)}
.pl:hover h3{color:var(--glow)}
.pl:focus-visible{outline:2px solid var(--glow);outline-offset:3px}
.pl h3{transition:color .2s}
.pl-h{display:flex;align-items:center;gap:10px;margin-bottom:9px}
.pl-h img{width:24px;height:24px}
.pl h3{font-size:14.5px;font-weight:700}
.pl p{font-size:13px;color:var(--color-text-muted)}
.pl .fr{margin-top:11px;font-size:12.5px;color:var(--color-text-secondary)}

/* faq */
.faq{max-width:820px;margin:0 auto}
details{border:1px solid var(--glass-line);border-radius:14px;background:var(--glass);
margin-bottom:10px;transition:.25s}
details[open]{border-color:color-mix(in srgb,var(--glow) 35%,transparent)}
summary{padding:16px 18px;cursor:pointer;font-weight:600;font-size:15px;list-style:none;
  display:flex;justify-content:space-between;gap:14px}
summary::-webkit-details-marker{display:none}
summary::after{content:'+';color:var(--glow);font-size:20px;line-height:1;font-weight:400;transition:.25s}
details[open] summary::after{content:'−'}
details p{padding:0 18px 17px;color:var(--color-text-muted);font-size:14px}

footer{border-top:1px solid var(--glass-line);margin-top:30px}
.f-in{max-width:1220px;margin:0 auto;padding:26px;display:flex;gap:20px;flex-wrap:wrap;
  color:var(--color-text-muted);font-size:13px}
.f-in a{text-decoration:none}
.f-in .r{margin-left:auto}

@media (max-width:980px){
  .hero{grid-template-columns:1fr;gap:34px}
  .nums,.grid{grid-template-columns:repeat(2,1fr)}
  .plats{grid-template-columns:1fr}
}

/* The mockup simply hid the nav links on narrow screens. On the real page that
   would leave a phone with no way to reach Services, Blog or the API docs, so
   below 980px they collapse into a panel behind a toggle instead. */
.navtoggle{display:none;width:40px;height:40px;padding:0;border:0;border-radius:50%;
  cursor:pointer;background:var(--glass);color:var(--color-text);
  align-items:center;justify-content:center;transition:background .2s}
.navtoggle:hover{background:color-mix(in srgb,var(--color-text) 12%,transparent)}
.navtoggle svg{pointer-events:none}
.navtoggle .x{display:none}
.nav-in.open .navtoggle .x{display:block}
.nav-in.open .navtoggle .bars{display:none}

@media (max-width:980px){
  .navtoggle{display:inline-flex;margin-left:auto}
  .lk{position:absolute;top:calc(100% + 10px);left:0;right:0;margin:0;
    flex-direction:column;gap:2px;padding:10px;border-radius:22px;
    border:1px solid var(--glass-line);
    /* solid, not glass: this panel sits over hero text, and anything
       translucent makes both unreadable. Lifted slightly off the page
       background so it still reads as a raised surface. */
    background:color-mix(in srgb,var(--color-text) 7%,var(--color-bg));
    box-shadow:0 18px 50px rgba(0,0,0,.45);
    opacity:0;visibility:hidden;transform:translateY(-8px);
    transition:opacity .22s,transform .22s cubic-bezier(.2,.8,.2,1),visibility .22s}
  .nav-in.open .lk{opacity:1;visibility:visible;transform:none}
  .lk a{padding:13px 15px;font-size:15px}
  .lk a::after{display:none}
}

/* ---------- v2 additions ---------- */

/* backdrop-filter is kept only on the nav pill and the sign-in card. Every
   glass surface re-samples and re-blurs what is behind it on every frame, and
   with the aurora moving underneath that ran continuously across 33 elements.
   The aurora is already blurred by 90px, so blurring it a second time through
   a card added almost nothing visually while costing a frame budget on weak
   devices -- measured worst frame went 23ms -> 48ms at 6x CPU throttling. */

/* The aurora is three 90px-blurred layers. On a phone that is a real cost for
   decoration, so it is dropped below 720px and the page keeps its flat bg. */
@media (max-width:720px){ .aurora{display:none} }
.aurora i{will-change:transform}

/* On white the same wash reads far weaker than it does on black: the blur
   spreads a light tint over a light page. Light theme gets more of it. */
:root[data-theme="light"] .aurora i{opacity:.55}
:root[data-theme="light"] .aurora i:nth-child(3){opacity:.38}

/* Gradient headline text needs a real colour underneath: if background-clip
   is unsupported the text would otherwise render transparent. */
h1 .g{color:var(--glow)}
@supports (-webkit-background-clip:text) or (background-clip:text){
  h1 .g{-webkit-text-fill-color:transparent}
}

/* Keyboard users could not see where they were on the glass controls. */
.b-glow:focus-visible,.b-glass:focus-visible,.nav .cta:focus-visible,
.lk a:focus-visible,summary:focus-visible{
  outline:2px solid var(--glow);outline-offset:3px}

/* live ticker on the delivered-orders figure */
.num.live{position:relative}
.num.live::after{content:'';position:absolute;top:14px;right:14px;width:7px;height:7px;border-radius:50%;
  background:var(--glow-2);box-shadow:0 0 0 0 color-mix(in srgb,var(--glow-2) 70%,transparent);
  animation:pulse 2.2s infinite}


/* ---------- how it works: horizontal stepper ---------- */
.flow{position:relative;margin-top:8px}

/* the rail runs behind the nodes; the filled part follows scroll progress */
.flow::before,.flow::after{content:'';position:absolute;top:21px;height:2px;border-radius:2px}
.flow::before{left:9%;right:9%;background:var(--glass-line)}
.flow::after{left:9%;width:var(--fill,0%);max-width:82%;
  background:linear-gradient(90deg,var(--glow),var(--glow-2));
  transition:width .6s cubic-bezier(.2,.8,.2,1)}

.flow-in{display:grid;grid-template-columns:repeat(4,1fr);gap:18px;position:relative;z-index:1}

.fs{background:none;border:0;padding:0;font:inherit;color:inherit;text-align:center;cursor:pointer}
.fs .node{width:44px;height:44px;margin:0 auto 16px;border-radius:50%;display:grid;place-items:center;
  font-size:13px;font-weight:800;letter-spacing:-.01em;
  border:2px solid var(--glass-line);background:var(--color-bg);color:var(--color-text-muted);
  transition:.4s cubic-bezier(.2,.8,.2,1)}
.fs h3{font-size:15.5px;font-weight:700;margin-bottom:6px;transition:.3s}
.fs p{font-size:13.5px;color:var(--color-text-muted);max-width:26ch;margin:0 auto}

.fs:hover .node{border-color:color-mix(in srgb,var(--glow) 50%,transparent);transform:translateY(-3px)}
.fs.on .node{border-color:transparent;color:#fff;transform:scale(1.1);
  background:linear-gradient(135deg,var(--btn-grad-from),var(--btn-grad-to));
  box-shadow:0 0 0 6px var(--color-bg),0 10px 30px color-mix(in srgb,var(--glow) 45%,transparent)}
.fs.on h3{color:var(--color-text)}
.fs:not(.on) h3{color:var(--color-text-secondary)}
.fs:focus-visible{outline:2px solid var(--glow);outline-offset:6px;border-radius:14px}

@media (max-width:900px){
  .flow::before,.flow::after{display:none}
  .flow-in{grid-template-columns:1fr;gap:26px;text-align:left}
  /* Column gap separates the node from the text; the row gap only sits between
     heading and paragraph, so it stays small. */
  .fs{display:grid;grid-template-columns:44px 1fr;column-gap:16px;row-gap:5px;
    text-align:left;align-items:start}
  .fs .node{margin:0}
  /* Three children, two columns: auto-placement put the paragraph in the 44px
     node column on the second row, so it wrapped one word per line. Pin it
     under the heading instead. */
  .fs p{max-width:none;grid-column:2}
  .fs h3{margin-bottom:0}
}

/* payment methods */
.pays{display:flex;flex-wrap:wrap;gap:10px}
.pay svg{flex:none}
.pay{display:inline-flex;align-items:center;gap:8px;padding:11px 18px;border-radius:14px;
  border:1px solid var(--glass-line);background:var(--glass);
  font-size:13.5px;font-weight:600;transition:.25s}
.pay:hover{transform:translateY(-3px);border-color:color-mix(in srgb,var(--glow) 40%,transparent)}
.pay svg{color:var(--color-text-muted)}


@media (prefers-reduced-motion:reduce){
  .aurora i,.track,.pulse{animation:none}
  .rv{opacity:1;transform:none;transition:none}
  *{scroll-behavior:auto}
}
/* ---------- pieces the live page needs that the mockup did not ---------- */

/* the sign-in card is a real form now; auth-backend.js inserts its status
   messages as the first child of the form, so they are styled here */
.auth form{margin:0}
.message{padding:10px 13px;border-radius:10px;font-size:13px;margin-bottom:13px;line-height:1.45}
/* Was a fixed #fca5a5 on a fixed red tint: fine on the dark theme, but in
   light mode that is pale pink on pale pink -- measured 1.04:1, so the text
   was effectively invisible. The danger/success tokens flip with the theme. */
.message.error{background:var(--color-danger-bg);
  color:var(--color-danger);border:1px solid color-mix(in srgb,var(--color-danger) 34%,transparent)}
.message.success{background:var(--color-success-bg);
  color:var(--color-success);border:1px solid color-mix(in srgb,var(--color-success) 34%,transparent)}

.auth-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:-4px 0 14px}
.remember{display:flex;align-items:center;gap:7px;font-size:12px;font-weight:500;
  color:var(--color-text-muted);margin:0;cursor:pointer}
.remember input{width:auto;margin:0;accent-color:var(--glow)}
.fp{font-size:12px;color:var(--color-text-muted);text-decoration:none;margin:0}
.fp:hover{color:var(--color-text)}

.or{display:flex;align-items:center;gap:12px;margin:16px 0 13px;
  font-size:11.5px;letter-spacing:.08em;color:var(--color-text-muted)}
.or::before,.or::after{content:'';flex:1;height:1px;background:var(--glass-line)}
.gbtn{display:flex;justify-content:center;min-height:44px}

.fp-note{font-size:12.5px;color:var(--color-text-muted);margin:0 0 12px}
#forgotBox .b-glass{width:100%}
.fp-cancel{width:100%;margin-top:9px;padding:9px;border:0;background:none;cursor:pointer;
  font:inherit;font-size:12.5px;color:var(--color-text-muted)}
.fp-cancel:hover{color:var(--color-text)}

/* already signed in: the card turns into a way back into the panel */
.auth-in{text-align:center;padding:6px 0 2px}
.auth-in p{font-size:13.5px;color:var(--color-text-secondary);margin-bottom:16px}
.auth-in strong{color:var(--color-text)}

/* Several call-to-action elements are links rather than buttons now, so they
   need the alignment and underline reset a <button> gets by default. */
.nav a.cta{display:inline-flex;align-items:center;text-decoration:none}
a.b-glow,a.b-glass{display:inline-flex;align-items:center;justify-content:center;
  text-decoration:none;line-height:1}
.auth a.b-glow{width:100%}
.auth .foot a{text-decoration:none}
.auth .foot a:hover{text-decoration:underline}

/* ---------- footer ---------- */
/* Tinted with the text colour, not with black. Mixing toward black darkens in
   both themes: in light that produced a mid grey (188,187,185) which cut the
   muted text from its documented 4.6:1 down to 3.0:1. Mixing toward
   --color-text flips direction with the theme and stays close to the page. */
footer{margin-top:70px;border-top:1px solid var(--glass-line);
  background:color-mix(in srgb,var(--color-bg) 94%,var(--color-text))}
.f-top{display:grid;grid-template-columns:1.5fr 1fr 1fr 1fr;gap:38px;
  max-width:1220px;margin:0 auto;padding:52px 26px 40px}
.f-brand{display:flex;align-items:center;font-weight:800;font-size:19px;
  letter-spacing:-.03em;text-decoration:none;color:var(--color-text);margin-bottom:12px}
.f-brand img{width:26px;height:26px}
.f-about{font-size:13.5px;color:var(--color-text-secondary);max-width:34ch;margin-bottom:18px}
.f-contact{display:flex;flex-direction:column;gap:9px}
.f-contact a{display:inline-flex;align-items:center;gap:9px;font-size:13.5px;
  color:var(--color-text-secondary);text-decoration:none;transition:color .2s}
.f-contact a:hover{color:var(--color-text)}
.f-contact svg{flex:none;color:var(--glow-2)}
.f-col h3{font-size:12px;font-weight:700;letter-spacing:.09em;
  color:var(--color-text);margin-bottom:15px}
.f-col ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.f-col a{font-size:13.5px;color:var(--color-text-secondary);text-decoration:none;transition:color .2s}
.f-col a:hover{color:var(--color-text)}
.f-col li span{font-size:13.5px;color:var(--color-text-secondary)}
.f-bot{border-top:1px solid var(--glass-line)}
.f-bot-in{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:12px;
  max-width:1220px;margin:0 auto;padding:20px 26px;font-size:12.5px;color:var(--color-text-secondary)}
.f-legal{display:flex;flex-wrap:wrap;gap:18px}
.f-legal a{color:var(--color-text-secondary);text-decoration:none}
.f-legal a:hover{color:var(--color-text)}
@media (max-width:900px){
  .f-top{grid-template-columns:1fr 1fr;gap:30px;padding:40px 22px 32px}
}
@media (max-width:560px){
  .f-top{grid-template-columns:1fr}
  .f-bot-in{flex-direction:column;align-items:flex-start}
}

/* ==========================================================================
   Legacy page bridge

   The marketing and SEO pages were built before this shell. They paint their
   own opaque section backgrounds, which sit on top of the aurora and make each
   page look like a different site. This section lines them up with the
   homepage: one measure, transparent sections, shared glass surfaces.
   Remove a rule here once the page it targets stops needing it.
   ========================================================================== */

/* .container is what those pages use where the homepage uses .wrap. Several
   sections override it to full width, so those have to be named explicitly —
   a bare .container rule loses to them on specificity. */
.container,
.service-filter .container,
.services-list .container,
.seo-section .container{max-width:1220px;margin:0 auto;padding:0 26px}

/* sections must let the aurora through, and stop drawing their own edges */
.service-filter,
.services-list,
.seo-section,
.page-header,
.contact-section,
.api-section,
.blog-section{background:transparent;background-image:none;border-top:0;border-bottom:0}

/* their card surfaces become the same glass the homepage uses */
/* .services-table-card is handled in style.css instead: the panel loads that
   file too, and one definition keeps the two Services views identical. */
.seo-card,
.contact-card,
.api-card{border:1px solid var(--glass-line);background:var(--glass)}

/* The old navigation was fixed to the top, so every page reserved ~120px for
   it. The pill is sticky and already takes its own space, which left that
   reservation as a hole under the header. */
.seo-page{padding-top:26px}
/* The hero's bottom padding and the first section's top padding stacked on top
   of the subtitle's own margin: 28 + 45 + 44 left a 151px hole between the
   intro sentence and the first heading. */
.seo-hero{padding-top:26px;padding-bottom:14px}
.seo-section{padding-top:26px}
.seo-hero .seo-subtitle{margin-bottom:14px}
/* enough to clear the sticky pill without reopening the hole */
.page-header{padding-top:34px;padding-bottom:26px}
.api-hero,.contact-hero{padding-top:26px}

/* The SEO pages ran a bigger type scale than the homepage, so a visitor moving
   between them saw two different sites. One scale now. */
.seo-title{font-size:clamp(30px,4vw,50px);letter-spacing:-.032em;line-height:1.12}
.seo-subtitle,.seo-lead{font-size:16px}

/* One type scale across the site. The SEO pages ran their own, so a heading
   was 48px there and 34px on the homepage. */
.seo-section h2,
.seo-article h2,
.page-title{font-size:clamp(24px,2.7vw,34px);font-weight:800;letter-spacing:-.032em;line-height:1.15}
.seo-section h3,
.seo-article h3{font-size:17px;font-weight:700}

/* The call to action carries the same gradient as the homepage, so "Create
   account" looks like the same button wherever a visitor meets it. */
.seo-actions .btn-primary,
.btn.btn-primary{border:0;border-radius:999px;padding:13px 26px;font-weight:700;
  color:#fff;background:linear-gradient(135deg,var(--btn-grad-from),var(--btn-grad-to));
  box-shadow:0 8px 28px color-mix(in srgb,var(--glow) 42%,transparent);
  transition:transform .25s,box-shadow .25s}
.seo-actions .btn-primary:hover,
.btn.btn-primary:hover{transform:translateY(-2px);
  box-shadow:0 14px 38px color-mix(in srgb,var(--glow) 60%,transparent)}

/* .btn-secondary is the second CTA on the landing pages; .btn-outline is the
   same role elsewhere. Both become the glass button the homepage uses. */
.seo-actions .btn-outline,
.seo-actions .btn-secondary,
.btn.btn-outline,
.btn.btn-secondary{border:1px solid var(--glass-line);border-radius:999px;padding:13px 24px;
  font-weight:700;background:var(--glass);color:var(--color-text);
  background-image:none;box-shadow:none;transition:transform .25s}
.seo-actions .btn-outline:hover,
.seo-actions .btn-secondary:hover,
.btn.btn-outline:hover,
.btn.btn-secondary:hover{transform:translateY(-2px);
  border-color:color-mix(in srgb,var(--glow) 40%,transparent)}

/* The closing call to action painted itself with the primary button colour and
   let its text inherit the body colour. In this token set those resolve to the
   same value, so the whole band rendered blank — a light strip with invisible
   text above the footer. It becomes a normal section instead. */
.cta-section{background:transparent;background-image:none;padding:56px 0}
.cta-title{font-size:clamp(24px,2.7vw,34px);font-weight:800;color:var(--color-text)}
.cta-subtitle{font-size:15.5px;color:var(--color-text-muted);opacity:1}
.cta-section .btn{border:0;border-radius:999px;padding:13px 26px;font-weight:700;color:#fff;
  background:linear-gradient(135deg,var(--btn-grad-from),var(--btn-grad-to));
  box-shadow:0 8px 28px color-mix(in srgb,var(--glow) 42%,transparent)}
.cta-section .btn:hover{background:linear-gradient(135deg,var(--btn-grad-from),var(--btn-grad-to));color:#fff}

/* the tabs and the table read as one block, so they sit closer together */
.service-filter{padding:24px 0 10px}
.services-list{padding-top:14px}

/* ---------- API docs ----------------------------------------------------- */
/* The docs page stacks its sections into one long 900px card, which is right
   for a reference page and stays. What did not match the rest of the site was
   the surface itself: an opaque panel with no shadow, and a header row that
   was neither uppercase nor the same size as every other table. */
.api-section > .container{background:var(--glass);
  border-left-color:var(--glass-line);border-right-color:var(--glass-line)}
.api-section--lead > .container{border-top-color:var(--glass-line);
  /* 120px was reserved for the old fixed navigation and left a hole under the
     header. The pill is sticky and takes its own space, so all that is needed
     is the same 26px of breathing room the other pages open with -- at 0 the
     card sat flush against the pill.
     This also overrides the 185px/110px this file's own media queries still
     set, because the shell is loaded after them. */
  margin-top:26px;box-shadow:0 8px 32px rgba(0,0,0,.4)}
.api-section:last-of-type > .container{border-bottom-color:var(--glass-line)}

/* same header treatment as the services table */
.param-row--head{background:var(--color-table-head-bg);font-size:12px;
  letter-spacing:.04em;text-transform:uppercase}
.params-table,
.api-kv-table{border-color:var(--glass-line)}
.api-kv-table td{font-size:15px}

/* ==========================================================================
   Sign-up form extras
   The sign-in card on the homepage needs none of these: it has no password
   reveal, no per-field hints and no consent line that wraps onto two rows.
   Everything else on /signup reuses the .auth rules above unchanged.
   ========================================================================== */
.auth .pw{position:relative}
/* keeps the typed value clear of the reveal button */
.auth .pw input{padding-right:44px}
.auth .pw-eye{position:absolute;top:11px;right:11px;width:24px;height:24px;
  display:grid;place-items:center;padding:0;border:0;background:none;
  cursor:pointer;color:var(--color-text-muted);transition:color .2s}
.auth .pw-eye:hover{color:var(--color-text)}

/* pulled up under the field it describes, since .auth input already
   carries a 13px bottom margin */
.auth .hint{display:block;font-size:12px;color:var(--color-text-muted);
  margin:-9px 0 13px}

/* .remember centres a single line; the consent text runs to two, so the
   box has to sit against the first one instead of the middle */
.auth .terms{align-items:flex-start;margin:2px 0 16px;line-height:1.5}
.auth .terms input{margin-top:2px}
.auth .terms a{color:var(--color-text);font-weight:600;text-decoration:none}
.auth .terms a:hover{text-decoration:underline}

/* The popup shell's close button. style.css hides it outside popup mode, but
   pages that only load the shell (see /signup) would otherwise render a stray
   "x" in the page flow, so the same two rules live here as well. */
.lightbox-close{position:absolute;top:16px;right:16px;width:44px;height:44px;
  border-radius:50%;border:1px solid var(--glass-line);background:var(--glass);
  color:var(--color-text);font-size:1.5rem;font-weight:700;cursor:pointer;
  display:none;align-items:center;justify-content:center;transition:.2s;z-index:3}
.lightbox-close:hover{border-color:var(--glow);color:var(--glow)}
body.popup-mode .lightbox-close{display:flex}
