﻿/* ===== SabrePM theme tokens =====
   The single design-token vocabulary for the App and Platform web clients (App Theme Manager
   design note, docs/design-notes/app-theme-manager-design-note.md). Served from the
   Sabre.Shared.Web RCL as _content/Sabre.Shared.Web/css/theme-tokens.css and linked by every
   host page BEFORE site.css, so component CSS may reference any token here without a fallback.

   Rules
   - Component CSS (.razor.css, SabrePM.styles.css, site.css) references tokens; it does not
     define colours. A hex literal in component CSS is a defect unless it is one of the listed
     exceptions at the bottom of this file. ThemeTokenFitnessTests enforces both.
   - Values here are the defaults SabrePM ships with, and they are the exact output of
     ThemeCssBuilder.BuildLight(SabreDefaultTheme) — derived shades included. ThemeTokenFitnessTests
     asserts that parity, so a page with no theme applied and a page running the default theme look
     identical. Change a default in SabreDefaultTheme, then copy the builder's output here.
   - At runtime the theme manager writes the tenant/environment-resolved values onto <html> as
     inline custom properties, which outrank everything in this file.
   - Keep the vocabulary small and semantic. Add a token only when a new *role* appears,
     never for a one-off shade.
   Public (Sabre.App.Web.Public) and Mobile keep their own copies of the chrome tokens because
   neither references Sabre.Shared.Web. */
:root {
    /* --- Chrome: the dark header / footer bars (every layout, portal and the help system) --- */
    --sabre-chrome-bg: #141417;
    --sabre-chrome-fg: #ffffff;
    --sabre-chrome-fg-muted: #adadae;
    --sabre-chrome-border: rgba(255, 255, 255, 0.10);
    --sabre-chrome-hover: color-mix(in srgb, var(--sabre-chrome-fg) 14%, transparent);   /* hover and track on the bar */
    --sabre-chrome-link: color-mix(in srgb, var(--sabre-chrome-fg) 70%, var(--gnt-primary-color));  /* a link on the bar */

    /* --- Surfaces --- */
    --gnt-surface-color: #ffffff;      /* page / panel / dialog background */
    --gnt-surface-2: #f8fafc;          /* alternate rows, sub-panels, sticky headers */

    /* --- Text --- */
    --gnt-text-color: #172033;         /* body text */
    --gnt-text-strong: #111826;        /* headings, emphasised values */
    --gnt-text-secondary: #3a465b;     /* labels, captions */
    --gnt-text-tertiary: #515f75;      /* de-emphasised copy */
    --gnt-muted-color: #64748b;        /* hints, placeholders, meta */
    --gnt-muted-text: #556379;         /* muted copy on tinted panels */
    --gnt-text-faint: #a2acb9;         /* disabled / faint */
    --gnt-text-inverse: #ffffff;       /* text on primary / danger / chrome fills */

    /* --- Borders --- */
    --gnt-border-color: #cbd5e1;       /* standard hairline */
    --gnt-border-soft: #dde4ec;        /* panel and card edges */
    --gnt-border-light: #eaeef3;       /* dividers inside a surface */
    --gnt-border: var(--gnt-border-light);

    /* --- Primary --- */
    --gnt-primary-color: #2f6fed;
    --gnt-primary-strong: #275bc2;     /* text/links on a primary tint, hover */
    --gnt-primary-tint: #eef3fe;       /* highlighted rows and callouts */
    --gnt-primary-border: #a1bef7;
    --gnt-primary-text: #214ea6;       /* text on a primary tint */
    --gnt-focus-color: #2f6fed;        /* focus rings and outlines */
    --gnt-accent-color: #3b82f6;       /* secondary emphasis, markers */

    /* --- Selection (grid rows, active tabs) --- */
    --gnt-selected-bg: #dbeafe;
    --gnt-selected-fg: #111827;
    --gnt-selected-border: #8eb3f6;

    /* --- Semantic. Every intent has the same five slots: color (fill), strong (hover), text (on a
       tint), tint and border. Pick an intent and a slot, never a shade. --- */
    --gnt-danger-color: #dc2626;
    --gnt-danger-strong: #b41f1f;
    --gnt-danger-text: #9a1b1b;
    --gnt-danger-tint: #fdf2f2;
    --gnt-danger-border: #f2adad;
    --gnt-success-color: #166534;
    --gnt-success-strong: #12532b;     /* hover on a success fill */
    --gnt-success-text: #0f4724;       /* text on a success tint */
    --gnt-success-tint: #f1f6f3;       /* "will be created" rows, calm banners */
    --gnt-success-border: #a6c4b2;
    --gnt-warning-color: #b7791f;
    --gnt-warning-strong: #966319;     /* hover on a warning fill */
    --gnt-warning-text: #805516;       /* text on a warning tint */
    --gnt-trial-accent: #ffce54;       /* the trial banner: amber in every theme, it is a state not a surface */
    --gnt-trial-accent-strong: #f5b800;/* its hover */
    --gnt-trial-on-accent: #1a1a1a;    /* text on the trial fill */
    --gnt-warning-tint: #f6efe4;       /* "will be changed" rows, acknowledged alerts */
    --gnt-warning-border: #e4ccaa;
    --gnt-info-color: #0e7490;
    --gnt-info-strong: #0b5f76;        /* hover on an info fill */
    --gnt-info-text: #0a5165;          /* text on an info tint */
    --gnt-info-tint: #f1f7f8;          /* "review this" rows — duplicates, soft issues */
    --gnt-info-border: #a3cad5;
    --gnt-neutral-color: #64748b;      /* the grey intent: draft, inactive, n/a */
    --gnt-neutral-strong: #525f72;
    --gnt-neutral-text: #465161;
    --gnt-neutral-tint: #f6f7f8;
    --gnt-neutral-border: #c4cad3;

    /* --- Status semantics (Lookup Role = Status). Chips, Gantt bars, kanban columns. --- */
    --gnt-status-open: #2f6fed;
    --gnt-status-inprogress: #b7791f;
    --gnt-status-complete: #166534;
    --gnt-status-onhold: #64748b;
    --gnt-status-cancelled: #dc2626;

    /* --- Designer / wizard accent ---
       The teal identity of the step wizards and the Record Template designer: hover and selected
       state on their own chrome, deliberately not the primary blue so a designer surface reads as
       a workspace rather than a form. A token rather than a literal so it follows dark mode. --- */
    --gnt-designer-accent: #327a8c;
    --gnt-designer-accent-strong: #235562;
    --gnt-designer-accent-tint: #f3f7f8;
    --gnt-designer-accent-tint-strong: #eaf2f4;

    /* --- Chart series, in order. Set from the theme's Chart Palette token at runtime. --- */
    --gnt-chart-1: #2f6fed;
    --gnt-chart-2: #0e7490;
    --gnt-chart-3: #b7791f;
    --gnt-chart-4: #166534;
    --gnt-chart-5: #7c3aed;
    --gnt-chart-6: #dc2626;
    --gnt-chart-7: #0891b2;
    --gnt-chart-8: #65a30d;

    /* --- Typography & spacing --- */
    --gnt-font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    --gnt-font-heading: var(--gnt-font-body);
    --gnt-font-size: 14px;
    --gnt-zoom: 1;                     /* the per-user text size zooms the root (gnt-theme.js sets it); 1 = follow the theme */
    --gnt-left-nav-row: 30px;          /* left-nav item height; site.css narrows it per density */
    --gnt-left-nav-star: 1.25rem;      /* the expand icon beside it, sized with the row */
    --gnt-mono-font: ui-monospace, "Cascadia Mono", Consolas, "Courier New", monospace;
    --gnt-code-surface: #141417;       /* a script or transcript block: dark in every theme, as a terminal is */
    --gnt-code-text: #e6edf3;          /* text on --gnt-code-surface */
    --gnt-radius: 4px;
    --gnt-formitem-pl: 3px;
    --gnt-formitem-pr: 3px;
    --gnt-row-padding: 6px;

    /* ===== Scales (CSS review 2026-10-05, CSS-10) =====
       Each step is the most-used literal already in component CSS, so adopting a token is a pure
       substitution: replace a literal only where it equals a step exactly, and leave near-misses
       (0.78rem, 0.82rem, 3px, 10px…) for a deliberate snap. Not themeable: SabreDefaultTheme does not
       emit these, and ThemeTokenFitnessTests only compares the tokens it does emit. */

    /* --- Radius. --gnt-radius stays the themeable corner (the theme manager writes it);
       --gnt-radius-sm follows it, so a tenant that squares its corners squares the small ones. --- */
    --gnt-radius-sm: var(--gnt-radius);  /* 4px: inputs, buttons, chips with corners */
    --gnt-radius-md: 6px;              /* cards, panels, callouts */
    --gnt-radius-lg: 8px;              /* dialogs, record panels */
    --gnt-radius-pill: 999px;          /* pills, round badges, status chips */

    /* --- Elevation. Slate-based shadows (rgb 15 23 42), the three most repeated. --- */
    --gnt-shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.08);      /* a raised control or chip */
    --gnt-shadow-md: 0 10px 28px rgba(15, 23, 42, 0.07);    /* a card or panel at rest */
    --gnt-shadow-lg: 0 10px 24px rgba(15, 23, 42, 0.18);    /* a floating menu, popover or flyout */
    --gnt-shadow-xl: 0 18px 44px rgba(15, 23, 42, 0.18);    /* a modal dialog, a tour card, a full panel over the page */

    /* --- Scrims: the dim layer behind a modal or a guided tour. Dark in every theme. --- */
    --gnt-scrim: rgba(15, 23, 42, 0.45);
    --gnt-scrim-soft: rgba(15, 23, 42, 0.25);   /* a lighter dim, where the page must stay readable */

    /* --- Hover on a neutral control or row: the text colour faintly over the surface, so it follows
       dark mode and a tenant's palette. Opaque, so it can sit under text without ghosting. --- */
    --gnt-hover-bg: color-mix(in srgb, var(--gnt-text-color) 8%, var(--gnt-surface-color));

    /* --- Favourite star. Gold in every theme: it is a state, not a surface (like the trial banner). --- */
    --gnt-favourite-color: #d4a017;

    /* --- Stacking. Tiers in ascending order; a component that needs to sit just above a sibling
       in its tier uses calc(var(--gnt-z-…) + n) rather than a new magic number. Current literals
       and the tier each belongs to (relative order is preserved):
         raised   10      1, 2, 3, 5, 9, 10, 12 — stacking inside a component
         sticky   20      20, 30 — sticky headers, the grid toolbar search
         dropdown 1000    900 – 1001 — assistant reopen tab, GNTTab menus, page-level popups
         overlay  1050    1049, 1050 — site.css backdrop and the panel above it (Bootstrap's modal pair)
         modal    3000    1200 – 3000 — feedback button, page dialogs, left-nav / detail-form flyouts
         popover  11050   10000 – 11060 — designer flyouts, GNTGridSelector / GNTToolsMenu /
                          GNTCommandBar popups, which must clear Syncfusion dialogs
         toast    12000   12000 — AppNotificationHost
         tour     100000  100000 – 100003 — gnt-tour layer, card and explore badges, above everything --- */
    --gnt-z-raised: 10;
    --gnt-z-sticky: 20;
    --gnt-z-dropdown: 1000;
    --gnt-z-overlay: 1050;
    --gnt-z-modal: 3000;
    --gnt-z-popover: 11050;
    --gnt-z-toast: 12000;
    --gnt-z-tour: 100000;

    /* --- Type scale for component copy. The root size stays --gnt-font-size (14px, themeable);
       these are rem steps under it. "base" is the panel body copy, the most-used value. --- */
    --gnt-font-size-xs: 0.72rem;       /* micro labels, counters, badge text */
    --gnt-font-size-sm: 0.75rem;       /* captions, chips, hints */
    --gnt-font-size-md: 0.8rem;        /* meta lines, dense tables, footers */
    --gnt-font-size-base: 0.85rem;     /* panel and form body copy */
    --gnt-font-size-lg: 0.9rem;        /* emphasised copy, subtitles */
    --gnt-font-size-xl: 1rem;          /* section headings inside a panel */

    /* --- Spacing: padding, margin and gap. --- */
    --gnt-space-1: 0.25rem;
    --gnt-space-2: 0.5rem;
    --gnt-space-3: 0.75rem;
    --gnt-space-4: 1rem;
    --gnt-space-5: 1.5rem;
    --gnt-space-6: 2rem;

    /* --- Breakpoints. Custom properties cannot be used in @media, so these are a convention, not
       tokens. Component CSS uses 12 widths today (420 – 1240px); new rules use only these three,
       and existing ones consolidate onto them:
         760px   phone / narrow — single column (10 uses today; 700, 720, 768, 800 snap here)
         900px   tablet — side panels stack (17 uses today, the most common; 860 snaps here)
         1100px  small desktop — dense grids drop secondary columns (9 uses; 980, 1000, 1200 snap here) --- */

    /* --- Timephased grid (GNT.Components gnt-timephase.css). GNT.Components may not reference
       Sabre.*, so the library also carries these values as defaults in a low-priority cascade layer
       for hosts without this file (its sandbox); these unlayered declarations win wherever this file
       is linked. Every value reads a theme token, directly or through color-mix(), so the grid follows
       the tenant theme and dark mode; the builder does not emit these, so they are mixed here. --- */
    --gnt-tp-unit: 28px;                          /* row height: one unit on both panes */
    --gnt-tp-border: var(--gnt-border-color);
    --gnt-tp-row-sep: var(--gnt-border-light);    /* the light line between measures of one entity */
    --gnt-tp-toolbar-bg: var(--gnt-surface-2);
    --gnt-tp-derived-fg: var(--gnt-muted-color);  /* derived, zero and secondary readouts */
    --gnt-tp-empty-fg: color-mix(in srgb, var(--gnt-muted-color) 45%, var(--gnt-surface-color));
    --gnt-tp-actual-bg: color-mix(in srgb, var(--gnt-border-color) 25%, var(--gnt-surface-color)); /* actuals periods */
    --gnt-tp-locked-bg: color-mix(in srgb, var(--gnt-text-color) 8%, var(--gnt-surface-color)); /* locked periods */
    --gnt-tp-rollup-fg: var(--gnt-text-color);
    --gnt-tp-negative-fg: var(--gnt-danger-strong);
    --gnt-tp-error-fg: var(--gnt-danger-strong);
    --gnt-tp-dirty-bg: var(--gnt-warning-tint);   /* an edited, unsaved cell: the "will be changed" role */
    --gnt-tp-pending-bg: repeating-linear-gradient(45deg, var(--gnt-surface-2), var(--gnt-surface-2) 4px,
        var(--gnt-tp-stripe) 4px, var(--gnt-tp-stripe) 8px);
    --gnt-tp-stripe: color-mix(in srgb, var(--gnt-border-color) 30%, var(--gnt-surface-color));
}

/* ===== Bootstrap bridge =====
   Bootstrap 5.3 components read per-component variables that its own rules set to literals
   (`.btn-primary { --bs-btn-bg: #0d6efd }`), so overriding `--bs-primary` alone does not move them.
   These rules re-point the components we actually use at the theme tokens. They are static CSS: the
   runtime applier only ever writes custom properties, never rules. */
.btn-primary {
    --bs-btn-bg: var(--gnt-primary-color);
    --bs-btn-border-color: var(--gnt-primary-color);
    --bs-btn-color: var(--gnt-text-inverse);
    --bs-btn-hover-bg: var(--gnt-primary-strong);
    --bs-btn-hover-border-color: var(--gnt-primary-strong);
    --bs-btn-hover-color: var(--gnt-text-inverse);
    --bs-btn-active-bg: var(--gnt-primary-strong);
    --bs-btn-active-border-color: var(--gnt-primary-strong);
    --bs-btn-disabled-bg: var(--gnt-primary-color);
    --bs-btn-disabled-border-color: var(--gnt-primary-color);
}

.btn-outline-primary {
    --bs-btn-color: var(--gnt-primary-color);
    --bs-btn-border-color: var(--gnt-primary-color);
    --bs-btn-hover-bg: var(--gnt-primary-color);
    --bs-btn-hover-border-color: var(--gnt-primary-color);
    --bs-btn-hover-color: var(--gnt-text-inverse);
}

.alert-danger {
    --bs-alert-bg: var(--gnt-danger-tint);
    --bs-alert-border-color: var(--gnt-danger-border);
    --bs-alert-color: var(--gnt-danger-text);
}

.alert-warning {
    --bs-alert-bg: var(--gnt-warning-tint);
    --bs-alert-border-color: var(--gnt-warning-color);
    --bs-alert-color: var(--gnt-text-color);
}

.alert-success {
    --bs-alert-bg: var(--gnt-surface-2);
    --bs-alert-border-color: var(--gnt-success-color);
    --bs-alert-color: var(--gnt-success-color);
}

/* ===== Status chips =====
   A status's colour comes from its semantic, not its name, so any surface that shows a status
   (grid cell, detail header, Gantt bar, kanban column) can pick the class and stay in step with the
   theme. Text colour is fixed to the inverse token because these are filled chips. */
.gnt-status-chip {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    line-height: 1.4;
    color: var(--gnt-text-inverse);
    background: var(--gnt-status-open);
}

.gnt-status-chip--open { background: var(--gnt-status-open); }
.gnt-status-chip--inprogress { background: var(--gnt-status-inprogress); }
.gnt-status-chip--complete { background: var(--gnt-status-complete); }
.gnt-status-chip--onhold { background: var(--gnt-status-onhold); }
.gnt-status-chip--cancelled { background: var(--gnt-status-cancelled); }

/* Permitted literal colours in component CSS (ThemeTokenFitnessTests budget):
   - status / gantt / risk-matrix category colours that are data, not chrome
   - translucent rgba() shadows and overlays
   Everything else should be a token. */
