/* ===========================================================================
   EZEmail console — enterprise design system
   ---------------------------------------------------------------------------
   Everything here is self-hosted. The Content-Security-Policy is
   `font-src 'self'` and `script-src 'self'`, so there is no CDN, no Google
   Fonts link and no external stylesheet anywhere in this console.

   The visual idea: this is infrastructure for people who need to know whether
   mail arrived. Numbers are the loudest thing on every page and are set in
   tabular figures; every colour that appears on a metric MEANS a delivery
   state — green delivered, red bounced, amber deferred, blue accepted.

   Enterprise conventions this file follows:
     - a quiet navy navigation rail that can collapse to icons,
     - a readable type scale (15px body, 14px tables, 28px page titles) with
       sentence-case table headers rather than faint all-caps,
     - cards with a defined header band that can be expanded and collapsed,
     - notices that lead with an icon and a bold first phrase, so the one
       sentence that matters is found before the paragraph is read.

   Class names are a contract with ~95 templates and several tests. Restyle
   freely; rename nothing.
   =========================================================================== */

/* --- self-hosted faces ---------------------------------------------------- */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/inter-latin-wght-normal.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('/assets/fonts/montserrat-latin-wght-normal.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'Nunito Sans';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('/assets/fonts/nunito-sans-latin-wght-normal.woff2') format('woff2-variations');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url('/assets/fonts/jetbrains-mono-latin-wght-normal.woff2') format('woff2-variations');
}

/* --- tokens --------------------------------------------------------------- */
/*
   The light theme is the one this product is designed in. It follows the
   reference console supplied with the brief — a white rail, a near-white page,
   white panels with a hairline border and one soft shadow, 8px corners — with
   every purple replaced by the Y5 brand green.

   ABOUT THE GREEN. #3a8e03 measures 4.16:1 against white, which is under the
   4.5 the WCAG asks for body text. So the brand colour fills things (buttons,
   the active nav tint, chart marks, the logo mark) and a darker step of the
   same hue, --accent-ink, carries the text that sits ON white. They read as
   one colour; only one of them is legible at 13px.

   ABOUT GREEN MEANING TWO THINGS. In a delivery console green already means
   "delivered", and the brand is now also green. They are kept apart by hue:
   the brand is a yellow-green (96°) and every success/delivered state is a
   teal-green (162°). Side by side they do not read as the same colour, and a
   chart that mixes them stays readable.
*/
:root {
  --bg:          #f8f9fd;
  --surface:     #ffffff;
  --surface-2:   #fafbfc;
  --surface-3:   #f1f4f9;
  --border:      #e6ebf1;
  --border-strong:#cfd6e0;

  --text:        #46525f;
  --text-soft:   #606e7b;
  --text-faint:  #8a97a6;
  --heading:     #171e25;

  /* The brand. --accent fills, --accent-ink writes. */
  --accent:      #3a8e03;
  --accent-hover:#2f7302;
  --accent-ink:  #2a6604;
  --accent-soft: #eaf7e1;
  --accent-wash: #f5fbf1;
  --accent-line: #cfe9b8;
  --accent-mute: #b4d89a;
  --accent-text: #ffffff;

  /* Delivery states. These are data colours before they are brand colours,
     and the success hue is deliberately teal so it is not the brand green. */
  --ok:        #0e9f6e;
  --ok-soft:   #e8f7f1;
  --ok-line:   #a7e3cd;
  --warn:      #b45309;
  --warn-soft: #fdf6e3;
  --warn-line: #f5d183;
  --bad:       #cf3a2c;
  --bad-soft:  #fdf1ef;
  --bad-line:  #f8c2ba;
  --info:      #0f5f85;
  --info-soft: #e0f0f8;

  /* The rail is white in this theme; the tokens stay so dark can flip them. */
  --rail:        #ffffff;
  --rail-2:      #ffffff;
  --rail-3:      #f1f4f9;
  --rail-line:   #e6ebf1;
  --rail-text:   #606e7b;
  --rail-faint:  #8a97a6;
  --rail-active: #3a8e03;
  --rail-accent: #3a8e03;
  --rail-head:   #171e25;
  --rail-shadow: 5px 0 39px rgba(23,30,37,.06);
  --rail-hover:    #f1f4f9;
  --rail-chip:     #f5f7fa;
  --rail-scroll:   #d7dee7;
  --rail-active-bg:#eaf7e1;

  --radius:    8px;
  --radius-sm: 6px;
  --radius-lg: 12px;
  --radius-pill: 999px;

  /* Shallow on purpose: one card shadow, tinted with the brand hue rather
     than black, so panels sit on the page instead of hovering over it. */
  --shadow-sm: 0 1px 2px rgba(23,30,37,.05);
  --shadow:    0 2px 10px rgba(93,124,74,.12);
  --shadow-lg: 0 17px 52px rgba(96,110,123,.30);
  --overlay:   rgba(23,30,37,.45);
  --ring:      0 0 0 4px var(--accent-soft);

  --sidebar-w:  64px;   /* the icon rail; a panel opens beside it */
  --rail-w:     64px;
  --panel-w:    264px;
  --topbar-h:   76px;

  --font: 'Nunito Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-display: 'Montserrat', 'Nunito Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  /* One spacing scale, so nothing is spaced by feel. */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 20px; --s6: 24px; --s7: 32px; --s8: 40px; --s9: 56px;

  --ease: cubic-bezier(.2,.8,.2,1);
}

/* Dark applies when the VIEWER asks for it, or when explicitly set. Written as
   two blocks rather than one so an explicit choice beats the system setting in
   both directions. The brand green lightens here: #3a8e03 on a near-black
   panel is 2.6:1 and unreadable, while #7fc94a is 9:1. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:          #0c1117;
    --surface:     #131a22;
    --surface-2:   #18212b;
    --surface-3:   #1f2a36;
    --border:      #26323f;
    --border-strong:#37475a;
    --text:        #d7dee7;
    --text-soft:   #a3b0bf;
    --text-faint:  #7c8a99;
    --heading:     #f2f6fa;
    --accent:      #7fc94a;
    --accent-hover:#93d862;
    --accent-ink:  #9bdc5c;
    --accent-soft: #16300b;
    --accent-wash: #101f09;
    --accent-line: #2f5c19;
    --accent-mute: #3f6b25;
    --accent-text: #0a1505;
    --ok:        #34d399; --ok-soft:  #0b2b22; --ok-line:  #1b5545;
    --warn:      #fbbf5c; --warn-soft:#2c2211; --warn-line:#59431a;
    --bad:       #f87171; --bad-soft: #2c1614; --bad-line: #5c2724;
    --info:      #67b7dd; --info-soft:#0d2733;
    --rail:      #0b1016;
    --rail-2:    #10171f;
    --rail-3:    #1b242f;
    --rail-line: rgba(255,255,255,.08);
    --rail-text: #b6c2cf;
    --rail-faint:#7c8a99;
    --rail-active:#ffffff;
    --rail-accent:#7fc94a;
    --rail-head: #ffffff;
    --rail-shadow: none;
    --rail-hover:    rgba(255,255,255,.07);
    --rail-chip:     rgba(255,255,255,.05);
    --rail-scroll:   rgba(255,255,255,.14);
    --rail-active-bg:rgba(127,201,74,.16);
    --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
    --shadow:    0 1px 3px rgba(0,0,0,.5);
    --shadow-lg: 0 18px 40px -12px rgba(0,0,0,.7);
    --overlay:   rgba(0,0,0,.62);
    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --bg:          #0c1117;
  --surface:     #131a22;
  --surface-2:   #18212b;
  --surface-3:   #1f2a36;
  --border:      #26323f;
  --border-strong:#37475a;
  --text:        #d7dee7;
  --text-soft:   #a3b0bf;
  --text-faint:  #7c8a99;
  --heading:     #f2f6fa;
  --accent:      #7fc94a;
  --accent-hover:#93d862;
  --accent-ink:  #9bdc5c;
  --accent-soft: #16300b;
  --accent-wash: #101f09;
  --accent-line: #2f5c19;
  --accent-mute: #3f6b25;
  --accent-text: #0a1505;
  --ok:        #34d399; --ok-soft:  #0b2b22; --ok-line:  #1b5545;
  --warn:      #fbbf5c; --warn-soft:#2c2211; --warn-line:#59431a;
  --bad:       #f87171; --bad-soft: #2c1614; --bad-line: #5c2724;
  --info:      #67b7dd; --info-soft:#0d2733;
  --rail:      #0b1016;
  --rail-2:    #10171f;
  --rail-3:    #1b242f;
  --rail-line: rgba(255,255,255,.08);
  --rail-text: #b6c2cf;
  --rail-faint:#7c8a99;
  --rail-active:#ffffff;
  --rail-accent:#7fc94a;
  --rail-head: #ffffff;
  --rail-shadow: none;
    --rail-hover:    rgba(255,255,255,.07);
    --rail-chip:     rgba(255,255,255,.05);
    --rail-scroll:   rgba(255,255,255,.14);
    --rail-active-bg:rgba(127,201,74,.16);
  --shadow-sm: 0 1px 2px rgba(0,0,0,.4);
  --shadow:    0 1px 3px rgba(0,0,0,.5);
  --shadow-lg: 0 18px 40px -12px rgba(0,0,0,.7);
  --overlay:   rgba(0,0,0,.62);
  color-scheme: dark;
}

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

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Numbers line up in every table and tile. */
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'cv05' 1, 'ss03' 1;
  text-rendering: optimizeLegibility;
}

/* --- type scale ----------------------------------------------------------- */
h1, h2, h3, h4, h5, h6 { margin: 0; font-family: var(--font-display); font-weight: 700; letter-spacing: -.012em; color: var(--heading); }
h1 { font-size: 27px; line-height: 1.25; font-weight: 700; letter-spacing: -.02em; }
h2 { font-size: 17px; line-height: 1.35; }
h3 { font-size: 15.5px; line-height: 1.4; }
h4 { font-size: 14px; }
p  { margin: 0 0 var(--s3); }
p:last-child { margin-bottom: 0; }

strong, b { font-weight: 650; color: var(--heading); }
.notice strong, .demo-banner strong { color: inherit; }

a { color: var(--accent-ink); text-decoration: none; font-weight: 600; }
a:hover { text-decoration: underline; text-underline-offset: 3px; }

code {
  font-family: var(--mono); font-size: .88em;
  padding: 1px 6px; border-radius: 5px;
  background: var(--surface-3); border: 1px solid var(--border);
}

hr { border: 0; border-top: 1px solid var(--border); margin: var(--s5) 0; }

.muted  { color: var(--text-soft); }
.tiny   { font-size: 13px; line-height: 1.5; }
.small  { font-size: 13.5px; }
.mono   { font-family: var(--mono); font-size: 13px; letter-spacing: -.01em; }
.num    { font-variant-numeric: tabular-nums; }
.wrap   { white-space: normal; overflow-wrap: anywhere; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }
td.truncate { max-width: 320px; }
.ok   { color: var(--ok); }
.warn { color: var(--warn); }
.bad  { color: var(--bad); }

/* An eyebrow that labels a group. Used for stat labels and legends. */
.legend-label, .stat-label {
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: .01em;
  color: var(--text-soft);
}

/* An important value somebody should not miss. */
.highlight {
  background: linear-gradient(transparent 58%, var(--warn-soft) 58%);
  font-weight: 600;
}
.key-figure { font-size: 20px; font-weight: 700; letter-spacing: -.02em; color: var(--heading); }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--accent); color: #fff; padding: var(--s3) var(--s4);
  border-radius: 0 0 var(--radius-sm) 0;
}
.skip:focus { left: 0; }

/* --- shell ---------------------------------------------------------------- */
.shell { display: flex; min-height: 100vh; }

.main-column {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  margin-left: var(--sidebar-w);
  transition: margin-left .22s var(--ease);
}

.main {
  flex: 1;
  padding: var(--s6) var(--s8) var(--s9);
  max-width: 1520px;
  width: 100%;
  outline: none;
}

/* --- sidebar: the icon rail and its panels (owner, 2026-10-19) ------------ */
/* Two columns. The RAIL is always there: one icon per section, hover for its
   name. A PANEL opens beside it with that section's pages. Only one panel is
   open at a time, so the menu never has to scroll up and down.
   Without JavaScript every panel is simply stacked under the rail. */
.sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  width: var(--sidebar-w);
  background: var(--rail);
  display: flex;
  flex-direction: row;
  z-index: 60;
  border-right: 1px solid var(--rail-line);
  box-shadow: var(--rail-shadow);
  transition: transform .22s var(--ease);
}

.rail {
  width: var(--rail-w); flex-shrink: 0;
  display: flex; flex-direction: column; align-items: center;
  padding: 10px 0;
  gap: 2px;
  border-right: 1px solid var(--rail-line);
  background: var(--rail);
}
.rail-brand {
  display: grid; place-items: center;
  width: 44px; height: 44px; margin-bottom: 8px;
  color: var(--rail-head); border-radius: var(--radius-sm);
}
.rail-brand:hover, .rail-brand:focus { color: var(--rail-head); text-decoration: none; background: var(--rail-hover); }
.rail-mark { width: 28px; height: 28px; display: block; }
.auth-brand .brand-logo { height: 34px; }

.rail-nav { display: flex; flex-direction: column; align-items: center; gap: 4px; width: 100%; }
.rail-divider { width: 24px; height: 1px; background: var(--rail-line); margin: 6px 0; }

.rail-btn {
  position: relative;
  width: 44px; height: 44px;
  display: grid; place-items: center;
  border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--rail-text);
  cursor: pointer;
  transition: background .12s ease, color .12s ease, transform .12s var(--ease);
}
.rail-btn .nav-icon { width: 21px; height: 21px; opacity: .85; }
.rail-btn:hover { background: var(--rail-hover); color: var(--rail-active); }
.rail-btn:hover .nav-icon { opacity: 1; }
.rail-btn:active { transform: scale(.96); }
.rail-btn.is-active { color: var(--rail-active); }
.rail-btn.is-active .nav-icon { color: var(--rail-accent); opacity: 1; }
.rail-btn[aria-expanded="true"] { background: var(--rail-active-bg); color: var(--rail-active); }
.rail-btn[aria-expanded="true"] .nav-icon { opacity: 1; }
/* The section holding the page you are on carries a bar, like the old active row. */
.rail-btn.is-active::before {
  content: ''; position: absolute; left: -10px; top: 10px; bottom: 10px; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--rail-accent);
}
.rail-dot { position: absolute; right: 8px; top: 8px; width: 6px; height: 6px; border-radius: 50%; background: var(--rail-accent); }

.rail-foot { margin-top: auto; padding-top: 8px; }
.rail-status {
  display: block; width: 12px; height: 12px; border-radius: 50%;
  background: currentColor; cursor: default;
  box-shadow: 0 0 0 3px color-mix(in srgb, currentColor 25%, transparent);
}
.rail-status.is-ok   { color: #2ea86b; }
.rail-status.is-warn { color: #e9a23b; }

/* The panel column. Fixed beside the rail on a desktop, over the page rather
   than pushing it, so opening a menu never reflows a chart. */
.nav-panels { flex: 1; min-width: 0; }
.nav-panel {
  display: flex; flex-direction: column;
  background: var(--rail-2);
  color: var(--rail-text);
}
.js .nav-panel {
  position: fixed; top: 0; bottom: 0; left: var(--rail-w);
  width: var(--panel-w);
  border-right: 1px solid var(--rail-line);
  box-shadow: var(--shadow-lg);
  z-index: 61;
  transform: translateX(-8px); opacity: 0; visibility: hidden;
  transition: transform .18s var(--ease), opacity .15s ease, visibility 0s linear .18s;
}
.js .nav-panel.is-open {
  transform: none; opacity: 1; visibility: visible;
  transition: transform .18s var(--ease), opacity .15s ease, visibility 0s;
}
.nav-panel-head {
  display: flex; align-items: center; gap: var(--s2);
  height: var(--topbar-h); flex-shrink: 0;
  padding: 0 var(--s3) 0 var(--s4);
  border-bottom: 1px solid var(--rail-line);
}
.nav-panel-title {
  flex: 1; min-width: 0; margin: 0;
  font-family: var(--font-display); font-size: 15px; font-weight: 700; letter-spacing: -.01em;
  color: var(--rail-head);
}
.nav-panel-close {
  width: 30px; height: 30px; flex-shrink: 0;
  display: grid; place-items: center;
  border: 0; border-radius: var(--radius-sm);
  background: none; color: var(--rail-faint); cursor: pointer;
}
.nav-panel-close svg { width: 16px; height: 16px; }
.nav-panel-close:hover { background: var(--rail-hover); color: var(--rail-head); }
html:not(.js) .nav-panel-close { display: none; }
.nav-panel-body {
  flex: 1; overflow-y: auto; overflow-x: hidden;
  padding: var(--s3) var(--s3) var(--s5);
  scrollbar-width: thin; scrollbar-color: var(--rail-scroll) transparent;
}
.nav-panel-body::-webkit-scrollbar { width: 6px; }
.nav-panel-body::-webkit-scrollbar-thumb { background: var(--rail-scroll); border-radius: 3px; }

.nav-entry { position: relative; }
.nav-item {
  display: flex; align-items: center; gap: var(--s3);
  padding: 9px var(--s3);
  margin-bottom: 2px;
  border-radius: var(--radius-sm);
  color: var(--rail-text);
  font-size: 14.5px;
  font-weight: 500;
  line-height: 1.35;
  position: relative;
  transition: background .12s ease, color .12s ease;
}
.nav-item > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-item:hover { background: var(--rail-hover); color: var(--rail-active); text-decoration: none; }
.nav-item.is-active {
  background: var(--rail-active-bg);
  color: var(--rail-active); font-weight: 700;
}
.nav-item.is-active::before {
  content: ''; position: absolute; left: -12px; top: 8px; bottom: 8px; width: 3px;
  border-radius: 0 3px 3px 0; background: var(--rail-accent);
}
.nav-item.is-active .nav-icon { color: var(--rail-accent); opacity: 1; }

.nav-icon {
  width: 19px; height: 19px; flex-shrink: 0;
  opacity: .78;
  transition: opacity .12s ease;
}
.nav-item:hover .nav-icon { opacity: 1; }

/* Sub-navigation: the drill-down under a parent, always shown — the panel is
   this section's whole menu, so there is nothing to fold away. Indented to the
   parent's LABEL rather than its icon, so the hierarchy reads down the text
   column. */
.nav-sub {
  margin: 0 0 var(--s2) 21px;
  padding-left: 14px;
  border-left: 1px solid var(--rail-line);
}
.nav-subitem {
  display: block;
  padding: 7px var(--s3);
  margin-bottom: 1px;
  border-radius: var(--radius-sm);
  color: var(--rail-faint);
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.4;
  transition: background .12s ease, color .12s ease;
}
.nav-subitem:hover { background: var(--rail-hover); color: var(--rail-active); text-decoration: none; }
.nav-subitem.is-active { color: var(--rail-active); font-weight: 700; background: var(--rail-active-bg); }

/* Find a page */
.nav-filter { padding: var(--s3) var(--s3) 0; flex-shrink: 0; }
.nav-filter-box {
  display: flex; align-items: center; gap: 8px;
  padding: 0 10px;
  border: 1px solid var(--rail-line); border-radius: var(--radius-sm);
  background: var(--rail-chip); color: var(--rail-faint);
  transition: border-color .12s ease, box-shadow .12s ease;
}
.nav-filter-box:focus-within { border-color: var(--rail-accent); color: var(--rail-head); background: var(--rail-hover); box-shadow: var(--ring); }
.nav-filter-box .nav-icon { width: 15px; height: 15px; flex-shrink: 0; opacity: 1; }
.nav-filter input[type=search] { min-height: 0;
  flex: 1; min-width: 0; padding: 9px 0; border: 0; background: none; color: var(--rail-head); font-size: 14px; }
.nav-filter input::placeholder { color: var(--rail-faint); }
.nav-filter input[type=search]:focus { outline: none; box-shadow: none; }
.nav-index-heading { padding: var(--s3) var(--s3) 4px; font-size: 11.5px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--rail-faint); }
.nav-index-link.is-child { padding-left: 22px; }
.nav-index-link.is-hidden, .nav-index-group.is-hidden { display: none; }
.nav-empty { display: none; padding: var(--s3) var(--s4); color: var(--rail-faint); font-size: 13.5px; }
.nav-panel-body.is-filtering-empty .nav-empty { display: block; }


/* --- topbar --------------------------------------------------------------- */
.topbar {
  position: sticky; top: 0; z-index: 40;
  height: var(--topbar-h);
  display: flex; align-items: center; gap: var(--s4);
  padding: 0 var(--s8);
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--border);
  box-shadow: 0 1px 0 rgba(15,27,45,.02);
}

.org-name {
  display: flex; align-items: center; gap: var(--s2);
  font-weight: 650; font-size: 15px; letter-spacing: -.01em; color: var(--heading);
  white-space: nowrap;
}
.org-name::before {
  content: ''; width: 9px; height: 9px; border-radius: 3px; background: var(--accent);
}
.org-switch select { min-width: 200px; font-weight: 600; }
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: var(--s2); }

.topbar-search {
  display: flex; align-items: center; gap: var(--s2);
  flex: 0 1 420px;
  min-width: 0;
  padding: 0 var(--s2) 0 var(--s3);
  height: 40px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text-faint);
  transition: border-color .12s ease, box-shadow .12s ease, background .12s ease;
}
.topbar-search:focus-within { border-color: var(--accent); background: var(--surface); color: var(--text); box-shadow: var(--ring); }
.topbar-search input[type=search] { min-height: 0;
  flex: 1; min-width: 0;
  border: 0; padding: 0; height: auto;
  background: none; box-shadow: none;
  font-size: 14.5px;
  color: var(--text);
}
.topbar-search input[type=search]:focus { outline: none; box-shadow: none; }
.topbar-search input::-webkit-search-decoration,
.topbar-search input::-webkit-search-cancel-button { -webkit-appearance: none; }

kbd, .kbd {
  display: inline-grid; place-items: center;
  min-width: 22px; height: 22px; padding: 0 6px;
  border: 1px solid var(--border-strong); border-bottom-width: 2px;
  border-radius: 5px;
  background: var(--surface);
  font-family: var(--font); font-size: 12px; font-weight: 600; color: var(--text-soft);
  line-height: 1;
}

.topbar .topbar-search-link { display: none; }
.topbar .menu-toggle { display: none; }

/* --- page head ------------------------------------------------------------ */
.page-head {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: var(--s5); margin-bottom: var(--s6);
  padding-bottom: var(--s5);
  border-bottom: 1px solid var(--border);
}
.page-head h1 + .muted { margin-top: 6px; font-size: 15px; color: var(--text-soft); max-width: 80ch; }
.page-actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); flex-shrink: 0; }
.page-actions .filters { padding: 0; border: 0; background: none; }
.page-actions form { margin: 0; }

/* Expand-all / collapse-all, inserted by console.js on pages with sections. */
.page-tools {
  display: flex; justify-content: flex-end; gap: var(--s2);
  margin: calc(-1 * var(--s3)) 0 var(--s3);
}

.crumbs {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  font-size: 13.5px; color: var(--text-faint); margin-bottom: var(--s2); font-weight: 500;
}
.crumbs a { color: var(--text-soft); }
.crumbs a:hover { color: var(--accent); }

/* --- cards ---------------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.card + .card { margin-top: var(--s5); }
.grid > .card + .card,
.grid > .card { margin-top: 0; }

.card-head {
  display: flex; align-items: center; justify-content: flex-end; flex-wrap: wrap;
  gap: var(--s2) var(--s4);
  padding: 14px var(--s5);
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
  min-height: 56px;
}
.card-head h2, .card-head h3 {
  display: flex; align-items: center; gap: var(--s2);
  font-family: var(--font-display); font-size: 16px; font-weight: 700; color: var(--heading);
  margin-right: auto;
}
/* A short accent tick in front of a section title, so the eye finds section
   starts down a long page without reading. Where a panel carries an icon
   badge the badge does that job, and two markers would be one too many. */
.card-head h2::before {
  content: ''; width: 4px; height: 16px; border-radius: 2px; background: var(--accent); flex-shrink: 0;
}
.card-head:has(.icon-badge) h2::before { display: none; }
.card-head .icon-badge { margin-right: calc(var(--s2) * -1 + 2px); }

/* The card header carries a badge now, so it needs the room a widget header
   has. */
.card-head:has(.icon-badge) { padding-top: 12px; padding-bottom: 12px; min-height: 60px; }
.card-head > .tiny.muted, .card-head > span.tiny { font-size: 13px; }
.card-head form { margin: 0; }
.card-head-tools { display: flex; align-items: center; gap: var(--s2); margin-left: auto; }

.card-toggle {
  display: inline-grid; place-items: center;
  width: 30px; height: 30px; flex-shrink: 0;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text-soft);
  cursor: pointer;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.card-toggle:hover { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-line); }
.card.is-collapsible > .card-head h2 { cursor: pointer; user-select: none; }
.card.is-collapsed > .card-head { border-bottom-color: transparent; }
.card.is-collapsed > :not(.card-head) { display: none !important; }
.card-collapsed-note { display: none; font-size: 12.5px; color: var(--text-faint); font-weight: 500; }
.card.is-collapsed .card-collapsed-note { display: inline; }

.card-body { padding: var(--s5); }
.card-body.tight { padding: 0; }
.card-body > .filters:first-child { margin: calc(-1 * var(--s5)) calc(-1 * var(--s5)) 0; }
.card-body.tight > .hint, .card-body.tight > p { padding: var(--s3) var(--s5) 0; }

/* --- grid ----------------------------------------------------------------- */
.grid { display: grid; gap: var(--s5); align-items: start; }
.grid-2 { grid-template-columns: repeat(2, minmax(0,1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0,1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
.grid-5 { grid-template-columns: repeat(5, minmax(0,1fr)); }

/* --- stat tiles ----------------------------------------------------------- */
.stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px var(--s5) var(--s5);
  box-shadow: var(--shadow);
  position: relative;
  overflow: hidden;
}
.stat::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 3px;
  background: var(--accent);
}
.stat.is-ok::before   { background: var(--ok); }
.stat.is-warn::before { background: var(--warn); }
.stat.is-bad::before  { background: var(--bad); }
.stat.is-quiet::before{ background: var(--border-strong); }
.stat.is-warn { background: linear-gradient(180deg, var(--warn-soft) 0%, var(--surface) 55%); }
.stat.is-bad  { background: linear-gradient(180deg, var(--bad-soft) 0%, var(--surface) 55%); }

.stat-label { display: flex; align-items: center; gap: 6px; }
.stat-value {
  display: block;
  font-family: var(--font-display);
  font-size: 32px;
  font-weight: 700;
  letter-spacing: -.03em;
  line-height: 1.1;
  margin-top: var(--s2);
  color: var(--heading);
  font-variant-numeric: tabular-nums;
}
.stat.is-ok .stat-value   { color: var(--ok); }
.stat.is-bad .stat-value  { color: var(--bad); }
.stat.is-warn .stat-value { color: var(--warn); }
.stat-sub { display: block; margin-top: 6px; font-size: 13px; color: var(--text-soft); }

/* --- THE SIGNATURE: delivery pipeline ------------------------------------- */
.pipeline { display: block; }

.pipeline-bar {
  display: flex;
  height: 14px;
  border-radius: var(--radius-pill);
  overflow: hidden;
  background: var(--surface-3);
  margin-bottom: var(--s5);
  box-shadow: inset 0 1px 2px rgba(15,27,45,.08);
}
.pipeline-seg {
  height: 100%;
  transition: width .5s cubic-bezier(.16,1,.3,1);
  min-width: 0;
}
.pipeline-seg + .pipeline-seg { box-shadow: -2px 0 0 var(--surface); }
.pipeline-seg.is-delivered { background: var(--ok); }
.pipeline-seg.is-bounced   { background: var(--bad); }
.pipeline-seg.is-deferred  { background: var(--warn); }
.pipeline-seg.is-pending   { background: var(--accent-line); }

.pipeline-legend { display: flex; flex-wrap: wrap; gap: var(--s4) var(--s7); }
.legend-item { display: flex; align-items: baseline; gap: var(--s2); }
.legend-dot {
  width: 10px; height: 10px; border-radius: 3px; flex-shrink: 0;
  transform: translateY(-1px);
}
.legend-dot.is-delivered { background: var(--ok); }
.legend-dot.is-bounced   { background: var(--bad); }
.legend-dot.is-deferred  { background: var(--warn); }
.legend-dot.is-pending   { background: var(--accent-line); }
.legend-value { font-size: 18px; font-weight: 700; color: var(--heading); font-variant-numeric: tabular-nums; }
.legend-label { display: block; }

/* --- badges --------------------------------------------------------------- */
.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  font-family: var(--font-display);
  font-size: 12.5px; font-weight: 600; line-height: 1.6;
  background: var(--surface-3);
  color: var(--text-soft);
  border: 1px solid var(--border);
  white-space: nowrap;
  vertical-align: middle;
}
.badge::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .75; }
.badge-ok    { background: var(--ok-soft);   color: var(--ok);   border-color: var(--ok-line); }
.badge-warn  { background: var(--warn-soft); color: var(--warn); border-color: var(--warn-line); }
.badge-bad   { background: var(--bad-soft);  color: var(--bad);  border-color: var(--bad-line); }
.badge-quiet { background: var(--surface-3); color: var(--text-soft); border-color: var(--border); }
.badge-quiet::before { display: none; }
.badge-info  { background: var(--accent-soft); color: var(--accent-ink); border-color: var(--accent-line); }

/* --- buttons -------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 38px;
  padding: 8px 16px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--heading);
  font-family: var(--font-display); font-size: 14px; font-weight: 700; line-height: 1.3;
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: background .12s ease, border-color .12s ease, box-shadow .12s ease, transform .06s ease;
  box-shadow: var(--shadow-sm);
}
.btn:hover { background: var(--surface-3); border-color: var(--text-faint); text-decoration: none; }
.btn:active { transform: translateY(1px); }

.btn-primary {
  background: var(--accent); border-color: var(--accent); color: var(--accent-text);
  box-shadow: 0 1px 2px rgba(23,30,37,.10), inset 0 1px 0 rgba(255,255,255,.18);
}
.btn-primary:hover { background: var(--accent-hover); border-color: var(--accent-hover); }

.btn-danger { background: var(--bad); border-color: var(--bad); color: #fff; }
.btn-danger:hover { background: #a82d21; border-color: #a82d21; }

.btn-ghost { background: transparent; border-color: transparent; box-shadow: none; color: var(--text-soft); }
.btn-ghost:hover { background: var(--surface-3); border-color: transparent; color: var(--heading); }

.btn-sm { min-height: 32px; padding: 5px 12px; font-size: 13px; }
.btn[disabled], .btn:disabled { opacity: .5; cursor: not-allowed; }
.btn svg { width: 16px; height: 16px; flex-shrink: 0; }

.icon-button {
  display: inline-grid; place-items: center;
  width: 38px; height: 38px;
  border: 1px solid transparent; background: transparent;
  border-radius: var(--radius-sm);
  color: var(--text-soft); cursor: pointer; font-size: 16px;
}
.icon-button:hover { background: var(--surface-3); color: var(--heading); text-decoration: none; }
.icon-button svg { width: 19px; height: 19px; }

/* The "?" beside a heading or metric. */
.help-tip {
  display: inline-grid; place-items: center;
  width: 18px; height: 18px; padding: 0; margin: 0 2px;
  border: 1px solid var(--border-strong); border-radius: 50%;
  background: var(--surface); color: var(--text-soft);
  font-family: var(--font); font-size: 11px; font-weight: 700; line-height: 1;
  cursor: help; vertical-align: middle;
  text-transform: none; letter-spacing: 0;
}
.help-tip:hover, .help-tip[aria-expanded="true"] { background: var(--accent); border-color: var(--accent); color: #fff; }

/* --- forms ---------------------------------------------------------------- */
.field { margin-bottom: var(--s5); }
.field:last-child { margin-bottom: 0; }

label {
  display: block;
  font-size: 14px; font-weight: 600;
  margin-bottom: 7px;
  color: var(--heading);
}
label.inline, label:has(> input[type=checkbox]), label:has(> input[type=radio]) {
  display: flex; align-items: center; gap: var(--s2); font-weight: 500;
}

/* A bare <input> — no type attribute — is a text field to the browser, but
   `input[type=text]` does not match it. 90 inputs in these templates carry no
   type and were rendering as unstyled browser defaults beside correctly styled
   selects, which is exactly how they looked: not part of the app.

   `input:not([type])` is ADDED rather than rewriting the list as a chain of
   :not()s, because every :not() contributes its argument's specificity: ten of
   them would outrank `.nav-filter input` and `.topbar-search input` and undo
   the sidebar and topbar search fields. Every selector here stays at (0,1,1). */
input:not([type]),
input[type=text], input[type=email], input[type=password], input[type=search],
input[type=number], input[type=url], input[type=date], input[type=datetime-local],
input[type=time], input[type=tel], input[type=month], input[type=week],
select, textarea {
  width: 100%;
  min-height: 40px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  color: var(--text);
  font-family: inherit; font-size: 14.5px; line-height: 1.5;
  transition: border-color .12s ease, box-shadow .12s ease;
  box-shadow: none;
}
input::placeholder, textarea::placeholder { color: var(--text-faint); }
input:hover:not(:focus), select:hover:not(:focus), textarea:hover:not(:focus) { border-color: var(--text-faint); }
textarea { min-height: 130px; resize: vertical; font-family: var(--mono); font-size: 13.5px; }
input[type=checkbox], input[type=radio] { width: 17px; height: 17px; accent-color: var(--accent); margin: 0; vertical-align: middle; }

input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--ring);
}
input:required + .hint::before { content: ''; }

select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23606e7b' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  padding-right: 34px;
}

.hint { font-size: 13px; color: var(--text-soft); margin-top: 6px; line-height: 1.55; }
.field-error {
  display: flex; align-items: center; gap: 6px;
  font-size: 13px; color: var(--bad); margin-top: 6px; font-weight: 600;
}
.field-error::before { content: '!'; display: inline-grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; background: var(--bad); color: #fff; font-size: 11px; font-weight: 800; }
input.is-error, textarea.is-error, select.is-error { border-color: var(--bad); box-shadow: 0 0 0 4px var(--bad-soft); }

fieldset { border: 1px solid var(--border); border-radius: var(--radius); padding: var(--s4) var(--s5); margin: 0 0 var(--s5); }
legend { padding: 0 6px; font-weight: 650; font-size: 14px; color: var(--heading); }

.filters {
  display: flex; flex-wrap: wrap; gap: var(--s3) var(--s4); align-items: flex-end;
  padding: var(--s4) var(--s5);
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}
.filters .field { margin-bottom: 0; min-width: 170px; }
.filters label { font-size: 13px; color: var(--text-soft); }

/* Focus ring for anything keyboard-reachable. */
a:focus-visible, button:focus-visible, summary:focus-visible, .nav-item:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}
.sidebar a:focus-visible, .sidebar button:focus-visible { outline-color: var(--rail-accent); }

/* --- tables --------------------------------------------------------------- */
.table-wrap { overflow-x: auto; }

table { width: 100%; border-collapse: collapse; font-size: 14px; }

thead th {
  position: sticky; top: 0;
  text-align: left;
  padding: 12px var(--s5);
  background: var(--accent-soft);
  border-bottom: 1px solid var(--accent-line);
  font-family: var(--font-display);
  font-size: 12.5px; font-weight: 700;
  letter-spacing: .01em;
  color: var(--accent-ink);
  white-space: nowrap;
}

tbody td {
  padding: 13px var(--s5);
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
  color: var(--text);
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr { transition: background .1s ease; }
tbody tr:nth-child(odd) td { background: var(--surface-2); }
tbody tr:hover td { background: var(--accent-wash); }
tbody td:first-child { font-weight: 550; }
tbody td a { font-weight: 600; }

tbody tr.row-flash td { background: var(--warn-soft) !important; transition: background .3s ease; }

td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }

/* The details column added by console.js. */
th.row-details-col, td.row-details-col { width: 1%; padding-left: var(--s2); padding-right: var(--s4); text-align: right; }
.row-details-btn {
  display: inline-grid; place-items: center;
  width: 28px; height: 28px;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text-soft);
  cursor: pointer;
}
.row-details-btn:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.row-details-btn svg { width: 15px; height: 15px; }

/* --- key/value ------------------------------------------------------------ */
/* Label/value pairs, the shape every settings and detail panel needs. Ruled
   rows rather than a bare grid: at more than about four pairs the eye loses
   which value belongs to which label. */
.kv { display: grid; grid-template-columns: minmax(150px, max-content) 1fr; gap: 0 var(--s5); margin: 0; }
.kv > dt { padding: 10px 0; border-bottom: 1px solid var(--border); font-size: 13.5px; color: var(--text-soft); }
.kv > dd { padding: 10px 0; border-bottom: 1px solid var(--border); margin: 0; color: var(--heading); font-weight: 500; }
.kv > dt:last-of-type, .kv > dd:last-of-type { border-bottom: 0; }
.kv dt, .kv dd { padding: 9px 0; border-bottom: 1px dashed var(--border); }
.kv dt:last-of-type, .kv dd:last-of-type { border-bottom: 0; }
.kv dt { color: var(--text-soft); font-size: 14px; font-weight: 500; }
.kv dd { margin: 0; font-size: 14.5px; font-weight: 600; color: var(--heading); overflow-wrap: anywhere; }

/* --- notices -------------------------------------------------------------- */
/* `display: block` below beats the browser's own [hidden] rule, so a notice
   marked hidden (e.g. the warm-up editor's empty "This schedule cannot be
   saved yet" box) showed on every page load. Hidden means hidden. */
.notice[hidden] { display: none; }
.notice {
  position: relative;
  display: block;
  padding: 14px var(--s5) 14px 52px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  border-left-width: 4px;
  background: var(--surface-2);
  margin-bottom: var(--s5);
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--text);
  min-width: 0;
  overflow-wrap: anywhere;
}
.notice > * { min-width: 0; }
.notice > div + div, .notice > p + p, .notice > div + form, .notice > p + form { margin-top: var(--s2); }
.notice::before {
  content: 'i';
  position: absolute; left: 16px; top: 14px;
  width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center;
  font-size: 13px; font-weight: 800; font-style: normal; line-height: 1;
  color: #fff; background: var(--text-soft);
}
.notice strong:first-child { font-weight: 700; }
.notice a { font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.notice-ok   { background: var(--ok-soft);   border-color: var(--ok-line);   border-left-color: var(--ok); }
.notice-ok::before   { content: '✓'; background: var(--ok); }
.notice-warn { background: var(--warn-soft); border-color: var(--warn-line); border-left-color: var(--warn); }
.notice-warn::before { content: '!'; background: var(--warn); }
.notice-bad  { background: var(--bad-soft);  border-color: var(--bad-line);  border-left-color: var(--bad); }
.notice-bad::before  { content: '!'; background: var(--bad); }
.notice-info { background: var(--info-soft); border-color: var(--accent-line); border-left-color: var(--accent); }
.notice-info::before { background: var(--accent); }
:root[data-theme="dark"] .notice::before { color: #0a111c; }
.notice-dismiss {
  position: absolute; right: 8px; top: 8px;
  width: 28px; height: 28px; display: grid; place-items: center;
  border: 0; background: none; border-radius: var(--radius-sm);
  color: inherit; opacity: .6; cursor: pointer; font-size: 18px; line-height: 1;
}
.notice-dismiss:hover { opacity: 1; background: rgba(15,27,45,.06); }
.notice.has-dismiss { padding-right: 44px; }

/* --- empty state ---------------------------------------------------------- */
.empty { padding: var(--s9) var(--s5); text-align: center; }
.empty h3 { font-size: 17px; margin-bottom: var(--s2); }
.empty h3::before {
  content: ''; display: block; width: 44px; height: 44px; margin: 0 auto var(--s4);
  border-radius: 12px; background: var(--accent-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' viewBox='0 0 24 24' fill='none' stroke='%232a6604' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 12h-6l-2 3h-4l-2-3H2'/%3E%3Cpath d='M5.45 5.11L2 12v6a2 2 0 002 2h16a2 2 0 002-2v-6l-3.45-6.89A2 2 0 0016.76 4H7.24a2 2 0 00-1.79 1.11z'/%3E%3C/svg%3E") center no-repeat;
}
.empty p { color: var(--text-soft); max-width: 52ch; margin-inline: auto; }
.empty .btn { margin-top: var(--s5); }

/* --- charts --------------------------------------------------------------- */
.chart { position: relative; width: 100%; height: 220px; }
.chart canvas { display: block; width: 100% !important; }

.legend { display: flex; gap: var(--s5); flex-wrap: wrap; margin-top: var(--s4); }

/* --- pager ---------------------------------------------------------------- */
.pager {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s4);
  padding: var(--s3) var(--s5);
  border-top: 1px solid var(--border);
  background: var(--surface-2);
  font-size: 14px;
}

/* --- user menu ------------------------------------------------------------ */
.avatar {
  width: 32px; height: 32px; flex-shrink: 0;
  display: grid; place-items: center;
  border-radius: 50%;
  background: linear-gradient(140deg, #4ca80a, #2a6604);
  color: #fff; font-size: 13px; font-weight: 700;
}
.avatar-lg { width: 42px; height: 42px; font-size: 16px; }

.menu { position: relative; }
.menu summary { list-style: none; cursor: pointer; }
.menu summary::-webkit-details-marker { display: none; }

details > summary.btn { list-style: none; cursor: pointer; display: inline-flex; }
details > summary.btn::-webkit-details-marker { display: none; }
.drawer {
  margin-top: var(--s3);
  padding: var(--s4);
  min-width: 280px;
  background: var(--surface-2, var(--surface));
  border: 1px solid var(--border);
  border-radius: var(--radius);
  text-align: left;
  white-space: normal;
  box-shadow: var(--shadow);
}
.drawer .field { margin-bottom: var(--s3); }
.drawer .field:last-of-type { margin-bottom: var(--s3); }

/* Generic disclosure with a +/- marker, for long explanatory blocks. */
details.disclosure { border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); margin: var(--s4) 0; }
details.disclosure > summary {
  display: flex; align-items: center; gap: var(--s3);
  padding: 12px var(--s4); cursor: pointer; list-style: none;
  font-weight: 650; color: var(--heading);
}
details.disclosure > summary::-webkit-details-marker { display: none; }
details.disclosure > summary::after {
  content: '+'; margin-left: auto; width: 22px; height: 22px; display: grid; place-items: center;
  border: 1px solid var(--border-strong); border-radius: 5px; font-weight: 600; color: var(--text-soft);
}
details.disclosure[open] > summary::after { content: '−'; }
details.disclosure[open] > summary { border-bottom: 1px solid var(--border); }
details.disclosure > .disclosure-body { padding: var(--s4); }

/* --- the route matrix ----------------------------------------------------- */
.matrix th.num, .matrix td.num { text-align: center; }
.matrix th { font-size: 12px; letter-spacing: .02em; }

.cell {
  display: inline-block;
  min-width: 38px;
  padding: 3px 8px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  font-weight: 650;
  text-decoration: none;
}
.cell:hover { text-decoration: none; filter: brightness(.96); }
.cell-ok    { background: var(--ok-soft);   color: var(--ok); }
.cell-warn  { background: var(--warn-soft); color: var(--warn); }
.cell-bad   { background: var(--bad-soft);  color: var(--bad); }
.cell-probe { background: var(--info-soft); color: var(--accent); }
.cell-none  { color: var(--text-soft); opacity: .4; }

td.num.warn { color: var(--warn); font-weight: 600; }

/* --- the demo banner ------------------------------------------------------ */
.demo-banner {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2);
  padding: 10px var(--s8);
  background: var(--warn-soft);
  border-bottom: 1px solid var(--warn-line);
  color: var(--warn);
  font-size: 13.5px;
  line-height: 1.5;
}
.demo-banner strong { font-weight: 700; }
.demo-banner a { margin-left: auto; color: inherit; text-decoration: underline; }

.user-chip {
  display: flex; align-items: center; gap: var(--s2);
  padding: 3px 12px 3px 3px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: 14px; font-weight: 600; color: var(--heading);
}
.user-chip:hover { background: var(--surface-3); }
.user-chip::after {
  content: ''; width: 7px; height: 7px; margin-left: 2px;
  border-right: 1.5px solid var(--text-faint); border-bottom: 1.5px solid var(--text-faint);
  transform: rotate(45deg) translateY(-2px);
}

.menu-panel {
  position: absolute; right: 0; top: calc(100% + 8px);
  min-width: 260px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: var(--s2);
  z-index: 70;
}
.menu-head { display: flex; align-items: center; gap: var(--s3); padding: var(--s3); border-bottom: 1px solid var(--border); margin-bottom: var(--s2); }
.menu-head > div { min-width: 0; }
.menu-head strong { display: block; }
.menu-item {
  display: flex; align-items: center; gap: var(--s3); width: 100%; text-align: left;
  padding: 9px var(--s3);
  border: 0; background: transparent;
  border-radius: var(--radius-sm);
  color: var(--text); font-family: inherit; font-size: 14px; font-weight: 500; cursor: pointer;
}
.menu-item svg { width: 17px; height: 17px; color: var(--text-faint); }
.menu-item:hover { background: var(--surface-3); text-decoration: none; }
.menu-item.danger { color: var(--bad); }
.menu-item.danger svg { color: var(--bad); }
.menu-sep { height: 1px; background: var(--border); margin: var(--s2) 0; }

/* --- dialogs (popups) ----------------------------------------------------- */
dialog.modal {
  width: min(640px, calc(100vw - 32px));
  max-height: min(86vh, 900px);
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
dialog.modal[open] { display: flex; flex-direction: column; animation: modal-in .18s var(--ease); }
dialog.modal::backdrop { background: var(--overlay); backdrop-filter: blur(2px); }
dialog.modal.modal-sm { width: min(460px, calc(100vw - 32px)); }
dialog.modal.modal-lg { width: min(880px, calc(100vw - 32px)); }
@keyframes modal-in { from { opacity: 0; transform: translateY(8px) scale(.98); } to { opacity: 1; transform: none; } }

.modal-head {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s4) var(--s5);
  border-bottom: 1px solid var(--border);
  background: var(--surface-2);
}
.modal-head h2 { font-size: 18px; flex: 1; min-width: 0; }
.modal-icon {
  width: 36px; height: 36px; flex-shrink: 0; display: grid; place-items: center;
  border-radius: 10px; background: var(--accent-soft); color: var(--accent); font-weight: 800; font-size: 17px;
}
.modal-danger .modal-icon { background: var(--bad-soft); color: var(--bad); }
.modal-close {
  width: 34px; height: 34px; display: grid; place-items: center;
  border: 0; background: none; border-radius: var(--radius-sm);
  color: var(--text-soft); font-size: 22px; line-height: 1; cursor: pointer;
}
.modal-close:hover { background: var(--surface-3); color: var(--heading); }
.modal-body { padding: var(--s5); overflow-y: auto; font-size: 15px; }
.modal-body .kv dd .mono { font-size: 13px; }
.modal-foot {
  display: flex; justify-content: flex-end; gap: var(--s2);
  padding: var(--s3) var(--s5);
  border-top: 1px solid var(--border);
  background: var(--surface-2);
}

/* Keyboard shortcut list inside the help dialog. */
.shortcuts { display: grid; grid-template-columns: max-content 1fr; gap: 10px var(--s5); align-items: center; margin: 0; }
.shortcuts dt { display: flex; gap: 4px; }
.shortcuts dd { margin: 0; color: var(--text-soft); }

/* --- popover (help tips) -------------------------------------------------- */
.popover {
  position: fixed; z-index: 120;
  max-width: 340px;
  padding: 12px 14px;
  border-radius: var(--radius);
  background: var(--heading); color: var(--surface);
  font-size: 13.5px; font-weight: 450; line-height: 1.55;
  box-shadow: var(--shadow-lg);
  text-transform: none; letter-spacing: 0;
}
.tooltip {
  position: fixed; z-index: 130; pointer-events: none;
  padding: 6px 10px; border-radius: 6px;
  background: #0b1628; color: #fff;
  font-size: 13px; font-weight: 550; white-space: nowrap;
  box-shadow: var(--shadow-lg);
}

/* --- toasts --------------------------------------------------------------- */
.toasts { position: fixed; right: 20px; bottom: 20px; z-index: 140; display: flex; flex-direction: column; gap: 8px; }
.toast {
  display: flex; align-items: center; gap: 10px;
  min-width: 220px; max-width: 380px;
  padding: 12px 16px;
  border-radius: var(--radius);
  background: #0b1628; color: #fff;
  font-size: 14px; font-weight: 550;
  box-shadow: var(--shadow-lg);
  animation: modal-in .18s var(--ease);
}
.toast::before { content: '✓'; display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: #16a34a; font-size: 12px; font-weight: 800; }

/* --- auth / public pages -------------------------------------------------- */
.auth {
  min-height: 100vh;
  display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  background: var(--bg);
}
.auth-aside {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; justify-content: space-between;
  padding: var(--s9);
  background:
    radial-gradient(700px 420px at 15% 0%, rgba(90,195,22,.30) 0%, transparent 60%),
    radial-gradient(600px 500px at 100% 100%, rgba(47,109,240,.25) 0%, transparent 60%),
    linear-gradient(160deg, #0c1a2e 0%, #13233b 100%);
  color: #d8e2d2;
}
.auth-aside .auth-brand { justify-content: flex-start; color: #fff; margin: 0; }
.auth-aside h2 { color: #fff; font-size: 34px; line-height: 1.2; letter-spacing: -.03em; font-weight: 700; max-width: 16ch; margin-bottom: var(--s4); }
.auth-aside p { color: #b9c6db; font-size: 16px; max-width: 46ch; }
.auth-points { list-style: none; padding: 0; margin: var(--s7) 0 0; display: grid; gap: var(--s3); }
.auth-points li { display: flex; gap: var(--s3); align-items: baseline; color: #d8e2d2; font-size: 15px; }
.auth-points li::before { content: '✓'; flex-shrink: 0; display: grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: rgba(90,195,22,.22); color: #a9e07a; font-size: 12px; font-weight: 800; transform: translateY(3px); }
.auth-aside .tiny { color: #8193ad; }
.auth-main { display: grid; place-items: center; padding: var(--s6); }
.auth > .auth-card { grid-column: 1 / -1; justify-self: center; align-self: center; }

.auth-card {
  width: 100%; max-width: 440px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: var(--s8);
}
.auth-brand {
  display: flex; align-items: center; justify-content: center; gap: var(--s3);
  margin-bottom: var(--s6);
  font-size: 19px; font-weight: 700; letter-spacing: -.02em; color: var(--heading);
}
.auth-card h1 { font-size: 24px; text-align: center; margin-bottom: var(--s2); }
.auth-card .muted { text-align: center; margin-bottom: var(--s6); font-size: 15px; }
.auth-card .btn { width: 100%; margin-top: var(--s2); min-height: 44px; font-size: 15px; }
.auth-card input { min-height: 44px; }

.public { min-height: 100vh; display: grid; place-items: center; padding: var(--s6); background: var(--bg); }
.public-card {
  max-width: 520px; width: 100%;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  padding: var(--s8); text-align: center;
}

/* --- bars (inline meters) ------------------------------------------------- */
.bar { height: 8px; background: var(--surface-3); border-radius: var(--radius-pill); overflow: hidden; }
.bar > span { display: block; height: 100%; background: var(--accent); border-radius: inherit; }

/* --- responsive ----------------------------------------------------------- */
@media (max-width: 1280px) {
  .main { padding: var(--s6) var(--s6) var(--s9); }
  .topbar { padding: 0 var(--s6); }
}

@media (max-width: 1100px) {
  .grid-4, .grid-5 { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .grid-3 { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .auth { grid-template-columns: minmax(0,1fr); }
  .auth-aside { display: none; }
}

@media (max-width: 860px) {
  .sidebar { transform: translateX(-100%); box-shadow: none; width: calc(var(--rail-w) + var(--panel-w)); }
  .sidebar.is-open { transform: none; box-shadow: var(--shadow-lg); }
  /* In the drawer the panel sits inside the sidebar, beside the rail. */
  .js .nav-panel { position: absolute; left: var(--rail-w); box-shadow: none; }
  .main-column { margin-left: 0; }
  .topbar .menu-toggle { display: inline-grid; }
  .main { padding: var(--s5) var(--s4) var(--s8); }
  .topbar { padding: 0 var(--s4); gap: var(--s2); }
  .topbar-search { display: none; }
  .topbar .topbar-search-link { display: inline-grid; }
  .user-chip .user-name, .topbar .role-badge, .org-name { display: none; }
  .demo-banner { padding: 10px var(--s4); }
  .demo-banner a { margin-left: 0; }
  .grid-2, .grid-3, .grid-4, .grid-5 { grid-template-columns: minmax(0,1fr); }
  .page-head { flex-direction: column; align-items: stretch; }
  h1 { font-size: 24px; }
  .stat-value { font-size: 28px; }
  .kv { grid-template-columns: minmax(0,1fr); }
  .kv dt { border-bottom: 0; padding-bottom: 0; }
  .auth-card { padding: var(--s6); }
}

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

@media print {
  .sidebar, .topbar, .page-actions, .pager, .page-tools, .card-toggle, .row-details-col, .help-tip { display: none !important; }
  .main-column { margin-left: 0 !important; }
  .card { box-shadow: none; break-inside: avoid; }
  .card.is-collapsed > :not(.card-head) { display: block !important; }
}

/* A figure a provider states for itself, against one it inherits from the
   platform. */
td.is-own { font-weight: 650; color: var(--heading); }
td.is-own::after { content: ' *'; color: var(--text-faint); font-weight: 400; }

/* --- IP & warm-up control plane ------------------------------------------ */
.chart-tall .chart { height: 320px; }
.chart-short .chart { height: 220px; }
.meter { display: grid; gap: 4px; min-width: 110px; }
.meter .bar > span.is-warn { background: var(--warn); }
.meter .bar > span.is-bad { background: var(--bad); }
.meter .bar > span.is-ok { background: var(--ok); }
.meter-label { font-size: 12.5px; color: var(--text-soft); white-space: nowrap; }
.action-row { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-start; }
.action-row form { margin: 0; }
.bulk-bar { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; padding: var(--s4) var(--s5); border-bottom: 1px solid var(--border); background: var(--surface-2, transparent); }
.bulk-bar .field { margin: 0; min-width: 160px; }
.schedule-table input[type=number], .schedule-table input[type=text] { width: 100%; min-width: 70px; padding: 4px 6px; font-size: 13.5px; }
.schedule-table td { vertical-align: middle; }
.schedule-table tr.is-today td { background: var(--accent-soft); }
.schedule-table tr.is-done td { color: var(--text-soft); }
.schedule-table tr.is-inactive td { opacity: .55; }
.schedule-table tr.has-error td { background: var(--bad-soft); }
.schedule-table .row-tools { white-space: nowrap; }
.schedule-table .row-tools button { padding: 2px 6px; font-size: 12px; }
.editor-toolbar { display: flex; flex-wrap: wrap; gap: 12px; align-items: flex-end; }
.editor-toolbar .field { margin: 0; min-width: 120px; }
.editor-errors { margin: 0; padding-left: 18px; }
.check-list { list-style: none; margin: 0; padding: 0; }
.check-list li { display: grid; grid-template-columns: 22px 170px 1fr; gap: 8px; padding: 7px 0; border-bottom: 1px dashed var(--border); font-size: 14px; }
.check-list li:last-child { border-bottom: 0; }
.check-list .ok { color: var(--ok); font-weight: 700; }
.check-list .bad { color: var(--bad); font-weight: 700; }
.split-actions { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 14px; }
.split-actions .drawer { margin: 0; }
.schedule-table .row-tools { display: flex; gap: 3px; }
.schedule-table .row-tools .btn { padding: 2px 6px; min-width: 0; }
.schedule-table input[type=text] { max-width: 160px; }
.schedule-table input[type=number] { max-width: 110px; }

/* ===========================================================================
   Reference components
   ---------------------------------------------------------------------------
   The patterns the reference console is built from, which this codebase had no
   equivalent for. They are ADDITIVE: every class here is new, so no template
   and no test changes meaning. Existing screens pick them up as they are
   adopted, and the demo under /demo shows each one in place.

   The anatomy worth naming, because it repeats on every screen there:
   a panel opens with a ROUND TINTED ICON beside its title, carries its content
   in the middle, and closes with a bordered footer holding one outlined
   action. That rhythm is what makes those pages look like one product.
   =========================================================================== */

/* --- icon badge ----------------------------------------------------------- */
/* The tinted circle in front of a panel title. `dark` inverts it for the one
   place per page that should be louder than the rest. */
.icon-badge {
  display: inline-grid; place-items: center; flex-shrink: 0;
  width: 44px; height: 44px;
  border-radius: 50%;
  background: var(--accent-soft);
  color: var(--accent-ink);
}
.icon-badge svg { width: 21px; height: 21px; }
.icon-badge.is-sm { width: 34px; height: 34px; }
.icon-badge.is-sm svg { width: 17px; height: 17px; }
.icon-badge.is-lg { width: 56px; height: 56px; }
.icon-badge.is-lg svg { width: 26px; height: 26px; }
.icon-badge.is-square { border-radius: var(--radius); }
.icon-badge.is-dark  { background: var(--accent); color: var(--accent-text); }
.icon-badge.is-ok    { background: var(--ok-soft);   color: var(--ok); }
.icon-badge.is-warn  { background: var(--warn-soft); color: var(--warn); }
.icon-badge.is-bad   { background: var(--bad-soft);  color: var(--bad); }
.icon-badge.is-info  { background: var(--info-soft); color: var(--info); }

/* --- widget --------------------------------------------------------------- */
/* A panel with the header/content/footer rhythm described above. Distinct from
   .card, which is the denser table container. */
.widget {
  display: flex; flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: var(--s5) var(--s6);
  height: 100%;
}
.widget-head { display: flex; align-items: center; gap: var(--s3); }
.widget-head h3 {
  font-family: var(--font-display);
  font-size: 16px; font-weight: 700; line-height: 1.25; color: var(--heading);
  margin: 0;
}
.widget-head .widget-sub { font-size: 12.5px; color: var(--text-faint); font-weight: 500; }
.widget-head-tools { margin-left: auto; display: flex; align-items: center; gap: var(--s2); }
.widget-body { flex: 1; padding-top: var(--s4); }
.widget-foot {
  display: flex; align-items: center; gap: var(--s3); flex-wrap: wrap;
  margin-top: var(--s4); padding-top: var(--s4);
  border-top: 1px solid var(--border);
}
.widget-foot .spacer { margin-left: auto; }

/* --- inset tile ----------------------------------------------------------- */
/* The flat sub-tiles inside a widget: no border, no shadow, just a wash. */
.tile {
  background: var(--surface-2);
  border-radius: var(--radius);
  padding: var(--s3) var(--s4);
}
.tile-label { display: block; font-size: 12px; font-weight: 600; color: var(--text-faint); }
.tile-value {
  display: block; margin-top: 2px;
  font-family: var(--font-display);
  font-size: 20px; font-weight: 700; line-height: 1.2; color: var(--heading);
  font-variant-numeric: tabular-nums;
}
.tile.is-ok   { background: var(--ok-soft); }
.tile.is-warn { background: var(--warn-soft); }
.tile.is-bad  { background: var(--bad-soft); }
.tile.is-brand{ background: var(--accent-wash); }

/* --- donut ---------------------------------------------------------------- */
/* Drawn with conic-gradient rather than a canvas: no library, no script, and
   it recolours with the theme because the stops are tokens. --p is the
   percentage, set inline. */
.donut {
  position: relative;
  width: 132px; height: 132px; flex-shrink: 0;
  border-radius: 50%;
  background: conic-gradient(var(--donut-color, var(--accent)) calc(var(--p, 0) * 1%), var(--surface-3) 0);
  display: grid; place-items: center;
}
.donut::after {
  content: ''; position: absolute; inset: 13px;
  border-radius: 50%; background: var(--surface);
}
.donut-label { position: relative; z-index: 1; text-align: center; line-height: 1.1; }
.donut-value { display: block; font-family: var(--font-display); font-size: 24px; font-weight: 700; color: var(--heading); }
.donut-cap   { display: block; margin-top: 3px; font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--text-faint); }
.donut.is-sm { width: 104px; height: 104px; }
.donut.is-sm::after { inset: 11px; }
.donut.is-ok   { --donut-color: var(--ok); }
.donut.is-warn { --donut-color: var(--warn); }
.donut.is-bad  { --donut-color: var(--bad); }

/* --- legend --------------------------------------------------------------- */
.legend-stack { display: flex; flex-direction: column; gap: 9px; }
.legend-row { display: flex; align-items: center; gap: var(--s2); font-size: 13.5px; }
.legend-row .dot { width: 9px; height: 9px; border-radius: 50%; background: var(--accent); flex-shrink: 0; }
.legend-row .dot.is-ok { background: var(--ok); } .legend-row .dot.is-warn { background: var(--warn); }
.legend-row .dot.is-bad { background: var(--bad); } .legend-row .dot.is-quiet { background: var(--border-strong); }
.legend-row .legend-n { margin-left: auto; font-weight: 700; color: var(--heading); font-variant-numeric: tabular-nums; }

/* --- segmented rate bar --------------------------------------------------- */
.rate-bar { display: flex; height: 12px; border-radius: 6px; overflow: hidden; background: var(--surface-3); }
.rate-bar span { display: block; height: 100%; }
.rate-bar .is-ok { background: var(--ok); } .rate-bar .is-warn { background: var(--warn); } .rate-bar .is-bad { background: var(--bad); }
.rate-bar .is-brand { background: var(--accent); }

/* --- tabs ----------------------------------------------------------------- */
.tabs { display: flex; gap: var(--s5); border-bottom: 1px solid var(--border); }
.tab {
  appearance: none; border: 0; background: none;
  padding: 10px 2px; margin-bottom: -1px;
  border-bottom: 3px solid transparent;
  font-family: var(--font); font-size: 14.5px; font-weight: 600;
  color: var(--text-soft); cursor: pointer; text-decoration: none;
}
.tab:hover { color: var(--accent-ink); text-decoration: none; }
.tab.is-active { color: var(--accent-ink); border-bottom-color: var(--accent); font-weight: 700; }

/* A pill switch, for two or three mutually exclusive views. */
.seg { display: inline-flex; padding: 3px; gap: 2px; background: var(--surface-3); border-radius: var(--radius-pill); }
.seg a, .seg button {
  appearance: none; border: 0; background: none;
  padding: 5px 14px; border-radius: var(--radius-pill);
  font-family: var(--font); font-size: 13px; font-weight: 600; color: var(--text-soft);
  cursor: pointer; text-decoration: none;
}
.seg .is-active { background: var(--surface); color: var(--accent-ink); box-shadow: var(--shadow-sm); }

/* --- switch --------------------------------------------------------------- */
.switch { display: inline-flex; align-items: center; gap: var(--s3); cursor: pointer; font-weight: 500; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .track {
  position: relative; width: 42px; height: 24px; flex-shrink: 0;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  transition: background .18s var(--ease);
}
.switch .track::before {
  content: ''; position: absolute; top: 3px; left: 3px;
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--surface); box-shadow: 0 2px 5px rgba(23,30,37,.30);
  transition: transform .18s var(--ease);
}
.switch input:checked + .track { background: var(--accent); }
.switch input:checked + .track::before { transform: translateX(18px); }
.switch input:focus-visible + .track { box-shadow: var(--ring); }
.switch input:disabled + .track { background: var(--surface-3); }
.switch input:disabled ~ .switch-label { color: var(--text-faint); }

/* --- dropzone ------------------------------------------------------------- */
.dropzone {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s3);
  padding: var(--s7) var(--s5);
  border: 2px dashed var(--accent-line); border-radius: var(--radius);
  background: var(--accent-wash);
  color: var(--text-soft); text-align: center;
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.dropzone:hover { border-color: var(--accent); background: var(--accent-soft); }
.dropzone strong { color: var(--heading); }
.dropzone .icon-badge { background: var(--surface); }

/* --- skeleton & spinner --------------------------------------------------- */
.skeleton {
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, var(--surface-3) 25%, var(--surface-2) 37%, var(--surface-3) 63%);
  background-size: 400% 100%;
  animation: skeleton 1.4s ease infinite;
}
@keyframes skeleton { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
.spinner {
  width: 22px; height: 22px; border-radius: 50%;
  border: 3px solid var(--accent-soft); border-top-color: var(--accent);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .skeleton, .spinner { animation: none; } }

/* --- initials badge ------------------------------------------------------- */
/* NOT .avatar and NOT .user-chip: both names are already taken, by the user
   menu's gradient circle and by its bordered pill. */
.initials {
  display: inline-grid; place-items: center; flex-shrink: 0;
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent-ink);
  font-family: var(--font-display); font-size: 14px; font-weight: 700; text-transform: uppercase;
}
.initials.is-sm { width: 30px; height: 30px; font-size: 12px; }

/* --- count chip ----------------------------------------------------------- */
.count-chip {
  display: inline-grid; place-items: center; min-width: 20px; height: 20px; padding: 0 6px;
  border-radius: var(--radius-pill);
  background: var(--accent); color: var(--accent-text);
  font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.count-chip.is-quiet { background: var(--surface-3); color: var(--text-soft); }

/* --- data list ------------------------------------------------------------ */
/* Label/value rows, the shape every settings and detail panel needs. */
.data-list { display: flex; flex-direction: column; }
.data-row {
  display: flex; align-items: baseline; gap: var(--s4);
  padding: 11px 0; border-bottom: 1px solid var(--border);
}
.data-row:last-child { border-bottom: 0; }
.data-row dt { flex: 0 0 210px; font-size: 13.5px; color: var(--text-soft); margin: 0; }
.data-row dd { margin: 0; flex: 1; color: var(--heading); font-weight: 500; min-width: 0; }

/* --- page grid helpers ---------------------------------------------------- */
/* Only .split is new. The column counts already exist as `.grid.grid-2` and
   friends, and redefining them HERE would land after the responsive block
   above and stop those grids collapsing on a phone. */
.split { display: grid; grid-template-columns: 1.4fr 1fr; gap: var(--s5); align-items: start; }
@media (max-width: 1100px) { .split { grid-template-columns: minmax(0, 1fr); } }

/* ===========================================================================
   Deliverability components
   ---------------------------------------------------------------------------
   The reference's deliverability screen is the densest thing in that product,
   and the four shapes it is built from are the ones this console most needs:

     .metric-head  an icon, one large number, and what the number is
     .gauge        a banded scale with a marker, for a rate that has a ceiling
     .chart        a line/area plot
     .compliance   a checklist whose rows each carry a verdict

   The charts are inline SVG with no library. Chart.js is already vendored for
   the live pages that need interaction; these are static, so a path costs
   nothing to draw, prints correctly, and recolours with the theme because the
   stroke is a token.
   =========================================================================== */

/* --- metric head ---------------------------------------------------------- */
.metric-head { display: flex; align-items: center; gap: var(--s3); }
.metric-head .metric-figure {
  font-family: var(--font-display);
  font-size: 30px; font-weight: 700; line-height: 1.05; color: var(--heading);
  font-variant-numeric: tabular-nums;
  display: block;
}
.metric-head .metric-name { font-size: 13.5px; font-weight: 600; color: var(--text-soft); }
.metric-head .metric-delta { font-size: 12.5px; font-weight: 700; }
.metric-delta.is-up   { color: var(--ok); }
.metric-delta.is-down { color: var(--bad); }

/* --- banded gauge --------------------------------------------------------- */
/* Three bands and a marker. The bands are fixed widths because the thresholds
   are fixed: what moves is the marker. */
.gauge { display: block; }
.gauge-scale { display: grid; grid-template-columns: 30% 30% 40%; font-size: 11.5px; color: var(--text-faint); }
.gauge-scale span:nth-child(2) { text-align: center; }
.gauge-scale span:nth-child(3) { text-align: right; }
.gauge-track { position: relative; display: flex; height: 12px; border-radius: 6px; overflow: hidden; margin: 6px 0; }
.gauge-track span { display: block; height: 100%; }
.gauge-track .band-ok   { width: 30%; background: var(--ok); }
.gauge-track .band-warn { width: 30%; background: var(--warn); }
.gauge-track .band-bad  { width: 40%; background: var(--bad); }
.gauge-marker { position: relative; height: 14px; }
.gauge-marker i {
  position: absolute; top: 0; transform: translateX(-50%);
  width: 0; height: 0;
  border-left: 6px solid transparent; border-right: 6px solid transparent;
  border-top: 8px solid var(--heading);
}
.gauge-note { display: grid; grid-template-columns: 30% 30% 40%; gap: 4px; font-size: 11.5px; color: var(--text-faint); }
.gauge-note span:nth-child(2) { text-align: center; }
.gauge-note span:nth-child(3) { text-align: right; }

/* --- charts --------------------------------------------------------------- */
.chart-frame { position: relative; width: 100%; }
.chart-frame svg { display: block; width: 100%; height: auto; overflow: visible; }
.chart-grid line { stroke: var(--border); stroke-width: 1; }
.chart-axis text { fill: var(--text-faint); font-size: 10px; font-family: var(--font); }
.chart-line { fill: none; stroke: var(--accent); stroke-width: 2.25; stroke-linecap: round; stroke-linejoin: round; }
.chart-line.is-ok   { stroke: var(--ok); }
.chart-line.is-bad  { stroke: var(--bad); }
.chart-line.is-warn { stroke: var(--warn); }
.chart-line.is-quiet{ stroke: var(--border-strong); stroke-dasharray: 4 4; stroke-width: 1.75; }
.chart-area { fill: var(--accent-soft); opacity: .8; }
.chart-area.is-ok  { fill: var(--ok-soft); }
.chart-area.is-bad { fill: var(--bad-soft); }
.chart-dot { fill: var(--surface); stroke: var(--accent); stroke-width: 2.25; }
.chart-bar { fill: var(--accent); }
.chart-bar.is-ok { fill: var(--ok); } .chart-bar.is-warn { fill: var(--warn); } .chart-bar.is-bad { fill: var(--bad); }
.chart-bar.is-quiet { fill: var(--surface-3); }
.chart-caption { display: flex; gap: var(--s4); flex-wrap: wrap; margin-top: var(--s3); font-size: 12.5px; color: var(--text-soft); }
.chart-caption i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; background: var(--accent); margin-right: 6px; vertical-align: -1px; }
.chart-caption i.is-ok { background: var(--ok); } .chart-caption i.is-bad { background: var(--bad); }
.chart-caption i.is-warn { background: var(--warn); } .chart-caption i.is-quiet { background: var(--border-strong); }

/* --- compliance checklist ------------------------------------------------- */
.compliance { display: flex; flex-direction: column; }
.compliance-row {
  display: flex; align-items: center; gap: var(--s3);
  padding: 12px 0; border-bottom: 1px solid var(--border);
}
.compliance-row:last-child { border-bottom: 0; }
.compliance-row .mark {
  display: inline-grid; place-items: center; flex-shrink: 0;
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--ok-soft); color: var(--ok);
  font-size: 14px; font-weight: 700;
}
.compliance-row .mark.is-warn { background: var(--warn-soft); color: var(--warn); }
.compliance-row .mark.is-bad  { background: var(--bad-soft);  color: var(--bad); }
.compliance-row .mark svg { width: 14px; height: 14px; }
.compliance-name { font-weight: 600; color: var(--heading); font-size: 14px; }
.compliance-detail { font-size: 12.5px; color: var(--text-faint); }
.compliance-row .verdict { margin-left: auto; }

/* --- live progress -------------------------------------------------------- */
/*
   One bar for every operation that takes long enough to wonder about: a CSV
   being uploaded and parsed, a campaign going out, a validation job working
   through a list.

   It is deliberately one component rather than a bar per screen. The console
   had three already — `.bar` on the campaign page, `.v-track` invented inside
   the validation view, `.rate-bar` from the delivery charts — and only one of
   them moved without a page reload, so "is it still going?" was answered
   differently depending on where you happened to be standing.

   The markup is inert without JavaScript: the fill is rendered server-side at
   whatever the last known percentage was, so a page with scripting off still
   shows where the job had got to.
*/
.progress { display: block; }

.progress-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s3); margin-bottom: 8px;
}
.progress-title { font-weight: 600; color: var(--heading); font-size: 14px; }
.progress-percent {
  font-family: var(--font-display);
  font-size: 20px; font-weight: 700; color: var(--heading);
  font-variant-numeric: tabular-nums;
}

.progress-track {
  position: relative;
  height: 10px;
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  overflow: hidden;
}
.progress-fill {
  display: block; height: 100%; width: 0;
  border-radius: inherit;
  background: var(--accent);
  transition: width .4s var(--ease);
}
.progress-fill.is-ok   { background: var(--ok); }
.progress-fill.is-warn { background: var(--warn); }
.progress-fill.is-bad  { background: var(--bad); }

/* Moving stripes while work is actually happening, and only then: a static
   striped bar beside a stalled job is a lie told slowly. */
.progress.is-running .progress-fill {
  background-image: linear-gradient(45deg,
    rgba(255,255,255,.28) 25%, transparent 25%, transparent 50%,
    rgba(255,255,255,.28) 50%, rgba(255,255,255,.28) 75%, transparent 75%, transparent);
  background-size: 28px 28px;
  animation: progress-stripes .8s linear infinite;
}
@keyframes progress-stripes { from { background-position: 0 0; } to { background-position: 28px 0; } }

/* An indeterminate phase — the file is still arriving and nobody can say how
   many rows are in it yet. */
.progress.is-indeterminate .progress-fill {
  width: 35% !important;
  animation: progress-sweep 1.1s var(--ease) infinite;
}
@keyframes progress-sweep {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(340%); }
}

.progress-meta {
  display: flex; flex-wrap: wrap; gap: var(--s2) var(--s5);
  margin-top: 8px; font-size: 12.5px; color: var(--text-soft);
}
.progress-meta b { color: var(--heading); font-variant-numeric: tabular-nums; font-weight: 700; }
.progress-note { margin-top: 6px; font-size: 12.5px; color: var(--text-faint); }

.progress.is-done .progress-fill { background: var(--ok); }
.progress.is-failed .progress-fill { background: var(--bad); }

@media (prefers-reduced-motion: reduce) {
  .progress .progress-fill { transition: none; animation: none; }
}
