/* ==========================================================================
   CCS ASPIRE — design tokens
   Special Education Document Creator and Tracking Solution
   Columbus City Schools

   Load this BEFORE any component stylesheet. Set the theme with
   data-theme="light" | "dark" | "hc" on <html>. Light is the default.

   Colour values are derived from the Columbus City Schools Brand & Style
   Guide. CCS Red is reserved for district identity and is NEVER used to
   signal status — see the status section.
   ========================================================================== */

/* -------------------------------------------------------------- fonts --- */
/* Self-hosted in css/fonts/aspire-fonts.css, linked ahead of this file in
   index.html. Not @import-ed from Google: district networks may block the
   CDN, and the prototype is expected to run with no network at all. */

:root {
  /* --- district identity (fixed across all themes) -------------------- */
  --ccs-red: #be2036;         /* PMS 200C — identity only, never status */
  --ccs-navy: #192751;        /* PMS 539C */
  --ccs-blue: #00649d;        /* PMS 2945C */
  --ccs-light-blue: #9fd1ee;  /* PMS 291C — tint and dark-on-navy text only */

  /* --- type families -------------------------------------------------- */
  --font-display: "Poppins", "Avenir Next", "Trebuchet MS", sans-serif;
  --font-body: "Atkinson Hyperlegible", "Verdana", "Tahoma", sans-serif;
  --font-doc: "Noto Serif", Georgia, "Times New Roman", serif;
  --font-data: "Roboto Mono", ui-monospace, Menlo, monospace;

  /* --- spacing (4px grid) --------------------------------------------- */
  --space-2xs: 2px;
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 12px;
  --space-base: 16px;
  --space-lg: 24px;
  --space-xl: 32px;
  --space-2xl: 48px;
  --space-3xl: 64px;

  /* --- radius ---------------------------------------------------------- */
  --radius-xs: 3px;
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 14px;
  --radius-pill: 999px;

  /* --- type scale ------------------------------------------------------ */
  /* Sizes are deliberately larger than a typical SaaS scale. Body is 16px,
     secondary 15px, and nothing in the interface goes below 14px. */
  --text-display-size: 36px;      --text-display-line: 44px;
  --text-title1-size: 28px;       --text-title1-line: 36px;
  --text-title2-size: 21px;       --text-title2-line: 28px;
  --text-title3-size: 18px;       --text-title3-line: 24px;
  --text-body-lg-size: 19px;      --text-body-lg-line: 28px;
  --text-body-size: 16px;         --text-body-line: 26px;
  --text-small-size: 15px;        --text-small-line: 22px;
  --text-label-size: 15px;        --text-label-line: 20px;
  --text-eyebrow-size: 13px;      --text-eyebrow-line: 18px;
  --text-doc-title-size: 22px;    --text-doc-title-line: 30px;
  --text-doc-heading-size: 17px;  --text-doc-heading-line: 24px;
  --text-doc-body-size: 15px;     --text-doc-body-line: 24px;
  --text-doc-note-size: 13px;     --text-doc-note-line: 20px;
  --text-data-size: 15px;         --text-data-line: 22px;
}

/* ====================================================== LIGHT (default) === */
:root,
[data-theme="light"] {
  --surface-page: #faf7f3;      /* warm paper, not #fff — long sessions */
  --surface-raised: #ffffff;
  --surface-subtle: #f2ede7;
  --surface-sunken: #efeae4;

  --line: #e2d9cf;              /* decorative hairline; exempt from 3:1 */
  --line-strong: #8c8078;       /* meaningful borders — 3.8:1 on raised */

  --ink-strong: #221e1a;
  --ink: #3a332d;
  --ink-muted: #4a423c;         /* 9.2:1 on page */
  --ink-on-fill: #ffffff;

  --brand: #192751;             /* primary actions, app chrome */
  --brand-hover: #0f1a3a;
  --brand-wash: #e7ecf5;
  --on-brand: #ffffff;

  --link: #00649d;
  --link-hover: #192751;

  --identity: #be2036;          /* the district rule and mark ground */

  --focus-ring: #00649d;

  /* status — see the four-channel rule in RESTYLE-ASPIRE.md */
  --status-not-started: #5c534b;  --wash-not-started: #efeae4;
  --status-in-progress: #00649d;  --wash-in-progress: #e1eef6;
  --status-due-soon: #8a5a00;     --wash-due-soon: #f7eedb;
  --status-past-due: #7f3314;     --wash-past-due: #f6e7e0;
  --status-complete: #0f5f4a;     --wash-complete: #e4f0ea;

  /* select chevron: a data URI cannot read a token, so the image itself is one */
  --chevron: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%234a423c' stroke-width='2'><path d='M6 9l6 6 6-6'/></svg>");

  --shadow-raised: 0 1px 2px #221e1a14, 0 2px 8px #221e1a0f;
  --shadow-overlay: 0 8px 32px #221e1a26;
  --overlay: #221e1ab3;
}

/* ================================================================ DARK === */
[data-theme="dark"] {
  --surface-page: #16181f;
  --surface-raised: #1e222c;
  --surface-subtle: #272c38;
  --surface-sunken: #0f1117;

  --line: #343a47;
  --line-strong: #6f7889;       /* 3.6:1 on raised */

  --ink-strong: #f4f2ef;
  --ink: #e2ddd7;
  --ink-muted: #aaa49c;         /* 7.1:1 on page */
  --ink-on-fill: #0b1220;

  --brand: #5aa6d8;             /* navy is unreadable on dark — lift to blue */
  --brand-hover: #7cbce6;
  --brand-wash: #17293f;
  --on-brand: #0b1220;

  --link: #7cbce6;
  --link-hover: #a4d3f0;

  --identity: #be2036;          /* unchanged: the mark is never recoloured */

  --focus-ring: #9fd1ee;

  --status-not-started: #a8a199;  --wash-not-started: #2a2e36;
  --status-in-progress: #5aa6d8;  --wash-in-progress: #12283a;
  --status-due-soon: #e0a94a;     --wash-due-soon: #35290f;
  --status-past-due: #d97a55;     --wash-past-due: #3a2116;
  --status-complete: #5fc9a2;     --wash-complete: #10312a;

  --chevron: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23aaa49c' stroke-width='2'><path d='M6 9l6 6 6-6'/></svg>");

  --shadow-raised: 0 1px 2px #00000066, 0 2px 8px #00000059;
  --shadow-overlay: 0 8px 32px #00000080;
  --overlay: #000000cc;
}

/* ====================================================== HIGH CONTRAST === */
[data-theme="hc"] {
  --surface-page: #000000;
  --surface-raised: #000000;
  --surface-subtle: #1c1c1c;
  --surface-sunken: #000000;

  --line: #ffffff;
  --line-strong: #ffffff;

  --ink-strong: #ffffff;
  --ink: #ffffff;
  --ink-muted: #e8e8e8;
  --ink-on-fill: #000000;

  --brand: #ffffff;
  --brand-hover: #e8e8e8;
  --brand-wash: #000000;
  --on-brand: #000000;

  --link: #9fd1ee;
  --link-hover: #ffffff;

  --identity: #ff5f70;

  --focus-ring: #ffd400;

  --status-not-started: #d0d0d0;  --wash-not-started: #000000;
  --status-in-progress: #7fd4ff;  --wash-in-progress: #000000;
  --status-due-soon: #ffd400;     --wash-due-soon: #000000;
  --status-past-due: #ff9e66;     --wash-past-due: #000000;
  --status-complete: #46ff9e;     --wash-complete: #000000;

  --chevron: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23ffffff' stroke-width='2'><path d='M6 9l6 6 6-6'/></svg>");

  --shadow-raised: none;
  --shadow-overlay: none;
  --overlay: #000000e6;
}

/* ---------- chart series ----------
   Four categorical hues for data series, distinct from every --status-* token:
   a chart line must never be mistaken for a state signal, and CCS Red is
   identity and appears in neither. Chosen to stay separable under the three
   common forms of colour blindness — blue, bronze, violet and green differ in
   lightness as well as hue, so they survive greyscale too. Order is fixed and
   never cycled: series 1 is always series 1 across every chart on a screen. */
:root, [data-theme="light"] {
  --chart-1: #00649d;
  --chart-2: #8a5a2b;
  --chart-3: #5b4b8a;
  --chart-4: #1f6f5c;
}
[data-theme="dark"] {
  --chart-1: #5aa6d8;
  --chart-2: #c99a63;
  --chart-3: #a397d4;
  --chart-4: #5fc9a2;
}
[data-theme="hc"] {
  --chart-1: #7fd4ff;
  --chart-2: #ffd400;
  --chart-3: #d0b0ff;
  --chart-4: #46ff9e;
}

/* ============================================== THE NAV CHROME === */
/* The rail, the phone app bar and the sign-in backdrop are one painted brand
   surface: CCS navy, in all three themes. That is what this block exists to say.

   They used to be painted with an old slate name that the (since deleted)
   compatibility shim pointed at --ink-strong — a token for TEXT on light
   paper. Two things went wrong. The rail came out a warm near-black rather
   than navy; and the district name and the two role labels, drawn from the same page ink ramp, landed dark-on-dark at 1.68:1,
   which is invisible rather than merely low. On top of that --ink-strong flips to
   near-white in Dark and pure white in HC, so the rail inverted against the page
   in exactly the themes a reviewer switches to in order to check contrast.

   So the chrome carries its own ink ramp and does NOT follow the theme. A viewer
   choosing Dark should not be handed a light-blue sidebar, and High Contrast must
   never turn it white. Declared once here; only HC refines it, and only upward.

   Measured on the navy ground — the body-text line is 4.5:1:
     --on-chrome        14.5:1        --on-chrome-subtle    9.7:1
     --on-chrome-muted  11.5:1        --on-chrome-label     8.9:1

   The translucent whites are tokens rather than rgba() spelled out at each use
   because they were the last scattered colour literals left outside this file. */
:root {
  --chrome: #192751;             /* CCS navy — the rail ground */
  --on-chrome: #ffffff;          /* wordmark, persona name, the active pill's text */
  --on-chrome-muted: #dfe6f2;    /* menu links */
  --on-chrome-subtle: #c9d4e8;   /* district name, and the role beneath the persona */
  --on-chrome-label: #9fd1ee;    /* the role label above the menu, and the here-marker */
  --chrome-hairline: #ffffff24;  /* the two dividers and the submenu rail */
  --chrome-hover: #ffffff14;     /* hovered menu item, resting sign-out button */
  --chrome-hover-strong: #ffffff29;

  /* The identity-provider screens are deliberately not CCS Aspire — the whole
     point of the hand-off is that the credential is typed somewhere else — so
     their backdrop is a neutral slate rather than the navy. It is fixed across
     themes for the same reason the navy is: the ink on it is fixed too. */
  --chrome-alt: #2b2f38;

  /* ---------- the sign-in brand panel ----------
     The left half of the sign-in screen: the mark, the name, the ASPIRE ladder
     and the district lockup, on a navy that deepens toward the bottom-right.

     Fixed across all three themes, and that is a decision rather than an
     oversight. A district sign-in screen is the one surface a visitor meets
     before they have a session, so there is nobody yet whose theme preference
     could apply — and a school district's front door inverting to near-white
     because the laptop is in Dark would read as a different institution. The
     inks below are therefore fixed too, exactly as the rail's are.

     Measured against the LIGHTEST stop, #2c3b72, because that is the worst
     case; every other stop is darker and reads higher:
       --on-brand-panel        10.63:1      --on-brand-panel-word    8.97:1
       --on-brand-panel-subtle  6.84:1 */
  --brand-panel: radial-gradient(135% 110% at 0% -12%,
    #2c3b72 0%, #1d2b57 38%, #13203f 70%, #0b1228 100%);
  --brand-panel-lightest: #2c3b72;  /* the stop the contrast above is measured on */
  --on-brand-panel: #ffffff;        /* the ASPIRE title and the ladder letters */
  --on-brand-panel-word: #e6ecf8;   /* the six ladder words */
  --on-brand-panel-subtle: #c3d0e8; /* the descriptor under the district lockup */
  --brand-panel-hairline: #ffffff33;

  /* ---------- the demonstration banner ----------
     Amber, and deliberately NOT red. CCS Red is doing identity work in the 6px
     rule directly above this band; a red band would both collide with that and
     read as an error, which this is not — it is a standing statement of what
     this environment is. It is also not on the status ramp, because it reports
     nothing about any student's record. Fixed across themes with the rest of
     the sign-in chrome. The ink reads 7.94:1 on the fill; the icon is 4.21:1,
     which clears the 3:1 that a graphic needs and is all it has to clear,
     because it is decorative and the sentence beside it carries the meaning. */
  --notice: #f6e7c8;
  --notice-line: #e0c99b;
  --notice-ink: #5b3f12;
  --notice-icon: #93641a;
}

/* High contrast wants more separation, not the same amount: every chrome ink goes
   to pure white and the dividers stop being translucent. The ground stays navy,
   because it is identity and it already measures 14.5:1 against white. */
[data-theme="hc"] {
  --on-chrome-muted: #ffffff;
  --on-chrome-subtle: #ffffff;
  --on-chrome-label: #ffffff;
  --chrome-hairline: #ffffff;
  --chrome-hover: #ffffff2e;
  --chrome-hover-strong: #ffffff4d;
}

/* ---------- the marks ----------
   The ASPIRE mark is real artwork now: the SVG files in img/brand, rendered by
   brandMark() in app.js and styled by .brand-mark in aspire-components.css. The
   dashed "CCS" placeholder that used to live here is gone with it.

   The Columbus City Schools apple is still NOT drawn, here or anywhere. The
   district's guide forbids recreating, recolouring, rotating or cropping its
   logo and requires red or white only, so an approximation drawn in this file
   would breach that guide inside a bid submitted to the district that wrote it.
   When CCS Communications supplies the artwork it sits BESIDE the ASPIRE mark —
   separated by a vertical rule, district mark given priority — never merged into
   one combined lockup. */

/* The one place CCS Red appears in the interface: a 4px identity rule under
   the app chrome. It is never a status, never an error, never a required-field
   marker. If this token turns up anywhere else, that is a bug. */
.sidebar .brand { border-block-end: 4px solid var(--identity); }

/* ---------------------------------------------------- type utilities --- */
/* Use these rather than setting a font-size by hand anywhere in the app. */

.asp-display     { font-family: var(--font-display); font-size: var(--text-display-size); line-height: var(--text-display-line); font-weight: 600; letter-spacing: -0.01em; color: var(--ink-strong); }
.asp-title-1     { font-family: var(--font-display); font-size: var(--text-title1-size); line-height: var(--text-title1-line); font-weight: 600; color: var(--ink-strong); }
.asp-title-2     { font-family: var(--font-display); font-size: var(--text-title2-size); line-height: var(--text-title2-line); font-weight: 600; color: var(--ink-strong); }
.asp-title-3     { font-family: var(--font-display); font-size: var(--text-title3-size); line-height: var(--text-title3-line); font-weight: 600; color: var(--ink-strong); }
.asp-body-lg     { font-family: var(--font-body); font-size: var(--text-body-lg-size); line-height: var(--text-body-lg-line); }
.asp-body        { font-family: var(--font-body); font-size: var(--text-body-size); line-height: var(--text-body-line); }
.asp-body-strong { font-family: var(--font-body); font-size: var(--text-body-size); line-height: var(--text-body-line); font-weight: 700; }
.asp-small       { font-family: var(--font-body); font-size: var(--text-small-size); line-height: var(--text-small-line); color: var(--ink-muted); }
.asp-label       { font-family: var(--font-body); font-size: var(--text-label-size); line-height: var(--text-label-line); font-weight: 700; color: var(--ink-strong); }
.asp-eyebrow     { font-family: var(--font-display); font-size: var(--text-eyebrow-size); line-height: var(--text-eyebrow-line); font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-muted); }

/* Generated documents. Serif so a family can tell at a glance that they are
   holding the IEP and not a printout of a screen. */
.asp-doc-title   { font-family: var(--font-doc); font-size: var(--text-doc-title-size); line-height: var(--text-doc-title-line); font-weight: 600; color: var(--ink-strong); }
.asp-doc-heading { font-family: var(--font-doc); font-size: var(--text-doc-heading-size); line-height: var(--text-doc-heading-line); font-weight: 600; color: var(--ink-strong); }
.asp-doc-body    { font-family: var(--font-doc); font-size: var(--text-doc-body-size); line-height: var(--text-doc-body-line); max-inline-size: 72ch; }
.asp-doc-note    { font-family: var(--font-doc); font-size: var(--text-doc-note-size); line-height: var(--text-doc-note-line); font-style: italic; color: var(--ink-muted); }

/* Student IDs, EMIS numbers, tabular dates — read character by character. */
.asp-data        { font-family: var(--font-data); font-size: var(--text-data-size); line-height: var(--text-data-line); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------- base ---- */
html { color-scheme: light dark; }

body {
  margin: 0;
  background: var(--surface-page);
  color: var(--ink-strong);
  font-family: var(--font-body);
  font-size: var(--text-body-size);
  line-height: var(--text-body-line);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--link); }
a:hover { color: var(--link-hover); }

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

/* ---- The sticky note on the sign-in page (app.css .about-name) ----
   Paper, ink and push pin. Fixed in every theme: it is a note stuck to the
   brand panel, not page furniture. The pin is blue, never CCS Red, which is
   identity only. Ink on paper is above 12:1. */
:root {
  --note-paper: #fff59a;
  --note-paper-deep: #fbe46b;
  --note-ink: #2a2716;
  --note-pin: #2f6fd0;
  --note-pin-light: #cfe2ff;
  --note-pin-dark: #163a78;
}
