/* ============================================================================
   vibecode.moe — design system
   Aesthetic: late-night editorial cyber-zine
   Display: Unbounded (geometric) · Italic accent: Instrument Serif
   Body: Hanken Grotesk · Mono: JetBrains Mono
   Signature: acid lime against deep ink, grain + gradient mesh atmosphere
   ============================================================================ */

/* ── Unbounded — self-hosted display font ──────────────────────────────────
   Variable font, weights 200–900. Split into 4 subsets matching what
   Google Fonts serves so the browser only downloads ranges that match
   the actual page content (most users hit cyrillic-only or latin-only).
   Files live under static/fonts/. `font-display: swap` keeps text
   readable while the woff2 streams in — for a display font that only
   touches headings, the brief FOUT is the right tradeoff.

   No italic face exists for Unbounded — italic-tagged elements pick up
   `--font-display-italic` (Instrument Serif) instead so the browser
   doesn't synthesise an ugly oblique. */
@font-face {
  font-family: "Unbounded";
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url("/static/fonts/unbounded-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
                 U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F,
                 U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
                 U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Unbounded";
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url("/static/fonts/unbounded-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
                 U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF,
                 U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
                 U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Unbounded";
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url("/static/fonts/unbounded-cyrillic.woff2") format("woff2");
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Unbounded";
  font-style: normal;
  font-weight: 200 900;
  font-display: swap;
  src: url("/static/fonts/unbounded-cyrillic-ext.woff2") format("woff2");
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF,
                 U+A640-A69F, U+FE2E-FE2F;
}

:root {
  color-scheme: dark;

  /* ink + paper */
  --ink:         #08080c;
  --ink-soft:    #0c0c12;
  --surface-1:   #11111a;
  --surface-2:   #16161f;
  --surface-3:   #1c1c26;
  --border:      #25252e;
  --border-soft: #1a1a22;
  --border-hot:  #2e2e3a;

  /* text */
  --paper:       #ece9e0;
  --paper-soft:  #d4d1c7;
  --mute:        #8d8d97;
  --mute-soft:   #6a6a74;
  --faint:       #494951;

  /* accents */
  --acid:        #c8ff3d;
  --acid-dim:    #a8e030;
  --acid-glow:   rgba(200, 255, 61, 0.22);
  --magenta:     #ff3da6;
  --magenta-dim: #d62b87;
  --cyan:        #36e2f0;
  --amber:       #fcd34d;
  --rose:        #f87171;
  --emerald:     #34d399;

  /* type */
  --font-display:        "Unbounded", "Hanken Grotesk", system-ui, sans-serif;
  /* Italic-tagged display blocks (.brand__name, hero accents, …) — Unbounded
     ships no italic face so we keep Instrument Serif for that style only.
     Pulled in via the same Google Fonts <link> the project already loads. */
  /* Instrument Serif removed — theme.css unconditionally overrides this
     variable to Inter (sans-only). Keeping a serif fallback here for
     when theme.css is stripped during a future rollback. */
  --font-display-italic: "Times New Roman", Georgia, serif;
  --font-body:           "Hanken Grotesk", "Helvetica Neue", system-ui, -apple-system, sans-serif;
  --font-mono:           "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* effects */
  --grain-opacity: 0.06;
  --mesh-opacity:  0.55;
  --radius-sm:  6px;
  --radius:     10px;
  --radius-lg:  18px;
  --radius-xl:  26px;

  --ease-out:   cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
}

* { box-sizing: border-box; }

/* Reset the UA-default 8px body margin so the header (sticky top: 0)
   sits flush against the viewport top and the page background
   reaches both viewport edges. Operator saw faint dark strips above
   the header and along the right gutter; the right one was
   `scrollbar-gutter: stable` reserving phantom scrollbar space, the
   top one was the browser's default body margin. */
html, body { margin: 0; padding: 0; }

html body {
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-body);
  font-weight: 400;
  font-feature-settings: "ss01", "cv11", "tnum";
  letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  min-height: 100vh;
  position: relative;
  overflow-x: hidden;
  /* Sticky-footer scaffolding: pages with short content (e.g.
     /panel/invites with one card) used to create an extra ~80px of
     scroll because the footer's `margin-top: 80px` pushed it past
     `100vh`. Body becomes a vertical flex column, <main> takes the
     slack, and the footer's `margin-top: auto` pins it to the
     bottom when the page is short and falls back to a normal
     spacing when it's long. */
  display: flex;
  flex-direction: column;
}
main {
  flex: 1 0 auto;
}

/* Atmospheric background ──────────────────────────────────────────── */
body::before {
  /* gradient mesh blobs */
  content: "";
  position: fixed;
  inset: -20vh -20vw;
  background:
    radial-gradient(48vw 42vw at 15% 12%, rgba(200, 255, 61, 0.10) 0%, transparent 60%),
    radial-gradient(36vw 36vw at 85% 18%, rgba(255, 61, 166, 0.075) 0%, transparent 65%),
    radial-gradient(50vw 40vw at 70% 90%, rgba(54, 226, 240, 0.06) 0%, transparent 65%);
  filter: blur(40px) saturate(1.1);
  z-index: -2;
  opacity: var(--mesh-opacity);
  pointer-events: none;
  /* Animation removed — a large filter:blur fixed-position layer being
     transformed every frame forces Firefox to re-rasterise the blurred
     pixmap on each tick (Gecko keeps it on CPU/Skia rather than the
     compositor). theme.css already sets `animation: none !important`
     here, but defensive: if theme.css is ever stripped, the un-themed
     site still gets the cheap variant. */
  animation: none;
  /* Force the blurred backdrop onto its own GPU layer in Firefox.
     Without the hint Gecko re-rasterises the blur each time the
     foreground above it repaints (TerminalDemo characters, Alpine
     reactivity, scroll-driven sticky-header backdrop sampling).
     With the hint it stays as a cached texture, and subsequent
     paints just composite the texture — much cheaper. ~9 MB of
     extra GPU memory in exchange for stable 60 fps on jank-sensitive
     pages like the landing typewriter and the panel donut. */
  will-change: transform;
}
body::after {
  /* grain texture */
  content: "";
  position: fixed;
  inset: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='220' height='220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' seed='3'/><feColorMatrix values='0 0 0 0 0.96 0 0 0 0 0.94 0 0 0 0 0.88 0 0 0 0.7 0'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
  background-size: 220px 220px;
  opacity: var(--grain-opacity);
  mix-blend-mode: overlay;
  pointer-events: none;
  z-index: -1;
}

@keyframes drift {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg); }
  100% { transform: translate3d(-3%, 4%, 0) rotate(8deg); }
}

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

/* Scrollbar ──────────────────────────────────────────────────────── */
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--ink); }
::-webkit-scrollbar-thumb {
  background: var(--surface-3);
  border-radius: 8px;
  border: 2px solid var(--ink);
}
::-webkit-scrollbar-thumb:hover { background: var(--border-hot); }

/* Typography utilities ───────────────────────────────────────────── */
/* Display class: Unbounded is a geometric/condensed sans, so the
   default weight reads thicker than the old Instrument Serif at the
   same value — we drop one notch (400 → 500 only where titles needed
   the heavier presence) and tighten the tracking a hair. */
.font-display { font-family: var(--font-display); font-weight: 500; letter-spacing: -0.01em; }
/* No italic Unbounded face — italic variant keeps Instrument Serif so
   the browser doesn't synthesise an ugly oblique on the geometric
   shapes. The two faces sit side by side in some templates (numbered
   list "07" italic + "Section title" upright); the typographic
   contrast is intentional. */
.font-display-i { font-family: var(--font-display-italic); font-style: italic; font-weight: 400; letter-spacing: -0.025em; }
.font-mono, code, pre, kbd { font-family: var(--font-mono); }

.eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--mute);
}

.tnum { font-variant-numeric: tabular-nums; }

/* Section divider with mono label (editorial rule) ───────────────── */
.section-rule {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 18px;
  margin: 64px 0 36px;
  color: var(--mute);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
}
.section-rule::before,
.section-rule::after {
  content: "";
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--border-hot) 25%, var(--border-hot) 75%, transparent);
}
.section-rule__num {
  color: var(--acid);
}
.section-rule__title {
  color: var(--paper);
}

/* Buttons ────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 42px;
  padding: 0 18px;
  border-radius: var(--radius-sm);
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.2s var(--ease-out), background 0.2s, color 0.2s, border-color 0.2s, box-shadow 0.2s;
  text-decoration: none;
  white-space: nowrap;
}
.btn:active { transform: translateY(1px); }

.btn--primary {
  background: var(--acid);
  color: var(--ink);
  box-shadow: 0 0 0 0 var(--acid-glow), inset 0 -2px 0 0 rgba(0, 0, 0, 0.18);
}
.btn--primary:hover {
  background: var(--acid-dim);
  box-shadow: 0 0 0 6px var(--acid-glow), inset 0 -2px 0 0 rgba(0, 0, 0, 0.22);
}

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

.btn--magenta {
  background: var(--magenta);
  color: var(--ink);
}
.btn--magenta:hover { background: var(--magenta-dim); }

.btn--danger-link {
  color: var(--rose);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  background: transparent;
  border: none;
  cursor: pointer;
  padding: 0;
}
.btn--danger-link:hover { color: #fca5a5; text-decoration: underline; text-underline-offset: 3px; }

.btn--sm { height: 34px; padding: 0 12px; font-size: 12.5px; }

/* Pill / chip ────────────────────────────────────────────────────── */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 11px;
  border-radius: 999px;
  border: 1px solid var(--border-hot);
  background: rgba(255, 255, 255, 0.02);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper-soft);
}
.pill__dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--acid);
  box-shadow: 0 0 0 0 var(--acid-glow);
  animation: pulse 2s var(--ease-out) infinite;
}
.pill--magenta .pill__dot { background: var(--magenta); box-shadow: 0 0 0 0 rgba(255, 61, 166, 0.4); }
.pill--cyan    .pill__dot { background: var(--cyan); box-shadow: 0 0 0 0 rgba(54, 226, 240, 0.4); }

@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 var(--acid-glow); }
  70%  { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* Surfaces (cards) ───────────────────────────────────────────────── */
.card {
  position: relative;
  background: linear-gradient(180deg, var(--surface-1) 0%, var(--surface-2) 100%);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px 22px;
}

.card--hero {
  background:
    radial-gradient(70% 100% at 0% 0%, rgba(200, 255, 61, 0.10) 0%, transparent 70%),
    linear-gradient(160deg, var(--surface-2), var(--surface-1));
  border: 1px solid var(--border-hot);
}

.card--magenta {
  background:
    radial-gradient(80% 120% at 100% 0%, rgba(255, 61, 166, 0.15) 0%, transparent 60%),
    linear-gradient(160deg, var(--surface-2), var(--surface-1));
  border: 1px solid var(--border-hot);
}

.card--emerald {
  background:
    radial-gradient(120% 80% at 0% 0%, rgba(52, 211, 153, 0.16) 0%, transparent 60%),
    linear-gradient(160deg, var(--surface-2), var(--surface-1));
  border: 1px solid rgba(52, 211, 153, 0.35);
}

/* Hairline corner marks (give cards a "spec sheet" feel) ─────────── */
.card--marked::before,
.card--marked::after {
  content: "";
  position: absolute;
  width: 10px;
  height: 10px;
  border: 1px solid var(--acid);
  opacity: 0.6;
  pointer-events: none;
}
.card--marked::before { top: -1px; left: -1px; border-right: none; border-bottom: none; }
.card--marked::after  { bottom: -1px; right: -1px; border-left: none; border-top: none; }

/* Inputs ─────────────────────────────────────────────────────────── */
.field-label {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mute);
  margin-bottom: 8px;
}
.field-label::before {
  content: "";
  width: 14px;
  height: 1px;
  background: var(--border-hot);
}

.input {
  width: 100%;
  height: 44px;
  padding: 0 14px;
  background: rgba(255, 255, 255, 0.015);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--paper);
  font-family: var(--font-body);
  font-size: 14.5px;
  letter-spacing: -0.005em;
  transition: border-color 0.15s, box-shadow 0.2s, background 0.15s;
  outline: none;
}
.input::placeholder { color: var(--mute-soft); }
.input:hover { border-color: var(--border-hot); }
.input:focus {
  border-color: var(--acid);
  background: rgba(200, 255, 61, 0.025);
  box-shadow: 0 0 0 4px var(--acid-glow);
}
.input--mono { font-family: var(--font-mono); font-size: 13.5px; letter-spacing: 0; }

/* Tables ─────────────────────────────────────────────────────────── */
.data-table {
  width: 100%;
  font-size: 13.5px;
  border-collapse: separate;
  border-spacing: 0;
}
.data-table thead th {
  text-align: left;
  padding: 12px 18px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mute);
  background: rgba(255, 255, 255, 0.015);
  border-bottom: 1px solid var(--border);
}
.data-table tbody td {
  padding: 13px 18px;
  border-bottom: 1px solid var(--border-soft);
  vertical-align: middle;
}
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr {
  transition: background 0.18s var(--ease-out);
}
.data-table tbody tr:hover {
  background: rgba(200, 255, 61, 0.025);
}

.data-table__id {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--paper);
}
.data-table__meta { color: var(--mute); font-family: var(--font-mono); font-size: 12px; }

.data-wrap {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: linear-gradient(180deg, rgba(17,17,26,0.4), rgba(11,11,16,0.4));
  backdrop-filter: blur(6px);
}

/* Status colors ──────────────────────────────────────────────────── */
.status-paid    { color: var(--emerald); }
.status-pending { color: var(--amber); }
.status-failed  { color: var(--rose); }
.status-other   { color: var(--mute); }

/* Code blocks ───────────────────────────────────────────────────── */
pre.code-block {
  margin: 0;
  padding: 18px 20px;
  background: linear-gradient(180deg, rgba(7, 7, 11, 0.7), rgba(11, 11, 18, 0.65));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-variant-ligatures: none;
  font-feature-settings: "tnum", "calt" off;
  font-size: 12.5px;
  line-height: 1.65;
  color: var(--paper-soft);
  overflow-x: auto;
  /* Force the same glyph metrics across cards. The first card looked
     "softer" than the other two because the surrounding .reveal
     animation ended on `translateY(0)` — Chrome / Firefox left the
     element on a sub-pixel compositor layer, which switched font
     rasterisation from grayscale to LCD-stripe and shifted weight.
     Pin the smoothing mode + freeze the rendering hint so the three
     cards rasterise identically no matter which animation cell
     finished last. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: geometricPrecision;
  font-synthesis: none;
}
pre.code-block .tok-meta { color: var(--mute); }
pre.code-block .tok-key  { color: var(--cyan); }
pre.code-block .tok-str  { color: var(--acid); }
pre.code-block .tok-cmd  { color: var(--magenta); }
pre.code-block .tok-fn   { color: var(--amber); }

.code-card {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, var(--surface-1), var(--ink-soft));
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.code-card pre.code-block { flex: 1; scrollbar-width: none; }
.code-card pre.code-block::-webkit-scrollbar { display: none; }
.code-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 18px;
  border-bottom: 1px solid var(--border);
  background: rgba(255, 255, 255, 0.015);
}
.code-card__title {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mute);
}
.code-card__dots { display: inline-flex; gap: 6px; }
.code-card__dots span { width: 8px; height: 8px; border-radius: 50%; background: var(--surface-3); display: inline-block; }
.code-card__dots span:nth-child(1) { background: var(--rose); }
.code-card__dots span:nth-child(2) { background: var(--amber); }
.code-card__dots span:nth-child(3) { background: var(--acid); }

/* Logo wedge mark ───────────────────────────────────────────────── */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--paper);
}
.brand__mark {
  width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  background: var(--ink);
  border: 1px solid var(--border-hot);
  border-radius: 6px;
  position: relative;
}
.brand__mark svg,
.brand__mark img { width: 14px; height: 14px; object-fit: contain; display: block; }
.brand__name {
  font-family: var(--font-display-italic);
  font-style: italic;
  font-size: 22px;
  letter-spacing: -0.02em;
  line-height: 1;
}
.brand__name .dot { color: var(--acid); }
.brand__name .ext {
  font-family: var(--font-mono);
  font-style: normal;
  font-size: 12.5px;
  color: var(--mute);
  letter-spacing: 0.02em;
}

/* Header ────────────────────────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: rgba(8, 8, 12, 0.65);
  /* Frosted-glass header is expensive in Firefox: backdrop-filter has
     to re-sample the content beneath the sticky bar on every scroll
     frame, and that content already includes the body::before blur(70px)
     blob — Gecko ends up doing nested blur work per frame. Reduced
     from `saturate(160%) blur(14px)` to a plain `blur(6px)`, then bumped
     the bg alpha on the themed copy (theme.css) to keep the bar
     readable. Visually almost identical at a glance, but the per-frame
     compositor cost drops dramatically. */
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-bottom: 1px solid var(--border-soft);
}
.site-header__inner {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 28px;
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}
.nav { display: flex; align-items: center; gap: 2px; }
.nav__link {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 12px;
  font-size: 13.5px;
  color: var(--paper-soft);
  border-radius: 6px;
  text-decoration: none;
  letter-spacing: -0.005em;
  /* "Регистрация →" and "Перейти в панель" kept wrapping the trailing
     glyph onto its own line on the narrowest viewports — the link's
     inline-flex was hugging content but the parent .nav was sized to
     a fixed row height of 32 px, so the wrap squeezed below the row
     baseline. nowrap forces the link to outgrow its parent instead;
     the parent nav already scrolls / wraps for us. */
  white-space: nowrap;
  transition: background 0.18s, color 0.18s;
  /* Reset native <button> defaults so a <button class="nav__link"> looks
     identical to an <a class="nav__link">. Without this the Logout button
     keeps its UA-styled grey fill + 1px border. */
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  font: inherit;
  font-size: 13.5px;
  cursor: pointer;
  line-height: 1;
}
.nav__link:hover { background: rgba(255, 255, 255, 0.04); color: var(--paper); }
.nav__link--active { background: rgba(200, 255, 61, 0.07); color: var(--acid); }
.nav__link--cta {
  background: var(--acid);
  color: var(--ink);
  font-weight: 600;
  padding: 0 14px;
}
.nav__link--cta:hover { background: var(--acid-dim); color: var(--ink); }
.nav__sep { width: 1px; height: 18px; background: var(--border-hot); margin: 0 8px; }
.nav__user {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 10px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--mute);
  border-radius: 6px;
}

/* Footer ────────────────────────────────────────────────────────── */
.site-footer {
  margin-top: 96px;
  border-top: 1px solid var(--border-soft);
  padding: 36px 28px 60px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: var(--mute);
}
.site-footer__inner {
  max-width: 1180px;
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 24px;
  align-items: end;
}
.site-footer__cols {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 36px;
  max-width: 720px;
  margin-bottom: 18px;
}
.site-footer__heading {
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  margin-bottom: 10px;
}
.site-footer__list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.site-footer__list a { color: var(--mute); text-decoration: none; transition: color 0.15s; }
.site-footer__list a:hover { color: var(--acid); }

/* Marquee ticker ────────────────────────────────────────────────── */
.ticker {
  border-top: 1px solid var(--border-soft);
  border-bottom: 1px solid var(--border-soft);
  overflow: hidden;
  position: relative;
  background: var(--ink-soft);
}
.ticker__track {
  display: inline-flex;
  gap: 56px;
  padding: 11px 0;
  white-space: nowrap;
  animation: ticker 38s linear infinite;
  will-change: transform;
}
.ticker__item {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mute);
  display: inline-flex;
  align-items: center;
  gap: 18px;
}
.ticker__item .acc { color: var(--acid); }
.ticker__item::after {
  content: "✦";
  color: var(--magenta);
  margin-left: 18px;
  font-size: 10px;
}
@keyframes ticker {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

/* Hero ──────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  padding: 64px 0 28px;
}
.hero__top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-bottom: 36px;
}
.hero__num {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--mute);
}
.hero__title {
  font-family: var(--font-display);
  font-size: clamp(60px, 12vw, 168px);
  line-height: 0.88;
  letter-spacing: -0.04em;
  font-weight: 400;
  color: var(--paper);
  margin: 0;
}
.hero__title .it {
  font-style: italic;
  letter-spacing: -0.05em;
}
.hero__title .em {
  color: var(--acid);
  position: relative;
  display: inline-block;
}
.hero__title .em::after {
  content: "";
  position: absolute;
  left: -2%;
  right: -2%;
  bottom: 0.12em;
  height: 0.06em;
  background: var(--acid);
  opacity: 0.25;
  transform: skewX(-12deg);
}
.hero__lede {
  margin-top: 28px;
  max-width: 560px;
  font-size: 17px;
  line-height: 1.55;
  color: var(--paper-soft);
  letter-spacing: -0.005em;
}
.hero__cta {
  margin-top: 32px;
  display: inline-flex;
  flex-wrap: wrap;
  gap: 12px;
}

/* Hero stats strip (under headline) ─────────────────────────────── */
.hero__stats {
  margin-top: 56px;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.hero__stat {
  padding: 22px 24px;
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.hero__stat:last-child { border-right: none; }
.hero__stat-label {
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--mute);
}
.hero__stat-value {
  font-family: var(--font-display);
  font-size: 32px;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--paper);
}
.hero__stat-value .small {
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--mute);
  margin-left: 4px;
}

/* Privacy section pull-quote ───────────────────────────────────── */
.pullquote {
  position: relative;
  font-family: var(--font-display-italic);
  font-style: italic;
  font-size: clamp(28px, 4vw, 46px);
  line-height: 1.12;
  letter-spacing: -0.025em;
  color: var(--paper);
  max-width: 880px;
  padding-left: 28px;
  border-left: 2px solid var(--acid);
}
.pullquote .quotemark {
  position: absolute;
  left: 16px;
  top: -10px;
  font-size: 1.1em;
  color: var(--acid);
}

/* Feature chips ─────────────────────────────────────────────────── */
.chip-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 24px;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 13px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--border-hot);
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.08em;
  color: var(--paper-soft);
}
.chip svg { color: var(--acid); }

/* Numbered cards (privacy etc) ──────────────────────────────────── */
.numcard {
  position: relative;
  padding: 22px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg, var(--surface-1), rgba(11,11,18,0.6));
  overflow: hidden;
}
.numcard__no {
  position: absolute;
  top: 14px;
  right: 18px;
  font-family: var(--font-display-italic);
  font-style: italic;
  font-size: 36px;
  color: var(--faint);
  line-height: 1;
}
.numcard__title {
  font-family: var(--font-display);
  font-size: 22px;
  letter-spacing: -0.02em;
  color: var(--paper);
  margin: 0 0 8px;
}
.numcard__body {
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--paper-soft);
}

/* Tag (small label) ─────────────────────────────────────────────── */
.tag {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.tag--text { background: rgba(255,255,255,0.04); color: var(--paper-soft); border: 1px solid var(--border-hot); }
.tag--image { background: rgba(255, 61, 166, 0.12); color: var(--magenta); border: 1px solid rgba(255, 61, 166, 0.35); }
.tag--ok { background: rgba(52, 211, 153, 0.10); color: var(--emerald); border: 1px solid rgba(52, 211, 153, 0.32); }

/* Auth split layout ─────────────────────────────────────────────── */
.auth-grid {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: 48px;
  align-items: center;
  min-height: calc(100vh - 64px - 200px);
}
.auth-grid__aside {
  position: relative;
  padding-right: 24px;
}
.auth-grid__form {
  position: relative;
  padding: 36px 36px 32px;
  border: 1px solid var(--border);
  border-radius: var(--radius-xl);
  background: linear-gradient(165deg, rgba(255,255,255,0.025), rgba(255,255,255,0));
}
.auth-grid__title {
  font-family: var(--font-display);
  font-size: 56px;
  line-height: 0.95;
  letter-spacing: -0.035em;
  color: var(--paper);
  margin: 0;
}
.auth-grid__title .it { font-style: italic; color: var(--acid); }
.auth-grid__sub {
  margin-top: 18px;
  color: var(--paper-soft);
  font-size: 15.5px;
  line-height: 1.55;
  max-width: 460px;
}
.auth-grid__meta {
  margin-top: 32px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--mute);
  letter-spacing: 0.06em;
}
.auth-grid__meta .row { display: flex; gap: 14px; align-items: baseline; }
.auth-grid__meta .row .k { color: var(--mute-soft); min-width: 90px; }
.auth-grid__meta .row .v { color: var(--paper); }

@media (max-width: 880px) {
  .auth-grid { grid-template-columns: 1fr; gap: 28px; }
  .auth-grid__aside { padding-right: 0; }
}

/* ── Phone / WebView overrides ───────────────────────────────────
   The auth split layout used a fixed `font-size: 56px` for the
   heading and a chunky 36 px form padding — fine on a 1280-wide
   desktop, but it spills out of a Telegram WebView (≈360 px) and
   the heading literally clips off the right edge. Bring everything
   down to fluid sizing so /login, /register, /admin/2fa/setup
   AND the new /login/2fa all fit. */
@media (max-width: 560px) {
  .auth-grid {
    /* Removing min-height keeps short-content pages from leaving
       a giant empty middle band; the form card sets its own
       intrinsic size. */
    min-height: 0;
    gap: 20px;
  }
  .auth-grid__title {
    font-size: clamp(28px, 8.5vw, 42px);
    line-height: 1.04;
    letter-spacing: -0.02em;
    overflow-wrap: anywhere;
  }
  .auth-grid__sub {
    font-size: 14.5px;
    margin-top: 14px;
  }
  .auth-grid__form {
    padding: 22px 18px 22px;
  }
  .auth-grid__meta {
    margin-top: 22px;
    font-size: 11px;
  }
  .auth-grid__meta .row {
    flex-wrap: wrap;
    gap: 4px 12px;
  }
  .auth-grid__meta .row .k {
    min-width: 0;
    flex: 0 0 auto;
  }
}

/* Inline error ──────────────────────────────────────────────────── */
.alert-error {
  margin-top: 18px;
  padding: 12px 14px 12px 16px;
  border: 1px solid rgba(248, 113, 113, 0.35);
  border-left: 3px solid var(--rose);
  background: rgba(248, 113, 113, 0.08);
  border-radius: var(--radius-sm);
  color: #fecaca;
  font-size: 13.5px;
  display: flex;
  gap: 10px;
  align-items: flex-start;
}
.alert-error__link {
  color: inherit;
  font-weight: 600;
  text-decoration: underline;
  text-decoration-color: rgba(254, 202, 202, 0.5);
  text-underline-offset: 2px;
  transition: text-decoration-color 0.15s ease;
}
.alert-error__link:hover {
  text-decoration-color: #fecaca;
}
.alert-error::before {
  content: "!";
  display: inline-grid;
  place-items: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--rose);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  flex-shrink: 0;
  margin-top: 1px;
}

/* Inline success (admin saved-OK banner) ─────────────────────────── */
.alert-ok {
  margin-top: 18px;
  padding: 12px 14px 12px 16px;
  border: 1px solid rgba(110, 231, 183, 0.35);
  border-left: 3px solid var(--emerald);
  background: rgba(110, 231, 183, 0.08);
  border-radius: var(--radius-sm);
  color: #bbf7d0;
  font-size: 13.5px;
  display: flex;
  gap: 10px;
  align-items: flex-start;
}

/* Inline checkbox label used in admin forms ──────────────────────── */
.check {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--paper-soft);
  cursor: pointer;
  user-select: none;
}
.check input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--acid);
  margin: 0;
}

/* Page entrance reveal ──────────────────────────────────────────── */
.reveal { opacity: 0; transform: translateY(14px); animation: reveal 0.8s var(--ease-out) forwards; }
.reveal[data-d="0"] { animation-delay: 0.00s; }
.reveal[data-d="1"] { animation-delay: 0.08s; }
.reveal[data-d="2"] { animation-delay: 0.16s; }
.reveal[data-d="3"] { animation-delay: 0.24s; }
.reveal[data-d="4"] { animation-delay: 0.32s; }
.reveal[data-d="5"] { animation-delay: 0.40s; }
.reveal[data-d="6"] { animation-delay: 0.48s; }
.reveal[data-d="7"] { animation-delay: 0.56s; }

@keyframes reveal {
  /* `transform: none` (not translateY(0)) so the compositor releases
     the element back to the integer pixel grid after the animation.
     translateY(0) keeps the element on a sub-pixel layer, which made
     monospace cards render with slightly different font weight per
     card depending on which animation finished last. */
  to { opacity: 1; transform: none; }
}

/* Caret blink for code prompts ──────────────────────────────────── */
.caret {
  display: inline-block;
  width: 0.5em;
  height: 1em;
  vertical-align: -0.16em;
  background: var(--acid);
  margin-left: 2px;
  animation: blink 1.05s steps(1) infinite;
}
@keyframes blink {
  0%, 50%   { opacity: 1; }
  51%, 100% { opacity: 0; }
}

/* Provider radio group ──────────────────────────────────────────── */
.provider-card {
  position: relative;
  padding: 14px 14px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: rgba(255, 255, 255, 0.015);
  transition: border-color 0.15s, background 0.15s;
  cursor: pointer;
}
.peer:checked + .provider-card {
  border-color: var(--acid);
  background: rgba(200, 255, 61, 0.06);
  box-shadow: 0 0 0 1px var(--acid);
}
.provider-card[data-disabled="true"] { opacity: 0.35; cursor: not-allowed; }
.provider-card__name {
  font-weight: 600;
  letter-spacing: -0.005em;
  font-size: 14px;
}
.provider-card__meta {
  margin-top: 4px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--mute);
}

/* Big amount field ──────────────────────────────────────────────── */
.amount-row {
  display: flex;
  gap: 10px;
  align-items: stretch;
}
.amount-row .input { font-family: var(--font-mono); font-size: 18px; height: 50px; }
.amount-row .qbtn {
  height: 50px;
  padding: 0 14px;
  font-family: var(--font-mono);
  font-size: 13px;
  background: transparent;
  color: var(--paper-soft);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.amount-row .qbtn:hover { border-color: var(--acid); color: var(--acid); }

/* Cf-Turnstile spacing ─────────────────────────────────────────── */
.cf-turnstile { display: inline-block; }

/* HTMX swap transitions ────────────────────────────────────────── */
.htmx-swapping  { opacity: 0; transition: opacity 150ms ease-out; }
.htmx-settling  { opacity: 0; transition: opacity 220ms ease-in; }
.htmx-settling.htmx-settling-after { opacity: 1; }

/* Container helper used in templates ───────────────────────────── */
.shell {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 28px;
}

/* "Big number" stat cell for dashboard ─────────────────────────── */
.stat-big {
  font-family: var(--font-display);
  font-size: 52px;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--paper);
}
.stat-big .unit {
  font-family: var(--font-mono);
  font-size: 14px;
  color: var(--mute);
  margin-left: 8px;
  letter-spacing: 0.08em;
}

/* Inline ellipsis copy block ───────────────────────────────────── */
.copybox {
  display: flex;
  align-items: stretch;
  gap: 8px;
}
.copybox .text {
  flex: 1;
  padding: 12px 14px;
  background: var(--ink);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 12.5px;
  word-break: break-all;
  color: var(--paper);
}
.copybox .text--lg { font-size: 13.5px; padding: 14px 16px; }
.copybox .btn { height: auto; padding: 10px 14px; }

/* Inline pill within copy ──────────────────────────────────────── */
.kbd {
  display: inline-block;
  padding: 1px 7px;
  background: rgba(255,255,255,0.05);
  border: 1px solid var(--border-hot);
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--paper-soft);
}

/* Headings used inside main shell ──────────────────────────────── */
.page-h1 {
  font-family: var(--font-display);
  font-size: 56px;
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--paper);
  margin: 0 0 8px;
}
.page-h1 .it { font-style: italic; color: var(--acid); }
.page-sub {
  color: var(--paper-soft);
  font-size: 15px;
  letter-spacing: -0.005em;
  max-width: 640px;
}

.section-h2 {
  font-family: var(--font-display);
  font-size: 36px;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--paper);
  margin: 0 0 16px;
}
.section-h2 .it { font-style: italic; color: var(--acid); }

/* Empty states ─────────────────────────────────────────────────── */
.empty {
  text-align: center;
  padding: 56px 24px;
  color: var(--mute);
  font-size: 14px;
}
.empty .h {
  display: block;
  font-family: var(--font-display-italic);
  font-style: italic;
  font-size: 22px;
  color: var(--paper-soft);
  margin-bottom: 6px;
}
/* Modifier — give the empty state the same translucent-card chrome
   the populated tables next to it (.usage-panel, .tx-panel,
   .keys-list) use, so a fresh account doesn't see a stripe of bare
   italic text where a panel was supposed to be. NOT folded into
   .empty because the admin_users "No users found" case already sits
   inside .data-wrap and would end up with a double border. */
.empty--card {
  background: rgba(255, 255, 255, 0.012);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
}

/* Aside info column ────────────────────────────────────────────── */
.aside-info {
  display: grid;
  gap: 22px;
}
.aside-info__row {
  display: grid;
  grid-template-columns: 110px 1fr;
  gap: 12px;
  align-items: baseline;
  font-family: var(--font-mono);
  font-size: 12.5px;
}
.aside-info__row .k { color: var(--mute); letter-spacing: 0.1em; text-transform: uppercase; font-size: 10.5px; }
.aside-info__row .v { color: var(--paper); word-break: break-all; }

/* Responsive ──────────────────────────────────────────────────── */
@media (max-width: 880px) {
  .hero { padding-top: 36px; }
  .hero__stats { grid-template-columns: 1fr; }
  .hero__stat { border-bottom: 1px solid var(--border); border-right: none; }
  .hero__stat:last-child { border-bottom: none; }
  .site-footer__inner { grid-template-columns: 1fr; }
  .site-footer__cols { grid-template-columns: repeat(2, 1fr); gap: 24px; }
  .page-h1 { font-size: 40px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001s !important;
    transition-duration: 0.001s !important;
  }
}

/* ============================================================================
   Billing — plan grid + checkout
   ============================================================================ */

.plan-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px;
}
@media (max-width: 1100px) { .plan-grid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 820px)  { .plan-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px)  { .plan-grid { grid-template-columns: 1fr; } }

.plan-card {
  position: relative;
  background: linear-gradient(180deg, var(--surface-1), var(--surface-2));
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 18px 18px 16px;
  cursor: pointer;
  transition: border-color 0.18s, transform 0.18s var(--ease-out), box-shadow 0.18s;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.plan-card:hover {
  border-color: var(--border-hot);
  transform: translateY(-2px);
}
.plan-card--featured {
  border-color: var(--magenta-dim);
  box-shadow: 0 0 0 1px rgba(255, 61, 166, 0.18) inset;
}
.plan-card--featured::before {
  content: "popular";
  position: absolute;
  top: -9px;
  right: 14px;
  background: var(--magenta);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: 4px;
}
.plan-card--selected {
  border-color: var(--acid);
  box-shadow: 0 0 0 1px var(--acid-glow), 0 0 0 4px rgba(200, 255, 61, 0.07);
}
.plan-card__head {
  font-family: var(--font-display);
  font-size: 18px;
  line-height: 1.2;
  color: var(--paper);
  letter-spacing: -0.01em;
}
.plan-card__desc {
  font-size: 12px;
  line-height: 1.4;
  color: var(--mute);
  margin: 0;
}
.plan-card__pill {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(200, 255, 61, 0.12);
  border: 1px solid rgba(200, 255, 61, 0.35);
  color: var(--acid);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
}
.plan-card--featured .plan-card__pill {
  background: rgba(255, 61, 166, 0.10);
  border-color: rgba(255, 61, 166, 0.30);
  color: var(--magenta);
}
.plan-card__savings {
  display: inline-flex;
  align-items: center;
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(52, 211, 153, 0.10);
  border: 1px solid rgba(52, 211, 153, 0.35);
  color: var(--emerald);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  font-weight: 600;
}

/* Soft "premium" badge for token-heavy models (Opus/GPT-5.5/Gemini 3 Pro).
   Informational, not punitive — explains why these drain the balance faster. */
.tag--heavy {
  background: rgba(252, 211, 77, 0.10);
  color: var(--amber);
  border: 1px solid rgba(252, 211, 77, 0.30);
  cursor: help;
  margin-left: 4px;
}
.tag--heavy::before {
  content: "✦";
  margin-right: 4px;
  opacity: 0.8;
}
.plan-card__models {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}
.plan-card__model {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.02em;
  padding: 2px 6px;
  border-radius: 4px;
  background: var(--ink-soft);
  border: 1px solid var(--border-soft);
  color: var(--paper-soft);
}
.plan-card__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 10px;
  margin-top: auto;
  padding-top: 8px;
  border-top: 1px solid var(--border-soft);
}
.plan-card__price {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1;
  color: var(--paper);
  font-variant-numeric: tabular-nums;
}
.plan-card__usd {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--mute);
  margin-top: 2px;
}
.plan-card__cta {
  background: transparent;
  border: 1px solid var(--border-hot);
  color: var(--paper);
  border-radius: 6px;
  padding: 7px 11px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.plan-card__cta:hover {
  border-color: var(--acid);
  color: var(--acid);
  background: rgba(200, 255, 61, 0.05);
}
.plan-card--featured .plan-card__cta:hover {
  border-color: var(--magenta);
  color: var(--magenta);
  background: rgba(255, 61, 166, 0.05);
}

/* Checkout area ──────────────────────────────────────────────────── */

.checkout-grid {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 18px;
}
@media (max-width: 880px) { .checkout-grid { grid-template-columns: 1fr; } }

.provider-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
}
/* Top-up bonus pill. Three states driven by .topup-bonus--{tier}:
     none  → muted "no bonus" text
     low   → subtle ok
     good  → emerald
     great → acid
     best  → acid+glow
   Lets the form sell "+ bonus" without lying when the deposit is
   below the 100₽ threshold. */
.topup-bonus {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 14px;
  border: 1px solid var(--border-soft);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.02);
  font-family: var(--font-mono);
  font-size: 12.5px;
  transition: border-color 180ms ease, background 180ms ease, color 180ms ease;
}
.topup-bonus__label {
  color: var(--mute);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 10.5px;
}
.topup-bonus__value {
  font-weight: 700;
  color: var(--paper);
  font-size: 14px;
}
.topup-bonus__pct {
  font-weight: 500;
  color: var(--mute-soft);
  font-size: 11.5px;
  margin-left: 4px;
}
.topup-bonus__value--none {
  color: var(--mute-soft);
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.02em;
}
.topup-bonus--none {
  border-color: var(--border-soft);
}
.topup-bonus--low {
  border-color: rgba(157, 213, 181, 0.30);
  background: rgba(157, 213, 181, 0.05);
}
.topup-bonus--good {
  border-color: rgba(157, 213, 181, 0.45);
  background: rgba(157, 213, 181, 0.10);
}
.topup-bonus--good .topup-bonus__value { color: var(--emerald); }
.topup-bonus--great {
  border-color: rgba(200, 255, 61, 0.45);
  background: rgba(200, 255, 61, 0.06);
}
.topup-bonus--great .topup-bonus__value { color: var(--acid); }
.topup-bonus--best {
  border-color: rgba(200, 255, 61, 0.65);
  background: rgba(200, 255, 61, 0.10);
  box-shadow: 0 0 0 1px rgba(200, 255, 61, 0.20), 0 0 18px -4px rgba(200, 255, 61, 0.45);
}
.topup-bonus--best .topup-bonus__value { color: var(--acid); }

.topup-hint {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--mute);
  letter-spacing: 0.01em;
  text-align: center;
}

.topup-receipt {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-top: 14px;
  border-top: 1px solid var(--border-soft);
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--mute);
}
.topup-receipt strong { color: var(--paper); }
.topup-receipt__bonus { color: var(--acid); }

/* Visually hide an element while keeping it accessible to screen
   readers / form serialisation. Used by the radio <input> inside
   each .provider-pick so the picker shows ONLY the bordered card
   instead of a stock OS radio dot above it. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.provider-pick {
  cursor: pointer;
  display: block;
}
.provider-pick[data-disabled="true"] {
  opacity: 0.4;
  cursor: not-allowed;
}
.provider-pick__inner {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 14px;
  background: rgba(255, 255, 255, 0.015);
  transition: border-color 0.15s, background 0.15s;
}
.provider-pick:hover:not([data-disabled="true"]) .provider-pick__inner {
  border-color: var(--border-hot);
}
.provider-pick input:checked + .provider-pick__inner {
  border-color: var(--acid);
  background: rgba(200, 255, 61, 0.05);
}
.provider-pick__name {
  font-family: var(--font-body);
  font-size: 13.5px;
  color: var(--paper);
  font-weight: 500;
}
.provider-pick__meta {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--mute-soft);
  margin-top: 3px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.amount-row {
  position: relative;
  display: flex;
  align-items: center;
}
.amount-row .input--mono {
  font-family: var(--font-mono);
  font-size: 22px;
  height: 56px;
  font-variant-numeric: tabular-nums;
  padding-right: 40px;
}
.amount-row__suffix {
  position: absolute;
  right: 16px;
  font-family: var(--font-mono);
  font-size: 18px;
  color: var(--mute);
  pointer-events: none;
}

.amount-slider {
  width: 100%;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  height: 22px;
}
.amount-slider::-webkit-slider-runnable-track {
  height: 2px;
  background: var(--border-hot);
  border-radius: 2px;
}
.amount-slider::-moz-range-track {
  height: 2px;
  background: var(--border-hot);
  border-radius: 2px;
}
.amount-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--acid);
  border: 2px solid var(--ink);
  box-shadow: 0 0 0 1px var(--acid-dim), 0 0 14px var(--acid-glow);
  margin-top: -8px;
  cursor: pointer;
}
.amount-slider::-moz-range-thumb {
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--acid);
  border: 2px solid var(--ink);
  cursor: pointer;
}

.quick-amounts {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}
.qbtn {
  height: 32px;
  padding: 0 12px;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--paper-soft);
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.qbtn:hover {
  border-color: var(--acid);
  color: var(--acid);
  background: rgba(200, 255, 61, 0.04);
}

.summary-card {
  background:
    radial-gradient(140% 90% at 100% 0%, rgba(54, 226, 240, 0.08) 0%, transparent 65%),
    linear-gradient(160deg, var(--surface-2), var(--surface-1));
  border: 1px solid var(--border-hot);
}
.summary-card--custom {
  background:
    radial-gradient(140% 90% at 100% 0%, rgba(200, 255, 61, 0.10) 0%, transparent 65%),
    linear-gradient(160deg, var(--surface-2), var(--surface-1));
}
.summary-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 11px 0;
  border-top: 1px dashed var(--border-soft);
}
.summary-row:first-of-type { margin-top: 22px; }
.summary-row__k {
  font-family: var(--font-mono);
  font-size: 11.5px;
  letter-spacing: 0.04em;
  color: var(--mute);
  text-transform: uppercase;
}
.summary-row__v {
  font-family: var(--font-display);
  font-size: 22px;
  color: var(--paper);
}

/* Language switcher inside <nav> ─────────────────────────────────── */
.lang-switch {
  display: inline-flex;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  margin-left: 8px;
}
.lang-switch__btn {
  padding: 4px 9px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: transparent;
  border: none;
  color: var(--mute);
  cursor: pointer;
  text-decoration: none;
}
.lang-switch__btn--active {
  background: var(--acid);
  color: var(--ink);
}
.lang-switch__btn:not(.lang-switch__btn--active):hover {
  color: var(--paper);
  background: rgba(255, 255, 255, 0.04);
}

/* ── Minimal Tailwind-style utilities (replace Tailwind Play CDN) ───
   Only the classes actually used in templates: grid, gap-{4,5,6},
   md:grid-cols-2, lg:grid-cols-{3,4}, h-4/w-4 for inline SVG icons.
   Anything beyond this should either go here too or be expressed
   via custom CSS classes. */
.grid { display: grid; }
.gap-4 { gap: 16px; }
.gap-5 { gap: 20px; }
.gap-6 { gap: 24px; }
.h-4 { height: 16px; }
.w-4 { width: 16px; }
@media (min-width: 768px) {
  .md\:grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .lg\:grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .lg\:grid-cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

