/* ==========================================================================
   phid-tokens.css — VENDORED from data-conductor
   --------------------------------------------------------------------------
   Upstream   data-conductor core/html/phid-tokens.css @ 509415c
   Vendored   2026-08-17
   Direction  one-way, data-conductor -> system-dev. data-conductor owns the
              design language; do not edit this copy. To change a token,
              change it upstream and re-vendor, noting the new commit above.
   ========================================================================== */

/* ==========================================================================
   phid-tokens.css — the PHi-D design language, as CSS custom properties
   --------------------------------------------------------------------------
   Last updated  2026-08-17
   Derives from  PHi-C_PHi-D_logo-guideline.pdf (2026-07-31) and the SVG artwork
   Records       the `reference` database — thread 1 in `status`, and the design
                 rulings in `decisions`. (The two docs/*-Action.md files cited
                 here until 2026-08-17 never existed on disk; the record was
                 retired into the database that day.)
   Served at     /assets/phid-tokens.css (embedded — see core/zig/http/http_assets.zig)

   THE ONE RULE THIS FILE EXISTS TO ENFORCE
   ----------------------------------------
   Tokens are named for their ROLE, never for their colour. The brand palette
   inverts between themes: navy is the strongest colour on white (9.44:1) and
   almost invisible on near-black (2.52:1); dawn is the exact reverse (2.05:1
   light, 9.36:1 dark). A token called --brand-primary pinned to navy breaks the
   moment the background flips. --phid-accent does not, because it resolves to a
   *different brand colour per theme*.

   So: use the semantic tokens in §4 onward. The raw palette in §2 is the anchor
   set, kept here for provenance — do not reference it from a page.

   THEME
   -----
   Both themes ship in every token via light-dark(). The page follows the OS by
   default; setting color-scheme on :root (or any subtree) pins it:

       :root            { color-scheme: light dark; }   /* default, below */
       [data-theme=light] { color-scheme: light; }
       [data-theme=dark]  { color-scheme: dark;  }

   light-dark() is supported by every engine since Safari 17.5 (2024-05).

   CONTRAST
   --------
   Every ratio in the comments is WCAG 2.x relative luminance, measured — not
   estimated — by the method in docs/2026-08-05-Wed-Action.md §4. Ratios are
   quoted against the surface the token is meant to sit on: --phid-surface-card
   for content, --phid-surface-page for chrome. Re-measure before changing a
   value; the comment is the contract.
   ========================================================================== */


/* ==========================================================================
   1. Typeface — Source Sans 3, local()-first
   --------------------------------------------------------------------------
   Guideline page 11 specifies Source Sans 3, chosen for database use: the
   numerals are unambiguous and 0/1 do not collide, which lowers misreading risk
   on tables of measurements.

   Delivery is local()-first (decision: 2026-08-05 §7.1). Zero bytes are added to
   the conductor binary, and the OTFs are installed on phic-db-01 at
   ~/.local/share/fonts/source-sans-3/. Elsewhere the stack degrades to the
   system UI sans, which is correct-looking but not the brand face. Moving to
   self-hosted woff2 later changes this section and nothing else.

   The src lists PostScript names — local() matches those, not the CSS family.
   ========================================================================== */

@font-face {
    font-family: "PHiD Sans";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: local("SourceSans3-Regular"), local("Source Sans 3"),
         local("SourceSansPro-Regular"), local("Source Sans Pro");
}

@font-face {
    font-family: "PHiD Sans";
    font-style: italic;
    font-weight: 400;
    font-display: swap;
    src: local("SourceSans3-It"), local("SourceSansPro-It");
}

@font-face {
    font-family: "PHiD Sans";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: local("SourceSans3-Semibold"), local("SourceSansPro-Semibold");
}

@font-face {
    font-family: "PHiD Sans";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: local("SourceSans3-Bold"), local("SourceSansPro-Bold");
}


/* ==========================================================================
   2. Raw brand palette — provenance only, do not use directly
   --------------------------------------------------------------------------
   Eight colours in four pairs, extracted from the SVG <style> blocks rather
   than transcribed. The _A set is the artwork for light backgrounds, _B the
   lightened set the designer supplies for dark ones.

   The four also form a properly-constructed sequential ramp: OKLCH lightness
   0.396 → 0.527 → 0.659 → 0.782 in even steps, which the guideline reads as a
   time axis, 紺青色 (night, past) → 曙色 (dawn, future). Monotonic lightness
   means the ordering survives colour-vision deficiency and greyscale printing.
   ========================================================================== */

:root {
    /* on light                     on dark  */
    --phid-navy-a:   #264677;   --phid-navy-b:   #3C5985;   /* 紺青 */
    --phid-violet-a: #6E6680;   --phid-violet-b: #7D758D;
    --phid-rose-a:   #B1867D;   --phid-rose-b:   #B9928A;
    --phid-dawn-a:   #F3A366;   --phid-dawn-b:   #F4AC75;   /* 曙   */
}


/* ==========================================================================
   3. Theme declaration
   ========================================================================== */

:root {
    color-scheme: light dark;
}

:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark;  }


:root {

    /* ======================================================================
       4. Surfaces
       ----------------------------------------------------------------------
       Neutrals are tinted toward the navy hue so they sit with the brand
       rather than beside it. The dark page colour is near-neutral black by
       measurement: on a blue-tinted dark surface such as #1C2B3A the _B set
       degrades badly (navy 2.03, violet 3.30).
       ====================================================================== */

    --phid-surface-page:    light-dark(#F6F8FA, #12181F);
    --phid-surface-card:    light-dark(#FFFFFF, #1A222C);
    --phid-surface-inset:   light-dark(#F1F4F7, #151C25);  /* wells, table heads, segmented controls */
    --phid-surface-hover:   light-dark(#EEF2F6, #212B37);
    --phid-surface-overlay: light-dark(#1B2431, #E3E9F1);  /* tooltips — inverted against the page */


    /* ======================================================================
       5. Borders
       ----------------------------------------------------------------------
       --phid-border-control is the only one that carries a contrast
       requirement: WCAG 1.4.11 asks 3:1 for a boundary that identifies a
       control. Measured 3.77:1 light, 3.09:1 dark, both against the card.
       The other two are decorative separators and are deliberately quieter.
       ====================================================================== */

    --phid-border-subtle:  light-dark(#EBEEF2, #222B36);
    --phid-border:         light-dark(#E2E6EC, #2B3542);
    --phid-border-control: light-dark(#78849B, #616E7E);


    /* ======================================================================
       6. Text
       ----------------------------------------------------------------------
       --phid-text-strong is the brand voice: navy on light, dawn on dark.
       This is the inversion, made concrete. Body text stays on the neutral
       ink — brand colour on every paragraph reads as decoration, and navy at
       body size is heavier than the guideline intends.
       ====================================================================== */

    --phid-text-strong:  light-dark(#264677, #F4AC75);  /* 9.44:1 / 8.41:1 on card */
    --phid-text:         light-dark(#1B2431, #E3E9F1);  /* 15.6:1 / 13.1:1 on card */
    --phid-text-muted:   light-dark(#5D6B7E, #98A5B6);  /*  5.43:1 / 6.41:1 on card */
    --phid-text-on-accent:  light-dark(#FFFFFF, #12181F); /* 9.44:1 / 9.36:1 on the accent fill */
    --phid-text-on-overlay: light-dark(#F6F8FA, #1B2431);


    /* ======================================================================
       7. Accent — interactive colour
       ----------------------------------------------------------------------
       Links, focus, selected state, the primary button fill, the primary data
       mark. Navy on light, dawn on dark; both clear 8:1, so the accent is
       never the reason something is hard to read.

       --phid-accent-wash is the accent at low alpha for a background tint
       (active tab, selected row). It is a background only — text placed on it
       takes --phid-text or --phid-text-strong, not the accent itself.
       ====================================================================== */

    --phid-accent:       light-dark(#264677, #F4AC75);
    --phid-accent-hover: light-dark(#1B3358, #F8C398);  /* 12.6:1 / 11.3:1 */
    --phid-accent-wash:  light-dark(rgba(38, 70, 119, 0.08), rgba(244, 172, 117, 0.14));
    --phid-accent-edge:  light-dark(rgba(38, 70, 119, 0.28), rgba(244, 172, 117, 0.34));

    /* Rose and violet, in the one role each holds in both themes.
       warm  — secondary marks, thresholds, the "other side" of a comparison.
       quiet — tertiary marks and low-emphasis UI. Violet is 3.67:1 on the dark
               card: large text and graphics only there, never body copy. */
    --phid-warm:  light-dark(#B1867D, #B9928A);  /* 3.19:1 / 5.76:1 on card */
    --phid-quiet: light-dark(#6E6680, #7D758D);  /* 5.42:1 / 3.67:1 on card */

    --phid-focus-ring: 0 0 0 3px light-dark(rgba(38, 70, 119, 0.28), rgba(244, 172, 117, 0.32));


    /* ======================================================================
       8. Data colour
       ----------------------------------------------------------------------
       Two ramps, for two different jobs.

       --phid-data-N is CATEGORICAL: unordered series, ordered by legibility so
       that the first series a chart reaches for is the most readable one. Slot
       4 is the low-contrast end in both themes (2.05:1 light, 2.52:1 dark) —
       large filled areas only, never a line, a point, or a label.

       --phid-seq-N is SEQUENTIAL: the guideline's own ramp, dark-to-light, for
       encoding a magnitude. Do not shuffle it; the even lightness steps are
       what make it work in greyscale and under colour-vision deficiency.
       ====================================================================== */

    --phid-data-1: light-dark(#264677, #F4AC75);  /* navy   ↔ dawn   */
    --phid-data-2: light-dark(#6E6680, #B9928A);  /* violet ↔ rose   */
    --phid-data-3: light-dark(#B1867D, #7D758D);  /* rose   ↔ violet */
    --phid-data-4: light-dark(#F3A366, #3C5985);  /* dawn   ↔ navy — fills only */

    --phid-seq-1: light-dark(#264677, #3C5985);
    --phid-seq-2: light-dark(#6E6680, #7D758D);
    --phid-seq-3: light-dark(#B1867D, #B9928A);
    --phid-seq-4: light-dark(#F3A366, #F4AC75);

    --phid-grid: light-dark(#E5E9EF, #283340);  /* axis rules, tick lines */


    /* ----------------------------------------------------------------------
       8b. Plot-locked scales — pinned to the images, NOT to the design language
       ----------------------------------------------------------------------
       These reproduce the matplotlib colormap the pipeline bakes into the PNGs,
       so that a legend drawn in HTML matches the image sitting next to it.

       They are deliberately NOT light-dark(). The rendered image does not change
       with the viewer's theme, so its key must not either — a themed legend would
       silently stop describing the picture it labels.

       The source of truth is the plotting code, not this file: contact maps use
       `magma_r` (core/phic2/phic2-v230-for-conductor.py:955). Change these only
       when that call changes.
       ---------------------------------------------------------------------- */

    --phid-cmap-contact-0: #FCFDBF;  /* magma_r low end — fewest contacts */
    --phid-cmap-contact-1: #FC8961;
    --phid-cmap-contact-2: #B73779;
    --phid-cmap-contact-3: #641A80;  /* stops short of magma_r's #000004 — see below */


    /* ----------------------------------------------------------------------
       8c. Babylon scene-locked — the dynamics viewer's own colours
       ----------------------------------------------------------------------
       Same rule as 8b, different renderer. These mirror constants compiled into
       the WebGL scene, so page chrome that labels the canvas keeps matching it:

           BG      dynamics_babylon.js:44   Color4(0.969, 0.969, 0.949)
           CHAIN   dynamics_babylon.js:45   Color3(0.071, 0.435, 0.404)
           HOVER   dynamics_babylon.js:51   Color3(0.937, 0.741, 0.263)
           CURSOR  dynamics_babylon.js:52   Color3(0.706, 0.192, 0.412)

       Not light-dark(), for the same reason as 8b: the canvas does not follow
       the viewer's theme, so a swatch that claims to name a bead colour must
       not either. Use these ONLY where the page is naming something drawn in
       the scene — ordinary chrome on those pages takes the normal tokens.

       The JS is the arbiter. It is Phase 2 code due to move to system-dev, so
       expect this block to move or die with it.
       ---------------------------------------------------------------------- */

    --phid-scene-bg:     #F7F7F2;
    --phid-scene-chain:  #126F67;
    --phid-scene-hover:  #EFBD43;   /* hovered bead, and gene markers in igv */
    --phid-scene-cursor: #B43169;   /* cursor bead */

    /* The igv legend names two more scene features. Both were transcribed by
       hand rather than derived, and neither matches its material exactly —
       preserved at the shipped value rather than "corrected", since the legend
       is what the reader compares against:

         coverage  the lit teal rod. The material is CHAIN (igv_demo.js:421),
                   so this is an approximation of how CHAIN appears once lit.
         acen      igv_demo.js:92 is Color3(0.72, 0.24, 0.28) = #B83D47; the
                   legend says #B83E47, one step out in green. Imperceptible. */
    --phid-scene-coverage: #25635F;
    --phid-scene-acen:     #B83E47;

    /* Readable derivations of the hover amber, for the annotation label that
       sits over the canvas. Pinned with it — they carry the same meaning. */
    --phid-scene-hover-text: #6B4C07;
    --phid-scene-hover-edge: #E3C98A;

    /* Overlay panels drawn ON the canvas rather than on the page, so they are
       keyed to the scene background, not to the theme. */
    --phid-scene-overlay: rgba(255, 255, 255, 0.86);


    /* ======================================================================
       9. Status
       ----------------------------------------------------------------------
       Outside the brand palette, deliberately: a job that failed must not be
       confusable with a brand accent, and the kit contains no red or green.
       Kept desaturated so they sit with the palette rather than shouting.
       ====================================================================== */

    --phid-ok:     light-dark(#2F6B4F, #7FC4A0);  /* 6.29:1 / 7.87:1 */
    /* 2026-09-06: BLUE, not amber, at the maintainer's request — and the whole
       token moves, so everything that means "warning" moves with it: the "Good"
       quality band on the Data page and in the directory rail, the quality chips,
       and the beta notice on the home page. That was the choice, made knowingly
       over giving the quality bands a colour of their own.
       Contrast is held to the same standard as the colour it replaces: 5.75:1 on
       the light card against 5.89:1 before, and 8.54:1 on the dark card against
       8.41:1. Note the dark value is no longer #F4AC75, which was the dark
       accent as well — warn and accent are now distinguishable in dark mode,
       which they were not. */
    --phid-warn:   light-dark(#1565C0, #8AC2FA);  /* 5.75:1 / 8.54:1 */
    --phid-danger: light-dark(#A3323F, #E98C96);  /* 6.81:1 / 6.61:1 */
    --phid-info:   var(--phid-accent);

    --phid-ok-wash:     light-dark(rgba(47, 107, 79, 0.10),  rgba(127, 196, 160, 0.14));
    --phid-warn-wash:   light-dark(rgba(21, 101, 192, 0.10), rgba(138, 194, 250, 0.14));
    --phid-danger-wash: light-dark(rgba(163, 50, 63, 0.09),  rgba(233, 140, 150, 0.14));


    /* ----------------------------------------------------------------------
       9b. Pipeline stage — colour encodes POSITION, not condition
       ----------------------------------------------------------------------
       §9 says what happened to a job. This says how far along it is. The five
       stages ride the §8 sequential ramp in pipeline order, so a dashboard can
       be read for progress by colour alone.

       DO NOT print a label in these colours. The ramp runs dark-to-light in
       both themes, which is what makes it sequential, and that means no single
       label colour survives it — measured on the card surface, seq-1 gives
       9.44:1 in light but 2.52:1 in dark, and seq-4 does the reverse. Both
       ends fail AA in one theme or the other.

       The badge recipe that does work, and the only supported use:

           .status-<stage> {
               background: color-mix(in srgb, var(--phid-stage-X) 14%,
                                              var(--phid-surface-card));
               box-shadow: inset 2px 0 0 var(--phid-stage-X);
               color: var(--phid-text);        <-- always, never the stage token
           }

       The wash barely moves the surface luminance, so --phid-text stays above
       13:1 in both themes; the hue is carried by the fill and the bar, where
       contrast does not apply. Terminal states are NOT here — completed, failed
       and pending are conditions, so they take --phid-ok / -danger / -warn.
       ---------------------------------------------------------------------- */

    --phid-stage-preprocessing: var(--phid-seq-1);
    --phid-stage-optimization:  var(--phid-seq-2);
    --phid-stage-msd:           var(--phid-seq-3);
    --phid-stage-losstangent:   var(--phid-seq-4);
    --phid-stage-zarr:          var(--phid-accent);


    /* ======================================================================
       10. Type scale
       ====================================================================== */

    --phid-font-sans: "PHiD Sans", "Source Sans 3", system-ui, -apple-system,
                      "Segoe UI", "Noto Sans CJK JP", "Noto Sans JP",
                      "Hiragino Kaku Gothic ProN", "Yu Gothic UI", sans-serif;
    --phid-font-mono: ui-monospace, "SFMono-Regular", "JetBrains Mono",
                      "DejaVu Sans Mono", Menlo, Consolas, monospace;

    --phid-text-xs:  11px;   /* uppercase labels, table heads */
    --phid-text-sm:  13px;
    --phid-text-md:  14px;   /* body */
    --phid-text-lg:  15px;
    --phid-text-xl:  17px;   /* stat values */
    --phid-text-2xl: 20px;   /* page title */

    --phid-weight-normal: 400;
    --phid-weight-medium: 600;
    --phid-weight-bold:   700;

    --phid-leading-tight: 1.25;
    --phid-leading-body:  1.6;
    --phid-tracking-caps: 0.05em;   /* the xs uppercase label treatment */
    --phid-tracking-tight: -0.01em; /* headings only */


    /* ======================================================================
       11. Space, radius, elevation
       ----------------------------------------------------------------------
       The structural half of the retired bdr-theme.css lands here (2026-08-05
       §5.1). Its 14px radius is split into a scale: controls take sm, cards md.
       Dark elevation leans on the border rather than the shadow, because a
       shadow on a near-black surface does almost nothing.
       ====================================================================== */

    --phid-space-1:  4px;
    --phid-space-2:  8px;
    --phid-space-3: 12px;
    --phid-space-4: 16px;
    --phid-space-5: 20px;
    --phid-space-6: 24px;
    --phid-space-8: 32px;
    --phid-space-10: 40px;

    --phid-radius-sm:   8px;   /* inputs, buttons, chips */
    --phid-radius-md:  12px;   /* cards, panels */
    --phid-radius-lg:  16px;   /* landing surfaces */
    --phid-radius-pill: 999px;

    --phid-shadow-card: light-dark(0 1px 2px rgba(27, 36, 49, 0.05),
                                   0 1px 2px rgba(0, 0, 0, 0.40));
    --phid-shadow-pop:  light-dark(0 12px 28px rgba(27, 36, 49, 0.14),
                                   0 12px 28px rgba(0, 0, 0, 0.55));

    --phid-transition: 0.18s ease;


    /* ======================================================================
       12. Logo
       ----------------------------------------------------------------------
       Guideline pages 09–10: minimum sizes, and proportions must not be
       altered. There is no icon-only or P-only mark in the kit, so the logo
       cannot go in a 60px nav bar — the navigation stays textual and the mark
       gets a header or landing area with room (decision: 2026-08-04 §18.3).
       Each variant also carries a clear-space margin of 2A on every side.
       ====================================================================== */

    --phid-logo-basic-min-width: 138px;  /* → 94px tall,  aspect 1.466:1 */
    --phid-logo-tset-min-width:  138px;  /* → 107px tall, aspect 1.290:1 */
    --phid-logo-yset-min-width:  202px;  /* → 100px tall, aspect 2.030:1 */

    /* Isolation space. The guideline (page 07) reserves 2A on every side, where
       A is the width of the P's stem — 39.68 of the 876.25 viewBox units, i.e.
       4.53% of the rendered width. At the 138px minimum that is 12.5px. */
    --phid-logo-isolation: 13px;

    /* The mark's six paint roles. The _A and _B colourways are the designer's
       own light and dark artwork, so switching between them is specified use,
       not recolouring — which page 10 forbids.

       --phid-logo-knock is the two dots on the D. Both source files paint them
       the background colour (white in _A, black in _B): they are holes, not
       white marks, so they follow the surface the logo is placed on. Put the
       logo on anything other than a card surface and this token must be
       overridden to match, or the dots will show as blobs. */
    --phid-logo-p1:    light-dark(#264677, #3C5985);  /* navy   — outer bowl */
    --phid-logo-p2:    light-dark(#6E6680, #7D758D);  /* violet */
    --phid-logo-p3:    light-dark(#B1867D, #B9928A);  /* rose   */
    --phid-logo-p4:    light-dark(#F3A366, #F4AC75);  /* dawn   — inner bowl */
    --phid-logo-word:  light-dark(#000000, #FFFFFF);  /* "Hi-D" */
    --phid-logo-knock: var(--phid-surface-card);
}


/* ==========================================================================
   13. The mark itself
   --------------------------------------------------------------------------
   The one place this file styles elements rather than declaring tokens. It
   earns the exception: the minimum width is a brand rule, and enforcing it
   here means no page can violate it by writing its own width.

   The mark is inlined into the page rather than served as an <img>, because
   an <img> can only follow prefers-color-scheme — the OS — and would ignore a
   [data-theme] override. Inlined, its fills resolve through the same
   light-dark() path as everything else and the two stay in step.
   ========================================================================== */

.brand-logo {
    display: block;
    flex: none;
    width: var(--phid-logo-basic-min-width);
    /* height:auto with the width above; the intrinsic ratio comes from the file's own
       width/height attributes now that the mark is an <img> rather than an inline SVG
       with a viewBox. Stated on the element so the header does not reflow while the
       image loads. */
    height: auto;
    margin-inline-end: var(--phid-logo-isolation);  /* the 2A the guideline reserves */
}

.brand-logo .lg-p1    { fill: var(--phid-logo-p1); }
.brand-logo .lg-p2    { fill: var(--phid-logo-p2); }
.brand-logo .lg-p3    { fill: var(--phid-logo-p3); }
.brand-logo .lg-p4    { fill: var(--phid-logo-p4); }
.brand-logo .lg-word  { fill: var(--phid-logo-word); }
.brand-logo .lg-knock { fill: var(--phid-logo-knock); }
