/* uptime.ooo — themeable design system. Three switchable themes driven by a
   data-theme attribute on <html>: "phosphor" (default terminal look), "pulse"
   (live-green, friendly), "signal" (violet, premium). Components read CSS
   variables so a theme swap is a single attribute change. */

:root {
  /* fonts */
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --font-body: var(--sans);
  --font-chrome: var(--mono);   /* headings, buttons, nav, labels, inputs, th, pills */
  --font-data: var(--mono);     /* numbers / .mono / values */
  --font-display: var(--font-chrome); /* h1 display face; themes may override */

  /* Shared cross-theme hooks. Default to the dark-theme values so existing
     themes are unchanged; light themes redefine them below. */
  --card-shadow: none;          /* elevation on panels/stats/cards */
  --flash-fg: #ffc7c4;          /* flash/error text on --down-bg */

  /* ---- theme: PHOSPHOR (default) ---- */
  --bg: #05070a;
  --bg-elev: #0a0e0c;
  --bg-elev2: #0e130f;
  --border: #16241a;
  --border-bright: #243b2c;
  --text: #cdd9cd;
  --muted: #6f8574;
  --accent: #3af07a;
  --accent-dim: #26a552;
  --btn-fg: #04140d;
  --up: #3af07a;      --up-bg: rgba(58,240,122,.12);
  --down: #ff5c5c;    --down-bg: rgba(255,92,92,.12);
  --pending: #ffc24b; --pending-bg: rgba(255,194,75,.12);
  --paused: #6f8574;  --paused-bg: rgba(111,133,116,.12);
  --bar-none: #152016;

  --radius: 6px;
  --pill-radius: 4px;
  --pill-border: 1px;
  --prefix-title: "\203A\A0";   /* › */
  --prefix-section: "#\A0";
  --btn-primary: var(--accent);
  --accent-glow: 0 0 20px rgba(58,240,122,.25);
  --spark-glow: drop-shadow(0 0 3px rgba(58,240,122,.5));
  --cursor-display: inline-block;
  --page-glow: radial-gradient(60% 40% at 50% -5%, rgba(58,240,122,.05), transparent 70%);
}

:root[data-theme="pulse"] {
  --font-chrome: var(--sans);
  --bg: #0a0f0d;
  --bg-elev: #101815;
  --bg-elev2: #141b17;
  --border: #1c2b24;
  --border-bright: #26382f;
  --text: #e8f0ea;
  --muted: #8ba396;
  --accent: #20e58a;
  --accent-dim: #12b981;
  --btn-fg: #04140d;
  --up: #20e58a;      --up-bg: rgba(32,229,138,.14);
  --down: #f0554e;    --down-bg: rgba(240,85,78,.14);
  --pending: #f5b14b; --pending-bg: rgba(245,177,75,.14);
  --paused: #7d9488;  --paused-bg: rgba(125,148,136,.14);
  --bar-none: #182420;
  --radius: 11px;
  --pill-radius: 999px;
  --pill-border: 0px;
  --prefix-title: "";
  --prefix-section: "";
  --btn-primary: linear-gradient(135deg, #20e58a, #12b981);
  --accent-glow: none;
  --spark-glow: none;
  --cursor-display: none;
  --page-glow: radial-gradient(60% 40% at 50% -5%, rgba(32,229,138,.06), transparent 70%);
}

:root[data-theme="signal"] {
  --font-chrome: var(--sans);
  --bg: #0b0b12;
  --bg-elev: #141420;
  --bg-elev2: #181826;
  --border: #242436;
  --border-bright: #33334a;
  --text: #e6e6f2;
  --muted: #9a9ab8;
  --accent: #7c5cff;
  --accent-dim: #635bff;
  --btn-fg: #ffffff;
  --up: #3ddc84;      --up-bg: rgba(61,220,132,.14);
  --down: #f0554e;    --down-bg: rgba(240,85,78,.14);
  --pending: #f5b14b; --pending-bg: rgba(245,177,75,.14);
  --paused: #7d7d99;  --paused-bg: rgba(125,125,153,.14);
  --bar-none: #24243a;
  --radius: 10px;
  --pill-radius: 999px;
  --pill-border: 0px;
  --prefix-title: "";
  --prefix-section: "";
  --btn-primary: linear-gradient(135deg, #635bff, #a855f7);
  --accent-glow: none;
  --spark-glow: none;
  --cursor-display: none;
  --page-glow: radial-gradient(60% 45% at 50% -8%, rgba(124,92,255,.10), transparent 70%);
}

/* ---- theme: DAYLIGHT (light, modern SaaS) ---- */
:root[data-theme="daylight"] {
  --font-chrome: var(--sans);
  --bg: #eef1f6;
  --bg-elev: #ffffff;
  --bg-elev2: #f7f9fc;
  --border: #e3e8ef;
  --border-bright: #d5dce6;
  --text: #1a2233;
  --muted: #697386;
  --accent: #4f46e5;
  --accent-dim: #6366f1;
  --btn-fg: #ffffff;
  --up: #16a34a;      --up-bg: rgba(22,163,74,.10);
  --down: #e11d48;    --down-bg: rgba(225,29,72,.10);
  --pending: #d97706; --pending-bg: rgba(217,119,6,.12);
  --paused: #94a3b8;  --paused-bg: rgba(148,163,184,.14);
  --bar-none: #e2e8f0;
  --radius: 12px;
  --pill-radius: 999px;
  --pill-border: 0px;
  --prefix-title: "";
  --prefix-section: "";
  --btn-primary: linear-gradient(135deg, #6366f1, #4f46e5);
  --accent-glow: none;
  --spark-glow: none;
  --cursor-display: none;
  --page-glow: none;
  --card-shadow: 0 1px 2px rgba(16,24,40,.04), 0 4px 12px rgba(16,24,40,.05);
  --flash-fg: var(--down);
}

/* ---- theme: MERIDIAN (light, editorial ledger) ---- */
:root[data-theme="meridian"] {
  --font-chrome: var(--sans);
  --font-display: var(--serif);
  --bg: #f4efe6;
  --bg-elev: #fbf8f1;
  --bg-elev2: #f1ebdf;
  --border: #e3dccd;
  --border-bright: #d3c9b4;
  --text: #211d16;
  --muted: #6f6853;
  --accent: #9a3f2f;
  --accent-dim: #b6543f;
  --btn-fg: #fbf8f1;
  --up: #3f6b3a;      --up-bg: rgba(63,107,58,.12);
  --down: #a83232;    --down-bg: rgba(168,50,50,.12);
  --pending: #a8781f; --pending-bg: rgba(168,120,31,.14);
  --paused: #9a9686;  --paused-bg: rgba(154,150,134,.16);
  --bar-none: #e3dccd;
  --radius: 4px;
  --pill-radius: 2px;
  --pill-border: 1px;
  --prefix-title: "";
  --prefix-section: "";
  --btn-primary: var(--accent);
  --accent-glow: none;
  --spark-glow: none;
  --cursor-display: none;
  --page-glow: none;
  --card-shadow: none;
  --flash-fg: var(--down);
}

/* ---- theme: BREEZE (light, airy & vibrant) ---- */
:root[data-theme="breeze"] {
  --font-chrome: var(--sans);
  --bg: #f2f5fb;
  --bg-elev: #ffffff;
  --bg-elev2: #f2f5fb;
  --border: #eaeefb;
  --border-bright: #dbe3f5;
  --text: #151a2e;
  --muted: #5b6580;
  --accent: #6b4ff7;
  --accent-dim: #22b8ff;
  --btn-fg: #ffffff;
  --up: #12b76a;      --up-bg: rgba(18,183,106,.10);
  --down: #f0416a;    --down-bg: rgba(240,65,106,.10);
  --pending: #f79009; --pending-bg: rgba(247,144,9,.12);
  --paused: #98a1bd;  --paused-bg: rgba(152,161,189,.14);
  --bar-none: #eaeefb;
  --radius: 16px;
  --pill-radius: 999px;
  --pill-border: 0px;
  --prefix-title: "";
  --prefix-section: "";
  --btn-primary: linear-gradient(120deg, #6b4ff7, #22b8ff);
  --accent-glow: none;
  --spark-glow: none;
  --cursor-display: none;
  --page-glow: radial-gradient(70% 45% at 12% -8%, rgba(107,79,247,.10), transparent 60%),
               radial-gradient(60% 40% at 100% 0%, rgba(34,184,255,.10), transparent 55%);
  --card-shadow: 0 2px 8px rgba(30,41,89,.05), 0 12px 30px -12px rgba(30,41,89,.12);
  --flash-fg: var(--down);
}

/* ---- theme: BLUE BLUR (dark, hedgehog-speed blue + ring gold) ---- */
:root[data-theme="blueblur"] {
  --font-chrome: var(--sans);
  --bg: #030a1f;
  --bg-elev: #08153a;
  --bg-elev2: #0c1c4a;
  --border: #142a5e;
  --border-bright: #1e3d82;
  --text: #eaf1ff;
  --muted: #8aa2d6;
  --accent: #2f7bff;
  --accent-dim: #1e5bd6;
  --btn-fg: #041027;
  --up: #37d67a;      --up-bg: rgba(55,214,122,.14);
  --down: #ff4b3e;    --down-bg: rgba(255,75,62,.14);
  --pending: #ffd23f; --pending-bg: rgba(255,210,63,.16);
  --paused: #7d8bb0;  --paused-bg: rgba(125,139,176,.16);
  --bar-none: #12224e;
  --radius: 12px;
  --pill-radius: 999px;
  --pill-border: 0px;
  --prefix-title: "";
  --prefix-section: "";
  --btn-primary: linear-gradient(135deg, #2f7bff, #16b6ff);
  --accent-glow: 0 0 20px rgba(47,123,255,.35);
  --spark-glow: drop-shadow(0 0 3px rgba(47,123,255,.6));
  --cursor-display: none;
  --page-glow: radial-gradient(60% 45% at 15% -8%, rgba(47,123,255,.16), transparent 60%),
               radial-gradient(50% 40% at 100% 0%, rgba(255,210,63,.08), transparent 55%);
}

/* ---- theme: MUSHROOM KINGDOM (light, plumber red on sky blue, coin gold) ---- */
:root[data-theme="mushroom"] {
  --font-chrome: var(--sans);
  --bg: #e6f3ff;
  --bg-elev: #ffffff;
  --bg-elev2: #f2f8ff;
  --border: #cfe4fb;
  --border-bright: #b3d3f5;
  --text: #1f2a44;
  --muted: #5f7196;
  --accent: #e52521;
  --accent-dim: #c81c18;
  --btn-fg: #ffffff;
  --up: #43b047;      --up-bg: rgba(67,176,71,.12);
  --down: #d81f1a;    --down-bg: rgba(216,31,26,.12);
  --pending: #f0b400; --pending-bg: rgba(240,180,0,.18);
  --paused: #9aa7bd;  --paused-bg: rgba(154,167,189,.16);
  --bar-none: #d6e6f8;
  --radius: 16px;
  --pill-radius: 999px;
  --pill-border: 0px;
  --prefix-title: "";
  --prefix-section: "";
  --btn-primary: linear-gradient(135deg, #ff4b3e, #e52521);
  --accent-glow: none;
  --spark-glow: none;
  --cursor-display: none;
  --page-glow: radial-gradient(70% 50% at 50% -10%, rgba(92,148,252,.18), transparent 65%);
  --card-shadow: 0 1px 2px rgba(20,40,80,.05), 0 6px 16px -6px rgba(20,40,80,.12);
  --flash-fg: var(--down);
}

/* ---- theme: BATTLE ROYALE (dark, loot-purple to cyan neon) ---- */
:root[data-theme="battleroyale"] {
  --font-chrome: var(--sans);
  --bg: #0e0820;
  --bg-elev: #17102e;
  --bg-elev2: #1e1638;
  --border: #2b2050;
  --border-bright: #3d2f70;
  --text: #efeaff;
  --muted: #a99cd0;
  --accent: #a24bff;
  --accent-dim: #7b2fe0;
  --btn-fg: #ffffff;
  --up: #3ddc84;      --up-bg: rgba(61,220,132,.14);
  --down: #ff5470;    --down-bg: rgba(255,84,112,.14);
  --pending: #ffb547; --pending-bg: rgba(255,181,71,.14);
  --paused: #8a82ac;  --paused-bg: rgba(138,130,172,.16);
  --bar-none: #241a44;
  --radius: 12px;
  --pill-radius: 999px;
  --pill-border: 0px;
  --prefix-title: "";
  --prefix-section: "";
  --btn-primary: linear-gradient(135deg, #a24bff, #24d3ff);
  --accent-glow: 0 0 20px rgba(162,75,255,.35);
  --spark-glow: drop-shadow(0 0 3px rgba(162,75,255,.6));
  --cursor-display: none;
  --page-glow: radial-gradient(60% 45% at 12% -8%, rgba(162,75,255,.16), transparent 60%),
               radial-gradient(55% 40% at 100% 0%, rgba(36,211,255,.12), transparent 55%);
}

/* ---- theme: BLOCK STUDIO (dark graphite, studio red, blocky sharp corners) ---- */
:root[data-theme="blockstudio"] {
  --font-chrome: var(--sans);
  --bg: #16171c;
  --bg-elev: #1f2127;
  --bg-elev2: #262931;
  --border: #33363f;
  --border-bright: #454954;
  --text: #eceef2;
  --muted: #9aa0ad;
  --accent: #e93323;
  --accent-dim: #c4271a;
  --btn-fg: #ffffff;
  --up: #35c759;      --up-bg: rgba(53,199,89,.14);
  --down: #ff453a;    --down-bg: rgba(255,69,58,.14);
  --pending: #ff9f0a; --pending-bg: rgba(255,159,10,.14);
  --paused: #8e939e;  --paused-bg: rgba(142,147,158,.16);
  --bar-none: #2b2e37;
  --radius: 3px;
  --pill-radius: 2px;
  --pill-border: 1px;
  --prefix-title: "";
  --prefix-section: "";
  --btn-primary: var(--accent);
  --accent-glow: none;
  --spark-glow: none;
  --cursor-display: none;
  --page-glow: none;
}

* { box-sizing: border-box; }
html { color-scheme: dark; }
/* Light themes render with a light form-control / scrollbar scheme. */
html[data-theme="daylight"], html[data-theme="meridian"], html[data-theme="breeze"], html[data-theme="mushroom"] { color-scheme: light; }

/* Meridian leans editorial: serif numerals on the headline stat strip echo a
   printed ledger, while the small data cells stay monospaced. */
:root[data-theme="meridian"] .stat-val { font-family: var(--serif); font-weight: 600; }

/* The impersonation bar hard-codes near-white ambers tuned for a dark ground.
   On a light canvas those wash out, so restate them in darker amber ink. */
html[data-theme="daylight"] .impersonation-bar,
html[data-theme="meridian"] .impersonation-bar,
html[data-theme="breeze"] .impersonation-bar {
  background: color-mix(in srgb, #f0a020 24%, var(--bg));
  border-bottom-color: color-mix(in srgb, #b8791a 60%, transparent);
  color: #7a4d05;
}
html[data-theme="daylight"] .impersonation-tag,
html[data-theme="meridian"] .impersonation-tag,
html[data-theme="breeze"] .impersonation-tag {
  color: #8a5a08; border-color: color-mix(in srgb, #b8791a 55%, transparent);
}
html[data-theme="daylight"] .impersonation-who,
html[data-theme="meridian"] .impersonation-who,
html[data-theme="breeze"] .impersonation-who { color: #5c3d08; }
html[data-theme="daylight"] .impersonation-note,
html[data-theme="meridian"] .impersonation-note,
html[data-theme="breeze"] .impersonation-note { color: color-mix(in srgb, #7a4d05 75%, transparent); }
/* Mushroom Kingdom is a light theme too — restate the amber impersonation bar. */
html[data-theme="mushroom"] .impersonation-bar {
  background: color-mix(in srgb, #f0a020 24%, var(--bg));
  border-bottom-color: color-mix(in srgb, #b8791a 60%, transparent);
  color: #7a4d05;
}
html[data-theme="mushroom"] .impersonation-tag { color: #8a5a08; border-color: color-mix(in srgb, #b8791a 55%, transparent); }
html[data-theme="mushroom"] .impersonation-who { color: #5c3d08; }
html[data-theme="mushroom"] .impersonation-note { color: color-mix(in srgb, #7a4d05 75%, transparent); }
body {
  margin: 0;
  background: var(--page-glow), var(--bg);
  color: var(--text);
  font: 15px/1.55 var(--font-body);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
h1, h2, h3 { font-family: var(--font-chrome); font-weight: 700; letter-spacing: -.01em; }
h1 { font-size: 1.4rem; margin: 0 0 .2rem; font-family: var(--font-display); }
h2 { font-size: 1rem; }
.muted { color: var(--muted); }
.small { font-size: .8rem; }
.mono { font-family: var(--font-data); font-size: .88em; }
.strong { font-weight: 600; }
.num { text-align: right; font-family: var(--font-data); font-variant-numeric: tabular-nums; }
.center { text-align: center; }

/* topbar */
.topbar {
  display: flex; align-items: center; gap: 1.1rem;
  padding: .6rem 1.25rem;
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  border-bottom: 1px solid var(--border);
  backdrop-filter: blur(8px);
  font-family: var(--font-chrome);
}
.brand { display: inline-flex; align-items: center; gap: .5rem; color: var(--text); font-weight: 800; letter-spacing: .2px; }
.brand .dom { color: var(--accent); margin-left: .12em; }
.brand svg { display: block; flex: none; color: var(--accent); }
.cursor { display: var(--cursor-display); width: 7px; height: 1em; background: var(--accent); margin-left: 1px;
  vertical-align: -2px; animation: blink 1.1s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }
.topbar nav { display: flex; gap: .15rem; }
.topbar nav a { color: var(--muted); padding: .3rem .55rem; border-radius: 5px; font-size: .85rem; }
.topbar nav a.active { color: var(--accent); background: color-mix(in srgb, var(--accent) 15%, transparent); }
.topbar nav a:hover { color: var(--text); text-decoration: none; }
.spacer { flex: 1; }
.org { color: var(--muted); font-size: .82rem; }

/* Operator console — a deliberately distinct red-accented chrome so the operator
   always knows they are acting across every tenant, not inside one org. */
.admin-link { color: #ff6a6a !important; border: 1px solid color-mix(in srgb, #ff6a6a 45%, transparent);
  padding: .18rem .5rem; border-radius: 5px; font-size: .82rem; font-family: var(--font-chrome); }
.admin-link:hover { background: color-mix(in srgb, #ff6a6a 15%, transparent); text-decoration: none; }
.admin-topbar { border-bottom: 2px solid #ff5c5c; }
.admin-badge { font-family: var(--font-chrome); font-size: .66rem; font-weight: 800; letter-spacing: 1px;
  color: #ff6a6a; border: 1px solid #ff5c5c; border-radius: 4px; padding: .1rem .4rem; text-transform: uppercase; }
.inline { display: inline; margin: 0; }
.linkbtn { background: none; border: 0; color: var(--muted); cursor: pointer; font: inherit; font-family: var(--font-chrome); font-size: .85rem; }
.linkbtn:hover { color: var(--accent); }

/* layout */
/* Content is fluid and uses the available width. In the sidebar (console)
   layout it fills the space beside the rail edge-to-edge; in top-bar mode it
   stays centered but wide. Forms self-constrain via .form, so wide is safe. */
.container { width: 100%; max-width: 1400px; margin: 1.6rem auto; padding: 0 1.6rem; }
.nav-sidebar .container { max-width: none; margin: 1.4rem 0; padding: 0 2rem; }
.container.narrow { max-width: 400px; margin-top: 8vh; }
.page-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: 1.25rem; }
.page-head h1::before { content: var(--prefix-title); color: var(--accent); }
.section { margin: 2rem 0 .75rem; padding-top: 1rem; border-top: 1px solid var(--border); }
.section::before { content: var(--prefix-section); color: var(--accent-dim); font-family: var(--font-chrome); }
.back { font-size: .85rem; }

/* flash */
.flash {
  background: var(--down-bg); border: 1px solid var(--down);
  color: var(--flash-fg); padding: .55rem .8rem; border-radius: var(--radius); margin-bottom: 1rem;
  font-family: var(--font-chrome); font-size: .88rem;
}

/* impersonation ("view as user") banner — amber, deliberately unlike the
   green app chrome so an operator can never mistake it for a normal session. */
.impersonation-bar {
  display: flex; align-items: center; gap: .7rem; flex-wrap: wrap;
  padding: .5rem 1rem;
  background: color-mix(in srgb, #f0a020 16%, var(--bg));
  border-bottom: 1px solid color-mix(in srgb, #f0a020 55%, transparent);
  color: #ffd79a; font-family: var(--font-chrome); font-size: .85rem;
}
.impersonation-tag {
  font-weight: 700; letter-spacing: .08em; color: #ffb84d;
  border: 1px solid color-mix(in srgb, #f0a020 55%, transparent);
  padding: .1rem .4rem; border-radius: var(--radius);
}
.impersonation-who { color: #ffe9c7; font-weight: 600; }
.impersonation-note { color: color-mix(in srgb, #ffd79a 70%, transparent); }
.impersonation-bar form { margin-left: auto; }

/* buttons */
.btn {
  display: inline-block; cursor: pointer; font: inherit; font-family: var(--font-chrome); font-size: .88rem;
  padding: .5rem .9rem; border-radius: var(--radius);
  border: 1px solid var(--border-bright); background: var(--bg-elev2); color: var(--text);
  transition: .12s;
}
.btn:hover { border-color: var(--accent-dim); color: var(--accent); text-decoration: none; }
.btn.primary { background: var(--btn-primary); border: 0; color: var(--btn-fg); font-weight: 700; padding: calc(.5rem + 1px) calc(.9rem + 1px); }
.btn.primary:hover { filter: brightness(1.06); box-shadow: 0 0 18px -4px var(--accent); color: var(--btn-fg); }
.btn.danger { color: var(--down); border-color: color-mix(in srgb, var(--down) 45%, transparent); background: transparent; }
.btn.danger:hover { background: var(--down-bg); color: var(--down); }
.actions { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; }
.small-btn { padding: .3rem .6rem; font-size: .8rem; }

/* pills */
.pill {
  display: inline-block; padding: .1rem .5rem; border-radius: var(--pill-radius);
  font-family: var(--font-data); font-size: .72rem; font-weight: 600; text-transform: uppercase; letter-spacing: .5px;
  border: var(--pill-border) solid currentColor;
}
.pill.up { color: var(--up); background: var(--up-bg); }
.pill.down { color: var(--down); background: var(--down-bg); }
.pill.pending { color: var(--pending); background: var(--pending-bg); }
.pill.paused, .pill.unknown { color: var(--paused); background: var(--paused-bg); }
.pill.resolved { color: var(--up); background: var(--up-bg); }

/* tables */
table.grid { width: 100%; border-collapse: collapse; font-size: .9rem; }
table.grid th {
  text-align: left; color: var(--muted); font-weight: 500; font-size: .74rem; font-family: var(--font-chrome);
  text-transform: uppercase; letter-spacing: .5px;
  padding: .5rem .6rem; border-bottom: 1px solid var(--border);
}
table.grid th.num { text-align: right; }
table.grid td { padding: .55rem .6rem; border-bottom: 1px solid var(--border); }
table.grid tr:hover td { background: var(--bg-elev); }
.trunc { max-width: 280px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* cards */
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: .75rem; margin: 1rem 0; }
.card { background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--radius); padding: .9rem 1rem; box-shadow: var(--card-shadow); }
.card-label { color: var(--muted); font-size: .74rem; font-family: var(--font-chrome); text-transform: uppercase; letter-spacing: .5px; }
.card-value { font-family: var(--font-data); font-size: 1.6rem; font-weight: 600; margin-top: .2rem; color: var(--accent); text-shadow: var(--accent-glow); }

/* empty state */
.empty { text-align: center; padding: 3rem 1rem; background: var(--bg-elev); border: 1px dashed var(--border-bright); border-radius: var(--radius); }
.empty p { color: var(--muted); margin-bottom: 1rem; font-family: var(--font-chrome); }

/* sparkline */
.spark-wrap { background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--radius); padding: .5rem; }
.spark { width: 100%; height: 120px; display: block; }
.sparkline { stroke: var(--accent); stroke-width: 1.5; vector-effect: non-scaling-stroke; filter: var(--spark-glow); }
.seg-up { fill: var(--up); }
.seg-down { fill: var(--down); }

/* uptime history bars — the status-page daily strip, shared with the app.
   bar-partial maps to the pending/warning colour so the strip stays themed. */
.bars { display: flex; gap: 2px; height: 34px; align-items: stretch; }
.bar { flex: 1; border-radius: 1px; min-width: 2px; background: var(--bar-none); }
.bar-up { background: var(--up); }
.bar-partial { background: var(--pending); }
.bar-down { background: var(--down); }
.bar-none { background: var(--bar-none); }
.bars-legend { display: flex; justify-content: space-between; color: var(--muted);
  font-size: .72rem; margin-top: .35rem; font-family: var(--font-chrome); }
/* compact variant for dashboard rows */
.bars.compact { height: 18px; gap: 1px; width: 130px; }
.bars.compact .bar { min-width: 1px; }
td .bars.compact { margin: 0; }

/* auth */
.auth-card { text-align: left; }
.auth-title { text-align: center; margin-bottom: .25rem; font-family: var(--font-chrome); }
.stack { display: flex; flex-direction: column; gap: .9rem; margin: 1.5rem 0; }
.stack label, .form label { display: flex; flex-direction: column; gap: .3rem; font-size: .82rem; font-family: var(--font-chrome); color: var(--muted); }
input, select, textarea {
  font: inherit; font-family: var(--font-chrome); color: var(--text); background: var(--bg-elev2);
  border: 1px solid var(--border-bright); border-radius: var(--radius); padding: .55rem .65rem; width: 100%;
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 18%, transparent); }
textarea { resize: vertical; }

/* forms */
.form { display: flex; flex-direction: column; gap: 1rem; max-width: 720px; }
.form-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1rem; }
.hint { font-size: .8rem; margin: -.4rem 0 0; font-family: var(--font-chrome); }
.advanced { background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--radius); padding: .75rem 1rem; }
.advanced summary { cursor: pointer; color: var(--muted); font-family: var(--font-chrome); }
.advanced > .form-row, .advanced > label { margin-top: .9rem; }

/* checkbox lists */
fieldset.checks { border: 1px solid var(--border); border-radius: var(--radius); padding: .75rem 1rem; }
fieldset.checks legend { color: var(--muted); font-size: .82rem; font-family: var(--font-chrome); padding: 0 .4rem; }
.check { flex-direction: row !important; align-items: center; gap: .5rem; color: var(--text) !important; padding: .25rem 0; cursor: pointer; }
.check input { width: auto; }

/* theme picker cards */
.theme-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; }
.theme-card { border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.theme-card.current { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.theme-prev { padding: 1.1rem; }
.theme-prev .pv-brand { font-weight: 800; font-size: 1.05rem; }
.theme-prev .pv-swatches { display: flex; gap: 6px; margin: .8rem 0; }
.theme-prev .pv-sw { width: 26px; height: 26px; border-radius: 6px; border: 1px solid rgba(255,255,255,.08); }
.theme-prev .pv-bar { display: flex; gap: 2px; height: 16px; margin-top: .3rem; }
.theme-prev .pv-bar span { flex: 1; border-radius: 2px; }
.theme-meta { padding: .9rem 1.1rem; border-top: 1px solid var(--border); display: flex; align-items: center; gap: .6rem; }
.theme-meta .name { font-family: var(--font-chrome); font-weight: 700; text-transform: capitalize; }

/* ---- account menu (top-bar layout) ---- */
/* A pure CSS <details> dropdown so the top bar carries only primary nav; all
   settings/account links collapse behind the org name. */
.acctmenu { position: relative; }
.acctmenu > summary {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: .4rem;
  padding: .28rem .6rem; border-radius: 6px; border: 1px solid var(--border);
  color: var(--muted); font-family: var(--font-chrome);
}
.acctmenu > summary::-webkit-details-marker { display: none; }
.acctmenu > summary .org { color: inherit; }
.acctmenu > summary:hover,
.acctmenu[open] > summary { color: var(--text); border-color: var(--border-bright); }
.acctmenu .caret { font-size: .7rem; transition: transform .12s; }
.acctmenu[open] .caret { transform: rotate(180deg); }
.acctmenu-pop {
  position: absolute; right: 0; top: calc(100% + .4rem); z-index: 40;
  min-width: 190px; display: flex; flex-direction: column; gap: .05rem;
  padding: .4rem; background: var(--bg-elev); border: 1px solid var(--border-bright);
  border-radius: 8px; box-shadow: 0 8px 24px rgba(0,0,0,.4);
}
.acctmenu-pop a, .acctmenu-signout {
  display: block; text-align: left; padding: .4rem .55rem; border-radius: 5px;
  color: var(--muted); font-size: .85rem; font-family: var(--font-chrome);
}
.acctmenu-pop a:hover, .acctmenu-signout:hover { color: var(--text); background: var(--bg-elev2); text-decoration: none; }
.acctmenu-pop a.active { color: var(--accent); background: color-mix(in srgb, var(--accent) 15%, transparent); }
.acctmenu-pop a.admin-link { color: #ff6a6a !important; border: 0; padding: .4rem .55rem; }
.acctmenu-sep { height: 1px; background: var(--border); margin: .3rem 0; }
.acctmenu-signout { width: 100%; }

/* ---- top-bar nav groups ---- */
/* The primary nav outgrew one row (8 icon+label destinations). Core links stay
   inline so mid-incident paths are one click; burst-use clusters collapse
   behind labeled <details>. Popup rules are prefixed .topbar to outrank the
   generic `.topbar nav a` link styling above. */
.navgroup { position: relative; }
.navgroup > summary {
  list-style: none; cursor: pointer; display: inline-flex; align-items: center; gap: .3rem;
  color: var(--muted); padding: .3rem .55rem; border-radius: 5px;
  font-size: .85rem; font-family: var(--font-chrome);
}
.navgroup > summary::-webkit-details-marker { display: none; }
.navgroup > summary:hover { color: var(--text); }
.navgroup[open] > summary { color: var(--text); background: var(--bg-elev2); }
.navgroup > summary.active { color: var(--accent); background: color-mix(in srgb, var(--accent) 15%, transparent); }
.navgroup .caret { font-size: .65rem; transition: transform .12s; }
.navgroup[open] .caret { transform: rotate(180deg); }
.navgroup-pop {
  position: absolute; left: 0; top: calc(100% + .4rem); z-index: 45;
  min-width: 184px; display: flex; flex-direction: column; gap: .05rem; padding: .4rem;
  background: var(--bg-elev); border: 1px solid var(--border-bright); border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0,0,0,.4);
}
.topbar .navgroup-pop a { display: flex; align-items: center; white-space: nowrap;
  padding: .4rem .55rem; border-radius: 5px; color: var(--muted); font-size: .85rem; }
.topbar .navgroup-pop a:hover { color: var(--text); background: var(--bg-elev2); text-decoration: none; }
.topbar .navgroup-pop a.active { color: var(--accent); background: color-mix(in srgb, var(--accent) 15%, transparent); }

/* ---- sidebar layout ---- */
.shell { display: flex; align-items: stretch; min-height: 100vh; }
.sidebar {
  flex: none; width: 220px; box-sizing: border-box;
  display: flex; flex-direction: column; gap: 1.1rem;
  padding: 1.1rem .9rem; border-right: 1px solid var(--border);
  background: color-mix(in srgb, var(--bg) 85%, transparent);
  position: sticky; top: 0; height: 100vh;
}
.sidebar .brand { padding: 0 .3rem; }
.side-nav { display: flex; flex-direction: column; gap: .1rem; }
.side-nav a {
  display: flex; align-items: center; gap: 0;
  color: var(--muted); padding: .42rem .55rem; border-radius: 6px; font-size: .88rem; font-family: var(--font-chrome);
}
.side-nav a:hover { color: var(--text); background: var(--bg-elev); text-decoration: none; }
.side-nav a.active { color: var(--accent); background: color-mix(in srgb, var(--accent) 15%, transparent);
  box-shadow: inset 2px 0 0 var(--accent); }
.side-nav a.admin-link { color: #ff6a6a !important; border: 0; padding: .42rem .55rem; }
.side-nav a.admin-link.active { box-shadow: inset 2px 0 0 #ff6a6a; }

/* nav icons — line glyphs that inherit the link colour, shown in both layouts */
.nav-ico { width: 15px; height: 15px; flex: none; margin-right: .55rem;
  stroke: currentColor; fill: none; stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; }
.topbar nav a { display: inline-flex; align-items: center; }

/* live fleet status in the sidebar foot */
.side-status { display: flex; align-items: center; flex-wrap: wrap; gap: .45rem;
  font-family: var(--font-data); font-size: .72rem; color: var(--muted); }
.side-status .dot-live { width: 7px; height: 7px; border-radius: 50%; background: var(--up);
  box-shadow: 0 0 6px var(--up); flex: none; }
.side-status .ss-up { color: var(--up); }
.side-status .ss-down { color: var(--down); }
.side-status .ss-paused { color: var(--muted); }
.side-group { display: flex; flex-direction: column; gap: .35rem; }
.side-label {
  margin: 0; padding: 0 .55rem; color: var(--muted); font-size: .66rem;
  text-transform: uppercase; letter-spacing: 1px; font-family: var(--font-chrome); opacity: .7;
}
.side-foot { margin-top: auto; display: flex; flex-direction: column; gap: .5rem; padding-top: .8rem; border-top: 1px solid var(--border); }
.shell-body { flex: 1; min-width: 0; display: flex; flex-direction: column; }

/* ---- collapsible sidebar (desktop icon-rail, persisted per browser) ---- */
.side-top { display: flex; align-items: center; justify-content: space-between; gap: .4rem; }
.side-collapse {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0; cursor: pointer;
  background: none; border: 1px solid var(--border); border-radius: 6px; color: var(--muted);
}
.side-collapse:hover { color: var(--text); border-color: var(--border-bright); }
.side-collapse .sc-ico { display: block; transition: transform .15s ease; }
html.sidebar-collapsed .side-collapse .sc-ico { transform: rotate(180deg); }

@media (max-width: 760px) { .side-collapse { display: none; } }

@media (min-width: 761px) {
  /* Collapsed: narrow the rail to icons only. font-size:0 hides the text labels
     while the fixed-size SVG glyphs stay put — no per-link markup changes. */
  html.sidebar-collapsed .sidebar { width: 64px; padding: 1.1rem .5rem; gap: .9rem; }
  html.sidebar-collapsed .side-top { flex-direction: column; align-items: center; gap: .7rem; }
  html.sidebar-collapsed .brand { font-size: 0; gap: 0; }
  html.sidebar-collapsed .side-label { display: none; }
  html.sidebar-collapsed .side-nav a { font-size: 0; justify-content: center; padding: .5rem; gap: 0; }
  html.sidebar-collapsed .nav-ico { margin-right: 0; }
  html.sidebar-collapsed .side-foot { display: none; }
}

/* ---- responsive nav chrome ----
   Shared by the tenant app and the operator console. Lived in base.html until
   the console grew a sidebar of its own; two copies of a layout this fiddly
   drift, and the console inheriting a stale copy is invisible until someone
   opens it on a phone. */
/* Responsive nav: full chrome on desktop, a hamburger dropdown on mobile so the
   header isn't crowded — for BOTH the top-bar and sidebar layouts. Pure-CSS
   checkbox toggle (reliable in both states); scoped to the layout template. */
.hambtn { display: none; }                        /* desktop: no hamburger */
/* The toggle used to carry the `hidden` attribute, which took it out of the
   tab order — so at mobile widths, where the hamburger is the only route to
   the navigation, a keyboard could not reach the menu at all. It is hidden
   here by CSS instead: gone on desktop, where there is no hamburger to
   operate, and merely invisible on mobile, where it must still be focusable.
   Being a rendered box rather than display:none also keeps label taps working
   on browsers that treat an undisplayed control as absent. */
.nav-toggle { display: none; }
.hamb, .hamb::before, .hamb::after { display: block; width: 17px; height: 2px; background: currentColor; border-radius: 2px; }
.hamb { position: relative; }
.hamb::before { content: ""; position: absolute; left: 0; top: -6px; }
.hamb::after  { content: ""; position: absolute; left: 0; top: 6px; }
.topnav { display: flex; gap: .15rem; }           /* desktop: inline top-bar nav */
.side-body { display: contents; }                 /* desktop: wrapper vanishes → groups stay direct sidebar children */

@media (max-width: 760px) {
  .hambtn { display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
    width: 38px; height: 34px; border: 1px solid var(--border); border-radius: 7px; color: var(--muted); }
  .nav-toggle { display: block; position: absolute; width: 1px; height: 1px; margin: -1px;
    padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .nav-toggle:checked ~ .hambtn { color: var(--accent); border-color: var(--border-bright); }
  /* The focus ring belongs on the button, because that is what is on screen. */
  .nav-toggle:focus-visible ~ .hambtn { outline: 2px solid var(--accent); outline-offset: 2px; }

  /* top-bar dropdown */
  .topbar { position: relative; }
  .topbar .topnav { position: absolute; top: calc(100% + .45rem); left: 0; z-index: 50;
    flex-direction: column; align-items: stretch; width: max-content; min-width: 210px; gap: .05rem; padding: .35rem;
    order: 0; overflow: visible; display: none;
    background: var(--bg-elev); border: 1px solid var(--border-bright); border-radius: 10px;
    box-shadow: 0 12px 34px -10px rgba(0,0,0,.55); }
  #topnav-toggle:checked ~ .topnav { display: flex; }
  .topbar .topnav a { white-space: nowrap; padding: .55rem .6rem; font-size: .9rem; }

  /* sidebar → compact top bar + hamburger dropdown */
  .sidebar { position: relative; flex-wrap: nowrap; align-items: center; gap: .5rem; }
  .sidebar .hambtn { margin-left: auto; }
  .side-body { display: none; }
  #sidenav-toggle:checked ~ .side-body { display: flex; flex-direction: column; gap: .6rem;
    position: absolute; top: calc(100% + .5rem); right: .6rem; left: .6rem; z-index: 50; padding: .6rem;
    background: var(--bg-elev); border: 1px solid var(--border-bright); border-radius: 12px;
    box-shadow: 0 14px 36px -10px rgba(0,0,0,.55); }
  #sidenav-toggle:checked ~ .side-body .side-group { flex-direction: column; align-items: stretch; gap: .1rem; }
  #sidenav-toggle:checked ~ .side-body .side-nav { flex-direction: column; flex-wrap: nowrap; }
  #sidenav-toggle:checked ~ .side-body .side-label { display: block; }
  #sidenav-toggle:checked ~ .side-body .side-foot { flex-direction: row; flex-wrap: wrap; gap: .5rem; margin: .2rem 0 0; }
}

/* ---- operator console ----
   The console reads across every tenant, so it must never be mistakable for
   the tenant app at a glance. The red rail edge is that signal, in the same
   place the old top bar carried it. */
.admin-sidebar { border-right: 2px solid #ff5c5c; }
.admin-sidebar .admin-badge { align-self: flex-start; }
.admin-backlink { font-size: .85rem; }

@media (min-width: 761px) {
  /* Collapsed to the icon rail: the badge and the back-link have no icon to
     shrink to, so they go rather than wrap. The red edge still identifies the
     console, which is the part that matters. */
  html.sidebar-collapsed .admin-sidebar .admin-badge { display: none; }
}

/* ---- table density (per-user) ---- */
.density-compact table.grid { font-size: .84rem; }
.density-compact table.grid th { padding: .32rem .55rem; }
.density-compact table.grid td { padding: .3rem .55rem; }

/* ---- preferences page ---- */
.pref-block { margin-bottom: 1.75rem; }
.pref-choice { display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; margin-top: .9rem; }
.pref-card {
  position: relative; display: flex; flex-direction: column; gap: .3rem; cursor: pointer;
  padding: 1rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-elev);
}
.pref-card:hover { border-color: var(--border-bright); }
/* highlight follows the live radio state, not the server-rendered one */
.pref-card:has(input:checked) { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); }
.pref-card:has(input:focus-visible) { outline: 2px solid var(--accent-dim); outline-offset: 2px; }
.pref-card input { position: absolute; opacity: 0; width: 0; height: 0; }
.pref-card-name { font-family: var(--font-chrome); font-weight: 700; }
.pref-card-desc { color: var(--muted); font-size: .82rem; }
.pref-card-fig { display: block; margin-bottom: .3rem; }
.fig-topbar, .fig-sidebar { display: block; width: 100%; height: 34px; border: 1px solid var(--border-bright); border-radius: 4px; position: relative; overflow: hidden; }
.fig-topbar::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 9px; background: var(--accent); opacity: .55; }
.fig-sidebar::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 26px; background: var(--accent); opacity: .55; }
.pref-cols { display: flex; flex-wrap: wrap; gap: .6rem .9rem; margin-top: .8rem; }
.pref-check {
  display: inline-flex; align-items: center; gap: .45rem; cursor: pointer; font-size: .88rem;
  padding: .4rem .7rem; border: 1px solid var(--border); border-radius: var(--radius); background: var(--bg-elev);
}
.pref-check input { accent-color: var(--accent); }
.pref-actions { margin-top: 1rem; display: flex; align-items: center; gap: .8rem; }

/* unsaved-change indication: amber marker on each edited control, pill by Save */
.pref-card.changed::after {
  content: ""; position: absolute; top: .6rem; right: .6rem; width: 8px; height: 8px; border-radius: 50%;
  background: var(--pending); animation: prefpulse 1.8s infinite;
}
@keyframes prefpulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--pending) 55%, transparent); }
  70%  { box-shadow: 0 0 0 6px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
.pref-check.changed { border-color: color-mix(in srgb, var(--pending) 55%, transparent); background: var(--pending-bg); }
.pref-tz.changed select { border-color: color-mix(in srgb, var(--pending) 55%, transparent); }
#prefs-dirty { display: none; }
.prefs-form.dirty #prefs-dirty { display: inline-block; }
.prefs-form.dirty .btn.primary { box-shadow: 0 0 18px -4px var(--accent); }
@media (prefers-reduced-motion: reduce) { .pref-card.changed::after { animation: none; } }

/* ---- analytics console ---- */
/* window selector (24h / 7d / 30d) */
.win-select { display: inline-flex; gap: .2rem; border: 1px solid var(--border); border-radius: var(--radius); padding: .2rem; }
.win-select a { color: var(--muted); padding: .25rem .6rem; border-radius: 4px; font-family: var(--font-chrome); font-size: .82rem; }
.win-select a:hover { color: var(--text); text-decoration: none; }
.win-select a.active { color: var(--accent); background: color-mix(in srgb, var(--accent) 15%, transparent); }

/* live visitor panel */
.live-panel { background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem 1.1rem; margin: 1rem 0 1.5rem; }
.live-head { display: flex; align-items: baseline; gap: .6rem; flex-wrap: wrap; }
.live-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--up); align-self: center;
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--up) 70%, transparent); animation: livepulse 1.8s infinite; }
.live-dot.stale { background: var(--paused); animation: none; box-shadow: none; }
@keyframes livepulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--up) 55%, transparent); }
  70%  { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}
.live-now { font-family: var(--font-data); font-size: 2.1rem; font-weight: 700; color: var(--accent); text-shadow: var(--accent-glow); line-height: 1; }
.live-label { font-family: var(--font-chrome); font-size: .9rem; }
.live-split { margin-left: auto; font-family: var(--font-chrome); font-size: .82rem; }
.live-grid { display: grid; grid-template-columns: 1fr 1fr 2fr; gap: 1.2rem; margin-top: 1rem; }
.live-col .card-label { margin-bottom: .4rem; }
.live-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: .1rem; }
.live-list li { display: flex; justify-content: space-between; gap: .6rem; padding: .18rem 0; font-size: .84rem; font-family: var(--font-chrome); }
.ll-label { color: var(--text); min-width: 0; }
.ll-count { color: var(--accent); font-family: var(--font-data); font-variant-numeric: tabular-nums; }
.live-feed { list-style: none; margin: 0; padding: 0; max-height: 220px; overflow-y: auto; display: flex; flex-direction: column; gap: .15rem; }
.live-feed li { display: flex; align-items: baseline; gap: .5rem; padding: .22rem 0; border-bottom: 1px solid var(--border); font-size: .82rem; }
.live-feed li:last-child { border-bottom: 0; }
.feed-surface { flex: none; font-family: var(--font-chrome); font-size: .62rem; font-weight: 700; text-transform: uppercase; letter-spacing: .5px;
  padding: .05rem .35rem; border-radius: 4px; border: 1px solid currentColor; }
.feed-surface.app { color: var(--accent); background: color-mix(in srgb, var(--accent) 12%, transparent); }
.feed-surface.public { color: var(--pending); background: var(--pending-bg); }
.feed-path { font-family: var(--font-data); color: var(--text); }
.feed-meta { flex: 1; text-align: right; font-family: var(--font-chrome); font-size: .74rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* traffic trend chart */
.chart { background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem; }
.chart-bars { display: flex; align-items: flex-end; gap: 3px; height: 160px; }
.chart-col { flex: 1; height: 100%; display: flex; align-items: flex-end; min-width: 3px; }
.chart-bar { width: 100%; min-height: 2px; border-radius: 2px 2px 0 0;
  background: linear-gradient(180deg, var(--accent), var(--accent-dim)); filter: var(--spark-glow); transition: opacity .12s; }
.chart-col:hover .chart-bar { opacity: .75; }
.chart-axis { display: flex; justify-content: space-between; margin-top: .5rem; color: var(--muted);
  font-family: var(--font-chrome); font-size: .74rem; }

/* breakdown tables grid */
.breakdown-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1.1rem 1.4rem; margin-top: 1rem; }
.breakdown .card-label { margin-bottom: .35rem; }
/* Fixed layout is load-bearing, not cosmetic. These tables sit in grid columns
   that can be as narrow as 240px, and their first column holds arbitrary user
   content — a chat URL with a UUID in it, a long referrer host. Under
   table-layout:auto the table's minimum width is its content's width, so a long
   path made the table wider than its grid column and it painted straight over
   the table beside it. max-width on the cell cannot prevent that; only taking
   the column widths away from the content can. */
table.grid.mini { font-size: .82rem; table-layout: fixed; width: 100%; }
table.grid.mini th { padding: .3rem .4rem; font-size: .68rem; }
table.grid.mini td { padding: .3rem .4rem; }
/* The two numeric columns are fixed so the label column absorbs the remainder
   and its ellipsis has something to bite on. */
table.grid.mini th:nth-child(n+2), table.grid.mini td:nth-child(n+2) { width: 4rem; }
/* With fixed layout the cell width comes from the table, so the generic 280px
   cap would only reintroduce a second, conflicting opinion. */
table.grid.mini td.trunc { max-width: none; }
.bd-empty { padding: .5rem .1rem; }

/* ===== command center dashboard ===== */
.cc-banner { display: flex; align-items: center; gap: .55rem; font-family: var(--font-chrome);
  font-size: .82rem; padding: .45rem .85rem; border-radius: var(--radius); }
.cc-banner .dot { width: 9px; height: 9px; border-radius: 50%; background: currentColor; box-shadow: 0 0 9px currentColor; }
.cc-banner.ok { color: var(--up); background: var(--up-bg); border: 1px solid color-mix(in srgb, var(--up) 35%, transparent); }
.cc-banner.degraded { color: var(--pending); background: var(--pending-bg); border: 1px solid color-mix(in srgb, var(--pending) 35%, transparent); }

.cc-strip { display: grid; grid-template-columns: repeat(6, 1fr); gap: .6rem; margin: 0 0 1.1rem; }
.cc-strip .stat { background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--radius); padding: .6rem .8rem; box-shadow: var(--card-shadow); }
.cc-strip .stat.alert { border-color: color-mix(in srgb, var(--down) 40%, transparent); }
/* Stat tiles center their label and value. The .num utility defaults to
   text-align:right (for table columns); override it inside the strip so the
   percentage/latency tiles line up with the plain-count tiles. */
.cc-strip .stat { text-align: center; }
.cc-strip .num { text-align: center; }
.stat-lbl { color: var(--muted); font-family: var(--font-chrome); font-size: .66rem; text-transform: uppercase; letter-spacing: .5px; }
.stat-val { font-family: var(--font-data); font-size: 1.5rem; font-weight: 700; margin-top: .1rem; }
.stat-val.up { color: var(--up); text-shadow: var(--accent-glow); }
.stat-val.down { color: var(--down); }
.stat-val.muted { color: var(--muted); }

.cc-grid { display: grid; grid-template-columns: 1.5fr 1fr; gap: 1rem; align-items: start; }
.cc-col { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
.panel { background: var(--bg-elev); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; box-shadow: var(--card-shadow); }
.panel > h2 { font-family: var(--font-chrome); font-size: .72rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .7px; margin: 0; padding: .55rem .9rem; border-bottom: 1px solid var(--border); color: var(--muted); }
.panel > h2::before { content: none; }
.panel > h2.crit { color: var(--down); }
.panel > h2.warn { color: var(--pending); }
.panel > h2 .cnt { float: right; color: var(--muted); font-weight: 400; text-transform: none; letter-spacing: 0; }
.panel-empty { margin: 0; padding: .8rem .9rem; font-size: .85rem; }

.inc { display: flex; align-items: center; gap: .7rem; padding: .6rem .9rem; border-top: 1px solid var(--bg-elev2); }
.inc:first-of-type { border-top: 0; }
.inc.live { background: color-mix(in srgb, var(--down) 5%, transparent); }
.inc .sig { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.inc .sig.down { background: var(--down); box-shadow: 0 0 8px var(--down); }
.inc .sig.pending { background: var(--pending); }
.inc-body { flex: 1; min-width: 0; }
.inc-name { overflow-wrap: anywhere; }
.inc-meta { font-size: .76rem; color: var(--muted); }

.cc-atrisk .num.bad { color: var(--down); }
.cc-atrisk .num.warnnum { color: var(--pending); }

.region { display: flex; align-items: center; gap: .6rem; padding: .5rem .9rem; border-top: 1px solid var(--bg-elev2); }
.region:first-of-type { border-top: 0; }
.region .rdot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.region .rdot.up { background: var(--up); }
.region .rdot.down { background: var(--down); }
.region .rname { flex: 1; min-width: 0; font-family: var(--font-data); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.region .rname a { color: inherit; }
.region .rstat { flex: none; color: var(--muted); font-family: var(--font-data); font-size: .8rem; }
.region .rstat.bad { color: var(--down); }

.rt { padding: .7rem .9rem; }
.rt-spark { width: 100%; height: 40px; display: block; margin-bottom: .5rem; }
.rt-nums { display: flex; justify-content: space-between; color: var(--muted); font-family: var(--font-data); font-size: .82rem; }
.rt-nums b { color: var(--text); }
.rt-nums b.warn { color: var(--pending); }
.slow { display: flex; align-items: baseline; gap: .6rem; justify-content: space-between; padding: .35rem .9rem; border-top: 1px solid var(--bg-elev2); font-family: var(--font-data); font-size: .82rem; }
.slow a { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.slow .ms { flex: none; color: var(--pending); }

.mw { display: flex; gap: .5rem; align-items: center; padding: .5rem .9rem; border-top: 1px solid var(--bg-elev2); }
.mw:first-of-type { border-top: 0; }
.evt { display: flex; gap: .55rem; align-items: baseline; padding: .4rem .9rem; border-top: 1px solid var(--bg-elev2); font-size: .82rem; color: var(--muted); overflow-wrap: anywhere; }
.evt > span:nth-child(2) { flex: 1; min-width: 0; }
.evt .when { flex: none; }
.evt .ed { font-size: .7rem; }
.evt .ed.down { color: var(--down); } .evt .ed.up { color: var(--up); } .evt .ed.ack, .evt .ed.pending { color: var(--pending); }
.evt b.down { color: var(--down); } .evt b.up { color: var(--up); } .evt b.pending { color: var(--pending); }
.evt .when { margin-left: auto; font-family: var(--font-data); font-size: .74rem; }

.cc-statusbar { display: flex; align-items: center; gap: 1.2rem; margin: 1.2rem 0 0; padding: .5rem 0 0;
  border-top: 1px solid var(--border); color: var(--muted); font-family: var(--font-data); font-size: .74rem; }
.cc-statusbar .live { color: var(--accent); }
.cc-statusbar .spacer { flex: 1; }

/* SLA sub-strip */
.cc-substrip-label { font-family: var(--font-chrome); font-size: .68rem; text-transform: uppercase;
  letter-spacing: .7px; color: var(--muted); margin: 0 0 .45rem; }
.cc-strip.sla { grid-template-columns: repeat(4, 1fr); }

/* plan & quota meters */
.quota { padding: .7rem .9rem; display: flex; flex-direction: column; gap: .3rem; }
.q-row { display: flex; justify-content: space-between; font-size: .82rem; color: var(--muted); }
.q-row .q-num { font-family: var(--font-data); color: var(--text); }
.q-bar { height: 5px; border-radius: 3px; background: var(--bg-elev2); overflow: hidden; margin-bottom: .45rem; }
.q-bar span { display: block; height: 100%; background: var(--accent); border-radius: 3px; }

/* alert delivery */
.alertline { display: flex; flex-wrap: wrap; align-items: center; gap: .8rem; padding: .7rem .9rem;
  font-family: var(--font-data); font-size: .84rem; }
.alertline .al-ok { color: var(--up); }
.alertline .al-fail { color: var(--down); }
.alertline .al-when { color: var(--muted); margin-left: auto; font-size: .78rem; }

/* compact density tightens the dashboard */
body.density-compact .cc-strip { gap: .45rem; }
body.density-compact .cc-strip .stat { padding: .45rem .65rem; }
body.density-compact .stat-val { font-size: 1.25rem; }
body.density-compact .cc-grid { gap: .7rem; }
body.density-compact .cc-col { gap: .7rem; }

/* ---- mobile ---- */
@media (max-width: 760px) {
  .live-grid { grid-template-columns: 1fr; gap: 1rem; }
  .live-split { margin-left: 0; width: 100%; }
  .cc-grid { grid-template-columns: 1fr; }
  /* Both stat strips go 2-up. .cc-strip.sla needs an explicit rule or its
     desktop repeat(4) wins on specificity and slices off-screen. minmax(0,1fr)
     lets tracks shrink below the big numbers instead of overflowing the page. */
  .cc-strip, .cc-strip.sla { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cc-statusbar { flex-wrap: wrap; gap: .4rem 1.2rem; }
  .cc-statusbar .spacer { display: none; }
  .feed-meta { text-align: left; white-space: normal; }
  .topbar { flex-wrap: wrap; gap: .5rem .7rem; padding: .55rem .9rem; }
  .topbar .spacer { display: none; }
  .topbar nav { order: 3; width: 100%; overflow-x: auto; gap: .1rem; padding-bottom: 2px; -webkit-overflow-scrolling: touch; }
  .topbar nav a { white-space: nowrap; }
  .acctmenu { margin-left: auto; }
  /* Inside the hamburger dropdown the groups flatten into in-flow accordions
     rather than floating popups. */
  .topbar .navgroup { width: 100%; }
  .topbar .navgroup > summary { width: 100%; padding: .55rem .6rem; font-size: .9rem; }
  .topbar .navgroup-pop { position: static; min-width: 0; padding: .1rem 0 .25rem .55rem;
    background: none; border: 0; box-shadow: none; }
  .org { margin-left: auto; }
  /* Sidebar collapses to a horizontal bar so it doesn't eat a phone's width. */
  .shell { flex-direction: column; min-height: 0; }
  /* relative, never static: the desktop rail is sticky and full height, which
     this undoes, but the hamburger's dropdown is positioned against this box.
     Making it static hands that job to whatever is positioned further up, and
     "top: 100%" then measures the page rather than the header — the menu opens
     just below the fold, so the button reacts and nothing appears. */
  .sidebar { width: auto; height: auto; position: relative; flex-direction: row; flex-wrap: wrap;
    align-items: center; gap: .5rem .8rem; border-right: 0; border-bottom: 1px solid var(--border); }
  .sidebar .side-group { flex-direction: row; align-items: center; gap: .4rem; }
  .sidebar .side-nav { flex-direction: row; flex-wrap: wrap; }
  .side-label { display: none; }
  .side-foot { margin: 0 0 0 auto; flex-direction: row; align-items: center; border-top: 0; padding-top: 0; }
  .pref-choice { grid-template-columns: 1fr; }
  .container { margin: 1.2rem auto; padding: 0 1rem; }
  .page-head { flex-direction: column; align-items: stretch; gap: .7rem; }
  .form-row { grid-template-columns: 1fr; }
  table.grid { font-size: .82rem; display: block; overflow-x: auto; white-space: nowrap; -webkit-overflow-scrolling: touch; }
  table.grid th, table.grid td { padding: .5rem .5rem; }
  .trunc { max-width: 160px; }
  .cards { grid-template-columns: 1fr 1fr; }
}

/* ---- shared site footer (RoamGO attribution) ---- */
.sitefooter { margin-top: auto; border-top: 1px solid var(--border);
  padding: 1.25rem 1.25rem calc(1.25rem + env(safe-area-inset-bottom));
  color: var(--muted); font-size: .82rem; }
.sitefooter-inner { max-width: 1000px; margin: 0 auto; display: flex; flex-wrap: wrap;
  align-items: center; justify-content: space-between; gap: .5rem 1rem; }
.sitefooter a { color: var(--muted); text-decoration: none; transition: color .12s; }
.sitefooter a:hover { color: var(--accent); }
.sitefooter .dom { color: var(--accent); }
.sitefooter-links { display: flex; gap: 1.1rem; }
@media (max-width: 640px) {
  .sitefooter-inner { justify-content: center; text-align: center; }
}

/* ===== notification channels ===== */
.ch-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(310px, 1fr)); gap: .75rem; margin-bottom: 1.6rem; }
.ch-card { display: flex; align-items: flex-start; gap: .85rem; background: var(--bg-elev);
  border: 1px solid var(--border); border-radius: var(--radius); padding: .9rem 1rem; box-shadow: var(--card-shadow); transition: border-color .12s; }
.ch-card:hover { border-color: var(--border-bright); }
.ch-ico { flex: none; width: 40px; height: 40px; border-radius: 10px; display: grid; place-items: center;
  color: var(--accent); background: color-mix(in srgb, currentColor 15%, transparent); }
.ch-ico svg { width: 19px; height: 19px; }
.ch-main { flex: 1; min-width: 0; }
.ch-top { display: flex; align-items: center; gap: .5rem; }
.ch-name { font-weight: 600; font-family: var(--font-chrome); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ch-meta { display: flex; align-items: center; gap: .4rem; margin-top: .18rem; font-size: .82rem; color: var(--muted); min-width: 0; }
.ch-type { text-transform: capitalize; flex: none; }
.ch-dot { opacity: .5; flex: none; }
.ch-dest { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.ch-added { font-size: .72rem; margin-top: .4rem; font-family: var(--font-data); }
.ch-del { flex: none; margin: 0; }

/* small square icon button (delete) */
.iconbtn { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; cursor: pointer;
  border: 1px solid var(--border-bright); background: var(--bg-elev2); border-radius: var(--radius); color: var(--muted); transition: .12s; }
.iconbtn svg { width: 16px; height: 16px; }
.iconbtn.danger:hover { color: var(--down); border-color: color-mix(in srgb, var(--down) 45%, transparent); background: var(--down-bg); }

/* per-type icon accent; the tile tint derives from currentColor */
.ch-ico.t-email    { color: #3b82f6; }
.ch-ico.t-webhook  { color: #8b5cf6; }
.ch-ico.t-slack    { color: #d6336c; }
.ch-ico.t-discord  { color: #5865f2; }
.ch-ico.t-teams    { color: #4f46e5; }
.ch-ico.t-telegram { color: #0ea5e9; }
.ch-ico.t-pagerduty{ color: #0ea472; }
.ch-ico.t-opsgenie { color: #e0870b; }
.ch-ico.t-sms      { color: #10b981; }

.ch-empty { text-align: center; padding: 2.6rem 1rem; background: var(--bg-elev);
  border: 1px dashed var(--border-bright); border-radius: var(--radius); margin-bottom: 1.6rem; }
.ch-empty svg { width: 34px; height: 34px; color: var(--muted); opacity: .7; }
.ch-empty p { margin: .5rem 0 0; }

.ch-add { max-width: 760px; }
.ch-add-body { padding: 1rem 1.1rem 1.2rem; }
.ch-add-body .flash { margin-bottom: 1rem; }
.ch-form { gap: .9rem; }
.chf { margin: 0; }
.chf[hidden] { display: none; }
.chf-hint { display: block; font-size: .78rem; margin-top: .2rem; }

@media (max-width: 760px) {
  .ch-list { grid-template-columns: 1fr; }
}

/* ===== status pages ===== */
/* min(360px,100%) + minmax(0,…) keep long nowrap URLs from widening the track
   past the viewport; the anchors ellipsize instead. */
.sp-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(360px, 100%), 1fr)); gap: .75rem; margin-bottom: 1.6rem; }
.sp-card { display: flex; flex-direction: column; gap: .7rem; background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius); padding: .95rem 1rem; box-shadow: var(--card-shadow); transition: border-color .12s; }
.sp-card:hover { border-color: var(--border-bright); }
.sp-head { display: flex; align-items: center; gap: .75rem; }
.sp-ico { flex: none; width: 40px; height: 40px; border-radius: 10px; display: grid; place-items: center;
  color: var(--accent); background: color-mix(in srgb, currentColor 14%, transparent); }
.sp-ico svg { width: 20px; height: 20px; }
.sp-title-wrap { flex: 1; min-width: 0; }
.sp-title { display: block; font-weight: 600; font-family: var(--font-chrome);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-badges { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .18rem; }
.sp-badge { display: inline-flex; align-items: center; gap: .28rem; padding: .05rem .4rem;
  color: var(--muted); border: 1px solid var(--border-bright); border-radius: var(--pill-radius);
  font-family: var(--font-chrome); font-size: .64rem; font-weight: 600; text-transform: uppercase; letter-spacing: .5px; }
.sp-badge svg { width: 10px; height: 10px; }
.sp-desc { margin: 0; font-size: .84rem; }
.sp-rows { display: flex; flex-direction: column; gap: .32rem; }
.sp-row { display: flex; align-items: center; gap: .5rem; font-size: .84rem; min-width: 0; }
.sp-row-label { flex: none; width: 80px; color: var(--muted); font-family: var(--font-chrome);
  font-size: .68rem; text-transform: uppercase; letter-spacing: .5px; }
.sp-row a, .sp-row .mono { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sp-row .pill { flex: none; }
.sp-foot { display: flex; flex-wrap: wrap; align-items: center; gap: .45rem; margin-top: auto;
  padding-top: .7rem; border-top: 1px solid var(--border); }
.sp-count { color: var(--muted); font-family: var(--font-data); font-size: .76rem; white-space: nowrap; }
.sp-foot .spacer { flex: 1; }

/* ===== maintenance windows ===== */
.mwin-list { display: flex; flex-direction: column; gap: .6rem; margin-bottom: 1.6rem; max-width: 860px; }
.mwin-card { display: flex; align-items: flex-start; gap: .85rem; background: var(--bg-elev); border: 1px solid var(--border);
  border-radius: var(--radius); padding: .85rem 1rem; box-shadow: var(--card-shadow); transition: border-color .12s; }
.mwin-card:hover { border-color: var(--border-bright); }
/* a window that is muting alerts right now reads amber, like a live warning */
.mwin-card.live { border-color: color-mix(in srgb, var(--pending) 45%, transparent);
  background: color-mix(in srgb, var(--pending) 4%, var(--bg-elev)); }
.mwin-ico { flex: none; width: 40px; height: 40px; border-radius: 10px; display: grid; place-items: center;
  color: var(--muted); background: color-mix(in srgb, currentColor 12%, transparent); }
.mwin-card.live .mwin-ico { color: var(--pending); }
.mwin-ico svg { width: 19px; height: 19px; }
.mwin-main { flex: 1; min-width: 0; }
.mwin-top { display: flex; align-items: center; gap: .5rem; }
.mwin-scope { font-weight: 600; font-family: var(--font-chrome); }
.mwin-when { margin-top: .18rem; font-size: .82rem; }
.mwin-meta { margin-top: .3rem; font-size: .78rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mwin-del { flex: none; margin: 0; }
.mwin-add { max-width: 760px; }
.mwin-add-body { padding: 1rem 1.1rem 1.2rem; }
.mwin-add-body .flash { margin-bottom: 1rem; }

@media (max-width: 760px) {
  .sp-list { grid-template-columns: minmax(0, 1fr); }
}

/* ===== team / members ===== */
/* success variant of .flash (invite created) — the danger red of the base
   .flash is wrong for a confirmation. */
.flash.ok-flash { background: var(--up-bg); border-color: color-mix(in srgb, var(--up) 55%, transparent); color: var(--up); }

.tm-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr));
  gap: .75rem; margin-bottom: 1.6rem; }
.tm-card { display: flex; align-items: center; gap: .85rem; background: var(--bg-elev);
  border: 1px solid var(--border); border-radius: var(--radius); padding: .85rem 1rem;
  box-shadow: var(--card-shadow); transition: border-color .12s; }
.tm-card:hover { border-color: var(--border-bright); }

/* avatar: initials tile with a presence dot pinned to its corner */
.tm-av { position: relative; flex: none; width: 42px; height: 42px; border-radius: 50%;
  display: grid; place-items: center; font-family: var(--font-chrome); font-weight: 700;
  font-size: .88rem; letter-spacing: .02em; color: var(--accent);
  background: color-mix(in srgb, currentColor 16%, transparent); }
.tm-av svg { width: 18px; height: 18px; }
.tm-av.pending { color: var(--muted); }
.tm-dot { position: absolute; right: -1px; bottom: -1px; width: 12px; height: 12px; border-radius: 50%;
  /* ring in the card's own background so the dot reads as an overlay, not a hole */
  box-shadow: 0 0 0 2.5px var(--bg-elev); }
.tm-dot.p-online { background: var(--up); }
.tm-dot.p-away { background: var(--pending); }
.tm-dot.p-offline { background: var(--paused); opacity: .75; }

.tm-main { flex: 1; min-width: 0; }
.tm-top { display: flex; align-items: center; gap: .45rem; min-width: 0; }
.tm-email { font-weight: 600; font-family: var(--font-chrome); font-size: .92rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tm-you { flex: none; font-family: var(--font-chrome); font-size: .62rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em; color: var(--accent); padding: .08rem .4rem;
  border-radius: var(--pill-radius); background: color-mix(in srgb, var(--accent) 15%, transparent); }
.tm-seen { margin-top: .2rem; font-size: .8rem; font-family: var(--font-data); color: var(--muted); }
.tm-seen.s-online { color: var(--up); }
.tm-seen.s-away { color: var(--pending); }
.tm-seen.s-pending { color: var(--muted); }
.tm-joined { margin-top: .22rem; font-size: .74rem; text-transform: capitalize; }
.tm-online-count { color: var(--up); }

.tm-actions { flex: none; display: flex; align-items: center; gap: .4rem; }
.tm-role { width: auto; padding: .3rem .45rem; font-size: .78rem; }

/* one-shot invite link banner */
.tm-invitelink { background: var(--bg-elev); border: 1px solid var(--border-bright);
  border-radius: var(--radius); padding: .8rem .95rem; margin-bottom: 1.2rem; }
.tm-invitelink-head { font-family: var(--font-chrome); font-size: .8rem; margin-bottom: .35rem; }
.tm-invitelink-url { word-break: break-all; font-size: .82rem; color: var(--accent); }

.tm-add { max-width: 760px; }
.tm-add-body { padding: 1rem 1.1rem 1.2rem; }

/* 8 stable avatar tints, chosen per-email in the handler */
.tm-av.a0 { color: #3b82f6; } .tm-av.a1 { color: #8b5cf6; }
.tm-av.a2 { color: #ec4899; } .tm-av.a3 { color: #f59e0b; }
.tm-av.a4 { color: #10b981; } .tm-av.a5 { color: #06b6d4; }
.tm-av.a6 { color: #ef4444; } .tm-av.a7 { color: #84cc16; }

@media (max-width: 760px) {
  .tm-list { grid-template-columns: minmax(0, 1fr); }
}
/* On a phone the role select + delete button crowd the address down to a few
   characters. Drop the controls onto their own row so the email gets the card. */
@media (max-width: 620px) {
  .tm-card { flex-wrap: wrap; }
  .tm-actions { flex-basis: 100%; justify-content: flex-end; margin-top: .15rem; }
  .tm-role { flex: 1; max-width: 11rem; }
}

/* ---- channels: add-form + safety panel side by side ---- */
.ch-bottom { display: grid; grid-template-columns: minmax(0, 760px) minmax(280px, 1fr); gap: 1rem; align-items: start; }
.ch-bottom .ch-add { max-width: none; }
.ch-side { display: flex; flex-direction: column; gap: 1rem; }
.ch-side-body { padding: .85rem 1rem 1rem; }
.ch-side-body p { margin: 0 0 .35rem; }
.panel.ch-alarm { border-color: color-mix(in srgb, var(--down) 45%, transparent); }
.ch-lead { font-family: var(--font-chrome); font-weight: 700; font-size: .95rem; }
.ch-lead.down { color: var(--down); }
.ch-lead.up { color: var(--up); }
.ch-silent { list-style: none; margin: .6rem 0 .5rem; padding: 0; display: flex; flex-direction: column; gap: .15rem; }
.ch-silent li { font-family: var(--font-data); font-size: .84rem; padding: .18rem 0; border-bottom: 1px solid var(--bg-elev2); }
.ch-silent li:last-child { border-bottom: 0; }

/* delivery health numbers */
.ch-health { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; margin-bottom: .6rem; }
.chh { background: var(--bg-elev2); border-radius: var(--radius); padding: .55rem .7rem; }
.chh-n { font-family: var(--font-data); font-size: 1.5rem; font-weight: 700; line-height: 1.1; }
.chh-n.up { color: var(--up); } .chh-n.down { color: var(--down); } .chh-n.muted { color: var(--muted); }
.chh-l { color: var(--muted); font-size: .72rem; text-transform: uppercase; letter-spacing: .5px; font-family: var(--font-chrome); }
.ch-badch { display: flex; flex-direction: column; gap: .1rem; padding: .5rem 0; border-top: 1px solid var(--bg-elev2); }

/* per-card usage + delivery footer */
.ch-foot { display: flex; align-items: center; gap: .4rem; margin-top: .4rem; font-size: .76rem;
  color: var(--muted); font-family: var(--font-data); flex-wrap: wrap; }
.ch-use.warn { color: var(--pending); }
.ch-ok { color: var(--up); }
.ch-fail { color: var(--down); font-weight: 600; }
.ch-foot .ch-added { margin-left: auto; }

@media (max-width: 980px) {
  .ch-bottom { grid-template-columns: 1fr; }
}

/* ---- Team-chat message bubbles ------------------------------------------
   Shared by the floating chat widget (chat_widget.html) and the pop-out chat
   window (chat_popout.html); emitted by /static/chat-widget.js. The full
   /app/chat page keeps its own tc-* styles. */
.cw-msg { max-width: 82%; padding: .45rem .65rem; border-radius: 10px; background: var(--bg-elev2); border: 1px solid var(--border); font-size: .88rem; overflow-wrap: break-word; }
.cw-msg.mine { align-self: flex-end; border-color: color-mix(in srgb, var(--accent) 45%, transparent); }
.cw-msg .cw-meta { display: block; font-family: var(--font-data); font-size: .68rem; color: var(--muted); margin-bottom: .15rem; }
.cw-msg audio { display: block; max-width: 230px; height: 34px; margin-top: .15rem; }
.cw-sys { align-self: center; color: var(--muted); font-family: var(--font-data); font-size: .72rem; text-align: center; }
.cw-empty { color: var(--muted); font-size: .83rem; }
/* One zone hint per chat surface (page, widget, pop-out, war room): every
   bubble carries a time, so the zone is named once above the composer rather
   than stamped on each message — same decision as the mobile apps. */
.cw-tz { align-self: center; text-align: center; color: var(--muted); font-family: var(--font-data); font-size: .66rem; margin: 0; padding: .1rem 0 .3rem; }
/* Docked chat = split pane: html.cw-dock-* pads the body by the panel width
   (--cw-w) so page content shifts aside instead of being overlaid. Applied
   pre-paint by chat_widget.html's restore script; these rules live here (in
   the <head> stylesheet) so the class lands before body's first layout. No
   transition on purpose: the panel snaps, so the page shift snaps with it —
   and an animated restore would slide 0→w on every live-page auto-reload. */
html.cw-dock-r body { padding-right: var(--cw-w, 340px); }
html.cw-dock-l body { padding-left: var(--cw-w, 340px); }
#uo-cw-ptt, #pp-ptt { user-select: none; -webkit-user-select: none; touch-action: none; }
#uo-cw-ptt.rec, #pp-ptt.rec { background: var(--down); color: #fff; animation: cwpulse 1s infinite; }
@keyframes cwpulse { 50% { filter: brightness(1.25); } }
