/* ==========================================================================
   Falcon Mail — admin portal stylesheet
   --------------------------------------------------------------------------
   Visual DNA (see v2/DESIGN.md):
     - warm opaque beige/cream body; one translucent orange-red accent
     - angular massing, generously rounded corners on every form
     - matte shell, glossy translucent accent
     - Bellini/Rams sparseness; accent carries personality, never decoration
     - Minitel + Programma 101 lineage

   Discipline rule: the accent is ONE colour and only signals
   attention-needed. Healthy/routine states get no colour, only weight.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&display=swap');

:root {
  /* ── Inks ─────────────────────────────────────────────────────── */
  --ink:       #1B1A17;
  --ink-soft:  #5A574E;
  --ink-faint: #93907F;
  --ink-mute:  #B8B3A0;

  /* ── Paper (the shell — matte, warm, opaque) ─────────────────── */
  --paper:      #F1ECDE;
  --paper-warm: #E8E0CB;
  --paper-cool: #ECE5D2;
  --paper-edge: #D2C9AE;
  --paper-line: #A89F86;

  /* ── Accent (the glossy translucent lens) ────────────────────── */
  /* One colour. Used for: attention-needed status, primary actions,
     current-position markers, the active nav link, alert backgrounds.
     Never for decoration. */
  --accent:        #D24830;
  --accent-deep:   #B33A24;
  --accent-soft:   rgba(210, 72, 48, 0.12);
  --accent-softer: rgba(210, 72, 48, 0.06);
  --accent-glow:   0 0 28px rgba(210, 72, 48, 0.28),
                   0 0 8px  rgba(210, 72, 48, 0.18);

  /* Solid-colour equivalents of the translucent stack inside .suspicious.
     Used as the background of the sticky dismiss column so that the
     data scrolling beneath it is cleanly obscured rather than bleeding
     through.

     --sticky-thead-bg ≈ paper #F1ECDE + accent-soft  (rgba 0.12)
     --sticky-row-bg   ≈ paper + accent-soft + accent-softer (0.06) */
  --sticky-thead-bg: #EDD8C9;
  --sticky-row-bg:   #ECD1C1;

  /* ── Type ─────────────────────────────────────────────────────── */
  --font: 'JetBrains Mono', 'Courier New', monospace;

  /* ── Geometry — chunky, rounded ──────────────────────────────── */
  --radius-card:   14px;
  --radius-pill:   999px;
  --radius-input:  10px;
  --radius-button: 10px;

  --gutter: 1.6rem;
  --content-w: min(78ch, 95vw);
}

/* ==========================================================================
   Reset + base
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* Matte shell — subtle paper grain so the cream reads as material
   rather than flat #F1ECDE. Tiny, never noisy. */
body {
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 220 220'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.78' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.10  0 0 0 0 0.09  0 0 0 0 0.07  0 0 0 0.04 0'/></filter><rect width='220' height='220' filter='url(%23n)'/></svg>");
  background-size: 220px 220px;
}

a {
  color: var(--ink);
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--paper-edge);
  transition: color 80ms linear, text-decoration-color 80ms linear;
}
a:hover {
  color: var(--accent);
  text-decoration-color: var(--accent);
}

/* ==========================================================================
   Layout — page + banner + footer
   ========================================================================== */

.page {
  max-width: var(--content-w);
  margin: 0 auto;
  padding: 1.5rem var(--gutter) 4rem;
}

/* Banner — clean single rule under the title. No double-line "receipt"
   feel. Stance: planted, generous space. */
.banner {
  padding: 1.4rem 0 1.2rem;
  margin: 0 0 1.4rem;
  border-bottom: 1px solid var(--paper-line);
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
}
.banner__title {
  font-family: var(--font);
  font-weight: 700;
  font-size: 1.7rem;
  letter-spacing: 0.02em;
  margin: 0;
  line-height: 1;
  color: var(--ink);
}
.banner__title .pip {
  display: inline-block;
  width: 0.36em; height: 0.36em;
  margin: 0 0.18em 0.16em;
  border-radius: 50%;
  background: var(--accent);
  vertical-align: middle;
  box-shadow: 0 0 10px rgba(210, 72, 48, 0.55);
}
.banner__meta {
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: right;
  line-height: 1.5;
}
.banner__meta strong { color: var(--ink); font-weight: 600; }

/* Nav — simple lowercase row, accent only on the active one */
.nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  margin: 0 0 1.8rem;
  font-size: 0.78rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.nav a {
  text-decoration: none;
  padding: 0.5rem 1.15rem 0.5rem 0;
  margin-right: 0.6rem;
  color: var(--ink-soft);
  position: relative;
}
.nav a:hover { color: var(--accent); }
.nav a.active {
  color: var(--ink);
  font-weight: 700;
}
.nav a.active::after {
  content: '';
  position: absolute;
  left: 0; right: 1.15rem;
  bottom: -2px;
  height: 2px;
  background: var(--accent);
  border-radius: 1px;
  box-shadow: 0 0 12px rgba(210, 72, 48, 0.55);
}
.nav .nav__signout {
  margin-left: auto;
  padding-left: 1.5rem;
}

/* Section rule — a single label, a single line. Bellini sparseness. */
.section { margin: 2.4rem 0 1.4rem; }
.section__rule {
  display: flex;
  align-items: baseline;
  gap: 0.8rem;
  margin: 0 0 1rem;
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.section__rule::after {
  content: '';
  flex: 1;
  border-top: 1px solid var(--paper-edge);
  align-self: center;
  margin-left: 0.2rem;
}
.section__rule .num {
  color: var(--ink-faint);
  font-weight: 700;
}

/* Footer — minimal, no rule above */
.signoff {
  margin-top: 3.5rem;
  padding-top: 1rem;
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-mute);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
}

/* ==========================================================================
   Stamps / pills — only the accent variant is used (others kept compat)
   ========================================================================== */

.stamp {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  border: 1.5px solid var(--accent);
  border-radius: var(--radius-pill);
  padding: 0.2em 0.85em;
  font-size: 0.66rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-deep);
  background: var(--accent-soft);
  box-shadow: 0 0 14px rgba(210, 72, 48, 0.18);
}
.stamp.solid {
  background: var(--accent);
  color: #FFF6E8;
  box-shadow: 0 0 18px rgba(210, 72, 48, 0.35);
}
/* legacy classes — all collapse to the single accent under the new DNA */
.stamp.red, .stamp.ochre, .stamp.green { /* identical to base .stamp */ }

/* Status dots — only "needs attention" gets the accent. Healthy/quiet
   states get a quiet ink dot. No green, no amber. */
.dot {
  display: inline-block;
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--ink-faint);
  margin-right: 0.5em;
  vertical-align: 1px;
}
.dot.live { background: var(--ink); }       /* up + recent */
.dot.warn { background: var(--ink-faint); } /* up but quiet — no urgency */
.dot.dead {                                  /* silent — needs attention */
  background: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-soft);
}

/* ==========================================================================
   KPI strip — chunky tiles, generous radius
   ========================================================================== */

.kpis {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8.5rem, 1fr));
  gap: 0;
  margin: 0 0 1.8rem;
  border: 1px solid var(--paper-line);
  border-radius: var(--radius-card);
  background: var(--paper-warm);
  overflow: hidden;
}
.kpi {
  padding: 1.05rem 1.2rem 1rem;
  border-right: 1px solid var(--paper-edge);
}
.kpi:last-child { border-right: none; }
.kpi__label {
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  margin: 0 0 0.55rem;
  font-weight: 600;
}
.kpi__value {
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1;
  color: var(--ink);
  font-feature-settings: "tnum";
}
.kpi__sub {
  margin-top: 0.5rem;
  font-size: 0.68rem;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
}
.kpi.alert {
  background: var(--accent-soft);
  box-shadow: inset 0 0 24px rgba(210, 72, 48, 0.10);
}
.kpi.alert .kpi__value { color: var(--accent-deep); }

/* ==========================================================================
   Tables / log
   ========================================================================== */

.log {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.86rem;
  /* min-width: 0 prevents the table forcing its parent wider than
     the parent's content box when long content + table-layout: fixed
     come into play. */
  min-width: 0;
}
.log th, .log td {
  text-align: left;
  padding: 0.55rem 1.8rem 0.55rem 0;
  vertical-align: top;
  border-bottom: 1px solid var(--paper-edge);
}
.log th:last-child, .log td:last-child {
  padding-right: 0;
}

/* Content cell clipping. Column widths come from <colgroup><col> on each
   table; table-layout: fixed makes those widths binding so the content
   cell can't push the table past its container. */
.log--clip { table-layout: fixed; width: 100%; }
.content--clip {
  position: relative;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: help;
}

/* Custom hover-tooltip for clipped content cells. Replaces the native
   browser title=… mechanism (locked to ~1s delay). Shows after 0.2s on
   hover, vanishes immediately on un-hover. data-tip carries the full
   text; the cell text itself stays clipped behind it. */
.content--clip[data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 50;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  line-height: 1.4;
  padding: 0.55rem 0.75rem;
  border-radius: 8px;
  white-space: normal;
  max-width: 40ch;
  width: max-content;
  pointer-events: none;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.12s linear, transform 0.12s linear;
  /* default transition-delay is 0 → vanishes immediately on un-hover */
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.22);
}
.content--clip[data-tip]:hover::after {
  opacity: 1;
  transform: translateY(0);
  transition-delay: 0.2s;  /* the 0.2s "show after a moment" delay */
}

/* Generic horizontal scroll wrapper for wide tables. The inner table
   keeps its natural / colgroup-defined width; the wrap scrolls if it
   exceeds the panel. Pair with overflow:hidden on the panel itself so
   the scroll never paints past a rounded corner. */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* Tiny extra padding-bottom so the scrollbar doesn't overlap content */
  padding-bottom: 2px;
}
.log thead th {
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 700;
  border-bottom: 1px solid var(--ink);
  padding-bottom: 0.55rem;
}
.log tr:last-child td { border-bottom: 1px solid var(--ink); }
.log .ts { color: var(--ink-soft); white-space: nowrap; font-feature-settings: "tnum"; }
.log .arrow { color: var(--accent); padding: 0 0.3em; font-weight: 700; }
.log .content { color: var(--ink); }
.log .num { font-feature-settings: "tnum"; text-align: right; white-space: nowrap; }
.log tr.alert { background: var(--accent-softer); }
.log tr.alert td { border-bottom-color: var(--accent); }
.log tr.alert .content::before {
  content: '⌧';
  color: var(--accent);
  margin-right: 0.4em;
  font-weight: 700;
}

/* ==========================================================================
   Histogram — chunky bars in ink, current-hour bar in accent
   ========================================================================== */

.histo {
  display: grid;
  grid-template-columns: repeat(24, 1fr);
  align-items: end;
  gap: 3px;
  height: 70px;
  padding: 6px 8px;
  background: var(--paper-warm);
  border: 1px solid var(--paper-line);
  border-radius: var(--radius-card);
}
.histo__bar {
  background: var(--ink);
  min-height: 1px;
  border-radius: 3px 3px 0 0;
  position: relative;
}
.histo__bar.now {
  background: var(--accent);
  box-shadow: 0 0 12px rgba(210, 72, 48, 0.5);
}
.histo__bar:hover::after {
  content: attr(data-label);
  position: absolute;
  bottom: 100%; left: 50%;
  transform: translateX(-50%);
  background: var(--ink);
  color: var(--paper);
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  padding: 0.2em 0.5em;
  border-radius: 4px;
  white-space: nowrap;
  z-index: 10;
}
.histo-axis {
  display: grid;
  grid-template-columns: repeat(24, 1fr);
  gap: 3px;
  font-size: 0.6rem;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  margin-top: 4px;
  padding: 0 8px;
}
.histo-axis span { text-align: center; }
.histo-axis span:nth-child(odd) { visibility: hidden; }

/* ==========================================================================
   Latency strip — single highlighted p50 tick, neutral p95/max
   ========================================================================== */

.lag { margin: 0.4rem 0; display: grid; gap: 0.5rem; }
.lag__track {
  position: relative;
  height: 32px;
  margin-bottom: 1.15rem;          /* room for the axis labels below */
  border: 1px solid var(--paper-line);
  border-radius: var(--radius-card);
  background: var(--paper-warm);
}
.lag__grid {
  position: absolute; top: 0; bottom: 0;
  width: 1px;
  background: var(--paper-line);
  opacity: 0.55;
}
.lag__axis {
  position: absolute; left: 0; right: 0;
  top: calc(100% + 5px);
  height: 1rem;
}
.lag__axis-tick {
  position: absolute; top: 0;
  transform: translateX(-50%);
  font-size: 0.58rem;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  white-space: nowrap;
}
.lag__tick {
  position: absolute;
  top: 4px;
  width: 3px; height: 24px;
  border-radius: 2px;
  background: var(--ink);
  transform: translateX(-50%);   /* centre on the position; never spill past the rim */
}
.lag__tick.p50 {
  background: var(--accent);
  box-shadow: 0 0 8px rgba(210, 72, 48, 0.6);
}
.lag__tick.p95 { background: var(--ink-soft); height: 18px; top: 7px; }
.lag__tick.max { background: var(--ink-faint); height: 12px; top: 10px; }
/* When max is beyond the axis it clamps to the right edge; a small arrow
   marks that it is off-scale (its true value is in the legend). */
.lag__tick.max.clamped::after {
  content: '';
  position: absolute; left: 4px; top: 50%;
  transform: translateY(-50%);
  border-left: 4px solid var(--ink-faint);
  border-top: 3px solid transparent;
  border-bottom: 3px solid transparent;
}
.lag__legend {
  font-size: 0.66rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-soft);
  display: flex;
  gap: 1.4rem;
  flex-wrap: wrap;
}
.lag__legend span::before {
  content: '';
  display: inline-block;
  width: 10px; height: 10px;
  margin-right: 0.4em;
  border-radius: 2px;
  vertical-align: middle;
}
.lag__legend .p50::before { background: var(--accent); box-shadow: 0 0 6px rgba(210, 72, 48, 0.5); }
.lag__legend .p95::before { background: var(--ink-soft); }
.lag__legend .max::before { background: var(--ink-faint); }

/* ==========================================================================
   Fleet — device cards as chunky rounded blocks
   ========================================================================== */

.fleet {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18.5rem, 1fr));
  gap: 1.1rem;
}
.fleet__card {
  border: 1px solid var(--paper-line);
  border-radius: var(--radius-card);
  background: var(--paper-warm);
  padding: 1.1rem 1.15rem 0.9rem;
  position: relative;
  transition: border-color 100ms linear;
}
.fleet__card:hover {
  border-color: var(--ink-mute);
}
.fleet__name {
  font-weight: 700;
  font-size: 1.1rem;
  letter-spacing: 0.02em;
  margin: 0.4rem 0 0.1rem;
  color: var(--ink);
}
.fleet__sta {
  font-size: 0.65rem;
  letter-spacing: 0.2em;
  color: var(--ink-soft);
  text-transform: uppercase;
  margin: 0 0 0.65rem;
  display: flex;
  align-items: center;
}
.fleet__row {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  font-size: 0.78rem;
  padding: 0.3rem 0;
  border-bottom: 1px solid var(--paper-edge);
}
.fleet__row:last-child { border-bottom: none; }
.fleet__row dt {
  color: var(--ink-soft);
  letter-spacing: 0.06em;
  font-size: 0.68rem;
  text-transform: uppercase;
  font-weight: 600;
}
.fleet__row dd {
  margin: 0;
  font-feature-settings: "tnum";
  color: var(--ink);
}
.fleet__form {
  margin-top: 0.8rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--paper-edge);
  display: flex;
  gap: 0.5rem;
}
.fleet__form input {
  flex: 1;
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-input);
  background: var(--paper);
  font-family: var(--font);
  font-size: 0.78rem;
  padding: 0.45rem 0.7rem;
  color: var(--ink);
  outline: none;
  transition: border-color 100ms linear;
}
.fleet__form input:focus { border-color: var(--ink); }

/* ==========================================================================
   Pending pile — subtle accent tint, no diagonal hatch
   ========================================================================== */

.pending-pile {
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: var(--radius-card);
  padding: 1.2rem 1.2rem 0.6rem;
  box-shadow: 0 0 28px rgba(210, 72, 48, 0.12);
}
.pending-pile h3 {
  margin: 0 0 0.85rem;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent-deep);
}

/* ==========================================================================
   Conversation graph — nodes + directed edges, log-scaled opacity
   ========================================================================== */

.mesh {
  margin: 0;
  padding: 0;
  background: var(--paper-warm);
  border: 1px solid var(--paper-line);
  border-radius: var(--radius-card);
}
.mesh-graph {
  display: block;
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
  height: auto;
}
/* SVG paint attrs don't reliably resolve CSS custom properties across
   all renderers, so the colour is also set inline on each <line>. The
   rules below cover hover and the cursor only. */
.mesh-edge {
  cursor: help;
  transition: stroke-width 100ms linear;
}
.mesh-edge:hover { stroke-width: 4; }

.mesh-node circle {
  fill: var(--paper);
  stroke: var(--ink);
  stroke-width: 2;
}
.mesh-node text {
  font-family: var(--font);
  font-size: 3.3px;            /* 30% of the former 11px; names wrap one word per line */
  font-weight: 700;
  letter-spacing: 0.06em;
  fill: var(--ink);
}
.mesh__cap {
  margin: 0;
  padding: 0.4rem 1rem 0.8rem;
  font-size: 0.66rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: center;
}

/* ==========================================================================
   Buttons / forms
   ========================================================================== */

button, .btn {
  font-family: var(--font);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  background: var(--ink);
  color: var(--paper);
  border: none;
  border-radius: var(--radius-button);
  padding: 0.55rem 1.3rem;
  cursor: pointer;
  transition: all 100ms linear;
}
button:hover, .btn:hover {
  background: var(--accent);
  color: #FFF6E8;
  box-shadow: var(--accent-glow);
}
button.ghost {
  background: transparent;
  color: var(--ink);
  border: 1px solid var(--ink);
}
button.ghost:hover {
  background: var(--accent);
  color: #FFF6E8;
  border-color: var(--accent);
}

/* ==========================================================================
   Login card — small, planted, with the accent on the primary CTA
   ========================================================================== */

.login-card {
  margin: 6vh auto 0;
  max-width: 26rem;
  border: 1px solid var(--paper-line);
  border-radius: var(--radius-card);
  background: var(--paper-warm);
  padding: 2rem 2rem 2.2rem;
  position: relative;
  text-align: center;
}
.login-card__eyebrow {
  font-size: 0.66rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--accent-deep);
  margin: 0 0 0.5rem;
  font-weight: 700;
}
.login-card__title {
  font-size: 1.6rem;
  font-weight: 700;
  margin: 0 0 0.6rem;
  letter-spacing: 0.02em;
  color: var(--ink);
}
.login-card__body {
  font-size: 0.84rem;
  color: var(--ink-soft);
  margin: 0 0 1.6rem;
}
.login-card form { margin: 0; }
.login-card button {
  width: 100%;
  padding: 0.7rem;
  font-size: 0.82rem;
  background: var(--accent);
  color: #FFF6E8;
  box-shadow: var(--accent-glow);
}
.login-card button:hover {
  background: var(--accent-deep);
}
.login-card__stamp {
  position: absolute;
  top: 0.9rem;
  right: 0.9rem;
  transform: rotate(8deg);
  opacity: 0.7;
}

/* ==========================================================================
   Suspicious activity — full accent treatment (the principal alert)
   ========================================================================== */

.suspicious {
  border: 2px solid var(--accent);
  border-radius: var(--radius-card);
  background: var(--accent-soft);
  box-shadow: 0 0 32px rgba(210, 72, 48, 0.18);
  padding: 1.2rem 1.2rem 1rem;
  margin: 0 0 1.8rem;
  /* Clip children to the rounded panel border. The inner .table-scroll
     wrapper handles horizontal overflow inside this clipped region. */
  overflow: hidden;
}
.suspicious__header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.9rem;
}
.suspicious__title {
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent-deep);
  margin: 0;
}
.suspicious__title::before { content: '⌧ '; }
.suspicious__count {
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-soft);
  display: inline-flex;
  align-items: center;
  gap: 0.9rem;
}
.suspicious__dismiss-all { margin: 0; }
.suspicious__dismiss-all button {
  background: transparent;
  color: var(--accent-deep);
  border: 1px solid var(--accent);
  padding: 0.35rem 0.85rem;
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: all 100ms linear;
}
.suspicious__dismiss-all button:hover {
  background: var(--accent);
  color: #FFF6E8;
  box-shadow: 0 0 14px rgba(210, 72, 48, 0.4);
}

/* Per-row dismiss button — small ✕ pill, unobtrusive until hovered. */
.dismiss-cell form { margin: 0; }
.dismiss-btn {
  background: transparent;
  color: var(--ink-faint);
  border: none;
  padding: 0.2rem 0.45rem;
  font-size: 1rem;
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: color 100ms linear, background 100ms linear, box-shadow 100ms linear;
}
.dismiss-btn:hover {
  color: #FFF6E8;
  background: var(--accent);
  box-shadow: 0 0 10px rgba(210, 72, 48, 0.4);
}

/* ──────────────────────────────────────────────────────────────────
   Sticky dismiss column for the suspicious table.

   The dismiss action is a CONTROL, not data — so it doesn't move when
   data scrolls horizontally. The ✕ stays anchored to the right edge of
   the visible panel at every viewport width. Data columns slide left
   underneath; a fade gradient on the leading edge of the sticky cell
   tells the eye there's content scrolling beneath.

   Background colours are solid equivalents of .suspicious's translucent
   stack (paper + accent-soft for thead, plus accent-softer for tbody)
   so the stuck cell visually belongs to its row at rest, while still
   being opaque enough to obscure data scrolling past at speed.
   ────────────────────────────────────────────────────────────────── */
.suspicious .dismiss-cell {
  position: sticky;
  right: 0;
  z-index: 2;
  background: var(--sticky-row-bg);
  text-align: center;
  padding: 0.55rem 0.55rem !important;
}
.suspicious thead th:last-child {
  position: sticky;
  right: 0;
  z-index: 2;
  background: var(--sticky-thead-bg);
  padding-right: 0.55rem !important;
}
.suspicious .dismiss-cell::before,
.suspicious thead th:last-child::before {
  content: '';
  position: absolute;
  right: 100%;
  top: 0; bottom: 0;
  width: 24px;
  pointer-events: none;
}
.suspicious .dismiss-cell::before {
  background: linear-gradient(to right,
                              rgba(236, 209, 193, 0)   0%,
                              rgba(236, 209, 193, 0.85) 70%,
                              var(--sticky-row-bg)     100%);
}
.suspicious thead th:last-child::before {
  background: linear-gradient(to right,
                              rgba(237, 216, 201, 0)   0%,
                              rgba(237, 216, 201, 0.85) 70%,
                              var(--sticky-thead-bg)   100%);
}

/* ==========================================================================
   Fleet card — last OTA failure ribbon
   ========================================================================== */

.fleet__alert {
  margin: 0.5rem 0 0.2rem;
  padding: 0.55rem 0.7rem;
  background: var(--accent-soft);
  border-left: 3px solid var(--accent);
  border-radius: 6px;
  font-size: 0.72rem;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.fleet__alert .upper {
  color: var(--accent-deep);
  font-weight: 700;
  font-size: 0.62rem;
  letter-spacing: 0.22em;
}
.fleet__alert code {
  font-family: var(--font);
  font-size: 0.72rem;
  color: var(--ink);
  background: transparent;
}

/* ==========================================================================
   Composer
   ========================================================================== */

.compose {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  background: var(--paper-warm);
  border: 1px solid var(--paper-line);
  border-radius: var(--radius-card);
  padding: 1.3rem 1.4rem 1.4rem;
}
.compose__label {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 700;
}
.compose__label > span { margin-bottom: 0.1rem; }
.compose select,
.compose textarea {
  font-family: var(--font);
  font-size: 0.92rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-input);
  padding: 0.65rem 0.8rem;
  outline: none;
  transition: border-color 100ms linear, box-shadow 100ms linear;
  resize: vertical;
}
.compose select:focus,
.compose textarea:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.compose__actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.8rem;
}
.compose__actions button {
  background: var(--accent);
  color: #FFF6E8;
  box-shadow: var(--accent-glow);
  padding: 0.7rem 1.8rem;
}
.compose__actions button:hover {
  background: var(--accent-deep);
}
.compose__actions small code {
  background: rgba(0,0,0,0.04);
  padding: 0.05em 0.4em;
  border-radius: 4px;
  font-family: var(--font);
}

.compose-result {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  margin: 0 0 1rem;
  font-size: 0.86rem;
}
.compose-result--err {
  color: var(--ink);
}
.compose-result--err .stamp {
  background: transparent;
  color: var(--accent-deep);
  border-color: var(--accent);
}

/* ==========================================================================
   Utility
   ========================================================================== */

.muted { color: var(--ink-soft); }
.mono  { font-family: var(--font); font-feature-settings: "tnum"; }
.upper { text-transform: uppercase; letter-spacing: 0.15em; font-size: 0.74rem; }

.no-data { font-style: italic; color: var(--ink-faint); padding: 0.6rem 0; }

.empty {
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-card);
  padding: 1.5rem;
  text-align: center;
  color: var(--ink-faint);
  font-size: 0.82rem;
  background: rgba(255,255,255,0.18);
}

/* ==========================================================================
   Row-detail modal (HTML5 <dialog>)
   --------------------------------------------------------------------------
   Click a row in the transmission log or suspicious panel and the full
   payload opens in a modal. Visual treatment matches the rest of the
   portal: warm cream panel on a tinted ink backdrop, one accent for the
   close button and the title underline.
   ========================================================================== */

.log tr.clickable { cursor: pointer; transition: background 80ms linear; }
.log tr.clickable:hover { background: var(--paper-warm); }
.log tr.alert.clickable:hover { background: var(--accent-soft); }

dialog.row-dialog {
  border: 1px solid var(--paper-line);
  border-radius: var(--radius-card);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font);
  padding: 1.6rem 1.7rem 1.5rem;
  max-width: min(58ch, 92vw);
  width: 58ch;
  box-shadow: 0 18px 60px rgba(27, 26, 23, 0.22);
  position: relative;
}
dialog.row-dialog::backdrop {
  background: rgba(27, 26, 23, 0.32);
}
/* A short fade-in. No transform, no blur. */
dialog.row-dialog[open] {
  animation: row-dialog-fade-in 100ms ease-out;
}
@keyframes row-dialog-fade-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

dialog.row-dialog--alert {
  border: 2px solid var(--accent);
  box-shadow: 0 18px 60px rgba(210, 72, 48, 0.22);
}

.row-dialog__close-form { margin: 0; }
.row-dialog__close {
  position: absolute;
  top: 0.9rem;
  right: 0.9rem;
  background: transparent;
  color: var(--ink-faint);
  border: none;
  padding: 0.2rem 0.45rem;
  font-size: 1rem;
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: color 100ms linear, background 100ms linear, box-shadow 100ms linear;
}
.row-dialog__close:hover {
  color: #FFF6E8;
  background: var(--accent);
  box-shadow: 0 0 10px rgba(210, 72, 48, 0.4);
}

.row-dialog__title {
  margin: 0 0 1rem;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  padding-bottom: 0.7rem;
  border-bottom: 1px solid var(--paper-edge);
}
dialog.row-dialog--alert .row-dialog__title {
  color: var(--accent-deep);
  border-bottom-color: var(--accent);
}

.row-dialog__grid {
  display: grid;
  grid-template-columns: 11rem 1fr;
  gap: 0.4rem 1rem;
  margin: 0 0 1rem;
  font-size: 0.82rem;
}
.row-dialog__grid dt {
  color: var(--ink-soft);
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 700;
  padding-top: 0.18rem;
}
.row-dialog__grid dd {
  margin: 0;
  color: var(--ink);
  font-feature-settings: "tnum";
  word-break: break-all;
}
.row-dialog__grid dd .arrow {
  color: var(--accent);
  padding: 0 0.3em;
  font-weight: 700;
}

.row-dialog__section-label {
  margin: 0.4rem 0 0.4rem;
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  font-weight: 700;
}
.row-dialog__content {
  margin: 0;
  padding: 0.8rem 0.95rem;
  background: var(--paper-warm);
  border: 1px solid var(--paper-edge);
  border-radius: var(--radius-input);
  font-family: var(--font);
  font-size: 0.86rem;
  line-height: 1.55;
  color: var(--ink);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 40vh;
  overflow-y: auto;
}

.row-dialog__actions {
  margin-top: 1rem;
  display: flex;
  justify-content: flex-end;
}
.row-dialog__actions form { margin: 0; }
.row-dialog__actions button.ghost {
  background: transparent;
  color: var(--accent-deep);
  border: 1px solid var(--accent);
  padding: 0.45rem 1rem;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  border-radius: var(--radius-pill);
}
.row-dialog__actions button.ghost:hover {
  background: var(--accent);
  color: #FFF6E8;
  border-color: var(--accent);
  box-shadow: 0 0 14px rgba(210, 72, 48, 0.4);
}

/* The hover-tooltip on clipped content cells is now redundant — clicking
   the row opens the modal. Suppress the ::after tooltip when the row is
   clickable so we don't get a tooltip racing the modal. */
.log tr.clickable .content--clip::after { content: none; }

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 540px) {
  .banner__title { font-size: 1.35rem; }
  .banner__meta { text-align: left; font-size: 0.65rem; }
  .kpis { grid-template-columns: repeat(2, 1fr); }
  .kpi {
    border-bottom: 1px solid var(--paper-edge);
    border-right: 1px solid var(--paper-edge);
  }
  .kpi:nth-child(2n) { border-right: none; }
  .kpi:nth-last-child(-n+2):nth-child(2n+1),
  .kpi:nth-last-child(-n+1) { border-bottom: none; }
  .pairs { grid-template-columns: auto auto 1fr auto; font-size: 0.78rem; }
}

/* ── Transmission-log row status dot ──────────────────────────────────
   Single-accent DNA: delivered rows use muted ink, retrying rows use
   ink-faint, dead rows use the accent. The accent is the only escape
   from grey — it pulls the eye exactly where attention is warranted. */
.log .status-dot {
  text-align: center;
  font-size: 0.85em;
  user-select: none;
  color: var(--ink-faint);
}
.log .status-delivered .status-dot { color: var(--ink-soft); }
.log .status-retrying  .status-dot { color: var(--ink-faint); }
.log .status-dead      .status-dot { color: var(--accent); }
