/*
 * The tokens every operator tool is drawn from: /vendor, /admin, /console and
 * /door.
 *
 * This is the one file in web/ that four pages share on purpose. The argument
 * against sharing (admin.css, console.css) was that a shared *component* layer
 * made the tools read as one screenshot with the label swapped, and that still
 * holds for components. What is shared here is the palette, and it has to be,
 * because a person picks their theme in one tool and expects the other three
 * to have it. A copy per page could not do that without four files drifting.
 *
 * Two axes, both set as attributes on <html> by lib/theme.js:
 *
 *   data-theme   light | dark
 *   data-accent  green | crimson | midnight | violet | gold
 *
 * Neither is ever absent in practice - lib/theme-boot.js writes both before the
 * first paint - but the bare :root below is the light green default anyway, so
 * a page that somehow loads without the boot script is still drawn.
 *
 * ── Two layers, and which one to reach for ──────────────────────────────────
 *
 * THE RAMP (--g-950 … --g-50) is the accent as a set of nine fixed shades. It
 * does NOT change between light and dark. Reach for it when you are painting
 * something that is dark in both themes: a panel gradient, the plan card, the
 * bright mark that sits on one of those.
 *
 * THE ROLES (--link, --accent, --tint, --thumb, --skel-a …) are what a colour
 * is FOR, and they do change with the theme. Reach for these everywhere else.
 * A link is --link, not --g-700: in dark mode --g-700 is a deep green nobody
 * can read on a #1c1c1f card, and --link is the bright one that works there.
 *
 * Getting that pair the wrong way round is the one mistake this file invites,
 * and it is invisible until somebody opens the other theme.
 */

/*
 * The face the tools are set in. Same-origin, as the pages' font-src 'self'
 * requires. Declared here rather than four times.
 */
@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url("/vendor/plus-jakarta-sans-variable.woff2") format('woff2');
}

/* ── The accent ramps ─────────────────────────────────────────────────────
 *
 * Nine shades plus --g-400, which exists only because dark mode needs a rung
 * between 500 and 300 bright enough to read as type on a dark card. The rungs
 * are theme-independent; the roles further down decide which is used when.
 *
 * The blocks are keyed on plain attribute selectors rather than :root, so a
 * theme can also be put on an element INSIDE the page. The Customize screen's
 * preview needs exactly that: it shows a card in a combination nobody has
 * committed to, on a page drawn in the committed one.
 */

/*
 * The written default, first, and first on purpose: :root and a one-attribute
 * selector have the same specificity, so whichever comes last wins. Below the
 * accent blocks this would have handed every accent green's ramp. It is here
 * for the page that loads without the boot script - mid-load, or a check
 * harness that blanks storage - so the ramp still resolves to something.
 */
:root {
  --g-950: #06241a;
  --g-900: #0a3627;
  --g-800: #0e4d35;
  --g-700: #126644;
  --g-600: #168253;
  --g-500: #1fa566;
  --g-400: #4fd08f;
  --g-300: #8fd8b2;
  --g-100: #e2f4ea;
  --g-50: #f0f9f4;
}

[data-accent="green"] {
  --g-950: #06241a;
  --g-900: #0a3627;
  --g-800: #0e4d35;
  --g-700: #126644;
  --g-600: #168253;
  --g-500: #1fa566;
  --g-400: #4fd08f;
  --g-300: #8fd8b2;
  --g-100: #e2f4ea;
  --g-50: #f0f9f4;
}

[data-accent="crimson"] {
  --g-950: #2a0609;
  --g-900: #400b11;
  --g-800: #5c1018;
  --g-700: #7c1722;
  --g-600: #9d1e2c;
  --g-500: #c42638;
  --g-400: #f0707e;
  --g-300: #ef9aa3;
  --g-100: #fbe4e7;
  --g-50: #fdf2f3;
}

[data-accent="midnight"] {
  --g-950: #050f1e;
  --g-900: #081a30;
  --g-800: #0c2747;
  --g-700: #103763;
  --g-600: #154a83;
  --g-500: #1c60a8;
  --g-400: #5aa0d8;
  --g-300: #94c0e9;
  --g-100: #e1edfa;
  --g-50: #f1f7fd;
}

/*
 * Built out from #5856d6, which is not a new colour here: it is the campus
 * purple /console and /admin already use to mark an institution, and the one
 * the app draws campus pins in.
 */
[data-accent="violet"] {
  --g-950: #150b2e;
  --g-900: #1e1147;
  --g-800: #2b1a68;
  --g-700: #3a248c;
  --g-600: #4a31b0;
  --g-500: #5b45d6;
  --g-400: #9585f2;
  --g-300: #b9aef0;
  --g-100: #e9e5fb;
  --g-50: #f4f2fd;
}

/*
 * The one accent that cannot be taken at face value. A mid gold under white
 * text fails contrast everywhere it matters, so this ramp is darker through
 * the middle than the word suggests: --g-700, which fills a button, is a deep
 * bronze. The bright end lives at 400 and above, where nothing sits on top.
 */
[data-accent="gold"] {
  --g-950: #2a1c02;
  --g-900: #3e2a04;
  --g-800: #573c06;
  --g-700: #745108;
  --g-600: #96690b;
  --g-500: #c08610;
  --g-400: #dda63a;
  --g-300: #f0cc76;
  --g-100: #fbeeca;
  --g-50: #fdf7e8;
}

/* ── Light ────────────────────────────────────────────────────────────────
 *
 * Apple's grouped-list palette: a cool grey canvas, white cards that lift off
 * it, and the accent's dark end for anything that is being asked to act.
 */

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

  --bg: #f2f2f5;
  --card: #ffffff;
  --inset: #f5f5f8;
  --inset-hover: #eeeef2;
  --fill: rgba(116, 116, 128, 0.1);
  --fill-2: rgba(116, 116, 128, 0.17);
  --sep: rgba(60, 60, 67, 0.1);
  --sep-2: rgba(60, 60, 67, 0.18);

  --ink: #15171c;
  --ink-2: #585c66;
  --ink-3: #8a8e97;

  /* Accent roles. */
  --link: var(--g-700);
  --link-strong: var(--g-800);
  --accent: var(--g-700);
  --accent-hover: var(--g-800);
  --tint: var(--g-50);
  --tint-2: var(--g-100);
  --tint-line: var(--g-100);
  /* The name the other three tools' stylesheets use for accent-coloured type.
     Same thing as --link; kept so admin.css, console.css and door.css need not
     all be rewritten to say --link. */
  --accent-text: var(--link);
  /* The hover of a white button sitting ON an accent panel. That panel is dark
     in both themes, so this is the light tint in both. */
  --on-panel-hover: var(--g-100);

  /* Greys with a job. */
  --thumb: #ffffff;
  --level-0: #dfe3e8;
  --hatch: #c9ccd3;
  --star-off: #d7dae0;
  --switch-off: #d5d7dd;
  --skel-a: #e9e9ee;
  --skel-b: #f4f4f7;
  --preview-a: color-mix(in srgb, var(--g-500) 10%, var(--card));
  --preview-b: color-mix(in srgb, var(--g-500) 4%, var(--card));
  --inst-base: #121417;
  --inst-edge: transparent;
  --toast-bg: rgba(21, 23, 28, 0.92);

  --red: #d92d20;
  --red-ink: #b42318;
  --red-tint: #fdecea;
  --red-line: #f5c6c1;
  --warn-tint: #fff4e5;
  --warn-ink: #8a4b00;
  /* The older name for the same tint, used by /vendor's plan notice. */
  --warn-bg: var(--warn-tint);

  --shadow-card: 0 1px 2px rgba(18, 24, 38, 0.04), 0 10px 28px -14px rgba(18, 24, 38, 0.12);
  --shadow-lift: 0 2px 6px rgba(18, 24, 38, 0.05), 0 22px 44px -18px rgba(18, 24, 38, 0.26);
  --shadow-thumb: 0 1px 2px rgba(0, 0, 0, 0.1), 0 3px 10px rgba(0, 0, 0, 0.07);
}

/* ── Dark ─────────────────────────────────────────────────────────────────
 *
 * The same roles at night values: near-black ground, raised grey cards, and
 * the accent's bright end for type. Only tokens change; every rule in
 * lib/shell.css and the four tools' stylesheets reads them.
 *
 * Written once, not twice. lib/theme-boot.js resolves `system` against
 * prefers-color-scheme before the first paint and stamps data-theme either
 * way, so there is no case where the attribute is missing and a media query
 * has to stand in for it.
 */

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

  --bg: #0a0a0c;
  --card: #1c1c1f;
  --inset: #28282c;
  --inset-hover: #313136;
  --fill: rgba(118, 118, 128, 0.24);
  --fill-2: rgba(118, 118, 128, 0.34);
  --sep: rgba(255, 255, 255, 0.08);
  --sep-2: rgba(255, 255, 255, 0.15);

  --ink: #f5f5f7;
  --ink-2: #a8a8ae;
  --ink-3: #86868c;

  /*
   * The accent roles, flipped. Type takes the bright end of the ramp, because
   * --g-700 on a #1c1c1f card is unreadable; a filled button keeps a mid shade
   * so that white on it still passes.
   */
  --link: var(--g-400);
  --link-strong: var(--g-300);
  --accent: var(--g-600);
  --accent-hover: var(--g-500);
  --tint: color-mix(in srgb, var(--g-400) 10%, transparent);
  --tint-2: color-mix(in srgb, var(--g-400) 17%, transparent);
  --tint-line: color-mix(in srgb, var(--g-400) 26%, transparent);
  --accent-text: var(--link);
  --on-panel-hover: var(--g-100);

  --thumb: #636366;
  --level-0: #3a3a3f;
  --hatch: #4d4d53;
  --star-off: #45454b;
  --switch-off: #3a3a3e;
  --skel-a: #1f1f23;
  --skel-b: #2b2b30;
  --preview-a: color-mix(in srgb, var(--g-500) 22%, var(--bg));
  --preview-b: color-mix(in srgb, var(--g-500) 10%, var(--bg));
  --inst-base: #0b0c0d;
  --inst-edge: rgba(255, 255, 255, 0.07);
  --toast-bg: rgba(58, 58, 62, 0.95);

  --red: #ff6b61;
  --red-ink: #ff8a80;
  --red-tint: rgba(255, 69, 58, 0.15);
  --red-line: rgba(255, 69, 58, 0.36);
  --warn-tint: rgba(255, 159, 10, 0.14);
  --warn-ink: #ffb340;
  --warn-bg: var(--warn-tint);

  /*
   * Shadow does almost nothing on a dark ground - there is no light for it to
   * take away - so the lift that separates a card from the page is carried by
   * a hairline instead, and the shadow only deepens the edge.
   */
  --shadow-card: 0 0 0 1px rgba(255, 255, 255, 0.055), 0 12px 30px -14px rgba(0, 0, 0, 0.7);
  --shadow-lift: 0 0 0 1px rgba(255, 255, 255, 0.08), 0 24px 48px -16px rgba(0, 0, 0, 0.85);
  --shadow-thumb: 0 1px 2px rgba(0, 0, 0, 0.45), 0 3px 8px rgba(0, 0, 0, 0.3);
}

/* ── What does not move ──────────────────────────────────────────────────── */

/*
 * The state colours are the map's own: open, busy, sold out, closed. They mean
 * the same thing in the app, on a pin, and here, so they are not part of the
 * accent and do not change when somebody picks a different one. A person who
 * sets the tools to crimson has not asked for "open" to stop being green.
 */
:root {
  --s-open: #1fa566;
  --s-busy: #f08a00;
  --s-sold: #e5383b;
  --s-closed: #8a8e97;
  --gold: #f2a100;

  --ring: 0 0 0 4px color-mix(in srgb, var(--g-500) 22%, transparent);

  --spring: cubic-bezier(0.32, 0.72, 0, 1);
  --ease: cubic-bezier(0.22, 1, 0.36, 1);

  --r-panel: 26px;
  --r-card: 22px;
  --r-ctl: 14px;
  --r-sm: 10px;

  /* One ramp. A size off it is a mistake. */
  --t-cap: 12px;
  --t-foot: 13px;
  --t-sub: 14px;
  --t-body: 15px;
  --t-lead: 17px;
  --t-title3: 20px;
  --t-title2: 24px;
  --t-title: 30px;
  --t-display: 40px;

  --side-w: 264px;
  --gap: 16px;

  --mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;
}

/* A shade brighter on the dark ground, where the light versions sit too close
   to the surface to read at a glance. Same hues. */
[data-theme="dark"] {
  --s-open: #2fc47f;
  --s-busy: #ffa01f;
  --s-sold: #ff5a5d;
  --s-closed: #9a9aa0;
  --gold: #ffb524;
}
