/* tokens.css — the single source of truth for design values.
   ============================================================================

   HOW THIS FILE IS MEANT TO BE USED
   ---------------------------------
   Load this FIRST on every page, before that page's own stylesheet:

       <link rel="stylesheet" href="../css/tokens.css">
       <link rel="stylesheet" href="../css/dashboard.css">   <- page CSS wins

   Because both this file and the page stylesheets declare their values on
   :root, the one that loads LAST wins. Page CSS loads last, so adding this
   file changes nothing on screen. It sits underneath as a fallback layer.

   A page adopts these tokens by DELETING its own :root block. At that moment
   the page falls through to the values here. That is the migration step, and
   it is done one page at a time so any regression is contained to one file.

   WHAT'S IN HERE
   --------------
   1. Primitives      — raw colour ramps, nothing semantic
   2. Semantic tokens — surface/text/border roles that components should use
   3. Scales          — spacing, radius, shadow, type, motion, z-index
   4. Legacy aliases  — the old per-page variable names, mapped onto the above
                        so a page keeps rendering after its :root is removed
   5. Dark theme      — OPT-IN ONLY, see the note above section 5

   KNOWN CONFLICTS TO RESOLVE DURING MIGRATION
   -------------------------------------------
   These names mean different things on different pages today. The canonical
   value is chosen below; the listed pages will shift when they migrate, so
   check them visually at that point.

     --radius-sm/md/lg/xl   dashboard uses 8/12/16/24px, vendor uses 4/6/8/12px.
                            Canonical is the middle ground (6/8/12/16). Vendor
                            corners get slightly rounder, dashboard slightly
                            tighter. Migrate vendor.css LAST.

     --primary-color        profile.css #667eea vs user-guide.css #4361ee.
                            Canonical is the brand indigo. Both pages shift.

     --warning-color        user-guide.css has it as pink #f72585, identical to
     --danger-color         its danger colour. That looks like an original bug;
                            canonical splits them back into amber and red.

   ========================================================================== */


/* ============================================================================
   1. PRIMITIVES — raw ramps. Prefer the semantic tokens in section 2 over
   reaching for these directly in component CSS.
   ========================================================================== */

:root {
    /* --- Brand: indigo. Anchored on #1a237e, the colour the dashboard, the
       invoice form and the vendor form already share. --- */
    --primary-50:  #e8eaf6;
    --primary-100: #c5cae9;
    --primary-200: #9fa8da;
    --primary-300: #7986cb;
    --primary-400: #5c6bc0;
    --primary-500: #3f51b5;
    --primary-600: #3949ab;
    --primary-700: #303f9f;
    --primary-800: #283593;
    --primary-900: #1a237e;   /* the brand colour */
    --primary-950: #0d1b5c;

    /* --- Accent: azure. Used for links, focus rings and secondary actions. ---

       NOTE: --accent-50 is deliberately NOT defined here. vendor.css declares it
       only inside its @media (prefers-color-scheme: dark) block (line ~1351) yet
       USES it in light-mode rules (.vendor-docs-badge background, line ~369, and
       .invoice-link:hover, line ~865). In light mode it therefore resolves to
       nothing today and those two elements render with no background. Defining
       it here would silently give them a blue fill — a real visual change, which
       Phase 1 is not allowed to make.

       Same story for --accent-200, --danger-200 and --danger-300: used by
       vendor.css/entity.css, declared nowhere. Left undefined on purpose.

       Fix these in the vendor.css migration step, deliberately and visibly. */
    --accent-100: #bbdefb;
    --accent-400: #42a5f5;
    --accent-500: #1e88e5;
    --accent-600: #1565c0;   /* dashboard's --color-accent */
    --accent-700: #0d47a1;

    /* --- Neutral: cool gray. Carried over from vendor.css unchanged, so that
       file's greys are unaffected when it migrates. --- */
    --gray-50:  #f9fafb;
    --gray-100: #f3f4f6;
    --gray-200: #e5e7eb;
    --gray-300: #d1d5db;
    --gray-400: #9ca3af;
    --gray-500: #6b7280;
    --gray-600: #4b5563;
    --gray-700: #374151;
    --gray-800: #1f2937;
    --gray-900: #111827;

    /* --- Semantic ramps. Each has a tint (50/100) for backgrounds, a mid for
       fills, and a dark (600/700) that clears 4.5:1 contrast on its own tint. --- */
    --success-50:  #ecfdf5;
    --success-100: #d1fae5;
    --success-500: #10b981;
    --success-600: #0b6e4f;
    --success-700: #0a5c42;

    --warning-50:  #fffbeb;
    --warning-100: #fef3c7;
    --warning-500: #f59e0b;
    --warning-600: #b45309;
    --warning-700: #92400e;

    --danger-50:  #fef2f2;
    --danger-100: #fee2e2;
    --danger-500: #ef4444;
    --danger-600: #b91c1c;
    --danger-700: #991b1b;

    --info-50:  #eff6ff;
    --info-100: #dbeafe;
    --info-500: #3b82f6;
    --info-600: #2563eb;
    --info-700: #1d4ed8;
}


/* ============================================================================
   2. SEMANTIC TOKENS — what a colour is FOR, not what it looks like.
   These are the ones the dark theme in section 5 flips.
   ========================================================================== */

:root {
    /* Surfaces, from furthest back to furthest forward */
    --surface-body:     var(--gray-50);
    --surface-default:  #ffffff;
    --surface-raised:   #ffffff;
    --surface-sunken:   var(--gray-100);
    --surface-hover:    var(--gray-100);
    --surface-active:   var(--gray-200);
    --surface-overlay:  rgba(15, 23, 42, 0.55);   /* modal scrim */

    /* Text, from loudest to quietest */
    --text-strong:   var(--gray-900);
    --text-default:  var(--gray-700);
    --text-muted:    var(--gray-500);
    --text-subtle:   var(--gray-400);
    --text-on-brand: #ffffff;

    /* Lines */
    --border-subtle: var(--gray-200);
    --border-default: var(--gray-300);
    --border-strong: var(--gray-400);

    /* Interactive */
    --focus-ring: var(--accent-600);

    /* Tells the browser which palette to render NATIVE UI with: the select
       dropdown arrow and its option list, the date picker icon and calendar
       popup, scrollbars, spin buttons, and the default caret. Without this the
       computed value is `normal`, so those parts stay light even when the field
       behind them is dark — visible as a washed-out arrow on a dark select. */
    color-scheme: light;
}


/* ============================================================================
   3. SCALES
   ========================================================================== */

:root {
    /* --- Spacing. Two naming families are kept because both are in active use:
       the t-shirt sizes (dashboard, forms) and the numeric steps (vendor).
       They resolve to the same underlying 4px grid. --- */
    --space-1:  0.25rem;   /*  4px */
    --space-2:  0.5rem;    /*  8px */
    --space-3:  0.75rem;   /* 12px */
    --space-4:  1rem;      /* 16px */
    --space-5:  1.25rem;   /* 20px */
    --space-6:  1.5rem;    /* 24px */
    --space-8:  2rem;      /* 32px */
    --space-10: 2.5rem;    /* 40px */
    --space-12: 3rem;      /* 48px */
    --space-16: 4rem;      /* 64px */

    --spacing-xxs: var(--space-1);
    --spacing-xs:  var(--space-2);
    --spacing-sm:  var(--space-4);
    --spacing-md:  var(--space-6);
    --spacing-lg:  var(--space-8);
    --spacing-xl:  var(--space-12);
    --spacing-xxl: var(--space-16);

    /* --- Radius. Middle ground between the dashboard and vendor scales;
       see the conflict note in the file header. --- */
    --radius-xs:   4px;
    --radius-sm:   6px;
    --radius-md:   8px;
    --radius-lg:   12px;
    --radius-xl:   16px;
    --radius-2xl:  24px;
    --radius-full: 9999px;

    /* --- Elevation. Tinted with the neutral hue rather than pure black, which
       keeps shadows from looking muddy over coloured surfaces. --- */
    --shadow-xs: 0 1px 2px rgba(16, 24, 40, 0.05);
    --shadow-sm: 0 2px 6px rgba(16, 24, 40, 0.07);
    --shadow-md: 0 6px 18px rgba(16, 24, 40, 0.09);
    --shadow-lg: 0 12px 32px rgba(16, 24, 40, 0.12);
    --shadow-xl: 0 20px 50px rgba(16, 24, 40, 0.16);
    --shadow-inner: inset 0 2px 4px rgba(16, 24, 40, 0.04);

    /* --- Typography --- */
    --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
                 Helvetica, Arial, sans-serif;
    --font-mono: 'JetBrains Mono', 'SF Mono', 'Cascadia Code', Consolas,
                 'Courier New', monospace;

    --text-xs:   0.75rem;    /* 12px */
    --text-sm:   0.875rem;   /* 14px */
    --text-base: 1rem;       /* 16px */
    --text-lg:   1.125rem;   /* 18px */
    --text-xl:   1.25rem;    /* 20px */
    --text-2xl:  1.5rem;     /* 24px */
    --text-3xl:  1.875rem;   /* 30px */
    --text-4xl:  2.25rem;    /* 36px */

    --weight-normal:   400;
    --weight-medium:   500;
    --weight-semibold: 600;
    --weight-bold:     700;

    --leading-tight:  1.25;
    --leading-normal: 1.5;
    --leading-loose:  1.7;

    /* --- Motion --- */
    --ease: cubic-bezier(0.4, 0, 0.2, 1);
    --transition-fast: 150ms var(--ease);
    --transition-base: 200ms var(--ease);
    --transition-slow: 300ms var(--ease);

    /* --- Stacking. Anything positioned should pull from here rather than
       inventing a number, which is how z-index wars start. --- */
    --z-base:      1;
    --z-dropdown:  100;
    --z-sticky:    200;
    --z-drawer:    900;
    --z-overlay:   1000;
    --z-modal:     1000;
    --z-modal-top: 1100;
    --z-popover:   2000;
    --z-toast:     2500;
    --z-tooltip:   3000;

    /* --- Layout --- */
    --container-max: 1280px;
    --sidebar-width: 260px;
    --sidebar-width-collapsed: 72px;
    --header-height: 64px;
}


/* ============================================================================
   4. LEGACY ALIASES
   The variable names each page invented, pointed at the canonical values above.
   These exist so a page keeps rendering the moment its own :root is deleted.
   As pages are rewritten onto the semantic tokens, entries here get retired.
   ========================================================================== */

:root {
    /* --- dashboard.css / invoiceUpload.css / vendor-create.css --- */
    --color-primary:       var(--primary-900);
    --color-primary-dark:  var(--primary-950);
    --color-primary-light: #534bae;
    --color-secondary:     #455a64;
    --color-accent:        var(--accent-600);
    --color-accent-light:  #5e92f3;

    --color-success:        var(--success-600);
    --color-success-light:  var(--success-500);
    --color-success-bg:     var(--success-50);
    --color-success-border: #a7dcb8;
    --color-warning:        var(--warning-600);
    --color-warning-light:  var(--warning-500);
    --color-warning-bg:     var(--warning-50);
    --color-warning-border: #f3c98b;
    --color-danger:         var(--danger-600);
    --color-danger-light:   var(--danger-500);
    --color-danger-bg:      var(--danger-50);
    --color-danger-border:  #f2b8b5;
    --color-info:           var(--info-600);
    --color-info-light:     var(--info-500);
    --color-info-bg:        var(--info-50);
    --color-info-border:    #a5d9df;

    --color-light:      var(--gray-100);
    --color-light-gray: var(--gray-200);
    --color-gray:       var(--gray-400);
    --color-dark-gray:  var(--gray-600);
    --color-dark:       var(--gray-900);
    --color-text:       var(--text-default);

    --bg-primary:   var(--surface-default);
    --bg-secondary: var(--gray-50);
    --bg-card:      var(--surface-default);
    --bg-hover:     var(--surface-hover);
    --bg-modal:     var(--surface-overlay);

    --font-family: var(--font-sans);

    --font-size-xs:   var(--text-xs);
    --font-size-sm:   var(--text-sm);
    --font-size-base: var(--text-base);
    --font-size-lg:   var(--text-lg);
    --font-size-xl:   var(--text-xl);
    --font-size-2xl:  var(--text-2xl);
    --font-size-3xl:  var(--text-3xl);
    --font-size-4xl:  var(--text-4xl);

    /* --- vendor.css --- */
    --bg-body:           var(--surface-body);
    --bg-surface:        var(--surface-default);
    --bg-surface-hover:  var(--surface-hover);
    --bg-surface-active: var(--surface-active);
    --border-light:      var(--border-subtle);
    --border-medium:     var(--border-default);
    --accent-400-legacy: #2c7a7a;   /* vendor's teal, retained for reference */

    /* --- entity.css --- */
    --entity-ink:          var(--gray-900);
    --entity-muted:        var(--gray-500);
    --entity-muted-soft:   var(--gray-400);
    --entity-line:         var(--border-subtle);
    --entity-line-strong:  var(--border-default);
    --entity-surface:      var(--surface-default);
    --entity-surface-alt:  var(--gray-50);
    --entity-surface-tint: var(--primary-50);
    --entity-brand:        var(--primary-900);
    --entity-brand-strong: var(--primary-950);
    --entity-brand-soft:   rgba(26, 35, 126, 0.12);
    --entity-success-bg:   var(--success-50);
    --entity-success-fg:   var(--success-600);
    --entity-warning-bg:   var(--warning-50);
    --entity-warning-fg:   var(--warning-600);
    --entity-danger-bg:    var(--danger-50);
    --entity-danger-fg:    var(--danger-600);
    --entity-shadow-sm:    var(--shadow-md);
    --entity-shadow-md:    var(--shadow-lg);

    /* --- user-management.css --- */
    --bg:            var(--surface-body);
    --card:          var(--surface-default);
    --text:          var(--text-strong);
    --muted:         var(--text-muted);
    --accent:        var(--accent-600);
    --accent-dark:   var(--accent-700);
    --accent-light:  #dbeafe;   /* literal: --accent-50 is intentionally undefined, see section 1 */
    --accent-hover:  var(--accent-700);
    --danger:        var(--danger-600);
    --danger-light:  var(--danger-100);
    --danger-hover:  var(--danger-700);
    --success:       var(--success-600);
    --success-light: var(--success-100);
    --success-hover: var(--success-700);
    --warning:       var(--warning-600);
    --warning-light: var(--warning-100);
    --border:        var(--border-subtle);
    --border-hover:  var(--border-default);
    --radius:        var(--radius-md);

    /* --- profile.css / user-guide.css --- */
    --primary-color:   var(--primary-900);
    --primary-dark:    var(--primary-950);
    --secondary-color: #764ba2;
    --text-primary:    var(--text-strong);
    --text-secondary:  var(--text-default);
    --border-color:    var(--border-subtle);
    --bg-light:        var(--gray-50);
    --bg-white:        var(--surface-default);
    --success-color:   var(--success-600);
    --success-bg:      var(--success-50);
    --error-color:     var(--danger-600);
    --error-bg:        var(--danger-50);
    --warning-color:   var(--warning-600);
    --info-color:      var(--info-600);
    --light-color:     var(--gray-50);
    --dark-color:      var(--gray-900);
    --gray-color:      var(--gray-500);
    --light-gray:      var(--gray-200);
    --border-radius:   var(--radius-md);
    --box-shadow:      var(--shadow-md);
    --transition:      all var(--transition-base);
}


/* ============================================================================
   5. DARK THEME — OPT-IN ONLY.

   Deliberately gated behind an explicit attribute rather than
   @media (prefers-color-scheme: dark). Four stylesheets already ship their own
   prefers-color-scheme blocks and the other eight do not; wiring dark mode to
   the OS here would flip those four out from under their own rules and drag
   the other eight halfway into a dark theme they were never designed for.

   Turn it on per page with <html data-theme="dark">, once every page has a
   theme toggle and has been checked. Until then this block never matches.
   ========================================================================== */

:root[data-theme="dark"] {
    /* Switches native UI (select arrow and option list, date picker and its
       calendar popup, scrollbars, spin buttons) to the dark palette. Without it
       those render light on top of dark fields. */
    color-scheme: dark;

    --surface-body:    #0f141f;
    --surface-default: #161d2b;
    --surface-raised:  #1d2637;
    --surface-sunken:  #0b0f18;
    --surface-hover:   #222c40;
    --surface-active:  #2b3750;
    --surface-overlay: rgba(3, 6, 12, 0.7);

    --text-strong:  #f3f4f6;
    --text-default: #d1d5db;
    --text-muted:   #9ca3af;
    --text-subtle:  #6b7280;

    --border-subtle:  #263043;
    --border-default: #33415a;
    --border-strong:  #47566f;

    /* Brand lightens in dark mode — #1a237e on a dark surface is unreadable. */
    --primary-900: #8b95e8;
    --primary-950: #6f7ade;
    --accent-600:  #60a5fa;

    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-sm: 0 2px 6px rgba(0, 0, 0, 0.45);
    --shadow-md: 0 6px 18px rgba(0, 0, 0, 0.5);
    --shadow-lg: 0 12px 32px rgba(0, 0, 0, 0.55);
    --shadow-xl: 0 20px 50px rgba(0, 0, 0, 0.6);
}


/* ============================================================================
   6. ACCESSIBILITY BASELINE
   The one thing this file does beyond declaring variables. A visible focus
   ring is load-bearing for keyboard users and only four of the twelve
   stylesheets currently define one, so it is set globally here.

   :focus-visible only matches keyboard focus, so this never puts a ring around
   a clicked button. Page CSS still loads after and can override per component.
   ========================================================================== */

:focus-visible {
    outline: 2px solid var(--focus-ring);
    outline-offset: 2px;
    border-radius: 2px;
}

@media (prefers-reduced-motion: reduce) {
    :root {
        --transition-fast: 1ms linear;
        --transition-base: 1ms linear;
        --transition-slow: 1ms linear;
    }
}
