/* ═══════════════════════════════════════════════════════════════════
   DataraFlow design tokens
   One file for the public site and the three portals: public.css and
   portal.css both build on these. The values are the ones DESIGN.md
   documents; change them here and nowhere else.

   The palette comes from the logo (static/images/dataraflow-logo.svg):
   a blue → cyan → teal gradient. The accent is the logo's cyan, darkened
   just far enough to pass AA for small text on both white and paper
   (4.9:1 / 4.6:1); the logo's blue is the fifth status colour (`info`),
   so it stays distinct from the accent; ink is the navy the blue end of
   the gradient reads as. The three brand tokens are the untouched logo
   stops, for artwork that wants the literal gradient (the share kit).
   ═══════════════════════════════════════════════════════════════════ */

:root {
    --df-brand-blue: #2563eb;
    --df-brand-cyan: #0891b2;
    --df-brand-teal: #14b8a6;

    --df-paper: #f5f7fb;
    /* Public site, light mode: near-white page and a neutral panel grey
       (public.css swaps these in for body.public only). */
    --df-public-paper: #fbfbfc;
    --df-public-panel: #f3f4f6;
    --df-surface: #ffffff;
    --df-ink: #0f1a33;
    /* Hover/active step for a solid ink button (.btn-dark): ink is already
       the darkest tone, so the feedback step lightens instead of darkening,
       and reverses again in dark mode where ink is already the lightest. */
    --df-ink-deep: #1c2a4d;
    --df-ink-2: #46516a;
    --df-ink-3: #66708a;
    --df-line: #dde3ef;
    /* The form-control border (inputs, .form-check-input, .input-group-text,
       the outline buttons). WCAG 1.4.11 wants 3:1 for a control boundary
       and the old #c5cee2 gave 1.58 - the borders were very nearly
       invisible. #858fa8 is 3.23 on white and 3.02 on paper. Raised
       knowingly: it darkens every input border on the site. */
    --df-line-strong: #858fa8;
    --df-accent: #087a9e;
    --df-accent-deep: #0b5f7c;
    --df-accent-soft: #e0f3f8;
    --df-cell: #bfe3ee;
    /* The logo's second colour, its teal, given one job: achievement
       (certified graduates, seals, the verify action). Text is darkened to
       pass AA on paper; the fill is the logo's own teal. */
    --df-achieve: #0f766e;
    --df-achieve-fill: #14b8a6;
    --df-on-achieve: #042f2c;
    --df-ok: #1f7a4d;
    --df-ok-soft: #e3f4ea;
    /* Hover/active step for a solid status button, same idea as
       --df-accent-deep: "further from the surface" - darker here, and
       lighter in dark mode where the status colours are already light. */
    --df-ok-deep: #17603c;
    --df-warn: #9a5b00;
    --df-warn-soft: #fdf1dc;
    --df-warn-deep: #7c4900;
    --df-danger: #c0392b;
    --df-danger-soft: #fbe6e3;
    --df-danger-deep: #a52f23;
    /* The vetting panel's fourth risk hue: at-risk sits between watch (warn)
       and critical (danger) and must never share a colour with either, so
       it gets its own token instead of borrowing --df-warn. */
    --df-at-risk: #a1490e;
    --df-at-risk-soft: #fde7d3;
    --df-shadow: 0 18px 40px -18px rgba(15, 26, 51, .28), 0 2px 6px -2px rgba(15, 26, 51, .08);
    --df-shadow-soft: 0 10px 24px -16px rgba(15, 26, 51, .25);
    --df-ease: cubic-bezier(.23, 1, .32, 1);
    --df-radius-ctl: 8px;
    --df-radius-tag: 6px;
    --df-radius-panel: 18px;
    --df-nav-h: 66px;

    /* Type system (Tassy, 8 Oct: "stabilize the system ... the same across
       board"). One scale for every public page, shared by both themes.
       Display = Bricolage condensed caps, for h1 and section h2 only (and
       a big figure where a design already sets it in display). Everything
       else is Inter. Sizes: hero ~90px at 1280 / ~49px at 375; h2 ~56px /
       36px. A hero line that does not fit wraps; it never shrinks. */
    --df-font-display: "Bricolage Grotesque", "Segoe UI", system-ui, sans-serif;
    --df-font-text: Inter, "Segoe UI", system-ui, sans-serif;
    --df-display-weight: 800;
    --df-display-stretch: 75%;
    --df-display-wdth: "wdth" 75;
    --df-display-lh: .9;
    --df-display-ls: -.005em;
    --df-type-hero: clamp(3rem, 2rem + 4.5vw, 5.75rem);
    --df-type-h2: clamp(2.25rem, 1.5rem + 2.6vw, 3.5rem);
    --df-type-h3: 1.25rem;
    --df-type-h3-lh: 1.3;
    --df-type-lede: clamp(1.0625rem, 1rem + .3vw, 1.25rem);
    --df-type-lede-lh: 1.55;
    --df-type-body: 1rem;
    --df-type-body-lh: 1.6;
    --df-type-eyebrow: .75rem;
    --df-type-eyebrow-ls: .12em;

    /* portal: a workspace needs a density scale, two more status colours
       and the shell measurements. */
    --df-space-1: 4px; --df-space-2: 8px; --df-space-3: 12px;
    --df-space-4: 16px; --df-space-5: 24px; --df-space-6: 32px;
    --df-row: 40px;
    --df-control: 36px;
    --df-text-sm: .875rem;
    --df-text: 1rem;
    --df-info: #2563eb;
    --df-info-soft: #e4ebfd;
    --df-neutral: #46516a;
    --df-neutral-soft: #eef1f7;
    /* `unknown` on the intern-tracking panel: a violet that matches nothing
       that carries a measured number, so an absent reading never looks fine. */
    --df-unknown: #7c3aed;
    --df-unknown-deep: #6d28d9;
    --df-unknown-soft: #efe9fe;
    /* Text on a filled status chip (a solid --df-ok / --df-warn / --df-danger
       background). White in light mode; dark in the dark theme, where the
       status colours themselves are light. Introduced so the ~44 literal
       `#fff` values in the portal stylesheets have a token to move to. */
    --df-on-status: #ffffff;
    /* Public site footer (static/css/df-sitefoot.css). Light in the light
       theme (Tassy, 7 Oct: "light, not black, not dark"): a soft grey sheet
       one step darker than the near-white page, so the curve alone marks
       the edge, no border. Footer-specific steps because this ground is
       darker than --df-paper: ink-3 (labels) 5.0:1, accent (links) 5.1:1,
       now (the "Now" label) 4.8:1, ink-2 7.0:1. */
    --df-foot-bg: #eef0f4;
    --df-foot-ink: #0f1a33;
    --df-foot-ink-2: #46516a;
    --df-foot-ink-3: #5b6680;
    --df-foot-line: #d6dce8;
    --df-foot-accent: #086d8d;
    --df-foot-accent-deep: #0b5f7c;
    --df-foot-now: #0f766e;
    --df-foot-closed: #b7791f;
    /* Navy ground: the approved dark chapters (Waitlist hero, What we look
       for, .dfe-navy, the brand gradient's first stop) and the light ink
       on it. Brand navy in light mode; the dark block neutralises them to
       near-black (Tassy, 8 Oct: no blue anywhere in the dark theme).
       These are the values the footer tokens held before the footer went
       light (7 Oct), so the pages look exactly as approved. Never point a
       page at --df-foot-* for "navy"; the footer follows the theme.
       --df-paper-fixed is certificate/ticket paper that stays light on any
       ground. --df-brand-gradient is the navy -> cyan -> teal brand ground. */
    --df-navy: #0b1426;
    --df-on-navy: #e9eef8;
    --df-on-navy-2: #a7b1c6;
    --df-navy-line: #27314a;
    --df-on-navy-accent: #4cc9ec;
    --df-on-navy-accent-deep: #7ad8f2;
    --df-on-navy-now: #5eead4;
    --df-on-navy-closed: #f5c36a;
    --df-paper-fixed: #e9eef8;
    --df-brand-gradient: linear-gradient(135deg, var(--df-navy) 0%, color-mix(in srgb, var(--df-brand-cyan) 82%, var(--df-navy)) 55%, color-mix(in srgb, var(--df-brand-teal) 62%, var(--df-navy)) 100%);
    --df-sidebar-w: 248px;
    --df-sidebar-w-collapsed: 64px;
    --df-topbar-h: 56px;

    /* legacy aliases: every name the portal templates still reference
       resolves to a token, so nothing breaks while the pages are moved
       over. The two gradients are now flat accent on purpose. Delete this
       block once `grep -rn "var(--logo-\|var(--primary-\|var(--card-\|var(--text-dark\|var(--text-muted"
       templates static` comes back empty. */
    --logo-blue: var(--df-accent);
    --logo-cyan: var(--df-accent-deep);
    --logo-teal: var(--df-accent);
    --logo-gradient: var(--df-accent);
    --logo-gradient-dark: var(--df-accent-deep);
    --primary-blue: var(--df-accent);
    --primary-teal: var(--df-accent-deep);
    --accent-teal: var(--df-accent);
    --dark-blue: var(--df-accent-deep);
    --light-gray: var(--df-paper);
    --text-dark: var(--df-ink);
    --text-muted: var(--df-ink-3);
    --success: var(--df-ok);
    --warning: var(--df-warn);
    --danger: var(--df-danger);
    --border-color: var(--df-line);
    --sidebar-width: var(--df-sidebar-w);
    --topbar-height: var(--df-topbar-h);
    --admin-bg: var(--df-paper);
    --card-radius: var(--df-radius-panel);
    --card-shadow: var(--df-shadow-soft);
    --card-shadow-hover: var(--df-shadow);
}

/* ═══════════════════════════════════════════════════════════════════
   Dark theme. Set by the inline resolver in templates/_theme_head.html,
   which writes data-theme and data-bs-theme together on <html>.

   Colour tokens only - spacing, radii, easing and the shell measurements
   are shared and stay in :root above. The three --df-brand-* stops are
   the literal logo and are deliberately absent: a logo has no dark
   variant, and the share kit renders artwork that gets posted off-site.

   Every value here is contrast-checked in tests/test_theme_tokens.py
   against the surface it actually sits on, parsed from this file.

   TRUE DARK (Tassy, 8 Oct: "actually make it dark ... I don't want that
   kind of blue"). Dark = a neutral near-black elevation ramp with no blue
   cast; the brand colour appears only as an accent (links, focus, active
   states, achievement). The ramp, darkest to lightest:
       page #0a0a0b -> raised #111113 -> card #16161a -> hover #1c1c21
       hairline #26262c, strong line #3a3a42
   Each step up is "closer to you", so depth reads from lightness alone.
   The navy bands and the brand gradient are neutralised here too: in
   dark mode a "navy" chapter is a raised near-black sheet and the
   gradient runs near-black -> teal. Light mode keeps the navy.
   ═══════════════════════════════════════════════════════════════════ */
[data-theme="dark"] {
    --df-paper: #0a0a0b;
    /* --df-public-paper is unused in dark (public.css only swaps it in for
       light); --df-public-panel is the raised step, and public.css points
       --df-panel at it in dark too. */
    --df-public-paper: #0a0a0b;
    --df-public-panel: #111113;
    --df-surface: #16161a;
    --df-ink: #ededef;
    --df-ink-deep: #d4d4d8;
    --df-ink-2: #a1a1aa;
    /* Tertiary text. #71717a (zinc-500) was the first pick but is only
       3.7:1 on a card; #8a8a93 is the same neutral, lifted to 5.3:1 on
       card and 4.8:1 on the lightest card mix. */
    --df-ink-3: #8a8a93;
    --df-line: #26262c;
    /* The form-control border. A UI component under WCAG 1.4.11, so it
       must clear 3:1 on card (3.4:1) and page (3.8:1): the decorative
       "strong line" #3a3a42 is too faint for an input edge, and lives in
       --df-navy-line instead. */
    --df-line-strong: #6b6b75;
    /* Not the light accent. #087a9e was darkened to pass AA on white; on a
       dark card it goes muddy and fails. This is the logo's cyan taken the
       other way. --df-accent-deep is the *brighter* step in dark, because
       in both themes it means "further from the surface". The soft and
       cell steps are teal-leaning so no surface ever reads as navy. */
    --df-accent: #4cc9ec;
    --df-accent-deep: #8fe0f7;
    --df-accent-soft: #0f2d33;
    --df-cell: #155a66;
    --df-achieve: #2dd4bf;
    --df-achieve-fill: #14b8a6;
    --df-on-achieve: #042f2c;
    --df-ok: #4ade80;
    --df-ok-soft: #10301f;
    --df-ok-deep: #86efac;
    --df-warn: #fbbf24;
    --df-warn-soft: #362707;
    --df-warn-deep: #fcd34d;
    --df-danger: #f87171;
    --df-danger-soft: #3a1b18;
    --df-danger-deep: #fca5a5;
    /* The vetting panel's fourth risk hue, kept orange and distinct from
       --df-warn (#fbbf24) and --df-danger (#f87171) in this theme too. */
    --df-at-risk: #fdba74;
    --df-at-risk-soft: #3b2006;
    /* Info is a status and stays the logo blue - status only, never a
       ground. */
    --df-info: #7cb0fb;
    --df-info-soft: #16233f;
    --df-neutral: #a1a1aa;
    --df-neutral-soft: #1c1c21;
    --df-unknown: #a78bfa;
    --df-unknown-deep: #c4b5fd;
    --df-unknown-soft: #251d3d;
    /* Text on a filled status chip. The status colours above are light in
       this theme, so white text on them would fail; the readable pair is
       dark text. See --df-on-status in :root. */
    --df-on-status: #0a0a0b;
    /* The footer follows the dark theme: the raised step, one above the
       page, so it does not glare. ink-3 5.5:1, ink-2 7.4:1, accent 9.8:1. */
    --df-foot-bg: #111113;
    --df-foot-ink: #ededef;
    --df-foot-ink-2: #a1a1aa;
    --df-foot-ink-3: #8a8a93;
    --df-foot-line: #26262c;
    --df-foot-accent: #4cc9ec;
    --df-foot-accent-deep: #8fe0f7;
    --df-foot-now: #5eead4;
    --df-foot-closed: #f5c36a;
    /* Navy ground, neutralised for dark (light keeps #0b1426): navy
       chapters become the raised near-black sheet, their rules the strong
       line, and the light ink on them the dark theme's own ink. */
    --df-navy: #111113;
    --df-on-navy: #ededef;
    --df-on-navy-2: #a1a1aa;
    --df-navy-line: #3a3a42;
    --df-on-navy-accent: #4cc9ec;
    --df-on-navy-accent-deep: #8fe0f7;
    --df-on-navy-now: #5eead4;
    --df-on-navy-closed: #f5c36a;
    /* Certificate/ticket paper: still paper in dark, minus the blue cast. */
    --df-paper-fixed: #ededef;
    /* A subtle near-black -> teal instead of the navy -> cyan blue. */
    --df-brand-gradient: linear-gradient(135deg, var(--df-navy) 0%, color-mix(in srgb, var(--df-brand-teal) 20%, var(--df-navy)) 60%, color-mix(in srgb, var(--df-brand-teal) 40%, var(--df-navy)) 100%);
    /* A shadow is nearly invisible on a dark background, so cards lean on
       --df-line for separation and the shadow only deepens the edge. */
    --df-shadow: 0 18px 40px -18px rgba(0, 0, 0, .66), 0 2px 6px -2px rgba(0, 0, 0, .4);
    --df-shadow-soft: 0 10px 24px -16px rgba(0, 0, 0, .55);
}
