/* 00_tokens.css — Design tokens (single source: styles.py COLORS/COLORS_DARK).
   The dark palette activates via html[data-theme="dark"], stamped by
   assets/theme.js before first paint and kept in sync by a clientside
   callback bound to the persisted theme store. */

:root {
    color-scheme: light;

    /* Backgrounds */
    --bg-page: #ffffff;
    --bg-card: #ffffff;
    --bg-hover: #f5f5f5;
    --bg-green-light: #d4fae8;
    --surface-warm: #fafaf8;

    /* Text */
    --text-primary: #0d0d0d;
    --text-secondary: #333333;
    --text-muted: #737373;
    --text-gray: #6e6e6e;   /* was #888 — now ≥4.5:1 on page AND hover bg */

    /* Brand */
    --brand-green: #1D9E75;
    --brand-green-accent: #18E299;   /* data viz / highlights only */
    --brand-green-deep: #0fa76e;
    --brand-green-hover: #168a63;
    --brand-navy: #1e293b;

    /* Text-context (WCAG AA) variants. Contrast is symmetric, so each token
       works both as text on light surfaces AND as a solid fill under
       --on-fill / white text (≥4.5 at 14px). --brand-green itself stays the
       brand fill/border color (identity); never use it for normal-size text. */
    --brand-green-text: #0C7A57;      /* 5.33 white / 4.89 hover / 4.73 green-light */
    --brand-green-fill: #157F5E;      /* green button/pill surface, white text → 4.97 */
    --brand-green-fill-hover: #0C7A57;
    --error-text: #b33a3a;            /* 5.86 on white, also fill under white text */
    --success-text: #047857;          /* 5.48 on white */
    --warning-text: #92400e;          /* 7.09 on white */

    /* Ink for solid fills — flips per theme so light fills carry dark text
       (e.g. dark-mode primary buttons = bright green + near-black label) */
    --on-fill: #ffffff;
    --on-bright: #0d1117;             /* theme-invariant dark ink for bright 3rd-party fills */

    /* Semantic */
    --success: #059669;
    --success-light: #d4fae8;
    --error: #d45656;
    --trust-blue: #1e40af;

    /* Borders */
    --border: rgba(0, 0, 0, 0.05);
    --border-medium: rgba(0, 0, 0, 0.08);
    --border-opaque: #e8e8e8;

    /* Logo knockout (bowl cutout of the R mark) */
    --logo-cutout: #ffffff;

    /* Third-party share-button brand colors (theme-invariant) */
    --share-linkedin: #0A66C2;
    --share-whatsapp: #25D366;

    /* On-primary (white text on brand/semantic fills; theme-invariant) */
    --on-primary: #ffffff;

    /* Warning amber (alert-warning, wordmark gradient stop) */
    --warning: #D97706;

    /* Wordmark gradient stops (brand.py lockup, sidebar divider) */
    --brand-teal: #0F766E;
    --brand-teal-deep: #115E59;

    /* RGB channels of semantic colors — compose alpha via
       rgb(var(--brand-green-rgb) / 0.15) instead of duplicating rgba literals */
    --brand-green-rgb: 29 158 117;
    /* #18E299 is theme-invariant (same in the dark block), so this channel
       var lives on :root only. Data-viz use only (landing preview bars). */
    --brand-green-accent-rgb: 24 226 153;
    --error-rgb: 212 86 86;
    --success-rgb: 5 150 105;

    /* Radius scale (DESIGN.md shapes: 8 inputs, 16 cards, 24 hero boxes, pill) */
    --radius-sm: 8px;
    --radius-md: 16px;
    --radius-lg: 24px;
    --radius-pill: 9999px;

    /* Elevation (DESIGN.md levels 1-4; dark theme overrides below) */
    --shadow-1: 0 2px 4px rgba(0, 0, 0, 0.03);    /* cards */
    --shadow-2: 0 4px 12px rgba(0, 0, 0, 0.08);   /* hover-lift */
    --shadow-3: 0 4px 24px rgba(0, 0, 0, 0.06);   /* auth/modal */
    --shadow-4: 0 8px 30px rgba(0, 0, 0, 0.12);   /* popovers, hero preview */

    /* Focus ring — single source for the brand-green halo on interactive
       controls (replaces 13 duplicated rgba(29,158,117,…) literals) */
    --focus-ring: 0 0 0 3px rgb(var(--brand-green-rgb) / 0.15);

    /* Motion */
    --dur-fast: 150ms;
    --dur-base: 200ms;
    --ease-standard: ease;
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);

    /* Typography scale — px-named, rem-based so it follows the user's
       browser font-size preference. Every legacy font-size literal maps to
       one of these with <=1px deviation at the 16px root (audit table in
       docs/ui-visual-redesign-plan.md §Phase 2). */
    --fs-3xs: 0.6875rem;      /* 11 */
    --fs-2xs: 0.75rem;        /* 12 */
    --fs-xs:  0.8125rem;      /* 13 */
    --fs-sm:  0.875rem;       /* 14 */
    --fs-md:  0.9375rem;      /* 15 */
    --fs-lg:  1rem;           /* 16 */
    --fs-xl:  1.0625rem;      /* 17 */
    --fs-2xl: 1.1875rem;      /* 19 */
    --fs-3xl: 1.25rem;        /* 20 */
    --fs-4xl: 1.375rem;       /* 22 */
    --fs-5xl: 1.5rem;         /* 24 */
    --fs-6xl: 1.625rem;       /* 26 */
    --fs-7xl: 1.75rem;        /* 28 */
    --fs-8xl: 1.875rem;       /* 30 */
    --fs-9xl: 2rem;           /* 32 */
    --fs-10xl: 2.125rem;      /* 34 */
    --fs-display-sm: 2.5rem;  /* 40 */
    --fs-display: 2.625rem;   /* 42 */

    /* Line height (unitless multipliers that appeared as literals) */
    --lh-tight: 1.1;
    --lh-snug: 1.3;
    --lh-ui: 1.4;
    --lh-normal: 1.5;
    --lh-relaxed: 1.6;

    /* Font weights */
    --fw-regular: 400;
    --fw-medium: 500;
    --fw-semibold: 600;
    --fw-bold: 700;
    --fw-extrabold: 800;

    /* Form-field system — one recipe shared by .text-input,
       .dash-dropdown .Select-control and .DateInput (border, radius,
       hover/focus borders, transition). Composed fields
       (.report-search-input, .plans-quota-input) inherit via .text-input. */
    --field-border: 1.5px solid var(--border-opaque);
    --field-radius: var(--radius-sm);
    --field-hover-border: var(--text-muted);
    --field-focus-border: var(--brand-green);
    --field-transition: border-color var(--dur-base) var(--ease-standard),
                         box-shadow var(--dur-base) var(--ease-standard);

    /* Spacing scale (theme-invariant, so it is defined here only and never
       redefined in the dark block). Every vertical rhythm value added from
       here on should come from this scale instead of a bare px literal. */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 24px;
    --space-6: 32px;
    --space-7: 48px;
}

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

    /* Backgrounds */
    --bg-page: #121212;
    --bg-card: #1e1e1e;
    --bg-hover: #2a2a2a;
    --bg-green-light: #0d2818;
    --surface-warm: #1a1a18;

    /* Text */
    --text-primary: #e8e8e8;
    --text-secondary: #cccccc;
    --text-muted: #a0a0a0;
    --text-gray: #8a8a8a;

    /* Brand */
    --brand-green: #1D9E75;
    --brand-green-accent: #18E299;
    --brand-green-deep: #22b985;
    --brand-green-hover: #25c48e;
    --brand-navy: #94a3b8;

    /* Text-context variants (AA on #121212/#1e1e1e). Fills flip to bright
       green + dark ink: white on #1D9E75/#22b985 fails AA at small sizes. */
    --brand-green-text: #1D9E75;      /* 5.53 page / 4.92 card */
    --brand-green-fill: #25c48e;      /* dark text → 8.67 */
    --brand-green-fill-hover: #34d399;
    --error-text: #f87171;            /* 6.03 on card */
    --success-text: #34d399;          /* 8.67 on card */
    --warning-text: #f59e0b;          /* 7.76 on card */
    --on-fill: #0d0d0d;

    /* Semantic */
    --success: #34d399;
    --success-light: #0d2818;
    --error: #f87171;
    --trust-blue: #60a5fa;

    /* Borders */
    --border: rgba(255, 255, 255, 0.08);
    --border-medium: rgba(255, 255, 255, 0.12);
    --border-opaque: #333333;

    --logo-cutout: #1e1e1e;

    /* Warning amber needs to lighten for contrast on dark surfaces */
    --warning: #f59e0b;

    /* Teal gradient stops lighten so the wordmark/divider stays visible */
    --brand-teal: #2aa79b;
    --brand-teal-deep: #1f7a70;

    /* RGB channels follow the dark palette */
    --error-rgb: 248 113 113;
    --success-rgb: 52 211 153;

    /* Dark-mode elevation: shadows must be deeper to read on dark surfaces */
    --shadow-1: 0 2px 4px rgba(0, 0, 0, 0.30);
    --shadow-2: 0 4px 12px rgba(0, 0, 0, 0.45);
    --shadow-3: 0 4px 24px rgba(0, 0, 0, 0.40);
    --shadow-4: 0 8px 30px rgba(0, 0, 0, 0.50);

    /* Dash 4.4 component design tokens. dcc.Dropdown (Radix) and
       dcc.DatePickerSingle render with these `--Dash-*` variables, whose light
       defaults (`--Dash-Fill-Inverse-Strong: #fff`, dark navy text) leave the
       select/date boxes and popups WHITE with near-white text in dark mode —
       illegible. Remap them to the dark palette so those controls follow the
       theme (dark box + near-white text). This themes every dcc control at once;
       no per-class overrides needed. */
    --Dash-Fill-Inverse-Strong: var(--bg-card);      /* trigger + popup surface */
    --Dash-Text-Strong: var(--text-primary);         /* value text, caret icon */
    --Dash-Text-Primary: var(--text-primary);        /* option / day text */
    --Dash-Text-Weak: var(--text-muted);             /* placeholder / muted */
    --Dash-Text-Disabled: var(--text-gray);
    --Dash-Stroke-Strong: var(--border-opaque);      /* control border */
    --Dash-Stroke-Weak: var(--border-medium);
    --Dash-Fill-Interactive-Strong: var(--brand-green);  /* selected accent (was purple) */
    --Dash-Fill-Primary-Hover: rgb(var(--brand-green-rgb) / 0.12);
    --Dash-Fill-Primary-Active: rgb(var(--brand-green-rgb) / 0.20);
    --Dash-Fill-Disabled: rgba(255, 255, 255, 0.06);
    --Dash-Shading-Strong: rgba(0, 0, 0, 0.60);      /* popup drop shadow */
    --Dash-Shading-Weak: rgba(0, 0, 0, 0.40);
}

/* Theme visibility helpers: the toggle shows the label of the TARGET mode */
.theme-label-to-light { display: none; }
.theme-label-to-dark { display: inline; }
html[data-theme="dark"] .theme-label-to-light { display: inline; }
html[data-theme="dark"] .theme-label-to-dark { display: none; }
/* Same mechanism for the icon-only toggle (conversion declutter): moon in
   light mode (target = dark), sun in dark mode (target = light). */
.theme-icon-to-light { display: none; }
.theme-icon-to-dark { display: inline-flex; }
html[data-theme="dark"] .theme-icon-to-light { display: inline-flex; }
html[data-theme="dark"] .theme-icon-to-dark { display: none; }
