/* =============================================================
   theme-light.css — light surface for the same instrument.
   Loaded after styles.css; it never changes layout, DOM or behaviour, only
   the values the surface is built from.

   How it works
     1. Everything styles.css hard-codes as a literal colour is re-declared
        here once, in terms of a variable. Those rules are theme-neutral: in
        dark they resolve to exactly the values they replaced, so the dark
        surface is byte-for-byte what it was.
     2. The light values are then a single token payload, applied down two
        paths: the system preference (when the reader has made no explicit
        choice) and the explicit choice (which must win over the system in
        both directions). The payload is emitted twice, at the bottom of this
        file; the two blocks are generated from one source and must stay
        identical.
   ============================================================= */

:root {
  color-scheme: dark;

  /* --- dark defaults: identical to the literals they replace ------------ */
  --page-glow: rgba(63, 185, 80, 0.08);

  --topbar-bg: #0b0e14;
  --verdict-top: #121826;
  --verdict-bottom: #0d1119;
  --verdict-sweep: rgba(120, 160, 255, 0.09);
  --diagnose-bottom: #0e1219;
  --result-bg: rgba(31, 111, 235, 0.07);
  --btn-fg: #06110a;
  --border-hover: #2c3545;
  --active-border: #33507d;
  --active-bg: rgba(31, 111, 235, 0.16);
  --tip-bg: #1b2130;
  --tip-border: #2c3545;
  --control-line: var(--line);
  --control-fill: var(--panel);
  --control-fill-muted: var(--panel-2);

  --chip-hair: rgba(255, 255, 255, 0.035);
  --chip-mark: rgba(230, 233, 240, 0.6);
  --major-bloom: rgba(218, 54, 51, 0.45);

  --col-filter: brightness(1.65);
  --alarm-filter: brightness(1.35);

  --pill-bg-mix: 10%;
  --pill-bd-mix: 28%;
  --pill-bd-mix-warm: 30%;

  --theme-name: "dark";
}

/* =============================================================
   Theme-neutral rewiring. Every rule below reproduces what styles.css
   already draws; the only change is that the literal became a token, so the
   light payload has something to move.
   ============================================================= */

/* ---------- Ground ---------- */

body {
  background-color: var(--bg);
  background-image: radial-gradient(1000px 420px at 50% -200px, var(--page-glow), transparent 70%);
}

/* Dark leaves both tokens unset, so the declaration is inert and the native
   (color-scheme-driven) scrollbar stands; light fills them in the payload. */
html { scrollbar-color: var(--scroll-thumb) var(--scroll-track); }

/* ---------- Top bar ---------- */

.topbar { background: var(--topbar-bg); }

/* ---------- Verdict ---------- */

.verdict { background: linear-gradient(180deg, var(--verdict-top), var(--verdict-bottom)); }

.verdict.is-alert::after { background: linear-gradient(90deg, transparent, var(--verdict-sweep), transparent); }

/* ---------- Wall cells ---------- */

/* Order matches styles.css: the state bloom, then the no-data hairline, then
   the column highlight, then the "now" marker. The no-data hairline stays
   intact at the tracking boundary in both themes. */

.cell[data-state="major_outage"] { box-shadow: 0 0 6px var(--major-bloom); }
.cell[data-state="unknown"], .cell[data-state="no_data"] { box-shadow: inset 0 0 0 1px var(--chip-hair); }
.cell.is-col { filter: var(--col-filter); }
.cell.is-now { box-shadow: inset 0 0 0 1px var(--chip-mark); }

@keyframes fx-alarm {
  0%, 100% { filter: brightness(1); }
  50% { filter: var(--alarm-filter); }
}

/* The legend's no-data swatch carries its hairline as an inline style, so the
   light version has to out-rank it. */
.wall-legend .swatch[style*="c-nodata"] {
  box-shadow: inset 0 0 0 1px var(--chip-hair) !important;
}

/* ---------- Controls ---------- */

#service-search,
.diagnose-form select,
.filter-button { border-color: var(--control-line); }

.filter-button:hover,
.wall-vendor #provider-trigger:hover,
.service-card:hover { border-color: var(--border-hover); }

.filter-button.is-active {
  border-color: var(--active-border);
  background: var(--active-bg);
}

/* ---------- Pills ---------- */

/* Derived from the text scale so a re-graded --t-* carries its own tint with
   it. If color-mix is unavailable the declarations drop and the styles.css
   literals stand; the pill's meaning lives in its text colour either way. */
.pill.operational { background: color-mix(in srgb, var(--t-op) var(--pill-bg-mix), transparent); border-color: color-mix(in srgb, var(--t-op) var(--pill-bd-mix), transparent); }
.pill.watch { background: color-mix(in srgb, var(--t-watch) var(--pill-bg-mix), transparent); border-color: color-mix(in srgb, var(--t-watch) var(--pill-bd-mix), transparent); }
.pill.maintenance { background: color-mix(in srgb, var(--t-maint) var(--pill-bg-mix), transparent); border-color: color-mix(in srgb, var(--t-maint) var(--pill-bd-mix), transparent); }
.pill.degraded { background: color-mix(in srgb, var(--t-degraded) var(--pill-bg-mix), transparent); border-color: color-mix(in srgb, var(--t-degraded) var(--pill-bd-mix-warm), transparent); }
.pill.partial_outage { background: color-mix(in srgb, var(--t-partial) var(--pill-bg-mix), transparent); border-color: color-mix(in srgb, var(--t-partial) var(--pill-bd-mix-warm), transparent); }
.pill.major_outage { background: color-mix(in srgb, var(--t-major) var(--pill-bg-mix), transparent); border-color: color-mix(in srgb, var(--t-major) var(--pill-bd-mix-warm), transparent); }

/* ---------- Diagnose, tooltip, footer ---------- */

.diagnose { background: linear-gradient(180deg, var(--panel), var(--diagnose-bottom)); }
.diagnose-form button { color: var(--btn-fg); }
.diagnose-result { background: var(--result-bg); }

#tip {
  background: color-mix(in srgb, var(--tip-bg) var(--tip-alpha), transparent);
  border-color: var(--tip-border);
}

/* =============================================================
   Theme toggle. Lives in the top bar alongside the language chip and the
   account links; present and identical in both themes.
   ============================================================= */

.theme-toggle,
.lang-toggle,
.account-link {
  flex: none;
  min-height: 22px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* Sized to sit inside the bar the brand already sets the height of, so
     adding it moves nothing below it. */
  padding: 4px 9px;
  font-family: var(--mono);
  font-size: 10.5px;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--fg-dim);
  background: var(--control-fill-muted, var(--panel-2));
  border: 1px solid var(--control-line, var(--line));
  border-radius: var(--control-r);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}

/* Half-filled square: the same mark in both themes, drawn in currentColor so
   it tracks hover and focus without a second rule. */
.theme-toggle::before {
  content: "";
  flex: none;
  width: 9px;
  height: 9px;
  background: linear-gradient(90deg, currentColor 0 50%, transparent 50%);
  box-shadow: inset 0 0 0 1px currentColor;
}

/* Reads the current theme out of CSS, so it is correct on the system path
   with no script and cannot flash the wrong word. */
.theme-toggle::after { content: var(--theme-name); }

.theme-toggle:hover,
.lang-toggle:hover,
.account-link:not(:disabled):hover { color: var(--fg); border-color: var(--border-hover); }

.account-link:disabled { cursor: default; opacity: 0.65; }

/* Once the nav is gone nothing pushes the buttons right, so the first chip
   takes over. The theme word still yields to its mark; the language and login
   labels are short enough to keep. */
@media (max-width: 620px) {
  .lang-toggle { margin-left: auto; }
  .lang-toggle, .theme-toggle, .account-link { min-width: 44px; justify-content: center; }
  .lang-toggle, .theme-toggle { position: relative; }
  /* Keep the compact visual shape while retaining a forgiving touch area. */
  .lang-toggle::before, .theme-toggle::after {
    content: "";
    display: block;
    position: absolute;
    inset: -12px 0;
  }
}

/* =============================================================
   The light payload, on both paths.

   Path 1 is the system preference, and it is deliberately declined by an
   explicit dark choice. Path 2 is the explicit light choice and, being later
   and no less specific, beats a dark system preference.

   The two blocks below are generated from one source. Keep them identical.
   ============================================================= */

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --provider-icon-invert: 0;

    /* Paper, not a negative of the panel: the ground is a hair cooler than the
       cards so a white chip still reads as raised against it. */
    --bg: #f4f5f8;
    --panel: #ffffff;
    --panel-2: #e9ecf3;
    --line: #ccd3e0;
    --line-soft: #e0e4ec;

    --fg: #10141c;
    --fg-dim: #4a5464;
    --fg-faint: #5f6878;

    /* Cell scale re-graded for a light ground. Same meanings, same order, but
       the ramp now runs quiet-to-loud downwards: healthy sits mid, anomalies go
       dark and saturated. Closest pair (partial/major) is dE76 25.4, i.e. the
       same separation the dark scale already ships. */
    --c-nodata: #e9edf4;
    --c-op: #2f8049;
    --c-watch: #2f74dc;
    --c-maint: #7d55d0;
    --c-degraded: #b58108;
    --c-partial: #d9601a;
    --c-major: #c92f2b;

    /* Text weights: every one of these clears 4.5:1 on --panel, --panel-2 and
       on its own pill tint. The dark scale's greens and blues float on white,
       so they are pushed down, not inverted. */
    --t-op: #18783a;
    --t-watch: #0a58ca;
    --t-maint: #6639ba;
    --t-degraded: #8a5d00;
    --t-partial: #a54800;
    --t-major: #c02020;

    /* Controls need a boundary the fill cannot provide: --panel-2 is only
       1.08:1 against --bg here, so the border carries the affordance. */
    --control-line: #858fa4;
    --control-fill: #ffffff;
    --control-fill-muted: #f0f2f7;

    /* Paper ink: every "depth" value below derives from this one colour so a
       re-tint moves the whole surface at once. */
    --ink: 20 26 38;
    --chip-hair: rgb(var(--ink) / 0.16);
    --chip-mark: rgb(var(--ink) / 0.7);

    /* Floating layers keep their geometry and lose most of their weight: on
       white a half-alpha black shadow reads as dirt, not as depth. */
    --float-shadow: 0 10px 26px rgb(var(--ink) / 0.16);
    --card-shadow: 0 3px 8px -4px rgba(20, 26, 38, 0.14), 0 12px 18px -14px rgba(20, 26, 38, 0.22);

    --page-glow: rgba(47, 116, 220, 0.06);

    --topbar-bg: #f4f5f8;
    --verdict-top: #ffffff;
    --verdict-bottom: #eef1f7;
    --verdict-sweep: rgba(20, 40, 90, 0.06);
    --diagnose-bottom: #edf0f6;
    --result-bg: rgba(10, 88, 202, 0.06);
    --btn-fg: #ffffff;
    --border-hover: #aab3c4;
    --active-border: #7fa5e6;
    --active-bg: rgba(10, 88, 202, 0.09);
    --tip-bg: #ffffff;
    --tip-border: #c6cddc;

    --major-bloom: rgba(201, 47, 43, 0.3);

    --pill-bg-mix: 13%;
    --pill-bd-mix: 46%;
    --pill-bd-mix-warm: 46%;

    /* Brightening a light chip washes it out, so "raised" and "alarming" are
       expressed by going down and more saturated instead of up. */
    --col-filter: brightness(0.92) saturate(1.3);
    --alarm-filter: brightness(0.84) saturate(1.2);

    --scroll-thumb: #b9c1d0;
    --scroll-track: #e9ecf3;

    --theme-name: "light";
  }
}

:root[data-theme="light"] {
  color-scheme: light;
  --provider-icon-invert: 0;

  /* Paper, not a negative of the panel: the ground is a hair cooler than the
     cards so a white chip still reads as raised against it. */
  --bg: #f4f5f8;
  --panel: #ffffff;
  --panel-2: #e9ecf3;
  --line: #ccd3e0;
  --line-soft: #e0e4ec;

  --fg: #10141c;
  --fg-dim: #4a5464;
  --fg-faint: #5f6878;

  /* Cell scale re-graded for a light ground. Same meanings, same order, but
     the ramp now runs quiet-to-loud downwards: healthy sits mid, anomalies go
     dark and saturated. Closest pair (partial/major) is dE76 25.4, i.e. the
     same separation the dark scale already ships. */
  --c-nodata: #e9edf4;
  --c-op: #2f8049;
  --c-watch: #2f74dc;
  --c-maint: #7d55d0;
  --c-degraded: #b58108;
  --c-partial: #d9601a;
  --c-major: #c92f2b;

  /* Text weights: every one of these clears 4.5:1 on --panel, --panel-2 and
     on its own pill tint. The dark scale's greens and blues float on white,
     so they are pushed down, not inverted. */
  --t-op: #18783a;
  --t-watch: #0a58ca;
  --t-maint: #6639ba;
  --t-degraded: #8a5d00;
  --t-partial: #a54800;
  --t-major: #c02020;

  /* Controls need a boundary the fill cannot provide: --panel-2 is only
     1.08:1 against --bg here, so the border carries the affordance. */
  --control-line: #858fa4;
  --control-fill: #ffffff;
  --control-fill-muted: #f0f2f7;

  /* Paper ink: every "depth" value below derives from this one colour so a
     re-tint moves the whole surface at once. */
  --ink: 20 26 38;
  --chip-hair: rgb(var(--ink) / 0.16);
  --chip-mark: rgb(var(--ink) / 0.7);

  /* Floating layers keep their geometry and lose most of their weight: on
     white a half-alpha black shadow reads as dirt, not as depth. */
  --float-shadow: 0 10px 26px rgb(var(--ink) / 0.16);
    --card-shadow: 0 3px 8px -4px rgba(20, 26, 38, 0.14), 0 12px 18px -14px rgba(20, 26, 38, 0.22);

  --page-glow: rgba(47, 116, 220, 0.06);

  --topbar-bg: #f4f5f8;
  --verdict-top: #ffffff;
  --verdict-bottom: #eef1f7;
  --verdict-sweep: rgba(20, 40, 90, 0.06);
  --diagnose-bottom: #edf0f6;
  --result-bg: rgba(10, 88, 202, 0.06);
  --btn-fg: #ffffff;
  --border-hover: #aab3c4;
  --active-border: #7fa5e6;
  --active-bg: rgba(10, 88, 202, 0.09);
  --tip-bg: #ffffff;
  --tip-border: #c6cddc;

  --major-bloom: rgba(201, 47, 43, 0.3);

  --pill-bg-mix: 13%;
  --pill-bd-mix: 46%;
  --pill-bd-mix-warm: 46%;

  /* Brightening a light chip washes it out, so "raised" and "alarming" are
     expressed by going down and more saturated instead of up. */
  --col-filter: brightness(0.92) saturate(1.3);
  --alarm-filter: brightness(0.84) saturate(1.2);

  --scroll-thumb: #b9c1d0;
  --scroll-track: #e9ecf3;

  --theme-name: "light";
}
