/* HELM — generated from the Open Design project 'HELM Fleet Dashboard — Soft UI'.
   Concatenated in order: helm.css, helm-overview.css, helm-wide.css
   Do not hand-edit here; edit in Open Design and re-run the deploy.
   Filename carries a content hash because Hestia's nginx sets `expires max`. */


/* ===== helm.css ===== */

/* =====================================================================
   HELM — fleet dashboard, soft UI
   Built on the WeCraftCode design system (assets/system.css in the
   "Soft Ui Design Wecraftcode Design System" project).

   RULES INHERITED AND KEPT:
   1. Token hex values are exact — not one is altered.
   2. Amber (--signal) is 2am / on-call / support ONLY. Never a generic CTA.
      In a monitoring product that rule is a gift: amber already means
      "this wants you at 2am", which is precisely what a finding is.

   TWO TOKENS ADDED, both lifted from the operator's OTHER design doc
   (files/DESIGN.md) rather than invented here, so the fleet keeps one
   vocabulary across both documents:
      --critical #FF5A63   down, failed, serving the wrong thing
      --inert    #4A5875   unknown, no data yet, not reporting

   WHY A STATUS RAMP NEEDS FOUR STEPS, NOT TWO
   Lime and amber cannot express the difference between "up but logging
   errors" and "answering 200 with the wrong site". This product exists to
   tell those apart, so the ramp has to.

   COLOUR IS NEVER THE ONLY SIGNAL. Every status carries a glyph as well as
   a hue — roughly 1 in 12 men cannot reliably separate amber from green.
   ===================================================================== */

/* ---- Tokens: dark (default) ---------------------------------------- */
:root {
  --bg: #0A0A0B;
  --surface: #141416;
  --border: #242428;
  --text: #FAFAFA;
  --text-muted: #8A8A92;
  --accent: #CDFF3E;      /* lime  — nominal, "systems online" */
  --signal: #FF9F45;      /* amber — needs you. on-call ONLY   */
  --critical: #FF5A63;    /* added — down / wrong / failed      */
  --inert: #4A5875;       /* added — unknown / no data yet      */

  --accent-ink: #0A0A0B;
  --surface-2: color-mix(in srgb, var(--surface) 88%, #fff 4%);
  --surface-3: color-mix(in srgb, var(--surface) 76%, #fff 6%);
  --hairline: 1px solid var(--border);

  /* soft-UI depth — inset highlight above, long soft drop below */
  --radius: 20px;
  --radius-sm: 14px;
  --radius-lg: 28px;
  --radius-pill: 999px;
  --shadow-soft: 0 1px 0 rgba(255,255,255,.045) inset, 0 22px 46px -26px rgba(0,0,0,.85);
  --shadow-raise: 0 1px 0 rgba(255,255,255,.07) inset, 0 34px 66px -28px rgba(0,0,0,.9);
  --shadow-inset: inset 0 2px 7px rgba(0,0,0,.55), inset 0 1px 0 rgba(255,255,255,.03);

  --glow-accent: color-mix(in srgb, var(--accent) 24%, transparent);
  --glow-signal: color-mix(in srgb, var(--signal) 26%, transparent);
  --glow-critical: color-mix(in srgb, var(--critical) 26%, transparent);

  --font-display: "Inter Tight", "Geist", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body: "Inter", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;
  --font-mono: "JetBrains Mono", "Geist Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --rail: 76px;
  --rail-open: 248px;
  --topbar: 72px;
  --maxw: 1560px;
  --gutter: clamp(1.25rem, 2.6vw, 2.5rem);
  --ease: cubic-bezier(.2, .7, .2, 1);
  --row-h: 64px;
}

/* ---- Tokens: light -------------------------------------------------- */
html[data-theme="light"] {
  --bg: #FBFBF9;
  --surface: #FFFFFF;
  --border: #E6E6E0;
  --text: #0A0A0B;
  --text-muted: #6A6A72;
  --accent: #CDFF3E;
  --signal: #FF9F45;
  --critical: #E03742;   /* the dark hue needs more weight on a light canvas */
  --inert: #8E97AC;

  --accent-ink: #0A0A0B;
  --surface-2: color-mix(in srgb, var(--surface) 96%, #000 3%);
  --surface-3: color-mix(in srgb, var(--surface) 92%, #000 5%);
  --shadow-soft: 0 1px 0 rgba(255,255,255,.9) inset, 0 18px 40px -26px rgba(20,20,25,.28);
  --shadow-raise: 0 1px 0 rgba(255,255,255,1) inset, 0 26px 52px -28px rgba(20,20,25,.34);
  --shadow-inset: inset 0 2px 5px rgba(20,20,25,.10), inset 0 1px 0 rgba(255,255,255,.6);
  --glow-accent: color-mix(in srgb, var(--accent) 40%, transparent);
  --glow-signal: color-mix(in srgb, var(--signal) 34%, transparent);
  --glow-critical: color-mix(in srgb, var(--critical) 30%, transparent);
}

/* ---- Base ----------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: .9375rem;
  line-height: 1.55;
  font-variant-numeric: tabular-nums;   /* figures must not reflow between refreshes */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  transition: background .5s var(--ease), color .5s var(--ease);
}
svg { display: block; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; border: 0; background: none; }
:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 6px; }
html[data-theme="light"] :focus-visible { outline-color: var(--text); }

h1, h2, h3 { font-family: var(--font-display); font-weight: 700; letter-spacing: -.02em; line-height: 1.1; }
.mono { font-family: var(--font-mono); font-weight: 500; letter-spacing: .1em; text-transform: uppercase; font-size: .7rem; }
.muted { color: var(--text-muted); }
.eyebrow { font-family: var(--font-mono); font-size: .68rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--text-muted); display: flex; align-items: center; gap: .7rem; }
.eyebrow::after { content: ""; flex: 1; height: 1px; background: var(--border); }

/* ---- Shell ---------------------------------------------------------- */
.shell { display: grid; grid-template-columns: var(--rail) 1fr; min-height: 100vh; }

/* ---- Left rail: soft pills, not a flat list ------------------------- */
.rail {
  position: fixed; inset: 0 auto 0 0; width: var(--rail); z-index: 40;
  background: color-mix(in srgb, var(--surface) 70%, var(--bg));
  border-right: var(--hairline);
  display: flex; flex-direction: column; overflow: hidden;
  transition: width .28s var(--ease);
}
.rail:hover, .rail:focus-within { width: var(--rail-open); box-shadow: var(--shadow-raise); }
.rail-brand { height: var(--topbar); display: flex; align-items: center; gap: .85rem; padding: 0 1.15rem; flex: none; }
.rail-brand .mark {
  width: 40px; height: 40px; flex: none; display: grid; place-items: center;
  border-radius: 13px; background: var(--accent); color: var(--accent-ink);
  font-family: var(--font-display); font-weight: 800; font-size: 1.05rem;
  box-shadow: 0 10px 22px -12px var(--glow-accent);
}
.rail-brand .word { font-family: var(--font-display); font-weight: 700; font-size: 1.1rem; letter-spacing: -.01em;
  white-space: nowrap; opacity: 0; transition: opacity .22s var(--ease); }
.rail:hover .word, .rail:focus-within .word { opacity: 1; }

.rail nav { padding: .5rem .7rem; display: grid; gap: .25rem; flex: 1; align-content: start; }
.nav-item {
  display: flex; align-items: center; gap: .9rem; height: 46px; padding: 0 .8rem;
  border-radius: var(--radius-sm); color: var(--text-muted); white-space: nowrap;
  font-weight: 500; font-size: .9rem;
  transition: background .2s var(--ease), color .2s var(--ease), box-shadow .2s var(--ease);
}
.nav-item .ico { width: 26px; flex: none; display: grid; place-items: center; }
.nav-item .ico svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.7; }
.nav-item .lbl { opacity: 0; transition: opacity .22s var(--ease); }
.rail:hover .nav-item .lbl, .rail:focus-within .nav-item .lbl { opacity: 1; }
.nav-item:hover { background: var(--surface-2); color: var(--text); }
/* active = recessed, the soft-UI way to say "you are here" */
.nav-item[aria-current="page"] {
  background: var(--surface-2); color: var(--text); box-shadow: var(--shadow-inset);
}
.nav-item[aria-current="page"] .ico { color: var(--accent); }
.nav-item.is-locked { color: color-mix(in srgb, var(--text-muted) 62%, transparent); cursor: not-allowed; }
.nav-item .badge-n {
  margin-left: auto; font-family: var(--font-mono); font-size: .66rem; font-weight: 600;
  padding: .18rem .45rem; border-radius: 7px; opacity: 0; transition: opacity .22s var(--ease);
}
.rail:hover .nav-item .badge-n, .rail:focus-within .nav-item .badge-n { opacity: 1; }
.badge-n.is-critical { background: color-mix(in srgb, var(--critical) 18%, transparent);
  color: var(--critical); border: 1px solid color-mix(in srgb, var(--critical) 36%, transparent); }
.badge-n.is-signal { background: color-mix(in srgb, var(--signal) 16%, transparent);
  color: var(--signal); border: 1px solid color-mix(in srgb, var(--signal) 34%, transparent); }
.nav-item .phase { margin-left: auto; font-family: var(--font-mono); font-size: .6rem; letter-spacing: .1em;
  color: var(--inert); border: 1px dashed var(--border); border-radius: 6px; padding: .1rem .35rem;
  opacity: 0; transition: opacity .22s var(--ease); }
.rail:hover .nav-item .phase { opacity: 1; }
.rail-foot { padding: .7rem; border-top: var(--hairline); flex: none; display: grid; gap: .25rem; }

/* ---- Top bar -------------------------------------------------------- */
.col { grid-column: 2; min-width: 0; }
.topbar {
  height: var(--topbar); position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: var(--gutter);
  padding: 0 var(--gutter);
  background: color-mix(in srgb, var(--bg) 78%, transparent);
  backdrop-filter: blur(16px) saturate(1.4);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  border-bottom: var(--hairline);
}
.topbar h1 { font-size: 1.15rem; font-weight: 700; }
.topbar .right { margin-left: auto; display: flex; align-items: center; gap: .6rem; }

/* host strip — their .status-strip, recessed pill with live dots */
.status-strip {
  display: inline-flex; flex-wrap: wrap; align-items: center; gap: .4rem 1.05rem;
  font-family: var(--font-mono); font-size: .7rem; letter-spacing: .04em; color: var(--text-muted);
  padding: .55rem 1rem; border: var(--hairline); border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--surface) 60%, transparent);
  box-shadow: var(--shadow-inset);
}
.status-item { display: inline-flex; align-items: center; gap: .45rem; }
.status-item b { color: var(--text); font-weight: 600; }

.icon-btn {
  width: 40px; height: 40px; display: grid; place-items: center; flex: none;
  border-radius: var(--radius-pill); border: var(--hairline); color: var(--text);
  background: var(--surface); box-shadow: var(--shadow-soft);
  transition: border-color .2s, transform .2s var(--ease);
}
.icon-btn:hover { border-color: var(--accent); transform: translateY(-2px); }
.icon-btn svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.7; }
.icon-btn .moon { display: none; }
html[data-theme="light"] .icon-btn .sun { display: none; }
html[data-theme="light"] .icon-btn .moon { display: block; }
.btn-quiet {
  height: 40px; padding: 0 1.1rem; border-radius: var(--radius-pill); border: var(--hairline);
  background: var(--surface); color: var(--text-muted); font-weight: 500; font-size: .85rem;
  box-shadow: var(--shadow-soft); transition: color .2s, border-color .2s, transform .2s var(--ease);
}
.btn-quiet:hover { color: var(--text); border-color: var(--accent); transform: translateY(-2px); }

main { max-width: var(--maxw); margin-inline: auto; padding: var(--gutter); display: grid; gap: var(--gutter); }

/* ---- Status dots and lamps ----------------------------------------- */
.dot { width: 9px; height: 9px; border-radius: 50%; flex: none; display: inline-block; }
.dot--ok { background: var(--accent); animation: pulse-ok 2.6s var(--ease) infinite; }
.dot--signal { background: var(--signal); animation: pulse-sig 2.6s var(--ease) infinite; }
.dot--critical { background: var(--critical); animation: pulse-crit 1.8s var(--ease) infinite; }
.dot--inert { background: var(--inert); }
@keyframes pulse-ok   { 0% { box-shadow: 0 0 0 0 var(--glow-accent); }   70% { box-shadow: 0 0 0 8px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
@keyframes pulse-sig  { 0% { box-shadow: 0 0 0 0 var(--glow-signal); }   70% { box-shadow: 0 0 0 8px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }
@keyframes pulse-crit { 0% { box-shadow: 0 0 0 0 var(--glow-critical); } 70% { box-shadow: 0 0 0 9px transparent; } 100% { box-shadow: 0 0 0 0 transparent; } }

/* glyph + hue together, never hue alone */
.lamp { display: inline-flex; align-items: center; gap: .5rem; white-space: nowrap;
  font-family: var(--font-mono); font-size: .72rem; letter-spacing: .04em; }
.lamp--ok { color: var(--accent); }
.lamp--signal { color: var(--signal); }
.lamp--critical { color: var(--critical); }
.lamp--inert { color: var(--inert); }
.glyph { font-size: .8em; }

/* ---- The 2am band — the signature element --------------------------
   Only rendered when something high-severity is open. When the fleet is
   clean this whole block is replaced by one quiet lime line, so the page
   is physically shortest on a good day.                               */
.band {
  position: relative; overflow: hidden; border-radius: var(--radius-lg);
  border: 1px solid color-mix(in srgb, var(--signal) 30%, var(--border));
  background: var(--surface); box-shadow: var(--shadow-soft);
  padding: clamp(1.5rem, 3vw, 2.25rem);
}
.band .glow {
  position: absolute; border-radius: 50%; filter: blur(100px); opacity: .5; pointer-events: none;
  background: var(--glow-signal); width: 42vw; height: 42vw; max-width: 560px; max-height: 560px;
  top: -60%; right: -6%;
}
.band .inner { position: relative; z-index: 2; }
.band h2 { font-size: clamp(1.5rem, 3vw, 2.2rem); max-width: 30ch; margin-top: .8rem; }
.band h2 .hl { color: var(--signal); }
.band .worst { margin-top: 1.4rem; display: grid; gap: .6rem; }
.band-ok { display: flex; align-items: center; gap: .8rem; padding: 1.1rem 1.4rem;
  border-radius: var(--radius); border: 1px solid color-mix(in srgb, var(--accent) 26%, var(--border));
  background: color-mix(in srgb, var(--accent) 5%, var(--surface)); box-shadow: var(--shadow-soft);
  font-weight: 500; }

/* ---- Stat tiles ----------------------------------------------------- */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(184px, 1fr)); gap: 1rem; }
.tile {
  padding: 1.35rem 1.4rem; border: var(--hairline); border-radius: var(--radius);
  background: var(--surface); box-shadow: var(--shadow-soft);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease), border-color .25s var(--ease);
}
.tile:hover { transform: translateY(-4px); box-shadow: var(--shadow-raise); }
.tile .n { font-family: var(--font-display); font-size: clamp(1.9rem, 3vw, 2.5rem); font-weight: 700;
  letter-spacing: -.03em; line-height: 1; display: block; }
.tile .l { color: var(--text-muted); font-size: .84rem; margin-top: .5rem; display: flex;
  align-items: center; gap: .45rem; }
.tile.is-ok .n { color: var(--accent); }
.tile.is-signal .n { color: var(--signal); }
.tile.is-critical .n { color: var(--critical); }
.tile.is-inert .n { color: var(--inert); }
.tile.is-critical { border-color: color-mix(in srgb, var(--critical) 26%, var(--border)); }
.tile.is-signal { border-color: color-mix(in srgb, var(--signal) 24%, var(--border)); }

/* ---- Panels --------------------------------------------------------- */
.panel { border: var(--hairline); border-radius: var(--radius); background: var(--surface);
  box-shadow: var(--shadow-soft); overflow: hidden; }
.panel-head { display: flex; align-items: center; gap: 1rem; padding: 1.15rem 1.4rem;
  border-bottom: var(--hairline); }
.panel-head h2 { font-size: 1.02rem; font-weight: 600; }
.panel-head .right { margin-left: auto; display: flex; align-items: center; gap: .5rem; }

/* ---- Fleet table — softened, still scannable ----------------------- */
.fleet { width: 100%; border-collapse: collapse; }
.fleet th {
  font-family: var(--font-mono); font-size: .64rem; letter-spacing: .13em; text-transform: uppercase;
  color: var(--text-muted); text-align: left; font-weight: 500;
  padding: .85rem 1.1rem; background: color-mix(in srgb, var(--surface) 70%, var(--bg));
  border-bottom: var(--hairline); white-space: nowrap;
}
.fleet td { height: var(--row-h); padding: .5rem 1.1rem; border-bottom: 1px solid
  color-mix(in srgb, var(--border) 55%, transparent); vertical-align: middle; white-space: nowrap; }
.fleet tbody tr { transition: background .18s var(--ease); }
.fleet tbody tr:hover { background: var(--surface-2); }
.fleet tbody tr:last-child td { border-bottom: 0; }
.fleet .num { text-align: right; font-family: var(--font-mono); font-size: .82rem; }
.dom { font-weight: 600; font-size: .92rem; }
.sub { color: var(--text-muted); font-size: .76rem; font-family: var(--font-mono); margin-top: .15rem; }
/* soft severity edge — a rounded bar, not a hard 4px rule */
.edge { position: relative; }
.edge::before { content: ""; position: absolute; left: .35rem; top: 50%; transform: translateY(-50%);
  width: 3px; height: 58%; border-radius: 999px; }
.edge--critical::before { background: var(--critical); }
.edge--signal::before { background: var(--signal); }

.pill { display: inline-flex; align-items: center; justify-content: center; min-width: 52px;
  padding: .28rem .55rem; border-radius: 9px; font-family: var(--font-mono); font-size: .64rem;
  letter-spacing: .07em; background: var(--surface-2); border: var(--hairline);
  color: var(--text-muted); box-shadow: var(--shadow-inset); }
.zero { color: color-mix(in srgb, var(--text-muted) 55%, transparent); }
.hot { color: var(--critical); font-weight: 600; }
.warm { color: var(--signal); font-weight: 600; }

/* honest no-data marker — their .placeholder-tag, reused verbatim in spirit */
.nodata { display: inline-flex; align-items: center; gap: .4rem; font-family: var(--font-mono);
  font-size: .64rem; letter-spacing: .1em; text-transform: uppercase; color: var(--inert);
  border: 1px dashed var(--border); border-radius: 7px; padding: .18rem .45rem; }

/* ---- Findings ------------------------------------------------------- */
.finding { display: grid; grid-template-columns: auto 1fr; gap: 1rem 1.1rem;
  padding: 1.25rem 1.4rem; border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent); }
.finding:last-child { border-bottom: 0; }
.finding .sev { width: 34px; height: 34px; border-radius: 11px; display: grid; place-items: center;
  flex: none; box-shadow: var(--shadow-inset); font-size: .78rem; }
.sev--critical { background: color-mix(in srgb, var(--critical) 14%, var(--surface-2)); color: var(--critical);
  border: 1px solid color-mix(in srgb, var(--critical) 30%, transparent); }
.sev--signal { background: color-mix(in srgb, var(--signal) 13%, var(--surface-2)); color: var(--signal);
  border: 1px solid color-mix(in srgb, var(--signal) 28%, transparent); }
.finding .title { font-weight: 600; font-size: .95rem; }
.finding .meta { display: flex; flex-wrap: wrap; gap: .35rem .8rem; margin-top: .35rem;
  font-family: var(--font-mono); font-size: .68rem; color: var(--text-muted); }
.finding .why { color: var(--text-muted); font-size: .86rem; margin-top: .6rem; max-width: 82ch; }
.finding pre { margin-top: .8rem; padding: .8rem 1rem; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--bg) 55%, var(--surface)); border: var(--hairline);
  box-shadow: var(--shadow-inset); font-family: var(--font-mono); font-size: .72rem; line-height: 1.65;
  color: var(--text-muted); white-space: pre-wrap; word-break: break-word; overflow-x: auto; }
.finding .go { margin-top: .8rem; display: inline-flex; align-items: center; gap: .4rem;
  font-size: .8rem; font-weight: 600; color: var(--accent); }

/* ---- Servers -------------------------------------------------------- */
.servers { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 1rem; }
.server { padding: 1.5rem; border: var(--hairline); border-radius: var(--radius);
  background: var(--surface); box-shadow: var(--shadow-soft); }
.server.is-unknown { border-style: dashed; background: color-mix(in srgb, var(--surface) 60%, transparent);
  box-shadow: none; }
.server h3 { font-size: 1.05rem; display: flex; align-items: center; gap: .6rem; }
.gauges { display: grid; gap: .9rem; margin-top: 1.25rem; }
.gauge .top { display: flex; align-items: baseline; gap: .5rem; font-family: var(--font-mono);
  font-size: .72rem; color: var(--text-muted); }
.gauge .top b { margin-left: auto; color: var(--text); font-size: .84rem; }
/* recessed track, soft filled bar */
.gauge .track { margin-top: .4rem; height: 9px; border-radius: 999px; background: var(--surface-2);
  box-shadow: var(--shadow-inset); overflow: hidden; }
.gauge .fill { height: 100%; border-radius: 999px; background: var(--accent); }
.gauge.is-signal .fill { background: var(--signal); }
.gauge.is-critical .fill { background: var(--critical); }

/* ---- Footnote ------------------------------------------------------- */
.footnote { font-family: var(--font-mono); font-size: .68rem; line-height: 1.8; color: var(--text-muted);
  border-top: var(--hairline); padding-top: 1.1rem; }

/* ---- Motion / responsive ------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
@media (max-width: 1100px) { .servers { grid-template-columns: 1fr; } }
@media (max-width: 900px) {
  .shell { grid-template-columns: 1fr; }
  .rail { position: static; width: 100%; border-right: 0; border-bottom: var(--hairline); }
  .rail:hover { width: 100%; box-shadow: none; }
  .rail nav { grid-auto-flow: column; grid-auto-columns: max-content; overflow-x: auto; }
  .rail .word, .rail .lbl, .rail .badge-n, .rail .phase { opacity: 1; }
  .rail-foot { display: none; }
  .col { grid-column: 1; }
  .table-wrap { overflow-x: auto; }
  .fleet { min-width: 860px; }
  .topbar { height: auto; padding-block: .9rem; flex-wrap: wrap; }
}


/* ===== helm-overview.css ===== */

/* =====================================================================
   HELM — overview / detail / login additions, on top of assets/helm.css
   Load second.

   Jobs:
     1. Fix the dark-mode depth, which read flatter than light mode.
     2. Hero counts + prominent progress bars — the overview's whole job.
     3. A calm site list, a visitors graph, and one line out to detail.
     4. Site-detail page furniture.
     5. Login.

   Deliberately NOT here: dense error tables, log-line evidence blocks,
   queue detail. Those belong on the detail and Issues pages. The
   overview answers "what have I got, is it healthy" — never "why did it
   break".
   ===================================================================== */

/* ---- 1. Dark depth, strengthened ------------------------------------
   The base highlight was rgba(255,255,255,.045) — on a #0A0A0B canvas
   that is almost nothing, which is why soft UI showed clearly in light
   mode and barely in dark. Raised to .085 / .14, drop shadows tightened
   so the falloff survives against near-black, and raised surfaces get a
   faint lit top edge.

   Overrides :root only. The light block in helm.css uses
   html[data-theme="light"] — more specific — so light is untouched.  */
:root {
  --shadow-soft:  0 1px 0 rgba(255,255,255,.085) inset, 0 16px 30px -18px rgba(0,0,0,.94);
  --shadow-raise: 0 1px 0 rgba(255,255,255,.14) inset,  0 24px 44px -20px rgba(0,0,0,.96);
  --shadow-inset: inset 0 3px 8px rgba(0,0,0,.62), inset 0 1px 0 rgba(255,255,255,.055);
  --edge-top: linear-gradient(180deg, rgba(255,255,255,.07), transparent 42%);
}
html[data-theme="light"] { --edge-top: linear-gradient(180deg, rgba(255,255,255,.9), transparent 40%); }

.panel, .hero-tile, .server, .band, .auth-card { position: relative; }
.panel::before, .hero-tile::before, .server::before, .band::before, .auth-card::before {
  content: ""; position: absolute; inset: 0 0 auto 0; height: 34%;
  background: var(--edge-top); pointer-events: none; z-index: 1; border-radius: inherit;
}
.panel > *, .hero-tile > *, .server > *, .band > *, .auth-card > * { position: relative; z-index: 2; }

/* more air between blocks than a dense console would use */
main { gap: clamp(1.5rem, 3vw, 2.5rem) !important; }
.body-pad { padding: clamp(1.25rem, 2.4vw, 1.75rem); }

/* ---- 2. Hero counts ------------------------------------------------- */
.hero-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 1rem; }
.hero-tile {
  padding: clamp(1.4rem, 2.4vw, 1.9rem); border: var(--hairline); border-radius: var(--radius);
  background: var(--surface); box-shadow: var(--shadow-soft);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.hero-tile:hover { transform: translateY(-4px); box-shadow: var(--shadow-raise); }
.hero-tile .cap { display: flex; align-items: center; gap: .5rem; font-family: var(--font-mono);
  font-size: .64rem; letter-spacing: .13em; text-transform: uppercase; color: var(--text-muted); }
.hero-tile .big { font-family: var(--font-display); font-weight: 700; letter-spacing: -.035em;
  font-size: clamp(2.6rem, 5vw, 3.6rem); line-height: 1; margin-top: .9rem; display: block; }
.hero-tile .unit { font-size: .42em; font-weight: 600; color: var(--text-muted);
  letter-spacing: -.01em; margin-left: .3rem; }
.hero-tile .note { color: var(--text-muted); font-size: .84rem; margin-top: .6rem; }
.hero-tile.accent .big { color: var(--accent); }
.hero-tile.signal .big { color: var(--signal); }
.hero-tile .ring { width: 34px; height: 34px; border-radius: 11px; display: grid;
  place-items: center; margin-left: auto; background: var(--surface-2);
  box-shadow: var(--shadow-inset); color: var(--accent); }
.hero-tile .ring svg { width: 17px; height: 17px; stroke: currentColor; fill: none; stroke-width: 1.8; }

/* ---- 3. Progress bars — the illustration of choice ------------------ */
.bars-col { display: grid; gap: clamp(1.1rem, 2vw, 1.6rem); }
.pbar .head { display: flex; align-items: baseline; gap: .6rem; }
.pbar .head .name { font-weight: 600; font-size: .95rem; }
.pbar .head .val { margin-left: auto; font-family: var(--font-mono); font-size: .95rem; }
.pbar .track {
  margin-top: .7rem; height: 16px; border-radius: 999px;
  background: color-mix(in srgb, var(--surface) 40%, var(--bg));
  box-shadow: var(--shadow-inset); overflow: hidden;
}
.pbar .fill {
  height: 100%; border-radius: 999px;
  background: linear-gradient(180deg, color-mix(in srgb, var(--accent) 92%, #fff 14%), var(--accent));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.45), 0 4px 12px -4px var(--glow-accent);
  transition: width .5s var(--ease);
}
.pbar.is-signal .fill { background: linear-gradient(180deg,
    color-mix(in srgb, var(--signal) 92%, #fff 14%), var(--signal));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 4px 12px -4px var(--glow-signal); }
.pbar.is-critical .fill { background: linear-gradient(180deg,
    color-mix(in srgb, var(--critical) 92%, #fff 14%), var(--critical));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 4px 12px -4px var(--glow-critical); }
.pbar .sub-note { color: var(--text-muted); font-size: .8rem; margin-top: .45rem; }

/* ---- 4. Graph — traffic is not a health signal, so it stays neutral - */
.graph { display: flex; align-items: flex-end; gap: clamp(.6rem, 1.6vw, 1.4rem);
  height: 180px; margin-top: 2rem; }
.gbar { flex: 1; display: flex; flex-direction: column; justify-content: flex-end;
  align-items: center; gap: .7rem; height: 100%; }
.gbar .col { width: 100%; max-width: 86px; border-radius: 12px 12px 5px 5px; position: relative;
  background: linear-gradient(180deg,
    color-mix(in srgb, var(--accent) 40%, var(--surface-3)),
    color-mix(in srgb, var(--accent) 10%, var(--surface-2)));
  box-shadow: var(--shadow-soft), inset 0 1px 0 rgba(255,255,255,.16);
  transition: filter .2s var(--ease); }
.gbar:hover .col { filter: brightness(1.28); }
.gbar .col .v { position: absolute; top: -1.7rem; left: 0; right: 0; text-align: center;
  font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; }
.gbar .d { font-family: var(--font-mono); font-size: .68rem; letter-spacing: .05em;
  color: var(--text-muted); }
/* an incomplete day must not read as traffic collapsing */
.gbar.is-partial .col { background: repeating-linear-gradient(135deg,
    color-mix(in srgb, var(--inert) 32%, var(--surface-2)) 0 7px, var(--surface-2) 7px 14px);
  box-shadow: var(--shadow-inset); }
.gbar.is-partial .col .v, .gbar.is-partial .d { color: var(--inert); }

/* ---- 5. Site list — calm rows, clickable, no error columns ---------- */
.sites { display: grid; }
.site-row {
  display: grid; grid-template-columns: 1.6rem 1fr auto auto 1.1rem; align-items: center;
  gap: 1.2rem; padding: 1.15rem clamp(1.25rem, 2.4vw, 1.75rem);
  border-bottom: 1px solid color-mix(in srgb, var(--border) 45%, transparent);
  transition: background .18s var(--ease); text-decoration: none; color: inherit;
}
.site-row:last-child { border-bottom: 0; }
.site-row:hover { background: var(--surface-2); }
.site-row:hover .chev { color: var(--accent); transform: translateX(3px); }
.site-row .name { font-weight: 600; font-size: 1rem; }
.site-row .role { color: var(--text-muted); font-size: .82rem; margin-top: .15rem; }
.site-row .stat { text-align: right; font-family: var(--font-mono); }
.site-row .stat .n { font-size: .95rem; }
.site-row .stat .k { display: block; font-size: .64rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-muted); margin-top: .2rem; }
.site-row .chev { color: var(--inert); transition: color .18s var(--ease), transform .18s var(--ease); }
.site-row .chev svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 2; }

/* one word, never a count of log groups */
.tag { display: inline-flex; align-items: center; gap: .35rem; padding: .3rem .65rem;
  border-radius: 999px; font-size: .74rem; font-weight: 600; white-space: nowrap; }
.tag--ok { color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 26%, transparent); }
.tag--signal { color: var(--signal); background: color-mix(in srgb, var(--signal) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--signal) 28%, transparent); }
.tag--critical { color: var(--critical); background: color-mix(in srgb, var(--critical) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--critical) 30%, transparent); }
.tag--inert { color: var(--inert); background: transparent; border: 1px dashed var(--border); }

/* ---- 6. One quiet line out to the detail pages ---------------------- */
.jump { display: flex; align-items: center; gap: 1rem; padding: 1.15rem 1.5rem;
  border-radius: var(--radius); border: var(--hairline); background: var(--surface);
  box-shadow: var(--shadow-soft); text-decoration: none;
  transition: border-color .2s, transform .2s var(--ease); }
.jump:hover { border-color: color-mix(in srgb, var(--accent) 60%, var(--border));
  transform: translateY(-2px); }
.jump .n { font-family: var(--font-display); font-weight: 700; font-size: 1.5rem; line-height: 1; }
.jump .t { font-weight: 500; }
.jump .t small { display: block; color: var(--text-muted); font-weight: 400; font-size: .82rem;
  margin-top: .2rem; }
.jump .arrow { margin-left: auto; color: var(--accent); font-weight: 600; white-space: nowrap; }
.jump.is-critical .n { color: var(--critical); }
.jump.is-signal .n { color: var(--signal); }

/* ---- 7. Email mini ------------------------------------------------- */
.mail-mini { display: grid; grid-template-columns: repeat(4, 1fr); gap: .75rem; }
.mail-mini > div { padding: .95rem 1rem; border-radius: var(--radius-sm); border: var(--hairline);
  background: color-mix(in srgb, var(--surface) 55%, var(--bg)); box-shadow: var(--shadow-inset); }
.mail-mini .n { font-family: var(--font-display); font-weight: 700; font-size: 1.45rem;
  line-height: 1; display: block; }
.mail-mini .l { font-family: var(--font-mono); font-size: .58rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-muted); margin-top: .45rem; display: block; }
.mail-mini .ok { color: var(--accent); } .mail-mini .sig { color: var(--signal); }
.mail-mini .crit { color: var(--critical); }
@media (max-width: 560px) { .mail-mini { grid-template-columns: repeat(2, 1fr); } }

/* ---- 8. Site detail page ------------------------------------------- */
.back { display: inline-flex; align-items: center; gap: .5rem; color: var(--text-muted);
  font-size: .84rem; font-weight: 500; text-decoration: none; }
.back:hover { color: var(--text); }
.back svg { width: 15px; height: 15px; stroke: currentColor; fill: none; stroke-width: 2; }

.site-head { display: flex; align-items: flex-start; gap: 1.25rem; flex-wrap: wrap; }
.site-head .titles h1 { font-size: clamp(1.7rem, 3.4vw, 2.4rem); letter-spacing: -.03em; }
.site-head .titles .what { color: var(--text-muted); margin-top: .45rem; }
.site-head .act { margin-left: auto; display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.btn-accent { height: 40px; padding: 0 1.2rem; border-radius: var(--radius-pill);
  background: var(--accent); color: var(--accent-ink); font-weight: 600; font-size: .86rem;
  box-shadow: 0 8px 20px -10px var(--glow-accent);
  transition: transform .18s var(--ease), box-shadow .2s var(--ease); }
.btn-accent:hover { transform: translateY(-2px); box-shadow: 0 14px 28px -10px var(--glow-accent); }

/* four small facts in a recessed strip */
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .75rem; }
.fact { padding: 1rem 1.1rem; border-radius: var(--radius-sm); border: var(--hairline);
  background: color-mix(in srgb, var(--surface) 55%, var(--bg)); box-shadow: var(--shadow-inset); }
.fact .k { font-family: var(--font-mono); font-size: .58rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-muted); display: block; }
.fact .v { font-family: var(--font-display); font-weight: 700; font-size: 1.3rem; line-height: 1;
  margin-top: .5rem; display: block; }
.fact .v small { font-size: .58em; font-weight: 500; color: var(--text-muted); }

/* the empty state that tells the truth instead of showing zero */
.empty { display: grid; place-items: center; text-align: center; gap: .9rem;
  padding: clamp(2rem, 4vw, 3rem); border: 1px dashed var(--border);
  border-radius: var(--radius); background: color-mix(in srgb, var(--surface) 45%, transparent); }
.empty .mark { width: 46px; height: 46px; border-radius: 14px; display: grid; place-items: center;
  background: var(--surface-2); box-shadow: var(--shadow-inset); color: var(--inert);
  font-size: 1.1rem; }
.empty p { color: var(--text-muted); font-size: .88rem; max-width: 46ch; }

/* issue rows — the detail page IS where error text belongs */
.issue { padding: 1.15rem clamp(1.25rem, 2.4vw, 1.75rem);
  border-bottom: 1px solid color-mix(in srgb, var(--border) 45%, transparent); }
.issue:last-child { border-bottom: 0; }
.issue .top { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; }
.issue .top .ttl { font-weight: 600; font-size: .95rem; }
.issue .top .count { margin-left: auto; font-family: var(--font-mono); font-size: .74rem;
  color: var(--text-muted); }
.issue .plain { color: var(--text-muted); font-size: .86rem; margin-top: .5rem; max-width: 80ch; }
.issue details { margin-top: .7rem; }
.issue summary { cursor: pointer; font-family: var(--font-mono); font-size: .68rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--accent); width: max-content; }
.issue pre { margin-top: .6rem; padding: .8rem 1rem; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--bg) 55%, var(--surface)); border: var(--hairline);
  box-shadow: var(--shadow-inset); font-family: var(--font-mono); font-size: .7rem;
  line-height: 1.65; color: var(--text-muted); white-space: pre-wrap; word-break: break-word;
  overflow-x: auto; }

/* ---- 9. Login ------------------------------------------------------ */
.auth-wrap { min-height: 100vh; display: grid; place-items: center; padding: var(--gutter);
  position: relative; overflow: hidden; }
.auth-glow { position: absolute; border-radius: 50%; filter: blur(120px); opacity: .34;
  background: var(--glow-accent); width: 46vw; height: 46vw; max-width: 620px; max-height: 620px;
  top: -18%; right: -10%; pointer-events: none; }
.auth-card { width: 100%; max-width: 396px; padding: clamp(1.8rem, 4vw, 2.6rem);
  border: var(--hairline); border-radius: var(--radius-lg); background: var(--surface);
  box-shadow: var(--shadow-raise); }
.auth-card .mark { width: 46px; height: 46px; border-radius: 15px; display: grid;
  place-items: center; background: var(--accent); color: var(--accent-ink);
  font-family: var(--font-display); font-weight: 800; font-size: 1.2rem;
  box-shadow: 0 12px 26px -12px var(--glow-accent); }
.auth-card h1 { font-size: 1.5rem; margin-top: 1.4rem; letter-spacing: -.02em; }
.auth-card .sub { color: var(--text-muted); font-size: .88rem; margin-top: .5rem; }
.auth-card .fld { margin-top: 1.4rem; }
.auth-card label { display: block; font-family: var(--font-mono); font-size: .62rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--text-muted); margin-bottom: .5rem; }
.auth-card input { width: 100%; height: 46px; padding: 0 1rem; color: var(--text);
  background: color-mix(in srgb, var(--surface) 40%, var(--bg)); border: var(--hairline);
  border-radius: var(--radius-sm); font: 400 .95rem/1 var(--font-body);
  box-shadow: var(--shadow-inset); transition: border-color .2s, box-shadow .2s; }
.auth-card input::placeholder { color: color-mix(in srgb, var(--text-muted) 70%, transparent); }
.auth-card input:focus { outline: none; border-color: var(--accent);
  box-shadow: var(--shadow-inset), 0 0 0 3px var(--glow-accent); }
.auth-card .go { width: 100%; height: 46px; margin-top: 1.7rem; border-radius: var(--radius-pill);
  background: var(--accent); color: var(--accent-ink); font-weight: 700; font-size: .95rem;
  box-shadow: 0 10px 24px -10px var(--glow-accent);
  transition: transform .18s var(--ease), box-shadow .2s var(--ease); }
.auth-card .go:hover { transform: translateY(-2px); box-shadow: 0 16px 32px -10px var(--glow-accent); }
.auth-card .go:active { transform: translateY(0); box-shadow: var(--shadow-inset); }
.auth-note { color: var(--text-muted); font-size: .78rem; line-height: 1.65; margin-top: 1.6rem;
  padding-top: 1.3rem; border-top: var(--hairline); }
.auth-err { margin-top: 1.2rem; padding: .7rem .9rem; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--critical) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--critical) 30%, transparent);
  color: var(--critical); font-size: .82rem; }
.auth-foot { text-align: center; margin-top: 1.6rem; font-family: var(--font-mono);
  font-size: .62rem; letter-spacing: .12em; text-transform: uppercase; color: var(--inert); }

/* ---- 10. Shared small pieces --------------------------------------- */
.hint { color: var(--text-muted); font-size: .84rem; line-height: 1.6; max-width: 76ch; }
.tiny-link { font-size: .82rem; font-weight: 600; color: var(--accent); }
.split { display: grid; grid-template-columns: 1.3fr 1fr; gap: 1rem; align-items: start; }
@media (max-width: 1100px) { .split { grid-template-columns: 1fr; } }
.stack-2 { display: grid; gap: 1rem; }


/* ===== helm-wide.css ===== */

/* =====================================================================
   HELM — wide-screen layout. Load THIRD, after helm.css and
   helm-overview.css.

   The base layout capped content at 1600px and centred it. On a large
   monitor that leaves a wide empty band down both sides while the panels
   stay narrow — the screenshot showed roughly 240px of dead space each
   side at ~1990px viewport.

   Fixed by removing the cap and letting the gutter grow with the
   viewport instead. Margins are still there and get *larger* on a big
   screen; the content simply uses the room it has.
   ===================================================================== */

:root {
  /* Gutter now scales with the viewport and tops out generously, so a 4K
     monitor gets real breathing room rather than a 40px edge. */
  --gutter: clamp(1rem, 2.2vw, 4rem);
}

/* No cap. The gutter provides the left and right margin. */
main {
  max-width: none;
  margin-inline: 0;
  padding-inline: var(--gutter);
}

/* The top bar has to line up with the content it sits above, or the
   heading floats away from the first tile edge. */
.topbar { padding-inline: var(--gutter); }

/* ---- What extra width should be spent on -----------------------------
   Not on stretching four tiles to 500px each. Above ~1700px the hero row
   is allowed a wider minimum so tiles grow to a readable size and then
   stop, and the two-column split gets a little more to the left panel
   where the progress bars live.                                       */
@media (min-width: 1700px) {
  .hero-row { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
  .split { grid-template-columns: 1.45fr 1fr; }
  .tiles { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
}

/* Beyond ~2300px, stop the hero row spreading into four enormous slabs —
   cap each tile and let the row stay left-aligned with the rest. */
@media (min-width: 2300px) {
  .hero-row { grid-template-columns: repeat(4, minmax(0, 420px)); }
  .servers { grid-template-columns: repeat(auto-fit, minmax(420px, 1fr)); }
}

/* ---- Long reading lines are the one real cost of full width ---------
   A paragraph 1800px wide is genuinely hard to read — the eye loses the
   line on the way back. Prose keeps a measure; data does not.        */
.hint, .empty p, .issue .plain, .footnote { max-width: 82ch; }
.site-head .titles .what { max-width: 92ch; }

/* The site list has room for the response time and the status word to
   breathe rather than crowding the right edge. */
@media (min-width: 1700px) {
  .site-row { grid-template-columns: 1.6rem 1fr auto auto 1.1rem; gap: 2rem; }
  .site-row .stat { min-width: 6rem; }
}

/* Graphs benefit most from the extra width — more days visible without
   the bars becoming slabs. */
@media (min-width: 1700px) {
  .graph { height: 220px; }
  .gbar .col { max-width: 110px; }
}

/* ==== merged from the Open Design project: assets/helm-depth.css ==== */
/* ============================================================================================
   HELM — depth revision: soft-UI surfaces, MATERIAL elevation
   Load AFTER helm.css / helm-overview.css. Overrides depth only; no colour, type or spacing.

   THE BRIEF, IN THE OWNER'S WORDS
   "The soft UI is too harsh… I'm gonna go with a little bit of soft UI and material design,
    especially when it comes to buttons, they are so deep. I like the 3D effect, but I don't want
    it to be IN. I want it OUT. Those parts that are in, I would like them to be either flat or
    material design."

   TWO SEPARATE FAULTS WERE MAKING IT HARSH, AND ONLY ONE WAS DIRECTION.

   1. DIRECTION. Content tiles carried `--shadow-inset`, which is a dent. A tile is an object you
      could pick up; a dent is a hole in the page. Objects now sit OUT (--elev-1/2). Only two
      things stay recessed, because they genuinely are: a text field you type into, and a button
      for the instant it is held down.

   2. BLUR RADIUS, which was the bigger half. The old raise was
         0 34px 66px -28px rgba(0,0,0,.9)
      — a 66px cloud offset 34px down at 90% black. That is not softness, it is fog: at that
      radius the shadow stops reading as "this is lifted" and becomes a dark smear the eye reads as
      grime. Material's ramp is tight and layered — a 1px contact line plus a short penumbra — so
      the object looks lifted a few millimetres rather than floating half a metre above a wall.
      Every shadow here is under 12px.

   3. Corollary: the old neumorphic top highlight was `inset 0 1px 0 rgba(255,255,255,1)` in light
      mode. A pure-white hairline along the top of every surface is the single most recognisable
      neumorphism tell, and against #FBFBF9 it glares. Dropped to .55, and the surface now earns
      its edge from a real border instead.

   WHAT IS DELIBERATELY NOT CHANGED: the tokens. Not one hex value moves. The brand's dark
   #0A0A0B / #141416, the lime #CDFF3E, the amber #FF9F45 and the type scale are untouched — this
   file is about how light falls on a surface, not what colour the surface is.
   ============================================================================================ */

:root {
  /* ── Material elevation ramp. Two shadows each: a tight contact line that anchors the object
        to the page, and a short penumbra that lifts it. Both stay under 12px of blur. ── */
  --elev-0: none;                                              /* flat: border does the work */
  --elev-1: 0 1px 2px rgba(0, 0, 0, .38),
            0 2px 6px -1px rgba(0, 0, 0, .34);                  /* resting tile / card         */
  --elev-2: 0 1px 2px rgba(0, 0, 0, .42),
            0 4px 10px -2px rgba(0, 0, 0, .40);                 /* button, interactive chip    */
  --elev-3: 0 2px 4px rgba(0, 0, 0, .44),
            0 8px 18px -4px rgba(0, 0, 0, .46);                 /* hover lift, open menu       */

  /* A 1px lit top edge. Present, but not the white glare of the old value. */
  --lip: inset 0 1px 0 rgba(255, 255, 255, .055);

  /* Recessed, and now used for only two things: a field you type in, and a held button. Shallow
     on purpose — 3px of blur, not 7px. */
  --press: inset 0 1px 3px rgba(0, 0, 0, .40);

  /* A flat well. Material's answer to "this is a container, not an object": tone change plus a
     hairline, no shadow at all. Used for progress tracks and quiet strips. */
  --well: color-mix(in srgb, var(--bg) 62%, var(--surface));

  /* Panels keep depth but lose the fog. */
  --shadow-soft: var(--lip), 0 1px 2px rgba(0, 0, 0, .34), 0 6px 14px -6px rgba(0, 0, 0, .42);
  --shadow-raise: var(--lip), 0 2px 4px rgba(0, 0, 0, .38), 0 10px 22px -8px rgba(0, 0, 0, .46);
  /* Kept only so any stale reference degrades to "flat" rather than to a dent. */
  --shadow-inset: none;
}

html[data-theme="light"] {
  --elev-1: 0 1px 2px rgba(20, 20, 25, .09),
            0 2px 6px -1px rgba(20, 20, 25, .08);
  --elev-2: 0 1px 2px rgba(20, 20, 25, .11),
            0 4px 10px -2px rgba(20, 20, 25, .10);
  --elev-3: 0 2px 4px rgba(20, 20, 25, .12),
            0 8px 18px -4px rgba(20, 20, 25, .14);
  /* .55 not 1. A pure-white lip is the neumorphism tell, and on #FBFBF9 it glares. */
  --lip: inset 0 1px 0 rgba(255, 255, 255, .55);
  --press: inset 0 1px 3px rgba(20, 20, 25, .12);
  --well: color-mix(in srgb, var(--bg) 55%, #ffffff);
  --shadow-soft: var(--lip), 0 1px 2px rgba(20, 20, 25, .07), 0 6px 14px -6px rgba(20, 20, 25, .10);
  --shadow-raise: var(--lip), 0 2px 4px rgba(20, 20, 25, .09), 0 10px 22px -8px rgba(20, 20, 25, .13);
  --shadow-inset: none;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --elev-1: 0 1px 2px rgba(20, 20, 25, .09), 0 2px 6px -1px rgba(20, 20, 25, .08);
    --elev-2: 0 1px 2px rgba(20, 20, 25, .11), 0 4px 10px -2px rgba(20, 20, 25, .10);
    --elev-3: 0 2px 4px rgba(20, 20, 25, .12), 0 8px 18px -4px rgba(20, 20, 25, .14);
    --lip: inset 0 1px 0 rgba(255, 255, 255, .55);
    --press: inset 0 1px 3px rgba(20, 20, 25, .12);
    --well: color-mix(in srgb, var(--bg) 55%, #ffffff);
  }
}

/* ── OUT: things that were dents and are now objects ─────────────────────────────────────── */
/* Each of these is a thing on the page, not a hole in it. */
.mail-mini > div,
.fact,
.pill,
.stat,
.kpi,
.hero-tile .ring,
.plain-list li > code,
.chip {
  box-shadow: var(--lip), var(--elev-1) !important;
  background: var(--surface);
}

/* ── FLAT: containers, per the "flat or material design" instruction ─────────────────────── */
/* A progress track IS a groove, so making it stand out would be wrong. Material solves that with
   tone, not with a shadow: the track is a flat low-contrast band and the FILL is what carries
   elevation. That reads as a measurement rather than a scratch in the surface. */
.pbar .track,
.gauge .track,
.status-strip,
.empty .mark {
  box-shadow: none !important;
  background: var(--well);
  border: var(--hairline);
}

.pbar .fill,
.gauge .fill {
  box-shadow: 0 1px 2px rgba(0, 0, 0, .22);   /* the fill lifts; the track does not */
}

/* ── The one thing the owner named directly: buttons ─────────────────────────────────────── */
/* Raised at rest, lifted on hover, and pressed only while actually held. The 1px translate is
   what sells a physical press — a shadow change alone reads as a colour flicker. */
.btn,
.auth-card .go,
button.go,
.tiny-link.btn,
[role="button"] {
  box-shadow: var(--lip), var(--elev-2);
  border: var(--hairline);
  border-radius: var(--radius-sm);
  transition: box-shadow .16s var(--ease), transform .10s var(--ease);
}

.btn:hover,
.auth-card .go:hover,
button.go:hover {
  box-shadow: var(--lip), var(--elev-3);
  transform: translateY(-1px);
}

.btn:active,
.auth-card .go:active,
button.go:active {
  box-shadow: var(--press) !important;
  transform: translateY(1px);
}

/* ── IN, legitimately: a field you type into ─────────────────────────────────────────────── */
/* Kept recessed because the affordance is correct — the cursor goes INTO this. Shallower than
   before, and the focus ring now comes from the accent rather than from more shadow. */
.auth-card input,
input[type="text"],
input[type="email"],
input[type="password"] {
  box-shadow: var(--press) !important;
  background: var(--well);
  border: var(--hairline);
}

.auth-card input:focus,
input:focus {
  box-shadow: var(--press), 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent) !important;
  border-color: var(--accent);
  outline: none;
}

/* ── Navigation: the current page reads as selected, not as a hole ──────────────────────── */
/* Material's own pattern: a tonal container plus a leading indicator bar. No dent. */
.nav-item[aria-current="page"] {
  box-shadow: none !important;
  background: color-mix(in srgb, var(--accent) 12%, var(--surface));
  position: relative;
}

.nav-item[aria-current="page"]::before {
  content: "";
  position: absolute;
  inset-block: 18%;
  inset-inline-start: 0;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--accent);
}

/* ── Severity marks and the partial-day bar keep their meaning, lose the dent ───────────── */
.finding .sev,
.issue .sev {
  box-shadow: var(--lip), var(--elev-1) !important;
}

.gbar.is-partial .col {
  box-shadow: none !important;
  background: repeating-linear-gradient(135deg,
    color-mix(in srgb, var(--text-muted) 26%, transparent) 0 3px,
    transparent 3px 7px);
}

/* ── No code on screen ──────────────────────────────────────────────────────────────────── */
/* The owner asked for "straight on-point errors, not technical". A <pre> of a stack trace is the
   opposite of that, so the styling that made one look at home is removed rather than restyled —
   if a raw log line ever reaches a page again it should look wrong, not comfortable. */
.finding pre,
.issue pre {
  display: none !important;
}

/* Reduced motion: keep the elevation, drop the movement. */
@media (prefers-reduced-motion: reduce) {
  .btn, .auth-card .go, button.go, [role="button"] { transition: none; }
  .btn:hover, .auth-card .go:hover, button.go:hover,
  .btn:active, .auth-card .go:active, button.go:active { transform: none; }
}

/* ==== merged from the Open Design project: assets/helm-pages.css ==== */
/* ============================================================================================
   HELM — shared layout for the inner pages (Problems, Site report, Email, Security, Databases,
   Alerts). Load AFTER helm.css, helm-overview.css, helm-wide.css and helm-depth.css.

   NO SHADOWS ARE DEFINED HERE. Every raised or flat surface pulls --elev-1/--elev-2/--lip/--well
   from helm-depth.css, so the "soft UI but material, out not in" decision lives in exactly one
   file. If depth needs tuning again, that is a one-file change and this stays untouched.

   These classes were extracted after the first two pages, because both had grown a near-identical
   inline <style> block. A third copy would have guaranteed they drifted apart.
   ============================================================================================ */

main { display: flex; flex-direction: column; gap: clamp(1.25rem, 2.4vw, 1.9rem); }

/* ── Page header ─────────────────────────────────────────────────────────────────────────── */
.page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 1.5rem;
  flex-wrap: wrap; }
.page-head h1 { font-family: var(--font-display); font-size: clamp(1.6rem, 2.4vw, 2.1rem);
  letter-spacing: -.02em; margin: 0 0 .35rem; }
.lede { color: var(--text-muted); font-size: .95rem; max-width: 66ch; margin: 0; line-height: 1.6; }
.back { font-size: .82rem; color: var(--text-muted); text-decoration: none; width: max-content; }
.back:hover { color: var(--accent); }

/* ── Figure row. One rhythm across every page, so the eye learns it once. ───────────────── */
.kpi-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: .85rem; }
.kpi-row.is-three { grid-template-columns: repeat(3, 1fr); }
.kpi-row.is-two { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 1000px) { .kpi-row, .kpi-row.is-three { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .kpi-row, .kpi-row.is-three, .kpi-row.is-two {
  grid-template-columns: 1fr; } }

.kpi { display: flex; flex-direction: column; gap: .2rem; padding: 1rem 1.1rem;
  border-radius: var(--radius-sm); border: var(--hairline); background: var(--surface); }
.k-lbl { font-family: var(--font-mono); font-size: .68rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--text-muted); }
.k-val { font-family: var(--font-display); font-size: 1.55rem; line-height: 1.15;
  letter-spacing: -.025em; }
.k-val.ok { color: var(--accent); }
.k-val.sig { color: var(--signal); }
.k-val.crit { color: var(--critical); }
.k-note { font-size: .78rem; color: var(--text-muted); line-height: 1.45; }

/* A figure with no collector behind it reads as PENDING, never as zero. That distinction is the
   whole reason this product exists: "0 visitors" and "nobody counted" are different facts. */
.kpi-row.is-pending .kpi { opacity: .62; }
.kpi-row.is-pending .k-val { color: var(--inert); }

/* ── Verdict chip next to a heading ──────────────────────────────────────────────────────── */
.verdict { display: inline-flex; align-items: center; gap: .45rem; font-size: .86rem;
  font-weight: 600; padding: .3rem .7rem; border-radius: var(--radius-pill);
  border: var(--hairline); background: var(--surface); box-shadow: var(--lip), var(--elev-1); }
.verdict.is-ok .g { color: var(--accent); }
.verdict.is-signal .g { color: var(--signal); }
.verdict.is-critical .g { color: var(--critical); }
.verdict.is-inert .g { color: var(--inert); }

.sub-h { font-family: var(--font-display); font-size: .95rem; letter-spacing: -.01em;
  margin: 1.7rem 0 .1rem; }

.btn { display: inline-block; padding: .5rem .95rem; font-size: .85rem; font-weight: 600;
  text-decoration: none; color: var(--accent-ink); background: var(--accent); }
.btn.is-quiet { background: var(--surface); color: var(--text); }

/* ── Triage strip: grouped by the ACTION required, not by log severity ──────────────────── */
/* "Fix now" and "Worth fixing" are decisions. "error" and "warning" are not — they make the
   reader do the triage the software should have done. */
.triage { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
@media (max-width: 840px) { .triage { grid-template-columns: 1fr; } }
.triage-card { display: grid; grid-template-columns: auto 1fr;
  grid-template-rows: auto auto auto; gap: .1rem .8rem; padding: 1.15rem 1.25rem;
  border-radius: var(--radius); border: var(--hairline); background: var(--surface);
  box-shadow: var(--lip), var(--elev-1); text-decoration: none; color: inherit;
  transition: box-shadow .16s var(--ease), transform .1s var(--ease); }
a.triage-card:hover { box-shadow: var(--lip), var(--elev-3); transform: translateY(-1px); }
.tri-mark { grid-row: 1 / 3; align-self: center; font-size: 1.5rem; line-height: 1; }
.tri-n { font-family: var(--font-display); font-size: 1.9rem; line-height: 1;
  letter-spacing: -.03em; }
.tri-lbl { font-weight: 650; font-size: .9rem; }
.tri-note { grid-column: 2; color: var(--text-muted); font-size: .8rem; }
.is-critical .tri-mark { color: var(--critical); }
.is-signal .tri-mark { color: var(--signal); }
.is-ok .tri-mark { color: var(--accent); }
.is-inert .tri-mark { color: var(--inert); }

/* ── A problem card, built to be READ rather than scanned past ──────────────────────────── */
.prob { border: var(--hairline); border-radius: var(--radius); background: var(--surface);
  box-shadow: var(--lip), var(--elev-1); overflow: hidden; }
.prob.is-critical { border-inline-start: 3px solid var(--critical); }
.prob.is-signal { border-inline-start: 3px solid var(--signal); }
.prob-head { display: flex; align-items: flex-start; gap: 1rem; padding: 1.35rem 1.5rem 0; }
.prob-head .sev { font-size: 1.15rem; line-height: 1.5; }
.prob.is-critical .sev { color: var(--critical); }
.prob.is-signal .sev { color: var(--signal); }
.prob-title { flex: 1 1 auto; min-width: 0; }
.prob-title h2 { font-family: var(--font-display); font-size: 1.16rem; letter-spacing: -.01em;
  margin: 0 0 .2rem; }
.prob-where { font-family: var(--font-mono); font-size: .78rem; color: var(--text-muted);
  margin: 0; }
.prob-body { padding: 1rem 1.5rem 1.5rem; }
/* Set larger than body copy on purpose: if only one line on the page gets read, it is this one. */
.prob-lead { font-size: 1.02rem; line-height: 1.62; margin: .5rem 0 1rem; max-width: 74ch; }
.prob-why { color: var(--text-muted); font-size: .9rem; line-height: 1.62; margin: 0 0 1.1rem;
  max-width: 74ch; }
.prob-do { border-radius: var(--radius-sm); border: var(--hairline); background: var(--well);
  padding: 1rem 1.1rem; max-width: 74ch; }
.do-label { display: block; font-family: var(--font-mono); font-size: .7rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent); margin-bottom: .4rem; }
.prob-do p { margin: 0; font-size: .92rem; line-height: 1.6; }
.prob-meta { display: flex; flex-wrap: wrap; gap: .4rem 1.4rem; margin-top: 1.1rem;
  padding-top: .9rem; border-top: var(--hairline); font-size: .8rem; color: var(--text-muted); }
.prob-meta b { color: var(--text); font-weight: 600; }

.mini-prob { display: flex; gap: .9rem; align-items: flex-start; padding: 1.05rem 1.15rem;
  border-radius: var(--radius-sm); border: var(--hairline); background: var(--surface);
  box-shadow: var(--lip), var(--elev-1); }
.mini-prob.is-signal { border-inline-start: 3px solid var(--signal); }
.mini-prob.is-critical { border-inline-start: 3px solid var(--critical); }
.mini-prob .sev { font-size: 1.05rem; line-height: 1.4; }
.mini-prob.is-signal .sev { color: var(--signal); }
.mini-prob.is-critical .sev { color: var(--critical); }
.mini-prob h3 { font-family: var(--font-display); font-size: 1rem; margin: 0 0 .3rem; }
.mini-prob p { margin: 0 0 .45rem; font-size: .9rem; line-height: 1.6; max-width: 72ch; }
.mini-meta { font-size: .78rem; color: var(--text-muted); }

/* ── Evidence, closed by default and clearly not addressed to the owner ─────────────────── */
/* The instruction was "no code on the screen". The log line is still kept, because a finding whose
   evidence has been thrown away cannot be verified — but it takes a deliberate click, and the
   summary says who it is for. */
.tech, .tech-panel { margin-top: 1rem; }
.tech-panel { margin-top: 0; border: var(--hairline); border-radius: var(--radius);
  background: var(--surface); box-shadow: var(--lip), var(--elev-1); overflow: hidden; }
.tech summary, .tech-panel summary { cursor: pointer; font-size: .84rem; color: var(--text-muted);
  list-style: none; display: flex; align-items: center; gap: .55rem; }
.tech summary { padding: .5rem 0; }
.tech-panel summary { padding: 1.05rem 1.4rem; font-size: .88rem; }
.tech summary::-webkit-details-marker,
.tech-panel summary::-webkit-details-marker { display: none; }
.tech summary::before, .tech-panel summary::before { content: "\25B8"; font-size: .7rem;
  transition: transform .15s var(--ease); }
.tech[open] summary::before, .tech-panel[open] summary::before { transform: rotate(90deg); }
.tech-note { font-size: .78rem; color: var(--text-muted); margin: .2rem 0 .6rem; }
.tech-line { display: block; font-family: var(--font-mono); font-size: .78rem;
  background: var(--well); border: var(--hairline); border-radius: var(--radius-sm);
  padding: .6rem .8rem; overflow-x: auto; white-space: pre; }

/* ── Two-column split, matching the overview ─────────────────────────────────────────────── */
.pair { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; align-items: start; }
@media (max-width: 1100px) { .pair { grid-template-columns: 1fr; } }

/* ── .plain-list ───────────────────────────────────────────────────────────────────────────
   A short list of facts, one line each: a thing, what it is, and a figure. Used by nearly every
   panel on these pages.

   IT LIVES HERE, NOT IN helm.css, AND THAT WAS A REAL BUG. The rule was added to the DEPLOYED
   stylesheet on the server, but the Open Design project keeps its own older copy of helm.css --
   so every list on these design pages rendered as unstyled bullets while the live dashboard looked
   correct. Two copies of a stylesheet in two places is exactly how that happens. Shared page rules
   belong in this file, which both sides load.

   Deliberately NOT a table: these are 5-8 rows of two or three fields, and a table would bring
   header cells, alignment rules and a horizontal scroll container on a phone for no gain.

   `word-break: break-all` on the code element is load-bearing -- an IPv6 address is 39 characters
   and would otherwise push a panel wider than its grid column and scroll the whole page sideways. */
.plain-list { list-style: none; margin: .55rem 0 0; padding: 0; border-top: var(--hairline); }
.plain-list li { display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem .75rem;
  padding: .62rem .1rem; border-bottom: var(--hairline); font-size: .86rem; }
.plain-list li > code { font-family: var(--font-mono); font-size: .82rem; color: var(--text);
  background: color-mix(in srgb, var(--surface) 55%, var(--bg));
  border: var(--hairline); border-radius: var(--radius-sm);
  padding: .12rem .42rem; word-break: break-all;
  box-shadow: var(--lip), var(--elev-1); }
.plain-list li > b { font-weight: 650; }
/* The last .muted on a row is the figure, pushed right. Earlier ones stay next to the label. */
.plain-list li .muted:last-child { margin-left: auto; text-align: right; white-space: nowrap; }
@media (max-width: 620px) {
  .plain-list li .muted:last-child { margin-left: 0; text-align: left; white-space: normal; }
}

/* ── Header trimmings ──────────────────────────────────────────────────────────────────────
   These three were used across six pages and defined in none of them — found by grepping every
   class attribute against every stylesheet rather than by looking at the pages, which is the only
   way this kind of gap surfaces. An undefined class does not error; it just quietly renders as
   nothing, and .head-aside carried the status chip at the top right of five screens. */
.head-aside { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.head-actions { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; margin-top: .4rem; }
/* A count sits beside a heading, so it is set in the mono face to read as data, not as prose. */
.pill--count { font-family: var(--font-mono); font-size: .76rem; white-space: nowrap; }
