/* Dashtxtastic Design Tokens
 * Single source of truth for palette, typography, spacing, brand overrides.
 * Inlined into every generated HTML output at write time (see HtmlGenerator).
 * Loaded by the admin shell via App.razor.
 *
 * Discipline (CONVENTIONS.md sections 11 and 12):
 *   - Razor templates must reference var(--token), never hex/rgb literals.
 *   - Hex/rgb values appear ONLY inside the palette sections of this file.
 *   - Generated HTML inlines this file into a <style> block; no <link rel="stylesheet">.
 *
 * THEMING (three states, order matters)
 *   1. bare :root                      -> complete light palette. Every token is
 *                                         declared here and nowhere else.
 *   2. @media (prefers-color-scheme:dark)
 *      guarded :root:not([data-theme="light"])
 *                                      -> OS dark preference, unless the viewer
 *                                         explicitly chose light.
 *   3. :root[data-theme="dark"]        -> explicit choice wins over OS in both
 *                                         directions.
 *   The default "system" setting stamps no attribute, so state 2 is what most
 *   viewers hit. Never declare a color ONLY inside a media or [data-theme] block:
 *   it will not apply in the unstamped state and the page renders one theme's
 *   text on the other theme's ground.
 *
 * SEMANTIC LAYER
 *   Templates and per-mode CSS bind to the semantic tokens (--paper, --surface,
 *   --surface-2, --ink, --ink-2, --ink-3, --rule, --rule-soft), never to raw
 *   palette values. Only the semantic tokens are redefined per theme, so adding
 *   a theme never means touching a template. The legacy --gray-* and --text
 *   tokens are retained as aliases onto the semantic layer so existing templates
 *   theme automatically.
 */

:root {
  /* === Brand-overridable (rewritten per user at generation time by BrandingService) ===
   * --brand-*-dark are the dark-theme counterparts. BrandingService currently writes
   * only the light pair; until it writes both, a custom brand color falls back to the
   * engine default in dark mode rather than rendering unreadable on a dark ground.
   */
  --brand-primary: var(--navy);
  --brand-accent: var(--blue);
  --brand-primary-dark: var(--navy-on-dark);
  --brand-accent-dark: var(--blue-on-dark);
  --brand-logo-url: none;
  --brand-display-name: "Dashtxtastic";

  /* === Palette (light) === */
  --navy: #1f2a5e;
  --navy-dark: #14204a;
  --green: #2f8f4f;
  --green-soft: #e6f3ea;
  --red: #b73b3b;
  --red-soft: #fbe6e6;
  --blue: #2a6fb5;
  --blue-soft: #e6eef8;
  --purple: #6b2d8c;
  --purple-soft: #f0e6f6;
  --orange: #d96b2c;
  --orange-soft: #fdeee0;
  --amber: #d9a52c;
  --amber-soft: rgba(217, 165, 44, 0.13);
  --amber-dark: #946d11;

  /* === Palette (dark counterparts) ===
   * Declared in :root so they always resolve; consumed by the dark blocks below.
   * Lightened and desaturated so they carry on a dark ground without glowing.
   */
  --navy-on-dark: #93a6e8;
  --green-on-dark: #6fbf87;
  --green-soft-on-dark: #16301f;
  --red-on-dark: #e58a8a;
  --red-soft-on-dark: #331919;
  --blue-on-dark: #74aae2;
  --blue-soft-on-dark: #16283a;
  --purple-on-dark: #b98cd6;
  --purple-soft-on-dark: #271733;
  --orange-on-dark: #e79a63;
  --orange-soft-on-dark: #331f12;
  --amber-on-dark: #e3b267;
  --amber-soft-on-dark: rgba(227, 178, 103, 0.16);

  /* === Semantic surfaces + ink (the theme-swappable layer) ===
   * Neutrals carry a slight hue bias toward the ink rather than sitting on pure
   * grey; a pure mid-grey reads as unconsidered.
   */
  --paper: #fbfaf6;
  --surface: #ffffff;
  --surface-2: #f2efe7;
  --surface-inverse: #ffffff;
  --ink: #16211e;
  --ink-2: #47554f;
  --ink-3: #7c8983;
  --rule: #ddd9cd;
  --rule-soft: #ebe7dc;

  /* Text and icons that sit ON a filled accent band (navy header, colored theme
   * strip). Distinct from --surface, which is a card ground. These are the same
   * white in light mode, which is why they were historically conflated; in dark
   * mode the accent lightens, so content on top of it must darken.
   */
  --on-accent: #ffffff;

  /* === Legacy neutral aliases ===
   * Retained so existing templates and per-mode CSS theme without edits.
   * Prefer the semantic names above in new code.
   */
  --text: var(--ink);
  --gray-100: var(--surface-2);
  --gray-200: var(--rule-soft);
  --gray-300: var(--rule);
  --gray-500: var(--ink-3);
  --gray-700: var(--ink-2);
  /* Projects.razor.css referenced --gray-900 while nothing defined it, so those rules
     collapsed to the inherited colour and rendered as washed-out text. Aliased to --ink like
     the rest of the ladder, which themes it for free. */
  --gray-900: var(--ink);

  /* === Pillar rotation (infographic templates) ===
   * Used by PillarPalette and the .pillar-{n} classes in InfographicFlow.cshtml,
   * InfographicBeforeAfter.cshtml, and InfographicStages.cshtml. Order matches the
   * skill: green, blue, purple, orange. Pattern C templates compute color via
   * PillarPalette, so the value, not the slot, is what matters.
   */
  /* === Timeline lane rotation (Timeline render mode) ===
   * Six hues so a Gantt with more than four groups still separates at a glance;
   * consumed by TimelineLanePalette.For(index) as --lane-1 .. --lane-6. These alias
   * the base hues rather than restating them, so the dark blocks below (which
   * redefine --green, --blue, --amber-dark, ...) theme the lanes for free.
   */
  --lane-1: var(--amber-dark);
  --lane-2: var(--blue);
  --lane-3: var(--green);
  --lane-4: var(--orange);
  --lane-5: var(--purple);
  --lane-6: var(--red);
  --lane-7: var(--navy);
  --lane-8: var(--amber);

  --pillar-1: var(--green);
  --pillar-2: var(--blue);
  --pillar-3: var(--purple);
  --pillar-4: var(--orange);

  /* === Infographic chip + band sizing === */
  --font-size-band-header: 13px;
  --font-size-chip: 11.5px;
  --font-size-subtitle: 15px;
  --font-size-title: 28px;
  --radius-sm: 4px;
  --radius-pill: 999px;
  --space-xs: 7px;
  --space-sm: 10px;
  --space-md: 16px;

  /* === Typography ===
   * Three roles. --font-display carries headings and numerals that want presence,
   * --font-body carries running text, --font-data carries anything tabular or
   * identifier-shaped. Self-contained output forbids linked web fonts, so all three
   * resolve to system stacks; the roles exist so an embedded-font kit can swap one
   * without touching a template.
   */
  --font-stack: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-display: var(--font-stack);
  --font-body: var(--font-stack);
  --font-data: var(--font-mono);
  --font-size-base: 14px;
  --font-size-headline: 30px;
  --font-size-h1: 28px;
  --font-size-card-title: 15px;
  --font-size-card-body: 13.5px;
  --font-size-badge: 16px;
  --font-size-footer-header: 12px;
  --font-size-arrow: 28px;
  --font-size-eyebrow: 11px;
  --font-size-label: 10.5px;
  --font-size-table: 14.5px;
  --font-size-body: 16px;
  --font-size-display: 44px;
  --line-height-base: 1.6;
  --line-height-tight: 1.05;
  --line-height-copy: 1.55;

  /* === Measure ===
   * Running text is capped near 62 characters. Full-bleed paragraphs across a
   * 1080px shell are the fastest way for a page to read as unpolished.
   */
  --measure: 62ch;
  --measure-narrow: 52ch;

  /* === Typographic treatment ===
   * The details that separate a styled page from a designed one: negative tracking
   * on display sizes, wide tracking on uppercase labels, heavy display weight.
   */
  --tracking-display: -0.03em;
  --tracking-tight: -0.015em;
  --tracking-normal: 0;
  --tracking-label: 0.13em;
  --tracking-eyebrow: 0.16em;
  --weight-display: 800;
  --weight-semibold: 600;

  /* === Layout === */
  --layout-max-width: 1080px;
  --layout-max-width-wide: 1380px;
  --layout-aside-width: 280px;
  --layout-breakpoint-narrow: 720px;
  --brand-logo-size: 32px;

  /* === Layout lock === */
  /* These five are the only supported way to change page width. layout-lock.css is inlined
     LAST (after kit.css) and pins body/.dtx-shell width and centering to them with
     !important, so a kit rule such as `.dtx-shell { max-width: 880px }` can no longer clamp
     or un-center a render mode's page by accident. A render mode declares its page width by
     overriding these in :root; a kit that wants a narrower card does the same. Defaults
     reproduce the pre-lock kit-base.css behavior: unclamped body, centered 1080px shell. */
  --layout-body-max-width: none;
  --layout-body-margin-inline: auto;
  --layout-shell-max-width: var(--layout-max-width);
  --layout-shell-margin-inline: auto;
  --layout-print-body-max-width: none;

  /* === Spacing === */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 14px;
  --space-4: 22px;
  --space-5: 32px;
  --space-6: 48px;
  --space-7: 64px;

  /* === Radius + shadow === */
  --radius-1: 3px;
  --radius-2: 6px;
  --radius-md: 6px;
  --shadow-1: 0 1px 2px rgba(22, 33, 30, 0.06);
  --shadow-2: 0 2px 8px rgba(22, 33, 30, 0.08);
  --shadow-3: 0 8px 24px rgba(14, 17, 23, 0.18);
  --shadow-4: 0 24px 60px rgba(14, 17, 23, 0.28);
  --shadow-drawer-edge: -2px 0 8px rgba(0, 0, 0, 0.12);
  --shadow-drawer: -4px 0 16px rgba(0, 0, 0, 0.08);
  --scrim: rgba(14, 17, 23, 0.4);
  --scrim-strong: rgba(14, 17, 23, 0.45);

  /* === Status badge colors ===
   * Referenced by Razor templates as --status-{slug} via StatusSlugger.ToSlug(). Adding a
   * new business status means adding a new token here AND letting it round-trip through
   * StatusSlugger; templates never hard-code hex literals. These resolve through the
   * palette tokens, so the dark blocks below re-theme them for free.
   */
  --status-active: var(--green-soft);
  --status-active-text: var(--green);
  --status-blocked: var(--red-soft);
  --status-blocked-text: var(--red);
  --status-in-progress: var(--blue-soft);
  --status-in-progress-text: var(--blue);
  --status-on-hold: var(--orange-soft);
  --status-on-hold-text: var(--orange);
  --status-draft: var(--gray-100);
  --status-draft-text: var(--gray-700);
  --status-published: var(--green-soft);
  --status-published-text: var(--green);
  --status-archived: var(--gray-200);
  --status-archived-text: var(--gray-500);
  --status-done: var(--green-soft);
  --status-done-text: var(--green);
  --status-default: var(--gray-100);
  --status-default-text: var(--gray-700);

  /* === Dashboard grid === */
  --tile-grid-columns: 3;
  --tile-grid-columns-md: 2;
  --tile-grid-columns-sm: 1;
  --tile-min-height: 160px;
  --tile-breakpoint-md: 1200px;
  --tile-breakpoint-sm: 700px;
}

/* === Theme state 2: OS dark preference ===
 * Guarded so an explicit light choice beats a dark OS. Only tokens are redefined here;
 * no component ever gets its sole color definition inside this block.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #0e1614;
    --surface: #16211e;
    --surface-2: #1e2b27;
    --surface-inverse: #0e1614;
    --ink: #edebe3;
    --ink-2: #a9b5af;
    --ink-3: #7a867f;
    --rule: #2c3a35;
    --rule-soft: #22302b;
    --on-accent: #0e1614;

    --navy: var(--navy-on-dark);
    --navy-dark: #7286d4;
    --green: var(--green-on-dark);
    --green-soft: var(--green-soft-on-dark);
    --red: var(--red-on-dark);
    --red-soft: var(--red-soft-on-dark);
    --blue: var(--blue-on-dark);
    --blue-soft: var(--blue-soft-on-dark);
    --purple: var(--purple-on-dark);
    --purple-soft: var(--purple-soft-on-dark);
    --orange: var(--orange-on-dark);
    --orange-soft: var(--orange-soft-on-dark);
    --amber: var(--amber-on-dark);
    --amber-soft: var(--amber-soft-on-dark);
    --amber-dark: #c99a4e;

    --brand-primary: var(--brand-primary-dark);
    --brand-accent: var(--brand-accent-dark);

    --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-2: 0 2px 8px rgba(0, 0, 0, 0.45);
    --shadow-3: 0 8px 24px rgba(0, 0, 0, 0.55);
    --shadow-4: 0 24px 60px rgba(0, 0, 0, 0.65);
    --shadow-drawer-edge: -2px 0 8px rgba(0, 0, 0, 0.5);
    --shadow-drawer: -4px 0 16px rgba(0, 0, 0, 0.45);
    --scrim: rgba(0, 0, 0, 0.6);
    --scrim-strong: rgba(0, 0, 0, 0.7);
  }
}

/* === Theme state 3: explicit dark choice ===
 * Same token set as state 2, so the toggle wins over the OS in both directions.
 */
:root[data-theme="dark"] {
  --paper: #0e1614;
  --surface: #16211e;
  --surface-2: #1e2b27;
  --surface-inverse: #0e1614;
  --ink: #edebe3;
  --ink-2: #a9b5af;
  --ink-3: #7a867f;
  --rule: #2c3a35;
  --rule-soft: #22302b;
  --on-accent: #0e1614;

  --navy: var(--navy-on-dark);
  --navy-dark: #7286d4;
  --green: var(--green-on-dark);
  --green-soft: var(--green-soft-on-dark);
  --red: var(--red-on-dark);
  --red-soft: var(--red-soft-on-dark);
  --blue: var(--blue-on-dark);
  --blue-soft: var(--blue-soft-on-dark);
  --purple: var(--purple-on-dark);
  --purple-soft: var(--purple-soft-on-dark);
  --orange: var(--orange-on-dark);
  --orange-soft: var(--orange-soft-on-dark);
  --amber: var(--amber-on-dark);
  --amber-soft: var(--amber-soft-on-dark);
  --amber-dark: #c99a4e;

  --brand-primary: var(--brand-primary-dark);
  --brand-accent: var(--brand-accent-dark);

  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-2: 0 2px 8px rgba(0, 0, 0, 0.45);
  --shadow-3: 0 8px 24px rgba(0, 0, 0, 0.55);
  --shadow-4: 0 24px 60px rgba(0, 0, 0, 0.65);
  --shadow-drawer-edge: -2px 0 8px rgba(0, 0, 0, 0.5);
  --shadow-drawer: -4px 0 16px rgba(0, 0, 0, 0.45);
  --scrim: rgba(0, 0, 0, 0.6);
  --scrim-strong: rgba(0, 0, 0, 0.7);
}

/* === Minimal base styling for the admin shell ===
 * Body uses tokens so the running Blazor app visibly reflects the design system.
 * Generated HTML output gets its own per-mode layout on top of the same tokens.
 */
html,
body {
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-body);
  font-size: var(--font-size-base);
  line-height: var(--line-height-base);
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--brand-accent);
}

h1,
h2,
h3,
h4,
h5,
h6 {
  color: var(--brand-primary);
  font-family: var(--font-display);
  letter-spacing: var(--tracking-tight);
  text-wrap: balance;
}
