/* ============================================================================
   boba.css — soft pastel-purple restyle, layered on top of app.css
   ────────────────────────────────────────────────────────────────────────────
   Aesthetic shift:
     FROM: acid-lime cyber-zine, editorial Instrument Serif italics, sharp
           rectangles, large §-numbered section rules, scrolling marquee.
     TO:   boba.xyz vibe — soft lavender accent, sans-only typography,
           pill-shaped buttons, generous rounding, organic background blobs,
           hidden editorial chrome (no ticker, no section §-numbers).

   Strategy: override design tokens + a small set of component rules. Most
   of app.css carries over unchanged — that means visual changes propagate
   to every page (panel, billing, admin, chat, etc.) without per-template
   edits. To roll back: just remove the <link> in base.html.
   ============================================================================ */

:root {
  /* ─── Palette ──────────────────────────────────────────────────── */
  --ink:         #0F0F12;
  --ink-soft:    #131317;
  --surface-1:   #1A1A20;
  --surface-2:   #1E1E26;
  --surface-3:   #25252E;
  --border:      #2A2A33;
  --border-soft: #1F1F26;
  --border-hot:  #3A3A47;

  --paper:       #F5F5F7;
  --paper-soft:  #DCDCE0;
  --mute:        #8E8E94;
  --mute-soft:   #6A6A72;
  --faint:       #4A4A54;

  /* Primary accent — lavender. Replaces acid-lime everywhere it was
     referenced via the --acid token (button bg, focus rings, brand dot,
     pill dot, section-rule num, etc.). */
  --acid:        #C4A9FF;
  --acid-dim:    #A88AEF;
  --acid-glow:   rgba(196, 169, 255, 0.22);

  /* Secondary accents — softened to pastel. */
  --magenta:     #F49AC2;
  --magenta-dim: #E07AAB;
  --cyan:        #8ED5DC;
  --amber:       #F4D58D;
  --rose:        #F0A8AC;
  --emerald:     #9DD5B5;

  /* ─── Typography — sans-only ──────────────────────────────────────
     Drop Instrument Serif everywhere (--font-display) and re-route it to
     the same Inter stack as --font-body. Keep --font-mono for code/IDs. */
  --font-display: "Inter", "Hanken Grotesk", "Helvetica Neue", system-ui, -apple-system, sans-serif;
  --font-body:    "Inter", "Hanken Grotesk", "Helvetica Neue", system-ui, -apple-system, sans-serif;

  /* ─── Generous rounding ─────────────────────────────────────────── */
  --radius-sm:  10px;
  --radius:     14px;
  --radius-lg:  20px;
  --radius-xl:  28px;

  /* ─── Atmospheric softening ─────────────────────────────────────── */
  --mesh-opacity:  0.72;
  --grain-opacity: 0.025;
}

/* ─── Body background — soft amorphous blobs ────────────────────────
   Replace the original three-color radial-gradient with four lavender /
   pink / cyan blobs and a slight central wash. Heavier blur, less
   saturation than the cyber-zine atmosphere.

   Also swap the animation to `boba-drift` — same idea but slower (90s
   instead of 38s) and with a smaller motion footprint. Feels calmer:
   one full traversal takes a minute and a half instead of half a
   minute, and the rotation is 4° instead of 8°. */
body::before {
  background:
    radial-gradient(58vw 50vw at 12% 14%, rgba(196, 169, 255, 0.10) 0%, transparent 64%),
    radial-gradient(44vw 44vw at 88% 22%, rgba(244, 154, 194, 0.075) 0%, transparent 64%),
    radial-gradient(60vw 50vw at 70% 92%, rgba(142, 213, 220, 0.06) 0%, transparent 64%),
    radial-gradient(34vw 30vw at 50% 50%, rgba(196, 169, 255, 0.04) 0%, transparent 70%) !important;
  filter: blur(70px) saturate(1.05) !important;
  animation: boba-drift 90s linear infinite alternate !important;
}
@keyframes boba-drift {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg); }
  100% { transform: translate3d(-1.6%, 2%, 0) rotate(4deg); }
}

/* prefers-reduced-motion override — kill the drift entirely. */
@media (prefers-reduced-motion: reduce) {
  body::before { animation: none !important; }
}

/* ─── Hide editorial chrome ─────────────────────────────────────────
   Ticker marquee is gone, section-rule loses its §-number + horizontal
   lines and becomes a simple heading. */
.ticker { display: none !important; }

.section-rule {
  display: flex;
  gap: 12px;
  margin: 56px 0 22px;
  align-items: baseline;
  font-family: var(--font-body);
  font-size: 14px;
  letter-spacing: 0;
  text-transform: none;
}
.section-rule::before,
.section-rule::after { display: none !important; }
.section-rule__num { display: none; }
.section-rule__title {
  color: var(--paper);
  font-weight: 600;
  font-size: 18px;
  letter-spacing: -0.012em;
  text-transform: none;
}

/* ─── Buttons — pill-shaped, soft shadow on hover ──────────────────── */
.btn {
  height: 44px;
  padding: 0 22px;
  border-radius: 999px;
  font-weight: 500;
  letter-spacing: -0.005em;
}
.btn--sm { height: 36px; padding: 0 16px; border-radius: 999px; font-size: 13px; }

.btn--primary {
  background: var(--acid);
  color: #1A1A20;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.10) inset;
}
.btn--primary:hover {
  background: var(--acid-dim);
  box-shadow: 0 6px 22px rgba(196, 169, 255, 0.28), 0 1px 0 rgba(255, 255, 255, 0.12) inset;
}

.btn--ghost {
  background: rgba(255, 255, 255, 0.04);
  border-color: transparent;
  color: var(--paper);
}
.btn--ghost:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: transparent;
}

.btn--magenta {
  background: var(--magenta);
  color: #1A1A20;
}
.btn--magenta:hover { background: var(--magenta-dim); }

.btn--danger-link {
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}

/* ─── Cards — softer surface, no corner marks ──────────────────────── */
.card {
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  padding: 26px;
}
.card--marked::before,
.card--marked::after { display: none !important; }
.card--hero,
.card--magenta,
.card--emerald {
  background:
    radial-gradient(80% 100% at 0% 0%, rgba(196, 169, 255, 0.08) 0%, transparent 70%),
    var(--surface-1);
  border: 1px solid var(--border-soft);
}

/* ─── Brand — drop the italic serif, cat mascot mark ───────────────── */
.brand__name {
  font-family: var(--font-body);
  font-weight: 700;
  font-style: normal;
  font-size: 18px;
  letter-spacing: -0.012em;
  line-height: 1;
}
.brand__name .dot { color: var(--acid); }
.brand__name .ext {
  font-family: var(--font-body);
  font-weight: 500;
  font-style: normal;
  font-size: 14px;
  color: var(--mute);
  letter-spacing: 0;
}

/* Brand mark — rounded lavender square holding the white cat SVG.
   `color: white` propagates to the cat path via `fill="currentColor"`
   in the inline SVG (base.html). Sized slightly bigger than the old
   wedge mark so the cat reads at small sizes. */
.brand__mark {
  width: 30px;
  height: 30px;
  background: var(--acid);
  border-color: transparent;
  border-radius: 9px;
  color: #FFFFFF;
}
.brand__mark svg,
.brand__mark img {
  width: 22px;
  height: 22px;
  object-fit: contain;
  display: block;
}
.brand__mark svg path,
.brand__mark svg ellipse {
  stroke: none;
}

/* ─── Site header — softer translucent ─────────────────────────────── */
.site-header {
  background: rgba(15, 15, 18, 0.78);
  border-bottom: 1px solid var(--border-soft);
}
.site-header__inner { height: 64px; }

/* ─── Nav — pill links, lavender active ────────────────────────────── */
.nav__link {
  border-radius: 999px;
  padding: 0 14px;
  font-weight: 500;
}
.nav__link:hover { background: rgba(255, 255, 255, 0.05); }
.nav__link--active {
  background: rgba(196, 169, 255, 0.12);
  color: var(--acid);
}
.nav__link--cta {
  background: var(--acid);
  color: #1A1A20;
  border-radius: 999px;
  padding: 0 16px;
}
.nav__link--cta:hover { background: var(--acid-dim); color: #1A1A20; }
.nav__user {
  font-family: var(--font-body);
  font-weight: 500;
}

/* The button inherits the rectangular silhouette of its wrapper — no
   pill rounding here, otherwise the active state (which has a filled
   background) shows the rounded shape while the inactive sibling stays
   flat-looking. The wrapper `.lang-switch` already supplies the 6px
   outer radius + overflow:hidden. */
.lang-switch__btn {
  border-radius: 0;
  cursor: pointer;
}

/* ─── Footer — minimal, single-row ─────────────────────────────────── */
.site-footer {
  margin-top: 80px;
  border-top: 1px solid var(--border-soft);
  padding: 24px 28px 28px;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--mute);
}
.site-footer__inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
}
.site-footer__cols,
.site-footer__heading,
.site-footer__list { display: none !important; }
.site-footer__inner > div:first-child > div:last-child {
  color: var(--mute);
  font-family: var(--font-body);
}
.site-footer__legal {
  display: inline-flex;
  align-items: center;
  gap: 18px;
  font-family: var(--font-body);
  font-size: 13px;
  color: var(--mute);
}
.site-footer__legal a {
  color: var(--mute);
  text-decoration: none;
  transition: color 160ms ease;
}
.site-footer__legal a:hover { color: var(--paper); }

/* ─── Inputs — softer ──────────────────────────────────────────────── */
.input {
  height: 46px;
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--border-soft);
  font-family: var(--font-body);
  font-size: 14.5px;
}
.input:focus {
  border-color: var(--acid);
  background: rgba(196, 169, 255, 0.04);
  box-shadow: 0 0 0 4px var(--acid-glow);
}

.field-label {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--mute);
}
.field-label::before { display: none; }

/* ─── Eyebrow — less aggressive ────────────────────────────────────── */
.eyebrow {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--mute);
}

/* ─── Pills / chips / tags ─────────────────────────────────────────── */
.pill {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  padding: 6px 12px;
}
.chip {
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
}
.tag {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  padding: 4px 10px;
}
.tag--image { background: rgba(244, 154, 194, 0.10); color: var(--magenta); border-color: rgba(244, 154, 194, 0.30); }
.tag--ok    { background: rgba(157, 213, 181, 0.12); color: var(--emerald); border-color: rgba(157, 213, 181, 0.30); }

/* ─── Hero title — drop the giant serif italic ─────────────────────── */
.hero__title {
  font-family: var(--font-body);
  font-weight: 700;
  font-style: normal;
  font-size: clamp(42px, 8vw, 88px);
  line-height: 1.05;
  letter-spacing: -0.028em;
}
.hero__title .it { font-style: normal; }
.hero__title .em {
  color: var(--acid);
  position: relative;
}
.hero__title .em::after { display: none; }
.hero__lede {
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
}

.hero__num { display: none; }   /* hide editorial "§ 01 / GATEWAY" label */
.hero__stat-label { font-family: var(--font-body); font-weight: 500; font-size: 12px; letter-spacing: 0; text-transform: none; }

/* Hero stat numbers — drop from 700 to 500 so they feel reportive,
   not brutalist. Boba uses a similar light-display weight for stats. */
.hero__stat-value {
  font-family: var(--font-body);
  font-weight: 500;
  font-style: normal;
  font-size: 32px;
  letter-spacing: -0.022em;
  color: var(--paper);
}
.hero__stat-value .small {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 13px;
  color: var(--mute);
}

/* Stats strip — softer card shell instead of edge-only borders. */
.hero__stats {
  margin-top: 48px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--surface-1);
  overflow: hidden;
}
.hero__stat {
  border-right: 1px solid var(--border-soft);
}
.hero__stat:last-child { border-right: none; }

/* The leftmost stat (live latency) gets a pulsing dot in front of the
   label so visitors register that the number is being measured live,
   not stamped at build time. Updates every 5 minutes via live_stats. */
.hero__stat-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.hero__stat-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--emerald);
  box-shadow: 0 0 0 0 rgba(157, 213, 181, 0.55);
  animation: hero-stat-dot-pulse 2.2s ease-out infinite;
}
@keyframes hero-stat-dot-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(157, 213, 181, 0.55); }
  70%  { box-shadow: 0 0 0 7px rgba(157, 213, 181, 0); }
  100% { box-shadow: 0 0 0 0 rgba(157, 213, 181, 0); }
}
.hero__stat-pending {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 18px;
  color: var(--mute);
  letter-spacing: -0.005em;
}

/* ─── Landing hero — boba-mode centering + cat mascot card ──────────
   When the index page sets `.hero--boba`, the section becomes a
   flex-column centered layout with the mascot card above the title.
   Inner pages (panel, billing, etc.) don't get this — they use the
   default left-aligned hero treatment. */
.hero--boba {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding-top: 56px;
}
.hero--boba .hero__top {
  justify-content: center;
  margin-bottom: 22px;
}
.hero--boba .hero__title {
  text-align: center;
  max-width: 14ch;
}
.hero--boba .hero__lede {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}
.hero--boba .hero__cta {
  justify-content: center;
}
.hero--boba .hero__stats {
  width: 100%;
}

.hero__mascot {
  width: 96px;
  height: 96px;
  margin-bottom: 28px;
  border-radius: 22px;
  background: var(--acid);
  display: grid;
  place-items: center;
  box-shadow:
    0 18px 60px -16px rgba(196, 169, 255, 0.45),
    0 4px 14px -6px rgba(196, 169, 255, 0.30);
  transition: transform 0.3s var(--ease-out);
}
.hero__mascot:hover {
  transform: rotate(-3deg) translateY(-2px);
}
.hero__mascot svg,
.hero__mascot img {
  width: 80px;
  height: 80px;
  object-fit: contain;
  display: block;
}

/* ─── Page headings — keep big but lose the editorial italic ──────── */
.page-h1 {
  font-family: var(--font-body) !important;
  font-style: normal !important;
  font-weight: 700;
  letter-spacing: -0.025em;
}
.page-sub {
  font-family: var(--font-body);
  color: var(--paper-soft);
}

/* `<span class="it">` is used across hero / page / numcard headings as
   an "emphasis" mark — originally rendered in italic Instrument Serif.
   Globally drop the italic and tint it lavender so it still reads as
   accent without the editorial slant. */
.it {
  font-style: normal !important;
  color: var(--acid);
}

/* ─── Pull-quote — restrained sans, lavender bar ───────────────────── */
.pullquote {
  font-family: var(--font-body);
  font-style: normal;
  font-weight: 500;
  font-size: clamp(22px, 3vw, 32px);
  line-height: 1.3;
  letter-spacing: -0.012em;
  border-left: 3px solid var(--acid);
  padding-left: 22px;
}
.pullquote .quotemark { display: none; }

/* ─── Numcard — drop italic ────────────────────────────────────────── */
.numcard {
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
}
.numcard__no {
  font-family: var(--font-body);
  font-weight: 800;
  font-style: normal;
  font-size: 28px;
  color: var(--faint);
}
.numcard__title {
  font-family: var(--font-body);
  font-weight: 600;
  font-style: normal;
  font-size: 18px;
  letter-spacing: -0.012em;
}
.numcard__body { font-size: 14px; }

/* ─── Data table ───────────────────────────────────────────────────── */
.data-wrap {
  border-radius: var(--radius-lg);
  background: var(--surface-1);
}
.data-table thead th {
  font-family: var(--font-body);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: none;
  color: var(--mute);
}
.data-table tbody tr:hover { background: rgba(196, 169, 255, 0.04); }

.data-table__id   { font-family: var(--font-mono); font-size: 12.5px; }
.data-table__meta { font-family: var(--font-body); font-size: 12.5px; color: var(--mute); }

/* ─── Stat / hero numbers ──────────────────────────────────────────── */
.stat-big {
  font-family: var(--font-body) !important;
  font-style: normal !important;
  font-weight: 700;
  letter-spacing: -0.02em;
}

/* ─── Code blocks — kept mono, softer borders ──────────────────────── */
pre.code-block, .code-card {
  border-radius: var(--radius);
  border-color: var(--border-soft);
}

/* ─── Selection ────────────────────────────────────────────────────── */
::selection { background: var(--acid); color: #1A1A20; }

/* ─── Plan cards (billing) — pill-shaped buttons inside, soft borders */
.plan-card {
  background: var(--surface-1);
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
}
.plan-card--featured {
  border-color: rgba(196, 169, 255, 0.40);
}

/* ─── Chat sidebar / main — already soft, just unify radii ─────────── */
.chat-side,
.chat-main {
  background: var(--surface-1);
  border-color: var(--border-soft);
  border-radius: var(--radius-lg);
}
.chat-msg--user {
  background: rgba(196, 169, 255, 0.10);
  border-color: rgba(196, 169, 255, 0.22);
}
.chat-msg--asst {
  background: rgba(255, 255, 255, 0.025);
}
.chat-toolbar select {
  border-radius: 8px;
}

/* ─── Provider picker (billing) — softer ──────────────────────────── */
.provider-pick {
  border-radius: var(--radius);
}
.provider-pick__name {
  font-family: var(--font-body);
  font-weight: 600;
}

/* ─── Misc cleanups: places using --font-display directly ─────────── */
[style*="--font-display"] {
  font-family: var(--font-display) !important;
  font-style: normal !important;
}

/* ─── Alerts ────────────────────────────────────────────────────── */
.alert-ok,
.alert-error {
  border-radius: var(--radius);
}

/* Editorial § markers were noise in production — hidden globally.
   Section titles still render via `.section-rule__title`. */
.section-rule__num { display: none; }

/* ─── Legal pages (Terms / Privacy) ─────────────────────────────────
   Read-only documents — narrow column, generous line-height, muted
   color hierarchy. No grids, no cards. */
.legal {
  max-width: 720px;
  margin: 48px auto 80px;
  padding: 0 4px;
}
.legal__head {
  padding-bottom: 22px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--border-soft);
}
.legal__head .page-h1 {
  margin: 12px 0 8px;
}
.legal__head .page-sub {
  color: var(--mute);
  font-size: 13.5px;
}
.legal__section {
  padding: 18px 0;
  border-bottom: 1px dashed var(--border-soft);
}
.legal__section:last-child {
  border-bottom: none;
}
.legal__h2 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 17px;
  letter-spacing: -0.01em;
  color: var(--paper);
  margin: 0 0 12px;
}
.legal p {
  margin: 0 0 12px;
  color: var(--paper-soft);
  font-size: 14.5px;
  line-height: 1.7;
}
.legal p:last-child {
  margin-bottom: 0;
}
.legal a {
  color: var(--acid);
  text-decoration: underline;
  text-decoration-color: rgba(196, 169, 255, 0.4);
  text-underline-offset: 2px;
}
.legal a:hover {
  text-decoration-color: var(--acid);
}
.legal strong {
  color: var(--paper);
  font-weight: 600;
}
.legal__list {
  margin: 0 0 12px;
  padding: 0;
  list-style: none;
}
.legal__list li {
  position: relative;
  padding: 6px 0 6px 22px;
  color: var(--paper-soft);
  font-size: 14.5px;
  line-height: 1.65;
}
.legal__list li::before {
  content: "";
  position: absolute;
  left: 4px;
  top: 14px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--acid);
  opacity: 0.6;
}

/* ─── Auth pages (login / register) — Boba-style centered card ────
   The page itself drops the site header/footer/ticker (see the {% block %}
   overrides in login.html / register.html). What's left is a single
   floating card in the middle of the viewport plus a "Back" pill in the
   top-left, matching the boba.xyz / Boba DeFi auth flow. */
body.page-auth main {
  padding: 0;
}
body.page-auth main .shell {
  max-width: none;
  margin: 0;
  padding: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

.auth-back {
  position: fixed;
  top: 22px;
  left: 22px;
  z-index: 10;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 16px 9px 12px;
  border-radius: 999px;
  background: rgba(30, 30, 38, 0.7);
  border: 1px solid var(--border-soft);
  color: var(--paper-soft);
  font-family: var(--font-body);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: background 180ms ease, border-color 180ms ease, color 180ms ease;
}
.auth-back:hover {
  background: rgba(40, 40, 50, 0.85);
  border-color: var(--border-hot);
  color: var(--paper);
}
.auth-back svg {
  flex: 0 0 auto;
}

.auth-card {
  width: 100%;
  max-width: 420px;
  margin: 48px auto;
  padding: 36px 32px 28px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-xl);
  background: var(--surface-1);
  text-align: center;
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.02) inset,
    0 20px 60px -20px rgba(0, 0, 0, 0.55);
}

.auth-card__logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  margin: 0 auto 18px;
  border-radius: 22px;
  background: var(--acid);
  box-shadow: 0 8px 32px -8px var(--acid-glow);
}
.auth-card__logo svg {
  width: 48px;
  height: 48px;
}

.auth-card__title {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 22px;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--paper);
  margin: 0;
}

.auth-card__form {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 24px;
  text-align: left;
}

.auth-card__field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.auth-card__field .input {
  width: 100%;
}

.auth-card__hint {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--mute-soft);
  letter-spacing: 0.02em;
}

.auth-card__submit {
  width: 100%;
  height: 48px;
  justify-content: center;
  font-size: 15px;
  font-weight: 600;
  margin-top: 4px;
}

.auth-card__alt {
  margin: 18px 0 0;
  font-size: 13px;
  color: var(--mute);
  text-align: center;
}
.auth-card__alt a {
  color: var(--acid);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 160ms ease;
}
.auth-card__alt a:hover {
  border-bottom-color: var(--acid);
}

.auth-card__tos {
  margin: 18px -4px 0;
  font-size: 11px;
  line-height: 1.55;
  color: var(--mute-soft);
  text-align: center;
}
.auth-card__tos a {
  color: var(--mute);
  text-decoration: underline;
  text-decoration-color: rgba(196, 169, 255, 0.35);
  text-underline-offset: 2px;
}
.auth-card__tos a:hover {
  color: var(--paper-soft);
}

.auth-card__referral {
  margin-top: 18px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(142, 213, 220, 0.08);
  border: 1px solid rgba(142, 213, 220, 0.28);
  color: var(--cyan);
  font-size: 12px;
  font-weight: 500;
}
.auth-card__referral .pill__dot {
  background: var(--cyan);
}

.auth-foot {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 22px;
  text-align: center;
  font-size: 12.5px;
  color: var(--mute-soft);
  pointer-events: none;
}
.auth-foot a,
.auth-foot span {
  display: inline-block;
  margin: 0 12px;
  pointer-events: auto;
}
.auth-foot a {
  color: var(--mute);
  text-decoration: none;
}
.auth-foot a:hover {
  color: var(--paper-soft);
}

@media (max-width: 560px) {
  .auth-back {
    top: 14px;
    left: 14px;
    padding: 7px 12px 7px 10px;
    font-size: 12px;
  }
  .auth-card {
    margin: 80px 16px 80px;
    padding: 28px 22px 22px;
  }
  .auth-card__title {
    font-size: 20px;
  }
  .auth-foot {
    bottom: 14px;
  }
}

/* ─── Language swap transition ─────────────────────────────────────
   While lang-switch.js is fetching the new locale's HTML and swapping
   <main>/<nav>/<footer> in place, fade main+footer briefly so the swap
   doesn't feel jarring. The lang switcher itself stays at full opacity
   so you can still see which button you pressed. */
body.lang-swapping main,
body.lang-swapping .site-footer {
  transition: opacity 140ms ease;
  opacity: 0.55;
  pointer-events: none;
}

/* ─── Live feed (landing) ──────────────────────────────────────────
   Two synthetic charts in a side-by-side grid — RPS (magenta) and edge
   ping (lavender). The values are generated client-side in
   /static/js/live-feed.js for decorative effect; the real upstream
   latency is the server-rendered number up in the hero stats strip. */
.live-feed {
  display: grid;
  grid-template-columns: 1fr;
  gap: 18px;
}

.live-feed__card {
  position: relative;
  padding: 22px 24px 18px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--surface-1);
  overflow: hidden;
}

.live-feed__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 14px;
}

.live-feed__title {
  font-family: var(--font-body);
  font-size: 13.5px;
  font-weight: 600;
  color: var(--paper);
  letter-spacing: -0.005em;
}
.live-feed__sub {
  margin-top: 2px;
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--mute);
}

.live-feed__pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(244, 154, 194, 0.10);
  border: 1px solid rgba(244, 154, 194, 0.25);
  color: var(--magenta);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.18em;
}
.live-feed__pill::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--magenta);
  animation: live-feed-pulse 1.6s ease-out infinite;
}
.live-feed__card--ping .live-feed__pill {
  background: rgba(196, 169, 255, 0.10);
  border-color: rgba(196, 169, 255, 0.28);
  color: var(--acid);
}
.live-feed__card--ping .live-feed__pill::before {
  background: var(--acid);
}
@keyframes live-feed-pulse {
  0%   { box-shadow: 0 0 0 0 currentColor; opacity: 1; }
  70%  { box-shadow: 0 0 0 5px transparent; opacity: 0.55; }
  100% { box-shadow: 0 0 0 0 transparent; opacity: 1; }
}

.live-feed__value {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 38px;
  line-height: 1;
  letter-spacing: -0.025em;
  color: var(--paper);
}
.live-feed__value-unit {
  margin-left: 5px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 500;
  color: var(--mute);
}
.live-feed__value-suffix {
  margin-left: 8px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--mute-soft);
  letter-spacing: 0.04em;
}

.live-feed__chart-wrap {
  position: relative;
  margin: 6px -12px -6px;
}
.live-feed__chart {
  display: block;
  width: 100%;
  height: 160px;
  overflow: visible;
}
.live-feed__line {
  fill: none;
  stroke-width: 1.6;
  stroke-linejoin: round;
  stroke-linecap: round;
}
.live-feed__forecast {
  stroke-width: 1.2;
  stroke-dasharray: 3 3;
  opacity: 0.55;
}
.live-feed__dot {
  r: 2.8;
}
.live-feed__card--rps .live-feed__line,
.live-feed__card--rps .live-feed__forecast {
  stroke: var(--magenta);
}
.live-feed__card--rps .live-feed__dot { fill: var(--magenta); }
.live-feed__card--ping .live-feed__line,
.live-feed__card--ping .live-feed__forecast {
  stroke: var(--acid);
}
.live-feed__card--ping .live-feed__dot { fill: var(--acid); }

/* Subtle dot-grid backdrop behind the chart — same idea as the
   Wrangler screenshot. Pure CSS, no extra DOM. */
.live-feed__card::after {
  content: "";
  position: absolute;
  inset: 64px 12px 12px;
  background-image: radial-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 14px 14px;
  pointer-events: none;
  z-index: 0;
}
.live-feed__head,
.live-feed__chart-wrap {
  position: relative;
  z-index: 1;
}

@media (max-width: 760px) {
  .live-feed__value {
    font-size: 32px;
  }
  .live-feed__chart {
    height: 120px;
  }
}

/* ─── Provider viewer (landing) ────────────────────────────────────
   Replaces the dense "models & pricing" table on /. Three tabs across
   the top (logos + name), and a panel beneath that lists the available
   model IDs for the selected provider. No prices, no type tags —
   pricing lives behind auth in /panel. */
[x-cloak] { display: none !important; }

.provider-viewer {
  border: 1px solid var(--border-soft);
  border-radius: var(--radius-lg);
  background: var(--surface-1);
  overflow: hidden;
}

.provider-tabs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  border-bottom: 1px solid var(--border-soft);
  background: rgba(255, 255, 255, 0.012);
}

.provider-tab {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 22px 18px;
  background: transparent;
  border: 0;
  border-right: 1px solid var(--border-soft);
  color: var(--mute);
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 500;
  cursor: pointer;
  transition: color 160ms ease, background 160ms ease;
  position: relative;
}
.provider-tab:last-child { border-right: 0; }
.provider-tab:hover { color: var(--paper-soft); background: rgba(255, 255, 255, 0.02); }
.provider-tab:focus-visible {
  outline: 2px solid var(--acid-glow);
  outline-offset: -2px;
}

.provider-tab--active {
  color: var(--paper);
  background: rgba(196, 169, 255, 0.06);
}
.provider-tab--active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--acid);
}

.provider-tab__logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  color: var(--mute);
  transition: color 160ms ease;
}
.provider-tab__logo svg {
  width: 100%;
  height: 100%;
}
.provider-tab--active .provider-tab__logo--openai    { color: #FFFFFF; }
.provider-tab--active .provider-tab__logo--anthropic { color: #D97757; }
.provider-tab--active .provider-tab__logo--gemini    { color: #8BB8FF; }

.provider-tab__name {
  letter-spacing: -0.01em;
}

.provider-panel {
  padding: 22px 22px 26px;
}

/* Alpine x-transition: enter classes for the panel as a whole. The
   surrounding <template x-if> un/remounts the panel each time `tab`
   changes — that's what restarts the per-card staggered fade-in. */
.provider-panel--enter {
  transition: opacity 240ms ease, transform 240ms ease;
}
.provider-panel--enter-start {
  opacity: 0;
  transform: translateY(6px);
}
.provider-panel--enter-end {
  opacity: 1;
  transform: translateY(0);
}

.model-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}

/* Each model card animates in with a small fade-up, and uses :nth-child
   to stagger so the rows arrive like a wave rather than all at once. */
.model-card {
  position: relative;
  padding: 14px 16px;
  border: 1px solid var(--border-soft);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.012);
  transition: transform 200ms ease, border-color 200ms ease, background 200ms ease;
  animation: model-card-in 360ms cubic-bezier(0.22, 1, 0.36, 1) both;
  will-change: transform, opacity;
}
.model-card:hover {
  transform: translateY(-2px);
  border-color: rgba(196, 169, 255, 0.32);
  background: rgba(196, 169, 255, 0.04);
}

.model-card__head {
  display: flex;
  align-items: center;
  gap: 10px;
}
.model-card__id {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--paper);
  letter-spacing: -0.005em;
}
.model-card__name {
  margin-top: 4px;
  font-family: var(--font-body);
  font-size: 12px;
  color: var(--mute);
  letter-spacing: -0.005em;
}

/* Tiny online dot in the top-right corner of every card — pulsing
   emerald, matches the live-feed pill / hero stat dot. Signals "this
   model is callable right now" without spelling it out. */
.model-card__online {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--emerald);
  box-shadow: 0 0 0 0 rgba(157, 213, 181, 0.55);
  animation: model-card-online-pulse 2.4s ease-out infinite;
}
@keyframes model-card-online-pulse {
  0%   { box-shadow: 0 0 0 0 rgba(157, 213, 181, 0.55); }
  70%  { box-shadow: 0 0 0 6px rgba(157, 213, 181, 0); }
  100% { box-shadow: 0 0 0 0 rgba(157, 213, 181, 0); }
}

@keyframes model-card-in {
  0% {
    opacity: 0;
    transform: translateY(10px) scale(0.985);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* Staggered delays — fixed schedule rather than var(--i) inline so the
   template stays clean. After the 10th card we cap the delay so larger
   model rosters don't trail in for an awkwardly long time. */
.model-card:nth-child(1)  { animation-delay:  20ms; }
.model-card:nth-child(2)  { animation-delay:  60ms; }
.model-card:nth-child(3)  { animation-delay: 100ms; }
.model-card:nth-child(4)  { animation-delay: 140ms; }
.model-card:nth-child(5)  { animation-delay: 180ms; }
.model-card:nth-child(6)  { animation-delay: 220ms; }
.model-card:nth-child(7)  { animation-delay: 260ms; }
.model-card:nth-child(8)  { animation-delay: 300ms; }
.model-card:nth-child(9)  { animation-delay: 340ms; }
.model-card:nth-child(n+10) { animation-delay: 380ms; }

/* Respect reduced-motion users — no slide, no stagger, just instant. */
@media (prefers-reduced-motion: reduce) {
  .model-card,
  .provider-panel--enter {
    animation: none !important;
    transition: none !important;
  }
  .model-card__online {
    animation: none;
  }
}

@media (max-width: 640px) {
  .provider-tab {
    padding: 16px 10px;
    font-size: 13px;
    gap: 8px;
  }
  .provider-tab__logo {
    width: 18px;
    height: 18px;
  }
  .provider-panel {
    padding: 16px 14px 20px;
  }
  .model-grid {
    grid-template-columns: 1fr;
    gap: 10px;
  }
}
