/* PremierMaint design tokens (R1-D24).
 *
 * This is the ONLY file allowed to contain a colour, radius, shadow or motion literal. Every other
 * stylesheet uses var(--…). tests/theme_test.php fails the build when a literal appears elsewhere,
 * which is what stops the three shells drifting apart again.
 *
 * Loaded first by index.html, admin.html and portal.html, before every other stylesheet.
 *
 * The look is a flat, utilitarian field-work system (R1-D23): solid fills, 1 px borders and spacing
 * instead of shadows, two radii, one brand colour, and status colours that only ever mean Pass,
 * Attention, Fail or Info.
 *
 * Contrast is a tested property, not a hope: tests/js/contrast.test.mjs reads this file and checks
 * 4.5:1 for text, 3:1 for control borders and the focus ring, and 7:1 for body text, because the
 * technician app is read on a phone in sunlight.
 */

:root {
  /* ---- Neutrals -------------------------------------------------------------------
   * A warm ramp, so the app reads as paper and ink rather than as a blue-grey dashboard.
   * Named by role, not by shade, so a dark theme later is a second block of values and
   * no markup change at all.
   */
  --paper: #f7f6f4;          /* the page */
  --panel: #ffffff;          /* cards, tables, inputs */
  --panel-sunk: #f2f0ed;     /* table headers, inset wells, disabled fields */
  --ink: #1a1a18;            /* body text: 16.1:1 on paper, 17.4:1 on panel */
  --muted: #5f5c57;          /* secondary text: 6.2:1 on paper */
  --line: #e2dfda;           /* separators between rows and sections */
  --line-strong: #949494;    /* borders of inputs and buttons: 3.0:1 on panel */

  /* ---- Brand ----------------------------------------------------------------------
   * One colour, for primary buttons, links and the active tab. Nothing else.
   *
   * Admin → Settings decides it, so a contractor rebrands the app and its reports from one
   * field. shared/branding.js overwrites --brand at runtime and DERIVES the four below from
   * it, because an admin can pick a colour that white text vanishes on. The values here are
   * the default and the fallback when Settings has not been filled in or the request fails.
   */
  --brand: #087d7a;          /* 4.97:1 against white, both directions */
  --brand-ink: #ffffff;      /* text and icons ON the brand colour */
  --brand-strong: #06605e;   /* hover and active */
  --brand-tint: #e6f3f2;     /* selected rows, quiet emphasis */
  --brand-on-tint: #065754;  /* text on that tint */

  /* ---- Status ---------------------------------------------------------------------
   * Four meanings, each with a solid (icons, bars, left rules), an ink for text on the tint,
   * and the tint itself. Never used for decoration or navigation, and never the only cue:
   * every use carries an icon or a word, so the app still reads in greyscale.
   */
  --ok: #0a6b50;        --ok-ink: #08543f;        --ok-tint: #e8f3ee;
  --warn: #8a4b05;      --warn-ink: #7a4205;      --warn-tint: #fdf0dd;
  --fail: #a3291f;      --fail-ink: #8c241b;      --fail-tint: #fdeceb;
  --info: #1b5e9c;      --info-ink: #17528a;      --info-tint: #e9f1f9;

  /* ---- Charts ---------------------------------------------------------------------
   * The Okabe–Ito set: eight hues that stay distinguishable with any common colour blindness.
   * Charts also vary shape or label, so colour is never carrying the meaning alone. Okabe–Ito's
   * sky blue is darkened from #56b4e9 to #3a94cc and its orange from #e69f00 to #b87d00, because
   * the originals are 2.3:1 on white and a chart line has to clear 3:1 like any other non-text
   * mark. The other six are unchanged.
   */
  --chart-1: #0072b2;  --chart-2: #b87d00;  --chart-3: #009e73;  --chart-4: #cc79a7;
  --chart-5: #3a94cc;  --chart-6: #d55e00;  --chart-7: #8a7fb5;  --chart-8: #6b6762;
  --chart-axis: #6b6762;     /* 5.6:1 on panel: axis labels are text */
  --chart-grid: #e2dfda;

  /* ---- Type -----------------------------------------------------------------------
   * One text face, one mono face (R1-D25), self-hosted. The mono face carries tag IDs,
   * report numbers and measurements, where a 0 must not read as an O.
   */
  --font: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Six sizes, no others. Body is 16px in the technician app and 14px in admin. */
  --text-xs: 12px;    /* table column headers, chips, captions */
  --text-sm: 14px;    /* admin body */
  --text-md: 16px;    /* technician body, inputs (also stops iOS zooming on focus) */
  --text-lg: 18px;    /* section headings */
  --text-xl: 22px;    /* page titles */
  --text-2xl: 28px;   /* the one number a screen is about, and measurement readouts */

  --weight-normal: 400;
  --weight-medium: 500;
  --weight-bold: 650;   /* headings and buttons; Plex Sans has a real 600, 650 picks SemiBold */

  --leading-tight: 1.25;
  --leading-normal: 1.5;

  /* ---- Space ----------------------------------------------------------------------
   * A 4px scale. Every margin, padding and gap uses one of these seven values.
   */
  --space-1: 4px;   --space-2: 8px;   --space-3: 12px;  --space-4: 16px;
  --space-5: 24px;  --space-6: 32px;  --space-7: 48px;

  /* ---- Shape ----------------------------------------------------------------------
   * Two radii. Status dots are the only full circle. No pill-shaped buttons.
   */
  --radius: 3px;        /* controls, inputs, panels, chips */
  --radius-lg: 6px;     /* dialogs and the large technician buttons */
  --radius-dot: 50%;
  --radius-pill: 999px;  /* counts and badges: a capsule whatever the text length */

  --border: 1px;
  --border-thick: 2px;  /* the left rule on a finding, the active tab underline */

  /* The one shadow in the system, for things that float above the page: dialogs and menus.
   * Panels and cards are separated by borders and spacing instead. */
  --shadow-pop: 0 8px 24px rgba(26, 26, 24, 0.18);

  /* ---- Focus ----------------------------------------------------------------------
   * Visible on every control, for keyboard users and for gloved taps that half-land.
   */
  --focus: #1b5e9c;             /* 3:1 against panel and paper */
  --focus-ring: 0 0 0 3px rgba(27, 94, 156, 0.35);
  --focus-width: 2px;

  /* ---- Motion ---------------------------------------------------------------------
   * Short and few. Nothing animates that a technician is waiting on.
   */
  --motion-fast: 120ms;
  --motion-slow: 200ms;
  --ease: cubic-bezier(0.2, 0, 0.2, 1);

  /* ---- Targets --------------------------------------------------------------------
   * Gloves, a ladder, and a phone held one-handed.
   */
  --tap: 48px;        /* every control the technician app shows */
  --tap-lg: 64px;     /* the primary action on a screen, and the camera button */
  --tap-admin: 36px;  /* desktop admin, where a mouse is pointing */
}

/* Respect the system setting rather than animating regardless. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-fast: 0ms;
    --motion-slow: 0ms;
  }
}

/* Print. An admin prints a reports list or an inspection to take into a meeting; the PDF report
 * has its own layout and is untouched by this.
 *
 * Tints either vanish or turn to mud on an office printer, so the whole palette collapses to ink
 * on white and meaning moves to the words, the borders and the left rules, which survive greyscale.
 * It is the same token names redefined, so no component rule needs a print variant of its own. */
@media print {
  :root {
    --paper: #ffffff;
    --panel: #ffffff;
    --panel-sunk: #ffffff;
    --brand-tint: #ffffff;
    --ok-tint: #ffffff;
    --warn-tint: #ffffff;
    --fail-tint: #ffffff;
    --info-tint: #ffffff;
    --ink: #000000;
    --muted: #444444;
    --line: #999999;
    --line-strong: #666666;
    --brand: #000000;
    --brand-ink: #ffffff;
    --ok: #000000;
    --warn: #000000;
    --fail: #000000;
    --info: #000000;
    --ok-ink: #000000;
    --warn-ink: #000000;
    --fail-ink: #000000;
    --info-ink: #000000;
    --brand-on-tint: #000000;
    --shadow-pop: none;
  }
}
