/* Nextepay platform design system — aligned to the marketing site (client-validated).
   Foundations: Plus Jakarta Sans (400/500/600, never 700+), a bright-gold signature used
   for FILLS on nuit and money moments (never gold text on white), a violet text accent on
   light, and the aurora gradient reserved for 1-2 accents per screen. Cards radius 22px,
   soft shadows lifting to violet on hover, tabular-nums on every figure. The whole UI is
   built on these tokens: flipping data-theme re-themes everything.
   See docs/design/design-system-nextepay.md (the spec + the consolidation backlog). */

:root {
  /* === Design system (site vitrine) — valeurs exactes === */
  /* Neutres */
  --nuit: #0b1320;
  --ardoise: #1f2937;
  --gris: #6b7280;
  --gris-clair: #f1f5f9;
  /* Or — signature de marque. Accent de FOND (nuit, moments d'argent), JAMAIS texte sur blanc. */
  --or1: #ffd60a;
  --or2: #ffb300;
  --grad-or: linear-gradient(135deg, #ffe14d 0%, #ffc400 55%, #ff9e00 100%);
  /* Accents électriques */
  --violet: #8b5cf6;
  --violet-txt: #7c3aed; /* version lisible sur fond clair — l'accent TEXTE sur clair */
  --cyan: #22d3ee;
  --rose: #fb7185;
  --grad-aurora: linear-gradient(115deg, #ffd60a 0%, #fb7185 35%, #8b5cf6 68%, #22d3ee 100%);
  --grad-aurora-light: linear-gradient(115deg, #f59e0b 0%, #ec4899 48%, #7c3aed 100%);
  /* États — valeurs exactes de la doc */
  --ok: #22c55e;
  --ok-txt: #15803d;
  --ok-wash: rgba(34, 197, 94, 0.12);
  --err: #e5484d;
  --err-wash: rgba(229, 72, 77, 0.12);
  /* The readable red, the counterpart of --ok-txt and --warn-txt. --err itself is a FILL
     (a dot, a border, a wash) and sits at 3.4:1 as text on its own wash, which fails AA.
     Anything that READS red uses this one. */
  --err-txt: #b91c1c;
  /* The red BORDER of a destructive control. --err at 32% reads 1.5:1 against the card, so
     the outline that makes it a button was not perceivable (WCAG 1.4.11 asks 3:1 of a
     component boundary). Built from the readable red instead: 3.1:1. */
  --err-line: rgba(185, 28, 28, 0.6);
  --warn-txt: #b45309;
  --warn-bg: rgba(255, 214, 10, 0.2);
  /* Surfaces annexes */
  --footer: #080d16;
  --code-bg: #0f1729;

  /* === Tokens sémantiques de l'app (remappés sur le design system) === */
  --canvas: #f1f5f9;
  --surface: #ffffff;
  --ink: #0b1320;
  --ink-soft: #1f2937;
  --muted: #6b7280;
  /* --muted, but for text on a CANVAS-filled chip: on that tint the plain one reads
     4.4:1. Same role, one shade deeper. */
  --muted-strong: #5f6b7a;
  --line: #eef1f5;
  --line-strong: #e4e9f0;
  /* The merchant pages' card line and row hover, named once so the inbox and the shell
     keep the same values (.cshell, .svc:hover and .inbox can point here next). */
  --card-line: #e7ecf3;
  --card-hover: #f8f9fc;

  /* Accent : OR en FOND (sur nuit / moments d'argent) ; l'accent TEXTE sur clair = VIOLET. */
  --accent: #ffc400;
  --accent-ink: #7c3aed;
  --accent-wash: rgba(124, 58, 237, 0.08);
  --brand-grad: var(--grad-or);
  /* Primary button — nuit workhorse on light, gold on dark (see the dark overrides). */
  --primary-bg: #0b1320;
  --primary-bg-hover: #1e2a3d;
  --primary-fg: #ffffff;
  /* --amber/--red duplicated --warn/--err EXACTLY; now aliases (single source of truth, no visual
     change). --live is a distinct green (not --ok), so it stays a literal. See design-system §9. */
  --amber: var(--warn-txt);
  --amber-wash: var(--warn-bg);
  --red: var(--err);
  --red-wash: var(--err-wash);
  --live: #16a34a;

  /* Hover wash (rows, ghost buttons, chips) — a touch darker than the surface. */
  --hover: #f1f5f9;
  /* Géométrie : pills 999px (boutons/chips), inputs 11px, cartes console via --radius-card. */
  --radius: 14px;
  --radius-pill: 999px;
  --radius-input: 11px;
  --radius-sm: 10px;
  /* Card containers — one source of truth so they can't drift (used to split 14/18/20/21):
     .panel, .meta-row, .hero-banner, .pbl-ccard, and the console glass cards (.cd-card /
     .side-card / .cshell .panel + .ledger-summary). 22px = the marketing charte. Small/inline
     elements keep --radius (14). See design-system §9. */
  --radius-card: 22px;
  /* Type scale (px) — the de-facto sizes, now named. Migrate literals to these over time
     (design-system §3/§9); additive, so defining them changes nothing until referenced. */
  --fs-title: 33px; /* page + hero titles */
  --fs-stat: 24px; /* KPI numbers */
  --fs-h: 14px; /* panel headings */
  --fs-btn: 13.5px; /* buttons */
  --fs-body: 13px; /* body / tables */
  --fs-label: 12px; /* form labels */
  --fs-kicker: 10.5px; /* uppercase kickers / table headers */
  /* Spacing rhythm (px) — the clustered values, now named (design-system §4/§9). */
  --space-1: 4px;
  --space-2: 6px;
  --space-3: 8px;
  --space-4: 10px;
  --space-5: 14px;
  --space-6: 16px;
  --space-7: 22px;
  --space-8: 26px;
  --space-9: 44px;
  /* Ombres douces (présentes mais légères) ; levée violette au survol des cartes cliquables. */
  --shadow-sm: 0 4px 18px rgba(11, 19, 32, 0.06);
  --shadow: 0 10px 40px rgba(11, 19, 32, 0.08);
  --shadow-pop: 0 10px 40px rgba(11, 19, 32, 0.08);
  --shadow-violet: 0 14px 44px rgba(139, 92, 246, 0.18);
  --sidebar-w: 232px;

  --display: "Plus Jakarta Sans", ui-sans-serif, system-ui, sans-serif;
  --body: "Plus Jakarta Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
}

/* Night mode — overrides the palette tokens; the whole UI is built on these
   variables, so flipping data-theme on <html> re-themes everything. */
[data-theme="dark"] {
  --canvas: #0b1320;
  --surface: #131c2e;
  --ink: #e8edf4;
  --ink-soft: #b3c0d1;
  --muted: #94a3b8;
  --muted-strong: #94a3b8;  /* already 6.8:1 on the dark chip fill */
  --line: #24304a;
  --line-strong: #38455f;
  --card-line: rgba(255, 255, 255, 0.09);
  --card-hover: rgba(255, 255, 255, 0.04);

  --hover: #1b2740;
  /* Sur fond sombre, l'accent TEXTE redevient or (l'or est lisible sur nuit). */
  --accent: #ffc400;
  --accent-ink: #ffd60a;
  --accent-wash: rgba(139, 92, 246, 0.16);
  --violet-txt: #a78bfa; /* violet plus clair, lisible sur nuit */
  --brand-grad: var(--grad-or);
  /* Primary button on nuit — gold with nuit text (a nuit button would vanish). */
  --primary-bg: #ffc400;
  --primary-bg-hover: #ffd60a;
  --primary-fg: #0b1320;
  /* --amber/--red inherit their :root aliases (→ dark --warn/--err, identical values); only
     --live differs and stays a literal. */
  --live: #46c07d;
  --ok: #46c07d;
  --ok-txt: #86efac;
  --ok-wash: rgba(34, 197, 94, 0.16);
  --err: #e5484d;
  --err-wash: rgba(229, 72, 77, 0.2);
  --err-txt: #fca5a5;
  --err-line: rgba(252, 165, 165, 0.6);
  --warn-txt: #e0a458;
  --warn-bg: rgba(255, 214, 10, 0.16);

  --shadow-sm: 0 4px 18px rgba(0, 0, 0, 0.4);
  --shadow: 0 10px 40px rgba(0, 0, 0, 0.55);
  --shadow-pop: 0 10px 40px rgba(0, 0, 0, 0.55);
  --shadow-violet: 0 14px 44px rgba(139, 92, 246, 0.28);
  color-scheme: dark; /* native date pickers, selects, scrollbars go dark too */
}
[data-theme="dark"] .pill.neutral {
  background: #222e44;
}

/* Aurora hairline at the very top of the window — the site's signature, kept in the app. */
body::before {
  content: "";
  position: fixed;
  inset: 0 0 auto 0;
  height: 3px;
  background: var(--grad-aurora);
  z-index: 1000;
  pointer-events: none;
}

/* Signature utilities — homeopathic (1-2 per screen, doc §5). .aurora = a highlighted
   title keyword on light; .gold-amount = a money confirmation value (paiement reçu). */
.aurora {
  background: var(--grad-aurora-light);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--violet-txt);
}
.gold-amount {
  background: var(--grad-or);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--or2);
}
/* The sidebar uses --ink as its (dark) background in light mode; in night mode
   --ink flips to a light value, so pin it to a dark shade explicitly. */
[data-theme="dark"] .sidebar {
  background: #0c1320;
}
/* Form controls hardcode a near-white background (e.g. `.field select`) — re-skin
   them for night mode. The `html` prefix lifts specificity above those single-
   class rules so the dark background actually wins; radios/checkboxes keep their
   native look via color-scheme. */
html[data-theme="dark"] input:not([type="radio"]):not([type="checkbox"]),
html[data-theme="dark"] select,
html[data-theme="dark"] textarea {
  background: #111a29;
  color: var(--ink);
  border-color: var(--line-strong);
}
html[data-theme="dark"] ::placeholder {
  color: var(--muted);
}
/* …but a focused field keeps the accent border. The rule above is specific enough
   to otherwise clobber it, leaving focus grey in night mode (unlike light mode). */
html[data-theme="dark"] input:not([type="radio"]):not([type="checkbox"]):focus,
html[data-theme="dark"] textarea:focus,
html[data-theme="dark"] select:focus {
  border-color: var(--accent);
}
/* Hover states and code blocks hardcode light colors (and `.code pre` even uses
   --ink as its background, which flips light in night mode) — re-skin them. */
html[data-theme="dark"] .txn-row:hover {
  background: #1b2740;
}
/* Exclude .primary/.danger — the `html` prefix here outranks their own :hover rules, so
   without this a hovered primary button turns into a dark box with dark (invisible) text. */
html[data-theme="dark"] .btn:not(.primary):not(.danger):hover {
  background: #1b2740;
}
html[data-theme="dark"] .btn.ghost:hover {
  background: #1b2740;
  color: var(--ink);
}
html[data-theme="dark"] .lang-tabs button:hover {
  background: #1b2740;
}
html[data-theme="dark"] .lang-tabs button.on {
  background: var(--accent);
  color: #0b1320;
}
html[data-theme="dark"] .code pre {
  background: #0c1320;
  color: #cbd5e2;
}
html[data-theme="dark"] .dev-section p code {
  background: #1b2740;
  color: var(--ink);
}
html[data-theme="dark"] .method.post {
  background: #2a2614;
  color: #d7b06a;
}
/* Status filter chips (clients page): the active chip fills with --ink, which
   flips light in night mode — keep the filled look but flip the text dark. */
html[data-theme="dark"] .chip:hover {
  background: #1b2740;
}
html[data-theme="dark"] .chip.on {
  color: var(--canvas);
}

/* Profile / preferences page */
.profile-form {
  padding: 18px;
  max-width: 480px;
}
.theme-choice {
  display: flex;
  gap: 18px;
}
.theme-opt {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-weight: 500;
}
/* The theme radios sit inside a .field, so `.field input` was boxing them like a text field
   (width:100%, padding, border, focus halo) — ~59px wide, and on click briefly wider still, which
   wrapped the row and nudged the Save button down-and-back. Reset them to plain native radios
   (higher specificity than `.field input`); the global :focus-visible outline handles focus. */
.theme-choice input[type="radio"] {
  width: auto;
  flex: none;
  margin: 0;
  padding: 0;
  border: 0;
  box-shadow: none;
}
/* Live theme preview (Settings) flips data-theme instantly in profile.html — measured to cause no
   layout shift or button re-colour, so it needs no transition/View-Transition wrapper (an earlier
   VT wrapper actually introduced a one-frame root-group reflow that nudged the Save button). */

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--body);
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
}
/* Dark: solid nuit page background + the signature conic blob behind the header
   (jaune↔violet, blurred), viewport-fixed so it sits top-right on every dark page —
   the exact reference decor (doc §Décor de page). --nuit stays a solid fill token. */
[data-theme="dark"] body { background: var(--nuit); }
[data-theme="dark"] body::after {
  content: "";
  position: fixed;
  top: -160px;
  left: 50%;
  transform: translateX(calc(-50% + 40px));
  width: 560px;
  height: 560px;
  border-radius: 50%;
  background: conic-gradient(from 90deg, #ffd60a, #8b5cf6, #ffd60a);
  filter: blur(110px);
  opacity: 0.14;
  pointer-events: none;
  z-index: -1;
}

a {
  color: var(--accent-ink);
  text-decoration: none;
}
a:hover {
  text-decoration: underline;
}
/* That underline is for links in running text. Buttons, cards, rows and icons rendered as <a>
   say "this opens" with their own hover; under them it ran beneath every word. (.btn.link,
   the button styled as a text link, keeps it: its own rule is more specific.) */
a.btn:hover, a.btn-cta:hover, a.btn-sm-or:hover, a.btn-ghost:hover, a.ck-row:hover,
a.set-card:hover, a.stat:hover, a.drawer-link:hover, a.dd-it:hover, a.pbl-ico:hover,
a.bell:hover {
  text-decoration: none;
}

/* tabular money / ids */
.mono {
  font-family: var(--mono);
  font-feature-settings: "tnum" 1, "zero" 1;
}
/* Every figure column must align: tabular-nums on the .num helper used across amount /
   number cells. Non négociable dans un dashboard de paiement (doc §1). */
.num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1, "zero" 1;
}
.amount {
  font-family: var(--mono);
  font-feature-settings: "tnum" 1, "zero" 1;
  letter-spacing: -0.01em;
  white-space: nowrap;
}
.amount .ccy {
  color: var(--muted);
  font-size: 0.78em;
  text-transform: uppercase;
  margin-right: 0.35em;
  letter-spacing: 0.04em;
}

/* ---------- app shell ---------- */
.shell {
  display: grid;
  grid-template-columns: var(--sidebar-w) 1fr;
  min-height: 100vh;
}

.sidebar {
  background: var(--surface);
  border-right: 1px solid var(--line);
  color: var(--ink-soft);
  display: flex;
  flex-direction: column;
  padding: 16px 12px;
  position: sticky;
  top: 0;
  height: 100vh;
}

.brand {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px 14px;
  color: var(--ink);
  font-family: var(--display);
  font-weight: 600;
  font-size: 18px;
  letter-spacing: -0.02em;
}
.brand:hover { text-decoration: none; }
.brand .brand-mark {
  width: 24px;
  height: 24px;
  object-fit: contain;
}
/* Nextepay text lockup (brandmark() macro): the lowercase "next·e·pay" wordmark with a
   gold e, and the "Next Electronic Payment" signature underneath — no pictogram. */
.brandmark {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  line-height: 1;
}
.brand-word { text-transform: lowercase; font-size: 1.14em; }
.brand-e {
  background: var(--brand-grad);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  color: var(--accent);
}
.brand-sig {
  font-family: var(--body);
  font-size: 8px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted);
}

.nav {
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.nav a {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  color: var(--ink-soft);
  font-size: 13.5px;
}
.nav a svg { width: 16px; height: 16px; opacity: 0.6; flex: none; }
.nav a:hover {
  background: var(--hover);
  color: var(--ink);
  text-decoration: none;
}
.nav a.active {
  background: var(--accent-wash);
  color: var(--violet-txt);
  font-weight: 600;
}
.nav a.active svg { opacity: 1; stroke: var(--violet-txt); }
.nav a.disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.nav .tag {
  margin-left: auto;
  font-size: 9.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 4px;
}

.nav-label {
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 16px 10px 6px;
}

/* Environment switch (Live/Sandbox) — segmented control pinned to the sidebar bottom. */
/* Global environment switch, top-right in the topbar. A compact segmented pill;
   the active side gets a coloured dot (green = live, amber = sandbox). */
.envswitch {
  display: inline-flex;
  gap: 2px;
  background: var(--canvas);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 2px;
}
.envswitch button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 12px;
  line-height: 1;
  padding: 5px 12px;
  border-radius: 999px;
  color: var(--muted);
  cursor: pointer;
}
.envswitch button:hover { color: var(--ink); }
.envswitch button.on {
  background: var(--surface);
  color: var(--ink);
  font-weight: 500;
  box-shadow: var(--shadow);
}
.envswitch button .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--line-strong);
  flex: none;
}
.envswitch button.on[value="production"] .dot { background: var(--live); }
.envswitch button.on[value="sandbox"] .dot { background: var(--amber); }
/* Inactive side: hide the dot so the pill reads clean (dot marks the active env). */
.envswitch button:not(.on) .dot { display: none; }

/* Direct merchant: a non-interactive Sandbox badge (no Live side to switch to). */
.envswitch.static { cursor: default; }
.envswitch.static .on {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: 0.82rem;
  font-weight: 500;
  box-shadow: var(--shadow);
}
.envswitch.static .on .dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--amber);
  flex: none;
}

/* Self-serve plan selection (choose_plan.html) — a faithful port of the marketing
   site's pricing cards: aurora-gradient price, gold-check bullets, a fee grid, and a
   nuit "hot" featured card with an aurora border + gold "Most popular" badge. The
   site's light hardcodes (#fff bg, #eef1f5 lines, --gris/--ardoise text) are mapped to
   theme tokens (--surface/--line/--muted/--ink) so the cards also read correctly in
   dark mode; the .hot card is nuit in BOTH themes and keeps its fixed light text. */
/* Centered, stacked header for the plan picker (the shared .page-head is a single
   baseline row — it crams the kicker, H1 and long sub onto one line). */
.pricing-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  max-width: 620px;
  margin: 6px auto 34px;
}
.pricing-head h1 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 30px;
  letter-spacing: -0.03em;
  margin: 0;
}
.pricing-head .sub {
  color: var(--muted);
  font-size: 14px;
  line-height: 1.55;
  margin: 0;
  max-width: 56ch;
}
/* Billing toggle (Monthly / Annual −25%), mirroring the public pricing page. The grid's
   data-period drives which price variant shows — no reflow, both are in the DOM. */
.bill-toggle {
  display: inline-flex; gap: 4px; margin-top: 14px; padding: 3px;
  border: 1px solid var(--line-strong); border-radius: 999px;
}
.bill-opt {
  border: 0; background: none; cursor: pointer; font: inherit; font-size: 12.5px;
  padding: 5px 14px; border-radius: 999px; color: var(--muted);
}
.bill-opt.active { background: var(--ink); color: var(--bg, #fff); }
.bill-opt em { font-style: normal; font-size: 10.5px; opacity: 0.75; margin-left: 2px; }
.price-grid .only-annual { display: none; }
.price-grid[data-period="annual"] .only-annual { display: inline; }
.price-grid[data-period="annual"] .only-monthly { display: none; }
.price-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
  align-items: stretch;
  /* Comfortable width, centered on the page (cards read too large full-bleed). */
  max-width: 940px;
  margin: 0 auto;
}
@media (max-width: 900px) { .price-grid { grid-template-columns: 1fr; max-width: 420px; } }
.price {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  padding: 32px 28px;
  text-align: left;
  display: flex;
  flex-direction: column;
  position: relative;
  transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s;
}
.price:hover { transform: translateY(-4px); box-shadow: var(--shadow-violet); }
.price h3 { font-size: 20px; font-weight: 600; color: var(--ink); margin: 0; }
/* Fixed height so a 1- vs 2-line tagline doesn't push the price/fees out of alignment
   across the three cards. */
.price .for { font-size: 13px; line-height: 1.45; color: var(--muted); margin-top: 6px; min-height: 2.9em; }
.price .rate {
  font-size: 46px;
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1.05;
  margin: 20px 0 2px;
  font-variant-numeric: tabular-nums;
  background: var(--grad-aurora-light);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
.price .rate small { font-size: 17px; letter-spacing: 0; }
.price .rate small.unit { font-size: 15px; color: var(--muted); -webkit-text-fill-color: var(--muted); }
.price .per { font-size: 13px; color: var(--muted); }
.price .fees { margin: 20px 0 4px; border-top: 1px solid var(--line); padding-top: 14px; }
.price .fees > div { display: flex; justify-content: space-between; gap: 12px; font-size: 12.5px; padding: 5px 0; color: var(--muted); text-align: left; }
.price .fees > div b { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.price ul { list-style: none; margin: 22px 0 26px; padding: 0; flex: 1; }
.price ul li { padding: 8px 0 8px 28px; position: relative; font-size: 14px; color: var(--ink); }
.price ul li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 15px;
  width: 12px;
  height: 7px;
  border-left: 2.5px solid var(--or2);
  border-bottom: 2.5px solid var(--or2);
  transform: rotate(-45deg);
}
.price .price-note { margin-top: 12px; font-size: 12.5px; color: var(--muted); }
/* FEATURED "hot" card — nuit ground + aurora border, dark in both themes. */
.price.hot {
  background:
    linear-gradient(var(--nuit), var(--nuit)) padding-box,
    var(--grad-aurora) border-box;
  border: 2px solid transparent;
  box-shadow: 0 18px 54px rgba(11, 19, 32, 0.28);
  color: #fff;
}
.price.hot h3 { color: #fff; }
.price.hot .rate { background: var(--grad-aurora); -webkit-background-clip: text; background-clip: text; }
.price.hot .rate small.unit { color: #8b97a8; -webkit-text-fill-color: #8b97a8; }
.price.hot .for, .price.hot .per { color: #8b97a8; }
.price.hot ul li { color: #c7d0dd; }
.price.hot ul li::before { border-color: var(--or1); }
.price.hot .fees { border-color: rgba(255, 255, 255, 0.12); }
.price.hot .fees > div { color: #8b97a8; }
.price.hot .fees > div b { color: #fff; }
.price.hot .price-note { color: #8b97a8; }
.price.hot .btn.ghost { color: rgba(255, 255, 255, 0.7); border-color: rgba(255, 255, 255, 0.22); }
/* The client's CURRENT plan — a violet ring; its CTA reads "Current plan". */
.price.current { border-color: var(--violet); box-shadow: 0 0 0 1px var(--violet), var(--shadow-sm); }
.price.current.hot { box-shadow: 0 0 0 2px var(--violet), 0 18px 54px rgba(11, 19, 32, 0.28); }
/* "Most popular" badge — gold pill straddling the top edge of the hot card. */
.badge-hot {
  position: absolute;
  top: -13px;
  right: 22px;
  background: var(--grad-or);
  color: var(--nuit);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 1px;
  text-transform: uppercase;
  border-radius: 999px;
  padding: 6px 14px;
  box-shadow: 0 6px 20px rgba(255, 214, 10, 0.4);
  white-space: nowrap;
}
.btn.block { display: block; width: 100%; text-align: center; }
.btn.sm { padding: 5px 10px; font-size: 0.82rem; }

/* Sandbox getting-started checklist (dashboard, direct merchant). Each step is a single
   light, whole-row link — a mark, the title, and a trailing chevron (actionable) or a muted
   value (done). No repeated button labels. Rows align to the panel header's 16px inset;
   dividers span the full panel width. */
.checklist { list-style: none; margin: 0; padding: 0; }
.checklist li + li { border-top: 1px solid var(--line); }
.ck-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 16px;
  color: inherit;
  text-decoration: none;
}
a.ck-row:hover { background: var(--hover); }
.ck-mark {
  flex: none;
  width: 20px;
  height: 20px;
  border: 1.5px solid var(--line-strong);
  border-radius: 50%;
  background: transparent;
}
.checklist li.done .ck-mark {
  border-color: var(--accent);
  background: var(--accent);
  position: relative;
}
.checklist li.done .ck-mark::after {
  content: "";
  position: absolute;
  left: 6px;
  top: 3px;
  width: 5px;
  height: 9px;
  border: solid #0b1320;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.ck-title { flex: 1; min-width: 0; font-weight: 500; color: var(--ink); }
.ck-title.muted,
.checklist li.done .ck-title { color: var(--muted); }
.ck-hint {
  flex: none;
  max-width: 45%;
  font-size: 0.82rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ck-go {
  flex: none;
  display: flex;
  color: var(--line-strong);
  transition: transform 0.12s, color 0.12s;
}
.ck-go svg { width: 16px; height: 16px; }
a.ck-row:hover .ck-title { color: var(--accent-ink); }
a.ck-row:hover .ck-go { color: var(--accent-ink); transform: translateX(2px); }
/* A step's own detail — what is left on it, under its row. Going live used to be a second
   card with a second list and a second percentage; it is the last step of this one now. */
.ck-note {
  margin: -4px 0 0;
  padding: 0 16px 13px 48px;   /* aligned with the row's title, past the mark */
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.55;
}
.ck-plan {
  margin: 0;
  padding: 13px 16px;
  border-top: 1px solid var(--line);
  font-size: 0.82rem;
  color: var(--muted);
}
.ck-plan a { color: var(--accent-ink); }
.checklist .ck-row form { margin: 0; }
.ck-dot { color: var(--line-strong); }

/* Signed-in identity row at the sidebar foot. */
.sideuser {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 6px 2px;
  border-top: 1px solid var(--line);
}
.sideuser .ava {
  width: 27px;
  height: 27px;
  border-radius: 50%;
  background: var(--accent-wash);
  color: var(--accent-ink);
  display: grid;
  place-items: center;
  font-size: 11px;
  font-weight: 600;
  flex: none;
}
.sideuser .who-name { font-size: 12.5px; color: var(--ink); line-height: 1.3; }
.sideuser .who-role { font-size: 11px; color: var(--muted); text-transform: capitalize; }
.sideuser .acts { margin-left: auto; display: flex; gap: 2px; }
.sideuser .acts a, .sideuser .acts button {
  width: 26px; height: 26px; display: grid; place-items: center;
  border: 0; background: 0; color: var(--muted); cursor: pointer; border-radius: 6px;
}
.sideuser .acts a:hover, .sideuser .acts button:hover { background: var(--hover); color: var(--ink); }

/* The configuration group + foot sit at the bottom of the sidebar column. */
.sidebar-bottom {
  margin-top: auto;
}

.sidebar-foot {
  margin-top: 10px;
  padding-top: 14px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  color: var(--muted);
}

/* ---------- main ---------- */
.main {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.topbar {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 28px;
  height: 58px;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 5;
}
.org {
  display: flex;
  align-items: center;
  gap: 8px;
  font-weight: 500;
}
.org .kind {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent-ink);
  background: var(--accent-wash);
  border-radius: 5px;
  padding: 2px 6px;
}
.topbar .spacer {
  flex: 1;
}
.who {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--muted);
  font-size: 13px;
}
.who .email {
  color: var(--ink-soft);
}
/* Topbar icon buttons (profile, sign out) — share the bell's understated look. */
.iconbtn {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  padding: 6px;
  border: none;
  background: none;
  color: var(--muted);
  cursor: pointer;
}
.iconbtn:hover { color: var(--ink); }
.iconbtn.danger:hover { color: var(--err-txt); }

/* Confirmation dialog (sign out, and reusable for other confirm prompts).
   Native <dialog>: top-layer centering + focus trap + Esc close come for free. */
.confirm-dialog {
  width: min(380px, calc(100vw - 32px));
  margin: auto; /* center in the top layer */
  padding: 24px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow);
  text-align: center;
}
.confirm-dialog::backdrop {
  background: rgba(14, 23, 38, 0.42);
  backdrop-filter: blur(2px);
}
.confirm-dialog[open] {
  animation: confirm-pop 0.14s ease-out;
}
@keyframes confirm-pop {
  from { opacity: 0; transform: translateY(6px) scale(0.97); }
  to { opacity: 1; transform: none; }
}
.confirm-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  margin-bottom: 14px;
  border-radius: 999px;
  background: var(--red-wash);
  color: var(--red);
}
/* 22px, the size every confirm dialog writes on its inline <svg>. Stated here too because
   the Developers dialog draws its trash through the icon macro, which ships no width — and
   an icon that big is decided by the call site rather than by the box it sits in. */
.confirm-icon svg { width: 22px; height: 22px; }
.confirm-dialog h2 {
  margin: 0 0 6px;
  font-family: var(--display);
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
}
.confirm-dialog p {
  margin: 0 auto 20px;
  max-width: 30ch;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--muted);
}
.confirm-actions {
  display: flex;
  gap: 10px;
  justify-content: center;
}
.confirm-actions .btn { padding: 8px 18px; }

/* Mobile nav: a hamburger toggles the sidebar as an off-canvas drawer. The
   checkbox + labels make it work with no JS (a nav click reloads the page, which
   resets the toggle). All hidden on desktop; the mobile @media block enables them. */
.nav-toggle,
.nav-backdrop {
  display: none;
}
.nav-burger {
  display: none;
  flex: none; /* never let the topbar squish the 38px square into an oval */
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  margin-left: -6px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
}
.nav-burger:hover {
  background: var(--hover);
}

/* notifications bell + badge */
.bell {
  position: relative;
  display: inline-flex;
  flex: none;
  align-items: center;
  color: var(--muted);
  padding: 6px;
  margin-right: 4px;
}
.bell:hover { color: var(--ink); }
.bell .badge {
  position: absolute;
  top: -1px;
  right: -3px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: var(--red);
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-feature-settings: "tnum" 1;
}

/* notifications list */
.notif-list { list-style: none; margin: 0; padding: 0; }
.notif {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--line);
}
.notif:last-child { border-bottom: none; }
.notif.unread { background: var(--accent-wash); }
.notif .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
}
.notif-msg { color: var(--ink); flex: 1; }
.notif-msg:hover { text-decoration: none; color: var(--accent-ink); }
.notif-time { color: var(--muted); font-size: 12px; white-space: nowrap; }
.notif.empty { color: var(--muted); justify-content: center; padding: 26px; }

.content {
  padding: 26px 28px 48px;
  width: 100%;
}

.page-head {
  display: flex;
  align-items: baseline;
  gap: 14px;
  /* Sit the title the same distance below the nav as the client-name hero, whose crumb pushes it
     down ~32px on the client page (these crumb-less pages had none). */
  margin-top: 32px;
  margin-bottom: 22px;
}
.page-head h1 {
  font-family: var(--display);
  font-weight: 600;
  /* Matches the client-name hero (.cd-title) so every page title is the same size/height. */
  font-size: 33px;
  line-height: 1.05;
  letter-spacing: -0.03em;
  margin: 0;
}
.page-head .sub {
  color: var(--muted);
  font-size: 13px;
}
/* Stack the subtitle UNDER the title, matching the Products .svc-head spacing exactly: a block
   layout, title then a 14px sub 6px below (same as .svcpage h1 + .svc-sub). */
.page-head.stacked { display: block; }
.page-head.stacked .sub { display: block; margin-top: 20px; font-size: 14px; }

/* ---------- stat cards ---------- */
.stats {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 14px;
  margin-bottom: 22px;
}
/* The tabs, filter bar and stat tiles are reused inside the per-store
   transactions panel, which (unlike the page-level /transactions view) has no
   body padding — inset them so the inputs and tiles aren't flush against the
   panel border. Scoped to direct panel children, so the page-level view (where
   these sit outside any panel) is untouched. */
.panel > .tabs,
.panel > .toolbar,
.panel > .stats {
  margin-left: 16px;
  margin-right: 16px;
}
.panel > .tabs {
  margin-top: 14px;
}
.stat {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 16px 16px 14px;
  box-shadow: var(--shadow-sm);
}
.stat .k {
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  display: flex;
  align-items: center;
  gap: 6px;
}
.stat .v {
  font-family: var(--display);
  font-weight: 600;
  font-size: 24px;
  letter-spacing: -0.02em;
  margin-top: 8px;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}
.stat .note {
  font-size: 11.5px;
  color: var(--muted);
  margin-top: 3px;
}

/* dormant — data blocked on the MarketPay feed (the signature state) */
.stat.dormant {
  border-style: dashed;
  border-color: var(--line-strong);
  box-shadow: none;
  background-image: repeating-linear-gradient(
    -45deg,
    transparent 0 7px,
    rgba(14, 23, 38, 0.022) 7px 8px
  );
}
.stat.dormant .v {
  color: var(--line-strong);
}
.stat.dormant .k {
  color: #928a7b;
}
.stat.dormant .await {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: 6px;
  font-size: 10.5px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--amber);
}
.stat.dormant .await::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--amber);
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}
/* Live-worker indicator: a pulsing green dot, used inline in the toggle button
   and the "Live worker" stat to signal the continuous poll is running. */
.live-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 7px;
  border-radius: 50%;
  background: var(--green, #1f9d55);
  vertical-align: middle;
  animation: pulse 2.4s ease-in-out infinite;
}
.btn.danger .live-dot { background: var(--red); }

/* ---------- panels ---------- */
.grid-2 {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: 16px;
}
/* Grid items default to min-width: auto, so a wide child (a nowrap table) pushes
   the column — and the whole card — past the viewport instead of scrolling inside
   it. min-width: 0 lets the column shrink so the table's overflow-x:auto contains
   it within the card (the same behaviour the full-width Transactions panel has). */
.grid-2 > * { min-width: 0; }
/* breathing room when a full-width panel follows the contact/documents grid
   (e.g. the Stores section on the client detail page) */
.grid-2 + .panel {
  margin-top: 20px;
}
.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow);
}
/* A panel that wraps a wide nowrap table (Transactions, esp. the many-column Acquired
   tab): scroll the table horizontally inside the card instead of letting it push the
   panel past the centered column and off the page. overflow clips to the border-radius,
   so the rounded frame is preserved. */
.panel.scrollx { overflow-x: auto; }
/* Space stacked panels (e.g. Transactions -> Provider accounts on the store page). */
.panel + .panel { margin-top: 16px; }
/* …but side-by-side panels in a 2-col grid must not inherit that top margin,
   otherwise the second column drops 16px and the two panels misalign. */
.grid-2 > .panel { margin-top: 0; }
/* The profile vignette sitting right below a panel (e.g. the onboarding
   "What's still needed" card) needs the same breathing room as stacked panels. */
.panel + .meta-row { margin-top: 16px; }

/* Clickable/selectable cards lift with a violet shadow on hover (doc §3). Real cards
   (pricing plans, any link-wrapped panel/tile); dense data rows keep a flat bg hover. */
a.panel,
.panel.clickable,
a.stat {
  transition:
    transform 0.18s cubic-bezier(0.2, 0.7, 0.2, 1),
    box-shadow 0.18s,
    border-color 0.18s;
}
a.panel:hover,
.panel.clickable:hover,
a.stat:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-violet);
  border-color: rgba(139, 92, 246, 0.35);
}
.panel-head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 16px;
  border-bottom: 1px solid var(--line);
  /* A head with a title, a count AND two buttons runs past a 320px phone. Let it wrap
     rather than push the page sideways. */
  flex-wrap: wrap;
}
.panel-head h2 {
  font-family: var(--display);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
}
.panel-head .count {
  font-size: 11px;
  color: var(--muted);
}
.panel-head .actions {
  margin-left: auto;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}
thead th {
  text-align: left;
  font-weight: 500;
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 9px 16px;
  border-bottom: 1px solid var(--line);
}
tbody td {
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
  vertical-align: middle;
}
tbody tr:last-child td {
  border-bottom: none;
}
td.num {
  text-align: right;
}
/* Document rows (checklist, per-owner, per-account): the label column absorbs the
   slack so the status pill and the Upload action stay grouped at the right edge
   instead of floating mid-row. */
.docs td:first-child {
  width: 100%;
}
.docs td.num {
  white-space: nowrap;
  padding-left: 6px;
}
/* Dashboard glance table: the date column reads fine a touch smaller. */
.glance td:first-child { font-size: 12px; }

.empty {
  padding: 26px 16px;
  text-align: center;
  color: var(--muted);
  font-size: 13px;
}
/* Actionable empty state: the message + a primary next step, centred. */
.empty-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}
.empty-cta > span { color: var(--muted); }

/* "Nothing here yet" on a money page: the fact, what will appear, and the one gesture that
   starts it. Replaces the counters entirely — a row of zeros is not an empty state, it is a
   grade. */
.nothing-yet {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 10px; padding: 46px 24px 50px; max-width: 44ch; margin: 0 auto;
}
.nothing-yet b { font-size: 16px; font-weight: 600; color: var(--ink); }
.nothing-yet p { margin: 0; font-size: 13.5px; line-height: 1.6; color: var(--muted); }
.nothing-yet .btn { margin-top: 6px; }
.ny-aside { font-size: 12.5px; color: var(--muted); }

/* status pills */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 600;
  padding: 3px 10px 3px 9px;
  border-radius: var(--radius-pill);
  border: 1px solid transparent;
  white-space: nowrap;
}
.pill::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
}
/* Payment status chips — exact design-system values (doc §2). Positive = green. */
.pill.ok { color: var(--ok-txt); background: var(--ok-wash); }
.pill.warn { color: var(--warn-txt); background: var(--warn-bg); }
.pill.bad { color: var(--err-txt); background: var(--err-wash); }
.pill.neutral { color: var(--ink-soft); background: var(--hover); }

/* Icon pastille — nuit ground, gold stroke icon, 44px, always flex:none (doc §1).
   The data-surface icon (transaction rows, KPI tiles) — applied in step 3. */
.ic-badge {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 13px;
  background: var(--nuit);
  color: var(--or1);
}
.ic-badge svg { width: 20px; height: 20px; stroke: var(--or1); }
.ic-badge.sm { width: 36px; height: 36px; border-radius: 11px; }
.ic-badge.sm svg { width: 17px; height: 17px; }

/* Applied MarketPay tariff, loaded into the store Channels tab. One bordered card
   per channel: header (type · family · code · method chip) then a compact rate grid
   grouped by card type. */
.pricing-slot:not(:empty) { margin: 10px 16px 16px; }
.ptar-offer { margin: 0 0 12px; color: var(--muted); font-size: 12.5px; }
.ptar { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; margin-top: 12px; }
.ptar:first-child { margin-top: 0; }
.ptar-head { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.ptar-type { font-weight: 600; font-size: 13.5px; }
.ptar-code { color: var(--muted); font-size: 12px; }
.ptar-method {
  margin-left: auto; font-size: 11px; font-weight: 600; color: var(--muted);
  padding: 2px 9px; border: 1px solid var(--line-strong); border-radius: 999px;
}
.ptar-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.ptar-table thead th {
  text-align: left; font-weight: 500; color: var(--muted); font-size: 10.5px;
  text-transform: uppercase; letter-spacing: 0.04em; padding: 0 10px 8px;
  border-bottom: 1px solid var(--line-strong);
}
.ptar-table th.num, .ptar-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.ptar-table td { padding: 7px 10px; }
.ptar-table tr.ptar-divide td { border-top: 1px solid var(--line); }
.ptar-card { font-weight: 600; color: var(--ink); vertical-align: middle; }
.ptar-zero { color: var(--muted); }
/* A cell holding brand-scoped lines (e.g. Bancontact priced apart from the other cards):
   one row per line, the scope named by a small muted tag before the price. */
.ptar-cellline { white-space: nowrap; }
.ptar-cellline + .ptar-cellline { margin-top: 2px; }
.ptar-brandtag {
  font-size: 10px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.04em;
  margin-right: 4px;
}
.ptar-note { margin: 10px 0 0; font-size: 11.5px; line-height: 1.5; color: var(--muted); }
.ptar-note .ptar-zero { font-variant-numeric: tabular-nums; }

/* Global document preview volet: opened by any [data-preview], slides in from the right,
   shows the document inline (we prefer this over a download). */
.docprev { position: fixed; inset: 0; z-index: 200; display: flex; justify-content: flex-end; }
.docprev[hidden] { display: none; }
.docprev-backdrop { position: absolute; inset: 0; background: rgba(20, 18, 14, 0.5); }
.docprev-card {
  position: relative; width: min(920px, 72vw); height: 100%;
  display: flex; flex-direction: column; background: var(--surface);
  border-left: 1px solid var(--line); box-shadow: -12px 0 40px rgba(0, 0, 0, 0.28);
}
.docprev-head {
  display: flex; align-items: center; gap: 12px; padding: 12px 16px;
  border-bottom: 1px solid var(--line);
}
.docprev-title { font-weight: 600; font-size: 13.5px; color: var(--ink); }
.docprev-open { margin-left: auto; font-size: 12px; color: #5488c4; font-weight: 600; text-decoration: none; }
.docprev-open:hover { text-decoration: underline; }
.docprev-close { border: 0; background: 0; font-size: 22px; line-height: 1; color: var(--muted); cursor: pointer; padding: 0 4px; }
.docprev-close:hover { color: var(--ink); }
.docprev-card iframe { flex: 1; width: 100%; border: 0; background: var(--surface); }
@media (max-width: 720px) { .docprev-card { width: 100%; } }
.kyc-segbar { display: flex; gap: 6px; margin: 12px 0 2px; }
.kyc-seg { height: 5px; flex: 1; border-radius: 999px; background: var(--line); }
.kyc-seg.on { background: var(--accent); }
.kyc-person { padding-top: 14px; margin-top: 14px; border-top: 1px solid var(--line); }
.kyc-person-head { display: flex; align-items: center; gap: 12px; }
.kyc-avatar {
  flex: none; width: 36px; height: 36px; border-radius: 50%;
  background: var(--accent-wash); color: var(--accent-ink);
  display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 600;
}
.kyc-person-id { min-width: 0; }
.kyc-person-name { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-weight: 500; font-size: 14px; }
.kyc-person-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.kyc-person-head > form { margin-left: auto; }
.kyc-row { display: flex; align-items: center; gap: 10px; margin-top: 12px; }
.kyc-row-icon { flex: none; color: var(--muted); display: inline-flex; font-size: 15px; line-height: 1; }
.kyc-row-icon svg { width: 18px; height: 18px; }
.kyc-row-main { flex: 0 1 auto; min-width: 0; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.kyc-row-name { font-size: 13px; font-weight: 500; }
.kyc-row-sub { font-size: 11.5px; color: var(--muted); }
.kyc-row-rejected { color: var(--red); }
.kyc-row-status { flex: none; }
.kyc-row-actions { flex: none; margin-left: auto; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.kyc-signproof { margin: 8px 0 0 28px; }
.kyc-legend {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--line);
  font-size: 11.5px; color: var(--muted);
}
.kyc-legend .dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; vertical-align: middle; }
.btn.icon-btn { display: inline-flex; align-items: center; gap: 5px; }
.btn.icon-btn svg { width: 14px; height: 14px; }
.olink-copy.icon-btn .olink-copy-default { display: inline-flex; align-items: center; gap: 5px; }

/* buttons */
.btn {
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  border-radius: var(--radius-pill);
  padding: 8px 18px;
  border: 1px solid var(--line-strong);
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  transition:
    transform 0.15s cubic-bezier(0.2, 0.7, 0.2, 1),
    box-shadow 0.15s,
    background 0.15s,
    border-color 0.15s;
}
.btn:hover { background: var(--hover); }
/* Primary = the ONE gold CTA per screen: gold-gradient pill, nuit text, gold glow. */
.btn.primary {
  background: var(--grad-or);
  border-color: transparent;
  color: var(--nuit);
  box-shadow: 0 6px 24px rgba(255, 214, 10, 0.35);
}
.btn.primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 30px rgba(255, 214, 10, 0.45);
}
/* Secondary = nuit workhorse (lifts with a violet shadow on hover). */
.btn.nuit {
  background: var(--nuit);
  border-color: var(--nuit);
  color: #fff;
}
.btn.nuit:hover {
  background: var(--primary-bg-hover);
  border-color: var(--primary-bg-hover);
  transform: translateY(-1px);
  box-shadow: var(--shadow-violet);
}
.btn.ghost { border-color: transparent; background: transparent; color: var(--muted); padding: 6px 12px; }
.btn.ghost:hover { background: var(--hover); color: var(--ink); }
.btn.link { border: none; background: none; padding: 0; border-radius: 0; color: var(--muted); }
.btn.link:hover { color: var(--accent-ink); text-decoration: underline; }
.btn.link.danger { color: var(--err-txt); }
.btn.link.danger:hover { color: var(--err-txt); }
/* Destructive button (doc §Boutons): red text on a red wash + a red-tinted border, in
   BOTH themes (no hardcoded colour). Hover intensifies the wash + border — never a solid
   red fill ("jamais de rouge plein"). */
.btn.danger { color: var(--err-txt); border-color: var(--err-line); background: var(--red-wash); }
.btn.danger:hover { background: rgba(229, 72, 77, 0.2); border-color: var(--err-txt); color: var(--err-txt); }
/* Same box as a plain .btn (like "Edit"), just a red icon; deepens to a red wash on hover. */
.btn.danger-icon { color: var(--err-txt); }
.btn.danger-icon:hover { background: var(--red-wash); border-color: var(--err-txt); color: var(--err-txt); }
.del-form { display: inline; margin: 0; }
.row-actions { display: flex; gap: 12px; justify-content: flex-end; align-items: center; }
.btn.small { padding: 4px 9px; font-size: 12px; }

/* table pager (per-store transactions) */
.pager {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 14px;
  padding: 10px 16px;
  border-top: 1px solid var(--line);
  font-size: 12.5px;
}

/* clickable transaction rows + right-side detail drawer */
.txn-row { cursor: pointer; }
.txn-row:hover { background: var(--hover); }

/* A right-side overlay drawer, matching the pay-by-link creation drawer (.pbl-drawer): full
   height, scrim, slide-in — instead of the old panel docked below the topbar. */
#txn-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(460px, 100%);
  background: var(--surface);
  border-left: 1px solid var(--line);
  box-shadow: -30px 0 80px rgba(0, 0, 0, 0.35);
  z-index: 1600; /* a true overlay above the topbar, like .pbl-drawer */
  overflow-y: auto;
}
#txn-panel:empty { display: none; }
#txn-panel:not(:empty) { animation: txn-drawer-in 0.4s cubic-bezier(0.2, 0.7, 0.2, 1); }
@keyframes txn-drawer-in {
  from { transform: translateX(105%); }
  to { transform: none; }
}
/* Dim + click-to-close scrim, shown while the drawer holds content (same look as .pbl-scrim). */
#txn-scrim {
  position: fixed;
  inset: 0;
  background: rgba(4, 8, 16, 0.55);
  backdrop-filter: blur(2px);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s;
  z-index: 1500;
}
body:has(#txn-panel:not(:empty)) #txn-scrim {
  opacity: 1;
  pointer-events: auto;
}
@media (prefers-reduced-motion: reduce) {
  #txn-panel:not(:empty) { animation: none; }
  #txn-scrim { transition: none; }
}
.drawer-card { padding: 22px 24px 44px; }
.drawer-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 16px;
}
.drawer-kicker {
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.drawer-id { font-size: 13px; margin-top: 2px; word-break: break-all; }
.drawer-close {
  font: inherit;
  font-size: 22px;
  line-height: 1;
  border: none;
  background: none;
  color: var(--muted);
  cursor: pointer;
  padding: 0 4px;
}
.drawer-close:hover { color: var(--ink); }

/* Compact inline marker for table cells (e.g. "Imported", "Phone"). */
.tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--canvas);
  border: 1px solid var(--line);
  color: var(--muted-strong);
  font-size: 10.5px;
  font-weight: 600;
  white-space: nowrap;
  vertical-align: middle;
}
html[data-theme="dark"] .tag { background: #111a29; }
/* Refund: a transaction that pays money back (negative against volume). */
.tag.refund { color: var(--red); border-color: #e3bbb2; background: var(--red-wash); }
.amount.refund { color: var(--red); }

/* Jump link from an acquired transaction back to its accepted one. */
.drawer-link {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin: 4px 0 12px;
  padding: 7px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  color: var(--accent-ink);
  font-size: 13px;
  text-decoration: none;
}
.drawer-link:hover { border-color: var(--accent); background: var(--canvas); }

/* collapsible field groups (Acceptance / Transaction / Settlement / Merchant) */
.drawer-group { border-top: 1px solid var(--line); }
.drawer-group > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 0 8px;
  font-family: var(--display);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.drawer-group > summary::-webkit-details-marker { display: none; }
.drawer-group > summary::before {
  content: "›";
  font-size: 15px;
  line-height: 1;
  color: var(--muted);
  transition: transform 0.15s ease;
}
.drawer-group[open] > summary::before { transform: rotate(90deg); }
.drawer-group .gcount {
  margin-left: auto;
  color: var(--muted);
  font-size: 10.5px;
  font-weight: 400;
  letter-spacing: 0;
}
.drawer-group .kv { padding-bottom: 10px; }
.kv { margin: 0; }
.kv > div {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 5px 0;
}
.kv dt { margin: 0; color: var(--muted); font-size: 12.5px; }
.kv dd { margin: 0; text-align: right; font-size: 13px; }
.refund-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 2px 0 12px; }
.refund-note { margin: 0; color: var(--muted); font-size: 12.5px; }
.refund-dialog .banner { margin: 0 0 14px; }
.refund-dialog .field input { width: 100%; }
.drawer-raw { margin-top: 18px; }
.drawer-raw summary { cursor: pointer; font-size: 12.5px; color: var(--muted); }
.drawer-raw pre {
  margin: 8px 0 0;
  background: var(--ink);
  color: #cbd5e2;
  border-radius: var(--radius-sm);
  padding: 12px;
  overflow-x: auto;
  font-size: 11.5px;
  line-height: 1.5;
}
/* Pretty-printed payload: keep newlines (override .mono's nowrap) and wrap long
   lines (XML/URLs) instead of forcing a wide horizontal scroll. */
.drawer-raw pre.payload { white-space: pre-wrap; overflow-wrap: anywhere; }
/* In night mode --ink is light, so the default bg would clash with the light text;
   pin a dark code background instead. */
html[data-theme="dark"] .drawer-raw pre { background: #0c1320; color: #cbd5e2; }

/* ---------- login ---------- */
.auth {
  min-height: 100vh;
  display: grid;
  place-items: center;
  background:
    radial-gradient(1100px 520px at 50% -10%, var(--accent-wash) 0%, transparent 55%),
    var(--canvas);
  padding: 24px;
}
.auth-card {
  width: 100%;
  max-width: 372px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow);
  padding: 30px 28px;
}
.auth .brand {
  display: flex;
  align-items: center;
  gap: 9px;
  color: var(--ink);
  font-family: var(--display);
  font-weight: 600;
  letter-spacing: -0.02em;
  padding: 0 0 6px;
  font-size: 20px;
}
.auth .brand .brand-mark {
  width: 26px;
  height: 26px;
  object-fit: contain;
}
.auth h1 {
  font-family: var(--display);
  font-size: 17px;
  font-weight: 600;
  margin: 14px 0 2px;
}
.auth .lede {
  color: var(--muted);
  font-size: 13px;
  margin: 0 0 20px;
}
.field {
  margin-bottom: 14px;
}
.field label {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-soft);
  margin-bottom: 5px;
}
.field input {
  width: 100%;
  font: inherit;
  font-size: 14.5px;
  padding: 10px 14px;
  border: 1.5px solid var(--line-strong);
  border-radius: var(--radius-input);
  background: var(--surface);
  color: var(--ink);
  transition: border-color 0.15s, box-shadow 0.15s;
}
/* Focus = violet border + soft violet halo (doc §2). */
.field input:focus {
  outline: none;
  border-color: var(--violet);
  box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.12);
}
.btn.block { width: 100%; justify-content: center; padding: 10px; }

/* secondary link row under an auth form (e.g. "Forgot your password?") */
.auth-alt { margin: 16px 0 0; font-size: 13px; text-align: center; color: var(--muted); }
.auth-alt a { color: var(--accent-ink); }

.flash {
  border-radius: var(--radius-sm);
  padding: 9px 12px;
  font-size: 13px;
  margin-bottom: 14px;
}
.flash.error { background: var(--red-wash); color: var(--red); border: 1px solid #f1cccc; }
.flash.ok { background: var(--accent-wash); color: var(--accent-ink); border: 1px solid #c3e6da; }

/* one-time secret reveal (a freshly minted API key) */
.flash.secret {
  background: var(--amber-wash);
  border: 1px solid #e6d4ad;
  color: var(--ink);
}
.flash.secret .secret-head {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--amber);
  margin-bottom: 8px;
}
.flash.secret .copy-row { padding: 0; }
.flash.secret .copy-row input { background: #fff; color: var(--ink); }

.keys-panel { margin-top: 16px; }

/* ---------- breadcrumbs ---------- */
.crumbs {
  font-size: 12.5px;
  color: var(--muted);
  margin-bottom: 6px;
}
.crumbs a { color: var(--muted); }
.crumbs span { margin: 0 7px; color: var(--line-strong); }

/* ---------- client meta row ---------- */
.meta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 36px;
  margin: 2px 0 22px;
  padding: 15px 20px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow);
}
.meta .k {
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.meta .mv {
  margin-top: 3px;
  font-size: 14px;
}

/* ---------- inline create form (details popover) ---------- */
.page-head .head-actions { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.page-head .head-actions form { margin: 0; }

.disclosure {
  position: relative;
  display: inline-block;
}
.disclosure > summary {
  list-style: none;
  cursor: pointer;
}
.disclosure > summary::-webkit-details-marker { display: none; }
.disclosure.right { margin-left: auto; }
/* An open menu hangs below its card: that card comes in front of the next one, which would
   otherwise be painted over the menu (Settings > Team, a person's Change role). */
.panel:has(details.disclosure[open]),
.card:has(details.disclosure[open]) { position: relative; z-index: 20; }

.card-form {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  z-index: 20;
  width: 320px;
  max-width: calc(100vw - 32px);
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius);
  box-shadow: 0 12px 32px -12px rgba(14, 23, 38, 0.32);
  padding: 16px;
}
.card-form .field:last-of-type { margin-bottom: 16px; }
/* Rejecting a document: Other's comment, styled as the inputs around it. */
.reject-doc .field textarea {
  width: 100%;
  font: inherit;
  font-size: 14px;
  padding: 9px 11px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
  resize: vertical;
}
.reject-doc .field textarea:focus {
  outline: none;
  border-color: var(--violet);
  box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.12);
}
/* The owner's review controls on a document row: Verify (the row's one filled button),
   Reject, Reopen. They replaced a status menu. */
.review-form { display: inline; margin: 0; }
.review-inline { display: inline-flex; gap: 8px; align-items: center; margin-left: 8px; }
.verif-card .btn-doc.verify { background: var(--primary-bg); color: var(--primary-fg); border-color: transparent; }
.verif-card .btn-doc.verify:hover { background: var(--primary-bg-hover); border-color: transparent; }

/* The onboarding file's strip, on the client page: one figure (verified
   over the whole file, the go-live bar), what waits on us, what waits on the client, and
   going live. "To review" is violet like the Received badge it counts. */
.file-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(210px, 100%), 1fr));
  gap: 20px 22px;
  background: var(--cd-card, var(--surface));
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-sm);
  padding: 22px 26px;
  margin-bottom: 18px;
}
.fs-cell { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.fs-k { font-size: var(--fs-kicker); font-weight: 600; letter-spacing: 0.11em; text-transform: uppercase; color: var(--muted); }
.fs-big { font-size: 13.5px; color: var(--muted); }
.fs-big b { font-size: 26px; font-weight: 700; color: var(--ink); margin-right: 4px; font-variant-numeric: tabular-nums; }
.fs-bar { display: flex; height: 7px; border-radius: 999px; overflow: hidden; background: var(--line-strong); }
.fs-bar i { display: block; height: 100%; }
.fs-ok { background: var(--ok); }
.fs-rev { background: var(--violet); }
.fs-miss { background: #cbd5e1; }
[data-theme="dark"] .fs-miss { background: rgba(255, 255, 255, 0.18); }
.fs-legend { display: flex; flex-wrap: wrap; gap: 4px 12px; font-size: 12px; color: var(--muted); }
.fs-legend b { font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.fs-legend .t-ok { color: var(--ok-txt); }
.fs-legend .t-rev { color: var(--violet-txt); }
[data-theme="dark"] .fs-legend .t-ok { color: #6ee7b7; }
[data-theme="dark"] .fs-legend .t-rev { color: #c4b5fd; }
.fs-v { font-size: 15px; font-weight: 600; color: var(--ink); }
.fs-v.fs-quiet { color: var(--muted); font-weight: 500; }
.fs-sub { font-size: 12.5px; color: var(--muted); line-height: 1.5; }
.fs-cell form { margin: 4px 0 0; }
/* The identity fields read as checklist rows; their mark is a glyph, not an emoji. */
.verif-card .id-row .dico { font-size: 13px; font-weight: 700; color: var(--ok-txt); }
.verif-card .sec-head .n { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* A client's history (client page, Activity tab): newest first, a line joining the dots. */
.history { list-style: none; margin: 0; padding: 0; }
.hist-item { display: grid; grid-template-columns: 12px minmax(0, 1fr); column-gap: 14px; padding: 0 0 16px; position: relative; }
.hist-item:not(:last-child)::before { content: ""; position: absolute; left: 5px; top: 18px; bottom: 2px; width: 2px; background: var(--cd-line, var(--line-strong)); }
.hist-dot { width: 12px; height: 12px; border-radius: 50%; margin-top: 4px; background: var(--muted); }
.hist-dot.t-client { background: var(--violet); }
.hist-dot.t-done { background: var(--ok); }
.hist-dot.t-bad { background: var(--err); }
.hist-dot.t-team { background: var(--ink-soft); }
.hist-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.hist-body b { font-weight: 600; font-size: 13.5px; color: var(--ink); }
.hist-detail { font-size: 12.5px; color: var(--muted); }
.hist-detail.bad { color: var(--err-txt); }
.hist-meta { font-size: 11.5px; color: var(--muted); }

/* ---- The onboarding inbox (onboarding_board.html): the merchant's vignette drawn three times
   at one height, the queue, the file and the document. White card, one 88px band, one 56px
   row, one kicker, one status column, one ink selection mark, and exactly one gold fill on
   the screen, Verify. Every rule sits under .rv, the page's root, so nothing here reaches
   another page; the tokens come from the top of this file and dark mode is their job, the
   few literal colours below have their [data-theme="dark"] pair next to them. ---- */
.rv { --rv-card: var(--surface); --rv-line: var(--card-line); --rv-sep: var(--line); --rv-wash: var(--hover);
  /* above the cards: topbar 58 + content padding 26 + page-head margin 32 + h1 35 + margin
     22; under them 26 (the content's 48px bottom padding, less the -22px margin). A flash
     banner adds its 40px (its 14px margin collapses into the head's 32), a second one 54
     more; the Partner view bar above the shell adds 49 */
  --rv-top: 173px;
  display: grid; grid-template-columns: 280px minmax(0, 1fr) minmax(0, 1.4fr); gap: 22px; align-items: stretch;
  width: 100%; max-width: none; height: calc(100vh - var(--rv-top) - 26px - var(--rv-flash, 0px)); min-height: 480px; margin-bottom: -22px }
.content:has(> .flash) > .rv { --rv-flash: 40px }
.content:has(> .flash + .flash) > .rv { --rv-flash: 94px }
body:has(.preview-bar) .rv { --rv-top: 222px }
[data-theme="dark"] .rv { --rv-card: rgba(255, 255, 255, 0.035) }
.rv .rv-card { background: var(--rv-card); border: 1px solid var(--rv-line); border-radius: var(--radius-card); box-shadow: var(--shadow-sm); min-width: 0; min-height: 0; display: flex; flex-direction: column }
[data-theme="dark"] .rv .rv-card { box-shadow: none }
.rv .rv-queue, .rv .rv-file { overflow: hidden }
.rv .rv-file { container-type: inline-size }
/* the document card lets the reject popover out; it takes the focus for the keys, its
   buttons and links carry the visible rings */
.rv .rv-doc { overflow: visible }
.rv .rv-doc:focus { outline: none }

/* the one band: 88px, a hairline under it that meets across the gutters */
.rv .rv-head { flex: none; height: 88px; box-sizing: border-box; padding: 0 22px; display: flex; align-items: center; gap: 14px; border-bottom: 1px solid var(--rv-sep) }
.rv .rv-name { min-width: 0; flex: 1 }
.rv .rv-name h2 { margin: 0; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; line-height: 1.3; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis }
.rv .rv-doc .rv-name h2 { font-size: 22px; letter-spacing: -0.02em; line-height: 1.15 }
.rv .rv-name span { display: block; margin-top: 3px; font-size: 12px; font-weight: 400; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums }
.rv .rv-end { margin-left: auto; flex: none; display: flex; align-items: center; gap: 14px }

/* the one kicker, the one link, the one status */
.rv .rv-k { font-size: 10.5px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); line-height: 1.4 }
/* 4px above and below, as every .link-vio has, so a link keeps a 24px target */
.rv .link-vio { display: inline-block; font: inherit; font-size: 12px; font-weight: 500; line-height: 1.4; color: var(--accent-ink); text-decoration: none; background: none; border: 0; padding: 4px 0; cursor: pointer; white-space: nowrap; list-style: none }
.rv .link-vio:hover { text-decoration: underline }
.rv .link-vio:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; border-radius: 4px }
.rv .st { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 500; white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--muted) }
.rv .st i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none }
.rv .st.ok { color: var(--ok-txt) }
.rv .st.pend { color: var(--warn-txt) }
.rv .st.rej { color: var(--err-txt) }
.rv .st.wait { color: var(--muted) }

/* queue: the tools in the band */
.rv .rv-tools { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px }
.rv .rv-tools form { display: flex; gap: 6px; margin: 0 }
.rv .rv-tools input[type="search"] { flex: 1; min-width: 0; height: 34px; box-sizing: border-box; font: inherit; font-size: 13.5px; font-weight: 500; padding: 0 12px; border: 1px solid var(--line-strong); border-radius: 999px; background: var(--rv-card); color: var(--ink) }
/* the global dark input fill outranks the rule above; the search keeps the select's fill */
html[data-theme="dark"] .rv .rv-tools input[type="search"] { background: var(--rv-card) }
.rv .rv-tools input::placeholder { color: var(--muted); font-weight: 400 }
.rv .rv-tools select { flex: none; height: 34px; box-sizing: border-box; font: inherit; font-size: 12px; font-weight: 500; padding: 0 6px 0 10px; border: 1px solid var(--line-strong); border-radius: 999px; background: var(--rv-card); color: var(--ink) }
.rv .rv-tools input:focus-visible, .rv .rv-tools select:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 1px }
/* the row scrolls sideways when the chips do not fit; its 4px padding (taken back by the
   margin) keeps a chip's focus ring inside the scroll box */
.rv .rv-chips { display: flex; align-items: center; gap: 12px; padding: 4px; margin: -4px; overflow-x: auto; scrollbar-width: none }
.rv .rv-chips::-webkit-scrollbar { display: none }
.rv .rv-chip { display: inline-flex; align-items: baseline; gap: 5px; font-size: 12px; font-weight: 500; color: var(--muted); text-decoration: none; padding: 2px 0; border-bottom: 1.5px solid transparent; white-space: nowrap; font-variant-numeric: tabular-nums; flex: none }
.rv .rv-chip:hover { color: var(--ink); text-decoration: none }
.rv .rv-chip.on { color: var(--ink); font-weight: 600; border-bottom-color: var(--ink) }
.rv .rv-chip span { color: var(--muted); font-weight: 500 }
.rv .rv-chip:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; border-radius: 4px }

/* queue: the lanes, the rows, the age on one x */
.rv .rv-lanes { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain }
.rv .rv-lane { margin: 0; min-height: 44px; box-sizing: border-box; padding: 16px 22px 6px; display: flex; align-items: center; gap: 8px; list-style: none }
.rv .rv-lane .rv-chev { margin-left: auto }
.rv details.rv-group > summary.rv-lane { cursor: pointer }
.rv details.rv-group > summary.rv-lane::-webkit-details-marker { display: none }
.rv details.rv-group > summary.rv-lane:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: -2px }
.rv details.rv-group[open] > summary.rv-lane .rv-chev { transform: rotate(180deg) }
.rv .rv-list { list-style: none; margin: 0; padding: 0 }
.rv .rv-list > li + li { border-top: 1px solid var(--rv-sep) }
.rv .rv-item { display: flex; align-items: center; gap: 12px; min-height: 56px; box-sizing: border-box; padding: 10px 22px; color: var(--ink); text-decoration: none }
.rv .rv-item:hover { background: var(--card-hover); text-decoration: none }
.rv .rv-item.on { background: var(--rv-wash); box-shadow: inset 3px 0 0 var(--ink) }
/* on the wash, the 12px muted text takes the stronger muted to keep 4.5:1 */
.rv .rv-item.on .rv-m span, .rv .rv-item.on .rv-age, .rv .rv-item.on .st.wait,
.rv .rv-row.is-cur .rv-m span { color: var(--muted-strong) }
.rv .rv-item:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: -2px }
.rv .rv-age { flex: none; font-size: 12px; font-weight: 500; color: var(--muted); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap }
.rv .rv-item .st { flex: none }
.rv .rv-m { min-width: 0; flex: 1 }
.rv .rv-m b, .rv .rv-m .rv-t { display: block; font-size: 13.5px; font-weight: 500; color: var(--ink); line-height: 1.3; text-decoration: none; overflow-wrap: anywhere }
.rv .rv-m .rv-t:hover { color: var(--accent-ink); text-decoration: underline }
.rv .rv-m .rv-t:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px; border-radius: 4px }
.rv .rv-m span { display: block; font-size: 12px; font-weight: 400; color: var(--muted); margin-top: 2px; line-height: 1.5 }
.rv .rv-m span time { white-space: nowrap }
.rv .rv-m span.bad { color: var(--err-txt) }

/* file: steps and lines on one grid (bubble | title | status | gesture), so every dot sits
   on one x; the steps scroll under the band, Go live stays at the foot */
.rv .rv-steps { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain }
.rv .rv-step + .rv-step, .rv .rv-stray { border-top: 1px solid var(--rv-sep) }
.rv .rv-stray > .rv-row:first-child { border-top: 0 }
.rv .rv-step > summary, .rv .rv-row { list-style: none; display: grid; grid-template-columns: 20px minmax(0, 1fr) 110px 48px; column-gap: 14px; align-items: center; box-sizing: border-box; padding: 0 22px }
.rv .rv-step > summary { min-height: 44px; cursor: pointer }
.rv .rv-step > summary::-webkit-details-marker { display: none }
.rv .rv-step > summary:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: -2px }
.rv .rv-step > summary .rv-k { grid-column: 2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis }
.rv .rv-step > summary .st { grid-column: 3 }
.rv .rv-step > summary .rv-chev { grid-column: 4 }
.rv .rv-step[open] > summary .st { display: none }
.rv .bub { width: 20px; height: 20px; border-radius: 50%; display: grid; place-items: center; font-size: 10.5px; font-weight: 500; border: 1.5px solid var(--line-strong); color: var(--muted); background: var(--rv-card); box-sizing: border-box; font-variant-numeric: tabular-nums }
.rv .rv-chev { color: var(--muted); display: block; justify-self: end; transition: transform 0.2s }
.rv .rv-step[open] > summary .rv-chev { transform: rotate(180deg) }
@media (prefers-reduced-motion: reduce) { .rv .rv-chev { transition: none } }
.rv .rv-row { min-height: 56px; padding-top: 10px; padding-bottom: 10px; border-top: 1px solid var(--rv-sep) }
.rv .rv-row > .rv-m { grid-column: 2 }
.rv .rv-row > .st { grid-column: 3; justify-self: start }
.rv .rv-row > .rv-end { grid-column: 4; justify-self: end; margin-left: 0 }
.rv .rv-row.is-done .rv-m b { color: var(--muted) }
.rv .rv-row.is-cur { background: var(--rv-wash); box-shadow: inset 3px 0 0 var(--ink) }
.rv .rv-golive { flex: none; border-top: 1px solid var(--rv-sep); padding-bottom: 18px }
.rv .rv-golive .rv-row { border-top: 0; min-height: 44px }
.rv .rv-golive-body { padding: 0 22px 0 56px }
.rv .rv-golive-body .fs-sub { font-size: 12px; font-weight: 400; color: var(--muted); line-height: 1.6; margin-top: 2px }
.rv .rv-golive-body form { margin-top: 10px }
/* never two gold buttons: with a Verify on the screen, Go live is the nuit workhorse */
.rv:has(.rv-doc .btn-sm-or) .rv-golive-body .btn.primary { background: var(--nuit); color: #ffffff; box-shadow: none }
[data-theme="dark"] .rv:has(.rv-doc .btn-sm-or) .rv-golive-body .btn.primary { background: #1b2740; color: #e8edf4; border-color: #2a3852 }

/* document: the facts and the verdict first (side by side from 1800px, where the card is
   690 wide; stacked under it), then the page on a canvas well that takes the rest of the
   card's height */
.rv .rv-doc-body { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 18px; padding: 18px 22px 22px }
.rv .rv-side { flex: none; display: flex; align-items: flex-start; gap: 22px }
.rv .rv-facts { margin: 0; flex: 1 1 auto; min-width: 0 }
.rv .rv-facts > div { display: grid; grid-template-columns: 116px minmax(0, 1fr); column-gap: 10px; align-items: baseline; min-height: 28px; padding: 5px 0; border-top: 1px solid var(--rv-sep) }
.rv .rv-facts > div:first-child { border-top: 0; padding-top: 0 }
/* a fact's key labels a value, not a section: the Small style, not the kicker */
.rv .rv-facts dt { font-size: 12px; font-weight: 400; line-height: 16px; color: var(--muted) }
.rv .rv-facts dd { margin: 0; font-size: 13px; font-weight: 500; line-height: 18px; color: var(--ink); overflow-wrap: anywhere }
.rv .rv-facts dd.mono { font-family: var(--mono) }
.rv .rv-facts dd.bad { color: var(--err-txt) }
.rv .rv-act { flex: none; max-width: 320px; display: flex; flex-direction: column; align-items: flex-end; text-align: right; gap: 6px }
.rv .rv-verdict { display: flex; align-items: center; gap: 10px }
.rv .rv-next { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px 10px; max-width: 100%; font-size: 12px; font-weight: 500; line-height: 16px; color: var(--muted); font-variant-numeric: tabular-nums }
.rv .rv-next a { display: inline-block; padding: 4px 0; color: var(--accent-ink); text-decoration: none; max-width: 100%; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis }
.rv .rv-next a:hover { text-decoration: underline }
.rv .rv-keys { margin: 0; font-size: 12px; font-weight: 400; line-height: 16px; color: var(--muted) }
/* the page is paper: white on both themes (the literal is meant for dark too), on the
   canvas well, with the card's own edge */
.rv .rv-page { flex: 1 1 auto; margin: 0; min-width: 0; min-height: 180px; display: flex; justify-content: center; align-items: flex-start; padding: 14px; box-sizing: border-box; background: var(--canvas); border-radius: 12px; overflow: hidden }
.rv .rv-page img { display: block; max-width: 100%; max-height: 100%; width: auto; height: auto; background: #ffffff; border: 1px solid var(--rv-line) }
.rv .rv-nofile { margin: auto; font-size: 12px; font-weight: 400; color: var(--muted) }
/* Verify: the one gold fill on the view, dark text on it on both themes (the literal is
   meant for dark too) */
.rv .btn-sm-or { display: inline-flex; align-items: center; height: 32px; box-sizing: border-box; padding: 0 16px; border-radius: 999px; background: var(--grad-or); color: #20180a; font: inherit; font-size: 12px; font-weight: 600; border: 0; cursor: pointer; white-space: nowrap; text-decoration: none; box-shadow: none; transition: transform 0.15s }
.rv .btn-sm-or:hover { transform: translateY(-1px) }
.rv .btn-sm-or:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px }
@media (prefers-reduced-motion: reduce) { .rv .btn-sm-or { transition: none } .rv .btn-sm-or:hover { transform: none } }
/* Reject: the destructive style, red text on a red wash with a red line, never solid red */
.rv .btn-sm-rj { display: inline-flex; align-items: center; height: 32px; box-sizing: border-box; padding: 0 16px; border-radius: 999px; font: inherit; font-size: 12px; font-weight: 600; color: var(--err-txt); background: var(--red-wash); border: 1px solid var(--err-line); cursor: pointer; list-style: none; white-space: nowrap }
.rv .btn-sm-rj::-webkit-details-marker { display: none }
.rv .btn-sm-rj:hover { background: rgba(229, 72, 77, 0.2); border-color: var(--err-txt) }
[data-theme="dark"] .rv .btn-sm-rj:hover { background: rgba(229, 72, 77, 0.3) }
.rv .btn-sm-rj:focus-visible { outline: 2px solid var(--accent-ink); outline-offset: 2px }
.rv .reject-doc { position: relative; margin-left: 0 }
/* the reasons open under the button, over the page: from its right edge while the verdict
   sits at the card's right (1800px and up), from its left edge once it is stacked under
   the facts. The submit is destructive too, so the popover never adds a second gold
   button */
.rv .reject-doc .card-form { left: auto; right: 0; top: calc(100% + 8px); bottom: auto; text-align: left; font-size: 13px }
.rv .reject-doc .card-form .btn.primary { background: var(--red-wash); color: var(--err-txt); border: 1px solid var(--err-line); box-shadow: none; transform: none }
.rv .reject-doc .card-form .btn.primary:hover { background: rgba(229, 72, 77, 0.2); border-color: var(--err-txt) }
[data-theme="dark"] .rv .reject-doc .card-form .btn.primary:hover { background: rgba(229, 72, 77, 0.3) }
.rv .rv-empty { margin: auto; padding: 26px 22px; display: flex; flex-direction: column; align-items: center; gap: 6px; text-align: center }
.rv .rv-lanes > .rv-empty { margin: 0 }
.rv .rv-empty b { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; color: var(--ink) }
.rv .rv-empty span { font-size: 12px; font-weight: 400; color: var(--muted); line-height: 1.5 }
.rv .rv-empty .link-vio { margin-top: 4px }
.rv .olink-copy-done { color: var(--ok-txt) }
/* read by a screen reader, not drawn: the copy link's "Copied" */
.rv .rv-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0 }

/* widths: the document gets the growth, the queue stays a column. Under 1800px the
   document card is under 690 wide: the facts over the verdict, so every value keeps 200px
   beside its label (an IBAN on one line) */
@media (max-width: 1799px) {
  /* stacked, the document card needs about 550px (band, facts, verdict, a 180px well):
     below that the page scrolls rather than the well spilling out of its card */
  .rv { grid-template-columns: 280px minmax(0, 1fr) minmax(0, 1.3fr); min-height: 560px }
  .rv .rv-side { flex-direction: column; gap: 14px }
  .rv .rv-act { max-width: none; align-items: flex-start; text-align: left; padding-top: 10px; border-top: 1px solid var(--rv-sep); align-self: stretch }
  .rv .rv-next { justify-content: flex-start }
  .rv .reject-doc .card-form { left: 0; right: auto }
}
@media (max-width: 1399px) {
  .rv { grid-template-columns: 280px minmax(0, 1fr) minmax(0, 1.2fr); gap: 18px }
}
/* under 1280px the three cards stack (side by side, the document card would be narrower
   than the 320px reasons popover and the file's titles under 120px); the page scrolls */
@media (max-width: 1279px) {
  .rv { grid-template-columns: minmax(0, 1fr); gap: 18px; height: auto; min-height: 0; margin-bottom: 0 }
  .rv .rv-lanes, .rv .rv-steps { overflow: visible }
  .rv .rv-page { flex: none }
  .rv .rv-page img { max-height: 60vh }
}
/* a file pane under 420 (1280 to 1600 screens): the status drops under the title on the
   same indent, so the title keeps the width the status column took */
@container (max-width: 420px) {
  .rv .rv-step > summary, .rv .rv-row { grid-template-columns: 20px minmax(0, 1fr) 48px; row-gap: 4px }
  .rv .rv-step > summary .st, .rv .rv-row > .st { grid-column: 2; grid-row: 2; justify-self: start }
  .rv .rv-step > summary .rv-chev, .rv .rv-row > .rv-end { grid-column: 3; grid-row: 1 / 3 }
}
/* under 360 (a 1280 screen) the band's two links stack, so the client's name keeps its width */
@container (max-width: 360px) {
  .rv .rv-head .rv-end { flex-direction: column; align-items: flex-end; gap: 4px }
}

/* The merchant's numbered bubble, as the owner and bank forms draw it on the client page. */
.bub { width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; font-size: 10.5px; font-weight: 500; flex: none; border: 1.5px solid var(--line-strong); color: var(--muted); background: var(--cd-card, var(--surface)); box-sizing: border-box }
/* Inline onboarding-wizard form (not a popover like .card-form). */
.onboard-form { max-width: 620px; text-align: left; }
.onboard-form .form-section-label {
  margin: 18px 0 10px;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--muted);
}
.onboard-form .form-section-label:first-of-type { margin-top: 0; }
/* VAT search box + matched-company vignette in the onboarding wizard. */
.vat-search { display: flex; gap: 8px; }
.vat-search input { flex: 1; }
/* Company "entity" card — header (avatar + name + sub + status) over a labelled
   field grid. Used by the VAT-search preview and the read-only step-1 identity view.
   Values render uppercase, like the rest of the app. */
.company-card {
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  overflow: hidden;
  margin: 4px 0 16px;
}
.company-card .cc-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 13px 15px;
  border-bottom: 1px solid var(--line);
}
.company-card .cc-avatar {
  width: 38px;
  height: 38px;
  border-radius: 9px;
  flex: none;
  display: grid;
  place-items: center;
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-family: var(--display);
  font-weight: 600;
  font-size: 14px;
}
.company-card .cc-title { min-width: 0; flex: 1; }
.company-card .cc-name {
  font-family: var(--display);
  font-weight: 600;
  font-size: 14.5px;
  color: var(--ink);
  letter-spacing: 0.01em;
  line-height: 1.2;
  text-transform: uppercase;
}
.company-card .cc-sub { font-size: 11.5px; color: var(--muted); margin-top: 2px; text-transform: uppercase; }
.company-card .cc-head .pill { margin-left: auto; align-self: flex-start; }
.company-card .cc-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 18px;
  padding: 14px 15px;
}
.company-card .cc-field.wide { grid-column: 1 / -1; }
.company-card .cc-field .k {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
.company-card .cc-field .v {
  font-size: 12.5px;
  color: var(--ink);
  margin-top: 2px;
  text-transform: uppercase;
  word-break: break-word;
}
@media (max-width: 560px) {
  .company-card .cc-grid { grid-template-columns: 1fr; }
}
.form-alert {
  border: 1px solid var(--red);
  background: var(--red-wash);
  color: var(--red);
  border-radius: var(--radius-sm);
  padding: 10px 13px;
  font-size: 13px;
  margin: 4px 0 16px;
}
/* A required field flagged empty on submit. */
.field input.input-error,
.field select.input-error {
  border-color: var(--red);
  box-shadow: 0 0 0 1px var(--red);
}
/* The per-account RIB cell in the Bank accounts table: file + status + upload,
   laid out on one line that wraps on narrow screens. */
.rib-cell {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.rib-cell .rib-file {
  min-width: 90px;
}
/* International phone input (tel-input.js): country selector glued to the national
   field. The national input keeps .field input styling; the button matches it. */
/* One unified control: the border + focus ring live on the wrapper, the button and
   field are transparent inside it, with a single divider between them. */
.tel-input {
  display: flex;
  position: relative;
  min-width: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
}
.tel-input .tel-national {
  min-width: 0;
}
.tel-input:focus-within {
  border-color: var(--violet);
  box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.12);
}
.tel-input .tel-national {
  width: auto;
  flex: 1;
  border: 0;
  border-radius: 0;
  background: transparent;
}
.tel-input .tel-national:focus {
  outline: none;
  box-shadow: none;
}
.tel-country {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 0 11px;
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-right: 1px solid var(--line-strong);
  border-radius: var(--radius-sm) 0 0 var(--radius-sm);
  cursor: pointer;
  white-space: nowrap;
}
.tel-flag {
  width: 21px;
  height: 14px;
  flex: none;
  display: inline-block;
  overflow: hidden;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(14, 23, 38, 0.12);
}
.tel-flag svg {
  display: block;
  width: 100%;
  height: 100%;
}
.tel-caret {
  font-size: 9px;
  color: var(--muted);
}
.tel-menu {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 30;
  margin: 5px 0 0;
  padding: 4px;
  min-width: 240px;
  max-height: 260px;
  overflow: auto;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow);
}
.tel-opt {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 9px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--ink);
  cursor: pointer;
}
.tel-opt:hover {
  background: var(--accent-wash);
}
.tel-opt .tel-name {
  flex: 1;
}
.tel-opt .tel-dial {
  color: var(--muted);
}
/* A disabled action reads as inactive (e.g. the gated wizard Continue/Finish). */
.btn:disabled,
.btn[disabled] {
  opacity: 0.45;
  cursor: not-allowed;
}
.field .opt {
  font-weight: 400;
  color: var(--muted);
  text-transform: none;
  letter-spacing: 0;
}

/* ---------- filter toolbar ---------- */
.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 28px;
  margin-bottom: 16px;
}
.filter {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.flabel {
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  margin-right: 2px;
}
.chip {
  font-size: 12px;
  color: var(--ink-soft);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 3px 11px;
}
.chip:hover { background: var(--hover); text-decoration: none; }
.chip.on {
  color: #fff;
  background: var(--ink);
  border-color: var(--ink);
}

/* sub-tabs (e.g. Accepted / Acquired on transactions) */
.tabs {
  display: flex;
  gap: 2px;
  margin-bottom: 16px;
  border-bottom: 1px solid var(--line);
}
.tab {
  position: relative;
  padding: 8px 15px;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tab:hover { color: var(--ink); text-decoration: none; }
/* active tab: strong text + gold underline (doc §Onglets — grad-or, not violet) */
.tab.on { color: var(--ink); }
.tab.on::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2.5px;
  border-radius: 3px;
  background: var(--grad-or);
}

/* ===== Slide-tabs standard (see slide-tabs.js) =====
   A gold underline that GLIDES to the active tab. slide-tabs.js injects .tab-underline into any
   [data-tabs] bar and adds .has-underline; without JS each bar keeps its static ::after (hidden
   here once the glider is live). Applies to Transactions, My business and Pay-by-link. */
[data-tabs] { position: relative; }
.tab-underline {
  position: absolute;
  left: 0;
  bottom: -1px;
  width: 0;
  height: 2.5px;
  border-radius: 3px;
  background: var(--grad-or);
  opacity: 0;
  pointer-events: none;
  transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.2, 1),
    width 0.28s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.2s;
}
.tabs.has-underline .tab.on::after,
.ctabs.has-underline .ctab.on::after,
.cd-tabs.has-underline .ctab.on::after,
.pbl-tabs.has-underline button.on::after { display: none; }
@media (prefers-reduced-motion: reduce) { .tab-underline { transition: none; } }

/* Client-side tab panels slide + fade in on switch (my-business, pay-by-link) — the "left-right"
   feel instead of a hard cut. Triggered by display none→flex/block when a panel is revealed. */
@keyframes tab-in { from { opacity: 0; transform: translateX(10px); } to { opacity: 1; transform: none; } }
.pbl-panel.on { animation: tab-in 0.28s cubic-bezier(0.2, 0.7, 0.2, 1); }
@media (prefers-reduced-motion: reduce) {
  .pbl-panel.on { animation: none; }
}

.note-line {
  margin-top: 14px;
  font-size: 12.5px;
  color: var(--muted);
}
.muted { color: var(--muted); }

/* search box + sortable column headers (clients list) */
.search { margin: 0; }
.search-input {
  font: inherit;
  font-size: 13px;
  padding: 7px 12px;
  min-width: 250px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
}
.search-input:focus {
  outline: none;
  border-color: var(--violet);
  box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.12);
}
thead th a.sort {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
thead th a.sort:hover,
thead th a.sort.on { color: var(--ink); }
.caret { font-size: 9px; }

/* two-field row + inline status select (client contact / documents) */
.form-row.two { display: flex; gap: 10px; }
/* min-width:0 lets a field with wide content (e.g. the tel-input widget) shrink to its
   half instead of blowing the column out and squashing its neighbour. */
.form-row.two .field { flex: 1; min-width: 0; }
.inline-status { margin: 0; }
select.mini,
input.mini {
  font: inherit;
  font-size: 12px;
  padding: 4px 9px;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  background: var(--surface);
  color: var(--ink);
}
select.mini:focus,
input.mini:focus {
  outline: none;
  border-color: var(--violet);
  box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.12);
}

/* in-store terminal charging (HTMX) */
.htmx-indicator { display: none; }
.htmx-indicator.htmx-request { display: inline; }
.charge-form {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
}
.charge-form .amt { width: 78px; text-align: right; }
.ccy-pre {
  color: var(--muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
td.tres { padding: 0 16px 8px; }
td.tres:empty { padding: 0; border: 0; }

/* form controls beyond the login card */
.field select {
  width: 100%;
  font: inherit;
  font-size: 14px;
  padding: 9px 11px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
}
.field select:focus {
  outline: none;
  border-color: var(--violet);
  box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.12);
}
.check {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-soft);
  margin-bottom: 16px;
}
.check input { width: auto; }

/* column chooser (transactions table) */
.col-search {
  width: 100%;
  font: inherit;
  font-size: 13px;
  padding: 7px 10px;
  margin-bottom: 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink);
}
.col-search:focus {
  outline: none;
  border-color: var(--violet);
  box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.12);
}
.col-hint { font-size: 11px; color: var(--muted); margin-bottom: 6px; }
.col-hint .grip { font-size: 11px; }
.col-choices { max-height: 300px; overflow-y: auto; margin-bottom: 12px; }
.col-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 6px;
  border-radius: 6px;
  font-size: 13px;
  color: var(--ink-soft);
  cursor: grab;
  user-select: none;
}
.col-item:hover { background: var(--hover); }
.col-item.dragging { opacity: 0.55; background: var(--accent-wash); }
.col-item .drag-handle { color: var(--line-strong); font-size: 12px; }
.col-item:hover .drag-handle { color: var(--muted); }
.col-item input { width: auto; }
.col-item .col-label { flex: 1; cursor: pointer; }

/* a slightly wider popover for the column chooser */
.card-form.wide { width: 340px; }

/* kebab (⋮) icon button + the table's columns menu */
.btn.icon {
  padding: 4px 9px;
  font-size: 17px;
  line-height: 1;
  letter-spacing: 1px;
  color: var(--muted);
}
.btn.icon:hover { color: var(--ink); }
.table-menu { margin-left: auto; }

/* Terminal row actions: a 3-dots dropdown grouping our internal workflow apart
   from device commands sent via MarketPay's NTMS. */
.actions-menu { width: 250px; padding: 12px; }
.actions-menu .menu-group {
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
  margin: 0 0 6px;
}
.actions-menu .menu-group:not(:first-child) {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}
.actions-menu form { margin: 0; }
.actions-menu .btn.link {
  display: block;
  width: 100%;
  text-align: left;
  padding: 5px 6px;
  border-radius: 8px;
}
.actions-menu .btn.link:hover { background: var(--canvas); }
/* Destructive menu rows (Delete terminal, Approve deassignment…) highlight red-on-wash,
   not the neutral hover — themed in both modes (doc §Boutons destructif). */
.actions-menu .btn.link.danger:hover { background: var(--red-wash); color: var(--err-txt); }
.actions-menu .muted-empty { font-size: 11.5px; color: var(--muted); }
.actions-menu .menu-group .menu-hint {
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--amber);
}
.actions-menu .btn.link:disabled {
  color: var(--muted);
  cursor: not-allowed;
  opacity: 0.6;
}
.actions-menu .btn.link:disabled:hover { background: none; }
/* Inline "assign to a partner" row inside the menu. */
.actions-menu .assign-form { display: flex; gap: 6px; align-items: center; margin-bottom: 2px; }
.actions-menu .assign-form select { flex: 1; min-width: 0; }
.actions-menu .assign-form .btn.link { width: auto; }

.table-menu .btn.icon { height: 36px; box-sizing: border-box; padding: 0 10px; }

/* Date-range picker (Flatpickr). Flatpickr's CSS loads AFTER app.css (per-page head
   block), so its same-specificity defaults would win — every override is prefixed
   with `.flatpickr-calendar` to outrank them and apply our palette in both themes. */
.daterange-input { min-width: 200px; cursor: pointer; }

/* Typography: match the app (Inter body, Space Grotesk for the month/year header).
   Flatpickr's defaults are heavy (bolder weekdays, bold month) — soften them. */
.flatpickr-calendar,
.flatpickr-calendar input { font-family: var(--body); }
.flatpickr-calendar .flatpickr-months { padding: 6px 6px 2px; }
.flatpickr-calendar .flatpickr-current-month {
  font-size: 15px;
  padding: 0;
  height: 34px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
}
.flatpickr-calendar .flatpickr-current-month .cur-month {
  font-family: var(--display);
  font-weight: 600;
  margin: 0;
}
.flatpickr-calendar .flatpickr-current-month .numInputWrapper { width: 5ch; }
.flatpickr-calendar .flatpickr-current-month input.cur-year {
  font-family: var(--display);
  font-weight: 600;
}
.flatpickr-calendar span.flatpickr-weekday {
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--muted);
}
.flatpickr-calendar .flatpickr-day { font-weight: 400; }

.flatpickr-calendar .flatpickr-day.today { border-color: var(--accent); }
.flatpickr-calendar .flatpickr-day.today:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.flatpickr-calendar .flatpickr-day.selected,
.flatpickr-calendar .flatpickr-day.startRange,
.flatpickr-calendar .flatpickr-day.endRange,
.flatpickr-calendar .flatpickr-day.selected:hover,
.flatpickr-calendar .flatpickr-day.startRange:hover,
.flatpickr-calendar .flatpickr-day.endRange:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.flatpickr-calendar .flatpickr-day.inRange {
  background: var(--accent-wash);
  border-color: var(--accent-wash);
  color: var(--accent-ink);
  box-shadow: -5px 0 0 var(--accent-wash), 5px 0 0 var(--accent-wash);
}

/* Dark re-skin: Flatpickr ships a light theme only. */
[data-theme="dark"] .flatpickr-calendar {
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--shadow);
  color: var(--ink);
}
[data-theme="dark"] .flatpickr-calendar.arrowTop::after { border-bottom-color: var(--surface); }
[data-theme="dark"] .flatpickr-calendar.arrowBottom::after { border-top-color: var(--surface); }
[data-theme="dark"] .flatpickr-calendar .flatpickr-months .flatpickr-month,
[data-theme="dark"] .flatpickr-calendar .flatpickr-current-month,
[data-theme="dark"] .flatpickr-calendar .flatpickr-current-month input.cur-year,
[data-theme="dark"] .flatpickr-calendar .flatpickr-monthDropdown-months { color: var(--ink); fill: var(--ink); }
[data-theme="dark"] .flatpickr-calendar .flatpickr-prev-month svg,
[data-theme="dark"] .flatpickr-calendar .flatpickr-next-month svg { fill: var(--ink); }
[data-theme="dark"] .flatpickr-calendar .flatpickr-prev-month:hover svg,
[data-theme="dark"] .flatpickr-calendar .flatpickr-next-month:hover svg { fill: var(--accent); }
[data-theme="dark"] .flatpickr-calendar .flatpickr-day { color: var(--ink-soft); }
[data-theme="dark"] .flatpickr-calendar .flatpickr-day:hover { background: #1b2740; border-color: #1b2740; }
[data-theme="dark"] .flatpickr-calendar .flatpickr-day.flatpickr-disabled,
[data-theme="dark"] .flatpickr-calendar .flatpickr-day.prevMonthDay,
[data-theme="dark"] .flatpickr-calendar .flatpickr-day.nextMonthDay { color: var(--muted); }
[data-theme="dark"] .flatpickr-calendar .flatpickr-day.inRange {
  background: var(--accent-wash);
  border-color: var(--accent-wash);
  color: var(--ink);
  box-shadow: -5px 0 0 var(--accent-wash), 5px 0 0 var(--accent-wash);
}
[data-theme="dark"] .flatpickr-calendar .flatpickr-day.selected,
[data-theme="dark"] .flatpickr-calendar .flatpickr-day.startRange,
[data-theme="dark"] .flatpickr-calendar .flatpickr-day.endRange {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}

/* inline warning banner inside a panel */
.banner {
  margin: 12px 16px 4px;
  padding: 9px 13px;
  border-radius: var(--radius-sm);
  font-size: 12.5px;
  color: var(--amber);
  background: var(--amber-wash);
  border: 1px solid #e6d4ad;
}
/* Neutral info banner (e.g. "showing one payout / terminal") — flush with content. */
.context-banner {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 4px 0 14px;
  color: var(--ink);
  background: var(--surface);
  border-color: var(--line-strong);
}
.context-banner .btn { white-space: nowrap; }

/* a second heading inside one panel (e.g. Terminals under Provider accounts) */

/* ---------- payment-link detail ---------- */
.pay-grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr;
  gap: 16px;
  align-items: start;
}
.ledger { margin: 0; }
.ledger > div {
  display: flex;
  gap: 16px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--line);
}
.ledger > div:last-child { border-bottom: none; }
.ledger dt {
  width: 120px;
  flex-shrink: 0;
  margin: 0;
  font-size: 11px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 1px;
}
.ledger dd { margin: 0; }
.ledger .full { flex-direction: column; gap: 8px; }
/* Two-column key/value ledger (KYC panel) — collapses to one column on phones. */
.ledger.cols-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 28px; }
@media (max-width: 640px) { .ledger.cols-2 { grid-template-columns: 1fr; } }
.items { list-style: none; margin: 0; padding: 0; }
.items li {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 5px 0;
  border-bottom: 1px dashed var(--line);
}
.items li:last-child { border-bottom: none; }

.pay-share { text-align: center; }
.qr {
  display: flex;
  justify-content: center;
  padding: 20px 16px 12px;
}
.qr svg { width: 196px; height: 196px; }
.copy-row {
  display: flex;
  gap: 8px;
  padding: 0 16px 12px;
}
.copy-row input {
  flex: 1;
  min-width: 0;
  font-size: 12px;
  padding: 8px 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink-soft);
}
.pay-share .btn.block {
  width: calc(100% - 32px);
  margin: 2px 16px 0;
}
.pay-share .note-line { padding: 0 16px; margin-top: 12px; }

/* Focus visibility everywhere. --accent-ink (violet on light, gold on dark) keeps the ring
   high-contrast in BOTH themes — the gold --accent was near-invisible on light surfaces (a11y). */
:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 2px;
  border-radius: 3px;
}

/* ---------- developer docs ---------- */
.devdoc { max-width: 880px; }
.devbar {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
  position: sticky;
  top: 58px;
  z-index: 4;
  background: var(--canvas);
  padding: 10px 0 14px;
  border-bottom: 1px solid var(--line);
}
.devbar .base { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 280px; }
.devbar .base .flabel { white-space: nowrap; }
.devbar .base input {
  flex: 1;
  min-width: 0;
  font-size: 12.5px;
  padding: 7px 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--ink-soft);
}
.lang-tabs {
  display: inline-flex;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.lang-tabs button {
  font: inherit;
  font-size: 12.5px;
  padding: 6px 13px;
  border: none;
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
}
.lang-tabs button + button { border-left: 1px solid var(--line-strong); }
.lang-tabs button:hover { background: var(--hover); }
.lang-tabs button.on { background: var(--ink); color: #fff; }

/* Developer hub: fields to fill (left) + documentation (right). */
.dev-2col {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 14px;
  align-items: start;
  margin-top: 16px;
}
.dev-fields { order: 2; }
.dev-fields .panel:first-child { margin-top: 0; }
.devdoc { order: 1; }
.panel-pad { padding: 14px 16px; }
.dfb-note { font-size: 12px; color: var(--muted); line-height: 1.55; margin: 0 0 12px; }
.dfb-note code { font-size: 11.5px; }
.panel-pad .confirm-editor { gap: 10px; }
.panel-pad .confirm-editor label { font-size: 12px; font-weight: 500; }
@media (max-width: 1000px) {
  .dev-2col { grid-template-columns: 1fr; }
}

.dev-section { margin: 26px 0; }

/* Checkout simulator form (the "dev-simulator" panel in the right column). */
.tryit-form { display: flex; flex-direction: column; gap: 10px; }
.tryit-modes { display: flex; gap: 16px; font-size: 13px; }
.tryit-modes label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.tryit-night { display: flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; }
.tryit-items { width: 100%; border-collapse: collapse; }
.tryit-items th {
  text-align: left; font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.05em; color: var(--muted); padding: 0 6px 4px 0;
}
.tryit-items td { padding: 0 6px 6px 0; }
.tryit-items input { width: 100%; }
.tryit-items td:nth-child(2) { width: 90px; }
.tryit-items td:nth-child(3) { width: 56px; }
.dev-section h2 {
  font-family: var(--display);
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 8px;
}
.dev-section > p { color: var(--ink-soft); font-size: 14px; margin: 0 0 12px; }
.dev-section p code {
  font-family: var(--mono);
  font-size: 12.5px;
  background: var(--hover);
  padding: 1px 5px;
  border-radius: 4px;
}

.endpoint { display: flex; align-items: center; gap: 10px; margin: 14px 0 8px; }
.method {
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 5px;
  letter-spacing: 0.03em;
}
.method.get { background: var(--accent-wash); color: var(--accent-ink); }
.method.post { background: #e7eefb; color: #2a52b5; }
.epath { font-size: 13px; color: var(--ink-soft); }

.code { position: relative; margin: 0 0 8px; }
.code pre {
  margin: 0;
  background: #0a101c;
  color: #d6e1f0;
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 16px;
  padding: 18px 22px;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.8;
}
.code pre code { background: none; padding: 0; color: inherit; font-size: inherit; }
.copy-code {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 2;
  font: inherit;
  font-size: 11px;
  padding: 3px 9px;
  border: 1px solid #38455f;
  border-radius: 5px;
  background: rgba(255, 255, 255, 0.06);
  color: #94a3b8;
  cursor: pointer;
}
.copy-code:hover { background: rgba(255, 255, 255, 0.12); color: #fff; }
.devdoc .lang { display: none; }
.devdoc[data-lang="curl"] .lang-curl,
.devdoc[data-lang="python"] .lang-python,
.devdoc[data-lang="node"] .lang-node,
.devdoc[data-lang="html"] .lang-html { display: block; }

.devnote {
  display: none;
  background: var(--amber-wash);
  border: 1px solid #e6d4ad;
  border-left: 3px solid var(--amber);
  border-radius: var(--radius-sm);
  padding: 12px 16px;
  font-size: 13.5px;
  line-height: 1.5;
  color: #6b5526;
  margin-bottom: 22px;
}
.devnote code { font-family: var(--mono); font-size: 12.5px; }
.devdoc[data-lang="html"] .devnote { display: block; }

.form-errors {
  background: var(--red-wash); border: 1px solid #e6c3bd; border-left: 3px solid var(--red);
  border-radius: var(--radius-sm); padding: 12px 16px; margin-bottom: 18px;
  font-size: 13.5px; color: #8a2a2a;
}
.form-errors ul { margin: 6px 0 0; padding-left: 20px; }

.confirm-editor { display: flex; flex-direction: column; gap: 14px; }
.confirm-editor label {
  display: flex; flex-direction: column; gap: 6px;
  font-weight: 600; font-size: 13px; color: var(--muted);
}
.confirm-editor textarea {
  font-family: var(--mono); font-size: 12.5px; line-height: 1.5;
  width: 100%; box-sizing: border-box; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: #fff; color: var(--ink); resize: vertical;
}

/* ---------- desktop responsiveness ----------
   Fluid from wide screens down to ~1024px laptops: reflow the multi-column
   grids so nothing gets crushed. Below ~860px the mobile fallback takes over. */
@media (max-width: 1180px) {
  .grid-2,
  .pay-grid { grid-template-columns: 1fr; }
}
@media (max-width: 1080px) {
  .stats { grid-auto-flow: row; grid-template-columns: repeat(2, 1fr); }
  .meta-row { gap: 20px 28px; }
}
/* On very wide screens, give the full-bleed content a little more breathing room. */
@media (min-width: 1700px) {
  .content { padding-left: 40px; padding-right: 40px; }
}

@media (max-width: 860px) {
  .shell { grid-template-columns: 1fr; }
  .nav-burger { display: inline-flex; }
  /* sidebar becomes an off-canvas drawer, slid in by the hamburger toggle */
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 40;
    width: min(82vw, 280px);
    height: 100vh;
    transform: translateX(-100%);
    transition: transform 0.22s ease;
    overflow-y: auto;
  }
  .nav-toggle:checked ~ .sidebar {
    transform: none;
    box-shadow: 0 18px 50px rgba(2, 8, 20, 0.45);
  }
  .nav-toggle:checked ~ .nav-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 35;
    background: rgba(2, 8, 20, 0.5);
  }
  /* keep the topbar on a single row */
  .topbar { padding: 0 12px; gap: 8px; }
  /* the partner/company name is redundant on a phone (the drawer header shows it)
     — drop it to free space so the controls never crowd the burger */
  .org { display: none; }
  .who { gap: 8px; }
  /* tiles + grids don't overflow the viewport */
  .stats { grid-auto-flow: row; grid-template-columns: repeat(2, 1fr); }
  .stat { min-width: 0; }
  .stat .v { font-size: 22px; }
  .grid-2, .pay-grid { grid-template-columns: 1fr; }
  /* wide data tables scroll within their card instead of widening the page */
  .content table { display: block; overflow-x: auto; white-space: nowrap; }
  /* Comfort on a phone: pin the first (identifier) column so it stays in view
     while scrolling a wide table sideways; a right edge-shadow both separates it
     and hints there's more to scroll. Kept on the real <table> (no card reflow,
     which would drop table semantics for screen readers — see research). */
  .content table th:first-child,
  .content table td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--surface);
    box-shadow: 6px 0 8px -6px rgba(14, 23, 38, 0.28);
  }
  .content table thead th:first-child { z-index: 2; }
  /* the detail drawer takes the full width on a phone (no peeking strip) */
  #txn-panel { width: 100vw; border-left: 0; box-shadow: none; }

  /* Columns popover trigger sizing on a phone (the filter bar has its own responsive
     rules; see .fbar). */
  .table-menu .btn.icon {
    height: 38px;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0 10px;
  }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
  /* Neutralise hover lifts so nothing jumps when motion is reduced. */
  .btn:hover, .card:hover, .kpi:hover, .txn-row:hover { transform: none !important; }
}

/* ---------- sortable table headers ---------- */
.th-sort {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
.th-sort:hover { color: var(--ink); }
.th-sort.on { color: var(--accent-ink); }
.th-sort .arrow { font-size: 10px; }

/* ---------- address autocomplete (Photon / OpenStreetMap) ---------- */
.addr-ac { position: relative; }
.addr-ac-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 40;
  margin: 0;
  padding: 4px;
  list-style: none;
  max-height: 240px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  box-shadow: 0 12px 32px -12px rgba(14, 23, 38, 0.32);
}
.addr-ac-item {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 7px 9px;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.addr-ac-item:hover,
.addr-ac-item.active { background: var(--accent-wash); }
.addr-ac-main { font-size: 13px; color: var(--ink); }
.addr-ac-sub { font-size: 11px; color: var(--muted); }

/* Onboarding pipeline: per-client progress bar. */
.progress { height: 6px; border-radius: 999px; background: var(--line); overflow: hidden; }
.progress-fill { height: 100%; background: var(--muted); border-radius: 999px; transition: width .2s ease; }
.progress-fill.ok { background: var(--accent); }

/* KYC document rejection reason, shown to the partner under the doc name. */
.docreject { margin-top: 3px; font-size: 11.5px; color: var(--red); background: var(--red-wash); border-radius: 4px; padding: 2px 6px; display: inline-block; }

/* "What's still needed" card (client detail / My business overview). */
.needs {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 15px 18px;
  margin-bottom: 14px;
}

/* Guided store creation — payment-solution picker (_store_form.html). */
.sol-groups { display: flex; flex-direction: column; gap: 12px; }
.sol-group-h {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 4px;
}
.sol-groups .sol-opt {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 5px 0;
  margin: 0;
  cursor: pointer;
}
.sol-groups .sol-opt > input { flex: none; margin-top: 2px; width: auto; }
.sol-body { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.sol-t { font-weight: 500; color: var(--ink); font-size: 13.5px; }
.sol-d { font-size: 12px; color: var(--muted); }

/* Subtle trash-icon delete for table rows — muted, turns red on hover (no red block). */
.btn-del {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--muted);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: color 0.12s, background 0.12s;
}
.btn-del:hover { color: var(--red); background: var(--red-wash); }
.btn-del svg { width: 15px; height: 15px; }

/* "Same as company" address toggle: a compact check, and the greyed disabled input. */
.addr-same { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--ink-soft); margin: 0 0 6px; cursor: pointer; }
.addr-same input { width: auto; margin: 0; }
.js-addr-input:disabled { background: var(--canvas); color: var(--muted); cursor: not-allowed; }

.ctabs { display: flex; gap: 20px; border-bottom: 1px solid var(--line); margin-bottom: 18px; }
.ctab { border: 0; background: 0; font: inherit; font-size: 13.5px; color: var(--muted); padding: 9px 0; cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; }
.ctab:hover { color: var(--ink); }
.ctab.on { color: var(--violet-txt); border-bottom-color: var(--violet-txt); font-weight: 600; }

.bento { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.bento .card { background: var(--surface); border: 1px solid var(--line); border-radius: 10px; padding: 15px 16px; }
.bento .card.wide { grid-column: 1 / -1; }
.bento .ch { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.bento .ch .lbl { font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); font-weight: 600; }
.bento .ch .sp { margin-left: auto; }
.bento .ch .count { margin-left: auto; color: var(--muted); font-size: 12px; }
.bento .big { font-family: var(--display); font-weight: 600; font-size: 18px; color: var(--accent-ink); margin-bottom: 2px; }

/* Topbar breadcrumb (per-page, via the {% block topbar %} slot). */
.crumb { font-size: 13px; color: var(--muted); }
.crumb b { color: var(--ink); font-weight: 500; }
.crumb .sep { margin: 0 4px; color: var(--line-strong); }

/* ---------- ledger summary (the "money" pages: transactions, payouts) ----------
   A single flat hairline band with one hero figure leading a row of supporting
   KPIs — replaces the equal card grid on these two views. Labels keep the
   `<div class="k">` shape the rest of the app (and its tests) rely on. */
.ledger-summary {
  display: flex;
  flex-wrap: wrap;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  margin-bottom: 22px;
  overflow: hidden;
}
/* The ledger band re-skins the ONE shared .stat tile (design-system §9: a single KPI atom, no
   more .lstat): it strips the grid card chrome and lays the tiles out as a connected,
   border-separated strip with a wide hero. .k / .v / .note typography is inherited from .stat;
   only the band-specific deltas and the dormant neutralisation live here. */
.ledger-summary .stat {
  flex: 1 1 0;
  min-width: 150px;
  padding: 15px 20px 14px;
  background: none;
  border: 0;
  border-left: 1px solid var(--line);
  border-radius: 0;
  box-shadow: none;
}
.ledger-summary .stat:first-child { border-left: 0; }
.ledger-summary .stat.hero { flex: 1.5 1 0; }
.ledger-summary .stat .v { font-size: 22px; line-height: 1; margin-top: 9px; color: var(--ink); }
.ledger-summary .stat.hero .v { font-size: 34px; color: var(--accent-ink); }
.ledger-summary .stat .note { margin-top: 6px; }
/* 30-day volume sparkline + trend chip (dashboard insights). */
.stat-spark {
  display: block;
  width: 100%;
  height: 22px;
  margin-top: 10px;
  color: var(--accent-ink);
  opacity: 0.85;
}
.trend { font-weight: 700; }
.trend.up { color: var(--ok-txt); }
.trend.down { color: var(--red); }
@media (max-width: 720px) {
  .ledger-summary .stat { flex-basis: 50%; border-top: 1px solid var(--line); }
  .ledger-summary .stat:nth-child(-n + 2) { border-top: 0; }
  .ledger-summary .stat:nth-child(2n + 1) { border-left: 0; }
}

/* Dormant KPI inside the band (dashboard: data blocked on the MarketPay feed). The band keeps the
   QUIET muted look — neutralise the grid tile's dashed frame + pulsing "await" dot. */
.ledger-summary .stat.dormant { background-image: none; }
.ledger-summary .stat.dormant .v { color: var(--muted); font-weight: 500; }
.ledger-summary .stat.dormant .k { color: var(--muted); }
.ledger-summary .stat.dormant .await {
  display: block;
  margin-top: 6px;
  font-size: 11.5px;
  color: var(--muted);
  font-style: italic;
  text-transform: none;
  letter-spacing: normal;
}
.ledger-summary .stat.dormant .await::before { content: none; }

/* Client overview: the transaction-activity band header. */
.ov-activity { margin-bottom: 16px; }
.ov-activity-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.ov-activity-head .lbl {
  font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
}
.ov-activity-link { margin-left: auto; font-size: 12px; color: var(--accent-ink); white-space: nowrap; }
.ov-activity-link:hover { text-decoration: underline; }

/* Detail-drawer id row: the id + a small, quiet copy-to-clipboard button. */
.drawer-idrow { display: inline-flex; align-items: center; gap: 7px; position: relative; }
.copy-btn {
  display: inline-grid;
  place-items: center;
  width: 22px;
  height: 22px;
  padding: 0;
  flex: none;
  border: 0;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  border-radius: 5px;
  transition: color 0.12s, background 0.12s;
}
.copy-btn:hover { color: var(--accent-ink); background: var(--hover); }
.copy-btn.copied { color: var(--live); }
.copy-flash {
  position: absolute;
  left: calc(100% + 6px);
  white-space: nowrap;
  font-size: 11px;
  font-weight: 500;
  color: var(--live);
  opacity: 0;
  transition: opacity 0.5s ease;
  pointer-events: none;
}
/* Shown instantly on copy (JS adds .copied to the button), then fades out when the
   class is removed ~1.2s later. */
.copy-btn.copied ~ .copy-flash { opacity: 1; transition: opacity 0s; }

/* --- Phone ID capture (KYC hand-off) ------------------------------------- */
/* Row action cluster: the "Phone" hand-off button sits next to Upload/Replace. */
.docactions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.docactions .disclosure.right { margin-left: 0; }

/* Desktop: the QR fragment loaded under an ID slot when the owner clicks "Phone". */
.idqr-row > td { padding: 0; border-top: 0; }
.idqr-slot:empty { display: none; }
.idqr {
  display: flex;
  gap: 16px;
  align-items: center;
  margin: 4px 0 12px;
  padding: 14px;
  background: var(--accent-wash);
  border: 1px solid var(--line);
  border-radius: 12px;
}
.idqr-code {
  flex: 0 0 auto;
  width: 116px;
  height: 116px;
  background: #fff;
  border-radius: 8px;
  padding: 7px;
  box-sizing: border-box;
}
.idqr-code svg { width: 100%; height: 100%; display: block; }
.idqr-body { min-width: 0; }
.idqr-title { font-weight: 600; font-size: 13.5px; margin: 0 0 3px; color: var(--ink); }
.idqr-sub { color: var(--muted); font-size: 12.5px; margin: 0 0 8px; line-height: 1.45; }
.idqr-wait { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--ink-soft); margin: 0 0 6px; }
.idqr-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--accent);
  animation: idqr-pulse 1.3s ease-in-out infinite;
}
@keyframes idqr-pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }
.idqr-links { display: flex; align-items: center; gap: 14px; }
.idqr-link { font-size: 12px; color: var(--muted); text-decoration: underline; }

/* Partner "send the onboarding link" card: share buttons, no QR (the client scans, not
   the partner). */
.olink {
  margin: 4px 0 12px; padding: 14px;
  background: var(--accent-wash); border: 1px solid var(--line); border-radius: 12px;
}
.olink-title { font-weight: 600; font-size: 13.5px; margin: 0 0 3px; color: var(--ink); }
.olink-sub { color: var(--muted); font-size: 12.5px; margin: 0 0 12px; line-height: 1.45; }
.olink-actions { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
/* All four actions are same-size .btn small; the copy button swaps its label on click. */
.olink-copy-done { display: none; color: var(--live); }
.olink-copy.copied .olink-copy-default { display: none; }
.olink-copy.copied .olink-copy-done { display: inline; }
/* Direct merchant: continue-on-phone framing with a QR. */
.olink-phone { display: flex; gap: 16px; align-items: flex-start; }
.olink-qr {
  flex: none;
  width: 116px;
  height: 116px;
  padding: 8px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
}
.olink-qr svg { display: block; width: 100%; height: 100%; }
.olink-phone-body { min-width: 0; }
@media (max-width: 560px) { .olink-phone { flex-direction: column; } }

/* Mobile capture page (standalone, no console shell). Mirrors the auth page. */
.mcap {
  min-height: 100vh;
  display: grid;
  place-items: center;
  background:
    radial-gradient(1100px 520px at 50% -10%, var(--accent-wash) 0%, transparent 55%),
    var(--canvas);
  padding: 20px;
}
.mcap-card {
  width: 100%;
  max-width: 420px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--shadow);
  padding: 26px 22px 22px;
}
.mcap .brand {
  display: flex; align-items: center; gap: 9px;
  color: var(--ink); font-family: var(--display); font-weight: 600;
  letter-spacing: -0.02em; font-size: 19px; padding-bottom: 4px;
}
.mcap .brand .brand-mark { width: 24px; height: 24px; object-fit: contain; }
.mcap h1 { font-family: var(--display); font-size: 18px; font-weight: 600; margin: 12px 0 4px; }
.mcap .lede { color: var(--muted); font-size: 13.5px; line-height: 1.5; margin: 0 0 18px; }
.mcap-card .btn.primary.block { margin-top: 16px; }
.mcap-foot { color: var(--muted); font-size: 11.5px; text-align: center; margin: 14px 0 0; }
/* Done / expired states. */
.mcap-done { text-align: center; }
.mcap-done .brand { justify-content: center; }
.mcap-tick, .mcap-warn {
  width: 56px; height: 56px; border-radius: 50%;
  display: grid; place-items: center; margin: 16px auto 4px;
  font-size: 30px; font-weight: 600;
}
.mcap-tick { background: color-mix(in srgb, var(--live) 16%, transparent); color: var(--live); }
.mcap-warn { background: color-mix(in srgb, var(--warn, #b7791f) 16%, transparent); color: var(--warn, #b7791f); }

/* Soft findings from the ID quality check on the confirmation screen. The photo WAS
   accepted, so this must read as a helpful aside, never as a failure — muted surface,
   left-aligned inside the centred card. */
.mcap-hint {
  margin-top: 18px; padding: 14px 16px; text-align: left;
  border: 1px solid var(--line); border-radius: 12px;
  background: color-mix(in srgb, var(--warn, #b7791f) 7%, transparent);
  font-size: 13.5px; line-height: 1.5;
}
.mcap-hint b { display: block; margin-bottom: 6px; }
.mcap-hint ul { margin: 0 0 8px; padding-left: 18px; }
.mcap-hint li { margin: 2px 0; }
.mcap-hint p { margin: 0; color: var(--muted); font-size: 12.5px; }

/* The details we ask for alongside an identity document (_id_fields.html). One rule set
   for all three surfaces — the phone wizard, the client portal and the console — so the
   fields look the same wherever the document is filed. */
.idf { margin: 14px 0 4px; text-align: left; }
.idf-lede { margin: 0 0 8px; color: var(--muted); font-size: 12.5px; }
.idf-row { display: block; margin-bottom: 10px; }
.idf-lbl { display: block; margin-bottom: 4px; font-size: 12.5px; font-weight: 600; }
.idf-req { color: var(--danger, #c0392b); font-weight: 700; }
.idf-row input {
  width: 100%;
  /* border-box or the 100% width plus the padding overflows the portal card on a phone —
     the same min-width trap that hid this card's content at 375px. */
  box-sizing: border-box;
  padding: 9px 10px;
  border: 1px solid var(--line, #e3e3e8);
  border-radius: 8px;
  font: inherit;
  font-size: 14px;
  background: var(--bg, #fff);
  color: inherit;
}
.idf-row input:focus { outline: 2px solid var(--accent, #f5a623); outline-offset: 1px; }

/* Declared details on a console KYC row: quiet by default, tinted once the card's own
   expiry has passed — that can happen while it waits in the review queue. */
/* Remove-file control on a KYC row: present but never inviting — destructive actions
   should be reachable, not prominent. */
.doc-del { display: inline; margin: 0; }
.btn-doc.danger { color: var(--muted); }
.btn-doc.danger:hover { color: var(--err); border-color: var(--err); }

.kyc-declared { color: var(--muted); }
.kyc-declared b { font-weight: 600; }
.kyc-declared b.kyc-expired { color: var(--danger, #c0392b); }

/* --- Client onboarding portal (/o/<token>) ------------------------------- */
.oport {
  min-height: 100vh; display: grid; place-items: center;
  background:
    radial-gradient(1100px 520px at 50% -10%, var(--accent-wash) 0%, transparent 55%),
    var(--canvas);
  padding: 24px 16px 40px;
}
.oport-card {
  width: 100%; max-width: 560px;
  /* min-width:0 — .oport is a grid, and a grid item defaults to min-width:auto, so it
     refuses to shrink below its content's min-content width. The document row (name +
     pill + buttons on one flex line) is ~470px wide, which pushed the whole card past a
     375px phone and cut the right-hand side off. This is what makes it actually fluid. */
  min-width: 0;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 16px; box-shadow: var(--shadow); padding: 26px 24px 22px;
}
.oport .brand {
  display: flex; align-items: center; gap: 9px; color: var(--ink);
  font-family: var(--display); font-weight: 600; letter-spacing: -0.02em; font-size: 19px;
}
.oport .brand .brand-mark { width: 24px; height: 24px; object-fit: contain; }
.oport h1 { font-family: var(--display); font-size: 19px; font-weight: 600; margin: 14px 0 4px; }
.oport .lede { color: var(--muted); font-size: 13.5px; line-height: 1.5; margin: 0 0 18px; }
/* --- Onboarding portal, redesigned (o_portal.html) -----------------------
   Built on the app's own tokens, not the mockup's hex values: --grad-aurora is already
   our signature gradient, --grad-or the CTA, --ok / --warn-txt the states. The mockup's
   palette was a reproduction of these, so binding to the tokens keeps the page in step
   when the brand moves. */
.ocard {
  width: 100%; max-width: 660px; min-width: 0;
  background: var(--surface); border-radius: 20px; position: relative; overflow: hidden;
  box-shadow: 0 24px 60px rgba(11, 19, 32, 0.1), 0 3px 12px rgba(11, 19, 32, 0.05);
}
/* No hairline on the card: body::before already paints the aurora across the top of the
   window, and the design system asks for it homeopathically (1-2 per screen). The mockup
   put it on the card because the mockup had no page-level strip. */
.ocard-in { padding: 30px 36px 26px; }

.ohead { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-bottom: 24px; }
.obrand-link { text-decoration: none; color: inherit; display: inline-flex; }
.obrand-link:hover { opacity: 0.85; }

.osecure {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  font-size: 10px; font-weight: 700; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ok); background: var(--nuit); border-radius: 999px; padding: 6px 13px;
}
.osecure svg { width: 11px; height: 11px; }

.otitle { font-family: var(--display); font-size: 24px; font-weight: 700; letter-spacing: -0.015em; line-height: 1.2; margin: 0; }
.obiz {
  background: var(--grad-aurora-light); background-clip: text; -webkit-background-clip: text;
  color: transparent;
}
.olede { color: var(--muted); font-size: 14px; margin: 8px 0 0; max-width: 52ch; }

.oflash { margin-top: 16px; border-radius: 12px; padding: 11px 14px; font-size: 13px; }
.oflash.ok { background: var(--ok-wash); color: var(--ok-txt); }
.oflash.warn { background: var(--warn-bg); color: var(--warn-txt); }
.oflash.error { background: var(--err-wash); color: var(--err-txt); }

/* --- progress --- */
.oprog { margin-top: 22px; background: var(--gris-clair); border-radius: 14px; padding: 16px 18px 15px; }
.oprog-top { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.oprog-lbl { font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.oprog-cnt { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }
.oprog-cnt span { color: var(--muted); font-weight: 600; }
.oprog-bar { height: 9px; border-radius: 999px; background: var(--line); overflow: hidden; }
.oprog-bar > i { display: block; height: 100%; border-radius: 999px; background: var(--grad-or); transition: width 0.7s cubic-bezier(0.2, 0.8, 0.25, 1); }
.oprog-hint { font-size: 12.5px; color: var(--muted); margin: 9px 0 0; }
.oprog-hint b { color: var(--ink); }

.odone { margin-top: 22px; display: flex; align-items: center; gap: 14px; background: var(--ok-wash); border-radius: 14px; padding: 16px 18px; }
.odone[hidden] { display: none; }
.odone-tick { width: 36px; height: 36px; border-radius: 50%; background: var(--ok-txt); color: #fff; display: flex; align-items: center; justify-content: center; font-weight: 800; flex: none; }
.odone b { display: block; font-size: 14.5px; color: var(--ink); }
.odone span { font-size: 13px; color: var(--muted); }

/* --- the walk ---------------------------------------------------------------------
   A trail, not a gate: every step is clickable, the current one is marked, finished ones
   carry a tick. Horizontal on a desktop, wrapping on a phone. */
.owalk {
  display: flex; flex-wrap: wrap; gap: 6px;
  list-style: none; margin: 22px 0 0; padding: 0;
}
.owalk-step a {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; border-radius: 999px; text-decoration: none;
  font-size: 12.5px; font-weight: 600; color: var(--muted);
  background: var(--gris-clair); border: 1px solid transparent;
}
.owalk-step a:hover { color: var(--ink); }
.owalk-step a:focus-visible { outline: 2px solid var(--violet-txt); outline-offset: 2px; }
.owalk-n {
  width: 18px; height: 18px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 700; background: var(--line); color: var(--muted);
}
.owalk-step.done a { color: var(--ok-txt); }
.owalk-step.done .owalk-n { background: var(--ok-txt); color: #fff; }
.owalk-step.active a { background: var(--nuit); color: #fff; }
.owalk-step.active .owalk-n { background: var(--or1); color: var(--nuit); }

/* --- one step at a time --- */
.ostep { margin-top: 24px; }
.ostep-h { font-family: var(--display); font-size: 17px; font-weight: 650; margin: 0; }
.ostep-blurb { color: var(--muted); font-size: 13px; margin: 4px 0 16px; }
.ostep-note { color: var(--muted); font-size: 12.5px; margin: 10px 0; }
.ostep-form { margin: 0 0 16px; }
.ostep-row2 { display: grid; grid-template-columns: 1fr 2fr; gap: 12px; }
.ostep-next {
  display: inline-block; margin-top: 16px;
  font-size: 12.5px; font-weight: 650; color: var(--violet-txt); text-decoration: none;
}
.ostep-next:hover { text-decoration: underline; }
.idf-opt { font-weight: 400; color: var(--muted); }

/* Continue-on-phone block inside a step: a small QR beside two lines of text. */
.ostep-phone {
  display: flex; gap: 14px; align-items: center;
  border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 14px; margin-top: 16px;
}
.ostep-phone-qr { flex: none; width: 84px; height: 84px; }
.ostep-phone-qr svg { width: 100%; height: 100%; display: block; }
.ostep-phone-t { margin: 0 0 2px; font-size: 13px; font-weight: 650; }
.ostep-phone .ostep-note { margin: 0; }

/* The confirmed-company summary on the walk's first step. */
.ostep-confirmed { margin-bottom: 16px; }
.ostep-confirmed .pill.ok { margin-left: auto; }
.ostep-fetched { margin: 12px 0 0; font-size: 12.5px; color: var(--muted); }
.ostep-fetched.ok { color: var(--ok-txt); }
.ostep-next-btn { margin-top: 18px; }

/* A live merchant's IBAN: shown as the account, not as a disabled form. A greyed-out
   field invites the merchant to fight it; a plain value with the reason does not. */
.ostep-live-iban {
  border: 1px solid var(--line); border-radius: 12px;
  padding: 14px 16px; margin-bottom: 16px;
}
.ostep-live-k {
  display: block; font-size: 10.5px; font-weight: 700;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); margin-bottom: 4px;
}
.ostep-live-iban .num { font-size: 15px; font-weight: 600; }
.ostep-live-iban .ostep-note { margin: 8px 0 0; }

/* --- section headers --- */
.osec { margin-top: 26px; }
.osec[hidden] { display: none; }
.osec-h { display: flex; align-items: center; gap: 9px; margin-bottom: 10px; }
.osec-t { font-size: 10.5px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.osec-n {
  font-size: 10.5px; font-weight: 700; min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: 999px; background: var(--gris-clair); color: var(--muted);
  display: inline-flex; align-items: center; justify-content: center; font-variant-numeric: tabular-nums;
}
.osec-n.warn { background: var(--warn-bg); color: var(--warn-txt); }
.osec-h hr { flex: 1; border: none; border-top: 1px solid var(--line); }

/* --- document rows --- */
.odoc {
  display: flex; align-items: center; gap: 14px;
  border: 1px solid var(--line); border-radius: 14px; padding: 14px 16px;
  background: var(--surface); position: relative; overflow: hidden;
  transition: border-color 0.2s ease, background 0.2s ease;
}
.odoc + .odoc { margin-top: 10px; }
.odoc.todo { border-color: rgba(255, 179, 0, 0.42); background: rgba(255, 214, 10, 0.06); }
.odoc.failed { border-color: var(--err); }
.odoc.justdone { animation: osettle 1.2s ease; }
@keyframes osettle { from { background: var(--ok-wash); } to { background: var(--surface); } }

.odoc-ic { width: 40px; height: 40px; border-radius: 12px; flex: none; display: flex; align-items: center; justify-content: center; }
.odoc-ic svg { width: 19px; height: 19px; }
.odoc-ic.dark { background: var(--nuit); color: #fff; }
.odoc-ic.line { background: var(--surface); border: 1.5px solid var(--line); color: var(--ink); }
.odoc-ic.warm { background: var(--or1); color: var(--nuit); }

.odoc-tx { flex: 1; min-width: 0; }
.odoc-t1 { font-size: 14px; font-weight: 650; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.odoc-t2 { font-size: 12px; color: var(--muted); margin-top: 1px; overflow-wrap: anywhere; }
.odoc-t2.bad { color: var(--err-txt); }
.odoc-t2.warn { color: var(--warn-txt); }

.opill {
  flex: none; display: inline-flex; align-items: center; gap: 6px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
  border-radius: 999px; padding: 5px 11px;
}
.opill-d { width: 6px; height: 6px; border-radius: 50%; flex: none; background: currentColor; }
.opill.rec { background: var(--ok-wash); color: var(--ok-txt); }
.opill.todo { background: var(--warn-bg); color: var(--warn-txt); }
.opill.fail { background: var(--err-wash); color: var(--err-txt); }
.opill.todo .opill-d { animation: opulse 1.5s ease-in-out infinite; }
@keyframes opulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

/* The upload progress line, hugging the bottom edge of its own card. */
.odoc-bar {
  position: absolute; left: 0; bottom: 0; height: 3px; width: 0;
  background: var(--grad-or); transition: width 1.4s cubic-bezier(0.3, 0.6, 0.3, 1);
}
.odoc-bar[hidden] { display: none; }

/* --- buttons --- */
.odoc-act { display: flex; gap: 8px; flex: none; align-items: center; }
.obtn {
  font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer;
  border-radius: 999px; padding: 8px 15px; display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid transparent; white-space: nowrap; text-decoration: none;
  transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.15s ease;
}
.obtn svg { width: 13px; height: 13px; }
.obtn:active { transform: scale(0.97); }
.obtn:focus-visible { outline: 2px solid var(--violet-txt); outline-offset: 2px; }
.obtn.primary { background: var(--grad-or); color: var(--nuit); box-shadow: 0 3px 10px rgba(255, 179, 0, 0.35); }
.obtn.primary:hover { box-shadow: 0 5px 16px rgba(255, 179, 0, 0.45); }
.obtn.ghost { background: var(--surface); border-color: var(--line); color: var(--muted); }
.obtn.ghost:hover { border-color: var(--gris); color: var(--ink); }
.obtn.dark { background: var(--nuit); color: #fff; }
.obtn.dark:hover { background: var(--ardoise); }
.obtn.busy { opacity: 0.55; pointer-events: none; }

/* A row waiting on US, not on the merchant: no control, just the reason. */
.odoc-pending { font-size: 12px; color: var(--muted); font-style: italic; }

.oup { margin: 0; display: inline-flex; }
.oup.asks { display: block; }
.oup-panel { width: 100%; margin-top: 10px; text-align: left; }
.oup-panel[hidden] { display: none; }
.oup-picked { margin: 0 0 6px; font-size: 12.5px; color: var(--muted); overflow-wrap: anywhere; }

/* --- handled for you --- */
.ohandled { background: var(--gris-clair); border-radius: 14px; padding: 14px 18px 15px; }
.ohandled-intro { display: flex; align-items: center; gap: 9px; font-size: 13px; color: var(--muted); padding-bottom: 12px; border-bottom: 1px solid var(--line); margin-bottom: 12px; }
.ohandled-intro b { color: var(--ink); font-weight: 650; }
.ohandled-badge { width: 20px; height: 20px; border-radius: 50%; background: var(--ok-txt); color: #fff; font-size: 11px; font-weight: 800; display: flex; align-items: center; justify-content: center; flex: none; }
.ohandled-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 8px 24px; }
.ohandled-grid li { display: flex; align-items: center; gap: 9px; font-size: 13.5px; color: var(--muted); }
.ohandled-ck { color: var(--ok-txt); font-size: 12px; font-weight: 800; flex: none; }

/* --- footer --- */
.ofoot {
  margin-top: 26px; padding-top: 18px; border-top: 1px solid var(--line);
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  font-size: 12.5px; color: var(--muted);
}
.ofoot-lock { display: flex; align-items: center; gap: 8px; }
.ofoot svg { width: 13px; height: 13px; flex: none; }
.ofoot a { color: var(--ink); font-weight: 650; }

/* --- toast --- */
.otoast {
  position: fixed; right: 26px; bottom: 26px; z-index: 300;
  background: var(--surface); border-radius: 14px; overflow: hidden;
  box-shadow: 0 18px 44px rgba(11, 19, 32, 0.25);
  display: flex; align-items: center; gap: 10px; padding: 12px 18px 12px 12px;
  opacity: 0; transform: translateY(10px) scale(0.97);
  transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.2, 0.8, 0.25, 1);
}
.otoast[hidden] { display: none; }
.otoast::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: 3px; background: var(--grad-aurora); }
.otoast.show { opacity: 1; transform: translateY(0) scale(1); }
.otoast-tick { width: 30px; height: 30px; border-radius: 50%; background: var(--ok-wash); color: var(--ok-txt); display: flex; align-items: center; justify-content: center; font-weight: 800; flex: none; }
.otoast-t1 { font-size: 13px; font-weight: 700; }
.otoast-t2 { font-size: 12px; color: var(--muted); margin-top: 1px; }

/* Phones. This portal is the "continue on phone" target, so it has to be genuinely
   comfortable at 375px: the row's name + pill + buttons do not fit on one line there. */
@media (max-width: 560px) {
  .ocard-in { padding: 24px 20px 20px; }
  .otitle { font-size: 21px; }
  .odoc { flex-wrap: wrap; row-gap: 10px; }
  .odoc-tx { min-width: 55%; }
  .odoc-act { width: 100%; justify-content: flex-end; }
  .oup.asks { flex: 1 0 100%; }
  .ohandled-grid { grid-template-columns: 1fr; }
  .ostep-row2 { grid-template-columns: 1fr; }
  .owalk-t { display: none; }  /* on a phone the numbered dots alone carry the trail */
  .ofoot { flex-direction: column; align-items: flex-start; }
  .otoast { left: 12px; right: 12px; bottom: 12px; }
}

/* Motion is decoration here; the state is always carried by the dot AND the word. */
@media (prefers-reduced-motion: reduce) {
  .opill.todo .opill-d, .odoc.justdone { animation: none; }
  .oprog-bar > i, .odoc-bar, .otoast { transition: none; }
}

/* The read gate (o_unlock.html) — a narrow, quiet page: it must read as a step, not as
   a wall the merchant has hit by mistake. */
.ounlock { margin: 18px 0 4px; text-align: left; }
.ounlock-sent { margin: 0 0 12px; font-size: 13px; color: var(--muted); }
.ounlock-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }
.ounlock input[name="code"] {
  font-family: var(--mono); font-size: 20px; letter-spacing: 0.32em; text-align: center;
}

.oport-foot { color: var(--muted); font-size: 11.5px; text-align: center; margin: 18px 0 0; }

/* In-page document preview panel */
.oport-modal { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; padding: 20px; }
.oport-modal[hidden] { display: none; }
.oport-modal-backdrop { position: absolute; inset: 0; background: rgba(20, 18, 14, 0.55); }
.oport-modal-card {
  position: relative; width: 100%; max-width: 820px; height: 90vh; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow); overflow: hidden;
}
.oport-modal-head {
  display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-bottom: 1px solid var(--line);
}
.oport-modal-title { font-weight: 600; font-size: 13.5px; color: var(--ink); }
.oport-modal-open { margin-left: auto; font-size: 12px; color: #5488c4; font-weight: 600; text-decoration: none; }
.oport-modal-open:hover { text-decoration: underline; }
.oport-modal-close {
  font: inherit; font-size: 22px; line-height: 1; cursor: pointer; color: var(--muted);
  background: none; border: none; padding: 0 4px;
}
.oport-modal-close:hover { color: var(--ink); }
.oport-modal-card iframe { flex: 1; width: 100%; border: 0; background: var(--surface); }

/* Info popover: an on-theme "i" that opens a small explanatory panel. */
.infopop { position: relative; display: inline-flex; }
.infopop > summary { list-style: none; cursor: pointer; }
.infopop > summary::-webkit-details-marker { display: none; }
.infopop-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 50%;
  background: #7cb0e6; color: #fff; border: none;
  font-size: 11px; line-height: 1;
  font-family: Georgia, "Times New Roman", serif; font-style: italic; font-weight: 600;
  user-select: none; transition: background 0.15s ease;
}
.infopop-btn:hover, .infopop[open] .infopop-btn { background: #6aa0da; }
.infopop-panel {
  position: absolute; top: 24px; left: 0; z-index: 40; width: 270px; max-width: 78vw;
  background: var(--surface); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: 12px; box-shadow: var(--shadow);
  padding: 12px 14px; font-size: 12.5px; line-height: 1.5; font-weight: 400;
}
.infopop-panel p { margin: 0 0 7px; color: var(--muted); }
.infopop-title { font-weight: 600; color: var(--ink) !important; font-size: 13px; }
.infopop-link {
  display: inline-block; margin-top: 2px; color: #5488c4; font-weight: 600; text-decoration: none;
}
.infopop-link:hover { text-decoration: underline; }

/* Phones: the popover anchors to its little icon mid-row, so it ran off the right edge and
   was unreadable. Pin it to the bottom of the viewport — always on screen, whatever the
   icon's position. MUST come after the base rule above: same specificity, so source order
   decides (placing it earlier left position/left/width overridden and the fix inert). */
@media (max-width: 560px) {
  .infopop-panel {
    position: fixed; left: 12px; right: 12px; bottom: 12px; top: auto;
    width: auto; max-width: none;
  }
}
.oubo-h1 { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.oubo-h1 .infopop-btn { width: 18px; height: 18px; font-size: 11px; }
.oport-msg { text-align: center; }
.oport-msg .brand { justify-content: center; }
.oport-msg .mcap-warn { margin: 16px auto 4px; }
.oport-card.oport-wide { max-width: 680px; }

/* UBO owners form (portal) */
.oubo-back { display: inline-block; margin: 14px 0 0; color: var(--muted); font-size: 12.5px; text-decoration: none; }
.oubo-back:hover { color: var(--ink); }
.oubo-lang { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--muted); margin: 0 0 16px; }
.oubo-lang a {
  text-decoration: none; color: var(--muted); border: 1px solid var(--line);
  padding: 3px 10px; border-radius: 999px;
}
.oubo-lang a.is-on { color: var(--ink); border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }
.oubo-status {
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 12px;
  font-size: 13px; color: var(--ink); margin: 0 0 16px;
  background: color-mix(in srgb, var(--accent) 6%, var(--surface));
}
.oubo-status.is-verified { background: color-mix(in srgb, var(--live) 8%, var(--surface)); }
.oubo-status.is-rejected { border-color: color-mix(in srgb, var(--bad, #c0392b) 45%, var(--line)); }
.oubo-list { list-style: none; margin: 0 0 8px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.oubo-name { font-weight: 600; font-size: 14px; color: var(--ink); margin-right: 6px; }
.oubo-owner-head { min-width: 0; flex: 1; }
.oubo-owner-meta { color: var(--muted); font-size: 12px; margin-top: 3px; }
.oubo-empty { color: var(--muted); font-size: 13px; padding: 6px 2px; }

/* Owner = inline card; editing expands in place (an accordion, not a pop-up). */
.oubo-owner { list-style: none; }
.oubo-edit {
  border: 1px solid var(--line); border-radius: 12px; background: var(--surface); overflow: hidden;
}
.oubo-edit > summary {
  display: flex; align-items: center; gap: 12px; cursor: pointer; padding: 12px 14px;
  list-style: none;
}
.oubo-edit > summary::-webkit-details-marker { display: none; }
.oubo-edit > summary:hover { background: color-mix(in srgb, var(--accent) 4%, var(--surface)); }
.oubo-edit[open] > summary { border-bottom: 1px solid var(--line); }
.oubo-edit-hint { margin-left: auto; font-size: 12px; color: var(--accent-ink); font-weight: 600; flex: 0 0 auto; }
.oubo-add { margin: 4px 0 4px; border-style: dashed; }
.oubo-add > summary { justify-content: center; }
.oubo-add-label { color: var(--accent-ink); font-weight: 600; font-size: 13.5px; }

/* Form: label beside the field (stacks on narrow screens). */
.of-wrap { padding: 14px; }
.of-form { display: flex; flex-direction: column; gap: 9px; }
.of-field { display: grid; grid-template-columns: 132px 1fr; gap: 6px 12px; align-items: center; }
.of-field-stack { grid-template-columns: 1fr; align-items: start; }
.of-label { font-weight: 600; font-size: 12.5px; color: var(--ink); }
.of-label .opt { color: var(--muted); font-weight: 400; }
.of-control { width: 100%; }
/* Match the app's field styling (see .field input) so the portal form is on-theme. */
input.of-control, textarea.of-control, select.of-control, .of-form .addr-ac input {
  width: 100%; font: inherit; font-size: 14.5px; padding: 10px 14px;
  border: 1.5px solid var(--line-strong); border-radius: var(--radius-input);
  background: var(--surface); color: var(--ink);
}
input.of-control:focus, textarea.of-control:focus, select.of-control:focus,
.of-form .addr-ac input:focus {
  outline: none; border-color: var(--violet); box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.12);
}
textarea.of-control { resize: vertical; min-height: 44px; }
.of-seg { display: flex; gap: 8px; }
.of-seg label { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--ink); }
.of-seg input { width: auto; }
.addr-ac { position: relative; }

/* Control criterion + progressive disclosure. */
.of-crit {
  border: 1px solid var(--line); border-radius: 10px; padding: 12px; margin: 4px 0;
  background: color-mix(in srgb, var(--accent) 3%, var(--surface));
}
.of-crit-title { font-weight: 600; font-size: 12.5px; color: var(--ink); margin: 0 0 8px; }
.of-crit-opt { display: flex; align-items: flex-start; gap: 8px; font-size: 12.5px; color: var(--ink); margin-bottom: 6px; line-height: 1.4; }
.of-crit-opt input { width: auto; margin-top: 2px; }
.of-cond { margin: 8px 0 2px; padding-left: 4px; border-left: 2px solid color-mix(in srgb, var(--accent) 30%, var(--line)); padding: 6px 0 2px 12px; }
.of-cond-note { font-size: 12px; color: var(--muted); margin: 4px 0; }
.of-check { display: flex; align-items: flex-start; gap: 8px; font-size: 12.5px; color: var(--ink); margin: 6px 0 2px; }
.of-check input { width: auto; margin-top: 2px; }
.of-actions { display: flex; align-items: center; gap: 8px; margin-top: 12px; }
@media (max-width: 560px) {
  .of-field { grid-template-columns: 1fr; gap: 3px; align-items: start; }
}

.oubo-generate {
  border-top: 1px solid var(--line); margin-top: 16px; padding-top: 16px;
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
.oubo-tally { font-size: 13px; color: var(--muted); display: flex; flex-direction: column; gap: 3px; }
.oubo-tally strong { color: var(--ink); }
.oubo-tally strong.bad, .oubo-warn { color: var(--bad, #c0392b); }
.oubo-warn { font-size: 12px; }
.oubo-actions { display: flex; align-items: center; gap: 8px; }
.ubo-sign-proof {
  font-size: 12px; color: var(--muted); margin: 6px 2px 0;
  padding-top: 6px; border-top: 1px dashed var(--line);
}
.ubo-sign-proof strong { color: var(--ink); }

/* Document preview + phone-signing QR (portal SES) */
.osign-preview { margin: 4px 0 14px; }
.osign-preview-head {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 12.5px; font-weight: 600; color: var(--ink); margin-bottom: 6px;
}
.osign-preview-head a { color: #5488c4; font-weight: 600; text-decoration: none; font-size: 12px; }
.osign-preview-head a:hover { text-decoration: underline; }
.osign-preview iframe {
  width: 100%; height: 78vh; max-height: 640px; min-height: 340px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--surface);
}
.osign-qr { margin: 0 0 16px; }
.osign-qr > summary {
  cursor: pointer; list-style: none; font-size: 12.5px; color: var(--accent-ink); font-weight: 600;
}
.osign-qr > summary::-webkit-details-marker { display: none; }
.osign-qr-body {
  display: flex; gap: 14px; align-items: center; margin-top: 10px;
  padding: 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface);
}
.osign-qr-code { flex: 0 0 auto; width: 108px; height: 108px; }
.osign-qr-code svg { width: 100%; height: 100%; }
.osign-qr-body p { margin: 0; font-size: 12px; color: var(--muted); line-height: 1.5; }

/* Signature pad (portal SES) */
.osign-consent { margin: 6px 0 14px; }
.osign-consent .of-check { align-items: flex-start; font-size: 12.5px; line-height: 1.45; color: var(--muted); }
.osign-consent .of-check input { margin-top: 2px; }
.osign-pad {
  position: relative; border: 1px solid var(--line); border-radius: 12px;
  background:
    repeating-linear-gradient(0deg, transparent, transparent 43px, color-mix(in srgb, var(--line) 60%, transparent) 44px),
    var(--surface);
  overflow: hidden;
}
.osign-pad canvas { display: block; width: 100%; height: auto; touch-action: none; cursor: crosshair; }
.osign-clear {
  position: absolute; top: 8px; right: 8px; font: inherit; font-size: 12px; cursor: pointer;
  padding: 4px 10px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); color: var(--muted);
}
.osign-clear:hover { color: var(--ink); }
.osign-hint { color: var(--muted); font-size: 12px; margin: 6px 2px 0; }
.osign-hint.bad { color: var(--bad, #c0392b); }

/* Multi-step client flow: pick document -> method -> camera/upload -> preview. */
.mchoice { display: grid; gap: 10px; margin: 4px 0 6px; }
.mopt {
  display: flex; align-items: center; gap: 12px;
  width: 100%; text-align: left; cursor: pointer;
  padding: 15px 16px; font: inherit; font-size: 15px; font-weight: 600; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: 13px;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.05s ease;
}
.mopt:hover { border-color: var(--accent); background: var(--accent-wash); }
.mopt:active { transform: scale(0.99); }
.mopt-ico { font-size: 24px; line-height: 1; }
.mopt-t { display: block; }
.mopt-s { display: block; font-size: 12px; font-weight: 500; color: var(--muted); margin-top: 1px; }
/* A clearly tappable "go back" chip at the top of secondary screens. */
.mchip-back {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0 0 12px; padding: 7px 12px; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line); border-radius: 999px;
  color: var(--ink-soft); font: inherit; font-size: 12.5px; font-weight: 500;
}
.mchip-back:hover { border-color: var(--accent); color: var(--ink); }
/* Opt-in "continue on your phone" link (never auto-shown). */
.mlink-qr {
  display: block; width: 100%; margin: 14px 0 0; padding: 0;
  background: none; border: 0; cursor: pointer; text-align: center;
  color: var(--muted); font: inherit; font-size: 12.5px; text-decoration: underline;
}
.mlink-qr:hover { color: var(--ink); }
/* display:block above would override the hidden ATTRIBUTE — the capture page toggles
   its "Use this photo anyway" escape link with [hidden], and it must actually hide. */
.mlink-qr[hidden] { display: none; }
/* Per-capture verdict checklist: every check with its own tick, so "looks good" comes
   with visible evidence. Colours carry the verdict; the glyph carries it for colour-blind
   readers (✓ / ⚠ / ✗ are in the markup). */
.mchecks { list-style: none; margin: 0; padding: 0; }
.mchecks li { padding: 3px 0; font-size: 13.5px; font-weight: 500; }
.mchecks li.mck-ok { color: var(--ok); }
.mchecks li.mck-warn { color: var(--amber); }
.mchecks li.mck-fail { color: var(--err-txt); }
.mfields { list-style: none; margin: 8px 0 0; padding: 8px 0 0; border-top: 1px solid var(--line); }
.mfields li { padding: 2px 0; font-size: 13.5px; }
/* Analysis-in-progress overlay on the captured photo: the person must SEE that the
   check is running (a greyed button alone reads as "stuck"). */
/* Per-owner mandatory-field gaps on the UBO page — amber, right under the card meta. */
.oubo-missing { margin-top: 4px; font-size: 12.5px; font-weight: 600; color: var(--amber); }
.mprev-wrap { position: relative; }
.mscan {
  position: absolute; inset: 0; display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: 10px; border-radius: 12px;
  background: rgba(255, 255, 255, 0.62); backdrop-filter: blur(1.5px);
  color: var(--ink); font-size: 14px; font-weight: 600;
}
.mscan[hidden] { display: none; }
.mscan-spin {
  width: 30px; height: 30px; border-radius: 50%;
  border: 3px solid var(--line); border-top-color: var(--accent);
  animation: mscan-rot 0.9s linear infinite;
}
@keyframes mscan-rot { to { transform: rotate(360deg); } }
/* Desktop -> phone hand-off QR on the method screen. */
.mqr {
  display: flex; gap: 14px; align-items: center;
  margin: 12px 0 0; padding: 14px;
  background: var(--accent-wash); border: 1px solid var(--line); border-radius: 13px;
}
.mqr-code { flex: 0 0 auto; width: 104px; height: 104px; background: #fff; border-radius: 8px; padding: 6px; box-sizing: border-box; }
.mqr-code svg { width: 100%; height: 100%; display: block; }
.mqr-t { font-weight: 600; font-size: 13.5px; margin: 0 0 3px; }
.mqr-s { color: var(--muted); font-size: 12.5px; margin: 0; line-height: 1.45; }
/* Live camera stage + framing guide. */
.mstage {
  /* MUST stay exactly 3:4 (the camera canvas backing ratio): the crop maps stage CSS px
     -> canvas px linearly, so any ratio drift distorts what gets captured (WYSIWYG).
     Short viewports are handled by capping the WIDTH (keeping the ratio), never the
     height alone — a max-height with width:100% would squash the canvas. */
  position: relative; width: 100%; max-width: calc(62vh * 3 / 4);
  aspect-ratio: 3 / 4;
  margin: 4px auto 0; border-radius: 14px; overflow: hidden; background: #000;
  display: grid; place-items: center;
}
/* The camera is drawn into this canvas (WYSIWYG). Its backing store is 3:4, same as
   the stage, so width/height:100% shows it without distortion. */
.mstage canvas { width: 100%; height: 100%; display: block; }
.mframe {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  border: 2px solid rgba(255, 255, 255, 0.9); border-radius: 10px;
  box-shadow: 0 0 0 100vmax rgba(0, 0, 0, 0.45);
  pointer-events: none;
}
.mcorner { position: absolute; width: 18px; height: 18px; border: 3px solid var(--accent); }
.mcorner.tl { top: -2px; left: -2px; border-right: 0; border-bottom: 0; border-top-left-radius: 10px; }
.mcorner.tr { top: -2px; right: -2px; border-left: 0; border-bottom: 0; border-top-right-radius: 10px; }
.mcorner.bl { bottom: -2px; left: -2px; border-right: 0; border-top: 0; border-bottom-left-radius: 10px; }
.mcorner.br { bottom: -2px; right: -2px; border-left: 0; border-top: 0; border-bottom-right-radius: 10px; }
.mcam-actions { display: flex; gap: 10px; margin-top: 14px; }
.mcam-actions .btn { flex: 1; justify-content: center; }
.mpreview { display: block; width: 100%; max-height: 62vh; object-fit: contain; margin: 4px 0 0; border-radius: 12px; border: 1px solid var(--line); background: #000; }

/* ============ Energy: kicker labels + nuit hero (site vitrine) ============ */
/* Kicker — a small uppercase label with an aurora dot; the site's section signature. */
.kicker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--violet-txt);
  background: var(--accent-wash);
  border: 1px solid rgba(124, 58, 237, 0.2);
  border-radius: 999px;
  padding: 5px 12px;
}
.kicker::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--grad-aurora);
  flex: none;
}

/* Dashboard hero — a nuit banner with a STATIC aurora glow (no animated blob in work screens). */
.hero-banner {
  position: relative;
  overflow: hidden;
  background: var(--nuit);
  color: #fff;
  border-radius: var(--radius-card);
  padding: 24px 28px 26px;
  margin-bottom: 22px;
}
.hero-banner::after {
  content: "";
  position: absolute;
  width: 340px;
  height: 340px;
  top: -170px;
  right: -70px;
  border-radius: 50%;
  background: conic-gradient(from 120deg, #ffd60a, #fb7185, #8b5cf6, #22d3ee, #ffd60a);
  filter: blur(90px);
  opacity: 0.26;
  pointer-events: none;
}
.hero-banner > * { position: relative; z-index: 1; }
.hero-banner h1 {
  font-family: var(--display);
  font-weight: 600;
  font-size: 28px;
  letter-spacing: -0.03em;
  margin: 12px 0 0;
  color: #fff;
}
.hero-banner h1 em { font-style: normal; background: var(--grad-aurora); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hero-banner .hero-sub { margin: 6px 0 0; color: #aebacc; font-size: 14.5px; }
.hero-banner .kicker { color: var(--or1); background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.14); }

/* ============ Night mode — on-theme fixes ============ */
/* Nuit secondary button vanishes on a dark page; lift it onto an elevated nuit surface. */
[data-theme="dark"] .btn.nuit { background: #1b2740; border-color: #2a3852; color: #fff; }
[data-theme="dark"] .btn.nuit:hover { background: #24324e; border-color: #38455f; }
/* The nuit hero/featured card equals the page background in dark — elevate + keep the accents. */
[data-theme="dark"] .hero-banner { background: #101a2c; }
[data-theme="dark"] .price.hot {
  background:
    linear-gradient(#101a2c, #101a2c) padding-box,
    var(--grad-aurora) border-box;
}

/* ============ Permanent nuit sidebar (day + night) — the app's premium, energetic frame ============ */
.sidebar {
  background: var(--nuit);
  border-right: 1px solid rgba(255, 255, 255, 0.07);
  color: #aebacc;
}
.sidebar .brand { color: #fff; }
.sidebar .brand-sig { color: rgba(255, 255, 255, 0.45); }
.sidebar .nav a { color: #aebacc; }
.sidebar .nav a svg { opacity: 0.72; }
.sidebar .nav a:hover { background: rgba(255, 255, 255, 0.06); color: #fff; }
.sidebar .nav a:hover svg { opacity: 1; }
.sidebar .nav a.active { background: rgba(139, 92, 246, 0.2); color: #c9b8fc; font-weight: 600; }
.sidebar .nav a.active svg { stroke: #c9b8fc; opacity: 1; }
.sidebar .nav a.disabled { color: rgba(174, 186, 204, 0.38); }
.sidebar .nav-label { color: rgba(174, 186, 204, 0.55); }
.sidebar .nav .tag { background: rgba(255, 255, 255, 0.08); color: #aebacc; }
.sidebar .sideuser { border-top-color: rgba(255, 255, 255, 0.08); }
.sidebar .sideuser .ava { background: rgba(255, 255, 255, 0.1); color: #fff; }
.sidebar .sideuser .who-name { color: #fff; }
.sidebar .sideuser .who-role { color: rgba(255, 255, 255, 0.5); }
.sidebar .sideuser .acts a,
.sidebar .sideuser .acts button { color: #aebacc; }
.sidebar .sideuser .acts a:hover,
.sidebar .sideuser .acts button:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }
.sidebar .sidebar-foot { color: rgba(255, 255, 255, 0.4); }

/* ============ Client shell — floating pill top-nav (V1 direct-merchant design) ============
   Rendered by base.html only for is_direct principals. The pill is a light glass surface in
   BOTH themes (as in the mockups); the page background is themed (light #F7F9FC / nuit). The
   aurora liseré (body::before, above) already sits over everything. */
.cshell { min-height: 100vh; }
/* Theme the page background behind the client shell without touching the shared body bg. */
body:has(.cshell) { background: #f7f9fc; }
[data-theme="dark"] body:has(.cshell) { background: var(--nuit); }

.topnav {
  position: sticky;
  top: 14px;
  z-index: 100;
  max-width: 1240px;
  margin: 18px auto 0;
  padding: 0 20px;
}
.topnav-pill {
  /* 3-column grid so the nav links sit dead-centre of the pill (like the marketing site),
     independent of the wordmark's vs the right controls' widths. The centre track is
     minmax(0, auto): content-width when it fits (→ centred), shrinkable + scrollable on
     tablets where five links + the chip don't fit (see .topnav-links overflow below). */
  display: grid;
  grid-template-columns: 1fr minmax(0, auto) 1fr;
  align-items: center;
  gap: 26px;
  background: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(14px);
  border-radius: 999px;
  padding: 10px 12px 10px 22px;
  box-shadow: 0 10px 34px rgba(15, 23, 42, 0.12);
}
[data-theme="dark"] .topnav-pill {
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.35), 0 1px 0 rgba(255, 255, 255, 0.6) inset;
}
.topnav .wordmark {
  justify-self: start;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--nuit);
  text-decoration: none;
}
.topnav .wordmark b {
  font-weight: 600;
  background: var(--grad-or);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.topnav-links {
  display: flex;
  gap: 4px;
  justify-self: center;
}
.topnav-links a {
  text-decoration: none;
  color: var(--nuit);
  font-size: 14.5px;
  font-weight: 600;
  padding: 9px 17px;
  border-radius: 999px;
  transition: background 0.2s, color 0.2s;
}
.topnav-links a:hover { background: var(--gris-clair); }
.topnav-links a.on,
.topnav-links a.on:hover { color: #fff; background: var(--nuit); }

/* Sliding pill indicator (JS adds .has-slider + injects .nav-ind). It glides to the hovered
   link and settles back on the active tab — the marketing header's effect. The nav pill is a
   light surface in both themes, so a --nuit pill + white text works dark and light alike. */
.topnav-links { position: relative; }
.topnav-links a { position: relative; z-index: 1; }
.topnav-links .nav-ind {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  z-index: 0;
  opacity: 0;
  pointer-events: none;
  background: var(--nuit);
  border-radius: 999px;
  transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.2, 1),
    width 0.24s cubic-bezier(0.2, 0.7, 0.2, 1), height 0.24s cubic-bezier(0.2, 0.7, 0.2, 1),
    opacity 0.2s;
}
/* With the slider live the pill draws the active tab's background; the link keeps only its
   white text. Hover stays the light-grey wash on the OTHER tabs (like the marketing site) —
   the pill itself only tracks the active tab, never the cursor. */
.topnav-links.has-slider a.on { background: transparent; color: #fff; }
@media (prefers-reduced-motion: reduce) { .topnav-links .nav-ind { transition: none; } }
.topnav-right {
  display: flex;
  align-items: center;
  gap: 10px;
  justify-self: end;
  padding-left: 16px;
  border-left: 1px solid var(--gris-clair);
}
.topnav .ico-btn {
  position: relative;
  width: 36px;
  height: 36px;
  border-radius: 999px;
  border: none;
  cursor: pointer;
  background: var(--gris-clair);
  color: var(--ardoise);
  display: grid;
  place-items: center;
  font-size: 15px;
  line-height: 1;
  text-decoration: none;
  transition: transform 0.15s;
}
.topnav .ico-btn:hover { transform: translateY(-1px); }
/* Visible command-palette opener: a search pill reading like a placeholder, with the shortcut.
   The topnav pill is white in BOTH themes, so this uses the static nav tokens (--gris-clair /
   --ardoise, never redefined) and literal light values — never theme-reactive tokens, which would
   flip to dark and break contrast on the white nav (mirrors how .ico-btn stays theme-invariant). */
.topnav .cmdk-trigger {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 36px;
  padding: 0 8px 0 12px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: var(--gris-clair);
  color: #64748b;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  transition: transform 0.15s, border-color 0.15s, color 0.15s;
}
.topnav .cmdk-trigger:hover {
  transform: translateY(-1px);
  border-color: var(--ardoise);
  color: var(--ardoise);
}
.topnav .cmdk-trigger svg { color: var(--ardoise); flex: none; }
.cmdk-trigger-lab { font-weight: 500; }
.cmdk-trigger-kbd {
  font-family: inherit;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ardoise);
  background: #fff;
  border: 1px solid rgba(15, 23, 42, 0.1);
  border-radius: 6px;
  padding: 3px 6px;
  line-height: 1;
}
.topnav .ico-badge {
  position: absolute;
  top: -3px;
  right: -3px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: #e5484d;
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  line-height: 1;
  display: grid;
  place-items: center;
}
.topnav .avatar {
  width: 36px;
  height: 36px;
  border-radius: 999px;
  border: none;
  cursor: pointer;
  background: var(--grad-or);
  color: #20180a;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  display: grid;
  place-items: center;
  transition: transform 0.15s;
}
.topnav .avatar:hover { transform: translateY(-1px); }

/* Account menu on the avatar (notifications + settings + sign-out) — keeps the top bar compact.
   The popover hangs over themed page content (not the white nav), so it uses themed tokens. */
.usermenu { position: relative; }
.usermenu > summary { position: relative; list-style: none; cursor: pointer; }
.usermenu > summary::-webkit-details-marker { display: none; }
.usermenu > summary::marker { content: ""; }
.usermenu[open] > summary { transform: translateY(-1px); }
.usermenu-pop {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 214px;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  box-shadow: var(--shadow-pop);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.usermenu-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 9px 11px;
  border: none;
  background: none;
  border-radius: 9px;
  font: inherit;
  font-size: 13.5px;
  color: var(--ink);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.usermenu-item:hover { background: var(--hover); }
.umi-ic { width: 18px; flex: none; text-align: center; font-size: 14px; }
.umi-badge {
  margin-left: auto;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--red);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.usermenu-sep { border: none; border-top: 1px solid var(--line); margin: 5px 4px; }
.usermenu-item.danger { color: var(--err-txt); }
.usermenu-item.danger:hover { background: var(--red-wash); }
/* Go-live call-to-action (top of the menu, brand accent). Pending state reads muted. */
.usermenu-item.golive { color: var(--accent-ink); font-weight: 600; }
.usermenu-item.golive:hover { background: var(--accent-wash); }
.usermenu-item.golive .umi-go { margin-left: auto; opacity: 0.75; }
.usermenu-item.golive.pending { color: var(--muted); font-weight: 500; }
.usermenu-item.golive.pending:hover { background: var(--hover); }

/* Content region: centered 1240px column that clears the sticky pill. Overrides the
   shared .content padding (this rule comes later in the file, so it wins). */
.cshell-content {
  width: 100%;
  max-width: 1240px;
  margin: 0 auto;
  padding: 58px 20px 90px;
}

/* ---- Mobile tab bar (client shell) --------------------------------------------------
   Desktop keeps the floating pill exactly as it is. Below 760px the pill's links move to a
   fixed bar at the bottom of the screen — thumb reach, one row, no wrapping. Hidden above
   that width, so there is never a second navigation on screen. */
.mobnav { display: none; }

/* Tablets (761–~900px): the pill still owns the navigation, but five links + the env chip no
   longer fit. Let the link row scroll inside the pill instead of wrapping it onto a second
   line and pushing the whole page sideways. `min-width: 0` is what actually allows a flex
   child to shrink below its content. */
.topnav-links {
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}
.topnav-links::-webkit-scrollbar { display: none; }
.topnav-links a { white-space: nowrap; }

@media (max-width: 760px) {
  .topnav-pill { gap: 10px; padding: 8px 10px 8px 16px; }
  .topnav-links { display: none; } /* they live in .mobnav down here */

  .mobnav {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 200;
    display: flex;
    justify-content: space-around;
    background: var(--surface);
    border-top: 1px solid var(--line-strong);
    /* Clear the home indicator on notched phones; 0px elsewhere. */
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .mobnav a {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    /* 56px ≥ the 44px minimum touch target (Apple HIG / Material). */
    min-height: 56px;
    padding: 8px 4px;
    text-decoration: none;
    color: var(--muted);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.01em;
  }
  .mobnav a svg { width: 21px; height: 21px; }
  .mobnav a span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
  /* "You are here" — violet, like every other selection in the design system. */
  .mobnav a.on { color: var(--violet-txt); }
  .mobnav a.on svg { stroke-width: 2.1; }

  /* Don't let the bar sit on top of the last row of content. */
  .cshell-content { padding: 34px 16px 96px; }
}

/* ---- Tables become cards on a phone (cardify.js adds .cards + data-label) ------------
   A dense table cannot shrink: below 760px its last columns land past the viewport, and on
   the dashboard there is no way to scroll to them. Each row becomes a card of labelled
   values instead. The class only lands once every cell carries its label, so with JS off
   the table stays a table inside its scrollable panel. */
.cards-switch { display: none; } /* desktop: the table is fine as a table */

@media (max-width: 760px) {
  table.cards,
  table.cards tbody { display: block; }
  table.cards thead { display: none; } /* the labels moved into the cells */
  table.cards tr {
    display: block;
    padding: 12px 14px;
    margin-bottom: 10px;
    border: 1px solid var(--line-strong);
    border-radius: 14px;
    background: var(--surface);
  }
  table.cards tr:last-child { margin-bottom: 0; }
  table.cards td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    padding: 5px 0;
    border: none;
    text-align: right;
  }
  table.cards td::before {
    content: attr(data-label);
    flex: 0 0 40%;
    text-align: left;
    color: var(--muted);
    font-size: 10.5px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
  }
  /* Cells with no header (an actions column) and the "no results" row: full width, no label. */
  table.cards td.card-full { display: block; text-align: left; }
  table.cards td.card-full::before { content: none; }
  /* The money is what the merchant came for. */
  table.cards td.num .amount { font-size: 16px; font-weight: 600; }
  /* The row is still the click target for the detail panel. */
  table.cards tr.txn-row { cursor: pointer; }

  /* The escape hatch, above the table: hand the real table back to whoever wants to compare. */
  .cards-switch { display: flex; justify-content: flex-end; margin-bottom: 10px; }

  /* ---- Density (lot 3) ------------------------------------------------------------
     The filter bar wrapped onto 136px of a 844px screen, KPI tiles were squeezed into
     four columns, and most controls sat under the 44px touch floor. */

  /* Two KPIs per line instead of four squeezed columns; the hero number takes the first
     line to itself — it's the one a merchant opens the app for. */
  .stats {
    grid-auto-flow: row;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    margin-bottom: 16px;
  }
  .stat .v { font-size: 20px; }
  .stat .v.hero { font-size: 24px; }

  .ledger-summary {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin-bottom: 16px;
  }
  .ledger-summary .stat { min-width: 0; padding: 13px 15px; border-left: 0; border-top: 1px solid var(--line); }
  .ledger-summary .stat.hero { grid-column: 1 / -1; border-top: 0; }
  /* With the hero on its own row, the right-hand column is every odd tile after it. */
  .ledger-summary .stat:nth-child(odd):not(.hero) { border-left: 1px solid var(--line); }
  .ledger-summary .stat .v { font-size: 19px; }
  .ledger-summary .stat.hero .v { font-size: 28px; }

  .topnav .ico-btn, .topnav .avatar { width: 40px; height: 40px; }
  /* Collapse the search pill to an icon-only button; the shortcut hint is desktop-only anyway. */
  .topnav .cmdk-trigger { width: 40px; height: 40px; padding: 0; justify-content: center; }
  .cmdk-trigger-lab, .cmdk-trigger-kbd { display: none; }

  /* Finish the density intent above: the filter bar's own controls were still under the touch
     floor. Full-width search (easier to hit + type) and ≥40px targets on the filter/pager buttons. */
  .fsearch { width: 100%; }
  .btn-filter,
  .btn-cols,
  .pager .btn { min-height: 40px; display: inline-flex; align-items: center; }
}


/* ============ Client detail "My business" — V1 mockup redesign ============
   Hero + gold tabs + sticky identity side-card + glassy cards (onboarding stepper,
   activity, company, bank). Themed via scoped --cd-card / --cd-line so it reads in
   both the light (owner sidebar) and dark (client pill) shells. All forms/HTMX/gates
   in client_detail.html are unchanged — this is presentation only. */
.cd-wrap { --cd-card: #ffffff; --cd-line: #e7ecf3; }
/* Slightly denser fill in dark: these cards used to rely on backdrop-filter for presence,
   which composited a frame late and smeared a halo at the card edges. The blur is gone
   (see .side-card/.cd-card below); this opacity keeps them reading as surfaces. */
[data-theme="dark"] .cd-wrap { --cd-card: rgba(255, 255, 255, 0.05); --cd-line: rgba(255, 255, 255, 0.09); }

/* ---- hero ---- */
.cd-hero { margin: 6px 0 20px; }
.cd-crumb { font-size: 13px; color: var(--muted); margin-bottom: 10px; }
.cd-crumb a { color: var(--muted); text-decoration: none; }
.cd-crumb a:hover { color: var(--violet-txt); }
[data-theme="dark"] .cd-crumb a:hover { color: #c4b5fd; }
.cd-crumb b { color: var(--ink); font-weight: 500; }
.cd-crumb .sep { margin: 0 6px; opacity: 0.5; }
.cd-hero-row { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; flex-wrap: wrap; }
.cd-title { font-family: var(--display); font-size: 33px; font-weight: 600; letter-spacing: -0.03em; line-height: 1.05; margin: 0; color: var(--ink); }
.cd-title .cd-form { font-weight: 400; color: var(--muted); font-size: 0.62em; letter-spacing: 0; }
.cd-hero-actions { display: flex; gap: 12px; flex-wrap: wrap; }

/* (removed .btn-or — a dead duplicate of .btn.primary; use .btn.primary for the gold CTA.) */

/* ---- gold tab underline (scoped to this page's tabs) ---- */
.cd-tabs .ctab { position: relative; }
.cd-tabs .ctab.on { color: var(--ink); border-bottom-color: transparent; }
.cd-tabs .ctab.on::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2.5px;
  border-radius: 3px; background: var(--grad-or);
}

/* ---- two-column layout ---- */
.cd-wrap { display: grid; grid-template-columns: 280px 1fr; gap: 22px; align-items: start; }
@media (max-width: 900px) { .cd-wrap { grid-template-columns: 1fr; } }
.cd-side { display: flex; flex-direction: column; gap: 14px; position: sticky; top: 92px; }
@media (max-width: 900px) { .cd-side { position: static; } }

/* .side-card shares the glass-card surface with .cd-card (defined together below); only padding differs. */
/* Billing tab — subscription card (My business). */
.bill-plan { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.bill-plan-name { font-size: 16px; font-weight: 700; }
.bill-plan-fee { font-size: 13px; color: var(--muted); margin-top: 2px; }
.bill-plan-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.bill-plan-actions form { margin: 0; }
/* The period an invoice CONCERNS, under what it covers. Tabular so a column of spans
   ("June 2026", "27 Jul 2026 → 26 Jul 2027") lines up on the digits. Both themes read it
   from --muted, so nothing here needs a dark override. */
.inv-period { font-size: 12px; color: var(--muted); margin-top: 2px; font-variant-numeric: tabular-nums; }
.bill-card { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.bill-card-chip { font-size: 13px; font-weight: 600; padding: 5px 12px; border-radius: 999px; background: var(--st-bg, rgba(0,0,0,0.05)); border: 1px solid var(--line); }

.side-card { padding: 20px 22px; }
/* No backdrop-filter: it composited a frame late (the halo popped in ~20-30ms after load)
   and smeared past the rounded edges. The denser --cd-card fill above carries the look. */
.sc-item { padding: 11px 0; border-bottom: 1px solid var(--cd-line); }
.sc-item:first-child { padding-top: 0; }
.sc-item:last-child { border-bottom: none; padding-bottom: 0; }
.sc-k { font-size: 10.5px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--muted); margin-bottom: 5px; }
.sc-v { font-size: 13.5px; font-weight: 500; line-height: 1.4; color: var(--ink); font-variant-numeric: tabular-nums; }
.sc-v.mono { font-size: 12.5px; word-break: break-all; }
.dot-st { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--or1); box-shadow: 0 0 8px var(--or1); margin-right: 8px; vertical-align: 1px; }
.dot-st.ok { background: var(--ok, #22c55e); box-shadow: 0 0 8px rgba(34, 197, 94, 0.55); }
.dot-st.warn { background: var(--or2); box-shadow: 0 0 8px var(--or2); }
.dot-st.bad { background: var(--err); box-shadow: none; }
.dot-st.neutral { background: var(--muted); box-shadow: none; }
.side-card .copy {
  cursor: pointer; border: none; background: rgba(139, 92, 246, 0.14); color: var(--violet-txt);
  font-size: 10px; font-weight: 600; padding: 3px 9px; border-radius: 999px; margin-left: 8px;
  font-family: inherit; vertical-align: 1px; transition: background 0.2s;
}
[data-theme="dark"] .side-card .copy { color: #c4b5fd; }
.side-card .copy:hover { background: rgba(139, 92, 246, 0.28); }
.side-card .copy.copied { background: rgba(34, 197, 94, 0.2); color: var(--ok, #22c55e); }
.cd-admin { display: flex; flex-direction: column; gap: 8px; }
.cd-admin > .disclosure, .cd-admin .btn.block { width: 100%; box-sizing: border-box; }
.cd-admin .disclosure > summary { width: 100%; box-sizing: border-box; text-align: center; justify-content: center; }

/* ---- main column cards ---- */
.cd-main { display: flex; flex-direction: column; min-width: 0; }
/* The cards live inside the active tab panel, so space THEM (not .cd-main's panels).
   :not([hidden]) keeps the tab toggle working — an unconditional display would defeat
   the `hidden` attribute and reveal every panel at once. */
.cd-main .ctab-panel:not([hidden]) { display: flex; flex-direction: column; gap: 28px; }
/* One glass-card surface for both the content card and the side card (they differ only in padding). */
.cd-card, .side-card { background: var(--cd-card); border: 1px solid var(--cd-line); border-radius: var(--radius-card); }
.cd-card { padding: 24px 26px; position: relative; }
/* No backdrop-filter here either — same late-composited halo. --cd-card carries the surface. */
.cd-card.needed::before {
  content: ""; position: absolute; inset: -1px; border-radius: calc(var(--radius-card) + 1px); padding: 1px;
  background: var(--grad-or); opacity: 0.4;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude; pointer-events: none;
}
.card-title { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.card-title h2 { font-size: 12px; font-weight: 600; letter-spacing: 0.11em; text-transform: uppercase; color: var(--muted); margin: 0; }
.card-title .n { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.card-title .ml { margin-left: auto; }
.card-title .pct { font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--violet-txt); }
[data-theme="dark"] .card-title .pct { background: var(--grad-or); -webkit-background-clip: text; background-clip: text; color: transparent; }

/* ---- stepper ---- */
.stepper { display: flex; align-items: center; flex-wrap: wrap; margin: 4px 0 16px; }
.step { display: flex; align-items: center; gap: 10px; font-size: 13.5px; font-weight: 500; }
.step .dot { width: 28px; height: 28px; border-radius: 50%; display: grid; place-items: center; font-size: 12.5px; font-weight: 600; flex: none; }
.step.done .dot { background: var(--grad-or); color: #20180a; box-shadow: 0 0 16px rgba(255, 190, 10, 0.35); }
.step.now .dot { background: rgba(139, 92, 246, 0.15); color: var(--violet-txt); border: 1.5px solid var(--violet); }
[data-theme="dark"] .step.now .dot { color: #c4b5fd; }
.step.next .dot { background: transparent; color: var(--muted); border: 1.5px solid var(--cd-line); }
.step.done { color: var(--ink); }
.step.now { color: var(--violet-txt); font-weight: 600; }
[data-theme="dark"] .step.now { color: #c4b5fd; }
.step.next { color: var(--muted); }
.step .todo {
  font-size: 10.5px; font-weight: 600; min-width: 17px; height: 17px; padding: 0 5px; border-radius: 999px;
  display: inline-grid; place-items: center;
  background: rgba(139, 92, 246, 0.14); color: var(--violet-txt); border: 1px solid rgba(139, 92, 246, 0.3);
}
[data-theme="dark"] .step .todo { color: #c4b5fd; }
.step-line { width: 44px; height: 2px; margin: 0 12px; border-radius: 2px; background: var(--cd-line); flex: none; }
.step-line.filled { background: var(--grad-or); }
@media (max-width: 560px) { .step-line { width: 18px; margin: 0 6px; } }

/* ---- progress bar ---- */
.cd-card .bar { height: 8px; border-radius: 999px; background: rgba(139, 92, 246, 0.1); overflow: hidden; margin: 4px 0 16px; }
[data-theme="dark"] .cd-card .bar { background: rgba(255, 255, 255, 0.06); }
.cd-card .bar i { display: block; height: 100%; border-radius: 999px; background: var(--grad-or); box-shadow: 0 0 16px rgba(255, 190, 10, 0.4); }

/* ---- onboarding card: two blocks (verify company / choose product) ---- */
.onb-block { padding: 16px 0; border-top: 1px solid var(--cd-line); }
.onb-block:first-of-type { padding-top: 6px; border-top: 0; }
.onb-block:last-of-type { padding-bottom: 2px; }
.onb-block-h { display: flex; align-items: center; gap: 11px; margin-bottom: 13px; }
.onb-block-h .dot {
  width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center;
  font-size: 12px; font-weight: 600; flex: none;
  background: rgba(139, 92, 246, 0.15); color: var(--violet-txt); border: 1.5px solid var(--violet);
}
[data-theme="dark"] .onb-block-h .dot { color: #c4b5fd; }
.onb-block-h .dot.done { background: var(--grad-or); color: #20180a; border: 0; box-shadow: 0 0 16px rgba(255, 190, 10, 0.35); }
.onb-block-t { font-size: 14px; font-weight: 600; color: var(--ink); }
.onb-block-h .ml { margin-left: auto; }
.onb-block-h .n { font-size: 12.5px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---- lead + chips + sub-label ---- */
.cd-card .lead { font-size: 14px; line-height: 1.6; color: var(--ink); }
.cd-card .lead b { font-weight: 600; color: var(--violet-txt); }
[data-theme="dark"] .cd-card .lead b { color: var(--or1); }
.cd-card .lead .link-tab {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: var(--violet-txt); font-weight: 600; text-decoration: underline; text-underline-offset: 2px;
}
[data-theme="dark"] .cd-card .lead .link-tab { color: var(--or1); }
.cd-card .chips { display: flex; flex-wrap: wrap; gap: 9px; }
.cd-card .chip {
  display: inline-flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 500;
  padding: 8px 14px; text-decoration: none; color: var(--ink);
  background: var(--gris-clair); border: 1px solid var(--cd-line);
}
[data-theme="dark"] .cd-card .chip { background: rgba(255, 255, 255, 0.05); }
.cd-card a.chip:hover { border-color: var(--violet); transform: translateY(-1px); }
.cd-card .chip .d { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.d-violet { background: var(--violet); box-shadow: 0 0 8px var(--violet); }
/* "only needed later (production)" — muted neutral dot, calmer than the violet "needed
   now" dot; in-palette (replaces the off-palette cyan). */
.d-muted { background: var(--muted); }
.cd-card .sub-label { font-size: 10.5px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--muted); margin: 18px 0 10px; }
.cd-onboard-foot { margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--cd-line); display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.cd-onboard-foot form { margin: 0; }
.qr-toggle {
  display: inline-flex; align-items: center; gap: 8px; background: transparent; border: 1px solid var(--cd-line);
  color: var(--ink); font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  padding: 9px 16px; border-radius: 999px; transition: border-color 0.2s, background 0.2s;
}
.qr-toggle:hover { border-color: var(--violet); background: rgba(139, 92, 246, 0.06); }
.qr-toggle svg { width: 15px; height: 15px; }
.qr-toggle .chev { margin-left: 4px; color: var(--muted); transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1); }
.qr-toggle[aria-expanded="true"] .chev { transform: rotate(180deg); }
.qr-toggle[aria-expanded="true"] { border-color: var(--violet); }
@media (prefers-reduced-motion: reduce) { .qr-toggle .chev { transition: none; } }
.link-v { font-size: 12.5px; font-weight: 500; color: var(--violet-txt); text-decoration: none; }
[data-theme="dark"] .link-v { color: #c4b5fd; }
.link-v:hover { text-decoration: underline; }

/* ---- activity (reuse the ledger-summary band, drop its own frame inside the card) ---- */
.cd-card .ledger-summary { background: transparent; border: 0; padding: 0; margin: 0; }
.cd-card .empty { border: 1px dashed var(--cd-line); }

/* ---- company details grid ---- */
.cd-card .ledger.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 30px; }
@media (max-width: 640px) { .cd-card .ledger.grid2 { grid-template-columns: 1fr; } }

/* ---- tables inside cards use the card hairline ---- */
.cd-card th, .cd-card td { border-color: var(--cd-line); }

/* ============ Client shell — Phase 3: premium surfaces across all client pages ============
   Scope the glassy card language to the client (pill) shell so Dashboard / Transactions /
   Payouts inherit it automatically, with no per-template edits. Owner/partner (sidebar) are
   untouched. Themed via the same scoped tokens as client_detail. */
.cshell { --cd-card: #ffffff; --cd-line: #e7ecf3; }
[data-theme="dark"] .cshell { --cd-card: rgba(255, 255, 255, 0.035); --cd-line: rgba(255, 255, 255, 0.09); }

.cshell .panel,
.cshell .ledger-summary {
  background: var(--cd-card);
  border: 1px solid var(--cd-line);
  border-radius: var(--radius-card);
}
[data-theme="dark"] .cshell .panel,
[data-theme="dark"] .cshell .ledger-summary { backdrop-filter: blur(8px); }
.cshell .panel { padding: 22px 24px; }

/* Dashboard hero: on the nuit client page a pure-nuit banner blends in — elevate it and
   keep it glassy so it reads as a card. */
[data-theme="dark"] .cshell .hero-banner {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--cd-line);
  backdrop-filter: blur(8px);
}

/* Give the money-page tables the card hairline inside the client shell. */
.cshell .panel th,
.cshell .panel td { border-color: var(--cd-line); }

/* ============ Read-only "Preview as client" banner ============
   Shown to an owner/partner while previewing a client. Full-width amber bar at the very
   top (above the pill nav) with the way out. Themed via global tokens. */
.preview-bar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 9px 22px;
  background: linear-gradient(135deg, rgba(255, 214, 10, 0.16), rgba(255, 179, 0, 0.12));
  border-bottom: 1px solid rgba(255, 179, 0, 0.35);
  font-size: 13px;
  color: var(--ink);
  position: relative;
  z-index: 150;
}
.preview-tag {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #20180a;
  background: var(--grad-or);
  padding: 3px 10px;
  border-radius: 999px;
  flex: none;
}
.preview-txt { color: var(--muted); }
.preview-txt b { color: var(--ink); font-weight: 600; }
.preview-bar form { margin: 0 0 0 auto; }
.preview-exit {
  border: 1px solid var(--line);
  background: transparent;
  cursor: pointer;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
  padding: 6px 14px;
  border-radius: 999px;
  transition: border-color 0.2s, background 0.2s;
}
.preview-exit:hover { border-color: var(--violet); background: rgba(139, 92, 246, 0.06); }
/* Owner preview is editable — violet (an allowed state), not the amber read-only warning. */
.preview-bar.can-edit {
  background: linear-gradient(135deg, rgba(139, 92, 246, 0.16), rgba(139, 92, 246, 0.1));
  border-bottom-color: rgba(139, 92, 246, 0.35);
}
.preview-bar.can-edit .preview-tag { background: var(--violet); color: #fff; }

/* ============ Verification tab (client_detail) — entity-grouped documents ============
   V1 "documents-multi" mockup. Same people_view data + forms as the KYC macros, in a more
   readable per-entity layout. Scoped under .verif-card so .badge / .doc-row etc. never
   clash with the rest of the app. Themed via the --cd-card / --cd-line tokens. */
.verif-card .why-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 14px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--muted);
}
.verif-card .why-toggle:hover { color: var(--ink); }
.verif-card .why-toggle .chev { transition: transform 0.35s; }
.verif-card .why-toggle[aria-expanded="true"] .chev { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .verif-card .why-toggle .chev { transition: none; } }
.verif-card .why-panel {
  margin-top: 12px;
  padding: 14px 18px;
  border-radius: 14px;
  background: rgba(139, 92, 246, 0.05);
  border: 1px solid var(--cd-line);
}
[data-theme="dark"] .verif-card .why-panel { background: rgba(255, 255, 255, 0.04); }
.verif-card .why-panel p { font-size: 12.5px; line-height: 1.6; color: var(--muted); margin: 0 0 10px; }
.verif-card .why-panel p:last-child { margin-bottom: 0; }
.verif-card .why-panel b { color: var(--ink); font-weight: 600; }

/* group head: person / bank / company */
.verif-card .doc-group-head { display: flex; align-items: center; gap: 12px; margin: 28px 0 4px; }
.verif-card .gavatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(139, 92, 246, 0.1);
  color: var(--violet-txt);
  display: grid;
  place-items: center;
  font-size: 12.5px;
  font-weight: 600;
  flex: none;
}
[data-theme="dark"] .verif-card .gavatar { background: rgba(139, 92, 246, 0.16); color: #c4b5fd; }
.verif-card .gavatar.gicon { font-size: 15px; line-height: 1; }
.verif-card .gname { font-size: 14.5px; font-weight: 600; color: var(--ink); }
.verif-card .tag-role {
  font-size: 11px;
  font-weight: 500;
  color: var(--violet-txt);
  background: rgba(139, 92, 246, 0.1);
  padding: 2px 10px;
  border-radius: 999px;
  margin-left: 8px;
  vertical-align: 1px;
  white-space: nowrap;
}
[data-theme="dark"] .verif-card .tag-role { color: #c4b5fd; background: rgba(139, 92, 246, 0.16); }
.verif-card .tag-role.tag-neutral { color: var(--muted); background: var(--hover); }
.verif-card .gmeta { font-size: 12px; color: var(--muted); margin-top: 2px; font-variant-numeric: tabular-nums; }

/* document row */
.verif-card .doc-row {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px 0 12px 46px;
  border-bottom: 1px solid var(--cd-line);
  flex-wrap: wrap;
}
.verif-card .dico {
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: var(--gris-clair);
  display: grid;
  place-items: center;
  flex: none;
  font-size: 14px;
  line-height: 1;
}
[data-theme="dark"] .verif-card .dico { background: rgba(255, 255, 255, 0.05); }
.verif-card .dinfo { flex: 1; min-width: 220px; }
.verif-card .dinfo b { font-size: 13.5px; font-weight: 600; display: block; color: var(--ink); }
.verif-card .dsub { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; line-height: 1.5; }
.verif-card .dsub-bad { color: var(--err-txt); }
.verif-card .dact { display: flex; gap: 8px; flex-shrink: 0; margin-left: auto; align-items: center; flex-wrap: wrap; }

/* status badge */
.verif-card .badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  font-weight: 500;
  padding: 3px 11px;
  border-radius: 999px;
  flex: none;
  border: 1px solid transparent;
}
.verif-card .badge i { width: 6px; height: 6px; border-radius: 50%; }
.verif-card .b-pending { color: #92400e; background: rgba(255, 214, 10, 0.13); border-color: rgba(255, 179, 0, 0.35); }
.verif-card .b-pending i { background: var(--or2); }
.verif-card .b-received { color: #7c3aed; background: rgba(139, 92, 246, 0.08); border-color: rgba(139, 92, 246, 0.25); }
.verif-card .b-received i { background: var(--violet); }
.verif-card .b-verified { color: #047857; background: rgba(16, 185, 129, 0.08); border-color: rgba(16, 185, 129, 0.25); }
.verif-card .b-verified i { background: #10b981; }
.verif-card .b-rejected { color: #e11d48; background: rgba(225, 29, 72, 0.06); border-color: rgba(225, 29, 72, 0.25); }
.verif-card .b-rejected i { background: #fb7185; }
[data-theme="dark"] .verif-card .b-pending { color: var(--or1); background: rgba(255, 214, 10, 0.09); border-color: rgba(255, 214, 10, 0.3); }
[data-theme="dark"] .verif-card .b-received { color: #c4b5fd; background: rgba(139, 92, 246, 0.12); border-color: rgba(139, 92, 246, 0.3); }
[data-theme="dark"] .verif-card .b-verified { color: #6ee7b7; background: rgba(16, 185, 129, 0.1); border-color: rgba(16, 185, 129, 0.3); }
[data-theme="dark"] .verif-card .b-rejected { color: #fda4af; background: rgba(251, 113, 133, 0.1); border-color: rgba(251, 113, 133, 0.3); }

/* row action buttons */
.verif-card .btn-sm-or {
  display: inline-flex;
  align-items: center;
  background: var(--grad-or);
  color: #20180a;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  border: none;
  cursor: pointer;
  padding: 7px 15px;
  border-radius: 999px;
  box-shadow: 0 4px 14px rgba(255, 179, 0, 0.3);
  transition: transform 0.15s;
  list-style: none;
  white-space: nowrap;
}
.verif-card .btn-sm-or::-webkit-details-marker { display: none; }
.verif-card .btn-sm-or::marker { content: ""; }
.verif-card .btn-sm-or:hover { transform: translateY(-1px); }
.verif-card .btn-doc {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: transparent;
  color: var(--ink);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  border: 1px solid var(--cd-line);
  cursor: pointer;
  padding: 6px 13px;
  border-radius: 999px;
  transition: border-color 0.2s;
  text-decoration: none;
  white-space: nowrap;
}
.verif-card .btn-doc:hover { border-color: var(--violet); }
.verif-card .btn-doc svg { width: 14px; height: 14px; }

/* status legend */
.verif-card .doc-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  margin-top: 20px;
  padding-top: 15px;
  border-top: 1px solid var(--cd-line);
  font-size: 12px;
  color: var(--muted);
}
.verif-card .doc-legend .ld { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 7px; }
.verif-card .ld-p { background: var(--or2); }
.verif-card .ld-r { background: var(--violet); }
.verif-card .ld-v { background: #10b981; }
.verif-card .ld-x { background: #fb7185; }

/* the owner review select stays compact inline */
.verif-card .dact .inline-status { margin: 0; }

/* Fill-&-sign action not yet wired (acquiring contract e-signature) — shown but inert. */
.verif-card .btn-sm-or.is-soon {
  background: none;
  color: var(--muted);
  border: 1px dashed var(--cd-line);
  box-shadow: none;
  cursor: default;
  font-weight: 500;
}
.verif-card .btn-sm-or.is-soon:hover { transform: none; }

/* Verification: "Add beneficial owner" row + per-owner remove in the group head. */
.verif-card .verif-add { display: flex; align-items: center; gap: 12px; margin: 26px 0 2px; }
.verif-card .verif-add .disclosure { margin-left: auto; }
.verif-card .doc-group-head .gremove { margin-left: auto; margin-bottom: 0; }
.verif-card .doc-group-head .gremove button { font-size: 12px; }

/* Verification: "Continue on phone" QR panel under an ID / UBO row + trash remove. */
.verif-card .doc-phone-toggle svg { width: 14px; height: 14px; margin-right: 6px; }
.verif-card .doc-phone-toggle .chev { margin-left: 7px; transition: transform 0.35s; }
.verif-card .doc-phone-toggle[aria-expanded="true"] .chev { transform: rotate(180deg); }
/* Reveal as a smooth accordion (the mockup's qr-panel), not an instant show. */
.verif-card .doc-phone-panel {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  margin: 0 0 0 46px;
  padding: 0 18px;
  background: rgba(139, 92, 246, 0.06);
  border: 1px solid rgba(139, 92, 246, 0.2);
  border-width: 0;
  border-radius: 14px;
  transition: max-height 0.42s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.32s, padding 0.32s,
    margin 0.32s, border-width 0.32s;
}
.verif-card .doc-phone-panel.open {
  max-height: 260px;
  opacity: 1;
  margin: 4px 0 14px 46px;
  padding: 16px 18px;
  border-width: 1px;
}
[data-theme="dark"] .verif-card .doc-phone-panel { background: rgba(139, 92, 246, 0.1); }
@media (prefers-reduced-motion: reduce) {
  .verif-card .doc-phone-panel { transition: none; }
  .verif-card .doc-phone-toggle .chev { transition: none; }
}
.verif-card .doc-phone-panel .qr { background: #fff; border-radius: 10px; padding: 8px; line-height: 0; flex: none; }
.verif-card .doc-phone-panel .qr svg { display: block; width: 104px; height: 104px; }
.verif-card .doc-phone-txt { flex: 1; min-width: 240px; }
.verif-card .doc-phone-txt b { display: block; font-size: 14px; color: var(--ink); margin-bottom: 4px; }
.verif-card .doc-phone-txt p { font-size: 12.5px; line-height: 1.5; color: var(--muted); margin: 0 0 10px; }
.verif-card .doc-phone-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.verif-card .doc-phone-actions .btn-doc svg { width: 13px; height: 13px; margin-right: 5px; }
.verif-card .doc-phone-actions .link-plain { font-size: 12.5px; font-weight: 500; color: var(--muted); text-decoration: none; }
.verif-card .doc-phone-actions .link-plain:hover { color: var(--ink); text-decoration: underline; }
.verif-card .doc-group-head .gremove .btn-del svg { width: 16px; height: 16px; }

/* Verification: section headers (owners / bank / company) with an inline "+ Add", the
   empty-state boxes, the "Soon" pill, the subtle trash, and the inline add-form panels. */
.verif-card .sec-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 30px 0 0;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--cd-line);
}
.verif-card .sec-head h3 {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}
.verif-card .sec-head .ml { margin-left: auto; }
.verif-card .sec-head .btn-doc { padding: 6px 14px; }

/* subtle trash remove in a group head */
.verif-card .doc-group-head .gremove { margin-left: auto; margin-bottom: 0; }
.verif-card .trash-o {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  background: none;
  border: 1px solid transparent;
  padding: 0;
  cursor: pointer;
  color: var(--muted);
  transition: color 0.15s, background 0.15s, border-color 0.15s;
}
/* Destructive style on interaction (red text + wash + border) — design-system rule. */
.verif-card .trash-o:hover,
.verif-card .trash-o:focus-visible {
  color: var(--err);
  background: var(--err-wash);
  border-color: var(--err);
}

/* Freshly created owner / bank group slides in with a brief violet ring after ?added. */
.vg-anim.just-added {
  border-radius: 14px;
  animation: vgIn 0.5s cubic-bezier(0.2, 0.7, 0.2, 1), vgRing 1.7s ease-out 0.1s;
}
@keyframes vgIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes vgRing { 0% { box-shadow: 0 0 0 0 rgba(139, 92, 246, 0.35); } 100% { box-shadow: 0 0 0 8px rgba(139, 92, 246, 0); } }
@media (prefers-reduced-motion: reduce) { .vg-anim.just-added { animation: none; } }

/* dashed empty-state row (no owner / no bank yet) */
.verif-card .empty-row {
  margin-top: 14px;
  border: 1.5px dashed var(--cd-line);
  border-radius: 14px;
  background: transparent;
  padding: 18px 20px;
  font-size: 13px;
  line-height: 1.6;
  color: var(--muted);
}
[data-theme="dark"] .verif-card .empty-row { border-color: rgba(255, 255, 255, 0.14); }
.verif-card .empty-row b { color: var(--ink); font-weight: 600; }

/* "Soon" pill next to the (disabled) Review & sign */
.verif-card .soon {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  background: rgba(139, 92, 246, 0.12);
  padding: 3px 9px;
  border-radius: 999px;
  align-self: center;
}
.verif-card .btn-doc[disabled] { opacity: 0.45; cursor: default; }
.verif-card .btn-doc[disabled]:hover { border-color: var(--cd-line); }

/* inline add-owner / add-bank form panel (revealed under the section header) */
.verif-card .vadd-panel {
  margin: 14px 0 4px;
  max-width: 520px;
}
/* The 520px cap is for the old stacked forms; a wizard (form + live preview) needs the full
   width of the card, otherwise its two-column grid squeezes the inputs to a stub. */
.verif-card .vadd-panel:has(.vwrap) {
  max-width: none;
}
/* `.card-form` carries popover geometry (absolute, anchored under a <details> summary).
   These two panels open in the flow instead, and have no positioned ancestor to anchor to
   — left as popovers they both land at the page's bottom-right, stacked on each other. */
.verif-card .vadd-panel .card-form {
  position: static;
  width: auto;
  box-shadow: none;
}

/* ============ Split sign-in page (login.html) — V1 mockup ============
   A white form column + a nuit duotone photo column. Fixed light design (the login
   renders unauthenticated), all scoped under .login-split so nothing leaks. Drop a photo
   at static/login-photo.jpg; until then the nuit gradient base shows. */
.login-split {
  display: grid;
  grid-template-columns: minmax(440px, 42%) 1fr;
  min-height: 100vh;
  /* The form side's palette, in one place: light here, the console's night below. */
  --lg-bg: #fff;
  --lg-aurora: 0;
  --lg-glow-gold: rgba(255, 214, 10, 0.07);
  --lg-glow-violet: rgba(139, 92, 246, 0.06);
  --lg-wordmark: #0b1320;
  --lg-card-bg: transparent;
  --lg-card-line: transparent;
  --lg-card-shadow: none;
  --lg-card-pad: 0;
  --lg-card-max: 384px;
  --lg-e-bg: var(--grad-or);
  --lg-e-ink: transparent;
  --lg-wm-sub: #94a3b8;
  --lg-title: #0f172a;
  --lg-ink: #0f172a;
  --lg-sub: #64748b;
  --lg-link: var(--violet-txt);
  --lg-input-bg: #fff;
  --lg-input-line: #e7ecf3;
  --lg-placeholder: #b6c0ce;
  --lg-focus-ring: rgba(139, 92, 246, 0.12);
  --lg-rule: #f1f5f9;
  --lg-legal: #b6c0ce;
  --lg-flash-bg: var(--red-wash);
  --lg-flash-ink: var(--red);
  --lg-flash-line: #f1cccc;
}
/* Night: the console's dark theme, token for token (nuit canvas with its conic glow, the
   surface card with its line and shadow, line-strong inputs, violet-txt links), when the
   device asks for it or when the page is told (`html[data-theme="dark"]`: the Tap to Pay
   app's own view opens sign-up with ?theme=night on a phone in night mode). The app shows
   the page itself because Samsung Internet repaints any light page in colours of its own,
   whatever the page declares (2026-10-15). */
@media (prefers-color-scheme: dark) {
  .login-split {
  --lg-bg: #0b1320;
  --lg-aurora: 0.14;
  --lg-glow-gold: transparent;
  --lg-glow-violet: transparent;
  --lg-wordmark: #e8edf4;
  --lg-wm-sub: #94a3b8;
  --lg-card-bg: #131c2e;
  --lg-card-line: #24304a;
  --lg-card-shadow: 0 10px 40px rgba(0, 0, 0, 0.55);
  --lg-card-pad: 28px 26px;
  --lg-card-max: 420px;
  --lg-title: #e8edf4;
  --lg-ink: #e8edf4;
  --lg-sub: #94a3b8;
  --lg-link: #a78bfa;
  --lg-input-bg: #131c2e;
  --lg-input-line: #38455f;
  --lg-placeholder: #94a3b8;
  --lg-focus-ring: rgba(139, 92, 246, 0.12);
  --lg-rule: #24304a;
  --lg-legal: #94a3b8;
  --lg-flash-bg: rgba(229, 72, 77, 0.2);
  --lg-flash-ink: #fca5a5;
  --lg-flash-line: rgba(229, 72, 77, 0.35);
  }
}
html[data-theme="dark"] .login-split {
  --lg-bg: #0b1320;
  --lg-aurora: 0.14;
  --lg-glow-gold: transparent;
  --lg-glow-violet: transparent;
  --lg-wordmark: #e8edf4;
  --lg-wm-sub: #94a3b8;
  --lg-card-bg: #131c2e;
  --lg-card-line: #24304a;
  --lg-card-shadow: 0 10px 40px rgba(0, 0, 0, 0.55);
  --lg-card-pad: 28px 26px;
  --lg-card-max: 420px;
  --lg-title: #e8edf4;
  --lg-ink: #e8edf4;
  --lg-sub: #94a3b8;
  --lg-link: #a78bfa;
  --lg-input-bg: #131c2e;
  --lg-input-line: #38455f;
  --lg-placeholder: #94a3b8;
  --lg-focus-ring: rgba(139, 92, 246, 0.12);
  --lg-rule: #24304a;
  --lg-legal: #94a3b8;
  --lg-flash-bg: rgba(229, 72, 77, 0.2);
  --lg-flash-ink: #fca5a5;
  --lg-flash-line: rgba(229, 72, 77, 0.35);
}
html:has(> body > .login-split) { color-scheme: light dark; }
/* 900px, per the design: below it the photo column goes and the form stands alone. Shared by
   Sign in and Create account on purpose — the two pages must break at the same width. */
@media (max-width: 900px) {
  .login-split { grid-template-columns: 1fr; }
  .login-split .login-photo-side { display: none; }
}

/* ---- form side ---- */
.login-form-side {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: 36px 40px 64px;
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(640px 420px at -10% -10%, var(--lg-glow-gold), transparent 65%),
    radial-gradient(720px 480px at 110% 110%, var(--lg-glow-violet), transparent 65%),
    var(--lg-bg);
}
/* The console's night glow (its body::after), on the form side only at night. */
.login-form-side::after {
  content: "";
  position: absolute;
  top: -160px;
  left: 50%;
  transform: translateX(calc(-50% + 40px));
  width: 560px;
  height: 560px;
  border-radius: 50%;
  background: conic-gradient(from 90deg, #ffd60a, #8b5cf6, #ffd60a);
  filter: blur(110px);
  opacity: var(--lg-aurora);
  pointer-events: none;
}
.login-form-side > * { position: relative; z-index: 1; }
.login-brand { flex-shrink: 0; }
.login-wordmark { font-size: 22px; font-weight: 600; color: var(--lg-wordmark); letter-spacing: -0.02em; text-decoration: none; }
.login-wordmark b {
  font-weight: 600;
  background: var(--lg-e-bg);
  -webkit-background-clip: text;
  background-clip: text;
  color: var(--lg-e-ink);
  -webkit-text-fill-color: var(--lg-e-ink);
}
.login-wm-sub { font-size: 8px; font-weight: 600; letter-spacing: 0.28em; color: var(--lg-wm-sub); text-transform: uppercase; margin-top: 2px; }
.login-center { flex: 1; display: flex; align-items: center; justify-content: center; width: 100%; }
.login-box {
  width: 100%;
  max-width: var(--lg-card-max);
  box-sizing: border-box;
  /* At night the form sits in the console's card (the same one the other sign-in pages use). */
  background: var(--lg-card-bg);
  border: 1px solid var(--lg-card-line);
  border-radius: var(--radius-card);
  box-shadow: var(--lg-card-shadow);
  padding: var(--lg-card-pad);
}
.login-box h1 { font-family: var(--display); font-size: 30px; font-weight: 600; letter-spacing: -0.025em; margin: 0 0 10px; color: var(--lg-title); }
.login-sub { font-size: 14.5px; color: var(--lg-sub); line-height: 1.55; margin-bottom: 32px; }
.login-box label { display: block; font-size: 13px; font-weight: 600; margin-bottom: 7px; color: var(--lg-ink); }
.login-lrow { display: flex; align-items: baseline; justify-content: space-between; }
.login-lrow a { font-size: 12.5px; font-weight: 500; color: var(--lg-link); text-decoration: none; }
.login-lrow a:hover { text-decoration: underline; }
/* Sign-up's password rule sits ON the label's line (a hint, not an action like "Forgot
   password?" — so it hugs the label instead of being pushed to the far edge). */
.login-lrow-hint { justify-content: flex-start; gap: 8px; }
.login-hint { font-size: 11.5px; color: var(--lg-sub); }
/* Create-account only: the form rises in a short cascade on first paint. Sign in has no
   motion, and the mockup asks for it here — 600ms, gone before a comparison. */
.login-split .reveal { opacity: 0; transform: translateY(14px); animation: login-rise 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) forwards; }
@keyframes login-rise { to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .login-split .reveal { opacity: 1; transform: none; animation: none; }
}
.login-box input {
  width: 100%;
  font-family: inherit;
  font-size: 14.5px;
  color: var(--lg-ink);
  padding: 13px 16px;
  border: 1.5px solid var(--lg-input-line);
  border-radius: 14px;
  background: var(--lg-input-bg);
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
  margin-bottom: 18px;
}
.login-box input::placeholder { color: var(--lg-placeholder); }
.login-box input:focus { border-color: var(--violet); box-shadow: 0 0 0 4px var(--lg-focus-ring); }
.login-box .flash { margin-bottom: 18px; }
.login-box .flash.error { background: var(--lg-flash-bg); color: var(--lg-flash-ink); border-color: var(--lg-flash-line); }
.login-btn-or {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  /* The gold gradient, as a 240x64 raster of the same stops (made by scripts, see the
     night comment above): Samsung Internet's dark mode halves an image's brightness, so
     this reads ochre there, where the CSS gradient is painted near black. Elsewhere the
     two are the same picture. */
  background: var(--grad-or);
  background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPAAAABACAIAAACr/W2wAAADhUlEQVR42u2dwVIsMQhFr/yf/7/2S3grLcc3SQfSpAm5G8vqGqaw+4gx5Awf+vUJVQDA91f99f3bK5cveLky9p7+EEvmnhCY748t5OeuBoX8/+xeMr2+6ItadvH1BeJ5WrDf+qiQxoubnDlCdDgErhAdDoErpArNGEpPLJwhuJBM1h47mneGtDlTO5pq/GH/XoGZZqSheS4T2RNNBKMZTbMG06xNmpG+DM+9lRDN3QrtHM1aoQx3LspNaCrRXIJm6wqS0rz8D4JsUmg1zRrgQTQ7IfowzWlWMmJGE3Y0YS+0sKMJe6GFHU1oZEj7PvdgbYVss/C9MRPJUUiuntZoiIkzR4gOh8AVosMhI72CsmW4k4kQzQRoJqN5550QsXCmwWgq0eyGYBHNO++EyEmFVh9dAzjQvPphZ2iu0km5an1zDbCi0Oo6mqt3Urqt78FCQjTDC+3V/RmnuXonpbttF1RIrGjCjibsaMKOJuz3B3Y0MXB/tPX+x3VS2tt2iwqJ/WnZjp5GH3CFK8R09NQdcmIn5V3reymaCEYTx5y9rrPwvfH3Sg5GM2GhdRzNPaMMD2ciRDMBmk/TXGgnRDItT/VgNB0HzeuvH3xraOPTCpSpHCFBMpXWlKkO2AmhsbKjsUJw0W19E81KamDRFiBGW980VjaVqdhJeZcJjRXKVKV2QoRrgDA0dUuZavOdEMkoUxW3VqkGBmaS0liB/bRqrOfnCMmtBtY9U0pjpbRMdd6ZUhormY2V09cP8LS+aawkNVYILqZb30RzRzXw7E5Kd9vOj6YSzXCZimV4IBO5SaZCsH+lwf4VZaoiOyE0VrIZK1w/TP1e0VihGljqDwKNFaTRAggubv/0URorm8tUx++EyEmFNs8wK4TQzH8ozcZKFplqdzWQMhXiPjlpf2OFc9a4E/KybUdjhXPWqmRCY4UyValMaKw8Yqxw/RCViXANQDWwUiZCNClTVcrEYqw456xpmjlrFWUq7oS0P32UxgrnrGH/wZs0VjhnrdCZUhornLO2dyelsYamsUI1sEQmUmIM8Mo5a5SpUmciy2UqPD/MaopmrTNnrWImRxorVAPrZkJjZQBNylT7ZEJjhXPWSmVCY4Vz1kplIrRWOWetUiZCNDlnrVImcpPnFz1nDZyzxjI8+OmjNFYoU9XJhMbKffoJ1w8JMqGxQjUQ9QZvEk3KVEUy+Qcdt4WlCffSswAAAABJRU5ErkJggg==") center / 100% 100% no-repeat;
  color: #20180a;
  font-family: inherit;
  font-size: 15px;
  font-weight: 600;
  border: none;
  cursor: pointer;
  padding: 14px 24px;
  border-radius: 999px;
  box-shadow: 0 8px 26px rgba(255, 179, 0, 0.35);
  transition: transform 0.18s, box-shadow 0.18s;
  margin-top: 4px;
}
.login-btn-or:hover { transform: translateY(-2px); box-shadow: 0 12px 34px rgba(255, 179, 0, 0.5); }
.login-signup { text-align: center; font-size: 13.5px; color: var(--lg-sub); margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--lg-rule); }
.login-signup a { color: var(--lg-link); font-weight: 600; text-decoration: none; }
.login-signup a:hover { text-decoration: underline; }
.login-legal { position: absolute; bottom: 18px; left: 0; right: 0; text-align: center; font-size: 11.5px; color: var(--lg-legal); }

/* ---- brand / photo side ---- */
.login-photo-side { position: relative; background: #0b1320; overflow: hidden; }
.login-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: saturate(0.82) contrast(1.04) brightness(0.94); }
.login-photo-ph {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(560px 480px at 62% 38%, rgba(148, 163, 184, 0.3), transparent 68%),
    radial-gradient(420px 700px at 58% 78%, rgba(100, 116, 139, 0.35), transparent 70%),
    linear-gradient(160deg, #1b2740 0%, #111a2e 55%, #0b1320 100%);
}
.login-tint {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(200deg, rgba(139, 92, 246, 0.16), rgba(11, 19, 32, 0) 46%),
    linear-gradient(20deg, rgba(255, 179, 0, 0.1), rgba(11, 19, 32, 0) 40%);
  mix-blend-mode: overlay;
  pointer-events: none;
}
.login-shade {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(to top, rgba(11, 19, 32, 0.94) 0%, rgba(11, 19, 32, 0.55) 30%, rgba(11, 19, 32, 0.12) 58%, rgba(11, 19, 32, 0.25) 100%);
}
.login-overlay { position: absolute; left: 56px; right: 56px; bottom: 44px; z-index: 3; max-width: 560px; }
/* Narrow panel (900-1050px): the three claims must hold one line, so give the overlay the
   side margin back rather than shrink the type further. */
@media (max-width: 1050px) { .login-overlay { left: 26px; right: 26px; } }
.login-rule { width: 52px; height: 3px; border-radius: 3px; background: var(--grad-aurora); margin-bottom: 22px; }
.login-quote { font-family: var(--display); font-size: clamp(26px, 2.6vw, 36px); font-weight: 600; letter-spacing: -0.025em; line-height: 1.18; color: #f8fafc; }
.login-quote b { background: var(--grad-or); -webkit-background-clip: text; background-clip: text; color: transparent; font-weight: 600; }
.login-qwho { margin-top: 14px; max-width: 440px; }
.login-qwho span { font-size: 14px; line-height: 1.6; color: #a8b3c4; }
/* One line, always: the three claims read as a single seal, so they never wrap. Gap and
   size ride the viewport to hold that line down to the 900px breakpoint. */
.login-trust { display: flex; flex-wrap: nowrap; gap: clamp(10px, 1.4vw, 20px); margin-top: 30px; padding-top: 20px; border-top: 1px solid rgba(255, 255, 255, 0.14); font-size: clamp(10px, 0.86vw, 12px); color: #a8b3c4; }
.login-trust span { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.login-trust i { width: 6px; height: 6px; border-radius: 50%; background: var(--or2); flex-shrink: 0; }


/* ============ Design-system filter bar (.fbar) — doc §Filtres de liste ============
   Reusable list-filter component: always-visible search (/ shortcut), a dashed
   "＋ Filter" command menu (field → values), removable violet chips (instant, no
   Apply), date presets and a Columns popover. Themed via app tokens so it reads in
   both the merchant pill shell (dark default) and the owner sidebar (light default).
   Wired to Transactions first; the other list screens adopt it on their turn. */
.fbar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 4px 0 18px;
  position: relative;
  /* Own stacking context above the console's glass panels/KPI band: their backdrop-filter
     (dark) otherwise composites over the absolutely-positioned filter popover. */
  z-index: 30;
}
.fbar-form { display: contents; }

/* search pill */
.fsearch {
  display: flex;
  align-items: center;
  gap: 9px;
  flex: 0 1 300px;
  min-width: 210px;
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 9px 16px;
  transition: border-color 0.2s, box-shadow 0.2s;
}
.fsearch:focus-within { border-color: var(--violet); box-shadow: 0 0 0 4px rgba(139, 92, 246, 0.12); }
.fsearch-ic { opacity: 0.55; font-size: 13px; line-height: 1; flex: none; }
.fsearch-input {
  flex: 1;
  min-width: 0;
  background: none;
  border: none;
  outline: none;
  font-family: inherit;
  font-size: 13.5px;
  color: var(--ink);
}
.fsearch-input::placeholder { color: var(--muted); }
.fsearch-input::-webkit-search-cancel-button { -webkit-appearance: none; }
.fsearch .slash {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--muted);
  border: 1px solid var(--line-strong);
  border-radius: 6px;
  padding: 1px 6px;
  flex-shrink: 0;
}

/* ＋ Filter — dashed command-menu trigger */
.fpop-wrap { position: relative; }
.btn-filter {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: transparent;
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  border: 1px dashed var(--line-strong);
  cursor: pointer;
  padding: 9px 16px;
  border-radius: 999px;
  transition: border-color 0.2s, background 0.2s;
}
.btn-filter:hover { border-color: var(--violet); background: rgba(139, 92, 246, 0.08); }

/* command-menu popover (light #fff / dark #151F33, doc §Filtres point 7) */
.fbar .pop {
  position: absolute;
  z-index: 60;
  top: calc(100% + 8px);
  left: 0;
  min-width: 250px;
  padding: 8px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: 0 24px 60px rgba(15, 23, 42, 0.18);
  display: none;
  animation: fpop 0.2s cubic-bezier(0.2, 0.7, 0.2, 1);
}
[data-theme="dark"] .fbar .pop { background: #151f33; border-color: rgba(255, 255, 255, 0.1); box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55); }
.fbar .pop.open { display: block; }
@keyframes fpop { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: none; } }
.fbar .p-item {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  text-align: left;
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink);
  background: none;
  border: none;
  cursor: pointer;
  padding: 9px 12px;
  border-radius: 10px;
  transition: background 0.15s;
}
.fbar .p-item:hover { background: rgba(139, 92, 246, 0.12); }
.fbar .p-item .ic { width: 18px; text-align: center; opacity: 0.7; font-size: 13px; flex: none; }
.fbar .p-head { display: flex; align-items: center; gap: 8px; padding: 6px 8px 10px; font-size: 12px; font-weight: 600; color: var(--muted); }
.fbar .p-back { background: none; border: none; color: var(--violet-txt); cursor: pointer; font-family: inherit; font-size: 12px; font-weight: 600; }
[data-theme="dark"] .fbar .p-back { color: #c4b5fd; }
.fbar .p-search {
  width: 100%;
  background: var(--hover);
  border: 1px solid var(--line);
  border-radius: 10px;
  font-family: inherit;
  font-size: 13px;
  color: var(--ink);
  padding: 8px 12px;
  outline: none;
  margin-bottom: 6px;
}
.fbar .p-search::placeholder { color: var(--muted); }
.fbar .p-list { max-height: 260px; overflow-y: auto; }
.fbar .p-item.scoped-out { display: none !important; }

/* active-filter chips — violet, removable, on every viewport (overrides the phone-only base) */
.fbar .fchips { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 0; }
.fbar .fchip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--violet-txt);
  background: rgba(139, 92, 246, 0.1);
  border: 1px solid rgba(139, 92, 246, 0.3);
  padding: 6px 8px 6px 13px;
  border-radius: 999px;
  animation: fpop 0.25s cubic-bezier(0.2, 0.7, 0.2, 1);
}
[data-theme="dark"] .fbar .fchip { color: #c4b5fd; background: rgba(139, 92, 246, 0.12); }
.fbar .fchip:hover { text-decoration: none; }
.fbar .fchip span {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: rgba(139, 92, 246, 0.16);
  color: inherit;
  font-size: 10px;
  line-height: 1;
  display: grid;
  place-items: center;
  transition: background 0.15s, color 0.15s;
}
.fbar .fchip:hover span { background: rgba(225, 29, 72, 0.25); color: var(--err); }
.fbar .clear-all { font-size: 12.5px; font-weight: 500; color: var(--muted); text-decoration: underline; }
.fbar .clear-all:hover { color: var(--ink); }

/* right cluster: date presets + columns */
.fbar .fright { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.fbar .seg { display: inline-flex; background: var(--surface); border: 1px solid var(--line); border-radius: 999px; padding: 3px; }
.fbar .seg button {
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  background: none;
  border: none;
  cursor: pointer;
  padding: 6px 13px;
  border-radius: 999px;
  transition: background 0.2s, color 0.2s;
}
.fbar .seg button.on { background: var(--hover); color: var(--ink); }
.fbar .daterange-slot { display: inline-flex; }
.fbar .daterange-slot[hidden] { display: none; }
.btn-cols {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: transparent;
  color: var(--ink);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  border: 1px solid var(--line-strong);
  cursor: pointer;
  padding: 9px 16px;
  border-radius: 999px;
  list-style: none;
  transition: border-color 0.2s, background 0.2s;
}
.btn-cols::-webkit-details-marker { display: none; }
.btn-cols:hover { border-color: var(--violet); background: rgba(139, 92, 246, 0.08); }

@media (prefers-reduced-motion: reduce) {
  .fbar .pop, .fbar .fchip { animation: none; }
}
@media (max-width: 720px) {
  .fbar .fright { margin-left: 0; width: 100%; }
  .fbar .seg { flex: 1; }
  .fbar .seg button { flex: 1; }
}

/* ============================================================================
   Products — the directory of every way to get paid (products.html, product_page.html).
   One service = one row; the row's state carries the difference. No catalogue, no cards,
   no "Add" button, no gold CTA on the list (there is no primary action to take there).
   Values come straight from the mockups; light is the base, dark overrides below. */
/* Full width of the shell (.cshell-content already caps it at 1240px and centres it), so this
   page lines up with Dashboard / Transactions / My business. The mockup's 980px column was a
   standalone document with no shell around it. */
/* padding-top (not a child margin, which would collapse) gives the same ~32px title offset as
   .page-head so the Products header sits at the same height as the others (6px comes from
   .svc-head's own padding). */
.svcpage { width: 100%; position: relative; padding-top: 26px; }

.svc-head { position: relative; padding: 6px 0 10px; }
/* The conic halo behind the title — the only decoration on the page. It sits INSIDE the column
   (right: 0): a halo bleeding past the edge widens the page's scrollable area, and clipping it
   back is worse than not overflowing — the clip cuts the blur into a hard-edged tinted rectangle.
   Only the blur, which is ink and not layout, is allowed to spill. */
.svc-head::before {
  content: "";
  position: absolute; top: -170px; right: 0; width: 520px; height: 520px;
  background: conic-gradient(from 90deg, #ffd60a, #8b5cf6, #ffd60a);
  filter: blur(110px); opacity: 0.11; border-radius: 50%; pointer-events: none;
}
.svcpage h1 { margin: 0; font-size: 33px; line-height: 1.05; font-weight: 600; letter-spacing: -0.03em; position: relative; }
.svc-sub { font-size: 14px; color: var(--muted); margin-top: 20px; position: relative; }

.svcpage .group { margin-top: 30px; }
.svcpage .g-label {
  font-size: 10.5px; font-weight: 600; letter-spacing: 0.12em;
  text-transform: uppercase; color: #94a3b8;
}
.svcpage .list {
  border: 1px solid #e7ecf3; border-radius: 20px; background: #fff;
  margin-top: 14px; overflow: hidden; box-shadow: 0 10px 30px rgba(15, 23, 42, 0.05);
}

/* --- a service row: icon | name + one honest sentence | state | chevron --- */
.svc {
  display: flex; align-items: center; gap: 17px; padding: 21px 24px;
  border-bottom: 1px solid #eef2f7; cursor: pointer;
  text-decoration: none; color: inherit; transition: background 0.15s;
}
.svc:last-child { border-bottom: none; }
/* The whole row is one link, so the global a:hover underline would run under every word of
   it (name, sentence, figures, state). Hover says "this opens" with the row's tint, the
   icon tile and the arrow instead. */
.svc:hover { background: #f8f9fc; text-decoration: none; }
.svc:focus-visible { outline: 2px solid var(--violet); outline-offset: -2px; }
.picon {
  width: 44px; height: 44px; border-radius: 13px; display: grid; place-items: center;
  font-size: 20px; flex-shrink: 0; background: rgba(139, 92, 246, 0.1);
  transition: background 0.15s;
}
.svc:hover .picon { background: rgba(139, 92, 246, 0.16); }
.picon.big { width: 54px; height: 54px; border-radius: 16px; font-size: 24px; }
.svc .nm { max-width: 440px; }
.svc .nm b { display: block; font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.svc .nm span { display: block; font-size: 12.5px; color: var(--muted); line-height: 1.55; margin-top: 3px; }

.svc .state { margin-left: auto; display: flex; align-items: center; gap: 26px; }
/* Running: its figures live in the row. */
.live { display: flex; gap: 30px; text-align: right; }
.live .v { font-size: 15px; font-weight: 600; font-variant-numeric: tabular-nums; }
.live .v.hero {
  background: linear-gradient(135deg, #7c3aed, #8b5cf6);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.live .l {
  font-size: 10px; color: #94a3b8; text-transform: uppercase;
  letter-spacing: 0.07em; font-weight: 600; margin-top: 3px;
}
/* Green is reserved for this, and only when a checkout has actually opened. */
.dot-on { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 500; color: #047857; }
.dot-on i { width: 7px; height: 7px; border-radius: 50%; background: #10b981; }
/* Not yet used: a calm invitation, never a shop button. */
.setup { font-size: 13px; font-weight: 600; color: var(--violet-txt); white-space: nowrap; }
.svc-muted { font-size: 12px; color: var(--muted); white-space: nowrap; }
.svc-warn { font-size: 12px; font-weight: 500; color: var(--err-txt); white-space: nowrap; }
.chev { color: #94a3b8; font-size: 15px; transition: transform 0.2s, color 0.15s; }
.svc:hover .chev { transform: translateX(3px); color: var(--violet-txt); }

.svcpage .note { font-size: 12px; color: var(--muted); margin-top: 16px; line-height: 1.6; }
.svcpage .note a { color: var(--violet-txt); text-decoration: none; font-weight: 600; }
.svcpage .note a:hover { text-decoration: underline; }
.svcpage .banner { margin: 16px 0 0; }
.svcpage .banner.ok { color: var(--ok-txt); background: var(--ok-wash); border-color: var(--ok); }

/* --- a single product's page --- */
.prod-hero { display: flex; align-items: center; gap: 17px; padding-top: 4px; }
.prod-hero h1 { font-size: 28px; }
.prod-hero-state { margin-left: auto; }
.svcpage .prod-body { padding: 24px; }
.prod-p { font-size: 13.5px; line-height: 1.65; color: var(--ink); margin: 0 0 16px; max-width: 620px; }
.prod-p a { color: var(--violet-txt); font-weight: 600; }
.svcpage .prod-body form { margin: 0; }

@media (max-width: 760px) {
  .live { display: none; }
  .svc .nm { max-width: none; }
  .prod-hero-state { margin-left: 0; }
}
/* Narrow phones: icon + name + "Available once live" + chevron on one line needs ~330px, so
   the state was cut off by a handful of pixels — the very word that says whether the product
   is usable. It drops under the name instead. */
@media (max-width: 380px) {
  .svc { flex-wrap: wrap; gap: 12px 14px; padding: 18px 16px; }
  .svc .nm { flex: 1 1 100%; order: 2; }
  .svc .state { margin-left: 0; flex: 1 1 100%; order: 3; gap: 12px; justify-content: space-between; }
}

.svcpage .reveal { animation: svc-up 0.6s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
@keyframes svc-up { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .svcpage .reveal { animation: none; } }

/* View Transitions: kept minimal. Tab switches (client-side and server/reload) no longer slide the
   content region — snapshotting a heavy page (the transactions table) hitched the switch, so tabs
   now load/toggle plainly and the slide-tabs underline carries the motion instead. We keep
   `navigation: auto` only because the pageswap guard in base.html reads `e.viewTransition` to set
   the `__nocascade` flag on same-path reloads (it always skips the actual transition). The root
   suppression keeps the shell from animating if any transition ever runs. Chrome/Edge; a no-op
   elsewhere. */
@view-transition { navigation: auto; }
::view-transition-old(root),
::view-transition-new(root) { animation: none; } /* the shell stays put */

/* Page-load "volet" cascade (the Products page feel) for MAIN-page navigation: the reveal script
   in base.html rises + fades main.content's top-level blocks in, staggered. It's skipped when a
   load was a tab-content slide (a VT already handled it) and on the Products page (its own
   .svcpage cascade). Keyframe only here — the script sets the per-block delay. */
@keyframes page-rise { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }

[data-theme="dark"] .svc-head::before { opacity: 0.14; }
[data-theme="dark"] .svcpage .list {
  border-color: rgba(255, 255, 255, 0.08);
  background: rgba(255, 255, 255, 0.035);
  box-shadow: none;
}
[data-theme="dark"] .svc { border-bottom-color: rgba(255, 255, 255, 0.05); }
[data-theme="dark"] .svc:hover { background: rgba(255, 255, 255, 0.028); }
[data-theme="dark"] .picon { background: rgba(139, 92, 246, 0.14); }
[data-theme="dark"] .live .v.hero { background-image: linear-gradient(135deg, #c4b5fd, #8b5cf6); }
[data-theme="dark"] .dot-on { color: #6ee7b7; }
[data-theme="dark"] .dot-on i { background: #34d399; box-shadow: 0 0 8px #34d399; }
[data-theme="dark"] .setup { color: #c4b5fd; }
[data-theme="dark"] .svcpage .note a { color: #c4b5fd; }

/* ============================================================================
   Pay by link — product page (Products / Pay by link). Reuses the shared
   .stats/.stat, .panel, table and .pill components; adds the header extras, the
   segmented drawer, campaign cards, sparkline and the violet "used up" pill.
   All colours come from tokens, so dark + light re-theme with data-theme. */
.pbl-crumb { font-size: 13px; color: var(--muted); margin-bottom: 10px; }
.pbl-crumb a { color: var(--muted); text-decoration: none; }
.pbl-crumb a:hover { color: var(--ink); }
.pbl-crumb b { color: var(--ink); font-weight: 500; }
.pbl-head-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.pbl-head-left { display: flex; align-items: center; gap: 14px; }
.pbl-head-left h1 { font-family: var(--display); font-weight: 600; font-size: 30px; letter-spacing: -0.03em; margin: 0; }
.pbl-head-actions { display: flex; gap: 10px; align-items: center; }

.pbl-tabs { display: flex; gap: 24px; border-bottom: 1px solid var(--line); margin: 18px 0 22px; }
.pbl-tabs button { background: none; border: none; font-family: inherit; cursor: pointer; color: var(--muted); font-size: 14.5px; font-weight: 500; padding: 11px 2px; position: relative; transition: color 0.2s; }
.pbl-tabs button:hover { color: var(--ink); }
.pbl-tabs button.on { color: var(--ink); }
.pbl-tabs button.on::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2.5px; border-radius: 3px; background: var(--grad-or); }

.pbl-panel { display: none; }
.pbl-panel.on { display: block; }
/* Developer hub tab panels (same tabbed pattern as pay-by-link). */
.dev-panel { display: none; }
.dev-panel.on { display: block; animation: tab-in 0.28s cubic-bezier(0.2, 0.7, 0.2, 1); }
@media (prefers-reduced-motion: reduce) { .dev-panel.on { animation: none; } }
.dev-quick { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 16px; }
@media (max-width: 900px) { .dev-quick { grid-template-columns: 1fr; } }
.dev-step { background: var(--card, var(--surface)); border: 1px solid var(--line); border-radius: 16px; padding: 20px 22px; }
.dev-step .n { width: 26px; height: 26px; border-radius: 50%; background: rgba(139, 92, 246, 0.15); border: 1px solid rgba(139, 92, 246, 0.4); color: var(--violet-txt); display: inline-grid; place-items: center; font-size: 12.5px; font-weight: 700; margin-bottom: 12px; }
.dev-step h3 { font-size: 15px; font-weight: 600; margin: 0 0 5px; }
.dev-step p { font-size: 12.5px; color: var(--muted); line-height: 1.6; margin: 0; }

/* ===== Dedicated API docs page (/developers/docs) ===== */
.apidocs { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: 44px; align-items: start; margin-top: 26px; max-width: 1120px; }
@media (max-width: 1000px) { .apidocs { grid-template-columns: 1fr; } .apidocs-side { display: none; } }
.apidocs-side { position: sticky; top: 100px; font-size: 13px; }
.apidocs-side .k { display: block; font-size: 10px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); margin: 18px 0 6px; }
.apidocs-side a { display: block; color: var(--muted); text-decoration: none; padding: 5px 10px; border-left: 2px solid transparent; border-radius: 0 8px 8px 0; }
.apidocs-side a:hover { color: var(--ink); background: rgba(127, 127, 127, .06); }
.apidocs-main { min-width: 0; }
.apidocs-main h2 { font-size: 22px; font-weight: 600; letter-spacing: -.02em; margin: 44px 0 8px; scroll-margin-top: 96px; }
.apidocs-main h2:first-child { margin-top: 0; }
.apidocs-main h3 { font-size: 16px; font-weight: 600; margin: 26px 0 6px; }
.apidocs-main > p { font-size: 13.5px; color: var(--ink-soft); line-height: 1.7; margin: 8px 0; max-width: 660px; }
.param-table { width: 100%; border-collapse: collapse; margin-top: 14px; font-size: 13px; }
.param-table th { text-align: left; font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); font-weight: 600; padding: 8px 12px; border-bottom: 1px solid var(--line); }
.param-table td { padding: 12px; border-bottom: 1px solid var(--line); vertical-align: top; }
.param-table td:first-child { font-family: var(--mono, ui-monospace); font-size: 12.5px; white-space: nowrap; }
.param-table .ptype { color: var(--muted); font-size: 11px; }
/* --or2 is a FILL (1.8:1 as text on white). The marker that says a parameter is
   REQUIRED has to be legible: --warn-txt is 5:1. */
.param-table .preq { color: var(--warn-txt); font-size: 9.5px; font-weight: 700; letter-spacing: .06em; margin-left: 6px; vertical-align: middle; }
.param-table td:last-child { color: var(--ink-soft); line-height: 1.6; }
.testcards { width: 100%; border-collapse: collapse; margin-top: 14px; font-size: 13px; }
.testcards th { text-align: left; font-size: 10px; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); font-weight: 600; padding: 8px 12px; border-bottom: 1px solid var(--line); }
.testcards td { padding: 11px 12px; border-bottom: 1px solid var(--line); }
.testcards td:first-child { font-family: var(--mono, ui-monospace); }
/* Subscriptions has no tabs row (single view), so its KPIs would hug the header. Give the first
   block the breathing room the Pay-by-link tabs otherwise provide. */
.subs-lead { margin-top: 24px; }

/* Hero KPI number — the violet gradient figure (design system Stats). */
.stat .v.hero { background: linear-gradient(135deg, #c4b5fd, #8b5cf6); -webkit-background-clip: text; background-clip: text; color: transparent; }
[data-theme="light"] .stat .v.hero { background: linear-gradient(135deg, #8b5cf6, #7c3aed); -webkit-background-clip: text; background-clip: text; color: transparent; }

/* Link cell */
.pbl-lname b { display: block; font-size: 13.5px; font-weight: 600; }
.pbl-url { display: inline-flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--muted); margin-top: 3px; }
.pbl-copy { background: var(--accent-wash); color: var(--violet-txt); border: none; cursor: pointer; font-family: inherit; font-size: 9.5px; font-weight: 600; padding: 2px 8px; border-radius: 999px; transition: background 0.15s; }
.pbl-copy:hover { background: rgba(139, 92, 246, 0.24); }
.pbl-copy.copied { color: var(--ok-txt); }
.pbl-amt-open { color: var(--violet-txt); font-weight: 600; }
.pbl-exp { color: var(--muted); font-size: 12.5px; }
.pbl-exp b { color: var(--ink); font-weight: 600; }
.pbl-camp { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 500; color: var(--violet-txt); background: var(--accent-wash); border: 1px solid rgba(139, 92, 246, 0.3); padding: 3px 10px; border-radius: 999px; }
.pbl-camp::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--violet); }

/* Violet "used up" pill — a completion, not a failure (design system). */
.pill.used { color: var(--violet-txt); background: var(--accent-wash); }
[data-theme="dark"] .pill.used { color: #c4b5fd; }

.pbl-racts { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
.pbl-ico { width: 30px; height: 30px; border-radius: 999px; border: 1px solid var(--line); background: transparent; color: var(--muted); cursor: pointer; font-size: 13px; display: grid; place-items: center; transition: border-color 0.2s, color 0.2s; text-decoration: none; }
.pbl-ico:hover { border-color: var(--violet); color: var(--ink); }
/* Web checkout: the Simulation tab (checkout simulator + webhook simulator). */
.wc-sim-modes { display: flex; gap: 18px; }
.wc-sim-modes label { display: inline-flex; align-items: center; gap: 7px; font-size: 13px; }
.wc-sim-items { border-collapse: collapse; margin-bottom: 10px; }
.wc-sim-items th { text-align: left; font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); font-weight: 600; padding: 4px 10px 4px 0; }
.wc-sim-items td { padding: 4px 10px 4px 0; }

/* Web checkout: the website switcher (one integration per e-commerce site). */
.wc-sites { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin: 4px 0 18px; }
.wc-site-pick { display: flex; align-items: center; gap: 8px; margin: 0; }
.wc-site-pick label { font-size: 12px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.wc-site-pick select { min-width: 200px; }
.wc-site-actions { display: flex; align-items: center; gap: 8px; }
.wc-site-actions .disclosure { position: relative; }
/* Web checkout: the default-return-URLs form. */
.wc-urls { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end; }
.wc-urls .field { flex: 1 1 280px; min-width: 220px; }
.wc-urls .field input { width: 100%; }
/* Appearance panel: a logo preview beside the display-name + upload fields. */
.wc-brand { display: flex; gap: 20px; align-items: flex-start; flex-wrap: wrap; }
.wc-brand-logo { flex: 0 0 auto; width: 88px; height: 88px; border-radius: 16px; border: 1px solid var(--line); background: #fff; display: grid; place-items: center; overflow: hidden; }
.wc-logo-preview { max-width: 100%; max-height: 100%; object-fit: contain; }
.wc-logo-empty { font-size: 11.5px; color: var(--muted); }
.wc-brand-fields { flex: 1 1 320px; min-width: 260px; display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.wc-brand-fields .field { width: 100%; }
.wc-brand-fields .field input[type="text"] { width: 100%; }
.wc-remove { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--muted); }
.fhelp { display: block; margin-top: 5px; font-size: 11.5px; color: var(--muted); }

.pbl-menu { position: relative; }
.pbl-menu > summary { list-style: none; width: 30px; height: 30px; border-radius: 999px; border: 1px solid var(--line); color: var(--muted); cursor: pointer; font-size: 15px; display: grid; place-items: center; }
.pbl-menu > summary::-webkit-details-marker { display: none; }
.pbl-menu[open] > summary { border-color: var(--violet); color: var(--ink); }
/* The rows live in a .scrollx panel (overflow-x:auto forces overflow-y to auto), and in the
   dark client shell that panel also has backdrop-filter — which both clips fixed descendants
   AND makes itself their containing block. So neither absolute nor fixed can escape it: on
   open, JS PORTALS this pop onto <body> and anchors it under the trigger (right-aligned), so
   it spills freely past the card; on close it is stowed back inside its <details>. */
/* Hidden until JS has portaled it onto <body> AND positioned it — so it is never painted
   in-flow inside the panel for a frame (that flashed the scrollbars and flicked on open). */
.pbl-menu-pop { display: none; position: fixed; z-index: 40; min-width: 180px; background: var(--surface); border: 1px solid var(--line); border-radius: 12px; box-shadow: var(--shadow-pop); padding: 6px; flex-direction: column; gap: 2px; }
.pbl-menu-pop.pbl-open { display: flex; }
.pbl-menu-pop a, .pbl-menu-pop button { display: block; width: 100%; text-align: left; background: none; border: none; font-family: inherit; font-size: 12.5px; color: var(--ink); padding: 8px 10px; border-radius: 8px; cursor: pointer; text-decoration: none; }
.pbl-menu-pop a:hover, .pbl-menu-pop button:hover { background: var(--accent-wash); }
.pbl-menu-pop .danger { color: var(--err-txt); }
.pbl-menu-pop .danger:hover { background: var(--red-wash); }
.pbl-menu-pop form { margin: 0; }

.pbl-tfoot { display: flex; align-items: center; padding: 13px 16px; font-size: 12.5px; color: var(--muted); }
.pbl-linkpay { color: var(--violet-txt); text-decoration: none; font-weight: 600; font-size: 12.5px; }
.pbl-linkpay:hover { text-decoration: underline; }

/* Campaigns */
.pbl-cgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
@media (max-width: 1000px) { .pbl-cgrid { grid-template-columns: 1fr; } }
.pbl-ccard { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-card); box-shadow: var(--shadow-sm); padding: 20px; display: flex; flex-direction: column; }
.pbl-ccard .top { display: flex; align-items: flex-start; gap: 10px; }
.pbl-ccard h3 { font-family: var(--display); font-size: 15.5px; font-weight: 600; margin: 0; }
.pbl-ccard .per { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.pbl-ccard .top .pill { margin-left: auto; }
.pbl-ckpis { display: flex; margin: 16px 0 12px; }
.pbl-ckpis .k { flex: 1; }
.pbl-ckpis .k .v { font-family: var(--display); font-size: 19px; font-weight: 600; font-variant-numeric: tabular-nums; }
.pbl-ckpis .k .l { font-size: 10.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; font-weight: 600; margin-top: 2px; }
.pbl-spark { display: flex; align-items: flex-end; gap: 3px; height: 36px; margin: 2px 0 12px; }
.pbl-spark i { flex: 1; min-height: 2px; border-radius: 3px 3px 0 0; background: linear-gradient(180deg, #8b5cf6, rgba(139, 92, 246, 0.25)); }
.pbl-ccard .foot { display: flex; align-items: center; margin-top: auto; padding-top: 12px; border-top: 1px solid var(--line); }
.pbl-ccard .foot .n { font-size: 12px; color: var(--muted); }
.pbl-ccard .foot a { margin-left: auto; }
.pbl-ccard.new { border-style: dashed; border-color: var(--line-strong); background: transparent; box-shadow: none; align-items: center; justify-content: center; gap: 10px; min-height: 200px; cursor: pointer; transition: border-color 0.2s; }
.pbl-ccard.new:hover { border-color: var(--violet); }
.pbl-ccard.new .plus { width: 40px; height: 40px; border-radius: 50%; background: var(--accent-wash); color: var(--violet-txt); display: grid; place-items: center; font-size: 19px; }
.pbl-ccard.new p { font-size: 12.5px; color: var(--muted); text-align: center; max-width: 230px; line-height: 1.5; }
.pbl-ccard.new b { color: var(--ink); }

/* Drawer + scrim */
.pbl-scrim { position: fixed; inset: 0; background: rgba(4, 8, 16, 0.55); backdrop-filter: blur(2px); opacity: 0; pointer-events: none; transition: opacity 0.3s; z-index: 1500; }
.pbl-scrim.open { opacity: 1; pointer-events: auto; }
.pbl-drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(460px, 100%); z-index: 1600; background: var(--surface); border-left: 1px solid var(--line); box-shadow: -30px 0 80px rgba(0, 0, 0, 0.35); transform: translateX(105%); transition: transform 0.4s cubic-bezier(0.2, 0.7, 0.2, 1); display: flex; flex-direction: column; }
.pbl-drawer.open { transform: none; }
.pbl-dhead { display: flex; align-items: center; gap: 12px; padding: 20px 24px; border-bottom: 1px solid var(--line); }
.pbl-dhead h2 { font-family: var(--display); font-size: 17px; font-weight: 600; margin: 0; }
.pbl-dclose { margin-left: auto; width: 32px; height: 32px; border-radius: 999px; border: 1px solid var(--line); background: none; color: var(--muted); cursor: pointer; font-size: 13px; }
.pbl-dclose:hover { color: var(--ink); border-color: var(--violet); }
.pbl-dbody { flex: 1; overflow-y: auto; padding: 22px 24px; }
.pbl-fgroup { margin-bottom: 22px; }
/* Edit-mode notice when a link already took money: amount/expiry are locked. */
.pbl-locknote { font-size: 12.5px; line-height: 1.5; color: var(--warn-txt); background: var(--warn-bg); border-radius: 10px; padding: 11px 13px; margin-bottom: 20px; }
.pbl-finput:disabled, .seg2 button:disabled { opacity: 0.55; cursor: not-allowed; }
.pbl-flabel { display: block; font-size: 12.5px; font-weight: 600; margin: 0 0 8px; }
.pbl-fhelp { font-size: 11.5px; color: var(--muted); margin-top: 6px; line-height: 1.5; }
.pbl-finput { width: 100%; font-family: inherit; font-size: 14px; color: var(--ink); background: var(--canvas); border: 1.5px solid var(--line); border-radius: 12px; padding: 11px 14px; outline: none; transition: border-color 0.2s, box-shadow 0.2s; }
.pbl-finput:focus { border-color: var(--violet); box-shadow: 0 0 0 4px var(--accent-wash); }
.pbl-frow { display: flex; gap: 10px; align-items: center; }
.pbl-frow .pbl-finput { flex: 1; min-width: 0; }
.pbl-frow span { font-size: 13px; color: var(--muted); white-space: nowrap; }
.seg2 { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; background: var(--canvas); border: 1px solid var(--line); border-radius: 12px; padding: 3px; gap: 3px; }
.seg2 button { font-family: inherit; font-size: 12.5px; font-weight: 600; color: var(--muted); background: none; border: none; cursor: pointer; padding: 9px 6px; border-radius: 9px; transition: all 0.2s; }
.seg2 button.on { background: var(--accent-wash); color: var(--violet-txt); }
.pbl-cond { margin-top: 10px; display: none; }
.pbl-cond.show { display: block; animation: pblfade 0.25s; }
@keyframes pblfade { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
.pbl-dfoot { padding: 16px 24px; border-top: 1px solid var(--line); }
.pbl-dfoot .btn { width: 100%; }

/* Success state (inside the drawer) */
.pbl-success { text-align: center; padding-top: 6px; }
.pbl-success .okmark { width: 52px; height: 52px; border-radius: 50%; background: var(--grad-or); display: grid; place-items: center; font-size: 22px; color: #20180a; margin: 6px auto 14px; }
.pbl-success h3 { font-family: var(--display); font-size: 17px; font-weight: 600; margin: 0 0 6px; }
.pbl-success .recap { font-size: 13px; color: var(--muted); margin-bottom: 18px; }
.pbl-linkbox { display: flex; align-items: center; gap: 10px; background: var(--accent-wash); border: 1px solid rgba(139, 92, 246, 0.25); border-radius: 12px; padding: 11px 14px; margin-bottom: 16px; }
.pbl-linkbox code { font-size: 12px; color: var(--violet-txt); flex: 1; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: inherit; }
.pbl-qr-white { background: #fff; border-radius: 14px; padding: 10px; display: inline-block; margin-bottom: 16px; }
.pbl-qr-white svg, .pbl-qr-white img { display: block; width: 150px; height: 150px; image-rendering: pixelated; }
.pbl-share { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

/* QR modal (row QR action) */
/* The QR modal is now a native <dialog> reusing .confirm-dialog (top-layer, focus-trap, Esc,
   ::backdrop); only a tighter width for the QR square differs. */
.qr-dialog { width: min(340px, calc(100vw - 32px)); }

@media (prefers-reduced-motion: reduce) {
  .pbl-drawer, .pbl-scrim, .pbl-cond { transition: none; animation: none; }
}

/* ---- Filter bar on a phone (must follow the .fbar section above to win on equal
   specificity). The bar carried search + Filter + four date presets + Columns + the chips
   and wrapped onto four rows; filter-bar.js moves the presets into the popover, which at
   this width is a bottom sheet. */
@media (max-width: 760px) {
  /* One row: search + Filter + Columns. The date presets moved into the sheet
     (filter-bar.js), and the chips wrap underneath only when a filter is on. */
  .fbar { gap: 8px; margin-bottom: 14px; }
  .fbar .fsearch { order: 1; flex: 1 1 120px; min-width: 0; }
  .fbar .fpop-wrap { order: 2; flex: 0 0 auto; }
  /* `width: 100%` from the older @media below 1000px would give it a row of its own. */
  .fbar .fright { order: 3; flex: 0 0 auto; width: auto; margin-left: 0; }
  .fbar .fright:empty { display: none; }
  .fbar .fchips { order: 4; flex: 1 1 240px; display: flex; flex-wrap: wrap; gap: 8px; }
  /* Rendered on every page, empty until a filter is on — and an empty flex item still
     reserves its basis, which pushed Columns onto a second row. */
  .fbar .fchips:empty { display: none; }
  .fbar .clear-all { order: 5; flex: 0 0 auto; }

  /* Narrow phones (≤380px: an SE, a Galaxy A0x). Search + Filter + Columns on one row need
     about 360px; below that the row overflowed the viewport by ~50px instead of wrapping,
     because `flex: 1 1 120px` keeps the search on the line at any cost. Give it its own row
     and let the two buttons share the next one. */
  @media (max-width: 380px) {
    .fbar .fsearch { flex: 1 1 100%; }
    .fbar .fpop-wrap, .fbar .fright { flex: 1 1 auto; }
    .fbar .btn-cols, .fbar .fpop-btn { width: 100%; justify-content: center; }
  }

  /* The presets, once inside the sheet. */
  .fbar .pf-period { padding: 2px 2px 10px; border-bottom: 1px solid var(--line); margin-bottom: 6px; }
  .fbar .pf-period .seg { display: flex; width: 100%; }
  .fbar .pf-period .seg button { flex: 1; }
  .fbar .pf-period .daterange-slot { display: block; margin-top: 8px; }

  /* The "＋ Filter" popover becomes a bottom sheet: at the bottom of a phone screen a
     dropdown anchored under its button is both cramped and out of thumb reach. */
  .fbar .pop {
    position: fixed;
    inset: auto 0 0 0;
    z-index: 300; /* above the tab bar — it's a modal choice */
    min-width: 0;
    max-height: 72vh;
    overflow-y: auto;
    border-radius: 20px 20px 0 0;
    padding: 8px 12px calc(12px + env(safe-area-inset-bottom, 0px));
    animation: fsheet 0.22s cubic-bezier(0.2, 0.7, 0.2, 1);
  }
  /* The grab handle every bottom sheet has — it says "this slides away". */
  .fbar .pop::before {
    content: "";
    display: block;
    width: 38px;
    height: 4px;
    margin: 4px auto 10px;
    border-radius: 999px;
    background: var(--line-strong);
  }

  /* Touch floor: 44px (Apple HIG) / 48dp (Material). */
  .fbar .p-item { min-height: 46px; }
  .fbar .seg button { min-height: 40px; padding: 9px 14px; }
  .fbar .btn-filter { min-height: 40px; }
  .fbar .fchip { min-height: 34px; padding: 8px 10px 8px 14px; }
  .fbar .clear-all { min-height: 34px; display: inline-flex; align-items: center; }
  /* The Columns chooser: the 13px checkbox is the only hit area, so grow its row instead. */
  .col-item { min-height: 44px; }
  .col-item label { display: flex; align-items: center; min-height: 44px; flex: 1; }
}
@keyframes fsheet { from { transform: translateY(14px); opacity: 0; } to { transform: none; opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .fbar .pop { animation: none; } }

/* ============================================================================
   Verification wizards (client_detail.html — Add owner / Add bank account).
   Ported from the nextepay-verification mockup, scoped under .vwrap so the
   generic class names (.f, .step, .pane, .pv…) never leak into the rest of the
   app. Colours resolve through the app's own tokens, remapped here once. */
.vwrap {
  --vw-line: var(--line-strong);
  --vw-sep: var(--line);
  --vw-card: var(--surface);
  --vw-txt: var(--ink);
  --vw-txt2: var(--muted);
  --vw-violet: #8b5cf6;
  --vw-violet-txt: var(--violet-txt);
  --vw-green: var(--ok-txt);
  --vw-red: var(--err);
  --vw-grad: var(--grad-or);
  --vw-wash: rgba(139, 92, 246, 0.08);
}
.vwrap .wiz-inner {
  border: 1px solid rgba(139, 92, 246, 0.35);
  border-radius: 18px;
  background: var(--vw-card);
  padding: 20px 22px;
  position: relative;
}
.vwrap .wiz-top { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.vwrap .wiz-close {
  margin-left: auto; width: 32px; height: 32px; border-radius: 50%; display: grid;
  place-items: center; border: 1px solid var(--vw-line); background: none; color: var(--vw-txt2);
  cursor: pointer; flex: none; font-size: 12px;
}
.vwrap .wiz-close:hover { color: var(--vw-txt); border-color: var(--vw-txt2); }
.vwrap .steps { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.vwrap .step { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 600; color: var(--vw-txt2); }
.vwrap .step .bub {
  width: 27px; height: 27px; border-radius: 50%; display: grid; place-items: center; flex: none;
  border: 1.5px solid var(--vw-line); font-size: 11.5px; transition: all 0.3s;
}
.vwrap .step.cur { color: var(--vw-violet-txt); }
.vwrap .step.cur .bub { border-color: var(--vw-violet); color: var(--vw-violet-txt); }
.vwrap .step.done .bub { background: var(--vw-grad); border-color: transparent; color: #20180a; }
.vwrap .step-link { width: 26px; height: 1.5px; background: var(--vw-line); flex: none; transition: background 0.3s; }
.vwrap .step-link.done { background: var(--vw-grad); }
.vwrap .wiz-grid { display: grid; grid-template-columns: 1fr 290px; gap: 26px; }
.vwrap .pane { display: none; animation: vwPane 0.3s; }
.vwrap .pane.on { display: block; }
@keyframes vwPane { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* align-items:start so the two cells top-align regardless of one carrying a hint below. */
.vwrap .f-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; align-items: start; }
.vwrap .f { margin-bottom: 14px; min-width: 0; }
.vwrap .f label {
  display: flex; gap: 6px; align-items: baseline; font-size: 10.5px; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--vw-txt2); margin-bottom: 7px;
}
.vwrap .f label .opt { font-size: 9.5px; letter-spacing: 0.04em; opacity: 0.75; text-transform: none; font-weight: 500; }
.vwrap .f input {
  width: 100%; height: 42px; border: 1px solid var(--vw-line); border-radius: 12px;
  background: var(--vw-card); color: var(--vw-txt); padding: 0 14px; font-size: 13.5px;
  line-height: 40px; outline: none; transition: border-color 0.15s, box-shadow 0.15s;
}
/* Row labels: one line, fixed height, so every input in a row starts at the same Y. */
.vwrap .f-row .f > label { white-space: nowrap; height: 15px; margin-bottom: 7px; }
.vwrap .f input:focus { border-color: var(--vw-violet); box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.15); }
.vwrap .f input.ok { border-color: rgba(52, 211, 153, 0.55); }
.vwrap .f input.bad { border-color: rgba(225, 29, 72, 0.55); }
.vwrap .hint { font-size: 11.5px; color: var(--vw-txt2); margin-top: 6px; min-height: 17px; }
.vwrap .hint.ok { color: var(--vw-green); }
.vwrap .hint.bad { color: var(--vw-red); }
.vwrap .iban-input { letter-spacing: 0.06em; font-size: 15px !important; font-variant-numeric: tabular-nums; }
.vwrap .bank-chip {
  display: none; align-items: center; gap: 8px; margin-top: 10px; font-size: 12px; font-weight: 600;
  padding: 6px 13px; border-radius: 999px; background: rgba(139, 92, 246, 0.1);
  color: var(--vw-violet-txt); border: 1px solid rgba(139, 92, 246, 0.3);
}
.vwrap .bank-chip.on { display: inline-flex; }
.vwrap .bank-chip i { width: 6px; height: 6px; border-radius: 50%; background: var(--vw-violet); display: inline-block; }
.vwrap .pct-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 12px; align-items: center; }
.vwrap .pct-chip {
  padding: 9px 16px; border-radius: 999px; border: 1px solid var(--vw-line); background: none;
  color: var(--vw-txt); font-size: 12.5px; font-weight: 600; cursor: pointer; transition: all 0.15s;
}
.vwrap .pct-chip:hover { border-color: var(--vw-violet); }
.vwrap .pct-chip.sel { border-color: var(--vw-violet); background: rgba(139, 92, 246, 0.1); color: var(--vw-violet-txt); }
.vwrap .pct-free {
  width: 86px; text-align: right; border: 1px solid var(--vw-line); border-radius: 999px;
  background: var(--vw-card); color: var(--vw-txt); padding: 9px 14px; font-size: 12.5px;
  font-weight: 600; outline: none;
}
.vwrap .pct-free:focus { border-color: var(--vw-violet); }
.vwrap .alloc-bar { height: 9px; border-radius: 999px; background: var(--vw-sep); overflow: hidden; display: flex; margin-top: 4px; }
.vwrap .alloc-bar .others { background: var(--vw-line); height: 100%; transition: width 0.3s; }
.vwrap .alloc-bar .mine { background: linear-gradient(90deg, var(--vw-violet), #a78bfa); height: 100%; transition: width 0.3s; }
.vwrap .alloc-bar.over .mine { background: linear-gradient(90deg, #f43f5e, #fb7185); }
.vwrap .alloc-note { font-size: 11.5px; color: var(--vw-txt2); margin-top: 7px; }
.vwrap .alloc-note b { color: var(--vw-txt); font-weight: 600; }
.vwrap .alloc-note.bad { color: var(--vw-red); }
.vwrap .chk {
  display: flex; align-items: center; gap: 10px; border: 1px solid var(--vw-line); border-radius: 12px;
  padding: 12px 14px; font-size: 13px; cursor: pointer; user-select: none;
  transition: border-color 0.15s, background 0.15s;
}
.vwrap .chk:hover { border-color: rgba(139, 92, 246, 0.45); }
.vwrap .chk.sel { border-color: var(--vw-violet); background: rgba(139, 92, 246, 0.08); }
.vwrap .chk .box {
  width: 16px; height: 16px; border-radius: 5px; border: 1.5px solid var(--vw-line); display: grid;
  place-items: center; flex: none; font-size: 10px; color: #20180a; transition: all 0.15s;
}
.vwrap .chk.sel .box { background: var(--vw-grad); border-color: transparent; }
.vwrap .chk:not(.sel) .box { color: transparent; }
.vwrap .wiz-foot { display: flex; align-items: center; gap: 12px; margin-top: 6px; }
.vwrap .wiz-foot .btn-cta { margin-left: auto; }
.vwrap .btn-back { font-size: 12.5px; font-weight: 600; color: var(--vw-txt2); background: none; border: none; cursor: pointer; padding: 8px 4px; display: none; }
.vwrap .btn-back.on { display: inline-block; }
.vwrap .btn-back:hover { color: var(--vw-txt); }
.vwrap .kbd-hint { margin-left: auto; font-size: 11px; color: var(--vw-txt2); }
.vwrap .kbd { font-size: 10px; border: 1px solid var(--vw-line); border-radius: 5px; padding: 1px 6px; font-weight: 600; }
.vwrap .btn-cta {
  padding: 12px 26px; border-radius: 999px; background: var(--vw-grad); border: none; cursor: pointer;
  color: #20180a; font-size: 13.5px; font-weight: 600; box-shadow: 0 6px 18px rgba(255, 179, 0, 0.35);
  transition: transform 0.15s, box-shadow 0.15s, opacity 0.15s;
}
.vwrap .btn-cta:hover { transform: translateY(-2px); box-shadow: 0 9px 22px rgba(255, 179, 0, 0.4); }
.vwrap .btn-cta:disabled { opacity: 0.45; cursor: default; transform: none; box-shadow: none; }
.vwrap .pv { align-self: start; }
.vwrap .pv-label { font-size: 10.5px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--vw-txt2); margin-bottom: 9px; }
.vwrap .pv-card { border: 1px solid var(--vw-line); border-radius: 16px; padding: 18px; background: var(--vw-card); transition: border-color 0.3s; }
.vwrap .pv-card.alive { border-color: rgba(139, 92, 246, 0.4); }
.vwrap .pv-id { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.vwrap .pv-ava {
  width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center; flex: none;
  border: 1.5px dashed var(--vw-line); color: var(--vw-txt2); font-size: 13px; font-weight: 600; transition: all 0.3s;
}
.vwrap .pv-ava.on { background: var(--vw-grad); border: none; color: #20180a; }
.vwrap .pv-name { font-size: 14.5px; font-weight: 600; min-height: 20px; }
.vwrap .pv-name .ph, .vwrap .pv-row .ph { display: inline-block; height: 11px; border-radius: 999px; background: var(--vw-sep); vertical-align: middle; }
.vwrap .pv-sub { font-size: 11.5px; color: var(--vw-txt2); }
.vwrap .pv-row { display: flex; justify-content: space-between; gap: 10px; padding: 8px 0; border-top: 1px solid var(--vw-sep); font-size: 12.5px; }
.vwrap .pv-row .k { color: var(--vw-txt2); font-weight: 600; font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; padding-top: 1px; }
.vwrap .pv-row .v { font-weight: 500; text-align: right; min-width: 0; overflow-wrap: anywhere; }
.vwrap .pv-row .v.violet { color: var(--vw-violet-txt); font-weight: 600; }
.vwrap .pv-next { margin-top: 12px; font-size: 11.5px; color: var(--vw-txt2); background: var(--vw-wash); border: 1px solid rgba(139, 92, 246, 0.3); border-radius: 12px; padding: 10px 12px; }
.vwrap .pv-next b { color: var(--vw-violet-txt); }
.vwrap .wiz-note { font-size: 11.5px; color: var(--vw-txt2); background: var(--vw-wash); border: 1px solid rgba(139, 92, 246, 0.3); border-radius: 12px; padding: 10px 12px; margin-top: 4px; }
.vwrap .wiz-note b { color: var(--vw-violet-txt); }
.vwrap .link-quiet { font-size: 12px; color: var(--vw-txt2); font-weight: 600; background: none; border: none; cursor: pointer; padding: 6px 0; }
.vwrap .link-quiet:hover { color: var(--vw-violet-txt); }
@media (max-width: 1000px) { .vwrap .wiz-grid { grid-template-columns: 1fr; } .vwrap .pv { display: none; } }
@media (prefers-reduced-motion: reduce) { .vwrap .pane { animation: none; } }

/* ============ Command palette (Cmd/Ctrl-K) ============
   Global jump-to bar: a native <dialog> (top-layer, focus-trap, Esc). Items are role-gated in
   base.html. Themed through the app tokens so it reads in both the merchant (dark) and owner
   (light) shells. */
dialog.cmdk {
  width: min(560px, calc(100vw - 28px));
  max-height: 72vh;
  margin: 12vh auto auto;
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: 16px;
  background: var(--surface);
  color: var(--ink);
  box-shadow: var(--shadow-pop);
  overflow: hidden;
}
dialog.cmdk::backdrop { background: rgba(11, 19, 32, 0.5); backdrop-filter: blur(3px); }
.cmdk-head { display: flex; align-items: center; gap: 11px; padding: 15px 16px; border-bottom: 1px solid var(--line); }
.cmdk-ic { color: var(--muted); flex: none; }
.cmdk-input { flex: 1; min-width: 0; border: none; background: none; color: var(--ink); font: inherit; font-size: 15.5px; outline: none; }
.cmdk-input::placeholder { color: var(--muted); }
.cmdk-esc { font-family: var(--mono); font-size: 11px; color: var(--muted); border: 1px solid var(--line); border-radius: 6px; padding: 2px 7px; flex: none; }
.cmdk-list { list-style: none; margin: 0; padding: 7px; overflow-y: auto; max-height: calc(72vh - 116px); }
.cmdk-item { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 10px; color: var(--ink); text-decoration: none; }
.cmdk-lab { font-size: 14px; font-weight: 500; }
.cmdk-grp { margin-left: auto; font-size: 10.5px; letter-spacing: 0.05em; text-transform: uppercase; color: var(--muted); }
.cmdk-item.sel, .cmdk-item:hover { background: var(--accent-wash); }
.cmdk-item.sel { box-shadow: inset 2px 0 0 var(--accent-ink); }
.cmdk-none { padding: 22px 16px; text-align: center; color: var(--muted); font-size: 13px; }
.cmdk-foot { display: flex; gap: 6px; align-items: center; padding: 10px 16px; border-top: 1px solid var(--line); font-size: 11.5px; color: var(--muted); }
.cmdk-foot kbd { font-family: var(--mono); font-size: 10px; border: 1px solid var(--line); border-radius: 5px; padding: 1px 5px; color: var(--ink-soft); }
@media (prefers-reduced-motion: no-preference) {
  dialog.cmdk[open] { animation: cmdk-in 0.15s cubic-bezier(0.2, 0.7, 0.2, 1); }
  @keyframes cmdk-in { from { opacity: 0; transform: translateY(-8px); } }
}

/* ================= Merchant Verification tab (.mverif) =================
   The §10 read-only view (nextepay-verification-v2 mockup): status matrix rows in
   vignettes, derived counter + message, the "Open my onboarding" hand-off panel.
   Scoped under .mverif; console tokens, so light + dark come for free. */
.mverif { max-width: 720px; }
.mverif .mv-line { display: flex; align-items: baseline; gap: 10px; margin-bottom: 10px; }
.mverif .mv-line .lb { font-size: 11px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.mverif .mv-line .n { font-size: 12.5px; color: var(--muted); }
.mverif .mv-line .pct { margin-left: auto; font-size: 13px; font-weight: 600; background: var(--grad-or); -webkit-background-clip: text; background-clip: text; color: transparent; }
.mverif .bar { height: 4px; border-radius: 999px; background: var(--line); overflow: hidden; }
.mverif .bar i { display: block; height: 100%; border-radius: 999px; background: var(--grad-or); }
.mverif .veri-msg { font-size: 14.5px; margin-top: 18px; line-height: 1.65; max-width: 560px; }
.mverif .veri-msg .bad { font-weight: 600; color: var(--err-txt); }
.mverif .veri-msg .warn { font-weight: 600; color: var(--warn-txt); }
.mverif .veri-msg .okc { font-weight: 600; color: var(--ok-txt); }
.mverif .hand {
  display: flex; align-items: center; gap: 16px; margin-top: 20px;
  background: var(--accent-wash); border: 1px solid rgba(139, 92, 246, 0.25); border-radius: 16px;
  padding: 15px 18px;
}
.mverif .hand .hm { font-size: 12.5px; color: var(--muted); line-height: 1.6; min-width: 0; }
.mverif .hand .hm b { color: var(--ink); font-weight: 500; }
.mverif .hand .btn-cta {
  margin-left: auto; padding: 12px 22px; border-radius: 999px; background: var(--grad-or);
  color: #20180a; font-size: 13px; font-weight: 600; white-space: nowrap; flex: none;
  box-shadow: 0 5px 16px rgba(255, 179, 0, 0.3);
  transition: transform 0.15s, box-shadow 0.15s;
  display: inline-flex; align-items: center; gap: 8px; text-decoration: none;
}
.mverif .hand .btn-cta:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(255, 179, 0, 0.38); }
.mverif .sec { margin-top: 34px; }
.mverif .sec-head { margin-bottom: 12px; }
.mverif .sec-head .t { font-size: 11px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.mverif .vig {
  border: 1px solid var(--line-strong); background: var(--surface); border-radius: 18px;
  padding: 18px 22px;
}
.mverif .vig + .vig { margin-top: 12px; }
.mverif .vig-head { display: flex; align-items: center; gap: 14px; }
.mverif .vig-sq {
  width: 40px; height: 40px; border-radius: 12px; background: var(--canvas);
  border: 1px solid var(--line-strong); display: grid; place-items: center; flex: none;
  font-size: 12.5px; font-weight: 600; color: var(--accent-ink);
}
.mverif .vig-name { min-width: 0; }
.mverif .vig-name b { font-size: 15px; font-weight: 600; display: block; letter-spacing: -0.01em; }
.mverif .vig-name span { font-size: 12px; color: var(--muted); }
.mverif .doc { display: flex; align-items: center; gap: 12px; margin-top: 15px; padding-top: 14px; border-top: 1px solid var(--line); }
.mverif .doc-m { min-width: 0; flex: 1; }
.mverif .doc-m b { font-size: 13.5px; font-weight: 500; display: block; }
.mverif .doc-m span { font-size: 12px; color: var(--muted); line-height: 1.55; display: block; margin-top: 1px; }
.mverif .doc-end { display: flex; align-items: center; gap: 14px; flex: none; }
.mverif .st { display: inline-flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 500; white-space: nowrap; }
.mverif .st .dot, .mverif .legend .dot { width: 6px; height: 6px; border-radius: 50%; display: inline-block; flex: none; }
.mverif .st.ok { color: var(--ok-txt); }
.mverif .st.ok .dot, .mverif .d-ok { background: #34d399; }
.mverif .st.pend { color: var(--warn-txt); }
.mverif .st.pend .dot, .mverif .d-pend { background: var(--or2); box-shadow: 0 0 6px rgba(255, 179, 0, 0.5); }
.mverif .st.wait { color: var(--accent-ink); }
.mverif .st.wait .dot, .mverif .d-wait { background: var(--violet); }
/* Ours to fetch, not fetched yet. Its own tone because the four others each claim
   something untrue here: amber says the merchant owes it, violet says we received it,
   green says verified, red says rejected. Grey says the honest thing, which is that this
   one is on us and not done. */
.mverif .st.auto { color: var(--muted); }
.mverif .st.auto .dot, .mverif .d-auto { background: var(--muted); }
.mverif .st.rej { color: var(--err-txt); }
.mverif .st.rej .dot, .mverif .d-rej { background: #fb7185; box-shadow: 0 0 6px rgba(251, 113, 133, 0.5); }
.mverif .link-vio { font-size: 12px; color: var(--accent-ink); font-weight: 500; white-space: nowrap; text-decoration: none; }
.mverif .btn-sm-or {
  padding: 8px 16px; border-radius: 999px; background: var(--grad-or); color: #20180a;
  font-size: 12px; font-weight: 600; box-shadow: 0 3px 10px rgba(255, 179, 0, 0.3); white-space: nowrap;
  transition: transform 0.15s; text-decoration: none; display: inline-block;
}
.mverif .btn-sm-or:hover { transform: translateY(-1px); }
.mverif .rej-panel {
  margin-top: 12px; font-size: 12.5px; line-height: 1.6; color: var(--muted);
  background: rgba(251, 113, 133, 0.07); border: 1px solid rgba(251, 113, 133, 0.3); border-radius: 12px;
  padding: 12px 15px;
}
.mverif .rej-panel b { color: var(--err-txt); font-weight: 600; }
.mverif .proof { display: flex; align-items: baseline; gap: 8px; font-size: 11.5px; color: var(--muted); margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.mverif .proof svg { flex: none; opacity: 0.6; position: relative; top: 1px; }
.mverif .proof b { font-weight: 500; color: var(--ink); }
.mverif .hold-note { font-size: 12px; color: var(--muted); margin-top: 12px; }
.mverif .legend { display: flex; gap: 20px; flex-wrap: wrap; margin-top: 36px; padding-top: 16px; border-top: 1px solid var(--line); }
.mverif .legend span { font-size: 11.5px; color: var(--muted); display: inline-flex; align-items: center; gap: 7px; }
@media (max-width: 700px) {
  .mverif .doc { flex-wrap: wrap; }
  .mverif .doc-end { width: 100%; justify-content: flex-end; }
  .mverif .hand { flex-direction: column; align-items: flex-start; }
  .mverif .hand .btn-cta { margin-left: 0; }
}

/* ================= Account-state banners (merchant shell) =================
   Suspension: every page, loud. Test mode: once per money surface — the facts a
   header badge alone was too quiet to carry. */
.statebar {
  border-radius: 12px; padding: 11px 16px; margin-bottom: 16px;
  font-size: 13px; line-height: 1.55;
}
.statebar b { font-weight: 600; }
.statebar a { color: var(--accent-ink); font-weight: 500; margin-left: 6px; }
.statebar.test {
  background: var(--warn-bg); border: 1px solid rgba(255, 179, 0, 0.35);
  color: var(--warn-txt);
}
.statebar.suspended {
  background: var(--err-wash); border: 1px solid rgba(229, 72, 77, 0.4);
  color: var(--err);
}

/* Narrow phones. Two things ran off a 320px screen here: the tab bar (four labels + 24px
   gaps) and the step's action button, which sat on the same line as a step's text inside a
   card that already spends 56px on padding. The bar scrolls like the top nav does; the
   button drops under the step it belongs to. */
@media (max-width: 380px) {
  .pbl-tabs { overflow-x: auto; scrollbar-width: none; gap: 18px; }
  .pbl-tabs::-webkit-scrollbar { display: none; }
  .pbl-tabs button { white-space: nowrap; }
  .wcx .card { padding-left: 18px; padding-right: 18px; }
  .wcx .step { flex-wrap: wrap; }
  .wcx .step .act { margin-left: 45px; align-self: flex-start; }
}

/* ============================================================
   Web checkout product page — everything scoped under .wcx.

   This arrived as a mockup port and brought its own complete palette: --wx-card, --wx-txt,
   --wx-violet-txt, a second set of every colour the application already had, with slightly
   different values. Two palettes for one product means every colour fix has to be made
   twice, and the second one gets forgotten — which is why the page that carried the only
   real contrast failures in the product was this one.

   The --wx-* names survive (99 call sites use them) but they are ALIASES now: one palette,
   one place to change a colour, and the light/dark switch is the application's own.
   ============================================================ */
.wcx {
  --wx-card: var(--surface); --wx-card-line: var(--line-strong); --wx-row-line: var(--line);
  --wx-txt: var(--ink); --wx-txt2: var(--muted);
  --wx-violet: var(--violet); --wx-violet-txt: var(--violet-txt);
  --wx-green-txt: var(--ok-txt); --wx-red-txt: var(--err-txt);
  --wx-input: var(--surface); --wx-code: var(--nuit); --wx-pop: var(--surface);
  --wx-shadow: var(--shadow-sm, 0 4px 18px rgba(15, 23, 42, 0.05));
  --wx-or1: var(--or1); --wx-or2: var(--or2);
  --wx-grad-or: var(--grad-or);
  --wx-aurora: linear-gradient(90deg, var(--or1), #fb7185, var(--violet), #22d3ee);
  position: relative;
}
/* The two the dark theme genuinely wants different: a card there is a translucent lift on
   the nuit background rather than a filled surface, and the code block goes one step deeper
   than the page. Everything else follows the palette. */
[data-theme="dark"] .wcx {
  --wx-card: rgba(255, 255, 255, 0.035);
  --wx-card-line: rgba(255, 255, 255, 0.08);
  --wx-row-line: rgba(255, 255, 255, 0.05);
  --wx-input: rgba(255, 255, 255, 0.045);
  --wx-code: #0a101c;
  --wx-shadow: none;
}

/* header row: title left, site picker right */
.wcx .page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap; margin-bottom: 10px; }
.wcx .site-picker { display: flex; align-items: center; gap: 10px; }
.wcx .site-picker > label { font-size: 10.5px; font-weight: 600; letter-spacing: 0.1em; color: var(--wx-txt2); }

/* custom dropdown (never a native select) */
.wcx .dd { position: relative; }
.wcx .dd-btn { display: inline-flex; align-items: center; gap: 9px; font-family: inherit; font-size: 13px; font-weight: 600; color: var(--wx-txt); background: var(--wx-card); border: 1px solid var(--wx-card-line); border-radius: 999px; padding: 9px 16px; cursor: pointer; transition: border-color 0.15s; }
.wcx .dd-btn:hover { border-color: var(--wx-violet); }
.wcx .dd .chev { font-size: 10px; color: var(--wx-violet-txt); transition: transform 0.25s; display: inline-block; }
.wcx .dd.open .chev { transform: rotate(180deg); }
.wcx .dd-menu { position: absolute; top: calc(100% + 8px); left: 0; min-width: 210px; z-index: 150; background: var(--wx-pop); border: 1px solid var(--wx-card-line); border-radius: 16px; padding: 6px; box-shadow: 0 18px 44px rgba(11, 19, 32, 0.35); opacity: 0; transform: translateY(-6px) scale(0.97); pointer-events: none; transition: opacity 0.2s, transform 0.2s cubic-bezier(0.2, 0.7, 0.2, 1); }
.wcx .dd.open .dd-menu { opacity: 1; transform: none; pointer-events: auto; }
.wcx .dd-menu.right { left: auto; right: 0; }
.wcx .dd-it { display: flex; align-items: center; gap: 10px; font-size: 13px; font-weight: 500; color: var(--wx-txt); padding: 9px 12px; border-radius: 10px; cursor: pointer; transition: background 0.15s; white-space: nowrap; }
.wcx .dd-it:hover { background: rgba(139, 92, 246, 0.09); }
.wcx .dd-it .tick { margin-left: auto; color: var(--wx-violet-txt); font-size: 12px; }

/* modal + scrim */
.wcx-scrim { position: fixed; inset: 0; background: rgba(11, 19, 32, 0.55); backdrop-filter: blur(3px); z-index: 280; opacity: 0; pointer-events: none; transition: opacity 0.3s; }
.wcx-scrim.on { opacity: 1; pointer-events: auto; }
.wcx-modal { position: fixed; top: 50%; left: 50%; width: min(430px, calc(100vw - 40px)); z-index: 290; background: var(--wx-pop, #fff); border: 1px solid var(--wx-card-line, #e7ecf3); border-radius: 20px; padding: 26px; box-shadow: 0 28px 70px rgba(11, 19, 32, 0.45); opacity: 0; transform: translate(-50%, -44%) scale(0.97); pointer-events: none; transition: opacity 0.3s, transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1); }
.wcx-modal.on { opacity: 1; transform: translate(-50%, -50%) scale(1); pointer-events: auto; }
.wcx-modal .modal-p { font-size: 12.5px; color: var(--wx-txt2, #64748b); line-height: 1.6; margin: 8px 0 18px; }
.wcx-modal .modal-foot { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }

/* buttons */
.wcx .btn-or, .wcx-modal .btn-or { display: inline-flex; align-items: center; gap: 8px; background: linear-gradient(135deg, #ffd60a, #ffb300); color: #20180a; font-family: inherit; font-size: 13.5px; font-weight: 600; border: none; border-radius: 999px; padding: 11px 22px; cursor: pointer; box-shadow: 0 8px 22px rgba(255, 179, 0, 0.35); transition: transform 0.15s, box-shadow 0.15s; text-decoration: none; }
.wcx .btn-or:hover, .wcx-modal .btn-or:hover { transform: translateY(-2px); box-shadow: 0 12px 26px rgba(255, 179, 0, 0.42); }
.wcx .btn-ghost, .wcx-modal .btn-ghost { display: inline-flex; align-items: center; gap: 7px; background: transparent; color: var(--wx-txt, #0f172a); font-family: inherit; font-size: 13px; font-weight: 600; border: 1px solid var(--wx-card-line, #e7ecf3); border-radius: 999px; padding: 9px 18px; cursor: pointer; transition: border-color 0.15s, background 0.15s; text-decoration: none; }
.wcx .btn-ghost:hover, .wcx-modal .btn-ghost:hover { border-color: var(--wx-violet, #8b5cf6); background: rgba(139, 92, 246, 0.07); }
.wcx .btn-sm, .wcx-modal .btn-sm { font-size: 12px; padding: 7px 14px; }
.wcx .btn-dashed { border-style: dashed; }
.wcx .btn-danger { background: rgba(225, 29, 72, 0.06); color: var(--wx-red-txt); border: none; font-family: inherit; font-size: 12px; font-weight: 600; border-radius: 999px; padding: 7px 14px; cursor: pointer; transition: background 0.15s; }
.wcx .btn-danger:hover { background: rgba(225, 29, 72, 0.12); }
.wcx .btn-or[disabled], .wcx .btn-ghost[disabled], .wcx-modal .btn-or[disabled] { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: none; }
.wcx .link-v { color: var(--wx-violet-txt); font-weight: 600; text-decoration: none; font-size: 13px; cursor: pointer; background: none; border: none; font-family: inherit; padding: 0; }
.wcx .link-v:hover { text-decoration: underline; }

/* cards */
.wcx .card { background: var(--wx-card); border: 1px solid var(--wx-card-line); border-radius: 22px; padding: 24px 28px; box-shadow: var(--wx-shadow); margin-bottom: 22px; position: relative; }
.wcx .card-head { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; flex-wrap: wrap; }
.wcx .card-label { font-size: 11px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--wx-txt2); }
.wcx .card-hint { font-size: 12.5px; color: var(--wx-txt2); font-weight: 400; }
.wcx .card-head .right { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.wcx .halo::after { content: ''; position: absolute; inset: -1px; border-radius: 23px; padding: 1.5px; background: linear-gradient(135deg, #ffd60a, #ffb300); opacity: 0.5; pointer-events: none; -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; }
.wcx .grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; align-items: stretch; }
.wcx .grid2 .card { margin-bottom: 0; display: flex; flex-direction: column; }
.wcx .card-foot { display: flex; justify-content: flex-end; margin-top: auto; padding-top: 18px; }
@media (max-width: 960px) { .wcx .grid2 { grid-template-columns: 1fr; } }

/* stepper */
.wcx .prog-wrap { display: flex; align-items: center; gap: 12px; min-width: 210px; }
.wcx .prog { flex: 1; height: 7px; border-radius: 999px; background: var(--wx-row-line); overflow: hidden; }
.wcx .prog i { display: block; height: 100%; border-radius: 999px; background: linear-gradient(135deg, #ffd60a, #ffb300); box-shadow: 0 0 12px rgba(255, 179, 0, 0.5); transition: width 0.8s cubic-bezier(0.2, 0.7, 0.2, 1); }
.wcx .prog-pct { font-size: 13px; font-weight: 600; background: linear-gradient(135deg, #ffd60a, #ffb300); -webkit-background-clip: text; background-clip: text; color: transparent; font-variant-numeric: tabular-nums; }
.wcx .steps { display: flex; flex-direction: column; }
.wcx .step { display: flex; align-items: flex-start; gap: 16px; padding: 14px 0; border-top: 1px solid var(--wx-row-line); }
.wcx .step:first-child { border-top: none; }
.wcx .step-dot { width: 29px; height: 29px; border-radius: 50%; flex-shrink: 0; display: grid; place-items: center; font-size: 13px; font-weight: 600; margin-top: 1px; }
.wcx .step.done .step-dot { background: linear-gradient(135deg, #ffd60a, #ffb300); color: #20180a; }
.wcx .step.now .step-dot { border: 1.5px solid var(--wx-violet); color: var(--wx-violet-txt); }
.wcx .step.todo .step-dot { border: 1.5px solid var(--wx-card-line); color: var(--wx-txt2); }
.wcx .step-body { flex: 1; }
.wcx .step-t { font-size: 14px; font-weight: 600; color: var(--wx-txt); }
.wcx .step.todo .step-t { color: var(--wx-txt2); font-weight: 500; }
.wcx .step.now .step-t { color: var(--wx-violet-txt); }
.wcx .step-d { font-size: 12.5px; color: var(--wx-txt2); margin-top: 3px; max-width: 520px; }
.wcx .step .act { margin-left: auto; align-self: center; flex-shrink: 0; }

/* KPIs */
.wcx .kpis { display: grid; grid-template-columns: repeat(4, 1fr); }
.wcx .kpi { padding: 6px 26px 6px 0; border-right: 1px solid var(--wx-row-line); }
.wcx .kpi + .kpi { padding-left: 26px; }
.wcx .kpi:last-child { border-right: none; padding-right: 0; }
.wcx .kpi-l { font-size: 10.5px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--wx-txt2); }
.wcx .kpi-v { font-size: 26px; font-weight: 600; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; margin: 8px 0 4px; color: var(--wx-txt); }
.wcx .kpi-v.hero { background: linear-gradient(90deg, var(--wx-violet-txt), var(--wx-violet)); -webkit-background-clip: text; background-clip: text; color: transparent; }
.wcx .kpi-s { font-size: 11.5px; color: var(--wx-txt2); }
@media (max-width: 760px) { .wcx .kpis { grid-template-columns: 1fr 1fr; row-gap: 18px; }
  .wcx .kpi:nth-child(2) { border-right: none; } .wcx .kpi:nth-child(3) { border-right: 1px solid var(--wx-row-line); padding-left: 0; }
  .wcx .kpi:nth-child(4) { padding-left: 26px; } }

/* tables */
.wcx table { width: 100%; border-collapse: collapse; }
.wcx th { font-size: 10.5px; font-weight: 600; letter-spacing: 0.09em; text-transform: uppercase; color: var(--wx-txt2); text-align: left; padding: 10px 16px; border-bottom: 1px solid var(--wx-card-line); }
.wcx td { font-size: 13px; font-weight: 500; padding: 13px 16px; border-bottom: 1px solid var(--wx-row-line); font-variant-numeric: tabular-nums; color: var(--wx-txt); }
.wcx tr:last-child td { border-bottom: none; }
.wcx tbody tr { transition: background 0.15s; }
.wcx tbody tr:hover { background: rgba(139, 92, 246, 0.04); }
.wcx td.num, .wcx th.num { text-align: right; }
.wcx td .cur { font-size: 10.5px; color: var(--wx-txt2); margin-left: 4px; }
.wcx .mono { font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 12px; }
.wcx .id-dim { color: var(--wx-txt2); }

/* status chips */
.wcx .st { display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; font-weight: 600; padding: 4px 11px; border-radius: 999px; }
.wcx .st i { width: 6px; height: 6px; border-radius: 50%; }
.wcx .st.green { color: var(--wx-green-txt); background: rgba(16, 185, 129, 0.09); border: 1px solid rgba(16, 185, 129, 0.28); }
.wcx .st.green i { background: #10b981; }
.wcx .st.red { color: var(--wx-red-txt); background: rgba(225, 29, 72, 0.08); border: 1px solid rgba(225, 29, 72, 0.26); }
.wcx .st.red i { background: #f43f5e; }
.wcx .st.violet { color: var(--wx-violet-txt); background: rgba(139, 92, 246, 0.10); border: 1px solid rgba(139, 92, 246, 0.3); }
.wcx .st.violet i { background: var(--wx-violet); }
.wcx .st.amber { color: #92600a; background: rgba(255, 179, 0, 0.09); border: 1px solid rgba(255, 179, 0, 0.3); }
[data-theme="dark"] .wcx .st.amber { color: #f5c044; }
.wcx .st.amber i { background: #ffb300; }
/* A checkout nobody finished: past, not a problem to act on, so no colour. */
.wcx .st.neutral { color: var(--wx-txt2); background: transparent; border: 1px solid var(--line); }
.wcx .st.neutral i { background: #94a3b8; }

/* empty states */
.wcx .empty { border: 1.5px dashed var(--wx-card-line); border-radius: 16px; padding: 30px; text-align: center; font-size: 13px; color: var(--wx-txt2); line-height: 1.6; }
.wcx .empty b { color: var(--wx-txt); font-weight: 600; display: block; margin-bottom: 2px; }

/* forms */
.wcx .field { margin-bottom: 16px; }
.wcx .field > label { display: block; font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--wx-txt2); margin-bottom: 7px; }
.wcx .field input[type="text"], .wcx .field input[type="url"], .wcx-modal .field input[type="text"] { width: 100%; font-family: inherit; font-size: 13.5px; color: var(--wx-txt, #0f172a); background: var(--wx-input, #fff); border: 1px solid var(--wx-card-line, #e7ecf3); border-radius: 12px; padding: 11px 14px; outline: none; transition: border-color 0.15s, box-shadow 0.15s; font-variant-numeric: tabular-nums; }
.wcx .field input:focus, .wcx-modal .field input:focus { border-color: var(--wx-violet, #8b5cf6); box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.18); }
.wcx .field input::placeholder, .wcx-modal .field input::placeholder { color: var(--wx-txt2, #64748b); opacity: 0.6; }
.wcx .field .help, .wcx-modal .field .help { font-size: 11.5px; color: var(--wx-txt2, #64748b); margin-top: 6px; }
.wcx-modal .field > label { display: block; font-size: 11px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--wx-txt2, #64748b); margin-bottom: 7px; }
.wcx-modal .card-label { font-size: 11px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--wx-txt2, #64748b); }
.wcx .f-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 700px) { .wcx .f-row { grid-template-columns: 1fr; } }
.wcx .seg { display: inline-flex; background: var(--wx-input); border: 1px solid var(--wx-card-line); border-radius: 999px; padding: 3px; gap: 2px; }
.wcx .seg button { font-family: inherit; font-size: 12.5px; font-weight: 600; color: var(--wx-txt2); background: none; border: none; border-radius: 999px; padding: 7px 16px; cursor: pointer; transition: all 0.18s; }
.wcx .seg button.on { background: rgba(139, 92, 246, 0.14); color: var(--wx-violet-txt); }
.wcx .dropzone { border: 1.5px dashed var(--wx-card-line); border-radius: 14px; padding: 18px; display: flex; align-items: center; gap: 14px; cursor: pointer; transition: border-color 0.15s, background 0.15s; }
.wcx .dropzone:hover { border-color: var(--wx-violet); background: rgba(139, 92, 246, 0.05); }
.wcx .dz-badge { width: 46px; height: 46px; border-radius: 12px; background: rgba(139, 92, 246, 0.12); display: grid; place-items: center; font-size: 18px; flex-shrink: 0; overflow: hidden; }
.wcx .dz-badge img { width: 100%; height: 100%; object-fit: contain; }
.wcx .dropzone p { font-size: 12.5px; color: var(--wx-txt2); line-height: 1.5; margin: 0; }
.wcx .dropzone p b { color: var(--wx-violet-txt); font-weight: 600; }

/* Appearance mini-preview */
.wcx .mini-prev { border-radius: 16px; overflow: hidden; border: 1px solid var(--wx-card-line); margin-top: 18px; }
.wcx .mini-prev .mp-top { height: 3px; background: linear-gradient(90deg, #ffd60a, #fb7185, #8b5cf6, #22d3ee); }
.wcx .mini-prev .mp-body { background: #0b1320; padding: 20px 22px; display: flex; align-items: center; gap: 13px; }
.wcx .mp-logo { width: 38px; height: 38px; border-radius: 10px; background: rgba(139, 92, 246, 0.2); display: grid; place-items: center; font-size: 13px; font-weight: 600; color: #c4b5fd; overflow: hidden; flex-shrink: 0; }
.wcx .mp-logo img { width: 100%; height: 100%; object-fit: contain; background: #fff; }
.wcx .mp-name { font-size: 14.5px; font-weight: 600; color: #e7ecf4; }
.wcx .mp-sub { font-size: 10.5px; color: #9aa6b8; margin-top: 2px; }
.wcx .mp-amt { margin-left: auto; font-size: 17px; font-weight: 600; font-variant-numeric: tabular-nums; background: linear-gradient(90deg, #fff, #c4b5fd); -webkit-background-clip: text; background-clip: text; color: transparent; }
.wcx .mini-prev .mp-note { font-size: 10.5px; color: var(--wx-txt2); padding: 8px 12px; text-align: center; border-top: 1px solid var(--wx-card-line); }

/* secret reveal (inside the API keys card) */
.wcx .secret-box { background: rgba(255, 179, 0, 0.07); border: 1px solid rgba(255, 179, 0, 0.35); border-radius: 14px; padding: 14px 16px; margin-bottom: 18px; }
.wcx .secret-box .s-t { font-size: 12px; font-weight: 600; color: #92600a; margin-bottom: 9px; display: flex; align-items: center; gap: 8px; }
[data-theme="dark"] .wcx .secret-box .s-t { color: #f5c044; }
.wcx .secret-row { display: flex; align-items: center; gap: 10px; }
.wcx .secret-row code { flex: 1; font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 12.5px; background: var(--wx-input); border: 1px solid var(--wx-card-line); border-radius: 10px; padding: 9px 12px; overflow-x: auto; white-space: nowrap; color: var(--wx-txt); }
.wcx .copy-btn2 { font-family: inherit; font-size: 11px; font-weight: 600; color: var(--wx-violet-txt); background: rgba(139, 92, 246, 0.10); border: 1px solid rgba(139, 92, 246, 0.3); border-radius: 999px; padding: 7px 14px; cursor: pointer; transition: background 0.15s; flex-shrink: 0; }
.wcx .copy-btn2:hover { background: rgba(139, 92, 246, 0.18); }
.wcx .copy-btn2.ok { color: var(--wx-green-txt); background: rgba(16, 185, 129, 0.1); border-color: rgba(16, 185, 129, 0.3); }
.wcx .s-x { margin-left: auto; background: none; border: none; color: var(--wx-txt2); cursor: pointer; font-size: 14px; font-family: inherit; }

/* API key rows */
.wcx .key-row { display: flex; align-items: center; gap: 16px; padding: 18px 2px; border-top: 1px solid var(--wx-row-line); flex-wrap: wrap; }
.wcx .key-row:first-child { border-top: none; }
.wcx .key-main { flex: 1; min-width: 0; }
.wcx .key-code { display: flex; align-items: center; gap: 12px; font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 13.5px; font-weight: 500; color: var(--wx-txt); letter-spacing: 0.01em; }
.wcx .key-meta { font-size: 11.5px; color: var(--wx-txt2); margin-top: 6px; font-variant-numeric: tabular-nums; }

/* webhook rows + deliveries fold */
.wcx .wh-row { display: flex; align-items: center; gap: 12px; padding: 13px 0; border-top: 1px solid var(--wx-row-line); flex-wrap: wrap; }
.wcx .wh-row:first-of-type { border-top: none; }
.wcx .wh-url { font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 12.5px; color: var(--wx-txt); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 640px; }
.wcx .wh-meta { font-size: 11.5px; color: var(--wx-txt2); font-variant-numeric: tabular-nums; }
.wcx .wh-acts { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.wcx .fold-btn { display: inline-flex; align-items: center; gap: 6px; background: none; border: none; font-family: inherit; font-size: 12px; font-weight: 600; color: var(--wx-violet-txt); cursor: pointer; padding: 4px 0; }
.wcx .fold-btn .chev { transition: transform 0.3s; display: inline-block; font-size: 10px; }
.wcx .fold-btn.open .chev { transform: rotate(180deg); }
.wcx .fold { max-height: 0; opacity: 0; overflow: hidden; transition: max-height 0.45s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.45s; }
.wcx .fold.open { max-height: 400px; opacity: 1; }

/* simulator */
.wcx .sim-grid { display: grid; grid-template-columns: minmax(300px, 420px) 1fr; gap: 28px; align-items: start; }
@media (max-width: 900px) { .wcx .sim-grid { grid-template-columns: 1fr; } }
.wcx .sim-lock { position: absolute; inset: 0; border-radius: 22px; backdrop-filter: blur(2px); background: rgba(247, 249, 252, 0.6); display: grid; place-items: center; z-index: 5; }
[data-theme="dark"] .wcx .sim-lock { background: rgba(11, 19, 32, 0.4); }
.wcx .sim-lock .inner { text-align: center; font-size: 13px; color: var(--wx-txt); background: var(--wx-pop); border: 1px solid var(--wx-card-line); border-radius: 16px; padding: 20px 26px; box-shadow: 0 18px 44px rgba(11, 19, 32, 0.3); }
.wcx .sim-lock .inner b { display: block; margin-bottom: 4px; }
.wcx .item-row { display: grid; grid-template-columns: 1fr 84px 110px 30px; gap: 10px; margin-bottom: 10px; align-items: center; }
.wcx .item-row input { font-family: inherit; font-size: 12.5px; color: var(--wx-txt); background: var(--wx-input); border: 1px solid var(--wx-card-line); border-radius: 10px; padding: 8px 11px; outline: none; font-variant-numeric: tabular-nums; }
.wcx .item-row input:focus { border-color: var(--wx-violet); }
.wcx .item-x { background: none; border: none; color: var(--wx-txt2); cursor: pointer; font-size: 14px; }
.wcx .item-x:hover { color: var(--wx-red-txt); }

/* syntax tint, shared by the simulator window and the docs' code blocks */
/* 5.2:1 on the #0a101c block. At #5b6b84 a comment read 3.5:1 — and comments are
   where the documentation actually explains itself. */
.code .cm, .codewin .cm { color: #7787a3; }
.code .ck, .codewin .ck { color: #ffd60a; }
.code .cs, .codewin .cs { color: #a5b4fc; }

/* toast */
.wcx-toast { position: fixed; bottom: 26px; left: 50%; transform: translate(-50%, 20px); opacity: 0; background: var(--surface); color: var(--ink); border: 1px solid var(--line); border-radius: 999px; padding: 11px 22px; font-size: 13px; font-weight: 500; box-shadow: 0 18px 44px rgba(11, 19, 32, 0.35); pointer-events: none; transition: all 0.35s cubic-bezier(0.2, 0.7, 0.2, 1); z-index: 300; }
.wcx-toast.on { opacity: 1; transform: translate(-50%, 0); }

/* dirty save (ghost -> gold once modified) */
.wcx .save-btn.gold { background: linear-gradient(135deg, #ffd60a, #ffb300); color: #20180a; border-color: transparent; box-shadow: 0 8px 22px rgba(255, 179, 0, 0.35); }

@media (prefers-reduced-motion: reduce) {
  .wcx .dd-menu, .wcx-modal, .wcx-scrim, .wcx .fold, .wcx .prog i, .wcx-toast { transition-duration: 0.001s; }
}

/* --- Web checkout simulator delta: fields row / single code window / footer --- */
.wcx #wcx-sim, .wcx #subs-sim { padding: 30px 34px; }
.wcx #wcx-sim .card-head, .wcx #subs-sim .card-head { margin-bottom: 24px; }
.wcx .sim-fields { display: flex; gap: 24px; align-items: flex-start; flex-wrap: wrap; }
.wcx .sim-fields .field { margin-bottom: 10px; }
.wcx .sim-fields .field > label { margin-bottom: 9px; }
.wcx .sim-fields input { height: 42px; }
.wcx .sim-fields .seg { height: 42px; border-radius: 12px; padding: 4px; align-items: center; }
.wcx .sim-fields .seg button { border-radius: 9px; padding: 8px 16px; height: 34px; }
.wcx #simAmt { width: 180px; }
.wcx #simRef { width: 280px; }
.wcx .codewin { margin-top: 26px; border-radius: 18px; overflow: hidden; border: 1px solid rgba(255, 255, 255, 0.08); background: var(--wx-code); }
.wcx .cw-bar { display: flex; align-items: center; gap: 18px; padding: 13px 18px; border-bottom: 1px solid rgba(255, 255, 255, 0.07); }
.wcx .cw-dots { display: flex; gap: 6px; }
.wcx .cw-dots i { width: 9px; height: 9px; border-radius: 50%; background: rgba(255, 255, 255, 0.13); }
.wcx .cw-tabs { display: flex; gap: 4px; }
.wcx .cw-tabs button { font-family: inherit; font-size: 12px; font-weight: 600; color: #8b98ac; background: none; border: none; border-radius: 8px; padding: 7px 15px; cursor: pointer; transition: all 0.15s; }
.wcx .cw-tabs button:hover { color: #d6e1f0; }
.wcx .cw-tabs button.on { background: rgba(139, 92, 246, 0.18); color: #c4b5fd; }
.wcx .cw-bar .copy-btn2 { margin-left: auto; }
.wcx .codewin .code { background: transparent; border: none; border-radius: 0; padding: 22px 24px; font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 12px; line-height: 1.85; color: #d6e1f0; overflow-x: auto; position: relative; white-space: pre; }
.wcx .cw-resp { border-top: 1px solid rgba(255, 255, 255, 0.07); }
.wcx .cw-lab { font-size: 10px; font-weight: 600; letter-spacing: 0.13em; text-transform: uppercase; color: #5b6b84; padding: 18px 24px 0; }
.wcx .cw-resp .code { padding-top: 10px; }
.wcx .sim-foot { display: flex; align-items: center; gap: 24px; margin-top: 26px; }
.wcx .sim-foot p { flex: 1; font-size: 12px; color: var(--wx-txt2); line-height: 1.6; max-width: 680px; margin: 0; }
.wcx .sim-foot .btn-or { flex-shrink: 0; }

/* --- Subscriptions cockpit additions (same .wcx system) --- */
.wcx .field textarea, .wcx-modal .field textarea, .wcx .field input[type="email"], .wcx-modal .field input[type="email"], .wcx .field input[type="date"], .wcx-modal .field input[type="date"] { width: 100%; font-family: inherit; font-size: 13.5px; color: var(--wx-txt, #0f172a); background: var(--wx-input, #fff); border: 1px solid var(--wx-card-line, #e7ecf3); border-radius: 12px; padding: 11px 14px; outline: none; transition: border-color 0.15s, box-shadow 0.15s; resize: vertical; }
.wcx .field textarea:focus, .wcx-modal .field textarea:focus { border-color: var(--wx-violet, #8b5cf6); box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.18); }
/* A shareable link in a box: the setup / signup URL + its copy pill. */
.wcx .linkline { display: flex; align-items: center; gap: 10px; margin-top: 14px; padding: 11px 14px; border: 1px solid var(--wx-card-line, #e7ecf3); border-radius: 12px; background: var(--wx-input, #fff); }
.wcx .linkline code { flex: 1; min-width: 0; font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 12px; color: var(--wx-violet-txt); overflow-wrap: anywhere; }
/* Inline copy pill inside a table cell (a row's setup / signup link). */
.wcx td .copy-btn2 { padding: 3px 10px; font-size: 10.5px; margin-left: 6px; }
.wcx .sub-link { font-size: 11.5px; color: var(--wx-txt2); font-family: ui-monospace, 'SF Mono', Menlo, monospace; overflow-wrap: anywhere; }
/* Per-plan integration panel (Plans tab): the three ways to put a plan on a site. */
.wcx .int-row td { background: var(--wx-input, #fbfcfe); padding: 0; }
[data-theme="dark"] .wcx .int-row td { background: rgba(255, 255, 255, 0.02); }
.wcx .int-panel { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: 26px; padding: 22px 24px 26px; }
.wcx .int-col { min-width: 0; }
.wcx .int-col .field { margin-bottom: 10px; }
.wcx .int-col .codewin { margin-top: 12px; }
.wcx .int-col .code { font-size: 11.5px; padding: 16px 18px; }
.wcx .field select { width: 100%; font-family: inherit; font-size: 13.5px; color: var(--wx-txt, #0f172a); background: var(--wx-input, #fff); border: 1px solid var(--wx-card-line, #e7ecf3); border-radius: 12px; padding: 11px 14px; outline: none; }
.wcx .field select:focus { border-color: var(--wx-violet, #8b5cf6); box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.18); }
.wcx .seg button:disabled { opacity: .45; cursor: not-allowed; }
/* Docs callout: a pointer from the reference back into the console (where the ids live). */
.apidocs .callout { border: 1px solid var(--wx-card-line, #e7ecf3); border-left: 3px solid var(--wx-violet, #8b5cf6); border-radius: 12px; background: rgba(139, 92, 246, 0.05); padding: 14px 18px; margin: 18px 0; }
.apidocs .callout .link-v { font-size: inherit; }


/* ============ Settings hub (templates/settings/, web/settings_nav.py) ============
   Local nav on the left, the page on the right. Both themes read from the shared
   tokens, so only --surface/--line/--muted change between them: iso-structure, no
   dark-only rules below except where a wash needs more weight to stay visible. */
.set-wrap { display: grid; grid-template-columns: 246px 1fr; gap: 26px; align-items: start; }

/* --- the local navigation column --- */
.set-nav { position: sticky; top: 96px; display: flex; flex-direction: column; gap: 3px; }
.set-search { position: relative; display: flex; align-items: center; margin-bottom: 12px; }
.set-search svg { position: absolute; left: 11px; color: var(--muted); pointer-events: none; }
.set-search input {
  width: 100%; padding: 9px 12px 9px 32px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  font: inherit; font-size: 13px;
}
.set-search input:focus { outline: none; border-color: var(--violet); box-shadow: 0 0 0 3px var(--accent-wash); }
.set-search input::-webkit-search-cancel-button { cursor: pointer; }
.set-group { margin-top: 16px; }
.set-glabel {
  font-size: 10.5px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin: 0 0 7px 11px;
}
.set-item {
  display: flex; align-items: center; gap: 9px; padding: 8px 11px; border-radius: 9px;
  color: var(--ink); text-decoration: none; font-size: 13.5px; font-weight: 500;
  /* 2.4.11: the pill nav is sticky at top:14px, so a focused item must never land under it. */
  scroll-margin-top: 110px;
  min-height: 34px;  /* 2.5.8 target size */
}
.set-item svg { width: 15px; height: 15px; flex: none; stroke-width: 1.9; color: var(--muted); }
.set-item:hover { background: var(--hover); }
/* The active item is the most contrasted of its group: violet wash, violet text, 600. */
.set-item.on { background: var(--accent-wash); color: var(--violet-txt); font-weight: 600; }
.set-item.on svg { color: var(--violet-txt); }
.set-lab { min-width: 0; }
/* Amber dot, pushed right: something inside is waiting on the merchant. */
.set-dot { margin-left: auto; width: 7px; height: 7px; border-radius: 50%; background: var(--warn-txt); flex: none; }
.set-none { font-size: 12.5px; color: var(--muted); margin: 14px 11px 0; line-height: 1.6; }

/* --- the page --- */
.set-main { min-width: 0; padding-top: 2px; }
.set-crumb { font-size: 12.5px; color: var(--muted); margin-bottom: 10px; }
.set-crumb a { color: var(--violet-txt); text-decoration: none; }
.set-crumb a:hover { text-decoration: underline; }
.set-crumb .sep { margin: 0 6px; opacity: .5; }
.set-crumb b { color: var(--ink); font-weight: 600; }
.set-h1 { font-size: 30px; font-weight: 600; letter-spacing: -.03em; margin: 0; }
.set-sub { font-size: 14px; color: var(--muted); margin: 7px 0 22px; max-width: 620px; line-height: 1.6; }
.set-note { font-size: 12.5px; color: var(--muted); line-height: 1.65; margin: 14px 0 0; }
.set-dim { color: var(--muted); font-size: 12.5px; }
.set-card-panel { padding: 22px 24px; }

/* --- the index's cards --- */
.set-sec { margin-bottom: 30px; }
.set-sec .set-glabel { margin: 0 0 12px; }
.set-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
.set-card {
  display: flex; flex-direction: column; gap: 4px; padding: 18px 20px; border-radius: 16px;
  background: var(--surface); border: 1px solid var(--line); text-decoration: none; color: var(--ink);
  transition: border-color .18s, transform .18s;
  scroll-margin-top: 110px;
}
.set-card:hover { border-color: var(--violet); transform: translateY(-1px); }
.set-card-ic {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 11px; background: var(--accent-wash);
  color: var(--violet-txt); margin-bottom: 8px;
}
.set-card-ic svg { width: 18px; height: 18px; stroke-width: 1.9; }
.set-card-t { font-size: 14px; font-weight: 600; }
.set-card-d { font-size: 12.5px; color: var(--muted); line-height: 1.55; }
.set-card-m {
  font-size: 12px; color: var(--muted); margin-top: 7px;
  font-variant-numeric: tabular-nums;
}
.set-card-m.warn { color: var(--warn-txt); font-weight: 600; }

/* --- responsive ---
   Under 1040px the column becomes a horizontal strip. On the INDEX it is hidden
   outright: the cards below already are that navigation, and a list of the same items
   stacked above them is exactly the duplication this hub exists to remove. */
@media (max-width: 1040px) {
  .set-wrap { grid-template-columns: 1fr; gap: 20px; }
  .set-nav { position: static; flex-direction: row; flex-wrap: wrap; gap: 6px; align-items: center; }
  .set-search { width: 100%; margin-bottom: 4px; }
  .set-group { display: contents; }
  .set-glabel { display: none; }
  .set-item { border: 1px solid var(--line); }
  .set-wrap.is-index .set-nav { display: none; }
}
@media (max-width: 760px) {
  .set-cards { grid-template-columns: 1fr; }
  .set-h1 { font-size: 25px; }
  .set-card-panel { padding: 18px 16px; }
  .set-card-panel .ledger.grid2 { grid-template-columns: 1fr; }
}

/* ============ Toolbar gear + the environment popover (base.html) ============ */
.topnav-gear {
  position: relative; display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; border-radius: 999px; color: var(--nuit);
  text-decoration: none; flex: none;
}
.topnav-gear svg { width: 17px; height: 17px; stroke-width: 1.9; }
.topnav-gear:hover { background: var(--gris-clair, rgba(11, 19, 32, .07)); }
/* Active is the same full nuit pill the nav links use: one visual language for "you are here". */
.topnav-gear.on { background: var(--nuit); color: #fff; }
.gear-dot {
  position: absolute; top: 5px; right: 5px; width: 7px; height: 7px; border-radius: 50%;
  background: var(--or2, #ffb300); box-shadow: 0 0 0 2px rgba(255, 255, 255, .95);
}
.topnav-gear.on .gear-dot { box-shadow: 0 0 0 2px var(--nuit); }

.envpop { position: relative; }
.envpop > summary { list-style: none; cursor: pointer; }
.envpop > summary::-webkit-details-marker { display: none; }
.envpop-card {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 60;
  width: 330px; border-radius: 16px; padding: 18px;
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: 0 18px 50px rgba(15, 23, 42, .22);
  text-align: left;
}
.envpop-t { font-size: 14.5px; font-weight: 600; color: var(--ink); }
.envpop-p { font-size: 12.5px; color: var(--muted); line-height: 1.6; margin: 7px 0 0; }
.envpop-list { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.envpop-list li { display: flex; align-items: center; gap: 9px; font-size: 12.5px; color: var(--ink); }
.envpop-list .d { width: 7px; height: 7px; border-radius: 50%; background: var(--warn-txt); flex: none; }
.envpop-list .more { color: var(--muted); padding-left: 16px; }
/* This was `.btn-cta`, a class that only exists under .vwrap: outside the onboarding
   wizard it resolved to nothing, so the popover's call to action rendered as bare text at
   18px. Given its own definition here, primary-button shaped and above the 24px bar. */
.envpop-cta {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  margin-top: 16px; width: 100%; min-height: 36px; padding: 9px 18px; border-radius: 10px;
  background: var(--primary-bg); color: var(--primary-fg); text-decoration: none;
  font-size: 13px; font-weight: 600;
}
.envpop-cta:hover { background: var(--primary-bg-hover); }
@media (max-width: 560px) { .envpop-card { width: min(330px, calc(100vw - 32px)); } }

/* --- Settings > Company: the statement preview and the dirty-state Save --- */
.set-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px; align-items: start; }
.set-help { font-size: 12px; color: var(--muted); line-height: 1.55; margin: 6px 0 0; }
.set-preview-lab {
  font-size: 10.5px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 9px;
}
/* One line of a bank statement. Opaque on purpose: a figure or an identifier must never
   be read through a translucent surface. */
.set-statement {
  display: flex; align-items: baseline; gap: 12px; padding: 14px 16px; border-radius: 12px;
  background: var(--hover); border: 1px solid var(--line);
}
.set-st-date { font-size: 12px; color: var(--muted); flex: none; }
.set-st-desc { font-size: 13px; font-weight: 600; color: var(--ink); word-break: break-all; }
.set-st-amt { margin-left: auto; font-size: 13px; color: var(--ink); flex: none; }
.set-actions { display: flex; align-items: center; gap: 12px; margin-top: 20px; }
.set-unsaved { font-size: 12.5px; color: var(--warn-txt); }
@media (max-width: 760px) { .set-two { grid-template-columns: 1fr; gap: 18px; } }

/* --- Settings > Stores: the channel list on a store card --- */
.set-card-panel.mt { margin-top: 18px; }
.set-chan { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.set-chan li { display: flex; align-items: baseline; gap: 9px; font-size: 13px; }
.set-chan .d { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--muted); }
.set-chan .d.ok { background: var(--ok-txt); }
.set-chan .d.idle { background: var(--muted); }

/* --- Settings > Team & access --- */
.tm-person { display: flex; align-items: center; gap: 10px; }
.tm-av {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 32px; height: 32px; border-radius: 50%; font-size: 11.5px; font-weight: 600;
  background: var(--grad-or, linear-gradient(135deg, #ffd60a, #ffb300)); color: #20180a;
}
.tm-av-idle { background: var(--hover); color: var(--muted); }
.tm-av-idle svg { width: 14px; height: 14px; }
.tm-person span span { display: block; }
.tm-mail { font-size: 12px; color: var(--muted); }
.tm-pending { opacity: .82; }
.tm-empty { text-align: left; }
.tm-empty p { font-size: 13px; color: var(--muted); line-height: 1.65; margin: 8px 0 0; max-width: 560px; }
.tm-suggest { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 16px; }
.tm-roles td { vertical-align: top; }
.tm-roles td .set-dim { font-size: 12px; margin-top: 3px; max-width: 320px; line-height: 1.5; }

/* --- the invitation landing page --- */
.join-role {
  font-size: 12.5px; color: var(--muted); line-height: 1.6; margin: 0 0 20px;
  padding: 12px 14px; border-radius: 12px; background: var(--accent-wash);
}
.join-note { font-size: 12.5px; color: var(--muted); line-height: 1.6; margin: 0 0 18px; }
.join-foot { font-size: 12px; color: var(--muted); margin: 18px 0 0; text-align: center; }
/* The shell those pages share (team and Tap to Pay invitations, step-up): one centred card.
   Themed by the tokens because, unlike Sign in, a signed-in person can land on it. Unstyled
   until lot 461, so every one of them rendered flush against the left edge. */
.login-wrap { min-height: 100vh; display: grid; place-items: center; padding: 32px 16px; }
.login-card {
  width: 100%; max-width: 420px; padding: 32px 30px; border-radius: var(--radius-card);
  background: var(--surface); border: 1px solid var(--line); box-shadow: var(--shadow);
}
.login-card .login-brand { font-size: 20px; font-weight: 600; letter-spacing: -0.02em; color: var(--ink); margin-bottom: 26px; }
.login-card .login-brand b {
  font-weight: 600; background: var(--grad-or); -webkit-background-clip: text;
  background-clip: text; color: transparent;
}
.login-h1 { font-family: var(--display); font-size: 24px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.25; color: var(--ink); margin: 0 0 10px; }
.login-card .login-sub { color: var(--muted); margin-bottom: 20px; }
.login-card .login-sub b { color: var(--ink); font-weight: 600; }

/* --- Settings > Security --- */
/* The design system's "to complete" pattern: a gold halo while two-factor is off, gone
   once it is on. Mask-composite so the border itself carries the gradient. */
.set-card-panel.halo { position: relative; }
.set-card-panel.halo::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1px;
  background: var(--grad-or, linear-gradient(135deg, #ffd60a, #ffb300));
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: .5; pointer-events: none;
}
.sec-enrol { display: grid; grid-template-columns: 168px 1fr; gap: 22px; align-items: start; margin-top: 16px; }
.sec-qr { background: #fff; padding: 10px; border-radius: 12px; line-height: 0; }
.sec-qr svg { width: 148px; height: 148px; image-rendering: pixelated; }
.sec-secret { font-size: 14px; letter-spacing: .06em; margin: 4px 0 16px; word-break: break-all; }
/* The recovery codes, in the amber "read this now" frame. Opaque: a code read through a
   translucent surface is a code someone mistypes. */
.sec-codes {
  margin: 16px 0; padding: 16px 18px; border-radius: 14px;
  background: var(--warn-bg); border: 1px solid var(--warn-txt);
}
.sec-codes b { font-size: 13.5px; color: var(--warn-txt); }
.sec-codes p { font-size: 12.5px; color: var(--muted); line-height: 1.6; margin: 6px 0 0; }
.sec-code-list {
  list-style: none; margin: 14px 0; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 20px;
}
.sec-code-list li { font-size: 13.5px; letter-spacing: .04em; }
@media (max-width: 760px) {
  .sec-enrol { grid-template-columns: 1fr; }
  .sec-code-list { grid-template-columns: 1fr; }
}

/* --- Settings > Payout account --- */
.po-account { display: flex; align-items: center; gap: 14px; margin-top: 4px; }
.po-ava {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 44px; height: 44px; border-radius: 12px; font-size: 19px; font-weight: 600;
  background: var(--accent-wash); color: var(--violet-txt);
}
/* Opaque, and tabular: an IBAN read through a translucent surface is an IBAN mistyped. */
.po-iban { font-size: 16px; font-weight: 600; letter-spacing: .04em; }
.po-proof {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  margin-top: 20px; padding-top: 16px; border-top: 1px solid var(--line); flex-wrap: wrap;
}
.po-proof b { font-size: 13.5px; }
.po-hold { font-size: 12.5px; color: var(--warn-txt); margin: 14px 0 0; font-weight: 600; }

/* --- Settings > Developers (keys, webhooks, events) --- */
/* The secret, once. Amber and opaque: it is copied character by character. */
.key-reveal {
  margin-bottom: 18px; padding: 16px 18px; border-radius: 14px;
  background: var(--warn-bg); border: 1px solid var(--warn-txt);
}
.key-reveal b { font-size: 13.5px; color: var(--warn-txt); }
.key-reveal p { font-size: 12.5px; color: var(--muted); line-height: 1.6; margin: 6px 0 12px; }
.key-reveal-val {
  font-size: 13px; word-break: break-all; padding: 10px 12px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--line); margin-bottom: 10px;
}
/* Generous rows, not a tight table: a key is read and copied, not scanned in bulk. */
.key-list { display: flex; flex-direction: column; gap: 2px; margin: 16px 0 4px; }
.key-row { padding: 14px 0; border-top: 1px solid var(--line); }
.key-row.revoked { opacity: .6; }
.key-main { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.key-val { font-size: 13.5px; letter-spacing: .02em; }
.key-meta { font-size: 12px; margin-top: 4px; }
.key-end { display: flex; align-items: center; gap: 10px; margin-top: 8px; }
.key-end form { margin: 0; }

/* Store picker: a custom dropdown, never a native select. */
.dd { position: relative; display: inline-block; margin-left: auto; }
.dd > summary { list-style: none; cursor: pointer; }
.dd > summary::-webkit-details-marker { display: none; }
.dd-btn, .dd-static {
  display: inline-flex; align-items: center; gap: 8px; padding: 7px 12px;
  border: 1px solid var(--line); border-radius: 10px; font-size: 13px; background: var(--surface);
}
.dd-static { margin-left: auto; }
.dd-lab { font-size: 10px; font-weight: 600; letter-spacing: .1em; color: var(--muted); }
.dd-val { font-weight: 600; }
.dd-caret { color: var(--muted); font-size: 10px; }
.dd-pop {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 40; min-width: 200px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 18px 50px rgba(15, 23, 42, .2); padding: 6px; display: flex; flex-direction: column;
}
.dd-it { padding: 9px 12px; border-radius: 9px; text-decoration: none; color: var(--ink); font-size: 13px; }
.dd-it:hover { background: var(--hover); }
.dd-it.on { background: var(--accent-wash); color: var(--violet-txt); font-weight: 600; }
/* Button-shaped menu entries (a destructive submit) share the entry look. */
button.dd-it { border: 0; background: none; font: inherit; font-size: 13px; text-align: left; width: 100%; cursor: pointer; }
/* Destructive entry: red TEXT, red wash on hover only — never a solid red block. */
.dd-it.danger { color: var(--err-txt); }
.dd-it.danger:hover { background: var(--err-wash); }
.dd-div { height: 1px; background: var(--line); margin: 5px 8px; }

/* Sandbox | Live segmented. Live is disabled until verified, with the reason on hover. */
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; }
.seg > span { padding: 6px 14px; font-size: 12.5px; font-weight: 600; }
.seg-on { background: var(--nuit); color: #fff; }
.seg-off { color: var(--muted); }
.seg-off[aria-disabled="true"] { opacity: .55; cursor: not-allowed; }

.wh-row { padding: 16px 0; border-top: 1px solid var(--line); }
.wh-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.wh-head .d { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--ok-txt); }
.wh-head .d.bad { background: var(--err); }
.wh-url { font-size: 13px; word-break: break-all; }
.wh-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 10px; }
.wh-actions form { margin: 0; display: flex; gap: 8px; flex-wrap: wrap; }
.wh-deliveries { margin-top: 14px; }
.wh-deliveries > summary { cursor: pointer; font-size: 12.5px; color: var(--violet-txt); }

/* --- Settings > Plan & rates: what was actually paid --- */
/* Three colours for three costs, and they never change meaning: violet is ours, and the
   two pass-through costs are the neutral ones. The merchant should be able to read the bar
   and the table without matching them up twice. */
.fee-bar {
  display: flex; height: 10px; border-radius: 999px; overflow: hidden; margin: 6px 0 18px;
  background: var(--line);
}
.fee-seg { display: block; height: 100%; }
.fee-seg.ours, .fee-dot.ours { background: var(--violet); }
.fee-seg.inter, .fee-dot.inter { background: var(--cyan); }
.fee-seg.net, .fee-dot.net { background: var(--muted); }
.fee-dot {
  display: inline-block; width: 9px; height: 9px; border-radius: 50%;
  margin-right: 9px; vertical-align: baseline;
}
.fee-table { width: 100%; border-collapse: collapse; }
.fee-table td { padding: 9px 0; font-size: 13.5px; border: 0; }
.fee-table td.num { text-align: right; font-variant-numeric: tabular-nums; }
.fee-total {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  flex-wrap: wrap; margin-top: 6px; padding-top: 14px; border-top: 1px solid var(--line-strong);
}
.fee-total b { font-size: 16px; }
.fee-total .set-dim { font-size: 12.5px; margin-left: 8px; }
/* The one number a merchant compares against another provider: given its own weight. */
.fee-eff { font-size: 15px; font-weight: 600; color: var(--violet-txt); font-variant-numeric: tabular-nums; }
.ptar-more { margin-top: 10px; }
.ptar-more > summary { font-size: 12.5px; color: var(--violet-txt); cursor: pointer; }
.ptar-more p { font-size: 12.5px; color: var(--muted); line-height: 1.65; margin: 10px 0 0; }
.ptar-incident td { border-top: 1px dashed var(--line-strong); }

/* The same three lines on ONE payment, inside the detail drawer. */
.fees-paid .kv { margin: 0; }
.fees-paid-total dt, .fees-paid-total dd { font-weight: 600; }
.fees-paid-total { border-top: 1px solid var(--line); padding-top: 6px; margin-top: 2px; }
.drawer-note { font-size: 12px; color: var(--muted); margin: 8px 0 0; line-height: 1.6; }

/* --- Settings > YOU: profile, notifications, appearance --- */
.pr-head { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
.pr-av {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 48px; height: 48px; border-radius: 50%; font-size: 17px; font-weight: 700;
  background: var(--grad-or); color: var(--nuit);
}
.pr-name { font-size: 16px; font-weight: 600; }

.nt-table { width: 100%; border-collapse: collapse; }
.nt-table th {
  font-size: 10px; font-weight: 600; letter-spacing: .1em; color: var(--muted);
  text-transform: uppercase; text-align: left; padding: 0 0 10px;
}
.nt-table th.nt-col, .nt-table td.nt-col { width: 88px; text-align: center; }
.nt-table td { padding: 14px 0; border-top: 1px solid var(--line); font-size: 13.5px; }
.nt-table td .set-dim { font-size: 12.5px; margin-top: 2px; }
/* Locked: always sent, and the row says so by weight rather than by colour alone. */
.nt-table tr.locked td:first-child b::after {
  content: "always on"; margin-left: 8px; font-size: 10px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase; color: var(--muted);
}

/* The switch. 44x24 hit area: WCAG 2.2 2.5.8 asks 24x24 minimum, and a control this small
   is also the one a thumb misses. */
.sw { display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 26px; cursor: pointer; }
.sw input { position: absolute; opacity: 0; width: 44px; height: 26px; margin: 0; cursor: pointer; }
.sw-track {
  display: block; width: 40px; height: 24px; border-radius: 999px; background: var(--line-strong);
  transition: background .16s ease; position: relative;
}
.sw-knob {
  position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%;
  background: var(--surface); box-shadow: 0 1px 3px rgba(15, 23, 42, .3);
  transition: transform .16s ease;
}
.sw input:checked + .sw-track { background: var(--ok-txt); }
.sw input:checked + .sw-track .sw-knob { transform: translateX(16px); }
.sw input:focus-visible + .sw-track { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.sw.is-locked { cursor: not-allowed; }
.sw.is-locked .sw-track { opacity: .5; }
@media (prefers-reduced-motion: reduce) {
  .sw-track, .sw-knob { transition: none; }
}

/* Segmented picker (Day | Night | System). Radios, so it is a radiogroup for real. */
.seg-pick { padding: 3px; gap: 3px; border-radius: 12px; }
.seg-pick .seg-opt {
  display: inline-flex; align-items: center; justify-content: center; min-height: 32px;
  padding: 6px 16px; border-radius: 9px; font-size: 12.5px; font-weight: 600;
  color: var(--muted); cursor: pointer;
}
.seg-pick .seg-opt input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.seg-pick .seg-opt.on { background: var(--nuit); color: #fff; }
[data-theme="dark"] .seg-pick .seg-opt.on { background: var(--accent); color: var(--nuit); }
.seg-pick .seg-opt:has(input:focus-visible) { outline: 2px solid var(--accent-ink); outline-offset: 2px; }

/* Opaque, because it carries an amount: nothing showing a figure is read through a blur. */
.ap-preview {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-top: 22px;
  padding: 14px 16px; border-radius: 12px; background: var(--canvas); border: 1px solid var(--line);
}
.ap-preview b { font-size: 15px; font-variant-numeric: tabular-nums; }
.ap-toast {
  position: fixed; left: 50%; bottom: 28px; transform: translateX(-50%); z-index: 200;
  padding: 10px 18px; border-radius: 999px; font-size: 13px; font-weight: 600;
  background: var(--nuit); color: #fff; box-shadow: var(--shadow);
}
[data-theme="dark"] .ap-toast { background: var(--accent); color: var(--nuit); }

/* --- the three fields that took the focus ring off and never gave it back --- */
/* Every other `outline: none` here is paired with a :focus style. These three were not, so
   tabbing into the command palette or a filter search said nothing at all. */
.cmdk-input:focus-visible,
.fbar .p-search:focus-visible,
.fsearch-input:focus-visible {
  outline: 2px solid var(--accent-ink);
  outline-offset: 2px;
  border-radius: 6px;
}
/* The pill around the list search lights up with it, so the ring reads as one control. */
.fsearch:has(.fsearch-input:focus-visible) { border-color: var(--accent-ink); }
/* Skip to content: hidden until focused, then the first thing on the page. The <main>
   landmark already satisfies 2.4.1 for a screen reader; this is for the keyboard. */
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 400;
  padding: 10px 16px; border-radius: 10px;
  background: var(--nuit); color: #fff; font-size: 13.5px; font-weight: 600;
  text-decoration: none; transition: top 0.15s;
}
.skip-link:focus { top: 12px; outline: 2px solid var(--accent); outline-offset: 2px; }


/* --- Help, at the same place on every settings page (WCAG 2.2 3.2.6) --- */
.set-help-link {
  display: flex; align-items: center; gap: 10px; min-height: 36px; margin-top: 18px;
  padding: 8px 10px; border-radius: 10px; color: var(--muted); text-decoration: none;
  font-size: 13px; border-top: 1px solid var(--line);
}
/* Same 15px as a nav item. The icon macro ships a viewBox and no width/height on purpose
   (it inherits its size), so a call site that sizes nothing gets the SVG default — which
   is how the question mark ended up bigger than the nav it sits under. */
.set-help-link svg { width: 15px; height: 15px; flex: none; stroke-width: 1.9; }
.set-help-link:hover { color: var(--ink); background: var(--hover); }
.set-help-dlg {
  max-width: 520px; width: calc(100% - 32px); padding: 26px 28px; border: 1px solid var(--line);
  border-radius: 18px; background: var(--surface); color: var(--ink); box-shadow: var(--shadow-pop);
}
.set-help-dlg::backdrop { background: rgba(11, 19, 32, .5); }
.set-help-x {
  float: right; width: 32px; height: 32px; border: 0; border-radius: 8px; cursor: pointer;
  background: transparent; color: var(--muted); font-size: 20px; line-height: 1;
}
.help-h { font-size: 18px; margin: 0 0 10px; }
.help-p { font-size: 13.5px; color: var(--muted); line-height: 1.7; margin: 0 0 14px; }
.help-list { margin: 0 0 14px; padding-left: 18px; font-size: 13.5px; line-height: 1.8; }

/* --- accessibility pass (WCAG 2.2 AA) --- */
/* 2.4.11 Focus Not Obscured: the top nav is a sticky pill at top:14px. Without this, tabbing
   to an element just below the fold scrolls it exactly under that pill. */
.set-main :is(a, button, input, select, textarea, summary, [tabindex]) { scroll-margin-top: 110px; }
/* 2.5.8 Target Size: the small controls that sat under 24px. Padding rather than font size,
   so nothing about the layout changes except what a finger can hit. */
.copy-btn, .drawer-close, .set-help-x { min-width: 24px; min-height: 24px; }
.row-actions .btn.small, .key-end .btn.small { min-height: 26px; }
/* Measured with getBoundingClientRect on every settings screen, not judged by eye. These
   two came back under the bar: a breadcrumb link 16px tall, and the popover's call to
   action at 18px. Padding on the link, a real button height on the CTA. */
.set-crumb a { display: inline-block; padding: 4px 2px; }
.envpop-cta { min-height: 34px; align-items: center; }
/* Inline padding on an inline-block does not push the surrounding line boxes, so these
   grow the hit area without moving anything on the page. 2.5.8 exempts a link sitting
   inside a sentence; these are standalone often enough that the exemption is not the
   answer, and the fix costs nothing where it is. */
.link-v, .link-vio { display: inline-block; padding-block: 4px; }
.btn-dashed { min-height: 26px; }
.apidocs a { display: inline-block; padding-block: 4px; }
/* The side rail is a list of destinations: full width, so a short one ("VAT") is as easy
   to hit as a long one. */
.apidocs-side a { display: block; padding-block: 4px; }

/* --- Settings > Shops: the two kinds behind "Add a shop" --- */
/* Side by side so the choice is one glance, stacked when there is no room for two. Equal
   height here, unlike a list of unrelated blocks: two options being compared read as two
   options when they are the same size. */
.shop-kinds { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; margin-top: 16px; }
.shop-kind { display: block; padding: 16px 18px; border: 1px solid var(--line); border-radius: 14px; background: var(--surface); cursor: pointer; }
.shop-kind:hover { border-color: var(--line-strong); }
/* Selected: nuit by day, gold by night — the segmented picker's rule. Gold on white is
   1.6:1, which is a decoration, not a state a reader can see. */
.shop-kind:has(input:checked) { border-color: var(--nuit); box-shadow: 0 0 0 1px var(--nuit) inset; }
[data-theme="dark"] .shop-kind:has(input:checked) { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.shop-kind:has(input:focus-visible) { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.shop-kind-h { display: flex; align-items: center; gap: 9px; margin-bottom: 6px; }
.shop-kind-h b { font-size: 14px; }
.shop-kind-h input { width: 16px; height: 16px; accent-color: var(--accent-ink); margin: 0; }
.shop-kind .set-help { display: block; font-size: 12px; color: var(--muted); line-height: 1.55; }
/* The name comes after the kind, so the form waits for a choice. Guarded by @supports:
   where :has() is unknown both forms stay visible, each labelled with the kind it adds,
   which is the old behaviour rather than a page with no way to submit. */
@supports selector(:has(*)) {
  .shop-add .shop-next { display: none; }
  .shop-add:has(#kindWebsite:checked) .for-website { display: block; }
  .shop-add:has(#kindStore:checked) .for-store { display: block; }
}
.shop-next { margin-top: 18px; }

/* ============ Settings v2 shared components (templates/_components.html) ============ */
/* Eight components shared by the six Settings screens. Defined once, here, so a screen
   cannot mint a private copy. Gallery with every state: /_design/components (debug only). */

/* --- IdentityHeader: initials square + title + chips + actions pushed right --- */
.idh { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
.idh-sq {
  display: grid; place-items: center; flex: none;
  width: 52px; height: 52px; border-radius: 15px;
  background: var(--accent-wash); color: var(--violet-txt);
  font-size: 16px; font-weight: 600;
}
.idh-main { flex: 1; min-width: 240px; }
/* The one 20px element of its screen: the object the whole page is about. */
.idh-title { margin: 0 0 7px; font-size: 20px; font-weight: 600; letter-spacing: -.02em; line-height: 1.25; }
.idh-chips { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.idh-actions { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; margin-left: auto; }
@media (max-width: 760px) { .idh-actions { margin-left: 0; width: 100%; } }

/* --- DefinitionGrid: 2 columns, 1px separators; 1 column under 1040px --- */
.defgrid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 1px; margin: 0;
  background: var(--line-strong); border: 1px solid var(--line-strong);
  border-radius: 16px; overflow: hidden;
}
/* Opaque: these cells carry identifiers (company numbers, IBAN-class values). */
.defcell { background: var(--surface); padding: 14px 16px; }
.defcell dt {
  font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 6px;
}
.defcell dd { margin: 0; font-size: 13.5px; font-weight: 500; line-height: 1.45; }
/* An absent value is a sentence, muted but readable, never a dash. */
.defval.is-empty { color: var(--muted); font-weight: 400; }
/* A hint never inherits its value's mono face or its tracking. */
.defhint {
  display: block; font-family: var(--body); font-variant-numeric: normal; letter-spacing: 0;
  font-size: 11.5px; font-weight: 400; color: var(--muted); margin-top: 4px; line-height: 1.5;
}
@media (max-width: 1040px) { .defgrid { grid-template-columns: 1fr; } }

/* --- DataRow: bold title + explanation + status/action zone, bottom separator --- */
.drow { display: flex; align-items: flex-start; gap: 16px; padding: 15px 0; border-bottom: 1px solid var(--line); }
.drow:last-child { border-bottom: 0; }
.drow-m { flex: 1; min-width: 200px; }
.drow-m > b { display: block; font-size: 13.5px; font-weight: 600; }
.drow-m > span { display: block; font-size: 12px; color: var(--muted); margin-top: 3px; line-height: 1.55; }
.drow-end { display: flex; align-items: center; gap: 10px; margin-left: auto; flex-wrap: wrap; justify-content: flex-end; }
/* Waiting on the merchant: the same amber dot as the nav item and the gear. */
.drow.needs-you { position: relative; padding-left: 16px; }
.drow.needs-you::before {
  content: ""; position: absolute; left: 0; top: 20px;
  width: 7px; height: 7px; border-radius: 50%; background: var(--warn-txt);
}

/* --- StatementPreview: what the descriptor competes with on a real statement --- */
/* Opaque surfaces throughout: every line carries an amount. */
.stp { margin: 0; border: 1px solid var(--line-strong); border-radius: 16px; background: var(--canvas); overflow: hidden; }
/* Muted text on a CANVAS surface needs the deeper muted: plain --muted reads 4.4:1 there. */
.stp-h {
  font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted-strong); padding: 13px 16px; border-bottom: 1px solid var(--line);
}
.stp-l {
  display: flex; align-items: center; gap: 12px; padding: 12px 16px;
  font-size: 12.5px; font-variant-numeric: tabular-nums; border-bottom: 1px solid var(--line);
}
.stp-l:last-child { border-bottom: 0; }
.stp-d { color: var(--muted-strong); width: 58px; flex: none; font-size: 11.5px; }
.stp-a { margin-left: auto; font-weight: 600; white-space: nowrap; }
/* The neighbours are scenery, aria-hidden and faded; contrast rules apply to content, and
   these are deliberately not content. */
.stp-l.is-masked { opacity: .42; }
.stp-l.is-masked .stp-n { letter-spacing: .14em; }
.stp-l.is-mine { background: var(--surface); box-shadow: inset 3px 0 0 var(--violet); }
.stp-l.is-mine .stp-n { font-family: var(--mono); font-weight: 600; font-size: 12.5px; overflow-wrap: anywhere; }
.stp-pfx { color: var(--violet-txt); }

/* --- ShopCard: header (pictogram, name, subline, chips, menu) + 2-column body --- */
.shc { border: 1px solid var(--line-strong); border-radius: 18px; background: var(--surface); box-shadow: var(--shadow-sm); overflow: hidden; }
.shc { margin-bottom: 14px; }
.shc-head { display: flex; align-items: center; gap: 13px; padding: 17px 20px; flex-wrap: wrap; }
.shc-sq {
  display: grid; place-items: center; flex: none;
  width: 40px; height: 40px; border-radius: 12px;
  background: var(--accent-wash); color: var(--violet-txt);
}
.shc-sq svg { width: 19px; height: 19px; }
.shc-id { min-width: 200px; }
.shc-id > b { display: block; font-size: 15.5px; font-weight: 600; letter-spacing: -.01em; }
.shc-sub { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--muted); margin-top: 4px; flex-wrap: wrap; }
.shc-act { margin-left: auto; display: flex; align-items: center; gap: 9px; }
.shc-body { display: grid; grid-template-columns: 1.35fr 1fr; border-top: 1px solid var(--line); }
.shc-col { padding: 16px 20px; min-width: 0; }
.shc-col + .shc-col { border-left: 1px solid var(--line); }
.shc-chan { display: flex; align-items: center; gap: 9px; font-size: 13px; padding: 5px 0; min-height: 24px; }
.shc-chan .d { width: 7px; height: 7px; border-radius: 50%; flex: none; background: var(--line-strong); }
.shc-chan.is-on .d { background: var(--ok); }
.shc-chan b { font-weight: 600; }
.shc-chan.is-off b { color: var(--muted); font-weight: 500; }
.shc-end { margin-left: auto; color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.shc-mini { display: flex; align-items: baseline; gap: 10px; font-size: 12.5px; padding: 5px 0; min-height: 24px; }
.shc-mini .k { color: var(--muted); width: 88px; flex: none; }
.shc-mini .v { font-weight: 500; min-width: 0; }
.shc-mini .v.is-empty { color: var(--muted); font-weight: 400; }
@media (max-width: 1040px) {
  .shc-body { grid-template-columns: 1fr; }
  .shc-col + .shc-col { border-left: 0; border-top: 1px solid var(--line); }
}

/* --- PermissionMatrix: roles compared cell by cell --- */
.pmx { width: 100%; border-collapse: collapse; }
.pmx th {
  font-size: 10px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted); padding: 0 6px 12px; border-bottom: 1px solid var(--line);
  text-align: center; line-height: 1.4;
}
.pmx th:first-child { text-align: left; padding-left: 0; width: 38%; }
.pmx td { padding: 13px 6px; border-bottom: 1px solid var(--line); text-align: center; vertical-align: middle; }
.pmx tr:last-child td { border-bottom: 0; }
.pmx tbody tr:hover { background: var(--hover); }
.pmx td:first-child { text-align: left; padding-left: 0; }
.pmx-name { display: flex; align-items: center; gap: 9px; min-height: 24px; }
.pmx-name b { font-size: 13.5px; font-weight: 600; }
.pmx-desc { display: block; font-size: 11.5px; color: var(--muted); margin-top: 4px; line-height: 1.5; max-width: 330px; }
/* The tick is the most contrasted element of the grid; the unchecked cell is a dim dash,
   never a red cross: an unchecked box is a scope, not an error. */
.pmx-yes {
  display: inline-grid; place-items: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--accent-wash); color: var(--violet-txt);
}
.pmx-yes svg { width: 12px; height: 12px; }
.pmx-no { display: inline-block; width: 10px; height: 2px; border-radius: 2px; background: var(--line-strong); }
/* The row's action shows when the row is examined, by pointer or by keyboard. */
.pmx-pick { opacity: 0; font-size: 12px; }
.pmx tr:hover .pmx-pick, .pmx tr:focus-within .pmx-pick { opacity: 1; }
@media (max-width: 760px) {
  .pmx th, .pmx td { padding: 10px 4px; }
  .pmx-desc { display: none; }
  .pmx-pick { opacity: 1; }
}

/* --- AccountCard: the gold € square + the IBAN in blocks of four --- */
/* Opaque: an IBAN read through a translucent surface is an IBAN mistyped. */
.acc {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  border: 1px solid var(--line-strong); border-radius: 16px; padding: 18px 20px;
  background: var(--canvas);
}
.acc-sq {
  display: grid; place-items: center; flex: none;
  width: 46px; height: 46px; border-radius: 14px;
  background: var(--grad-or); color: #20180a; font-size: 19px; font-weight: 600;
}
.acc-m { min-width: 220px; }
.acc-iban {
  display: block; font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 16px; font-weight: 600; letter-spacing: .02em; overflow-wrap: anywhere;
}
/* The bank/BIC/date subline explains the mono value above it, so it is not mono. It sits
   on the canvas-filled card, where plain --muted fails AA by a hair. */
.acc-sub { display: block; font-family: var(--body); font-size: 12.5px; color: var(--muted-strong); margin-top: 5px; }
.acc-end { margin-left: auto; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }

/* ============ Team-flow components (lot D0): Drawer, RolePicker, RowMenu, StepUp ==== */
/* --- Drawer: the 440px right panel every team action opens in. Never a centred modal:
   the role grid must stay readable behind it, choosing a role is a comparison. --- */
.drw-veil {
  position: fixed; inset: 0; z-index: 200; background: rgba(11, 19, 32, 0.42);
  backdrop-filter: blur(2px); opacity: 0; pointer-events: none; transition: opacity .32s;
}
.drw-veil.on { opacity: 1; pointer-events: auto; }
.drw {
  position: fixed; top: 0; right: 0; bottom: 0; width: 440px; max-width: 100vw;
  background: var(--surface); z-index: 210; border-left: 1px solid var(--line-strong);
  box-shadow: -24px 0 60px rgba(11, 19, 32, 0.16);
  display: flex; flex-direction: column;
  transform: translateX(100%); transition: transform .32s cubic-bezier(.2, .7, .2, 1);
  visibility: hidden;
}
[data-theme="dark"] .drw { box-shadow: -24px 0 70px rgba(0, 0, 0, 0.55); }
.drw.on { transform: none; visibility: visible; }
.drw-head { display: flex; align-items: flex-start; gap: 13px; padding: 22px 24px 16px; border-bottom: 1px solid var(--line); }
.drw-head h3 { margin: 0 0 4px; font-size: 17px; font-weight: 600; letter-spacing: -.02em; }
.drw-head p { margin: 0; font-size: 12.5px; color: var(--muted); line-height: 1.55; }
.drw-x {
  margin-left: auto; width: 30px; height: 30px; display: grid; place-items: center; flex: none;
  border: 0; background: none; color: var(--muted); border-radius: 8px; cursor: pointer; font-size: 18px;
}
.drw-x:hover { background: var(--hover); color: var(--ink); }
/* The body scrolls; the foot does NOT belong to the scroll area — it stays visible. */
.drw-body { flex: 1; overflow-y: auto; padding: 20px 24px 24px; }
.drw-foot {
  display: flex; align-items: center; gap: 10px; padding: 16px 24px;
  border-top: 1px solid var(--line); background: var(--surface); flex: none;
}
.drw-foot .sp { margin-left: auto; display: flex; gap: 10px; }
.drw-note { font-size: 11.5px; color: var(--muted); line-height: 1.55; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
.drw-note b { color: var(--ink); font-weight: 600; }
@media (max-width: 1040px) { .drw { width: 100%; } }
@media (prefers-reduced-motion: reduce) { .drw, .drw-veil { transition: none; } }

/* --- RolePicker: radio cards with the role's permission chips. Granted = violet chip;
   refused = struck grey. Never a native select. --- */
.rlp { display: grid; gap: 8px; margin-bottom: 6px; }
.rlp-role {
  display: flex; gap: 12px; align-items: flex-start; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: 14px;
  padding: 13px 14px; transition: border-color .15s;
}
.rlp-role:hover { border-color: var(--violet); }
.rlp-role:has(input:checked) { border-color: var(--violet); background: var(--accent-wash); box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.12); }
.rlp-role:has(input:focus-visible) { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.rlp-role input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.rlp-tick {
  width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid var(--line-strong);
  flex: none; margin-top: 2px; display: grid; place-items: center; color: transparent; font-size: 11px;
}
.rlp-role:has(input:checked) .rlp-tick { border-color: var(--violet); background: var(--violet); color: #fff; }
.rlp-main { flex: 1; min-width: 0; }
.rlp-main b { display: block; font-size: 13.5px; font-weight: 600; }
.rlp-main b .pill { margin-left: 7px; vertical-align: 1px; }
.rlp-main > span { display: block; font-size: 11.5px; color: var(--muted); line-height: 1.5; margin-top: 3px; }
.rlp-caps { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 8px; }
.rlp-cap {
  flex: none; white-space: nowrap; font-size: 9.5px; font-weight: 600; letter-spacing: .03em;
  border-radius: 5px; padding: 3px 6px; background: var(--accent-wash); color: var(--violet-txt);
}
.rlp-cap.off { background: none; border: 1px solid var(--line); color: var(--muted); text-decoration: line-through; }
.rlp-role.is-disabled { opacity: .45; cursor: not-allowed; }

/* --- RowMenu: the ⋯ menu. Anchored fixed by rowmenu.js, flips when the bottom is
   short, closes on outside click, Escape and scroll. --- */
.rmn-btn {
  width: 30px; height: 30px; display: inline-grid; place-items: center; border: 0;
  background: none; color: var(--muted); border-radius: 8px; cursor: pointer; font-size: 16px;
}
.rmn-btn:hover, .rmn-btn[aria-expanded="true"] { background: var(--accent-wash); color: var(--violet-txt); }
.rmn {
  position: fixed; z-index: 240; min-width: 226px; background: var(--surface);
  border: 1px solid var(--line-strong); border-radius: 14px; padding: 6px;
  box-shadow: 0 18px 50px rgba(11, 19, 32, 0.2); display: none;
}
[data-theme="dark"] .rmn { box-shadow: 0 22px 54px rgba(0, 0, 0, 0.5); }
.rmn.on { display: block; }
.rmn-head { font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); padding: 6px 11px 8px; }
.rmn [role="menuitem"] {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; border: 0;
  background: none; font: inherit; font-size: 13px; color: var(--ink); padding: 9px 11px;
  border-radius: 9px; cursor: pointer; min-height: 36px; text-decoration: none;
}
.rmn [role="menuitem"]:hover, .rmn [role="menuitem"]:focus-visible { background: var(--accent-wash); outline: none; }
.rmn [role="menuitem"].danger { color: var(--err-txt); }
.rmn [role="menuitem"].danger:hover, .rmn [role="menuitem"].danger:focus-visible { background: var(--err-wash); }
.rmn-div { height: 1px; background: var(--line); margin: 5px 8px; }
/* A menu inside a nowrap table cell must not inherit it: its text wraps in the menu. */
.rmn { white-space: normal; }
.rmn form { margin: 0; }
/* The table column that holds a row's ⋯: as narrow as the button, at the row's end. */
.rmn-cell { width: 1%; white-space: nowrap; text-align: right; }
/* A side-card value with its own ⋯ beside it (the client page's partner). */
.sc-v.sc-with-menu { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.sc-with-menu .rmn-btn { margin: -6px -6px -6px 0; }
/* The one form field a confirm dialog may carry (which partner a client moves to). */
.confirm-dialog .field { text-align: left; margin: 0 0 20px; }

/* --- StepUpDialog: the ONE centred modal of the chantier — it protects the money. The
   drawer stays open and intact behind it. Native <dialog>, so Escape and the focus trap
   come from the platform, and paste is never blocked. --- */
.sup { border: 1px solid var(--line-strong); border-radius: 20px; background: var(--surface); color: var(--ink); width: 400px; max-width: calc(100vw - 32px); padding: 26px; box-shadow: 0 30px 80px rgba(11, 19, 32, 0.28); }
.sup::backdrop { background: rgba(11, 19, 32, 0.5); }
.sup-lock { width: 40px; height: 40px; border-radius: 12px; background: var(--accent-wash); color: var(--violet-txt); display: grid; place-items: center; margin-bottom: 14px; }
.sup h3 { margin: 0 0 6px; font-size: 17px; font-weight: 600; letter-spacing: -.02em; }
.sup .why { margin: 0 0 18px; font-size: 13px; color: var(--muted); line-height: 1.6; }
.sup-acts { display: flex; gap: 10px; align-items: center; margin-top: 20px; }
.sup-acts .sp { margin-left: auto; display: flex; gap: 10px; }

/* --- Settings v2 shared refinements (lot B/C/D reviews) --- */
/* The dashed affordance means "not there yet, yours to create". The base class only
   carried a min-height (the a11y pass); this is its actual look. Scoped variants
   (.wcx .btn-dashed) keep their own. */
.btn-dashed {
  display: inline-flex; align-items: center; gap: 7px;
  border: 1.5px dashed var(--line-strong); border-radius: 999px; background: none;
  color: var(--violet-txt); font: inherit; font-size: 12.5px; font-weight: 600;
  padding: 7px 14px; cursor: pointer; min-height: 30px;
}
.btn-dashed:hover { border-color: var(--violet); background: var(--accent-wash); }
/* "Add a shop": the same dashed language at full width — the screen's main action when
   adding, placed between the last card and the foot note. */
.addshop {
  display: flex; align-items: center; justify-content: center; gap: 9px; width: 100%;
  border: 1.5px dashed var(--line-strong); border-radius: 18px; background: none;
  color: var(--violet-txt); font-size: 13.5px; font-weight: 600;
  padding: 16px; cursor: pointer; min-height: 56px; list-style: none;
}
.addshop::-webkit-details-marker { display: none; }
.addshop:hover { border-color: var(--violet); background: var(--accent-wash); }

/* The status dot is for STATUSES. A chip naming a fact or a scope ("read only",
   "online", "in person") drops it: .flat removes the ::before dot, nothing else. */
.pill.flat::before { display: none; }
/* In the settings hub the maquette's ghost is a BORDERED pill; the app-wide borderless
   ghost stays as it is everywhere else. */
.set-main .btn.ghost {
  border: 1px solid var(--line-strong); border-radius: 999px; min-height: 34px;
  color: var(--ink);
}
.set-main .btn.ghost:hover { border-color: var(--violet); }
/* The disclosure chevron: ▾ that pivots on open, never the native ► triangle. */
.ptar-more > summary { list-style: none; display: inline-flex; align-items: center; gap: 8px; }
.ptar-more > summary::-webkit-details-marker { display: none; }
.ptar-more > summary::before { content: "▾"; display: inline-block; transition: transform .25s; }
.ptar-more[open] > summary::before { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .ptar-more > summary::before { transition: none; } }
/* The save bar sits behind its own rule, like every card foot that carries an action. */
.set-actions.savebar { border-top: 1px solid var(--line); padding-top: 16px; }

/* --- Company (lot B): identity chips, the counter in the label, folded forms --- */
/* A dotless chip: these carry identity facts (number, country), not a status. */
.idh-chip {
  display: inline-flex; align-items: center; gap: 2px;
  font-size: 11.5px; font-weight: 600; padding: 4px 11px;
  border-radius: 999px; border: 1px solid var(--line-strong);
  color: var(--muted-strong); white-space: nowrap;
}
/* The character counter lives in the label, pushed right, and follows the typing. */
.field label.with-ct { display: flex; align-items: baseline; gap: 8px; }
.field label.with-ct .lab-ct { margin-left: auto; font-weight: 500; color: var(--muted); }
/* A form folded under its row: the row's action opens it (JS in place, :target without). */
.fold-form { display: none; margin-top: 12px; }
.fold-form:target, .fold-form.open { display: block; }

/* --- Company (lot B): the copy chip on the enterprise number --- */
.copy-chip {
  border: 0; border-radius: 999px; background: var(--accent-wash); color: var(--violet-txt);
  font: inherit; font-family: var(--body); font-size: 10.5px; font-weight: 600;
  padding: 3px 9px; margin-left: 6px; cursor: pointer;
  min-width: 24px; min-height: 24px;
}
/* Feedback in place, from the shared [data-copy-text] handler's .copied class. */
.copy-chip.copied .lbl { display: none; }
.copy-chip.copied::after { content: "copied ✓"; }

/* --- Team (lot D): avatars, the inserts under the table, the role picker --- */
/* The reader's own avatar is gold; everyone else violet, so "you" is findable at a glance. */
.tm-av.other { background: var(--accent-wash); color: var(--violet-txt); }
/* A pending invitation: dashed circle, no fill — a seat that exists but is not taken. */
.tm-av.inv { background: none; border: 1.5px dashed var(--line-strong); color: var(--muted); }
/* The insert under the table: a complement to the rows, never their replacement. */
.tm-insert {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  border: 1.5px dashed var(--line-strong); border-radius: 16px;
  padding: 18px 20px; margin-top: 18px;
}
.tm-insert .tx { flex: 1; min-width: 260px; }
.tm-insert .tx b { display: block; font-size: 13.5px; margin-bottom: 5px; }
.tm-insert .tx span { display: block; font-size: 12.5px; color: var(--muted); line-height: 1.6; }
.tm-insert .acts { display: flex; gap: 9px; flex-wrap: wrap; }
/* The 2FA aggregate: amber, solid-edged, and it names people. Gone at zero. */
.tm-insert.warn { border-style: solid; border-color: var(--warn-txt); background: var(--warn-bg); }
.tm-insert.warn .tx b, .tm-insert.warn .tx span { color: var(--warn-txt); }
/* Role picker: styled radios with the role's summary in the control, never a native
   select — the choice IS the comparison, so the comparison lives in the choice. */
.role-pick { display: flex; flex-direction: column; gap: 6px; }
.role-opt {
  display: flex; gap: 10px; align-items: flex-start; cursor: pointer;
  border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px;
}
.role-opt:hover { border-color: var(--line-strong); }
.role-opt:has(input:checked) { border-color: var(--nuit); box-shadow: 0 0 0 1px var(--nuit) inset; }
[data-theme="dark"] .role-opt:has(input:checked) { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.role-opt:has(input:focus-visible) { outline: 2px solid var(--accent-ink); outline-offset: 2px; }
.role-opt input { width: 15px; height: 15px; margin: 2px 0 0; accent-color: var(--accent-ink); flex: none; }
.role-opt span b { display: block; font-size: 13px; }
.role-opt span em { display: block; font-style: normal; font-size: 11.5px; color: var(--muted); line-height: 1.5; margin-top: 2px; }

/* --- Payout (lot E): the no-account box inside the halo card --- */
/* Dashed and amber-edged: something is waiting on the merchant, and the box says what. */
.po-empty {
  border: 1.5px dashed var(--warn-txt); border-radius: 16px;
  padding: 26px; text-align: center; color: var(--muted); font-size: 13px;
}
.po-empty > b { display: block; font-size: 14px; color: var(--ink); margin-bottom: 6px; }
.po-empty > p { margin: 0 auto; max-width: 460px; line-height: 1.6; }
.po-empty > p b { color: var(--ink); }

/* --- FeeBreakdown: the bar, the legend, the total, and the ghost empty state --- */
/* Three colours for three costs, and they never change meaning: violet is our fee, gold
   the interchange, cyan the network fees (the v2 canon; plan.html's .fee-* family migrates
   onto this component in lot G and retires). */
.fbk-bar { display: flex; height: 11px; border-radius: 999px; overflow: hidden; margin: 2px 0 16px; background: var(--line); }
.fbk-seg { display: block; height: 100%; }
.fbk-seg.ours, .fbk-dot.ours { background: var(--violet); }
.fbk-seg.inter, .fbk-dot.inter { background: var(--or2); }
.fbk-seg.net, .fbk-dot.net { background: var(--cyan); }
.fbk-legend { display: grid; gap: 11px; }
.fbk-row { display: flex; align-items: center; gap: 11px; font-size: 13px; }
.fbk-dot { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.fbk-rate { margin-left: auto; color: var(--muted); font-size: 11.5px; white-space: nowrap; }
.fbk-amt { width: 92px; text-align: right; margin-left: 24px; font-weight: 600; }
.fbk-total {
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
  margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line-strong);
}
.fbk-total > b { font-size: 16px; font-weight: 600; }
.fbk-meta { font-size: 12.5px; color: var(--muted); }
/* The one number a merchant compares against another provider. Violet text on light (gold
   text on white is a decoration, not a figure); gold on nuit, where gold is legible. */
.fbk-eff { margin-left: auto; font-size: 14px; font-weight: 600; color: var(--violet-txt); }
[data-theme="dark"] .fbk-eff {
  background: var(--grad-or); -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* The empty state keeps the structure: the bar and the lines stay, as ghosts, with the
   caller's sentence under them. A centred phrase alone does not say what will appear. */
.fbk.is-empty .fbk-legend { opacity: .45; }
.fbk-foot { font-size: 12px; color: var(--muted); line-height: 1.6; margin: 14px 0 0; }
.fbk-foot b { color: var(--ink); }
@media (max-width: 760px) { .shop-kinds { grid-template-columns: 1fr; } }

/* Platform notifications drawer: the sentence saying what a notification means. */
.drawer-group > p { margin: 0 0 12px; font-size: 13px; line-height: 1.5; }
/* Terminal charge panel: what the terminal read from the card, and its receipt. */
.tres-details { max-width: 340px; margin-top: 8px; }
.tres-receipt { max-width: 340px; margin-top: 6px; }
/* Transaction drawer: the two receipts sit closer than raw payload blocks. */
.drawer-group .drawer-receipt { margin: 2px 0 10px; }

/* Going live (_golive_panel.html): four steps, top to bottom. */
.golive { margin: 0 0 18px; }
.golive .gl-switch { display: flex; align-items: center; gap: 10px; }
.gl-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.gl-step { border: 1px solid var(--cd-line); border-radius: 12px; padding: 14px 16px; }
.gl-step.later { opacity: 0.6; }
.gl-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.gl-head h3 { font-size: 14px; font-weight: 600; margin: 0; }
.gl-head .pill { margin-left: auto; }
.gl-n {
  width: 22px; height: 22px; border-radius: 50%; display: inline-grid; place-items: center;
  font-size: 12px; font-weight: 700; background: var(--hover); color: var(--ink-soft);
}
.gl-step.done .gl-n { background: var(--ok-wash); color: var(--ok-txt); }
.gl-gaps, .gl-notes, .gl-solutions { margin: 6px 0 10px; padding-left: 18px; font-size: 13px; line-height: 1.6; }
.gl-gaps li { color: var(--err-txt); }
.gl-notes li { color: var(--muted); }
.gl-solutions { list-style: none; padding: 0; }
.gl-solutions li { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; }
.gl-what { display: grid; gap: 4px; margin: 6px 0; font-size: 13px; }
.gl-what div { display: grid; grid-template-columns: minmax(0, 140px) minmax(0, 1fr); gap: 10px; }
.gl-what dt { color: var(--muted); }
.gl-what dd { margin: 0; overflow-wrap: anywhere; }
.gl-error { color: var(--err-txt); font-size: 13px; overflow-wrap: anywhere; }
.gl-send { display: grid; gap: 10px; justify-items: start; margin-top: 8px; }
.gl-confirm { display: flex; gap: 8px; align-items: flex-start; font-size: 13px; line-height: 1.5; }

/* A person's report (tap_to_pay_report.html): period links in the tab bar's clothes, two
   cards side by side, the custom range. */
.rp-periods a { color: var(--muted); font-size: 14.5px; font-weight: 500; padding: 11px 2px; position: relative; text-decoration: none; transition: color 0.2s; }
.rp-periods a:hover, .rp-periods a.on { color: var(--ink); }
.rp-periods a.on::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2.5px; border-radius: 3px; background: var(--grad-or); }
.rp-range { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin: -8px 0 18px; font-size: 13px; color: var(--muted); }
.rp-range label { display: flex; align-items: center; gap: 8px; }
.rp-range input[type="date"] { font: inherit; color: var(--ink); background: var(--cd-card, transparent); border: 1px solid var(--line); border-radius: 8px; padding: 6px 8px; }
.rp-range .ml { margin-left: auto; }
.rp-two { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.rp-two .card { margin: 0 0 16px; }
.page-sub { margin: 4px 0 0; color: var(--muted); font-size: 13.5px; }
@media (max-width: 760px) { .rp-two { grid-template-columns: minmax(0, 1fr); } }

/* The applied tariff, per channel (_store_pricing.html): two labelled blocks like the
   merchant's rates card, the payment methods then the rates by region, the percentage and
   the fixed amount each in their own column. */
.ptar-pushed { margin: -4px 0 12px; font-size: 12px; }
.ptar-block { margin-top: 14px; }
.ptar-label { font-size: 11px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin-bottom: 8px; }
.ptar-schemes td, .ptar-rates td { vertical-align: top; }
.ptar-schemes .pill { vertical-align: middle; }
.ptar-region td { padding: 14px 10px 4px; font-size: 12.5px; font-weight: 600; color: var(--ink); }
.ptar-rates tbody tr:not(.ptar-region) td { border-top: 1px solid var(--line); }
.ptar-dim { color: var(--muted); font-size: 12px; }
.ptar-rates .set-dim { font-size: 11.5px; margin-top: 1px; }

/* The brand marks (_brand_macros.html), and the store page's Accepts column. */
.brand-logo { display: inline-block; vertical-align: middle; flex: 0 0 auto; }
td.accepts { white-space: nowrap; }
td.accepts .brand-logo + .brand-logo { margin-left: 4px; }

/* The client page's Acquiring tab (_client_acquiring.html, lot 524): one line of company
   facts, then per channel a head that reads like a sentence, the accepted brands in a
   strip, and the tariff as one grid (payments in rows, regions in columns) capped in width
   so the figures stay near their labels on a wide screen. Colour marks exceptions only. */
.acq-panel > .panel-head { padding: 16px 24px; }
.acq-pad { margin: 0; padding: 16px 24px; }
.acq-pad-box { margin: 16px 24px; }
.acq-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 20px; padding: 12px 24px; font-size: 12.5px; color: var(--muted); border-bottom: 1px solid var(--line); }
.acq-meta strong { color: var(--ink); font-weight: 600; }
.acq-id { font-family: var(--mono); font-size: 11.5px; color: var(--muted); display: inline-flex; align-items: center; gap: 2px; }
.acq-copy { border: 0; background: transparent; color: var(--muted); border-radius: 6px; padding: 4px; line-height: 0; cursor: pointer; }
.acq-copy:hover { background: var(--hover); color: var(--ink); }
.acq-copy.copied { color: var(--ok-txt); }
.acq-status { display: inline-flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--ink-soft); font-weight: 500; }
.acq-dot { width: 7px; height: 7px; border-radius: 50%; background: #22c55e; box-shadow: 0 0 0 3px rgba(34, 197, 94, 0.18); }
.acq-dot.warn { background: #f59e0b; box-shadow: 0 0 0 3px rgba(245, 158, 11, 0.18); }
.acq-ch { padding: 24px 24px 28px; }
.acq-ch + .acq-ch { border-top: 1px solid var(--line); }
.acq-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.acq-title { font-family: var(--display); font-size: 18px; font-weight: 600; letter-spacing: -0.015em; color: var(--ink); margin: 0; }
.acq-chip { font-size: 12px; padding: 5px 11px; border-radius: 999px; background: var(--hover); color: var(--ink-soft); font-weight: 500; white-space: nowrap; }
.acq-sub { margin-top: 8px; font-size: 12.5px; color: var(--muted); display: flex; flex-wrap: wrap; gap: 4px 18px; align-items: center; }
.acq-sub a { color: var(--violet-txt); font-weight: 500; text-decoration: none; }
.acq-sub a:hover { text-decoration: underline; }
.acq-accepts { margin-top: 18px; display: flex; flex-wrap: wrap; align-items: center; gap: 10px 20px; padding-bottom: 20px; border-bottom: 1px solid var(--line); }
.acq-k { font-size: 11px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); margin: 0; }
.acq-brand { display: inline-flex; align-items: center; gap: 9px; font-size: 13px; color: var(--ink-soft); font-weight: 500; }
.acq-brand.off { opacity: 0.55; }
.acq-brand .off-note { font-size: 11.5px; color: var(--muted); font-weight: 400; }
.acq-contract { font-size: 12.5px; color: var(--muted); padding-left: 20px; border-left: 1px solid var(--line-strong); }
.acq-contract .acq-id { color: var(--ink); }
.acq-grid { margin-top: 24px; max-width: 920px; }
.acq-grid-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 14px; margin-bottom: 12px; }
.acq-src { font-size: 12.5px; color: var(--muted); }
.acq-src.warn { color: var(--warn-txt); }
.acq-matrix { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.acq-matrix th { font-size: 12px; font-weight: 500; color: var(--muted); text-align: right; padding: 0 18px 10px; border-bottom: 1px solid var(--line-strong); white-space: nowrap; }
.acq-matrix th:first-child { text-align: left; padding-left: 0; }
.acq-matrix td { padding: 12px 18px; text-align: right; border-bottom: 1px solid var(--line); font-variant-numeric: tabular-nums; color: var(--ink); font-weight: 600; font-size: 14px; white-space: nowrap; vertical-align: top; position: relative; }
.acq-matrix td:first-child { text-align: left; padding-left: 0; font-weight: 500; font-size: 13.5px; color: var(--ink-soft); width: 100%; white-space: normal; }
.acq-matrix tr:last-child td { border-bottom: 0; }
.acq-matrix td.only { color: var(--muted); font-weight: 400; font-size: 12.5px; text-align: left; padding-left: 34px; }
.acq-matrix td.unpriced { color: var(--muted); font-weight: 400; }
.acq-matrix td.diff::after { content: ""; position: absolute; top: 13px; right: 4px; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.acq-pay { display: inline-flex; align-items: center; gap: 10px; }
.acq-note { display: block; font-size: 11.5px; color: var(--muted); font-weight: 400; margin-top: 2px; }
.acq-tag { display: inline-block; margin-left: 8px; padding: 1px 7px; border-radius: 999px; background: var(--hover); color: var(--muted-strong); font-size: 11px; font-weight: 500; }
.acq-alert { margin: 14px 0 0; font-size: 12.5px; color: var(--warn-txt); }
.acq-foot { margin: 10px 0 0; font-size: 12px; color: var(--muted); }
.acq-empty { margin: 16px 0 0; }
