/*
 * The palette. One file, one job per colour.
 *
 * navy   structure -- header, sidebar, headings
 * teal   action    -- buttons, links, toggles, focus, the active edge-bar
 * sand   controls  -- filter pills, inputs, secondary buttons
 * paper  the page
 * coral  THE BRAND MARK, and the Settings section marker (the user's decision, 21 Sep) -- nothing
 *        else. Not a button, not a link, not a chip, not a badge.
 *        It is the one colour that means "Torvi" rather than "do something", and it stops
 *        meaning that the moment it is also a control. So it is NOT a token here: it lives in
 *        client/brand/torvi-mark.svg, which every page shows as an image, and
 *        tools/brandcheck.py fails if the coral's value turns up anywhere else.
 *
 * STATUS COLOURS ARE NOT PART OF THIS. Green means Active, amber means Not submitted, red
 * means destructive, and they mean that regardless of what the interface is painted with.
 * They are listed last and unchanged.
 */
:root {
  /* Structure */
  --navy:      #0B1642;   /* header, sidebar, headings, primary text on light */
  --navy-2:    #1C2A63;   /* active/hover fill inside navy surfaces */
  --navy-text: #B8C2E6;   /* inactive text on navy */

  /* Action */
  --coral:     #E0674A;   /* the mark's coral: the Settings section marker only (brandcheck holds it there) */
  --coral-soft:#FBE7E1;   /* its hover tint on that list, a tint and not the coral */
  --teal:      #0F766E;   /* primary buttons, links, toggles-on, focus rings, active edge */
  --teal-tint: #CCE8E4;   /* selected rows, info banners, teal chip backgrounds */
  /*
   * The pressed/hover state of a teal control. Replaces a darker BLUE (#2A63D6) that 19 rules
   * used for exactly this -- left alone, every button would have turned teal and then flashed
   * blue under the cursor.
   */
  --teal-dark:  #0B5D56;
  --teal-text: #0F4F4A;   /* text on teal-tint */
  /*
   * ALSO ADDED BY THE GATE. --teal on --navy-2 is 2.46:1 -- the active edge-bar the brief
   * asks for would have been very nearly invisible against the fill it sits beside, which is
   * the one thing an active marker cannot be. Same hue, lifted until it reads: 7.23:1.
   * Only ever teal on a navy surface.
   */
  --teal-bright: #2DD4BF;

  /* Controls */
  --sand:      #E9E2D6;   /* filter pills, inputs, secondary controls */
  --sand-text: #5A5040;   /* text on sand */

  /* Surfaces */
  --paper:  #F6F2EC;      /* page background */
  --card:   #FFFFFF;      /* cards */
  /*
   * The warm equivalent of the cool light fills the interface was full of -- hover rows,
   * zebra striping, subtle panels. 248 of those were written out as #E9EDF5 and six near
   * neighbours, none of them a token, so the recolour could not reach them and the interface
   * came out warm where the palette reached and cool where it did not.
   *
   * It is a SURFACE, not a control: a hover row is not something you identify by its edge, so
   * its 1.08:1 against paper is not a contrast failure. What has to be legible is the text on
   * it, and that is measured -- ink 13.33:1, muted 5.38:1.
   */
  --surface-2: #EFE9E0;
  --line:   #E4DCD0;      /* DIVIDERS. Decorative, and WCAG exempts decoration. */
  /*
   * ADDED BY THE CONTRAST GATE, not by the brief. A control has to be distinguishable from
   * the surface it sits on, and neither half of the specified palette does it: --sand on
   * --paper is 1.15:1, so a filter pill is barely an object, and --line at 1.22:1 cannot
   * carry the edge either. #948771 is the lightest value that clears 3:1 on BOTH paper
   * (3.16) and card (3.52). Used for input, pill and secondary-button edges; --line stays
   * for the dividers it was meant for.
   */
  --control-edge: #948771;
  --radius: 14px;

  /* Text */
  --ink:   #1B1F3B;       /* body text */
  --muted: #5F5E5A;       /* secondary text */
  /*
   * HEADINGS, LABELS AND THE TEXT THAT WAS WRITTEN AS --navy (7 Oct, item 22).
   *
   * --navy does two jobs: it is a SURFACE (the sidebar, the tab bar, a hero card) and it was also
   * the colour of a heading, a field label, a person's name in a list, a ghost button's text. The
   * two jobs part company in the dark palette, where the surface must stay navy -- a navy tab bar
   * is navy in both -- and the text must not: navy text on a near-black card is the "navy on dark,
   * unreadable" in every one of the reports, from the Offer sheet's own tab label to "Total 8h 0m"
   * to every label in Edit shift.
   *
   * So the TEXT job gets its own token, identical to --navy in Light and to --ink in Dark, and
   * `color: var(--heading)` is now `color: var(--heading)` everywhere it meant text. --navy keeps the
   * surfaces. Nothing about the light interface changes: the value is the same colour.
   */
  --heading: #0B1642;

  /*
   * Status. Untouched by the recolour, on purpose: these are the colours somebody reads to
   * know whether a shift is covered or a timesheet is late, and they must not shift meaning
   * because the interface was repainted.
   */
  --ok:      #1A9E6F;
  --ok-bg:   #E9F8F1;
  --warn:    #B4740E;
  --warn-bg: #FDF3E3;
  --danger:  #E5484D;
  /*
   * THE SAME RED, DARK ENOUGH TO PUT WHITE ON. --danger carries white at 3.91:1, under the
   * 4.5 a label needs -- fine as a chip colour or as text on a light background, which is
   * what it is everywhere else, and not fine as a button fill with "End shift" written across
   * it. 5.73:1.
   *
   * BUTTON FILLS ONLY. Status chips keep --danger, because a chip's red is a state and must
   * not drift from the red used to say "overdue" elsewhere; the outlined Delete keeps it too,
   * since its red is text on white and already legible.
   */
  --danger-button: #BE3036;
  --green:   #0F9D58;
  --amber:   #B45309;
  /*
   * "In progress" was the same blue as every button, so it changed meaning twice: once as a
   * status and once as an action. It keeps the blue it has always had, under a name that says
   * it is a status -- mapping it to teal would have made a running shift look like a button.
   */
  --status-progress:    #2F6FED;
  --status-progress-bg: #EEF2FB;
  /* The red status chip's own background. Written out as #FDEDEE in the pages that needed it. */
  --danger-bg: #FDEDEE;
  /*
   * STATUS AS TEXT. --ok, --warn, --danger and --status-progress stay exactly as they are -- they
   * are the colours somebody reads a state by, and must not shift meaning. But as the LABEL of a
   * chip on their own tint they measured 3.11, 3.51, 3.45 and 4.06:1, under the 4.5 text needs;
   * nothing had ever put that pair in front of the contrast gate. These are the same hue, stepped
   * down until the label is legible on its tint and on a bare card. Chip labels read these; dots,
   * bars and icons keep the originals.
   */
  --ok-text:     #157E59;
  --warn-text:   #99630C;
  --danger-text: #D31E24;
  --status-progress-text: #1D62EB;

  /*
   * TEXT ON A FILLED COLOUR -- a button label, a tab label, the words on a hero card. Pages
   * have used var(--card) for this, because in the light palette a card is white and so is the
   * label. In the dark palette a card is a dark surface, and "white text on teal" silently
   * becomes navy text on teal. These say what they mean, so the two can differ.
   *
   * --on-teal is dark in the dark palette: the spec's bright dark-mode teal carries white at
   * 2.49:1 and dark ink at 7.38:1.
   */
  --on-teal: #FFFFFF;
  --on-fill: #FFFFFF;   /* on navy, navy-2 and the destructive red, in both palettes */

  /*
   * DEPRECATED, for one release. Existing code still reads these; new code must not.
   * tools/palettecheck.py holds the count at today's number and fails if it grows, so they
   * can only be removed, never added to.
   */
  --blue:        var(--teal);
  --blue-light:  var(--teal);
  --bg:          var(--paper);
  --panel:       var(--card);
  --text-muted:  var(--muted);
  --navy-soft:   var(--navy-2);
}

/* ---- Forced light (decision 2, 19 Sep) ----------------------------------------------------
 *
 * DIALOGS STAY LIGHT IN DARK MODE, for now. A dark-ready screen can open a dialog written for the
 * light palette -- a form with its own inline colours, a signature pad drawn on white -- and in the
 * dark palette those came out light text on a light card. Marked data-force-light, a subtree gets
 * the light values back for every token the dark palette changes -- and every page dialog
 * (.modal-backdrop) is marked so by its class (S5), and the text colour with them
 * (a colour inherited from a dark body is a computed value, not a token, so it has to be set here).
 *
 * ABOVE the dark blocks, and not written `html[...]`, on purpose: it sets a dialog's own tokens, so
 * where it sits in the file does not change what wins -- but the checkers read the palette's LAST
 * value for each token as the one in force, and read every `html[data-dark-ready]` block as a copy
 * of the dark palette.
 */
@media (max-width: 900px) {
  /*
   * ── A DIALOG IS DARK WITH ITS PAGE (7 Oct) ─────────────────────────────────────────────
   *
   * This used to read `.modal-backdrop:not([data-dark-ok])`: every dialog was forced back to the
   * light palette unless somebody had marked it, and six had been. Reported from an iPhone --
   * Edit shift, the Offer shift sheet and Incident all open white in dark mode -- and the list was
   * nineteen dialogs across fourteen pages, not three.
   *
   * The default is the wrong way round for a product whose dark mode is a setting rather than an
   * experiment: a new dialog inherits the palette of the page it is on, and the few surfaces that
   * must stay light say so with data-force-light, which is what that attribute is for. A signature
   * is ink on paper and is printed; a dialog is not.
   */
  [data-dark-ready] [data-force-light] {
    --paper: #F6F2EC; --card: #FFFFFF; --surface-2: #EFE9E0; --ink: #1B1F3B; --muted: #5F5E5A;
    --line: #E4DCD0; --control-edge: #948771; --sand: #E9E2D6; --sand-text: #5A5040;
    --navy: #0B1642; --heading: #0B1642; --navy-2: #1C2A63; --navy-text: #B8C2E6;
    --teal: #0F766E; --teal-dark: #0B5D56; --teal-bright: #2DD4BF; --teal-tint: #CCE8E4; --teal-text: #0F4F4A;
    --on-teal: #FFFFFF; --on-fill: #FFFFFF; --danger-button: #BE3036;
    --ok: #1A9E6F; --ok-bg: #E9F8F1; --warn: #B4740E; --warn-bg: #FDF3E3; --danger: #E5484D; --danger-bg: #FDEDEE;
    --status-progress: #2F6FED; --status-progress-bg: #EEF2FB;
    --ok-text: #157E59; --warn-text: #99630C; --danger-text: #D31E24; --status-progress-text: #1D62EB;
    /* The aliases too: each was resolved at the root from the DARK values, and a custom property
       inherits its computed value -- redefining --card alone leaves --panel dark. */
    --bg: var(--paper); --panel: var(--card); --text-muted: var(--muted); --navy-soft: var(--navy-2);
    --blue: var(--teal); --blue-light: var(--teal);
    color: var(--ink); color-scheme: light;
  }
}

/* ---- Dark ---------------------------------------------------------------------------------
 *
 * ONLY ON THE PHONE SCREENS BUILT FOR IT. A screen opts in with data-dark-ready on <html>, and
 * only at phone width. Every other page reads --navy as its TEXT colour, and --navy stays navy
 * in the dark palette (the tab bar and hero cards are navy in both) -- so switching the whole
 * app would turn every desktop page and every screen not yet redesigned into navy on near-black.
 * A screen that is not dark-ready stays light in dark mode: inconsistent, never illegible.
 *
 * FOLLOWS THE SYSTEM, unless <html data-theme="light|dark"> overrides it. platform.js sets that
 * attribute before first paint from the person's choice in Settings, so an override never
 * flashes the other palette first.
 *
 * THE SAME TOKENS, TWICE, and they must stay identical: once for "the system is dark" and once
 * for "the person chose dark". tools/contrastcheck.py measures every pair in this palette as
 * well as the light one, and fails if the two copies disagree.
 *
 * TWO VALUES DIFFER FROM THE MOBILE SPEC, both by measurement. --danger-button: the spec's
 * #D6454B carries white at 4.36:1, under the 4.5:1 the same spec requires; #C43A40 is the
 * nearest red that clears it (5.22:1) and still stands off the dark page (3.43:1). --on-teal:
 * dark ink on the bright teal, because white on it is 2.49:1.
 */
@media (max-width: 900px) and (prefers-color-scheme: dark) {
  html[data-dark-ready]:not([data-theme="light"]) {
    --paper:      #12162B;
    --card:       #1B2140;
    --surface-2:  #232A4F;
    --ink:        #F4F1EA;
    --muted:      #A9AEC4;
    --line:       #2B3258;
    --control-edge: #7E86AD;
    --sand:       #262D50;
    --sand-text:  #C9CEE3;
    --navy:       #0B1642;
    --heading:    #F4F1EA;
    --navy-2:     #23305E;
    --navy-text:  #B8C2E6;
    --teal:       #14B8A6;
    --teal-dark:  #11A394;
    --teal-bright: #2DD4BF;
    --teal-tint:  #173F3B;
    --teal-text:  #8FE0D4;
    --on-teal:    #0B1230;
    --on-fill:    #FFFFFF;
    --danger-button: #C43A40;
    --ok:         #3FCB95;
    --ok-bg:      #14352B;
    --warn:       #E6A94A;
    --warn-bg:    #3A2D14;
    --danger:     #F2787C;
    --danger-bg:  #3D1C22;
    --status-progress:    #7FA6FF;
    --status-progress-bg: #1C2A55;
    --ok-text:     #3FCB95;
    --warn-text:   #E6A94A;
    --danger-text: #F2787C;
    --status-progress-text: #7FA6FF;
  }
}
@media (max-width: 900px) {
  html[data-dark-ready][data-theme="dark"] {
    --paper:      #12162B;
    --card:       #1B2140;
    --surface-2:  #232A4F;
    --ink:        #F4F1EA;
    --muted:      #A9AEC4;
    --line:       #2B3258;
    --control-edge: #7E86AD;
    --sand:       #262D50;
    --sand-text:  #C9CEE3;
    --navy:       #0B1642;
    --heading:    #F4F1EA;
    --navy-2:     #23305E;
    --navy-text:  #B8C2E6;
    --teal:       #14B8A6;
    --teal-dark:  #11A394;
    --teal-bright: #2DD4BF;
    --teal-tint:  #173F3B;
    --teal-text:  #8FE0D4;
    --on-teal:    #0B1230;
    --on-fill:    #FFFFFF;
    --danger-button: #C43A40;
    --ok:         #3FCB95;
    --ok-bg:      #14352B;
    --warn:       #E6A94A;
    --warn-bg:    #3A2D14;
    --danger:     #F2787C;
    --danger-bg:  #3D1C22;
    --status-progress:    #7FA6FF;
    --status-progress-bg: #1C2A55;
    --ok-text:     #3FCB95;
    --warn-text:   #E6A94A;
    --danger-text: #F2787C;
    --status-progress-text: #7FA6FF;
  }
}

