/*
 * OneTap — canonical design tokens (Phase 1 of the master redesign).
 *
 * ONE source of truth for colour, type, radius, elevation, motion and
 * z-index, shared by all three surfaces (public marketing site, client
 * dashboard, admin panel). Each surface's own stylesheet (theme.css,
 * dashboard.css, admin.css) loads AFTER this file and aliases its local
 * variable names to the --ot-* tokens defined here — so there is exactly
 * one place a colour is ever defined.
 *
 * Theme model — three states:
 *   - System (default): no data-theme attribute. Light is the base look;
 *     prefers-color-scheme: dark swaps to the dark palette.
 *   - Light forced:  <html data-theme="light">
 *   - Dark forced:   <html data-theme="dark">
 * The no-flash inline <head> script in each layout sets the attribute
 * before first paint; theme-toggle.js cycles System -> Light -> Dark.
 *
 * Accent is a single blue hue (#2563EB) held CONSTANT across both themes,
 * with only its hover / readable-text variants shifting per theme. Every
 * foreground/background pair below is checked to WCAG AA (4.5:1 body,
 * 3:1 large/UI) in BOTH themes independently.
 */

@import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@500;600;700&family=Inter:wght@400;500;600;700&display=swap');

/* ============================================================= *
 *  LIGHT  (base — applies with no data-theme, and when forced)   *
 * ============================================================= */
:root {
  /* Surfaces */
  --ot-bg:            #F8FAFC;
  --ot-bg-subtle:     #EEF2F7;
  --ot-surface:       #FFFFFF;
  --ot-surface-2:     #F1F5F9;
  --ot-border:        #E2E8F0;
  --ot-border-strong: #CBD5E1;
  /* RGB triplet (not a color) so a consumer can apply its own alpha —
     same convention as Bootstrap's own --bs-*-rgb vars. Used by the
     public navbar's scrolled-state scrim (public.css), which used to be
     a hardcoded dark rgba() that stayed dark even in light mode. */
  --ot-bg-rgb: 248, 250, 252;

  /* Text */
  --ot-text:        #0F172A;
  --ot-text-muted:  #475569;
  --ot-text-subtle: #64748B;

  /* Accent — blue, constant hue across themes */
  --ot-accent:       #2563EB;
  --ot-accent-hover: #1D4ED8;
  --ot-accent-ink:   #FFFFFF;   /* text/icons ON an accent fill */
  --ot-accent-text:  #1D4ED8;   /* accent used AS text/icon on a page surface */
  --ot-accent-soft:  rgba(37, 99, 235, 0.09);
  --ot-accent-line:  rgba(37, 99, 235, 0.35);

  /* Secondary hues (badges, avatars, chart categories — not body text) */
  --ot-info:          #0F766E;
  --ot-info-soft:     rgba(15, 118, 110, 0.10);
  --ot-accent-2:      #7C3AED;
  --ot-accent-2-soft: rgba(124, 58, 237, 0.10);

  /* Semantic */
  --ot-success:      #15803D;
  --ot-success-soft: rgba(21, 128, 61, 0.10);
  --ot-warning:      #B45309;
  --ot-warning-soft: rgba(180, 83, 9, 0.10);
  --ot-danger:       #DC2626;
  --ot-danger-soft:  rgba(220, 38, 38, 0.10);
  --ot-danger-ink:   #FFFFFF;

  /* Focus ring (accessibility — never removed, only restyled) */
  --ot-ring: 0 0 0 3px rgba(37, 99, 235, 0.35);

  /* Typography */
  --ot-font-head: 'Space Grotesk', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --ot-font-body: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;

  /* Radius */
  --ot-radius-sm: 8px;
  --ot-radius-md: 12px;
  --ot-radius-lg: 16px;
  --ot-radius-xl: 22px;
  --ot-radius-pill: 999px;

  /* Elevation — one consistent scale, tuned for a light ground */
  --ot-shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.10);
  --ot-shadow-md: 0 2px 6px rgba(15, 23, 42, 0.06), 0 10px 24px -12px rgba(15, 23, 42, 0.18);
  --ot-shadow-lg: 0 8px 20px rgba(15, 23, 42, 0.10), 0 30px 60px -24px rgba(15, 23, 42, 0.28);

  /* Motion — shared rhythm for every surface */
  --ot-dur-fast: 160ms;
  --ot-dur-base: 260ms;
  --ot-dur-slow: 420ms;
  --ot-ease:      cubic-bezier(0.16, 1, 0.3, 1);
  --ot-ease-fast: ease;

  /* Spacing scale (4pt rhythm) — reference, not required everywhere */
  --ot-space-1: 4px;
  --ot-space-2: 8px;
  --ot-space-3: 12px;
  --ot-space-4: 16px;
  --ot-space-5: 24px;
  --ot-space-6: 32px;
  --ot-space-7: 48px;
  --ot-space-8: 64px;

  /* Z-index scale — the only layering values any surface should use */
  --ot-z-base:    1;
  --ot-z-sticky:  20;
  --ot-z-nav:     40;
  --ot-z-overlay: 55;
  --ot-z-drawer:  60;
  --ot-z-modal:   80;
  --ot-z-toast:   100;

  /* Responsive: the one place the sidebar-nav mechanism switches.
     Below this width nav is an overlay drawer; at/above it a persistent
     pinned panel. Kept as a token so every surface agrees. */
  --ot-bp-sidebar: 1024px;

  color-scheme: light;
}

/* ============================================================= *
 *  DARK  (system preference — unless light is forced)            *
 * ============================================================= */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ot-bg:            #0B1220;
    --ot-bg-rgb:        11, 18, 32;
    --ot-bg-subtle:     #070C16;
    --ot-surface:       #131C2E;
    --ot-surface-2:     #1B2540;
    --ot-border:        #2A3651;
    --ot-border-strong: #3B4A6B;

    --ot-text:        #E8EDF6;
    --ot-text-muted:  #9AA7BD;
    --ot-text-subtle: #7E8CA6;

    --ot-accent:       #2563EB;
    --ot-accent-hover: #3B82F6;
    --ot-accent-ink:   #FFFFFF;
    --ot-accent-text:  #93C5FD;
    --ot-accent-soft:  rgba(59, 130, 246, 0.16);
    --ot-accent-line:  rgba(96, 165, 250, 0.45);

    --ot-info:          #2DD4BF;
    --ot-info-soft:     rgba(45, 212, 191, 0.14);
    --ot-accent-2:      #A78BFA;
    --ot-accent-2-soft: rgba(167, 139, 250, 0.14);

    --ot-success:      #4ADE80;
    --ot-success-soft: rgba(74, 222, 128, 0.13);
    --ot-warning:      #FBBF24;
    --ot-warning-soft: rgba(251, 191, 36, 0.13);
    --ot-danger:       #F87171;
    --ot-danger-soft:  rgba(248, 113, 113, 0.14);
    --ot-danger-ink:   #FFFFFF;

    --ot-ring: 0 0 0 3px rgba(96, 165, 250, 0.45);

    --ot-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.40), 0 1px 3px rgba(0, 0, 0, 0.50);
    --ot-shadow-md: 0 2px 6px rgba(0, 0, 0, 0.40), 0 12px 28px -14px rgba(0, 0, 0, 0.60);
    --ot-shadow-lg: 0 10px 26px rgba(0, 0, 0, 0.45), 0 36px 70px -28px rgba(0, 0, 0, 0.70);

    color-scheme: dark;
  }
}

/* ============================================================= *
 *  DARK  (forced via the toggle)                                 *
 * ============================================================= */
:root[data-theme="dark"] {
  --ot-bg:            #0B1220;
  --ot-bg-rgb:        11, 18, 32;
  --ot-bg-subtle:     #070C16;
  --ot-surface:       #131C2E;
  --ot-surface-2:     #1B2540;
  --ot-border:        #2A3651;
  --ot-border-strong: #3B4A6B;

  --ot-text:        #E8EDF6;
  --ot-text-muted:  #9AA7BD;
  --ot-text-subtle: #7E8CA6;

  --ot-accent:       #2563EB;
  --ot-accent-hover: #3B82F6;
  --ot-accent-ink:   #FFFFFF;
  --ot-accent-text:  #93C5FD;
  --ot-accent-soft:  rgba(59, 130, 246, 0.16);
  --ot-accent-line:  rgba(96, 165, 250, 0.45);

  --ot-info:          #2DD4BF;
  --ot-info-soft:     rgba(45, 212, 191, 0.14);
  --ot-accent-2:      #A78BFA;
  --ot-accent-2-soft: rgba(167, 139, 250, 0.14);

  --ot-success:      #4ADE80;
  --ot-success-soft: rgba(74, 222, 128, 0.13);
  --ot-warning:      #FBBF24;
  --ot-warning-soft: rgba(251, 191, 36, 0.13);
  --ot-danger:       #F87171;
  --ot-danger-soft:  rgba(248, 113, 113, 0.14);
  --ot-danger-ink:   #FFFFFF;

  --ot-ring: 0 0 0 3px rgba(96, 165, 250, 0.45);

  --ot-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.40), 0 1px 3px rgba(0, 0, 0, 0.50);
  --ot-shadow-md: 0 2px 6px rgba(0, 0, 0, 0.40), 0 12px 28px -14px rgba(0, 0, 0, 0.60);
  --ot-shadow-lg: 0 10px 26px rgba(0, 0, 0, 0.45), 0 36px 70px -28px rgba(0, 0, 0, 0.70);

  color-scheme: dark;
}

/* ============================================================= *
 *  Bootstrap 5 remap — its grid / components / JS inherit the    *
 *  theme with no Sass build step (public site uses Bootstrap).   *
 * ============================================================= */
:root {
  --bs-body-bg: var(--ot-bg);
  --bs-body-color: var(--ot-text);
  --bs-border-color: var(--ot-border);
  --bs-primary: var(--ot-accent);
  --bs-primary-rgb: 37, 99, 235;
  --bs-danger: var(--ot-danger);
  --bs-danger-rgb: 220, 38, 38;
  --bs-success: var(--ot-success);
  --bs-success-rgb: 21, 128, 61;
  --bs-link-color: var(--ot-accent-text);
  --bs-link-hover-color: var(--ot-accent-hover);
  --bs-font-sans-serif: var(--ot-font-body);
  --bs-border-radius: var(--ot-radius-md);
}

/* ============================================================= *
 *  Global primitives shared by every surface                     *
 * ============================================================= */

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  background-color: var(--ot-bg);
  color: var(--ot-text);
  font-family: var(--ot-font-body);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Headings + amounts use the display face on every surface. Individual
   surfaces may narrow this (e.g. only h1–h3) but the family is one. */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--ot-font-head);
  font-weight: 700;
  letter-spacing: -0.01em;
}
img { max-width: 100%; height: auto; }

/* Focus visibility — a hard accessibility requirement. Restyle, never
   remove. Applied once here for all three surfaces. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--ot-accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Tabular figures for anything money/countdown-shaped */
.ot-figure { font-variant-numeric: tabular-nums; }

/* --- Fluid auto-fill grid -------------------------------------------------
   The column count is a RESULT of available width, never a set of fixed
   breakpoint steps. Consumers set --ot-col-min (and optionally --ot-gap):

     <div class="ot-grid-auto" style="--ot-col-min:180px">…</div>
------------------------------------------------------------------------- */
.ot-grid-auto {
  display: grid;
  gap: var(--ot-gap, 16px);
  grid-template-columns: repeat(auto-fill, minmax(min(var(--ot-col-min, 220px), 100%), 1fr));
}
/* Same, but the last row stretches to fill instead of leaving gaps —
   use for small fixed sets (e.g. 3 service cards) that should still go
   fluid on narrow screens. */
.ot-grid-fluid {
  display: grid;
  gap: var(--ot-gap, 16px);
  grid-template-columns: repeat(auto-fit, minmax(min(var(--ot-col-min, 240px), 100%), 1fr));
}

/* --- Reusable page header ----------------------------------------------
   Every inner page: title + one-line subtitle on the left; on
   money/balance pages a BALANCE pill sits top-right. One component,
   not per-page markup.

     <header class="ot-page-header">
       <div class="ot-page-header__titles">
         <h1 class="ot-page-header__title">Add funds</h1>
         <p class="ot-page-header__sub">Top up your OneTap wallet.</p>
       </div>
       <span class="ot-balance-pill ot-figure">Balance $12.40</span>
     </header>
------------------------------------------------------------------------- */
.ot-page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 24px;
}
.ot-page-header__titles { min-width: 0; }
.ot-page-header__title {
  font-family: var(--ot-font-head);
  font-size: clamp(1.3rem, 1.05rem + 1.1vw, 1.65rem);
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0;
  color: var(--ot-text);
}
.ot-page-header__sub {
  margin: 5px 0 0;
  color: var(--ot-text-muted);
  font-size: 0.92rem;
  line-height: 1.45;
}
.ot-balance-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 15px;
  border-radius: var(--ot-radius-pill);
  background: var(--ot-accent-soft);
  color: var(--ot-accent-text);
  border: 1px solid var(--ot-accent-line);
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.01em;
  white-space: nowrap;
  flex-shrink: 0;
}
.ot-balance-pill svg { width: 15px; height: 15px; }

/* --- Theme control (System / Light / Dark) ---------------------------
   A single button that cycles the three states. Which glyph shows is
   driven by data-theme-pref on <html> (set by theme-toggle.js),
   independent of the RESOLVED light/dark look. */
.ot-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--ot-radius-pill);
  border: 1px solid var(--ot-border);
  background: transparent;
  color: var(--ot-text);
  cursor: pointer;
  transition: border-color var(--ot-dur-fast) var(--ot-ease-fast),
              color var(--ot-dur-fast) var(--ot-ease-fast);
}
.ot-theme-toggle:hover { border-color: var(--ot-accent); color: var(--ot-accent-text); }
.ot-theme-toggle svg { width: 18px; height: 18px; }
/* Default (attribute absent) reads as System. */
.ot-theme-toggle .ot-ti-light,
.ot-theme-toggle .ot-ti-dark { display: none; }
:root[data-theme-pref="light"] .ot-theme-toggle .ot-ti-system,
:root[data-theme-pref="light"] .ot-theme-toggle .ot-ti-dark { display: none; }
:root[data-theme-pref="light"] .ot-theme-toggle .ot-ti-light { display: block; }
:root[data-theme-pref="dark"] .ot-theme-toggle .ot-ti-system,
:root[data-theme-pref="dark"] .ot-theme-toggle .ot-ti-light { display: none; }
:root[data-theme-pref="dark"] .ot-theme-toggle .ot-ti-dark { display: block; }

/* --- Popover menu (the topbar "Language & Theme" dropdown, and any
   other click-to-open menu). Trigger sits in an .ot-menu-wrap; JS toggles
   [data-open] on the .ot-menu and aria-expanded on the trigger. --------- */
.ot-menu-wrap { position: relative; }
.ot-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 244px;
  padding: 8px;
  background: var(--ot-surface);
  border: 1px solid var(--ot-border);
  border-radius: var(--ot-radius-lg);
  box-shadow: var(--ot-shadow-lg);
  z-index: var(--ot-z-modal);
  display: none;
}
.ot-menu[data-open] {
  display: block;
  animation: ot-menu-in var(--ot-dur-fast) var(--ot-ease);
}
@keyframes ot-menu-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
.ot-menu__label {
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ot-text-subtle);
  margin: 8px 8px 6px;
}
.ot-menu__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 4px 8px 10px;
}
.ot-menu__link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 8px;
  border-radius: var(--ot-radius-sm);
  color: var(--ot-text);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
}
.ot-menu__link:hover { background: var(--ot-surface-2); }
.ot-menu__link svg { width: 16px; height: 16px; color: var(--ot-text-muted); }
.ot-menu__sep { height: 1px; background: var(--ot-border); margin: 6px 4px; }

/* Segmented control (e.g. System / Light / Dark). Buttons carry
   aria-pressed; JS keeps exactly one pressed. */
.ot-seg {
  display: inline-flex;
  border: 1px solid var(--ot-border);
  border-radius: var(--ot-radius-pill);
  padding: 2px;
  gap: 2px;
}
.ot-seg button {
  appearance: none;
  border: 0;
  background: transparent;
  color: var(--ot-text-muted);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  padding: 6px 11px;
  min-height: 34px;
  border-radius: var(--ot-radius-pill);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  transition: background var(--ot-dur-fast) var(--ot-ease-fast),
              color var(--ot-dur-fast) var(--ot-ease-fast);
}
.ot-seg button:hover { color: var(--ot-text); }
.ot-seg button[aria-pressed="true"] { background: var(--ot-accent); color: var(--ot-accent-ink); }
.ot-seg button svg { width: 14px; height: 14px; }

/* --- Language switch (EN / FR) — shared markup, see language_switcher() */
.ot-lang-switch {
  display: inline-flex;
  border: 1px solid var(--ot-border);
  border-radius: var(--ot-radius-pill);
  padding: 2px;
  gap: 2px;
}
.ot-lang-btn {
  padding: 5px 11px;
  border-radius: var(--ot-radius-pill);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--ot-text-muted);
  text-decoration: none;
  transition: background var(--ot-dur-fast) var(--ot-ease-fast),
              color var(--ot-dur-fast) var(--ot-ease-fast);
}
.ot-lang-btn:hover { color: var(--ot-text); }
.ot-lang-btn.active { background: var(--ot-accent); color: var(--ot-accent-ink); }

/* --- Reduced motion — honoured globally ------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
