/* LayerOne design tokens — single source of truth (Phase 0 of the frontend overhaul).
   Loaded first in every layout. New components consume these variables so the
   brand, spacing, radius, and type scales stay consistent across the marketing
   site, client area, and admin console. Dark mode is a token swap, not a
   per-component override. */

:root {
  color-scheme: light;

  /* Brand — one hue family across the whole product. Royal blue; the LayerOne
     rebrand moved the whole product off the previous indigo/violet family. */
  --l1-brand: #2563eb;
  --l1-brand-strong: #1d4ed8;
  --l1-brand-soft: #eff4ff;
  --l1-brand-border: #bfd3fe;
  --l1-brand-contrast: #ffffff;

  --l1-accent: #0f9f76;
  --l1-accent-soft: #e6f4f1;

  /* Semantic status. --info is deliberately NOT blue: the brand is blue now, so
     a blue "info" pill was indistinguishable from a brand-coloured one. It sits
     on teal-cyan instead — still cool, still reads as informational, but clearly
     not the brand. Do not move it back to a blue hue. */
  --l1-ok: #0f7a4a;
  --l1-ok-soft: #ecfdf3;
  --l1-warn: #9a5b0a;
  --l1-warn-soft: #fff7ed;
  --l1-danger: #b42318;
  --l1-danger-soft: #fef2f2;
  --l1-info: #0e7490;
  --l1-info-soft: #ecfeff;

  /* Surfaces + text (light) */
  --l1-surface-1: #ffffff;
  --l1-surface-2: #f6f8fc;
  --l1-surface-3: #eef1f7;
  --l1-border: #d9dee8;
  --l1-border-strong: #b8c0cf;
  --l1-ink: #111827;
  --l1-ink-soft: #374151;
  --l1-ink-muted: #6b7280;
  --l1-on-brand: #ffffff;

  /* Spacing scale */
  --l1-space-1: 4px;
  --l1-space-2: 8px;
  --l1-space-3: 12px;
  --l1-space-4: 16px;
  --l1-space-5: 24px;
  --l1-space-6: 32px;
  --l1-space-7: 48px;
  --l1-space-8: 64px;

  /* Radius */
  --l1-radius-sm: 8px;
  --l1-radius-md: 10px;
  --l1-radius-lg: 14px;
  --l1-radius-pill: 999px;

  /* Type scale */
  --l1-text-xs: 0.75rem;
  --l1-text-sm: 0.875rem;
  --l1-text-base: 1rem;
  --l1-text-lg: 1.125rem;
  --l1-text-xl: 1.25rem;
  --l1-text-2xl: 1.5rem;
  --l1-text-3xl: 1.875rem;

  /* Weights (standard steps only) */
  --l1-fw-normal: 400;
  --l1-fw-medium: 500;
  --l1-fw-semibold: 600;
  --l1-fw-bold: 700;

  /* Elevation */
  --l1-shadow-sm: 0 1px 2px rgba(17, 24, 39, 0.06);
  --l1-shadow-md: 0 6px 20px rgba(17, 24, 39, 0.10);
  --l1-shadow-lg: 0 18px 42px rgba(17, 24, 39, 0.16);

  /* Fonts — native system stack, no webfont. This is the Bootstrap 5
     --bs-font-sans-serif list on purpose: Bootstrap is still on the page for its
     classes, and when the body font and Bootstrap's own components disagree the
     mismatch shows up as two slightly different typefaces in the same form.
     Nothing is downloaded, so there is no FOUT and no third-party font request.
     Headings share the body stack — a separate display face (this was Space
     Grotesk) reads as marketing voice on dense console screens. */
  --l1-font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
    "Noto Sans", "Liberation Sans", Arial, sans-serif, "Apple Color Emoji",
    "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
  --l1-font-head: var(--l1-font-body);

  /* Motion */
  --l1-transition: 150ms ease;

  /* Marketing hero band.
     Every public page opens on a dark full-bleed band — homepage hero, inner
     page heroes, the CTA band and .l1-section-dark. That ground was the literal
     #172235 repeated with !important across three marketing layers, so retuning
     it meant finding all six copies; it is a token now so it can be tuned once.

     Lighter and slightly bluer than the #172235 it replaces: hsl(218, 39%, 15%)
     to hsl(220, 45%, 23%). Most of the change is the lightness lift — the hue
     moves under 2 degrees, which is what "slightly more blue" needs, since the
     brand blue does the saturating and the band only has to sit under it.

     --l1-hero-glow-rgb is the corner/beam glow layered over that ground. It was
     rgba(160, 167, 178, …), a neutral grey that lightened the band without
     tinting it. Stored as a bare triple, not a colour, because the six call
     sites each use their own alpha — same reason --bs-primary-rgb is a triple in
     components.css. */
  --l1-hero-ground: #203255;
  --l1-hero-glow-rgb: 125, 168, 232;

  /* The scrim laid over the hero ground, top-to-bottom, so white headline text
     stays legible over the world-map artwork underneath.

     This — not the ground — is what actually decides how dark a hero looks. It
     used to be rgba(16, 21, 34, .66) fading to rgba(12, 14, 24, .88): a
     near-neutral black at up to 88% opacity, which covered the ground almost
     completely. Retuning --l1-hero-ground alone moved the rendered colour barely
     at all, because only 12% of it was showing through at the bottom.

     Both stops are now blue-tinted rather than neutral, and the per-rule alphas
     that consume these were eased back by about a third, so the ground and its
     glow are visible instead of merely present. Keep enough scrim to hold text
     contrast: the hero headline is pure white and the sub is white at 82%. */
  --l1-hero-scrim-top-rgb: 24, 38, 68;
  --l1-hero-scrim-bottom-rgb: 18, 28, 52;

  /* Marketing-specific (not used by app components directly) */
  --l1-primary-glow: rgba(37, 99, 235, 0.16);
  --l1-shadow-soft: var(--l1-shadow-md);
  --l1-shadow-glow: 0 18px 48px rgba(37, 99, 235, 0.16);
  --l1-portal: var(--l1-surface-2);

  /* Marketing compatibility aliases (legacy --l1-* in marketing CSS) */
  --l1-primary: var(--l1-brand);
  --l1-primary-2: var(--l1-brand-strong);
  --l1-primary-dark: #1e3a8a;
  --l1-primary-soft: color-mix(in srgb, var(--l1-brand) 12%, transparent);
  --l1-bg: var(--l1-surface-2);
  --l1-bg-2: var(--l1-surface-1);
  --l1-bg-3: var(--l1-surface-3);
  --l1-surface: var(--l1-surface-1);
  --l1-text: var(--l1-ink);
  --l1-text-muted: var(--l1-ink-muted);
  --l1-text-dim: #7b8494;
  --l1-text-soft: var(--l1-ink-muted);
  --l1-muted: var(--l1-ink-muted);
  --l1-heading-font: var(--l1-font-head);
  --l1-radius: var(--l1-radius-sm);
}

[data-l1-theme="dark"] {
  color-scheme: dark;
  /* Same blue family as light, lifted for contrast against a dark ground. Keep
     the hue in step with light mode — the pre-rebrand theme shifted dark mode a
     hue further into violet than light, and dark pages read as a different
     brand colour than the marketing site. */
  --l1-brand: #60a5fa;
  --l1-brand-strong: #93c5fd;
  --l1-brand-soft: rgba(96, 165, 250, 0.16);
  --l1-brand-border: rgba(96, 165, 250, 0.38);
  --l1-brand-contrast: #0b0f18;

  --l1-accent: #37d4a5;
  --l1-accent-soft: rgba(55, 212, 165, 0.16);

  --l1-ok: #34d399;
  --l1-ok-soft: rgba(52, 211, 153, 0.15);
  --l1-warn: #fbbf24;
  --l1-warn-soft: rgba(251, 191, 36, 0.15);
  --l1-danger: #f87171;
  --l1-danger-soft: rgba(248, 113, 113, 0.15);
  /* Teal-cyan, matching light mode: --info must not collide with the blue brand.
     This was #60a5fa, which is now exactly --l1-brand. */
  --l1-info: #22d3ee;
  --l1-info-soft: rgba(34, 211, 238, 0.15);

  /* Blue-tinted slate. These surfaces are the largest painted area in the
     product, so the cast is deliberately faint — enough that dark pages read as
     part of a blue theme, not enough to compete with the brand accents. Keep it
     subtle; a saturated navy ground makes every status colour vibrate. */
  --l1-surface-1: #191d28;
  --l1-surface-2: #131822;
  --l1-surface-3: #202634;
  --l1-border: rgba(255, 255, 255, 0.13);
  --l1-border-strong: rgba(255, 255, 255, 0.24);
  --l1-ink: #f8fafc;
  --l1-ink-soft: #cbd5e1;
  --l1-ink-muted: #9aa3b2;
  --l1-on-brand: #ffffff;

  --l1-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --l1-shadow-md: 0 6px 20px rgba(0, 0, 0, 0.45);
  --l1-shadow-lg: 0 18px 48px rgba(0, 0, 0, 0.5);

  --l1-primary-glow: rgba(96, 165, 250, 0.22);
  --l1-shadow-soft: 0 18px 48px rgba(0, 0, 0, 0.34);
  --l1-shadow-glow: 0 18px 52px rgba(0, 0, 0, 0.42);
  --l1-portal: #0b0f18;

  --l1-primary: var(--l1-brand);
  --l1-primary-2: var(--l1-brand-strong);
  --l1-primary-dark: #bfdbfe;
  --l1-primary-soft: var(--l1-brand-soft);
  --l1-bg: #0b0f18;
  --l1-bg-2: #121722;
  --l1-bg-3: #191d28;
  --l1-surface: #161b28;
  --l1-text: var(--l1-ink);
  --l1-text-muted: #aab2c0;
  --l1-text-dim: #8b93a1;
  --l1-text-soft: var(--l1-text-muted);
  --l1-muted: var(--l1-text-muted);
}

/* ==========================================================================
   v3 console layer — dense application UI
   --------------------------------------------------------------------------
   The tokens above are shared with the marketing site and must keep their
   current values. Everything below is additive: new primitives that dense
   admin/client surfaces need, plus a console-tuned accent scoped to
   .l1-console-body so public pages keep the existing brand indigo.
   ========================================================================== */

:root {
  /* Control sizing — one ladder for buttons, inputs, selects, pills */
  --l1-control-h-sm: 28px;
  --l1-control-h-md: 34px;
  --l1-control-h-lg: 40px;
  --l1-control-pad-x: 12px;

  /* Data tables */
  --l1-row-h: 44px;
  --l1-row-h-compact: 36px;
  --l1-cell-pad-x: 14px;
  --l1-cell-pad-y: 6px;
  --l1-table-head-h: 36px;

  /* Shell geometry */
  --l1-topbar-h: 52px;
  --l1-sidebar-w: 232px;
  --l1-sidebar-w-collapsed: 60px;
  --l1-content-max: 1440px;
  --l1-content-pad: var(--l1-space-5);

  /* Focus — one visible ring everywhere, never removed without replacement */
  --l1-focus-ring: 0 0 0 3px color-mix(in srgb, var(--l1-brand) 34%, transparent);
  --l1-focus-ring-offset: 1px;

  /* Numeric/identifier text: aligned digits so columns scan vertically */
  --l1-font-data: ui-monospace, "SF Mono", "JetBrains Mono", "Cascadia Mono", Menlo, Consolas, monospace;
  --l1-font-feature-tabular: "tnum" 1, "lnum" 1;

  /* Dense-surface type ramp (smaller than the marketing ramp by design) */
  --l1-text-micro: 0.6875rem;  /* 11px — column heads, meta */
  --l1-text-dense: 0.8125rem;  /* 13px — table cells */
}

/* Console-tuned accent. The marketing royal blue (#2563eb) is deliberately vivid
   for hero surfaces; at admin density it vibrates against white and competes
   with status colors, so the console steps down to a deeper navy. */
.l1-console-body {
  --l1-brand: #1e40af;
  --l1-brand-strong: #1e3a8a;
  --l1-brand-soft: #eef3ff;
  --l1-brand-border: #bfd3fe;

  /* Cooler, flatter neutrals — closer to a dashboard than a landing page.
     Faintly blue-tinted so the console greys sit in the same family as the
     brand rather than reading as a neutral grey app with a blue button. */
  --l1-surface-1: #ffffff;
  --l1-surface-2: #f6f8fc;
  --l1-surface-3: #eceff6;
  --l1-border: #e1e5ee;
  --l1-border-strong: #c6ccdb;
  --l1-ink: #16191f;
  --l1-ink-soft: #3d4450;
  --l1-ink-muted: #667085;

  /* Tighter corners than the marketing site — carried over from the v2
     corporate skin, which this layer absorbed. */
  --l1-radius-sm: 6px;
  --l1-radius-md: 8px;
  --l1-radius-lg: 8px;

  /* Elevation is flat in dense UI; borders do the separating work. */
  --l1-shadow-sm: none;
  --l1-shadow-md: 0 4px 12px rgba(16, 24, 40, 0.08);
  --l1-shadow-lg: 0 12px 32px rgba(16, 24, 40, 0.12);

  /* No font override here anymore: --l1-font-head already resolves to the body
     stack site-wide, so the console no longer has to opt out of a display face. */
}

[data-l1-theme="dark"] .l1-console-body,
[data-l1-theme="dark"] .l1-client-portal-body,
.l1-console-body[data-l1-theme="dark"] {
  color-scheme: dark;
  --l1-brand: #60a5fa;
  --l1-brand-strong: #93c5fd;
  --l1-brand-soft: rgba(96, 165, 250, 0.16);
  --l1-brand-border: rgba(96, 165, 250, 0.38);

  --l1-surface-1: #1b2130;
  --l1-surface-2: #131822;
  --l1-surface-3: #242b3c;
  --l1-border: rgba(255, 255, 255, 0.10);
  --l1-border-strong: rgba(255, 255, 255, 0.18);
  --l1-ink: #f3f4f6;
  --l1-ink-soft: #d1d5db;
  --l1-ink-muted: #9ca3af;
  --l1-shadow-sm: none;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --l1-transition: 0ms;
  }
}

/* ==========================================================================
   Shell neutrals — the Bootstrap decoupling layer.

   shell.css and app.css read ~262 var(--bs-*) values for the console and client
   shell: surfaces, borders, body text. Those resolved from Bootstrap's :root,
   so the shell could not render without Bootstrap on the page.

   These started as Bootstrap's neutral greys lifted verbatim, so the original
   substitution was a provable no-op. The LayerOne rebrand broke that equality on
   purpose: every value here now carries the same faint blue cast as the
   --l1-surface scale, because the shell greys paint the sidebar, topbar and
   table chrome, and leaving them Bootstrap-neutral left a grey frame around a
   blue product. The cast is small (roughly a 6-10 point B channel lift, hue
   only, luminance held) so text contrast ratios are unchanged.

   They are still deliberately NOT folded into the --l1-surface or --l1-ink scales
   (avoid writing a glob-slash pair in a CSS comment — it closes the comment and
   silently turns the rest of this block into parse garbage, which is exactly how
   this section broke the first time). The shell greys and the l1 palette
   genuinely differ (#dde2ec vs #d9dee8, #1b2130 vs
   #111827), and collapsing them is a visual decision, not a refactor. Keeping
   them separate makes the divergence visible and reviewable instead of silently
   restyling every console page in the same commit that removes Bootstrap.
   ========================================================================== */

:root {
  --l1-line: #dde2ec;
  --l1-line-translucent: rgba(0, 0, 0, 0.175);
  --l1-shell-bg: #ffffff;
  --l1-shell-bg-subtle: #f7f9fc;
  --l1-shell-bg-muted: #e8ecf4;
  --l1-shell-hover: #fafbfe;
  --l1-shell-ink: #1b2130;
  --l1-shell-ink-muted: rgba(27, 33, 48, 0.75);
}

[data-l1-theme="dark"] {
  --l1-line: #464f61;
  --l1-line-translucent: rgba(255, 255, 255, 0.15);
  --l1-shell-bg: #1b2130;
  --l1-shell-bg-subtle: #232a3a;
  --l1-shell-bg-muted: #2c3446;
  --l1-shell-hover: #2c3446;
  --l1-shell-ink: #dde2ec;
  --l1-shell-ink-muted: rgba(221, 226, 236, 0.75);
}

/* The dark client portal runs a warmer, deeper palette than the admin console.
   Higher specificity than the block above, so file order does not matter. */
html[data-l1-theme="dark"] .l1-client-portal-body {
  --l1-line: rgba(255, 255, 255, 0.13);
  --l1-line-translucent: rgba(255, 255, 255, 0.1);
  --l1-shell-bg: #191d28;
  --l1-shell-bg-subtle: #131822;
  --l1-shell-bg-muted: #202634;
  --l1-shell-hover: rgba(255, 255, 255, 0.055);
  --l1-shell-ink: #f3f4f6;
  --l1-shell-ink-muted: #aab2c0;
}
