/* ============================================================
   Globconnects design system
   Token model is decoupled so light/dark both look intentional:
   - brand FILLS (saturated, on-brand text stays white)
   - brand TEXT/icons on surfaces  → --brand-text (theme-aware)
   - neutral text  → --heading / --ink / --muted
   - surfaces      → --bg / --surface / --surface-2 / --surface-3 / --line
   Legacy tokens (--brand-ink/-soft/-softer/--card) are aliased so
   every existing selector keeps working.
   ============================================================ */
:root {
  color-scheme: light;

  /* brand fills — saturated, stable across themes */
  --brand: #0d9488;
  --brand-600: #0f766e;   /* hover fill */
  --brand-700: #115e59;   /* deep gradient end */
  --brand-800: #134e4a;
  --accent: #14b8a6;
  --on-brand: #ffffff;    /* text/icons on brand fills */

  /* brand as text/icon on surfaces (theme-aware) */
  --brand-text: #0f766e;

  /* neutral text */
  --heading: #0d2f2b;
  --ink: #15302d;
  --muted: #61807b;

  /* surfaces */
  --bg: #f2fbfa;
  --surface: #ffffff;
  --surface-2: #f1faf8;
  --surface-3: #e0f4f1;
  --line: #dbefec;
  --line-strong: #c4e6e1;

  /* legacy aliases (keep older rules working) */
  --brand-ink: var(--heading);
  --brand-soft: var(--surface-3);
  --brand-softer: var(--surface-2);
  --card: var(--surface);

  /* semantic */
  --ok: #16a34a;   --ok-soft: #e7f7ec;
  --warn: #d97706; --warn-soft: #fdf1e0;
  --err: #dc2626;  --err-soft: #fdeaea;

  /* code blocks — always dark */
  --code-bg: #0b2e2a;
  --code-ink: #dff3ef;

  /* geometry & elevation */
  --radius: 18px;
  --radius-sm: 12px;
  --radius-lg: 24px;
  --shadow-sm: 0 4px 16px rgba(17, 94, 89, .07);
  --shadow: 0 16px 40px rgba(17, 94, 89, .10);
  --shadow-lg: 0 30px 70px rgba(17, 94, 89, .16);
  --ring: 0 0 0 4px rgba(20, 184, 166, .18);

  /*
   * The system font stack. No downloaded typeface anywhere in the product.
   *
   * This is the face that used to appear for the instant before Outfit arrived,
   * and it is now the only one. The upside is not only taste: system text paints
   * on the very first frame, so there is no flash and no reflow when a webfont
   * lands, nothing is fetched from Google on any page load, and there is no
   * third-party request carrying the visitor's IP.
   *
   * The trade, stated plainly: this is not one typeface everywhere. Windows gets
   * Segoe UI, macOS and iOS get San Francisco, Android gets Roboto. The site
   * will look native on each rather than identical across all.
   *
   * "Twemoji Country Flags" must come FIRST: Windows ships no country-flag
   * glyphs at all (Segoe UI Emoji omits regional-indicator sequences), so
   * 🇳🇬 renders as the letters "NG". Its unicode-range is flags-only, so it
   * changes no other character, and it is served from our own /assets.
   */
  --font: "Twemoji Country Flags", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
}

@font-face {
  font-family: "Twemoji Country Flags";
  src: url("/assets/fonts/TwemojiCountryFlags.woff2") format("woff2");
  unicode-range: U+1F1E6-1F1FF, U+1F3F4, U+E0062-E007F;
  font-display: swap;
}

[data-theme="dark"] {
  color-scheme: dark;

  /* Fills stay mid-teal, not the bright #2dd4bf: --on-brand is white, and white
     on a 400-level teal falls under 2:1. #0f9c8e keeps button labels readable
     while still reading as "brighter than light mode". */
  --brand: #0f9c8e;
  --brand-600: #14b8a6;   /* hover fill — lighter on dark */
  --brand-700: #0d9488;   /* gradient still rich */
  --brand-800: #0f766e;
  --accent: #2dd4bf;
  --on-brand: #ffffff;

  --brand-text: #5eead4;

  --heading: #e9faf7;
  --ink: #dcf1ed;
  --muted: #90b0ab;

  --bg: #0a1a18;
  --surface: #102826;
  --surface-2: #163331;
  --surface-3: #1d423f;
  --line: #22403d;
  --line-strong: #2e5551;

  --ok: #34d399;   --ok-soft: #0f2e24;
  --warn: #fbbf24; --warn-soft: #33270f;
  --err: #f87171;  --err-soft: #3a1a1e;

  /* Lifted above --bg (#0a1a18): if a code block sits at or below the page
     colour it reads as a hole rather than a raised block. */
  --code-bg: #16332f;
  --code-ink: #dff3ef;

  --shadow-sm: 0 4px 16px rgba(0, 0, 0, .34);
  --shadow: 0 16px 40px rgba(0, 0, 0, .46);
  --shadow-lg: 0 30px 70px rgba(0, 0, 0, .56);
  --ring: 0 0 0 4px rgba(45, 212, 191, .30);
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  font-family: var(--font);
  color: var(--ink);
  background: var(--bg);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  transition: background-color .25s ease, color .25s ease;
}

a { color: var(--brand-text); text-decoration: none; transition: color .12s ease; }
a:hover { color: var(--brand); }

h1, h2, h3, h4 { margin: 0 0 .4em; line-height: 1.15; color: var(--heading); letter-spacing: -.01em; }
h1 { font-size: clamp(28px, 4vw, 40px); font-weight: 800; letter-spacing: -.02em; }
p { margin: 0 0 1em; color: var(--muted); }
small { color: var(--muted); }

/*
 * Page shell. This was a flat min(1140px, 92vw), so every page was pixel-
 * identical from 1366 to 2560 — at 1920 that is 390px of dead gutter each side
 * and the API docs rendered their code samples at 784px on a screen with room
 * for 1100. It now steps up on large displays, matching --lp-w on the landing
 * page so the two never disagree at a given width.
 *
 * Prose is protected where it is written (the docs body caps its own measure),
 * so the extra width goes to tables, code and side-by-side panels — the things
 * that were actually cramped — not to unreadable 140-character lines.
 */
.container { width: min(1280px, 92vw); margin-inline: auto; }
@media (min-width: 1600px) { .container { width: min(1400px, 90vw); } }
@media (min-width: 1920px) { .container { width: min(1520px, 88vw); } }

/*
 * The `hidden` attribute must actually hide.
 *
 * The UA stylesheet gives [hidden] { display: none }, but that is a zero-
 * specificity rule any class beats — so `.btn`, `.field` and `.panel`, which all
 * set display, silently defeated it. A <label class="field" hidden> stayed on
 * screen. Every toggle in the app leans on this attribute (bulk bars, the bell
 * panel, code-language tabs, the PEP field, the profile edit form), so it is
 * fixed once, here, rather than per component.
 */
[hidden] { display: none !important; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: 1px solid transparent; border-radius: 999px; cursor: pointer;
  font: inherit; font-weight: 700; padding: 12px 22px; min-height: 46px;
  transition: transform .14s ease, box-shadow .14s ease, background .14s ease, border-color .14s ease, color .14s ease;
  background: var(--brand); color: var(--on-brand); box-shadow: var(--shadow-sm);
}
.btn:hover { transform: translateY(-1px); background: var(--brand-600); box-shadow: var(--shadow); }
.btn:active { transform: translateY(0); box-shadow: var(--shadow-sm); }
.btn:focus-visible { outline: none; box-shadow: var(--ring); }
.btn.ghost { background: var(--surface); color: var(--heading); border-color: var(--line); box-shadow: none; }
.btn.ghost:hover { border-color: var(--brand); background: var(--surface-2); color: var(--brand-text); box-shadow: var(--shadow-sm); }
/* A ghost button acting as an on/off toggle reads as "on" when tinted. */
.btn.ghost.active { border-color: var(--brand); background: var(--surface-2); color: var(--brand-text); }
.btn.dark { background: var(--code-bg); color: #fff; }
.btn.block { width: 100%; }
.btn.sm { min-height: 34px; padding: 7px 14px; font-size: 13px; }
.btn.danger { background: var(--surface); color: var(--err); border-color: var(--err-soft); box-shadow: none; }
.btn.danger:hover { background: var(--err-soft); border-color: var(--err); color: var(--err); }
.btn[disabled] { opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; }

/* ---------- Cards / panels ---------- */
.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-sm); padding: 22px;
}
.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm); padding: 24px; }
.panel + .panel { margin-top: 20px; }
/*
 * …but only when they are STACKED. Inside a grid the container's gap already
 * does the spacing, and this margin lands on top of it — dropping every panel
 * after the first 20px below its own row, so a two-up pair sits visibly
 * stepped rather than level.
 */
.cols-2 > .panel + .panel, .cols-3 > .panel + .panel, .cols-4 > .panel + .panel,
.cols-5 > .panel + .panel, .cols-sidebar > .panel + .panel,
.sec-grid > .panel + .panel { margin-top: 0; }

/* ---------- Forms ---------- */
.field { display: block; margin-bottom: 16px; }
.field > span { display: block; font-size: 13px; font-weight: 700; color: var(--muted); margin-bottom: 6px; }
.field input, .field select, .field textarea,
input.field, select.field, textarea.field {
  width: 100%; min-height: 44px; padding: 0 14px; font: inherit; color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); outline: none;
  transition: border-color .14s ease, box-shadow .14s ease, background .14s ease;
}
.field textarea, textarea.field { padding: 12px 14px; min-height: 90px; resize: vertical; }
.field input::placeholder, input.field::placeholder, textarea::placeholder { color: color-mix(in srgb, var(--muted) 75%, transparent); }
.field input:focus, .field select:focus, .field textarea:focus,
input.field:focus, select.field:focus, textarea.field:focus {
  border-color: var(--brand); background: var(--surface); box-shadow: var(--ring);
}
/*
 * File inputs.
 *
 * The base .field rule gives the box its border and radius, but the control
 * INSIDE it is drawn by the OS — a grey "Choose File" button and "No file
 * chosen" in the browser's own font, sitting unaligned against the app's
 * rounded fields. ::file-selector-button is the only handle on it.
 *
 * Dashed border because this is a drop target rather than something you type
 * into — it reads as "put a file here" at a glance.
 */
/* Matched on the ELEMENT, not on a .field wrapper: the corporate-document
   slots in the KYC wizard are bare inputs with no wrapper, and a
   wrapper-scoped rule left them looking like raw OS controls. */
input[type="file"] {
  display: flex; align-items: center; gap: 12px;
  width: 100%; min-height: 46px; margin: 0;
  padding: 6px 12px 6px 6px;
  font: inherit; font-size: 13.5px; color: var(--muted); cursor: pointer;
  border: 1px dashed var(--line-strong); border-radius: var(--radius-sm);
  background: var(--surface-2); outline: none;
  transition: border-color .14s ease, background .14s ease, color .14s ease;
}
input[type="file"]:hover {
  border-color: var(--brand); background: var(--surface-3); color: var(--ink);
}
input[type="file"]:focus-visible { border-color: var(--brand); box-shadow: var(--ring); }
input[type="file"]::file-selector-button {
  flex: 0 0 auto; margin: 0;
  padding: 8px 18px; border-radius: 999px;
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--brand-text);
  font: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
  transition: background .14s ease, color .14s ease, border-color .14s ease;
}
input[type="file"]::file-selector-button:hover {
  background: var(--brand); color: var(--on-brand); border-color: var(--brand);
}
/* Separate block, not merged above: an unsupported pseudo-element would
   invalidate the whole selector list and drop the styling entirely. */
input[type="file"]::-webkit-file-upload-button {
  flex: 0 0 auto; margin: 0;
  padding: 8px 18px; border-radius: 999px;
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--brand-text);
  font: inherit; font-size: 13px; font-weight: 700; cursor: pointer;
}

/* Make dropdowns obviously selectable with a chevron. */
.field select, select.field {
  appearance: none; -webkit-appearance: none; cursor: pointer; padding-right: 36px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b6580' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center;
}

/* View/Edit rows: read-only until "Edit" is clicked. */
.edit-row .v-edit { display: none; }
.edit-row.editing .v-view { display: none; }
.edit-row.editing input.v-edit, .edit-row.editing select.v-edit { display: block; }
.edit-row.editing label.v-edit { display: inline-flex; }
.edit-row.editing button.v-edit, .edit-row.editing a.v-edit { display: inline-flex; }
.row-actions { display: flex; gap: 6px; align-items: center; }
/* Keep the actions column visible while an edit table scrolls sideways. */
table.data:has(.edit-row) th:last-child { position: sticky; right: 0; background: var(--surface-2); z-index: 2; }
table.data:has(.edit-row) td:last-child { position: sticky; right: 0; background: var(--surface); box-shadow: -8px 0 12px -10px rgba(0, 0, 0, .25); }
.cell-val { font-weight: 600; color: var(--ink); }
.cell-sub { color: var(--muted); font-size: 12px; }
.field .err { color: var(--err); font-size: 12px; min-height: 14px; display: block; margin-top: 4px; }
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; }
.chips { display: grid; grid-template-columns: repeat(auto-fit, minmax(64px, 1fr)); gap: 8px; margin-bottom: 16px; }
.chips button { border: 1px solid var(--line); background: var(--surface); border-radius: var(--radius-sm); min-height: 42px; font: inherit; font-weight: 700; color: var(--heading); cursor: pointer; transition: border-color .14s ease, background .14s ease, color .14s ease; }
.chips button:hover { border-color: var(--brand); color: var(--brand-text); background: var(--surface-2); }

/* ---------- Admin Table Enhancements (Drag & Drop, Search, Bulk Actions) ---------- */
.drag-handle { cursor: grab; color: var(--muted); opacity: 0.5; padding: 4px 6px; display: inline-flex; align-items: center; user-select: none; }
.drag-handle:hover { opacity: 1; color: var(--brand-text); }
.edit-row.dragging { opacity: 0.35; background: var(--surface-3) !important; }
.edit-row.drag-over { outline: 2px dashed var(--brand); outline-offset: -2px; }

.table-search { display: flex; align-items: center; gap: 8px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 0 12px; height: 38px; }
.table-search input { border: 0; background: transparent; font: inherit; font-size: 13.5px; color: var(--ink); outline: none; width: 180px; }
.table-search input::placeholder { color: var(--muted); opacity: 0.7; }
/* type="search" brings a native clear button; tone it into the theme. */
.table-search input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; width: 14px; height: 14px; cursor: pointer; opacity: .45;
  background: no-repeat center / 12px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b6580' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M6 6l12 12M18 6 6 18'/%3E%3C/svg%3E"); }
.table-search input[type="search"]::-webkit-search-cancel-button:hover { opacity: .9; }

.bulk-bar { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; background: var(--surface-3); border: 1px solid var(--line); border-radius: var(--radius); padding: 10px 16px; margin-bottom: 14px; box-shadow: var(--shadow-sm); animation: fadeIn .14s ease-out; }
.bulk-bar .bulk-count { font-weight: 700; color: var(--heading); font-size: 13.5px; }
.bulk-bar .bulk-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-left: auto; }
.bulk-bar input.field, .bulk-bar select.field { min-height: 34px; padding: 0 10px; font-size: 13px; height: 34px; width: auto; }
/* The `display: flex` above beats the browser's own `[hidden] { display:none }`,
   so without this the bar stays on screen with nothing selected. */
.bulk-bar[hidden] { display: none; }
/* Every control on one baseline: the select carries a bottom margin from
   `.field` and the buttons are pill-shaped, so they drifted out of line. */
.bulk-bar .btn.sm, .bulk-bar select.field, .bulk-bar input.field { height: 34px; min-height: 34px; margin: 0; align-self: center; }
.bulk-bar select.field { border-radius: 999px; background-position: right 10px center; padding-right: 30px; }


/* ---------- Auth shell ---------- */
.auth { min-height: 100vh; display: grid; place-items: center; padding: 28px 16px;
  background: radial-gradient(1200px 500px at 100% -10%, var(--surface-3), transparent), var(--bg); }
.auth-card { width: min(440px, 100%); }
.auth-card .brand { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 18px; font-weight: 800; color: var(--heading); }

/* ---------- Marketing / landing ---------- */
.nav { display: flex; align-items: center; justify-content: space-between; padding: 20px 0; }
.nav .brand { display: flex; align-items: center; gap: 10px; font-weight: 800; color: var(--heading); font-size: 20px; }
.nav .links { display: flex; align-items: center; gap: 22px; }
.nav .links a { color: var(--heading); font-weight: 600; }
.nav .links a:hover { color: var(--brand-text); }
.brand { display: inline-flex; align-items: center; gap: 10px; font-weight: 800; color: var(--heading); flex-shrink: 0; text-decoration: none; }
.brand-mark { width: 38px; height: 38px; border-radius: 0; display: inline-grid; place-items: center;
  background: none !important; background-color: transparent !important; box-shadow: none !important; border: none !important; flex-shrink: 0; padding: 0; }
.brand-mark img, img.brand-img { width: 100%; height: 100%; object-fit: contain; display: block; background: none !important; background-color: transparent !important; box-shadow: none !important; border: none !important; filter: none !important; }
.brand-logo-img { height: 38px; width: auto; max-width: 220px; object-fit: contain; display: block; flex-shrink: 0; background: none !important; background-color: transparent !important; box-shadow: none !important; border: none !important; filter: none !important; }
.topbar-mobile-brand { display: none !important; align-items: center; flex-shrink: 0; }
.topbar-mobile-brand .brand-logo-img { height: 28px; max-width: 140px; }
@media (max-width: 900px) {
  .shell .sidebar:not(.sidebar-admin) ~ .main .topbar .topbar-mobile-brand,
  .topbar-mobile-brand { display: inline-flex !important; }
  .tb-greet { display: none; }
}
@media (min-width: 901px) {
  .topbar-mobile-brand { display: none !important; }
}
.site-foot .brand { display: inline-flex; align-items: center; margin-bottom: 12px; }
.site-foot .brand-logo-img { height: 36px; max-width: 180px; }
.hero { display: grid; grid-template-columns: 1.05fr .95fr; gap: 40px; align-items: center; padding: 40px 0 60px; }
/* Reusable, not hero-only: the developer docs had hand-copied these as inline
   styles, which is why that page drifted from the landing page's look. */
.eyebrow { display: inline-block; background: var(--surface-3); color: var(--brand-text); font-weight: 700; font-size: 13px; padding: 8px 16px; border-radius: 999px; margin-bottom: 18px; }
.accent { color: var(--brand); }
.hero h1 { font-size: clamp(38px, 6vw, 66px); }
.hero-card { background: var(--surface); border: 1px solid var(--line); border-radius: 26px; box-shadow: var(--shadow); padding: 26px; }
.service-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin-top: 30px; }
.service-tiles .tile { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; box-shadow: var(--shadow-sm); transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease; }
.service-tiles .tile:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--line-strong); }
.service-tiles .tile b { color: var(--heading); }
.feature-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; margin: 20px 0 60px; }

/* ---------- App shell (dashboard/admin) ---------- */
.shell { display: grid; grid-template-columns: 260px 1fr; min-height: 100vh; }
.sidebar { background: var(--surface); border-right: 1px solid var(--line); padding: 20px 14px; position: sticky; top: 0; height: 100vh; overflow-y: auto; display: flex; flex-direction: column; }
.sidebar .brand { display: flex; align-items: center; gap: 9px; font-weight: 800; color: var(--heading); padding: 4px 8px 16px; margin-bottom: 4px; border-bottom: 1px solid var(--line); flex: 0 0 auto; }
.sidebar .brand-name { font-size: 18px; }
.sidebar .brand-tag { margin-left: auto; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .08em; color: var(--brand-text); background: rgba(13, 148, 136, .12); padding: 3px 8px; border-radius: 999px; }
.sidebar nav { display: flex; flex-direction: column; gap: 4px; flex: 1 0 auto; padding-top: 8px; }
.sidebar .nav-label { font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); font-weight: 700; margin: 16px 14px 4px; opacity: .75; }
.sidebar .nav-label:first-child { margin-top: 2px; }
.sidebar nav a, .sidebar nav button {
  display: flex; align-items: center; gap: 13px; padding: 11px 14px; border-radius: 12px; color: var(--ink);
  font-weight: 500; font-size: 14.5px; letter-spacing: -.01em; border: 0; background: transparent; cursor: pointer; font-family: inherit; text-align: left; width: 100%;
  transition: background .14s ease, color .14s ease;
}
.sidebar nav a:hover, .sidebar nav button:hover { background: var(--surface-2); color: var(--brand-text); }
.sidebar nav a.active { background: var(--brand); color: var(--on-brand); font-weight: 600; box-shadow: 0 6px 16px rgba(13, 148, 136, .28); }
/* Solid behind the links. The old `transparent -> surface over 20px` gradient
   let nav items scrolled underneath show through the pinned footer, so on a
   short window "Back to app" appeared to sit on top of "Customers". */
.sidebar .nav-bottom { position: sticky; bottom: 0; margin-top: auto; display: flex; flex-direction: column; gap: 4px; padding-top: 14px; border-top: 1px solid var(--line); background: var(--surface); }
/* Keep the soft fade, but above the footer where nothing is clickable. */
.sidebar .nav-bottom::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 20px; background: linear-gradient(to bottom, transparent, var(--surface)); pointer-events: none; }
.sidebar nav a .icon, .sidebar nav button .icon { flex: none; }
.main { min-width: 0; }
.topbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 16px 28px; background: color-mix(in srgb, var(--surface) 88%, transparent); backdrop-filter: saturate(1.4) blur(8px); border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 5; }
.topbar .search { flex: 1; max-width: 420px; }
.topbar .search input { width: 100%; min-height: 42px; border: 1px solid var(--line); border-radius: 999px; padding: 0 16px; background: var(--surface-2); color: var(--ink); }
.profile { display: flex; align-items: center; gap: 10px; font-weight: 700; color: var(--heading); }
.avatar { width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center; color: #fff; font-weight: 800; background: linear-gradient(135deg, var(--brand), var(--accent)); background-size: cover; background-position: center; flex: 0 0 auto; }
.profile-link { display: inline-flex; align-items: center; gap: 10px; color: inherit; }
.profile-link:hover { color: var(--brand-text); }

/* Theme toggle (topbar) */
.icon-toggle { border: 1px solid var(--line); background: var(--surface); border-radius: 12px; width: 42px; height: 42px; display: grid; place-items: center; color: var(--heading); cursor: pointer; transition: border-color .14s ease, background .14s ease, color .14s ease; }
.icon-toggle:hover { border-color: var(--brand); background: var(--surface-2); color: var(--brand-text); }
.icon-toggle .ic-sun { display: none; }
.icon-toggle .ic-moon { display: inline-flex; }
[data-theme="dark"] .icon-toggle .ic-sun { display: inline-flex; }
[data-theme="dark"] .icon-toggle .ic-moon { display: none; }

/* ---------- Notification bell ---------- */
.bell-wrap { position: relative; }
.bell-btn { position: relative; border: 1px solid var(--line); background: var(--surface); border-radius: 12px; width: 42px; height: 42px; display: grid; place-items: center; color: var(--heading); cursor: pointer; transition: border-color .14s ease, background .14s ease, color .14s ease; }
.bell-btn:hover { border-color: var(--brand); background: var(--surface-2); color: var(--brand-text); }
.bell-dot { position: absolute; top: 8px; right: 9px; width: 9px; height: 9px; border-radius: 50%; background: var(--err); border: 2px solid var(--surface); }

.bell-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.38); backdrop-filter: blur(2px); z-index: 1040; display: block; }
.bell-backdrop[hidden] { display: none !important; }
@media (min-width: 641px) {
  .bell-backdrop { display: none !important; }
}

.bell-panel {
  position: absolute;
  top: 52px;
  right: -40px;
  width: 360px;
  max-width: calc(100vw - 24px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.16), 0 4px 12px rgba(0, 0, 0, 0.08);
  z-index: 1050;
  overflow: hidden;
  animation: bellFadeIn .18s cubic-bezier(0.16, 1, 0.3, 1);
}

@keyframes bellFadeIn {
  from { opacity: 0; transform: translateY(-6px) scale(0.98); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

@media (max-width: 640px) {
  .bell-panel {
    position: fixed;
    top: 66px;
    left: 12px;
    right: 12px;
    width: auto;
    max-width: none;
    max-height: calc(100vh - 100px);
    border-radius: 18px;
    box-shadow: 0 20px 48px rgba(0, 0, 0, 0.28), 0 0 0 1px rgba(0, 0, 0, 0.08);
    z-index: 1050;
  }
}

.bell-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 13px 18px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--line);
}
.bell-head strong { font-size: 14.5px; font-weight: 700; color: var(--heading); }
.bell-clear {
  border: 0;
  background: color-mix(in srgb, var(--brand) 12%, transparent);
  color: var(--brand-text);
  font-weight: 700;
  font-size: 12.5px;
  padding: 4px 10px;
  border-radius: 999px;
  cursor: pointer;
  transition: all .14s ease;
}
.bell-clear:hover { background: color-mix(in srgb, var(--brand) 22%, transparent); }

.bell-list {
  max-height: 380px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}
@media (max-width: 640px) {
  .bell-list { max-height: calc(100vh - 180px); }
}

.bell-list a { display: block; color: inherit; text-decoration: none; }
.bell-item {
  position: relative;
  padding: 13px 18px;
  border-bottom: 1px solid var(--line);
  transition: background .14s ease;
}
.bell-list a:hover .bell-item, .bell-item:hover { background: var(--surface-2); }
.bell-item.unread {
  background: color-mix(in srgb, var(--brand) 6%, var(--surface));
  border-left: 3.5px solid var(--brand);
}
.bell-t {
  font-weight: 700;
  font-size: 13.5px;
  color: var(--heading);
  line-height: 1.35;
}
.bell-b {
  font-size: 13px;
  color: var(--muted);
  margin-top: 3px;
  line-height: 1.45;
  word-break: break-word;
}
.bell-time {
  font-size: 11.5px;
  color: var(--muted);
  margin-top: 5px;
  font-weight: 500;
}
.bell-empty {
  padding: 32px 18px;
  text-align: center;
  color: var(--muted);
  font-size: 14px;
}

/* ---------- Profile page ---------- */
/* Profile hero: a brand cover band with the avatar lifted over its edge, so
   the card reads as an identity header rather than another form panel. */
.profile-hero { padding: 0; overflow: hidden; }
.profile-cover { height: 108px; background: linear-gradient(120deg, var(--brand-800) 0%, var(--brand) 45%, var(--accent) 100%); position: relative; }
/* Faint radial highlight — stops the band reading as a flat block of colour. */
.profile-cover::after { content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 180% at 88% -30%, rgba(255,255,255,.30), transparent 60%); }
/* Only the PHOTO column rises into the band. Pulling the whole row up (which an
   earlier version did) drags the name with it — dark heading text lands on dark
   green and becomes unreadable. The text column stays in normal flow. */
.profile-body { padding: 0 26px 24px; position: relative; }
.profile-top { display: flex; gap: 22px; align-items: flex-start; flex-wrap: wrap; }
.profile-photo { text-align: center; margin-top: -56px; }
.avatar-lg { width: 104px; height: 104px; border-radius: 28px; font-size: 34px; margin: 0 auto 12px;
  box-shadow: 0 0 0 5px var(--surface), var(--shadow); }
.profile-meta { flex: 1; min-width: 250px; padding-top: 14px; }
/* Edit button pinned to the top-right of the row, clear of the cover band. */
.profile-actions { padding-top: 14px; margin-left: auto; }
.profile-edit { margin: 0; }
.profile-edit .pe-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 16px; }
.profile-edit .pe-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
.profile-edit .field { margin-bottom: 12px; }

/* Security pair: transaction PIN and password, side by side.
   align-items:start stops the shorter card stretching to match the taller one,
   and the shared .sec-form pushes both buttons to the card's bottom edge so
   they line up across the pair whatever the field count. */
.section-title { font-size: 19px; margin: 0 0 12px; }
/*
 * min(320px, 100%) rather than a bare 320px.
 *
 * minmax() treats its first argument as a HARD minimum: on a 320px phone the
 * content column is only ~250px wide, so a 320px floor made the track wider
 * than its container and the cards ran off the screen. min(…, 100%) lets the
 * track collapse to whatever room there actually is.
 */
.sec-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: 18px; align-items: start; }
.sec-card { display: flex; flex-direction: column; }
.sec-state { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 14px 0 0; padding-top: 14px; border-top: 1px solid var(--line);
  font-size: 13px; color: var(--muted); }
.sec-state .badge { display: inline-flex; align-items: center; gap: 4px; }
.sec-form { margin-top: 14px; display: flex; flex-direction: column; }
.sec-form .field { margin-bottom: 12px; }
.sec-form .btn { align-self: flex-start; margin-top: auto; }

/* Identity slots: what is on file, per document. */
.id-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; }
.id-slot { display: flex; align-items: center; gap: 10px; padding: 11px 13px;
  border: 1px solid var(--line); border-radius: 13px; background: var(--surface-2); }
.id-slot.is-held { border-color: var(--ok); background: var(--ok-soft); }
.id-ic { flex: 0 0 auto; width: 30px; height: 30px; border-radius: 10px; display: inline-flex;
  align-items: center; justify-content: center; background: var(--surface-3); color: var(--muted); }
.id-slot.is-held .id-ic { background: var(--ok); color: #fff; }
.id-t { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.id-t strong { font-size: 13px; color: var(--heading); }
.id-t span { font-size: 12.5px; color: var(--muted); }

/* A public key is a long unbreakable token — let it wrap rather than widen the
   row past the card. */
.profile-name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0 0 6px; font-size: 15px; font-weight: 700; letter-spacing: -.2px; }
.profile-name .badge { font-size: 10.5px; padding: 1px 7px; vertical-align: middle; }
.profile-contact { display: flex; align-items: center; gap: 8px 14px; flex-wrap: wrap; margin: 0; color: var(--muted); font-size: 14px; }
/*
 * INLINE flow here, not flex — deliberately.
 *
 * An email address is one unbreakable token. Under flex the row could not
 * shrink below it, so on a phone the address pushed past the card and the
 * verification chip was sliced in half at the edge. Adding flex-wrap did not
 * help either: flexbox assigns items to lines BEFORE shrinking them, so the
 * long address simply took a line of its own and stranded the icon above it.
 *
 * As inline content it all reflows like prose — icon, address, chip — the
 * address breaking mid-token where it has to and the chip staying whole.
 */
.profile-contact .pc-item { display: flex; align-items: flex-start; gap: 6px; min-width: 0; max-width: 100%; }
.profile-contact .pc-item > svg { flex: 0 0 auto; width: 15px; height: 15px; opacity: .75; margin-top: 3px; }
/* The icon is a fixed column; everything else is ONE shrinkable box of inline
   content, so the value wraps under itself instead of pushing the icon onto a
   line of its own, and the chip flows along at the end. */
.profile-contact .pc-body { min-width: 0; overflow-wrap: anywhere; }
.profile-contact .vchip { vertical-align: middle; margin-left: 4px; }

/* Verification chip. The tick is the point — a green pill alone reads as
   decoration, while a check next to the address reads as a state. */
.vchip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px 3px 7px;
  border-radius: 999px; font-size: 11.5px; font-weight: 800; letter-spacing: .01em;
  text-decoration: none; white-space: nowrap; }
.vchip svg { width: 13px; height: 13px; }
.vchip.is-ok { background: var(--ok-soft); color: var(--ok); }
.vchip.is-pending { background: var(--warn-soft); color: var(--warn); }
a.vchip.is-pending:hover { background: var(--warn); color: #fff; }

/* Full width, below the photo+name row — not nested inside the text column,
   so the four cards get the whole card width instead of wrapping 3+1. */
.profile-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-top: 18px; }
.profile-stats > div { display: flex; align-items: center; gap: 11px;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 14px; padding: 12px 14px; }
.ps-ic { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 11px; display: inline-flex;
  align-items: center; justify-content: center; background: var(--surface-3); color: var(--brand-text); }
.ps-ic svg { width: 17px; height: 17px; }
.ps-t { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.profile-stats span { font-size: 11.5px; color: var(--muted); font-weight: 600; }
.profile-stats strong { font-size: 17px; color: var(--heading); letter-spacing: -.2px; }

@media (max-width: 640px) {
  .profile-body { padding: 0 18px 20px; }
  .profile-top { gap: 16px; }
  .profile-cover { height: 92px; }
  .profile-photo { margin-top: -48px; }
  .avatar-lg { width: 88px; height: 88px; border-radius: 24px; font-size: 30px; }
  .profile-name { font-size: 13.5px; gap: 6px; }
  .profile-name .badge { font-size: 10px; padding: 1px 6px; }
  .profile-meta { padding-top: 10px; }
}
.content { padding: 28px; }
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 22px; }

/* ---------- Segmented toggle (Local / International) ---------- */
.seg-toggle { display: inline-flex; background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px; padding: 4px; gap: 4px; margin-bottom: 18px; }
.seg-toggle button { border: 0; background: transparent; font: inherit; font-weight: 700; color: var(--muted); padding: 8px 18px; border-radius: 9px; cursor: pointer; transition: color .14s ease, background .14s ease, box-shadow .14s ease; }
.seg-toggle button.active { background: var(--surface); color: var(--brand-text); box-shadow: var(--shadow-sm); }

/* ---------- Recipient verification ---------- */
.verify-box { margin: -4px 0 10px; padding: 10px 14px; border-radius: 12px; font-size: 14px; font-weight: 600; border: 1px solid transparent; }
.verify-box.ok { background: var(--ok-soft); color: var(--ok); border-color: color-mix(in srgb, var(--ok) 25%, transparent); }
.verify-box.warn { background: var(--warn-soft); color: var(--warn); border-color: color-mix(in srgb, var(--warn) 25%, transparent); }
/* Verification is automatic, so it needs an in-flight state the button used to
   convey by turning into "Verifying…". */
.verify-box.pending { background: var(--surface-2); color: var(--muted); border-color: var(--line); }
.verify-box.pending::before { content: ""; display: inline-block; width: 12px; height: 12px; margin-right: 8px;
  vertical-align: -1px; border: 2px solid var(--line-strong); border-top-color: var(--brand); border-radius: 50%;
  animation: verify-spin .7s linear infinite; }
@keyframes verify-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .verify-box.pending::before { animation: none; } }
.verify-box strong { color: inherit; }
.verify-box .verify-sub { margin-top: 3px; font-size: 12px; font-weight: 500; opacity: .85; }

.provider-card { padding: 16px 18px; }

/* Hidden by default; the max-width:900px block turns it back on, i.e. exactly
   when the customer sidebar is replaced by the bottom bar. */
.mobile-only { display: none; }

/* ---------- Catalogue sync: one row per provider group ---------- */
.sync-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 10px; }
.sync-row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; min-width: 0;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 12px;
}
.sync-row .sync-meta { min-width: 0; }
.sync-row .cell-val { display: block; font-size: 14px; }
.sync-row .cell-sub { white-space: normal; font-size: 12px; }
.sync-row .btn.sm { flex: 0 0 auto; }

/* ---------- Menu list (profile account links) ---------- */
.menu-list { display: flex; flex-direction: column; }
.menu-list form { margin: 0; }
.menu-list a, .menu-list button { display: flex; align-items: center; gap: 12px; width: 100%; padding: 14px 6px; border: 0; border-top: 1px solid var(--line); background: transparent; font: inherit; font-weight: 600; font-size: 15px; color: var(--ink); text-align: left; cursor: pointer; transition: color .14s ease; }
.menu-list > a:first-child, .menu-list form:first-child button { border-top: 0; }
.menu-list a:hover, .menu-list button:hover { color: var(--brand-text); }
.menu-list .mi-ic { flex: 0 0 auto; width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center; background: var(--surface-3); color: var(--brand-text); }
.menu-list .mi-t { flex: 1 1 auto; }
.menu-list .mi-ch { flex: 0 0 auto; color: var(--muted); font-size: 20px; }
.menu-list .mi-danger { color: var(--err); }
.menu-list .mi-danger .mi-ic { background: var(--err-soft); color: var(--err); }

/* ---------- Developer docs ---------- */
.quickstart { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-top: 22px; }
.qs-step { display: flex; gap: 12px; align-items: flex-start; background: var(--surface); border: 1px solid var(--line); border-radius: 16px; padding: 16px 18px; box-shadow: var(--shadow-sm); }
.qs-step .qs-num { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; background: var(--brand); color: var(--on-brand); font-weight: 800; display: grid; place-items: center; }
.qs-step strong { color: var(--heading); }
.qs-step p { margin: 3px 0 0; font-size: 13px; }
.doc-toc { display: flex; flex-direction: column; gap: 8px; }
.doc-toc a { color: var(--muted); font-weight: 600; }
.doc-toc a:hover { color: var(--brand-text); }
.doc h3 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.verb { font-size: 11px; font-weight: 800; letter-spacing: .04em; padding: 3px 9px; border-radius: 7px; color: #fff; }
.verb.get { background: var(--ok); }
.verb.post { background: var(--brand); }
.doc-list { list-style: none; padding: 0; margin: 10px 0 0; display: flex; flex-direction: column; gap: 8px; }
.doc-list li { display: flex; align-items: center; gap: 8px; }
/* Prose items (the webhook rules) wrap their text in a span and sit as multi-
   line paragraphs, so align the marker to the first line rather than centre. */
.doc-list li:has(> span) { align-items: flex-start; }
.doc-list li > span::before { content: "→"; color: var(--brand-text); font-weight: 700; margin-right: 8px; }

.code-block { border: 1px solid var(--line); border-radius: 12px; overflow: hidden; margin: 12px 0 0; background: var(--code-bg); }
.code-bar { display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; background: rgba(255,255,255,.06); border-bottom: 1px solid rgba(255,255,255,.08); }
.code-label { color: rgba(255,255,255,.6); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; }
.code-copy { border: 1px solid rgba(255,255,255,.2); background: transparent; color: #fff; font-weight: 700; font-size: 12px; padding: 4px 12px; border-radius: 8px; cursor: pointer; }
.code-copy:hover { background: rgba(255,255,255,.12); }
.code-block pre { margin: 0; padding: 14px 16px; overflow-x: auto; color: var(--code-ink); font: 13px/1.6 ui-monospace, "SF Mono", Menlo, monospace; white-space: pre; }
.code-copy.is-copied { border-color: var(--ok); color: #fff; background: rgba(22, 163, 74, .35); }

/* Provider-log payloads: one compact, scrollable, copiable block per row.
   Capped in height so a 40-line webhook body can't stretch the table row. */
.log-payload { margin: 0; max-width: 470px; }
.log-payload .code-bar { padding: 5px 10px; }
.log-payload pre { max-height: 150px; overflow: auto; padding: 10px 12px; font-size: 12px; line-height: 1.5; }
.data.logs td { vertical-align: top; }
.data.logs td code { white-space: nowrap; }
.lang-tabs { margin-top: 12px; }
.lang-btns { display: inline-flex; gap: 4px; background: var(--surface-2); border: 1px solid var(--line); border-radius: 10px; padding: 3px; }
.lang-btns button { border: 0; background: transparent; font: inherit; font-weight: 700; font-size: 13px; color: var(--muted); padding: 6px 14px; border-radius: 7px; cursor: pointer; }
.lang-btns button.active { background: var(--surface); color: var(--brand-text); box-shadow: var(--shadow-sm); }
@media (max-width: 720px) { .quickstart { grid-template-columns: 1fr; } }

/* API reference — grouped TOC, parameter tables, endpoint index */
.doc-toc-panel { position: sticky; top: 20px; align-self: start; }
.doc-toc-panel > summary { list-style: none; font-weight: 800; font-size: 16px; color: var(--heading); margin-bottom: 10px; }
.doc-toc-panel > summary::-webkit-details-marker { display: none; }
@media (min-width: 641px) { .doc-toc-panel > summary { pointer-events: none; } } /* desktop: acts as a heading, not a toggle */
.doc-toc .toc-label { font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); font-weight: 800; margin: 16px 0 2px; opacity: .7; }
.doc-toc .toc-label:first-child { margin-top: 0; }
.doc-toc a { padding: 3px 0; font-size: 14px; }
.doc .endpoint { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0 0 4px; }
.doc .endpoint .path { font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-weight: 700; font-size: 15px; color: var(--heading); }
.doc h4 .path { font-size: 14px; }
.doc-sub { color: var(--muted); font-size: 13px; text-transform: uppercase; letter-spacing: .05em; font-weight: 700; margin: 18px 0 8px; }
.doc-table { width: 100%; border-collapse: collapse; margin: 6px 0 6px; font-size: 13.5px; }
.doc-table th { text-align: left; padding: 8px 12px; background: var(--surface-2); color: var(--muted); font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; border-bottom: 1px solid var(--line); font-weight: 800; }
.doc-table td { padding: 9px 12px; border-bottom: 1px solid var(--line); vertical-align: top; color: var(--ink); }
.doc-table tr:last-child td { border-bottom: 0; }
.doc-table td:first-child code { color: var(--brand-text); font-weight: 700; }
.doc-table .type { color: var(--muted); font-family: ui-monospace, monospace; font-size: 12px; white-space: nowrap; }
.doc-table .req { color: var(--err); font-weight: 700; font-size: 11px; text-transform: uppercase; letter-spacing: .03em; }
.doc-table .opt { color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .03em; }
.endpoint-index { width: 100%; border-collapse: collapse; font-size: 14px; }
.endpoint-index th { text-align: left; padding: 10px 14px; background: var(--surface-2); color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: .05em; border-bottom: 1px solid var(--line); }
.endpoint-index td { padding: 10px 14px; border-bottom: 1px solid var(--line); }
.endpoint-index tr:last-child td { border-bottom: 0; }
.endpoint-index tr:hover td { background: var(--surface-2); }
.endpoint-index .path { font-family: ui-monospace, monospace; font-weight: 700; color: var(--heading); font-size: 13.5px; }
.endpoint-index a.path { color: var(--brand-text); }
/* Chips, not a run-on line of text — the rest of the site states facts in
   bordered surfaces, and this read as an afterthought under the intro. */
.doc-meta { display: flex; flex-wrap: wrap; gap: 10px; margin: 22px 0 4px; padding: 0; list-style: none; }
.doc-meta li {
  display: inline-flex; align-items: baseline; gap: 8px; min-width: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
  padding: 8px 16px; font-size: 13.5px; color: var(--ink); box-shadow: var(--shadow-sm);
}
.doc-meta li strong { color: var(--muted); font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; flex: 0 0 auto; }
.doc-meta li code { font-size: 12.5px; overflow-wrap: anywhere; }

/* Docs hero: same display type as the landing page, a size down. */
.doc-hero { padding: 22px 0 8px; }
.doc-hero h1 { font-size: clamp(34px, 5vw, 56px); margin: 0 0 12px; }
.doc-hero p.lead { max-width: 64ch; font-size: 17px; color: var(--muted); margin: 0; }

/* ---------- eSIM receipt ---------- */
.esim-panel .esim-qr { display: flex; justify-content: center; margin: 6px 0 14px; }
.esim-panel .esim-qr img { border: 1px solid var(--line); border-radius: 16px; padding: 10px; background: #fff; max-width: 100%; height: auto; }

/* ---------- Pager ---------- */
.pager { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 16px; }
.pager-count { color: var(--muted); font-size: 13px; font-weight: 600; }
.pager-nav { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pager-btn { display: inline-flex; align-items: center; justify-content: center; min-width: 36px; height: 36px; padding: 0 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); color: var(--heading); font-weight: 700; font-size: 14px; transition: border-color .14s ease, background .14s ease, color .14s ease; }
.pager-btn:hover { border-color: var(--brand); background: var(--surface-2); color: var(--brand-text); }
.pager-btn.active { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.pager-btn.disabled { opacity: .45; pointer-events: none; }
.pager-gap { color: var(--muted); padding: 0 2px; }

/* ---------- Breadcrumb ---------- */
.breadcrumb { display: flex; align-items: center; flex-wrap: wrap; gap: 2px; margin: 0 0 8px; font-size: 13px; font-weight: 600; }
.breadcrumb a { color: var(--muted); display: inline-flex; align-items: center; padding: 3px 9px; border-radius: 8px; transition: color .14s ease, background .14s ease; }
.breadcrumb a:hover { color: var(--brand-text); background: var(--surface-2); }
.breadcrumb .sep { color: var(--line-strong); font-weight: 400; padding: 0 1px; user-select: none; }
.breadcrumb .current { color: var(--heading); padding: 3px 9px; }

/* ---------- Wallet card ---------- */
.wallet-card { color: #fff; border-radius: 22px; padding: 26px; position: relative; overflow: hidden;
  background: radial-gradient(600px 300px at 90% -20%, rgba(255,255,255,.22), transparent), linear-gradient(135deg, var(--brand-700), var(--brand)); box-shadow: var(--shadow); }
.wallet-card small { color: rgba(255,255,255,.75); text-transform: uppercase; letter-spacing: .08em; font-size: 12px; font-weight: 700; }
.wallet-card .balance { font-size: clamp(34px, 6vw, 52px); font-weight: 800; margin: 8px 0; letter-spacing: -.02em; }
.wallet-card .actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.wallet-card .actions .btn.ghost { background: rgba(255,255,255,.16); color: #fff; border-color: rgba(255,255,255,.30); }
.wallet-card .actions .btn.ghost:hover { background: rgba(255,255,255,.26); }

/* ---------- Stat tiles ---------- */
.stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(216px, 1fr)); gap: 16px; }
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; box-shadow: var(--shadow-sm); transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease; }
.stat:hover { transform: translateY(-2px); box-shadow: var(--shadow); border-color: var(--line-strong); }
.stat .label { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); }
.stat .value { font-size: 24px; font-weight: 800; color: var(--heading); letter-spacing: -.02em; line-height: 1.15; white-space: nowrap; }

/* ---------- Service grid ---------- */
.services { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; }
.service { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; box-shadow: var(--shadow-sm); color: var(--heading); font-weight: 700; transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease; position: relative; }
.service:hover { border-color: var(--brand); transform: translateY(-3px); box-shadow: var(--shadow); }
.service .ic { width: 46px; height: 46px; border-radius: 13px; display: grid; place-items: center; font-size: 20px; background: var(--surface-3); color: var(--brand-text); transition: background .14s ease, color .14s ease; }
.service:hover .ic { background: var(--brand); color: var(--on-brand); }

/* ---------- Tables ---------- */
.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
table.data { width: 100%; border-collapse: collapse; min-width: 640px; }
/* Key/value tables (e.g. the receipt) don't need the wide min-width. */
table.data.kv { min-width: 0; }
table.data.kv th { white-space: nowrap; width: 1%; }
table.data.kv td { word-break: break-word; }
table.data th, table.data td { text-align: left; padding: 13px 16px; border-bottom: 1px solid var(--line); font-size: 14px; }
table.data th { background: var(--surface-2); color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .05em; }
table.data tr:last-child td { border-bottom: 0; }
table.data tr.clickable { cursor: pointer; }
table.data tr.clickable:hover td { background: var(--surface-2); }
/* Compact inline-edit inputs inside admin tables (keeps rows tidy). */
table.data td { vertical-align: middle; }
table.data input.field, table.data select.field { min-height: 38px; padding: 0 10px; border-radius: 10px; font-size: 14px; }
table.data select.field { padding-right: 30px; background-position: right 8px center; }
table.data .btn.ghost { padding: 8px 14px; min-height: 38px; }
table.data tfoot th { border-bottom: 0; border-top: 1px solid var(--line); }

/* ---------- AutoSync-style admin table arrangement ---------- */
.table-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-sm); overflow: hidden; margin-top: 20px; }
.table-card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 16px 20px; border-bottom: 1px solid var(--line); background: var(--surface-2); }
.table-card-head h3 { margin: 0; font-size: 16px; color: var(--heading); }
.table-card-head .sub { margin: 2px 0 0; font-size: 13px; color: var(--muted); }
.table-card-head .head-actions { display: flex; gap: 8px; flex: 0 0 auto; }
.table-card > .table-wrap { border: 0; border-radius: 0; box-shadow: none; }
.table-card > .filters { padding: 14px 20px; margin: 0; border-bottom: 1px solid var(--line); }
.table-card > .pager { margin: 0; padding: 13px 20px; border-top: 1px solid var(--line); background: var(--surface-2); }

/* A table cell holding several lines. Keeps them as ONE flex item once the
   table stacks into cards, so the lines stay stacked instead of spreading
   across the row. */
.cell-lines { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

/* Transaction rows carry up to four verbs; let them wrap instead of forcing
   the table wider, and keep them right-aligned with the rest of the row. */
.txn-actions { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
.txn-actions .btn.sm { white-space: nowrap; }

.icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; padding: 0; border-radius: 10px; border: 1px solid var(--line); background: var(--surface); color: var(--muted); cursor: pointer; transition: color .14s ease, border-color .14s ease, background .14s ease, transform .14s ease; }
.icon-btn:hover { color: var(--brand-text); border-color: var(--brand); background: var(--surface-2); transform: translateY(-1px); }
.icon-btn.danger:hover { color: var(--err); border-color: var(--err); background: var(--err-soft); }
.icon-btn.primary { background: var(--brand); border-color: var(--brand); color: var(--on-brand); }
.icon-btn.primary:hover { background: var(--brand-600); color: var(--on-brand); }
.icon-btn .icon { width: 17px; height: 17px; }

.id-code { display: flex; flex-direction: column; gap: 2px; }
.id-code .id { font-weight: 700; color: var(--ink); }
.id-code code { font-size: 12px; color: var(--muted); }

.count-link { display: inline-flex; align-items: center; gap: 6px; font-weight: 700; color: var(--brand-text); white-space: nowrap; }
.count-link:hover { color: var(--brand); }
.count-link .n { background: var(--surface-3); color: var(--brand-text); padding: 2px 9px; border-radius: 999px; font-size: 12px; }

.thumb { width: 34px; height: 34px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; font-weight: 800; font-size: 12px; color: #fff; background: var(--brand); text-transform: uppercase; letter-spacing: -.02em; flex: 0 0 auto; }
.net-cell { display: flex; align-items: center; gap: 10px; }

/* ---------- Network picker (vending) ---------- */
/* 76px keeps the four Nigerian networks on one row inside the buy panel, and
   still wraps cleanly for services with more providers (electricity has 7). */
.net-picker { display: grid; grid-template-columns: repeat(auto-fit, minmax(76px, 1fr)); gap: 10px; }
/* Exactly four (the Nigerian network set) always share one row — auto-fit drops
   T2 onto a second line as soon as the panel narrows. minmax(0,…) lets the
   columns shrink past the card's natural width instead of overflowing. */
.net-picker:has(> .net-card:nth-child(4):last-child) { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.net-card { min-width: 0; }
/* Wrap to two lines instead of truncating: "Port Harcourt Electric" and
   "Kaduna Electric" were both being cut to "Port Har…" / "Kaduna …". */
.net-card .net-name { max-width: 100%; line-height: 1.25; text-align: center; overflow-wrap: anywhere; hyphens: auto; }
.net-picker:empty { display: none; }
.net-card {
  display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 12px 8px;
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2);
  font: inherit; font-weight: 700; font-size: 13px; color: var(--heading); cursor: pointer;
  transition: border-color .14s ease, background .14s ease, transform .14s ease, box-shadow .14s ease;
}
.net-card:hover { border-color: var(--brand); transform: translateY(-2px); }
.net-card.active { border-color: var(--brand); background: var(--surface); box-shadow: var(--ring); color: var(--brand-text); }
.net-card .net-name { line-height: 1; }
/* Provider logos (DisCos, cable, betting) are wide wordmarks. In a 34px square
   they scale to fit the WIDTH and end up ~10px tall and unreadable, so on the
   vending card the logo gets the card's full width to work with. Compact marks
   like MTN/Glo just centre in it. */
.net-card .net-logo { width: 100%; max-width: 60px; height: 36px; }
/* Operator logos are supplied on transparent backgrounds and some (MTN) are
   near-black, so they sit on a fixed white tile rather than the themed surface
   — otherwise they vanish in dark mode. */
.net-logo { width: 34px; height: 34px; border-radius: 10px; object-fit: contain; flex: 0 0 auto; display: block; }
img.net-logo { background: #fff; padding: 3px; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .06); }
/* For marks published only in white — a white tile would hide them entirely. */
img.net-logo.on-dark { background: #12302d; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12); }
/* Added by JS once the cards render — the select stays the state holder, and
   remains visible if the script never ran. Needs to outrank `.field select`,
   which sets width:100%, so it is qualified rather than left bare. */
.field select.net-select-hidden, .net-select-hidden {
  position: absolute; width: 1px; height: 1px; min-height: 0; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; appearance: none; background-image: none;
}

.vis-tag { display: inline-flex; align-items: center; gap: 5px; font-weight: 700; font-size: 12px; color: var(--ok); }
.vis-tag::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.vis-tag.off { color: var(--muted); }
.country-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(72px, 1fr)); gap: 8px; max-height: 220px; overflow-y: auto; padding: 4px; }
.country-chip { display: flex; align-items: center; gap: 5px; padding: 7px 8px; border: 1px solid var(--line); border-radius: 10px; cursor: pointer; font-size: 13px; font-weight: 600; user-select: none; transition: border-color .14s ease, background .14s ease; }
.country-chip:hover { border-color: var(--brand); }
.country-chip:has(input:checked) { border-color: var(--brand); background: var(--surface-2); color: var(--brand-text); }
.country-chip input { accent-color: var(--brand); }
.soon-tag { display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px; font-size: 10px; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; background: var(--warn-soft); color: var(--warn); vertical-align: middle; }
.service { position: relative; }
.dial-chip { display: inline-flex; align-items: center; padding: 0 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface-2); font-weight: 700; color: var(--heading); white-space: nowrap; }
.soon-hero { text-align: center; display: flex; flex-direction: column; align-items: center; padding: 48px 24px; }
.soon-ic { width: 64px; height: 64px; border-radius: 18px; display: inline-flex; align-items: center; justify-content: center; background: var(--surface-3); color: var(--brand-text); margin-bottom: 16px; }
/* A neutral fill by DEFAULT. Callers build the variant from data
   (`class="badge <?= $x ?>"`), and a state with no variant — "Not started" on
   the business-verification row — used to land here as unstyled bare text. */
.badge { display: inline-block; padding: 4px 10px; border-radius: 999px; font-size: 12px; font-weight: 700;
  background: var(--surface-3); color: var(--muted); }
.badge.successful, .badge.active, .badge.credit { background: var(--ok-soft); color: var(--ok); }
.badge.pending { background: var(--warn-soft); color: var(--warn); }
.badge.failed, .badge.reversed, .badge.suspended, .badge.debit { background: var(--err-soft); color: var(--err); }
.badge.muted { background: var(--surface-2); color: var(--muted); }

/* ---------- Toast ----------
 * Deliberately loud.
 *
 * The previous version sat at the BOTTOM of the page filled with --surface and
 * a hairline --line border — the same fill as every card behind it — so only a
 * 26px icon carried any colour at all. "Purchase successful" read as page
 * furniture and got missed.
 *
 * Now: top of the viewport where the eye already is, the status colour across
 * the WHOLE pill rather than one dot, larger type, a hard shadow to lift it off
 * the page, and a countdown bar so it never just silently disappears.
 *
 * Colours are literal rather than themed on purpose. The fill is solid and the
 * text on it is always white, so fixed values guarantee the contrast holds in
 * both light and dark — a themed --ok would go pale-on-white in one of them.
 */
.toast { position: fixed; left: 50%; top: 20px; transform: translate(-50%, -160%) scale(.96);
  opacity: 0; pointer-events: none;
  display: flex; align-items: center; gap: 14px;
  width: max-content; min-width: min(92vw, 340px); max-width: min(92vw, 560px);
  padding: 15px 16px; border-radius: 16px;
  color: #fff; font-weight: 700; font-size: 15.5px; line-height: 1.4;
  background: #1e293b;
  box-shadow: 0 20px 55px rgba(2, 20, 18, .38), inset 0 0 0 1px rgba(255, 255, 255, .14);
  z-index: 999; overflow: hidden;
  transition: opacity .26s ease, transform .34s cubic-bezier(.2, .9, .3, 1.25); }
.toast.show { opacity: 1; transform: translate(-50%, 0) scale(1); pointer-events: auto; }

/* Status fills. Each also tints its own shadow so the colour reads even in
   peripheral vision. */
.toast.success { background: linear-gradient(135deg, #17a34a, #0d9488); box-shadow: 0 20px 55px rgba(13, 148, 136, .45), inset 0 0 0 1px rgba(255,255,255,.16); }
.toast.error   { background: linear-gradient(135deg, #e11d48, #b91c1c); box-shadow: 0 20px 55px rgba(190, 24, 40, .45), inset 0 0 0 1px rgba(255,255,255,.16); }
.toast.info    { background: linear-gradient(135deg, #0f766e, #155e75); box-shadow: 0 20px 55px rgba(15, 118, 110, .45), inset 0 0 0 1px rgba(255,255,255,.16); }
.toast.loading { background: linear-gradient(135deg, #334155, #1e293b); }

.toast .toast-ic { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .20); color: #fff; }
.toast .toast-ic svg { width: 19px; height: 19px; }
.toast .toast-msg { flex: 1 1 auto; }
.toast.toast-link { cursor: pointer; }
.toast.toast-link .toast-msg::after { content: " →"; opacity: .8; }

.toast .toast-x { flex: 0 0 auto; border: 0; background: rgba(255, 255, 255, .14); color: #fff;
  font-size: 18px; line-height: 1; cursor: pointer; width: 26px; height: 26px; border-radius: 8px; }
.toast .toast-x:hover { background: rgba(255, 255, 255, .30); }

/* Countdown. Width is driven by an animation whose duration JS sets inline, so
   the bar always matches the real dismiss delay rather than guessing at it. */
.toast .toast-bar { position: absolute; left: 0; bottom: 0; height: 3px; width: 100%;
  background: rgba(255, 255, 255, .55); transform-origin: left center; transform: scaleX(1); }
.toast .toast-bar.run { animation: toast-countdown linear forwards; }
.toast:hover .toast-bar.run { animation-play-state: paused; }
@keyframes toast-countdown { to { transform: scaleX(0); } }

.toast-spin { width: 19px; height: 19px; border-radius: 50%; border: 2.5px solid currentColor;
  border-top-color: transparent; animation: toast-spin .7s linear infinite; }
@keyframes toast-spin { to { transform: rotate(360deg); } }

@media (max-width: 560px) {
  .toast { left: 12px; right: 12px; width: auto; max-width: none; min-width: 0;
    transform: translate(0, -160%) scale(.96); font-size: 15px; }
  .toast.show { transform: translate(0, 0) scale(1); }
}

/* Motion is the attention-getter here, so reduced-motion keeps the toast just
   as visible — it simply appears instead of springing in. */
@media (prefers-reduced-motion: reduce) {
  .toast { transition: opacity .2s ease; transform: translate(-50%, 0) scale(1); }
  .toast.show { transform: translate(-50%, 0) scale(1); }
  .toast-spin { animation-duration: 1.6s; }
  @media (max-width: 560px) {
    .toast, .toast.show { transform: none; }
  }
}

/* ---------- Misc ---------- */
.alert { padding: 12px 16px; border-radius: var(--radius-sm); font-size: 14px; margin-bottom: 16px; }
.alert.warn { background: var(--warn-soft); color: var(--warn); }
.alert.info { background: var(--surface-3); color: var(--brand-text); }
.muted { color: var(--muted); }
.row { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.right { margin-left: auto; }
.mt { margin-top: 18px; }
.hide { display: none !important; }
code, pre { font-family: "SFMono-Regular", ui-monospace, Menlo, monospace; }
pre.code { background: var(--code-bg); color: var(--code-ink); padding: 16px 18px; border-radius: var(--radius-sm); overflow-x: auto; font-size: 13px; line-height: 1.55; }

/* ---------- Responsive column grids (collapse on small screens) ---------- */
/* minmax(0,1fr) lets tracks shrink below their content's min-width so a wide
   child (e.g. amount chips) can't blow the grid past the viewport. */
.cols-2, .cols-3, .cols-4, .cols-5, .cols-sidebar { display: grid; gap: 16px; align-items: start; }
.cols-2 { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cols-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.cols-sidebar { grid-template-columns: 280px minmax(0, 1fr); gap: 24px; }
@media (max-width: 900px) {
  .cols-3, .cols-4, .cols-5, .cols-sidebar { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
}
@media (max-width: 640px) {
  .cols-2, .cols-3, .cols-4, .cols-5, .cols-sidebar { grid-template-columns: minmax(0, 1fr); }
  /* API-docs TOC: on a single-column layout it must not be sticky (it would pin
     full-height over the content). It becomes a collapsible dropdown instead. */
  .doc-toc-panel { position: static; }
  .doc-toc-panel > summary { cursor: pointer; display: flex; align-items: center; justify-content: space-between; margin: 0; }
  .doc-toc-panel > summary::after { content: "⌄"; font-size: 20px; line-height: 1; color: var(--muted); transform: translateY(-4px); transition: transform .2s ease; }
  .doc-toc-panel[open] > summary { margin-bottom: 12px; }
  .doc-toc-panel[open] > summary::after { transform: translateY(2px) rotate(180deg); }
  .doc-toc { flex-flow: row wrap; gap: 6px 14px; }
  .doc-toc .toc-label { width: 100%; margin: 8px 0 0; }

  /* Stackable tables → cards (no horizontal scroll on phones). */
  .table-wrap:has(table.data.stackable) { border: 0; background: transparent; overflow: visible; }
  /* A panel that's mostly a stackable list already shows each row as a card —
     drop the panel's own box so the cards aren't nested/cramped inside it. */
  .panel:has(.table-wrap table.data.stackable) { padding: 0; background: transparent; border: 0; box-shadow: none; }
  /* Same for a table-card wrapping a stackable list — otherwise its border +
     overflow:hidden clips the stacked cards' edges. Let cards sit free. */
  .table-card:has(table.data.stackable) { border: 0; background: transparent; box-shadow: none; overflow: visible; margin-top: 8px; }
  .table-card:has(table.data.stackable) > .table-card-head { background: transparent; border-bottom: 0; padding: 0 2px 10px; }
  .table-card:has(table.data.stackable) > .filters { padding: 0 2px 12px; border-bottom: 0; }
  .table-card:has(table.data.stackable) > .pager { background: transparent; border-top: 0; padding: 14px 2px 2px; }

  /* The head is a nowrap flex row, so a 180px search box + button pushed past
     the card edge. Let it wrap and give the search the full line. */
  .table-card-head { flex-wrap: wrap; }
  .table-card-head .head-actions { width: 100%; flex: 1 1 100%; }
  .table-search { flex: 1 1 auto; }
  .table-search input { width: 100%; min-width: 0; }
  /* Drag-to-reorder is a pointer gesture and the select-all checkbox has no
     column header once rows are cards — both are noise on a phone. */
  table.data.stackable td.col-drag { display: none; }
  table.data.stackable td.col-sel { justify-content: flex-start; border-bottom: 0; padding-bottom: 0; }
  table.data.stackable td.col-sel::before { content: "Select"; }
  /* Long codes must wrap inside the card rather than widen it. */
  table.data.stackable td { overflow-wrap: anywhere; min-width: 0; }
  table.data.stackable td code { white-space: normal; overflow-wrap: anywhere; }
  /* Row actions sit on their own line, comfortably tappable. */
  table.data.stackable td.col-action { justify-content: flex-end; }
  table.data.stackable td.col-action .row-actions { gap: 10px; }
  table.data.stackable td.col-action .icon-btn { width: 38px; height: 38px; }
  table.data.stackable { min-width: 0; }
  table.data.stackable thead { display: none; } /* stacked cards use td::before labels */
  /* The catalogue tables repeat the header in a <tfoot>. Left visible it is a
     real multi-column row, which forces the whole table back to its natural
     width (~616px) and pushes every card value off screen. */
  table.data.stackable tfoot { display: none; }
  /* The pinned action column is a horizontal-scroll affordance; in a stacked
     card it just sticks to the right edge. (Already unpinned for .customers on
     desktop — this covers every stackable table on mobile.) */
  table.data.stackable:has(.edit-row) td:last-child { position: static; box-shadow: none; background: transparent; }
  table.data.stackable tbody { display: block; }
  table.data.stackable tr { display: block; background: var(--surface); border: 1px solid var(--line); border-radius: 14px; box-shadow: var(--shadow-sm); padding: 4px 2px; margin-bottom: 12px; }
  table.data.stackable tr:last-child { margin-bottom: 0; }
  table.data.stackable td { display: flex; justify-content: space-between; align-items: center; gap: 14px; border: 0; border-bottom: 1px solid var(--line); padding: 10px 14px; text-align: right; font-size: 14px; }
  table.data.stackable tr td:last-child { border-bottom: 0; }
  table.data.stackable td::before { content: attr(data-label); font-weight: 700; color: var(--muted); text-transform: uppercase; font-size: 11px; letter-spacing: .04em; text-align: left; flex: 0 0 auto; }
  table.data.stackable td:empty { display: none; }

  /* Stacked cards read label-left / value-right, so multi-line values align right. */
  table.data.stackable td .cell-lines { align-items: flex-end; text-align: right; }

  /* Transaction verbs: full-width, evenly split, thumb-sized on a phone. */
  table.data.stackable td.col-action .txn-actions { justify-content: flex-start; width: 100%; gap: 8px; }
  table.data.stackable td.col-action .txn-actions .btn.sm { flex: 1 1 auto; min-height: 40px; justify-content: center; }

  /* Provider logs: the payload is a block, not a value — give it the full card
     width with the label above it instead of the default label|value row. */
  table.data.stackable td.col-payload { flex-direction: column; align-items: stretch; text-align: left; gap: 8px; }
  table.data.stackable td.col-payload::before { text-align: left; }
  table.data.stackable td.col-payload .log-payload { max-width: none; }
  table.data.stackable td.col-payload .log-payload pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  /* Endpoint paths are long; let them wrap rather than widen the card. */
  table.data.stackable.logs td code { white-space: normal; }

  /* Customers table has richer cells (identity block, two-part activity, stacked
     verification badges). Stack each as label-above-value so nothing overflows. */
  table.data.stackable.customers td { flex-direction: column; align-items: flex-start; text-align: left; gap: 4px; overflow-wrap: anywhere; }
  table.data.stackable.customers td::before { text-align: left; }
  table.data.stackable.customers .cell-sub { white-space: normal; }
  /* Customer identity = full-width card header (avatar + name), no label. */
  table.data.stackable.customers td:has(.net-cell) { background: var(--surface-2); border-radius: 12px 12px 0 0; padding: 12px 14px; }
  table.data.stackable.customers td:has(.net-cell)::before { display: none; }
  table.data.stackable.customers .net-cell { width: 100%; }
  table.data.stackable.customers .net-cell .thumb { width: 40px; height: 40px; font-size: 14px; }
  /* Action buttons sit in a comfortable row. */
  table.data.stackable.customers td:has(.row-actions) .row-actions { flex-wrap: wrap; gap: 8px; }
}

/* Customers table (desktop): 8 columns is wide, so DON'T pin the action column
   (that pin overlaps the verification column when space is tight) and trim
   widths so the table fits its container instead of spilling. */
@media (min-width: 641px) {
  .data.stackable.customers:has(.edit-row) th:last-child,
  .data.stackable.customers:has(.edit-row) td:last-child { position: static; box-shadow: none; background: transparent; }
  .data.stackable.customers th, .data.stackable.customers td { padding-left: 12px; padding-right: 12px; }
  .data.stackable.customers .cell-sub { white-space: normal; }
  .data.stackable.customers td[data-label="Email"] { word-break: break-word; }
  .data.stackable.customers .row-actions { gap: 5px; }
  .data.stackable.customers .row-actions .icon-btn { width: 31px; height: 31px; }
}

/* ---------- Icons ---------- */
.icon { flex: none; vertical-align: middle; display: inline-block; }
.sidebar nav a .icon, .sidebar nav button .icon { color: var(--muted); }
.sidebar nav a:hover .icon, .sidebar nav button:hover .icon { color: var(--brand-text); }
.sidebar nav a.active .icon { color: var(--on-brand); }
.icon-pill { width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; background: var(--surface-3); color: var(--brand-text); flex: none; }
.tile-icon { width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center; background: var(--surface-3); color: var(--brand-text); margin-bottom: 10px; }

/* ---------- Responsive ---------- */
.menu-btn { display: none; border: 1px solid var(--line); background: var(--surface); border-radius: 12px; width: 44px; height: 44px; font-size: 20px; cursor: pointer; color: var(--heading); }

/* Floating bottom tab bar — mobile only. */
.bottomnav { display: none; }
@media (max-width: 900px) {
  .hero { grid-template-columns: 1fr; }
  .feature-grid, .service-tiles { grid-template-columns: 1fr 1fr; }
  .shell { grid-template-columns: 1fr; }
  /* Customer sidebar → bottom bar. Admin keeps its drawer (hamburger). */
  .sidebar:not(.sidebar-admin) { display: none; }
  /* Shown exactly where the sidebar stops: the profile page's "Account & more"
     list is the only route to Settings, API docs, push and Logout on mobile. */
  .mobile-only { display: block; }
  .menu-btn { display: none; }
  body:has(.sidebar-admin) .menu-btn { display: grid; place-items: center; }
  .sidebar-admin { position: fixed; inset: 0 auto 0 0; width: 264px; z-index: 46; transform: translateX(-100%); transition: transform .2s ease; }
  body.nav-open .sidebar-admin { transform: none; }
  body.nav-open::after { content: ""; position: fixed; inset: 0; background: rgba(4,20,18,.5); z-index: 30; }
  .grid-2 { grid-template-columns: 1fr; }
  .nav .links { display: none; }
  .nav-compact { display: flex; }

  .bottomnav { display: flex; position: fixed; left: 12px; right: 12px; bottom: 12px; z-index: 45;
    background: color-mix(in srgb, var(--surface) 92%, transparent); backdrop-filter: saturate(1.4) blur(10px); border: 1px solid var(--line); border-radius: 20px;
    padding: 8px 4px calc(8px + env(safe-area-inset-bottom, 0px)); justify-content: space-around;
    box-shadow: var(--shadow); }
  .bottomnav a { flex: 1 1 0; display: flex; flex-direction: column; align-items: center; gap: 3px;
    color: var(--muted); font-size: 11px; font-weight: 600; padding: 5px 2px; border-radius: 14px; min-width: 0; }
  .bottomnav a .icon { width: 22px; height: 22px; }
  .bottomnav a.active { color: var(--brand); }
  .bottomnav a.active .icon { color: var(--brand); }
  body:has(.bottomnav) .content { padding-bottom: 92px; }
  .topbar { padding-block: 12px; }
}
@media (max-width: 640px) {
  /* Page headers: stack the title and action buttons full-width instead of
     leaving the action floating with empty space beside it. */
  .page-head { flex-direction: column; align-items: stretch; }
  .page-head .btn, .page-head .row { width: 100%; }
  .page-head .row { justify-content: flex-start; }
  .page-head .btn.right, .page-head .right { margin-left: 0; }
}
@media (max-width: 560px) {
  .feature-grid, .service-tiles { grid-template-columns: 1fr; }
  .content, .topbar { padding-inline: 16px; }
  /* Tighter so four network cards still fit a 320px phone. */
  .net-picker { gap: 7px; }
  .net-card { padding: 10px 4px; font-size: 12px; gap: 6px; }
  .net-logo { width: 30px; height: 30px; }
  /* Declutter the top bar on very small screens: keep balance + avatar. */
  .topbar .profile b { display: none; }
}

/* ---- Searchable select (combobox) ---- */
.ss-wrap { position: relative; }
.ss-wrap .ss-input { padding-right: 38px; cursor: text; background-image: none; }
.ss-wrap::after {
  content: ""; position: absolute; right: 13px; top: 50%; width: 16px; height: 16px; margin-top: -8px; pointer-events: none;
  background: no-repeat center / 16px url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b6580' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
.ss-list {
  position: absolute; z-index: 60; left: 0; right: 0; top: calc(100% + 4px);
  max-height: 264px; overflow-y: auto; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); padding: 5px;
}
.ss-item { padding: 9px 12px; border-radius: 9px; cursor: pointer; font-size: 15px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ss-item:hover, .ss-item.active { background: var(--surface-3); }
.ss-item.sel { color: var(--brand-text); font-weight: 600; }
.ss-empty { padding: 11px 12px; color: var(--muted); font-size: 14px; }

/* ---- Filter bar (transaction & wallet history) ---- */
.filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 16px; }
.filters input, .filters select {
  min-height: 40px; padding: 0 12px; font: inherit; font-size: 14px; color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); outline: none;
  transition: border-color .14s ease, box-shadow .14s ease, background .14s ease;
}
.filters input[type="date"] { padding-right: 8px; cursor: pointer; }
.filters .grow { flex: 1 1 220px; min-width: 180px; }
.filters select {
  appearance: none; -webkit-appearance: none; cursor: pointer; padding-right: 32px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b6580' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center;
}
.filters input:focus, .filters select:focus { border-color: var(--brand); background: var(--surface); box-shadow: var(--ring); }
.filters .btn.sm { min-height: 40px; }
@media (max-width: 560px) {
  .filters { gap: 8px; }
  .filters .grow { flex-basis: 100%; }
  .filters select, .filters input[type="date"] { flex: 1 1 46%; }
}

/* Lighter dropdown chevrons on dark surfaces. */
[data-theme="dark"] .field select, [data-theme="dark"] select.field,
[data-theme="dark"] .filters select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23a49dbb' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}
[data-theme="dark"] .ss-wrap::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23a49dbb' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
}

/* ---- Polish: empty states, stat icons, landing ---- */
.empty-state { display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; padding: 34px 16px; color: var(--muted); font-weight: 500; }
.empty-state .es-ic { width: 48px; height: 48px; border-radius: 14px; display: grid; place-items: center; background: var(--surface-3); color: var(--brand-text); }
td .empty-state { padding: 26px 16px; }

.stat.has-ic { display: flex; align-items: center; gap: 15px; }
.stat .stat-ic { flex: 0 0 auto; width: 46px; height: 46px; border-radius: 13px; display: grid; place-items: center; background: var(--surface-3); color: var(--brand-text); }
.stat .stat-body { min-width: 0; }

/* Landing feature cards lift on hover, like service tiles */
.feature-grid .card { transition: transform .14s ease, box-shadow .14s ease, border-color .14s ease; }
.feature-grid .card:hover { transform: translateY(-3px); box-shadow: var(--shadow); border-color: var(--line-strong); }

/* Trust / stats band on the landing page */
.trust { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin: 8px 0 44px; }
.trust .t { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px; box-shadow: var(--shadow-sm); }
.trust .t .n { font-size: 26px; font-weight: 800; color: var(--heading); letter-spacing: -.02em; }
.trust .t .l { font-size: 13px; color: var(--muted); font-weight: 600; margin-top: 2px; }
@media (max-width: 760px) { .trust { grid-template-columns: 1fr 1fr; } }

/* Richer landing footer */
.site-foot { border-top: 1px solid var(--line); margin-top: 20px; padding: 34px 0 40px; }
.site-foot .cols { display: flex; justify-content: space-between; gap: 28px; flex-wrap: wrap; margin-bottom: 22px; }
.site-foot .brand { display: inline-flex; align-items: center; gap: 10px; font-weight: 800; color: var(--heading); margin-bottom: 8px; }
.site-foot .fcol h4 { font-size: 13px; text-transform: uppercase; letter-spacing: .06em; color: var(--muted); margin: 0 0 10px; }
.site-foot .fcol a { display: block; color: var(--ink); font-weight: 600; font-size: 14px; padding: 4px 0; }
.site-foot .fcol a:hover { color: var(--brand-text); }
.site-foot .legal { display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap; padding-top: 18px; border-top: 1px solid var(--line); color: var(--muted); font-size: 13px; }

/* ---- Settings: toggle switch + rows ---- */
.setting-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.switch { position: relative; display: inline-flex; cursor: pointer; flex: 0 0 auto; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .track { width: 46px; height: 26px; border-radius: 999px; background: var(--line-strong); transition: background .18s ease; position: relative; }
.switch .track::after { content: ""; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.3); transition: transform .18s ease; }
.switch input:checked + .track { background: var(--brand); }
.switch input:checked + .track::after { transform: translateX(20px); }
.switch input:disabled + .track { opacity: .5; cursor: not-allowed; }

/* ---- Gateways: per-job cron switches ---- */
.cron-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; }
.cron-head-text { flex: 1 1 auto; min-width: 0; }
.cron-master { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 6px; }
.cron-master-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); }
.cron-jobs { margin-top: 16px; border-top: 1px solid var(--line); }
.cron-job { padding: 14px 0; border-bottom: 1px solid var(--line); }
.cron-job:last-child { border-bottom: 0; padding-bottom: 0; }
.cron-job .cell-sub { margin-top: 3px; font-size: 12.5px; }
.cron-job .badge { margin-left: 8px; vertical-align: middle; }
/* Master switch off: the per-gateway switches still save, but nothing runs —
   so show them as inert rather than pretending they're active. */
.cron-jobs.is-paused { opacity: .5; }

/* Verify-email banner */
.verify-banner { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; background: var(--warn-soft); color: var(--warn); border: 1px solid color-mix(in srgb, var(--warn) 25%, transparent); border-radius: var(--radius-sm); padding: 12px 16px; margin-bottom: 18px; font-weight: 600; font-size: 14px; }
.verify-banner .vb-ic { flex: 0 0 auto; }
.verify-banner .vb-msg { flex: 1 1 auto; min-width: 160px; }
.verify-banner button { flex: 0 0 auto; border: 1px solid currentColor; background: transparent; color: inherit; font: inherit; font-weight: 700; font-size: 13px; padding: 6px 14px; border-radius: 999px; cursor: pointer; }
.verify-banner button:hover { background: color-mix(in srgb, var(--warn) 12%, transparent); }

/* PIN modal */
.pin-modal { position: fixed; inset: 0; z-index: 70; display: none; align-items: center; justify-content: center; padding: 20px; background: rgba(4,20,18,.5); backdrop-filter: blur(3px); }
.pin-modal.show { display: flex; }
.pin-modal .pin-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow-lg); padding: 24px; width: min(360px, 100%); text-align: center; }
.pin-modal .pin-input { letter-spacing: .5em; text-align: center; font-size: 22px; font-weight: 700; margin: 14px 0; }
.pin-modal .pin-input.masked { -webkit-text-security: disc; text-security: disc; }
.pin-modal .pin-actions { display: flex; gap: 10px; }

/* Gateways · provider settings accordion */
.gw-group { border: 1px solid var(--border); border-radius: 12px; margin-top: 12px; overflow: hidden; background: var(--surface); }
.gw-group + .gw-group { margin-top: 10px; }
.gw-group > summary { cursor: pointer; padding: 13px 16px; font-weight: 600; list-style: none; display: flex; justify-content: space-between; align-items: center; gap: 12px; transition: background .15s ease; }
.gw-group > summary::-webkit-details-marker { display: none; }
.gw-group > summary:hover { background: var(--surface-2); }
.gw-group[open] > summary { border-bottom: 1px solid var(--border); }
.gw-group .gw-title .muted { font-weight: 400; font-size: 12px; }
.gw-group .gw-meta { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); flex: 0 0 auto; }
.gw-form { padding: 16px; }
.gw-hint { font-size: 12px; margin: 12px 0 0; }
.gw-hint a { color: var(--brand-ink); }
.gw-hint code { font-size: 11px; }

/* ============================================================
   Signed-in app shell — dashboard design system
   ------------------------------------------------------------
   Scoped to .shell on purpose. The public landing page keeps its
   own lighter teal; everything behind the login uses the deeper,
   flatter palette below (hairline borders and mint fills instead
   of shadows, pill controls, 18px cards). The TYPEFACE is shared:
   only the colours change across that boundary, not the letters.
   Colours are the sRGB equivalents of the reference's oklch set.
   ============================================================ */
/* .shell = signed-in app · .auth = sign-in/register/reset/404 · .docs = API
   reference. Everything except the marketing landing page (.lp). */
.shell, .auth, .docs {
  --brand: #0d6b64;        /* primary fill — deeper than the marketing teal */
  --brand-600: #0a5751;
  --brand-700: #084640;
  --brand-800: #063a35;
  --accent: #17a394;
  --brand-text: #0d6b64;

  --heading: #0e302c;
  --ink: #16403a;
  --muted: #5f7d78;

  --bg: #f5fbf9;
  --surface: #ffffff;
  --surface-2: #f1f9f6;
  --surface-3: #e7f6f1;   /* mint fill — quick actions, icon badges, pills */
  --line: #e3efeb;
  --line-strong: #d3e7e1;

  --radius: 18px;
  --radius-sm: 12px;
  --radius-lg: 22px;
  /* Near-flat: the design separates with hairlines, not elevation. */
  --shadow-sm: 0 1px 2px rgba(14, 48, 44, .04);
  --shadow: 0 2px 8px rgba(14, 48, 44, .05);
  --shadow-lg: 0 12px 32px rgba(14, 48, 44, .10);
  --ring: 0 0 0 4px rgba(13, 107, 100, .15);

  /*
   * ONE typeface for the whole product, from --font.
   *
   * This used to pin the signed-in app to Plus Jakarta Sans while the landing
   * page used Outfit. Two families meant the type visibly changed the moment a
   * customer signed in, which reads as the page still loading rather than as a
   * design. --font already carries the flag fallback ("Twemoji Country Flags"
   * first, because Windows ships no regional-indicator glyphs), so pointing at
   * it keeps that behaviour and leaves one place to change the typeface.
   */
  font-family: var(--font);
  background: var(--bg);
}
[data-theme="dark"] .shell, [data-theme="dark"] .auth, [data-theme="dark"] .docs {
  --brand: #2fb3a3;
  --brand-600: #46c4b4;
  --brand-700: #17a394;
  --brand-800: #0d6b64;
  --accent: #5eead4;
  --brand-text: #6fdccb;

  --heading: #eafaf7;
  --ink: #dbf0ec;
  --muted: #8fb0ab;

  --bg: #0b1d1b;
  --surface: #102724;
  --surface-2: #16322e;
  --surface-3: #1c3f3a;
  --line: #22423d;
  --line-strong: #2d5751;
}

/* ---- sidebar ---- */
.shell .sidebar { background: var(--bg); border-right: 1px solid var(--line); padding: 22px 16px; }
.shell .sidebar .brand { gap: 11px; margin-bottom: 26px; font-size: 19px; font-weight: 800; color: var(--heading); }
/* Circular badge, not the rounded square used on the marketing site. */
.shell .sidebar .brand-mark { width: 38px; height: 38px; border-radius: 50%; background: var(--brand); box-shadow: none; font-size: 16px; }
.shell .sidebar nav { gap: 3px; }
.shell .sidebar nav a, .shell .sidebar nav button {
  border-radius: 999px; padding: 11px 16px; font-size: 14.5px; font-weight: 500; color: var(--ink); }
.shell .sidebar nav a:hover, .shell .sidebar nav button:hover { background: var(--surface-3); color: var(--brand-text); }
.shell .sidebar nav a.active { background: var(--brand); color: #fff; font-weight: 600; box-shadow: none; }
.shell .sidebar .nav-label { margin: 18px 0 6px; padding-left: 16px; font-size: 11px; letter-spacing: .1em; }
.shell .sidebar .nav-bottom form button { width: 100%; justify-content: flex-start; border: 1px solid var(--line);
  background: var(--surface); border-radius: 999px; }
/* Bottom pills in the admin sidebar ("Back to app" / "Back to website"),
   mirroring the reference's bottom-of-rail button. */
.shell .side-back { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; padding: 11px 16px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--surface);
  color: var(--muted); font-size: 13.5px; font-weight: 600; }
.shell .side-back:hover { color: var(--brand-text); border-color: var(--brand); background: var(--surface-3); }
/* Only the back-arrow flips — the globe next to "Back to website" must not. */
.shell .side-back.flip-ic .icon { transform: rotate(180deg); }

/* ---- topbar ---- */
.shell .topbar { background: var(--surface); border-bottom: 1px solid var(--line); backdrop-filter: none; padding: 15px 30px; }
.shell .topbar .search input { background: var(--surface-2); border-color: var(--line); }
.shell .tb-greet { font-size: 17px; font-weight: 700; color: var(--heading);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
/* Below this the greeting plus the wallet chip, theme toggle, bell and avatar
   no longer fit — the greeting is the expendable one. */
@media (max-width: 720px) {
  .shell .tb-greet { display: none; }
  .shell .topbar { padding: 12px 16px; }
  .shell .topbar .right.profile { gap: 8px; min-width: 0; }
}

/* ---- surfaces ---- */
.shell .content { padding: 26px 30px 40px; }
.shell .panel, .shell .card, .shell .stat, .shell .service {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: none; }
.shell .page-head h1 { font-size: 30px; font-weight: 800; letter-spacing: -.02em; color: var(--heading); margin: 0 0 4px; }
.shell .page-head p { margin: 0; color: var(--muted); font-size: 14.5px; }

/* ---- controls ---- */
.shell .btn { border-radius: 999px; font-weight: 600; box-shadow: none; }
.shell .btn:hover { box-shadow: none; transform: none; background: var(--brand-600); }
.shell .btn.ghost { border-color: var(--line-strong); }
.shell .btn.ghost:hover { background: var(--surface-3); border-color: var(--brand); }
.shell .field input, .shell .field select, .shell input.field, .shell select.field {
  border-radius: 12px; border-color: var(--line-strong); }

/* ---- tables ---- */
.shell table.data th { background: transparent; font-size: 11.5px; font-weight: 700; letter-spacing: .07em; color: var(--muted); }
.shell table.data th, .shell table.data td { padding: 15px 18px; }
.shell table.data tr.clickable:hover td { background: var(--surface-2); }

/* ---- status pills ---- */
.shell .badge { border-radius: 999px; padding: 5px 12px; font-size: 12px; font-weight: 600; text-transform: capitalize; }
.shell .badge.successful, .shell .badge.success { background: #dff3e9; color: #14795a; }
.shell .badge.pending { background: #fbf0dc; color: #92660f; }
.shell .badge.failed, .shell .badge.reversed { background: #fde8e4; color: #b93c28; }
[data-theme="dark"] .shell .badge.successful, [data-theme="dark"] .shell .badge.success { background: #10352a; color: #5fd8a6; }
[data-theme="dark"] .shell .badge.pending { background: #38290d; color: #e7b45a; }
[data-theme="dark"] .shell .badge.failed, [data-theme="dark"] .shell .badge.reversed { background: #3a1c17; color: #f0917c; }

/* ---- KPI row ---- */
.kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 16px; }
.kpi { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px 22px; }
.kpi .k-label { font-size: 13.5px; color: var(--muted); margin-bottom: 8px; }
.kpi .k-value { font-size: 26px; font-weight: 800; letter-spacing: -.02em; color: var(--heading); line-height: 1.15; }
.kpi .k-sub { margin-top: 6px; font-size: 12.5px; color: var(--muted); }
.kpi .k-sub.up { color: #14795a; }

/* ---- balance panel + quick actions ---- */
.bal-panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 22px; }
.bal-panel .b-label { font-size: 13.5px; color: var(--muted); }
.bal-panel .b-value { font-size: 34px; font-weight: 800; letter-spacing: -.025em; color: var(--heading); margin: 4px 0 16px; }
.bal-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 20px; }
.qa-title { font-size: 14px; font-weight: 700; color: var(--heading); margin: 0 0 10px; }
.qa-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.qa { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px; min-height: 74px;
  padding: 12px 6px; border-radius: 14px; background: var(--surface-3); color: var(--heading);
  font-size: 12.5px; font-weight: 600; text-align: center; transition: background .14s ease, color .14s ease; }
.qa:hover { background: var(--brand); color: #fff; }
.qa .icon { color: var(--brand-text); }
.qa:hover .icon { color: #fff; }
/* "Intl" marker — the tile is position:relative so the pill can sit in its
   corner without taking part in the centred column layout. */
.qa { position: relative; }
.qa-intl { position: absolute; top: 5px; right: 5px;
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px 6px 2px 5px; border-radius: 999px;
  background: var(--surface); color: var(--brand-text);
  font-size: 9.5px; font-weight: 800; letter-spacing: .02em; line-height: 1.4; }
.qa-intl svg { width: 10px; height: 10px; }
.qa:hover .qa-intl { background: rgba(255, 255, 255, .92); color: var(--brand); }

/* ---- activity list (recent transactions) ---- */
.act-list { display: flex; flex-direction: column; }
.act { display: flex; align-items: center; gap: 14px; padding: 15px 0; border-top: 1px solid var(--line); color: var(--ink); }
.act:first-child { border-top: 0; }
.act-ic { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%; display: grid; place-items: center;
  background: var(--surface-3); color: var(--brand-text); }
.act-main { flex: 1 1 auto; min-width: 0; }
/* Truncate rather than wrap. Live provider catalogues return long plan names
   ("Airtel Nigeria Data Bundle 1.5GB 30 Days"), and letting one wrap pushed the
   row taller than its neighbours and broke the rhythm of the list. The sub-line
   below already does this; the title was missing it. */
.act-main b { display: block; font-size: 14.5px; font-weight: 700; color: var(--heading);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.act-main small { display: block; font-size: 12.5px; color: var(--muted); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.act-right { flex: 0 0 auto; text-align: right; }
.act-right b { display: block; font-size: 14.5px; font-weight: 700; color: var(--heading); }
.act-right b.in { color: #14795a; }
.act-right small { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }

/* ---- auth pages (sign in / register / reset / 404) ---- */
.auth { background: var(--bg); }
.auth .auth-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  box-shadow: var(--shadow); padding: 32px 30px; }
.auth .brand { display: inline-flex; align-items: center; gap: 11px; margin-bottom: 20px;
  font-weight: 800; font-size: 19px; color: var(--heading); }
.auth .brand-mark { width: 38px; height: 38px; border-radius: 50%; background: var(--brand); box-shadow: none; }
.auth h1 { font-size: 26px; font-weight: 800; letter-spacing: -.02em; color: var(--heading); margin: 0 0 6px; }
.auth > .auth-card > p { color: var(--muted); font-size: 14.5px; margin: 0 0 22px; }
.auth .field input, .auth .field select { border-radius: 12px; border-color: var(--line-strong); background: var(--surface-2); }
.auth .field input:focus { background: var(--surface); }
.auth .btn { border-radius: 999px; box-shadow: none; }
.auth .btn:hover { box-shadow: none; transform: none; background: var(--brand-600); }

/* ---- API reference ---- */
.docs { background: var(--bg); }
/* Cap the measure on prose only. The wider shell exists for tables, code
   samples and the endpoint index — those still fill the column, which is the
   whole point — but a 140-character paragraph is harder to read, not easier. */
.docs p, .docs li { max-width: 82ch; }
.docs pre, .docs table, .docs .doc-table { max-width: none; }
.docs .panel, .docs .card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: none; }
.docs .btn { border-radius: 999px; box-shadow: none; }
.docs .btn:hover { box-shadow: none; transform: none; }
.docs .doc-table th { background: transparent; font-size: 11.5px; letter-spacing: .07em; color: var(--muted); }
.docs .doc-table th, .docs .doc-table td { border-bottom: 1px solid var(--line); }
.docs .req { color: #b93c28; }
.docs .opt { color: var(--muted); }

/* ---- wallet: balance beside the funding panel ---- */
/* The balance sits narrower than the funding panel: it is one number, while the
   panel carries the account, the note and an action. Equal columns gave the
   balance a large empty field and made the page look unfinished. */
.wallet-split { display: grid; grid-template-columns: minmax(0, .78fr) minmax(0, 1.22fr); gap: 18px; align-items: stretch; }
.wallet-split > .wallet-card { margin: 0; display: flex; flex-direction: column; justify-content: center; }
.wallet-split > .panel { margin: 0; display: flex; flex-direction: column; }
@media (max-width: 1000px) { .wallet-split { grid-template-columns: minmax(0, 1fr); } }

/* ---------- wallet: dedicated account ---------- */
.va-title { margin: 0 0 16px; font-size: 16px; font-weight: 700; color: var(--heading); letter-spacing: -.01em; }

/* The account number is the point of the panel, so it gets the room. Framed
   with a hairline and a tinted ground rather than a nested card with its own
   shadow, which read as a second panel inside the first. */
.va-card { border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); padding: 16px 18px; }
.va-card + .va-card { margin-top: 10px; }
.va-bank { display: block; font-size: 11.5px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); }
/* Copy sits beside the number, not pushed to the far edge of the card. Across
   a wide panel space-between put a hand's width between the button and the
   thing it copies, so it stopped reading as belonging to it. */
.va-num-row { display: flex; align-items: center; gap: 14px; margin: 6px 0 4px; flex-wrap: wrap; }
/* tabular-nums so the digits sit on an even rhythm, like an account number
   printed on a statement rather than prose. */
.va-num { font-size: clamp(26px, 3.4vw, 32px); font-weight: 800; letter-spacing: .06em; color: var(--heading);
  font-variant-numeric: tabular-nums; line-height: 1.1; }
.va-name { font-size: 13px; color: var(--muted); }
.va-copy { flex: 0 0 auto; width: 38px; height: 38px; display: grid; place-items: center; cursor: pointer;
  border: 1px solid var(--line-strong); border-radius: 11px; background: var(--surface); color: var(--muted);
  transition: color .14s ease, border-color .14s ease, background .14s ease; }
.va-copy:hover { color: var(--brand-text); border-color: var(--brand); background: var(--surface-3); }

.va-note { margin: 14px 0 0; font-size: 13px; line-height: 1.55; color: var(--muted); }
/* The fee is a fact worth stating once, plainly — not a parenthetical buried
   mid-sentence, and not a warning. */
.va-fee { display: inline-block; margin-left: 2px; padding: 1px 8px; border-radius: 999px;
  background: var(--surface-3); color: var(--brand-text); font-size: 12px; font-weight: 600; }
.va-held { margin: 0 0 14px; font-size: 12.5px; color: var(--muted); display: flex; align-items: center; gap: 6px; }
.va-held .icon { color: var(--brand); }

/* A quiet text action, not a third button competing with Copy and the CTA. */
.va-check { margin-top: auto; padding: 12px 0 0; display: inline-flex; align-items: center; gap: 7px; align-self: flex-start;
  background: none; border: 0; cursor: pointer; font: inherit; font-size: 12.5px; font-weight: 600; color: var(--muted); }
.va-check:hover { color: var(--brand-text); }
.va-check:disabled { opacity: .6; cursor: default; }

.va-form { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; align-items: end; margin-top: 18px; }
.va-form .btn { grid-column: 1 / -1; justify-self: start; }

/* Coming-soon services get the mint hero treatment rather than a bare card. */
.shell .qa.is-soon { opacity: .72; }
.shell .qa.is-soon:hover { opacity: 1; }

/* ---- settings: single centred column, as in the reference ---- */
.shell .content.settings-col > * { width: min(820px, 100%); margin-inline: auto; }

/* ---- dashboard split + sparkline ---- */
.dash-split { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 18px; align-items: start; }
.spark-wrap { margin-top: 18px; }
.spark { display: block; width: 100%; height: 170px; overflow: visible; }
.spark-grid { stroke: var(--line); stroke-width: 1; stroke-dasharray: 4 5; vector-effect: non-scaling-stroke; }
/* non-scaling-stroke keeps the line even, since preserveAspectRatio="none"
   stretches the viewBox horizontally to whatever width the card is. */
.spark-line { fill: none; stroke: var(--brand); stroke-width: 2.5; stroke-linecap: round;
  stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.spark-axis { display: flex; justify-content: space-between; margin-top: 8px; font-size: 12px; color: var(--muted); }

/* ---- fraud alerts: injection payload preview ---- */
.fraud-alerts .cell-sub code { font-size: 11.5px; background: var(--surface-3); color: var(--brand-text);
  padding: 1px 6px; border-radius: 6px; word-break: break-all; }
.fraud-alerts .cell-sub.payload { margin-top: 4px; }
.fraud-alerts .cell-sub.payload code { display: inline-block; max-width: 100%; color: var(--err);
  background: var(--err-soft); }

/* ---- virtual cards ---- */
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap: 18px; }
.vcard-wrap { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; }
.vcard { position: relative; border-radius: 16px; padding: 20px; color: #fff; overflow: hidden;
  background: linear-gradient(135deg, var(--brand-700), var(--brand) 70%, var(--accent)); min-height: 168px;
  display: flex; flex-direction: column; box-shadow: 0 10px 26px rgba(13, 107, 100, .28); }
.vcard.is-frozen, .vcard.is-dead { filter: saturate(.5) brightness(.9); }
.vcard-top { display: flex; justify-content: space-between; align-items: center; }
.vcard-label { font-weight: 700; font-size: 14.5px; }
.vcard-brand { font-weight: 800; letter-spacing: .06em; font-size: 15px; font-style: italic; opacity: .95; }
.vcard-pan { margin-top: 26px; font-size: 19px; letter-spacing: .12em; font-variant-numeric: tabular-nums; }
.vcard-foot { margin-top: auto; padding-top: 16px; display: flex; justify-content: space-between; align-items: flex-end; }
.vcard-cap { display: block; font-size: 10px; text-transform: uppercase; letter-spacing: .09em; opacity: .8; }
.vcard-foot b { font-size: 20px; font-weight: 800; letter-spacing: -.01em; }
.vcard-exp { font-variant-numeric: tabular-nums; font-size: 13px; opacity: .9; }
.vcard-flag { position: absolute; top: 12px; right: 12px; background: rgba(0,0,0,.32); color: #fff;
  font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px; }
.vcard-actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }
.vcard-actions .btn.sm { flex: 1; min-width: 84px; }
.vcard-note { display: flex; align-items: center; gap: 7px; margin-top: 10px; padding: 8px 11px; border-radius: 10px;
  background: var(--warn-soft); color: var(--warn); font-size: 12px; font-weight: 600; }
.vcard-note .icon { flex: 0 0 auto; }
.vcard-reveal { margin-top: 12px; border-top: 1px solid var(--line); padding-top: 12px; }
.vcard-reveal .rv { display: flex; justify-content: space-between; align-items: center; padding: 4px 0; font-size: 13px; }
.vcard-reveal .rv span { color: var(--muted); }
.vcard-reveal .rv code { font-size: 13.5px; color: var(--heading); background: var(--surface-3); padding: 2px 8px; border-radius: 6px; letter-spacing: .04em; }
.vcard-reveal .rv-note { margin-top: 8px; font-size: 11.5px; color: var(--warn); }
.cost-line { font-size: 13px; color: var(--muted); }
.cost-line strong { color: var(--heading); }

/* ---- card create / fund modal ---- */
.pin-modal .pin-card.card-modal { width: min(440px, 100%); max-height: 88vh; padding: 0; text-align: left;
  display: flex; flex-direction: column; overflow: hidden; }
.card-modal.cm-narrow { width: min(360px, 100%); }
.card-modal .cm-head { padding: 20px 22px 14px; border-bottom: 1px solid var(--line); }
.card-modal .cm-head h3 { margin: 0 0 4px; font-size: 18px; color: var(--heading); }
.card-modal .cm-head p { margin: 0; font-size: 13px; line-height: 1.5; color: var(--muted); }
/* Two-column grid; the form's own gap is the ONLY spacing — .field margins are
   zeroed here so labels don't double up against the grid. */
.card-modal .cm-body { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 12px; padding: 18px 22px; overflow-y: auto; }
.card-modal .cm-body .field { margin: 0; }
/* Any child may span, not just .field — the identity notice is a plain div and
   was silently left at half width by the narrower selector. */
.card-modal .cm-body .span-2 { grid-column: 1 / -1; }
.card-modal .cm-body .field > span { font-size: 12px; margin-bottom: 5px; }
.card-modal .cm-body .field > span .opt { font-style: normal; font-weight: 500; color: var(--muted); font-size: 11px; }
.card-modal .cm-body .field input, .card-modal .cm-body .field select { min-height: 42px; }
.card-modal .cm-sec { grid-column: 1 / -1; margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--line);
  font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--muted); }
.card-modal .cm-cost { font-size: 13px; color: var(--muted); }
.card-modal .cm-cost strong { color: var(--heading); }
.card-modal .cm-actions { display: flex; gap: 10px; padding: 14px 22px; border-top: 1px solid var(--line); background: var(--surface-2); }
.card-modal .cm-actions .btn { flex: 1; }
/* Identity notice inside the card modal. Icon in its own column so the text
   wraps as a block beside it rather than round it, and margin-bottom cleared
   because the grid's gap already spaces it. */
.card-modal .cm-note { display: flex; align-items: flex-start; gap: 10px; margin: 0;
  font-size: 13px; line-height: 1.5; }
.card-modal .cm-note > svg { flex: 0 0 auto; margin-top: 1px; }
.card-modal .cm-note > span { min-width: 0; }
.card-modal .cm-note strong { font-weight: 800; }
.card-modal .cm-note a { text-decoration: underline; color: inherit; }
.card-modal .cm-note-ok { padding: 11px 14px; border-radius: var(--radius-sm);
  background: var(--ok-soft); color: var(--ok); }

@media (max-width: 460px) { .card-modal .cm-body { grid-template-columns: 1fr; } }

/* ---- filter chips ---- */
.chips { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }
.chip { padding: 9px 18px; border-radius: 999px; border: 1px solid var(--line-strong); background: var(--surface);
  color: var(--ink); font-size: 13.5px; font-weight: 600; cursor: pointer; }
.chip:hover { border-color: var(--brand); color: var(--brand-text); }
.chip.active { background: var(--brand); border-color: var(--brand); color: #fff; }

@media (max-width: 1000px) {
  .dash-split { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 640px) {
  .shell .content { padding: 18px 16px 90px; }
  .bal-actions { grid-template-columns: 1fr; }
  .qa-grid { grid-template-columns: repeat(2, 1fr); }
  .shell .page-head h1 { font-size: 24px; }
}

/* ============================================================
   Landing page (.lp)
   Marketing-only styles. Scoped under .lp so nothing here can
   reach the signed-in app or admin, which share this stylesheet.
   Colour comes entirely from the tokens at the top of the file,
   so light and dark both follow the brand automatically.
   ============================================================ */
/* The shell width. It used to be a flat min(1180px, 92vw), which meant the page
   was pixel-identical from 1366 all the way to 2560 — at 1920 that left 370px
   of dead gutter each side and at 2560 the design used under half the screen.
   It now steps up on genuinely large displays. Readability is protected in the
   hero copy itself (max-width in ch), so the extra width lands on the layout,
   not on 120-character lines. */
.lp { --lp-w: min(1280px, 92vw); }
@media (min-width: 1600px) { .lp { --lp-w: min(1400px, 90vw); } }
@media (min-width: 1920px) { .lp { --lp-w: min(1520px, 88vw); } }
.lp-nav-inner, .lp-hero-inner, .lp-trust, .lp-pop { width: var(--lp-w); margin-inline: auto; }
.lp .site-foot { width: var(--lp-w); margin-inline: auto; }

/* extra button modifiers the landing needs */
.btn.lg { min-height: 50px; padding: 13px 26px; font-size: 15px; }
.btn.soft { background: var(--surface-3); color: var(--brand-text); border-color: transparent; box-shadow: none; }
.btn.soft:hover { background: var(--brand); color: var(--on-brand); box-shadow: var(--shadow-sm); }
.btn.on-teal { background: var(--brand); color: var(--on-brand); }

/* ---------- nav ---------- */
.lp-nav { position: sticky; top: 0; z-index: 40; background: var(--surface); border-bottom: 1px solid var(--line); }
.lp-nav-inner { display: flex; align-items: center; gap: 20px; min-height: 68px; }
/* .brand has no base rule outside .nav/.site-foot, and .brand-mark is a grid
   (block-level) — without this the mark and the wordmark stack vertically. */
.lp-nav .brand { display: inline-flex; align-items: center; gap: 10px; flex: 0 0 auto;
  white-space: nowrap; font-weight: 800; font-size: 18px; color: var(--heading); }
.lp-menu { display: flex; align-items: center; gap: 4px; margin-inline: auto; }
.lp-menu-link { position: relative; display: inline-flex; align-items: center; gap: 5px; padding: 10px 14px; border-radius: 10px;
  font-weight: 600; font-size: 14.5px; color: var(--ink); background: none; border: 0; cursor: pointer; font-family: inherit; }
.lp-menu-link:hover { color: var(--brand-text); background: var(--surface-2); }
.lp-menu-link.is-active { color: var(--brand-text); }
/* Underline marks the current page — matches the reference's active tab. */
.lp-menu-link.is-active::after { content: ""; position: absolute; left: 14px; right: 14px; bottom: -14px; height: 2px; background: var(--brand); border-radius: 2px; }
.lp-nav-actions { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
/* Hidden by default. On desktop the hero button is the way in and the Create
   free account panel is the way to join, so auth links here would only crowd
   the menu bar. The narrow breakpoint reveals them inside the open burger
   menu, which is a phone's only navigation. */
.lp-menu-auth { display: none; }

/* Hero picker scope toggle (International / Nigeria) + its footnote. */
.lp-scope { margin-bottom: 14px; width: 100%; }
.lp-scope button { flex: 1; }
.lp-quote-note { margin: 10px 0 0; text-align: center; font-size: 12px; color: var(--muted); }
.lp-quote-h { display: flex; align-items: center; gap: 8px; margin: 0 0 14px; font-size: 17px; }
.lp-total { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  margin: 4px 0 12px; padding-top: 12px; border-top: 1px solid var(--line); font-size: 13.5px; color: var(--muted); }
.lp-total strong { font-size: 18px; color: var(--heading); }
.lp-burger { display: none; border: 1px solid var(--line); background: var(--surface); color: var(--heading); border-radius: 12px; width: 42px; height: 42px; place-items: center; cursor: pointer; }

/* Pay Bills dropdown */
.lp-drop { position: relative; }
.lp-drop-btn .icon { transition: transform .16s ease; }
.lp-drop.open .lp-drop-btn { color: var(--brand-text); background: var(--surface-2); }
.lp-drop.open .lp-drop-btn .icon { transform: rotate(180deg); }
.lp-drop-panel { display: none; position: absolute; top: calc(100% + 12px); left: 50%; transform: translateX(-50%);
  width: 440px; padding: 10px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); grid-template-columns: 1fr 1fr; gap: 2px; }
.lp-drop.open .lp-drop-panel { display: grid; }
.lp-drop-panel a { display: flex; align-items: flex-start; gap: 11px; padding: 10px 11px; border-radius: 12px; color: var(--ink); }
.lp-drop-panel a:hover { background: var(--surface-2); }
.lp-drop-panel b { display: block; font-size: 14px; color: var(--heading); }
.lp-drop-panel small { display: block; font-size: 11.5px; color: var(--muted); line-height: 1.45; margin-top: 2px; }
.lp-drop-ic { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; background: var(--surface-3); color: var(--brand-text); }
/* "Intl" chip on the rows that are not Nigeria-only. inline-flex with a raised
   baseline so it rides alongside the label without stretching the row. */
.lp-drop-intl { display: inline-flex; align-items: center; gap: 3px; margin-left: 6px;
  padding: 1px 6px 1px 5px; border-radius: 999px; font-size: 9.5px; font-weight: 700;
  letter-spacing: .03em; text-transform: uppercase; vertical-align: 1px;
  background: var(--brand-soft, var(--surface-3)); color: var(--brand-text); }
.lp-drop-intl svg { width: 10px; height: 10px; }

/* ---------- hero ---------- */
/* No overflow:hidden here. It used to clip the decorative globe, but it also
   clipped the "Pay a bill" listboxes at the hero's bottom edge — a 12-DisCo or
   19-platform list got cut in half. Nothing in the hero overflows horizontally
   (the globe is display:none below 1140px), so clipping buys nothing. */
.lp-hero { position: relative; padding: 58px 0 44px; overflow: hidden;
  background: linear-gradient(170deg, var(--surface-2) 0%, var(--bg) 62%); }

/* Ambient Floating Glass Bubbles */
.lp-bubbles { position: absolute; inset: 0; overflow: hidden; pointer-events: none; z-index: 0; }
.lp-bubble {
  position: absolute; border-radius: 50%; pointer-events: none; will-change: transform, opacity;
  background: radial-gradient(circle at 35% 30%, rgba(255, 255, 255, 0.48) 0%, rgba(55, 196, 179, 0.22) 32%, rgba(13, 107, 100, 0.10) 65%, rgba(6, 58, 53, 0.03) 100%);
  border: 1px solid rgba(255, 255, 255, 0.42);
  box-shadow: 0 10px 32px rgba(13, 107, 100, 0.12), inset 0 0 16px rgba(255, 255, 255, 0.26);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
}
.lp-bubble::before {
  content: ""; position: absolute; top: 14%; left: 20%; width: 28%; height: 20%;
  background: radial-gradient(ellipse at center, rgba(255, 255, 255, 0.85) 0%, rgba(255, 255, 255, 0) 80%);
  border-radius: 50%; transform: rotate(-35deg);
}
.lp-bubble::after {
  content: ""; position: absolute; bottom: 12%; right: 18%; width: 14%; height: 10%;
  background: radial-gradient(ellipse at center, rgba(255, 255, 255, 0.5) 0%, rgba(255, 255, 255, 0) 80%);
  border-radius: 50%;
}

.lp-b-1 { width: 130px; height: 130px; top: 6%; left: 3%; animation: lpFloat1 22s ease-in-out infinite; opacity: 0.85; }
.lp-b-2 { width: 75px; height: 75px; top: 52%; left: 10%; animation: lpFloat2 26s ease-in-out infinite -4s; opacity: 0.75; }
.lp-b-3 { width: 210px; height: 210px; top: -2%; right: 5%; animation: lpFloat3 30s ease-in-out infinite -2s; opacity: 0.6; }
.lp-b-4 { width: 60px; height: 60px; top: 68%; right: 26%; animation: lpFloat4 19s ease-in-out infinite -7s; opacity: 0.8; }
.lp-b-5 { width: 95px; height: 95px; top: 20%; left: 40%; animation: lpFloat1 25s ease-in-out infinite -11s; opacity: 0.7; }
.lp-b-6 { width: 44px; height: 44px; top: 14%; right: 34%; animation: lpFloat2 17s ease-in-out infinite -5s; opacity: 0.85; }
.lp-b-7 { width: 160px; height: 160px; bottom: 2%; left: 26%; animation: lpFloat3 28s ease-in-out infinite -9s; opacity: 0.65; }
.lp-b-8 { width: 50px; height: 50px; top: 80%; left: 5%; animation: lpFloat4 21s ease-in-out infinite -3s; opacity: 0.75; }
.lp-b-9 { width: 85px; height: 85px; top: 38%; right: 2%; animation: lpFloat1 24s ease-in-out infinite -14s; opacity: 0.8; }
.lp-b-10 { width: 34px; height: 34px; top: 86%; right: 12%; animation: lpFloat2 16s ease-in-out infinite -1s; opacity: 0.9; }

[data-theme="dark"] .lp-bubble {
  background: radial-gradient(circle at 35% 30%, rgba(143, 232, 219, 0.35) 0%, rgba(55, 196, 179, 0.18) 32%, rgba(13, 107, 100, 0.08) 65%, rgba(4, 30, 28, 0.02) 100%);
  border: 1px solid rgba(143, 232, 219, 0.32);
  box-shadow: 0 12px 36px rgba(15, 118, 110, 0.28), inset 0 0 18px rgba(143, 232, 219, 0.24);
}

@keyframes lpFloat1 {
  0% { transform: translate3d(0, 0, 0) scale(1) rotate(0deg); }
  25% { transform: translate3d(22px, -32px, 0) scale(1.05) rotate(40deg); }
  50% { transform: translate3d(-16px, -58px, 0) scale(0.96) rotate(90deg); }
  75% { transform: translate3d(26px, -24px, 0) scale(1.04) rotate(135deg); }
  100% { transform: translate3d(0, 0, 0) scale(1) rotate(180deg); }
}

@keyframes lpFloat2 {
  0% { transform: translate3d(0, 0, 0) scale(1) rotate(0deg); }
  30% { transform: translate3d(-28px, 24px, 0) scale(0.95) rotate(-35deg); }
  60% { transform: translate3d(18px, -40px, 0) scale(1.06) rotate(55deg); }
  85% { transform: translate3d(-12px, -15px, 0) scale(0.98) rotate(105deg); }
  100% { transform: translate3d(0, 0, 0) scale(1) rotate(180deg); }
}

@keyframes lpFloat3 {
  0% { transform: translate3d(0, 0, 0) scale(1); }
  33% { transform: translate3d(35px, -45px, 0) scale(1.07); }
  66% { transform: translate3d(-25px, -22px, 0) scale(0.93); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}

@keyframes lpFloat4 {
  0% { transform: translate3d(0, 0, 0) scale(1); }
  40% { transform: translate3d(-22px, -36px, 0) scale(1.05); }
  70% { transform: translate3d(30px, 18px, 0) scale(0.96); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}

/* Columns are copy | purchase card | globe. The card was a fixed 290px, which
   made the one element on the page that takes money the narrowest column on the
   screen — and it truncated its own longer option labels. It now grows with the
   viewport; the decorative globe is capped tighter, since it earns less. */
.lp-hero-inner { position: relative; z-index: 2; display: grid; gap: 34px; align-items: center;
  grid-template-columns: minmax(0, 1fr) clamp(290px, 23vw, 372px) clamp(300px, 21vw, 340px); }
.lp-hero-copy h1 { font-size: clamp(34px, 4.1vw, 58px); line-height: 1.1; letter-spacing: -.02em; margin: 0 0 16px; color: var(--heading); }
.lp-hero-copy h1 .accent { color: var(--brand-text); }
.lp-hero-copy p { font-size: 16.5px; line-height: 1.65; color: var(--muted); max-width: 46ch; margin: 0 0 26px; }
.lp-hero-cta { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.lp-how { display: inline-flex; align-items: center; gap: 11px; font-weight: 600; font-size: 14.5px; color: var(--heading); }
.lp-how:hover { color: var(--brand-text); }
.lp-play { width: 38px; height: 38px; border-radius: 50%; display: grid; place-items: center;
  border: 1.5px solid var(--brand); color: var(--brand-text); }
.lp-play .icon path { fill: currentColor; }

/* hero "Pay a bill" card */
.lp-quote { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 22px; box-shadow: var(--shadow-lg); }
.lp-quote h3 { margin: 0 0 16px; font-size: 18px; color: var(--heading); }
.lp-f { display: block; margin-bottom: 13px; }
.lp-f > span:first-child { display: block; font-size: 11.5px; font-weight: 600; color: var(--muted); margin-bottom: 5px; }
.lp-f-in { display: flex; align-items: center; gap: 9px; padding: 0 12px; height: 46px;
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm); background: var(--surface); color: var(--muted); }
.lp-f-in:focus-within { border-color: var(--brand); box-shadow: var(--ring); }
.lp-f-in .icon:first-child { flex: 0 0 auto; }
.lp-f-ic { flex: 0 0 auto; display: inline-flex; }
.lp-f-in select, .lp-f-in input { flex: 1 1 auto; min-width: 0; border: 0; background: none; outline: none;
  font-family: inherit; font-size: 14.5px; font-weight: 500; color: var(--heading); appearance: none; }
.lp-f-in input::placeholder { color: var(--muted); font-weight: 400; }
.lp-quote .btn { margin-top: 6px; }

/* ---------- custom listbox (.lp-sel) ---------- */
.lp-sel { position: relative; }
/* The trigger is the whole field row, so every pixel of it opens the list —
   a native <select> under a <label> only responded on its own text. */
.lp-sel-btn { display: flex; align-items: center; gap: 9px; width: 100%; height: 46px; padding: 0 12px;
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm); background: var(--surface);
  color: var(--muted); font-family: inherit; font-size: 14.5px; cursor: pointer; text-align: left; }
.lp-sel-btn:hover { border-color: var(--brand); }
.lp-sel-btn:focus-visible { outline: none; border-color: var(--brand); box-shadow: var(--ring); }
.lp-sel.open .lp-sel-btn { border-color: var(--brand); box-shadow: var(--ring); }
.lp-sel-val { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-weight: 500; color: var(--heading); }
.lp-sel-caret { flex: 0 0 auto; display: inline-flex; transition: transform .16s ease; }
.lp-sel.open .lp-sel-caret { transform: rotate(180deg); }

.lp-sel-list { position: absolute; z-index: 30; top: calc(100% + 6px); left: 0; right: 0; margin: 0; padding: 6px;
  list-style: none; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg); max-height: 244px; overflow-y: auto; overscroll-behavior: contain; }
.lp-sel-list li { padding: 9px 11px; border-radius: 9px; font-size: 14px; font-weight: 500; color: var(--ink); cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lp-sel-list li:hover { background: var(--surface-2); color: var(--brand-text); }
.lp-sel-list li[aria-selected="true"] { background: var(--surface-3); color: var(--brand-text); font-weight: 600; }
/* Thin themed scrollbar — 12 DisCos and 19 betting platforms both scroll. */
.lp-sel-list::-webkit-scrollbar { width: 8px; }
.lp-sel-list::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: 99px; border: 2px solid var(--surface); }
.lp-sel-list { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }

/* decorative globe */
.lp-globe { position: relative; height: 300px; display: grid; place-items: center; }
.lp-orbit { position: absolute; width: 290px; height: 290px; border-radius: 50%; border: 1.5px dashed var(--line-strong); }
.lp-planet { position: relative; width: 218px; height: 218px; border-radius: 50%; overflow: hidden;
  background: radial-gradient(circle at 33% 27%, #8fe8db 0%, #37c4b3 42%, var(--brand) 74%, var(--brand-700) 100%);
  box-shadow: inset -16px -20px 44px rgba(4, 48, 44, .34), 0 26px 60px rgba(15, 118, 110, .30); }
/* latitude lines + one meridian ellipse — enough to read as a globe */
.lp-planet::before { content: ""; position: absolute; inset: 0;
  background: repeating-linear-gradient(to bottom, transparent 0 26px, rgba(255, 255, 255, .17) 26px 27px); }
.lp-planet::after { content: ""; position: absolute; top: 0; bottom: 0; left: 50%; width: 58%; transform: translateX(-50%);
  border: 1px solid rgba(255, 255, 255, .19); border-radius: 50%; }
.lp-bub { position: absolute; width: 46px; height: 46px; border-radius: 50%; display: grid; place-items: center;
  background: var(--surface); color: var(--brand-text); box-shadow: var(--shadow); }
.lp-bub-1 { top: 6px; right: 34px; animation: lpBob1 6s ease-in-out infinite; }
.lp-bub-2 { top: 42%; right: -6px; animation: lpBob2 7s ease-in-out infinite -2s; }
.lp-bub-3 { bottom: 34px; left: 16px; animation: lpBob3 6.5s ease-in-out infinite -3s; }
.lp-bub-4 { bottom: 4px; right: 52px; animation: lpBob4 7.5s ease-in-out infinite -1.5s; }

@keyframes lpBob1 { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-8px) rotate(3deg); } }
@keyframes lpBob2 { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-10px) rotate(-3deg); } }
@keyframes lpBob3 { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(8px) rotate(2deg); } }
@keyframes lpBob4 { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(7px) rotate(-2deg); } }

/* ---------- trust strip ---------- */
.lp-trust { display: grid; grid-template-columns: repeat(4, 1fr); margin-top: -26px; position: relative; z-index: 2;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; }
.lp-trust-i { display: flex; align-items: flex-start; gap: 13px; padding: 22px 20px; }
.lp-trust-i + .lp-trust-i { border-left: 1px solid var(--line); }
.lp-trust-ic { flex: 0 0 auto; width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  background: var(--surface-3); color: var(--brand-text); }
.lp-trust-i b { display: block; font-size: 14.5px; color: var(--heading); margin-bottom: 3px; }
.lp-trust-i p { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--muted); }

/* ---------- popular services ---------- */
.lp-pop { display: grid; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); gap: 26px; align-items: start; margin-top: 54px; margin-bottom: 60px; }
/* The rail is a horizontal scroller: without min-width:0 its intrinsic width
   (all six cards) propagates up the grid and scrolls the whole PAGE sideways. */
.lp-pop-main, .lp-rail-wrap { min-width: 0; }
.lp-pop-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.lp-pop-head h2 { margin: 0; font-size: 26px; color: var(--heading); }
.lp-viewall { display: inline-flex; align-items: center; gap: 7px; font-weight: 600; font-size: 14px; color: var(--brand-text); }
.lp-rail-wrap { position: relative; }
.lp-rail { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(178px, 1fr); gap: 16px;
  overflow-x: auto; scroll-snap-type: x mandatory; padding-bottom: 4px; scrollbar-width: none; }
.lp-rail::-webkit-scrollbar { display: none; }
.lp-scard { scroll-snap-align: start; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 20px 17px; text-align: center; transition: transform .16s ease, box-shadow .16s ease, border-color .16s ease; }
.lp-scard:hover { transform: translateY(-3px); border-color: var(--brand); box-shadow: var(--shadow); }
.lp-scard-ic { width: 52px; height: 52px; border-radius: 16px; display: grid; place-items: center; margin: 0 auto 13px;
  background: var(--surface-3); color: var(--brand-text); }
.lp-scard h3 { margin: 0 0 6px; font-size: 15.5px; color: var(--heading); }
.lp-scard p { margin: 0 0 15px; font-size: 12.5px; line-height: 1.5; color: var(--muted); min-height: 38px; }
.lp-rail-btn { position: absolute; top: 50%; right: -16px; transform: translateY(-50%); width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center; background: var(--surface); color: var(--brand-text);
  border: 1px solid var(--line); box-shadow: var(--shadow); cursor: pointer; }
.lp-rail-btn:hover { background: var(--brand); color: var(--on-brand); border-color: var(--brand); }

/* app panel — two columns so the phone can never sit on top of the copy */
.lp-app { display: grid; grid-template-columns: minmax(0, 1fr) 178px; gap: 18px; align-items: end;
  overflow: hidden; background: var(--surface-3); border-radius: var(--radius-lg); padding: 28px 0 0 28px; }
.lp-app-copy { padding: 0 0 28px; }
.lp-app h3 { margin: 0 0 10px; font-size: 23px; line-height: 1.22; color: var(--heading); }
.lp-app p { margin: 0 0 20px; font-size: 13.5px; line-height: 1.6; color: var(--muted); }
.lp-app-actions { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.lp-app-link { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; font-size: 13.5px; color: var(--brand-text); }
/* Phone mock is decorative — it bleeds off the panel's bottom edge. The bleed
   is sized to land BELOW the last transaction row, never mid-text. */
/* --code-bg, not --heading: --heading is a TEXT token and inverts to near-white
   in dark mode, which turned the phone bezel white. --code-bg is dark in both. */
.lp-phone { position: relative; bottom: -14px; width: 186px; padding: 9px 9px 0; border-radius: 24px 24px 0 0;
  background: var(--code-bg); box-shadow: -14px 18px 44px rgba(15, 118, 110, .28); }
/* The 26px of bottom padding is what the panel's overflow clips, so the bleed
   never eats a transaction row. */
.lp-phone-scr { background: var(--surface); border-radius: 18px 18px 0 0; padding: 14px 12px 26px; }
.lp-phone-scr > small { display: block; font-size: 10px; color: var(--muted); }
.lp-phone-scr > b { display: block; font-size: 11px; color: var(--muted); font-weight: 600; margin-top: 8px; }
.lp-phone-bal { font-size: 21px; font-weight: 800; color: var(--heading); letter-spacing: -.02em; }
.lp-phone-bal span { font-size: 13px; color: var(--muted); }
.lp-phone-quick { display: flex; gap: 7px; margin: 12px 0 13px; }
.lp-phone-quick span { flex: 1 1 0; height: 32px; border-radius: 9px; display: grid; place-items: center;
  background: var(--surface-3); color: var(--brand-text); }
.lp-phone-tx { display: flex; align-items: center; gap: 8px; padding: 7px 0; border-top: 1px solid var(--line); }
.lp-phone-tx > span { flex: 0 0 auto; width: 24px; height: 24px; border-radius: 8px; display: grid; place-items: center;
  background: var(--surface-3); color: var(--brand-text); }
.lp-phone-tx div { flex: 1 1 auto; min-width: 0; }
/* Fixed 186px of phone — every line truncates rather than wrapping, or the
   rows grow and the bleed starts cutting text again. */
.lp-phone-tx b, .lp-phone-tx small { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.lp-phone-tx b { font-size: 10.5px; color: var(--heading); }
.lp-phone-tx small { font-size: 9px; color: var(--muted); }
.lp-phone-tx em { flex: 0 0 auto; font-style: normal; font-size: 10px; font-weight: 700; color: var(--err); white-space: nowrap; }

/* ---------- responsive ---------- */
@media (max-width: 1140px) {
  /* Globe is decoration — first thing to go when width gets tight. */
  .lp-hero-inner { grid-template-columns: minmax(0, 1fr) 300px; }
  .lp-globe { display: none; }
}
@media (max-width: 980px) {
  .lp-menu { display: none; }
  .lp-menu.open { display: flex; position: absolute; top: 68px; left: 0; right: 0; flex-direction: column; align-items: stretch;
    padding: 12px; gap: 2px; background: var(--surface); border-bottom: 1px solid var(--line); box-shadow: var(--shadow); }
  .lp-menu.open .lp-menu-link.is-active::after { display: none; }
  /* Auth links appear only in the OPEN menu, set apart by a rule so they don't
     read as more navigation. */
  .lp-menu.open .lp-menu-auth { display: flex; font-weight: 700; color: var(--brand-text); }
  .lp-menu.open .lp-menu-auth.is-first { margin-top: 6px; padding-top: 14px; border-top: 1px solid var(--line); border-radius: 0; }
  .lp-menu.open .lp-drop-panel { position: static; transform: none; width: auto; box-shadow: none; border: 0; padding: 4px 0 4px 12px; }
  /* .lp-menu carried the margin-inline:auto that pushed the actions right; with
     it hidden the actions must claim the free space themselves, or they bunch
     against the brand while the burger floats off at the far edge. */
  .lp-nav-actions { margin-left: auto; }
  .lp-burger { display: grid; margin-left: 0; }
  .lp-trust { grid-template-columns: repeat(2, 1fr); }
  .lp-trust-i:nth-child(odd) { border-left: 0; }
  .lp-trust-i:nth-child(n+3) { border-top: 1px solid var(--line); }
  .lp-pop { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 760px) {
  .lp-hero { padding: 36px 0 34px; }
  .lp-hero-inner { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  /*
   * Nothing fits beside the brand, theme toggle and burger at this width. The
   * header carries no auth buttons at all now, so this only suppresses the
   * signed-in Dashboard button — "Go to dashboard" is in the burger menu, and
   * a signed-out visitor reaches Login there and in the hero.
   */
  .lp-nav-actions .btn { display: none; }
  .lp-trust { grid-template-columns: 1fr; }
  .lp-trust-i { border-left: 0 !important; }
  .lp-trust-i + .lp-trust-i { border-top: 1px solid var(--line); }
  .lp-rail { grid-auto-columns: minmax(158px, 78%); }
  .lp-rail-btn { display: none; }
  /* Panel stacks: phone stops bleeding off the right and centres under the copy. */
  .lp-app { grid-template-columns: minmax(0, 1fr); padding: 26px 22px 0; }
  .lp-app-copy { padding-bottom: 6px; }
  .lp-phone { margin: 0 auto; }
  .lp .site-foot .cols { gap: 20px; }
}
@media (max-width: 560px) {
  /* Badge only — the wordmark plus the actions overflow a 390px viewport. */
  .lp-nav .brand-word { display: none; }
  .lp-nav-inner { gap: 12px; }
}

/* ============================================================
   Rich Authentication Layout (Login / Register / Reset)
   ============================================================ */
.auth-page {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 20px;
  background: var(--bg);
  position: relative;
  overflow-x: hidden;
}
.auth-page::before {
  content: "";
  position: absolute;
  top: -20%;
  left: 10%;
  width: 550px;
  height: 550px;
  background: radial-gradient(circle, rgba(13, 148, 136, 0.12) 0%, rgba(20, 184, 166, 0) 70%);
  pointer-events: none;
  z-index: 0;
}
.auth-page::after {
  content: "";
  position: absolute;
  bottom: -15%;
  right: 8%;
  width: 480px;
  height: 480px;
  background: radial-gradient(circle, rgba(13, 107, 100, 0.10) 0%, rgba(13, 107, 100, 0) 70%);
  pointer-events: none;
  z-index: 0;
}

.auth-box {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1060px;
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 28px;
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  min-height: 640px;
}

/* Left Showcase Pane */
.auth-showcase {
  background: linear-gradient(145deg, #093834 0%, #0d6b64 55%, #13887c 100%);
  color: #ffffff;
  padding: 44px 38px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  position: relative;
  overflow: hidden;
}
.auth-showcase::after {
  content: "";
  position: absolute;
  top: -50px;
  right: -50px;
  width: 260px;
  height: 260px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.12), transparent 70%);
  pointer-events: none;
}
.auth-showcase-top .brand {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  text-decoration: none;
  color: #ffffff;
  font-weight: 800;
  font-size: 20px;
  margin-bottom: 36px;
}
.auth-showcase h2 {
  font-size: clamp(26px, 2.6vw, 34px);
  font-weight: 800;
  line-height: 1.2;
  color: #ffffff;
  margin: 0 0 16px;
  letter-spacing: -0.02em;
}
.auth-showcase p.showcase-desc {
  font-size: 15px;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.85);
  margin: 0 0 32px;
}
.auth-features {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-bottom: 32px;
}
.auth-feature-item {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid rgba(255, 255, 255, 0.14);
  padding: 12px 16px;
  border-radius: 16px;
  backdrop-filter: blur(4px);
}
.auth-feature-ic {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.18);
  display: grid;
  place-items: center;
  color: #ffffff;
}
.auth-feature-text strong {
  display: block;
  font-size: 14px;
  color: #ffffff;
  margin-bottom: 2px;
}
.auth-feature-text span {
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.78);
  line-height: 1.4;
}
.auth-showcase-foot {
  padding-top: 20px;
  border-top: 1px solid rgba(255, 255, 255, 0.15);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  font-size: 12.5px;
  color: rgba(255, 255, 255, 0.82);
}
.auth-stars {
  color: #fbbf24;
  letter-spacing: 2px;
  font-size: 13px;
}

/* Right Form Pane */
.auth-form-panel {
  padding: 44px 48px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.auth-top-nav {
  display: flex;
  align-items: center;
  /* flex-end, not space-between: on login and register the only thing left up
     here is the theme toggle, and space-between would park it at the far left.
     The narrow breakpoint restores space-between once the brand appears beside
     it. Pages that still carry a "Back to sign in" link get it back too. */
  justify-content: flex-end;
  gap: 12px;
  margin-bottom: 28px;
}
/* Pages that still carry "Back to sign in" push the toggle away themselves —
   margin-auto rather than :has(), so this holds on older engines too. */
.auth-back-link { margin-right: auto; }
/* Desktop shows the logo in the showcase pane, so it would be duplicated here. */
.auth-top-brand { display: none; font-size: 17px; }
.auth-top-brand .brand-mark { width: 32px; height: 32px; }
.auth-back-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  transition: color .14s ease, transform .14s ease;
}
.auth-back-link:hover {
  color: var(--brand-text);
  transform: translateX(-2px);
}
.auth-header {
  margin-bottom: 26px;
}
.auth-header h1 {
  font-size: clamp(24px, 3vw, 30px);
  font-weight: 800;
  color: var(--heading);
  margin: 0 0 6px;
  letter-spacing: -0.02em;
}
.auth-header p {
  font-size: 14.5px;
  color: var(--muted);
  margin: 0;
  line-height: 1.5;
}

.auth-form {
  display: flex;
  flex-direction: column;
  gap: 16px;
}
.auth-form .field {
  margin: 0;
}
.auth-form .field > span {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 13px;
  font-weight: 700;
  color: var(--heading);
  margin-bottom: 6px;
}
.auth-input-wrap {
  position: relative;
  display: flex;
  align-items: center;
}
.auth-input-ic {
  position: absolute;
  left: 14px;
  color: var(--muted);
  pointer-events: none;
  display: flex;
  align-items: center;
  justify-content: center;
}
.auth-input-wrap input {
  padding-left: 42px !important;
}
.auth-input-wrap .pw-toggle {
  position: absolute;
  right: 12px;
  background: transparent;
  border: 0;
  color: var(--muted);
  cursor: pointer;
  padding: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  transition: color .14s ease, background .14s ease;
}
.auth-input-wrap .pw-toggle:hover {
  color: var(--brand-text);
  background: var(--surface-3);
}

.auth-grid-2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.auth-meta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 13px;
}
.auth-checkbox {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  color: var(--ink);
  font-weight: 500;
  user-select: none;
}
.auth-checkbox input {
  accent-color: var(--brand);
  width: 16px;
  height: 16px;
  cursor: pointer;
}
.auth-forgot {
  color: var(--brand-text);
  font-weight: 600;
  text-decoration: none;
}
.auth-forgot:hover {
  text-decoration: underline;
}

.auth-submit-btn {
  width: 100%;
  min-height: 48px;
  font-size: 15px;
  font-weight: 700;
  border-radius: var(--radius-sm);
  margin-top: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.auth-switch {
  text-align: center;
  margin-top: 14px;
  font-size: 14px;
  color: var(--muted);
}
.auth-switch a {
  font-weight: 700;
  color: var(--brand-text);
  margin-left: 4px;
}
.auth-switch a:hover {
  text-decoration: underline;
}

.auth-trust-note {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--muted);
  font-weight: 600;
}

/* Auth Responsiveness */
@media (max-width: 960px) {
  .auth-box {
    grid-template-columns: 1fr;
    max-width: 520px;
    border-radius: 22px;
  }
  .auth-showcase {
    display: none;
  }
  /* The showcase pane (and the only logo) is gone here, so the mark in the top
     bar becomes the branding and the route home. */
  .auth-top-brand { display: inline-flex; }
  .auth-top-nav { justify-content: space-between; }
  .auth-form-panel {
    padding: 34px 26px;
  }
}
@media (max-width: 540px) {
  .auth-page {
    padding: 16px 12px;
  }
  .auth-form-panel {
    padding: 26px 18px;
  }
  .auth-grid-2 {
    grid-template-columns: 1fr;
    gap: 16px;
  }
}
