/* ==========================================================================
   Gov PAM — Operations Console
   Western Cape Provincial Parliament

   Light is the primary theme and is designed first, from first principles.
   The dark theme is a separate set of values, not an inversion.

   Palette rationale
   -----------------
   The WCPP seal is gold on black with the national primaries inside it. Gold
   sits near hue 45. Its harmonic complement is near hue 225 — a deep navy —
   which is why gold-and-navy is the settled pairing of legislatures and
   universities. The accent is therefore a dark, low-chroma navy: it reads as
   institutional, it never competes with the seal for attention, and it is dark
   enough (11.1:1 on white) to carry body-weight text and solid buttons.

   Saturated colour is reserved for status meaning. Nothing decorative is
   coloured. Every status is additionally carried by a glyph and a word, so the
   interface survives monochrome printing and colour-vision deficiency
   (WCAG 1.4.1).
   ========================================================================== */

:root {
  /* --- Surfaces: cool, near-neutral, four steps of depth ------------------ */
  --canvas:        #F7F8FA;
  --surface:       #FFFFFF;
  --surface-sunk:  #F1F3F6;
  --surface-deep:  #E7EBF0;
  --line:          #D6DCE4;
  --line-soft:     #E7EAEF;

  /* --- Ink: measured against #FFFFFF / #F7F8FA --------------------------- */
  --ink:           #14181F;  /* 17.8:1 on white · 16.7:1 on canvas */
  --ink-2:         #4C5560;  /*  7.6:1 on white ·  7.2:1 on canvas */
  --ink-3:         #5E6875;  /*  5.6:1 on white ·  5.2:1 on canvas */

  /* --- Accent: institutional navy ---------------------------------------- */
  --accent:        #1D3C6D;  /* 11.1:1 on white */
  --accent-strong: #142C52;
  --accent-soft:   #E9EEF6;
  --accent-line:   #C2D0E4;
  --on-accent:     #FFFFFF;

  /* --- Status: colour + glyph + word -------------------------------------
     These carry operational meaning, which is the only kind an operator can
     act on. Healthy needs no attention; warning needs attention today;
     critical needs attention now; expired and denied are terminal outcomes;
     pending is waiting on a person. */
  --pos:           #1A6B45;  /* 6.6:1 on white  — healthy, active, allowed */
  --pos-soft:      #E3F0E9;
  --pos-line:      #B4D8C5;

  --warn:          #8A5A0B;  /* 5.9:1 on white  — warning, expiring, due */
  --warn-soft:     #F7EEDC;
  --warn-line:     #E3CB9B;

  --info:          #4A3D7A;  /* 9.5:1 on white  — pending, awaiting a person */
  --info-soft:     #EDEAF6;
  --info-line:     #CBC3E4;

  --mute:          #5E6875;  /* 5.6:1 on white  — inactive, closed, unknown */
  --mute-soft:     #EEF0F4;
  --mute-line:     #CFD5DE;

  --neg:           #9B2C22;  /* 7.6:1 on white  — critical, denied, expired */
  --neg-soft:      #F8E7E5;
  --neg-line:      #E8BCB6;

  --focus:         #1D3C6D;
  --focus-ring:    #FFFFFF;

  --mono: ui-monospace, "SF Mono", SFMono-Regular, "Cascadia Mono", "Roboto Mono", Menlo, Consolas, monospace;
  --ui: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  --rail: 268px;
  --pad: 20px;
  --r: 3px;
  --shadow: 0 1px 2px rgba(20, 24, 31, .05), 0 1px 1px rgba(20, 24, 31, .04);
}

:root[data-theme="dark"] {
  --canvas:        #101419;
  --surface:       #171C23;
  --surface-sunk:  #1D232B;
  --surface-deep:  #232A33;
  --line:          #2E3742;
  --line-soft:     #242B34;

  --ink:           #E8ECF1;
  --ink-2:         #A3ADBA;
  --ink-3:         #8B95A2;

  --accent:        #7FA6DC;
  --accent-strong: #9CBCE9;
  --accent-soft:   #1B2739;
  --accent-line:   #2C3E58;
  --on-accent:     #0B1220;

  --pos:           #62BC8E;
  --pos-soft:      #14261D;
  --pos-line:      #24523A;

  --warn:          #D9A64F;
  --warn-soft:     #2A2113;
  --warn-line:     #57431E;

  --info:          #A697E0;
  --info-soft:     #211E33;
  --info-line:     #3B3459;

  --mute:          #8B95A2;
  --mute-soft:     #1E242C;
  --mute-line:     #333C47;

  --neg:           #E38279;
  --neg-soft:      #2C1A18;
  --neg-line:      #5A2E28;

  --focus:         #9CBCE9;
  --focus-ring:    #0B1220;

  --shadow: 0 1px 2px rgba(0, 0, 0, .4);
}

/* ==========================================================================
   Base
   ========================================================================== */

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

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

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--ui);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -.01em; text-wrap: balance; }
p { margin: 0; }
img { max-width: 100%; height: auto; }

/* A focus indicator that survives every background in the console:
   dark ring, light halo. Never removed, never colour-only. */
:where(a, button, input, select, [tabindex]):focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  box-shadow: 0 0 0 4px var(--focus-ring);
  border-radius: 2px;
}

.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }

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

.skip-link {
  position: absolute; left: 8px; top: -60px; z-index: 60;
  background: var(--accent); color: var(--on-accent);
  padding: 10px 16px; border-radius: var(--r); font-weight: 600;
  text-decoration: none; transition: top .12s ease;
}
.skip-link:focus { top: 8px; }

/* ==========================================================================
   Masthead
   ========================================================================== */

.masthead {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  padding: 10px var(--pad);
  position: sticky; top: 0; z-index: 40;
}

/* The seal is a government legislature's emblem. It sits on its own white
   plate with clear space equal to the height of the seal's own margin, is
   never recoloured, and is never placed on a tint. In dark mode the plate
   stays white so the artwork is unaltered. */
.logo-plate {
  background: #FFFFFF;
  border: 1px solid var(--line-soft);
  border-radius: var(--r);
  padding: 7px 12px;
  display: flex; align-items: center;
  flex: none;
}
:root[data-theme="dark"] .logo-plate { border-color: #2E3742; }
.logo-plate img { display: block; height: 34px; width: auto; }

.masthead-id { min-width: 0; }
.masthead-title {
  font-size: 14px; font-weight: 700; letter-spacing: -.005em; color: var(--ink);
  white-space: nowrap;
}
.masthead-sub {
  font-family: var(--mono); font-size: 10.5px; text-transform: uppercase;
  letter-spacing: .1em; color: var(--ink-3); margin-top: 1px;
}

.masthead-spacer { flex: 1 1 auto; min-width: 0; }

/* Connection state. The console polls, so the operator has to be able to tell
   "nothing is happening" from "the console stopped being told what is
   happening". The state is a word and a glyph, never the colour alone. */
.link-state {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--mute);
  border-radius: var(--r);
  padding: 5px 11px;
  background: var(--surface-sunk);
  color: var(--ink);
  font-size: 12px;
  white-space: nowrap;
}
.link-glyph { font-family: var(--mono); font-weight: 700; color: var(--mute); }
.link-word { font-weight: 600; }
.link-time { font-family: var(--mono); font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.link-state--live     { border-left-color: var(--pos);  background: var(--pos-soft);  border-color: var(--pos-line); }
.link-state--live .link-glyph { color: var(--pos); }
.link-state--slow     { border-left-color: var(--warn); background: var(--warn-soft); border-color: var(--warn-line); }
.link-state--slow .link-glyph { color: var(--warn); }
.link-state--offline  { border-left-color: var(--neg);  background: var(--neg-soft);  border-color: var(--neg-line); }
.link-state--offline .link-glyph { color: var(--neg); }
.link-state--paused .link-glyph { color: var(--ink-3); }

.masthead-actions { display: flex; align-items: center; gap: 8px; }

.whoami {
  display: flex; flex-direction: column; gap: 1px; text-align: right;
  padding-right: 10px; border-right: 1px solid var(--line-soft);
}
.whoami-name { font-size: 12px; font-weight: 600; }
.whoami-role { font-family: var(--mono); font-size: 10px; color: var(--ink-3); text-transform: uppercase; letter-spacing: .08em; }

.menu-btn { display: none; }

/* ==========================================================================
   Shell + navigation
   ========================================================================== */

.shell { display: grid; grid-template-columns: var(--rail) minmax(0, 1fr); }

.rail {
  background: var(--surface);
  border-right: 1px solid var(--line);
  display: flex; flex-direction: column;
  position: sticky; top: 55px;
  height: calc(100vh - 55px);
  overflow-y: auto;
}

.nav { padding: 6px 0 14px; flex: 1; }

/* Group headers name an operational concern — the thing the operator came to
   do — rather than a section of a document. */
.nav-group { margin-top: 12px; }
.nav-group:first-child { margin-top: 4px; }
.nav-group-title {
  display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap;
  padding: 8px var(--pad) 6px;
  border-top: 1px solid var(--line-soft);
}
.nav-group:first-child .nav-group-title { border-top: 0; }
.nav-group-name {
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .11em; color: var(--ink-2);
}

/* Three columns: glyph, label, count. The glyph is a scanning aid down a long
 * menu; the count is the number of things on that screen that need attention,
 * so the menu itself tells the operator where to go next. */
.nav-item {
  display: grid;
  grid-template-columns: 16px 1fr auto;
  align-items: center;
  gap: 4px 9px;
  width: 100%;
  padding: 7px var(--pad);
  background: none; border: 0;
  border-left: 3px solid transparent;
  color: var(--ink-2);
  font: inherit; font-size: 13px;
  text-align: left; cursor: pointer;
}
.nav-item__icon {
  font-size: 12px;
  line-height: 1;
  text-align: center;
  color: var(--ink-3);
}
.nav-item[aria-current="page"] .nav-item__icon { color: var(--accent); }
.nav-item:hover { background: var(--surface-sunk); color: var(--ink); }
.nav-item[aria-current="page"] {
  border-left-color: var(--accent);
  background: var(--accent-soft);
  color: var(--ink);
  font-weight: 600;
}
.nav-label { min-width: 0; }

/* Attention count. Present only when the screen has something outstanding, so
   an empty menu genuinely means an empty queue. The number is accompanied by a
   visually hidden word in the markup, so a screen reader hears
   "Approvals, 3 need attention" rather than "Approvals 3". */
.nav-count {
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--warn);
  background: var(--warn-soft);
  border: 1px solid var(--warn-line);
  border-radius: 8px;
  padding: 0 6px;
  min-width: 20px; text-align: center;
  white-space: nowrap;
  justify-self: end;
}
.nav-count--neg { color: var(--neg); background: var(--neg-soft); border-color: var(--neg-line); }

.rail-foot {
  border-top: 1px solid var(--line-soft);
  padding: 12px var(--pad);
  display: flex; flex-direction: column; gap: 8px;
}
.rail-foot-label {
  font-family: var(--mono); font-size: 10px; text-transform: uppercase;
  letter-spacing: .11em; color: var(--ink-3);
}
.rail-foot-value { font-size: 12px; color: var(--ink); font-weight: 600; }

/* ==========================================================================
   Views
   ========================================================================== */

.main { min-width: 0; }
.view { padding: var(--pad); max-width: 1680px; }

/* --- View header: title, one line of orientation, and the controls that act
       on the whole screen. ------------------------------------------------- */
.module-head {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  padding: 16px 18px;
  margin-bottom: 16px;
}
.module-titleline {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-bottom: 6px;
}
.module-title { font-size: 20px; margin-right: auto; }

.module-desc { color: var(--ink-2); max-width: 84ch; font-size: 13.5px; }

.module-meta {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: center;
  margin-top: 12px; padding-top: 12px;
  border-top: 1px solid var(--line-soft);
}

/* ==========================================================================
   Panels, metrics, tables
   ========================================================================== */

.grid { display: grid; gap: 14px; }
.c2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.c3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.c4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.mt { margin-top: 14px; }

.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  overflow: hidden;
  min-width: 0;
}
.panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 9px 14px;
  background: var(--surface-sunk);
  border-bottom: 1px solid var(--line-soft);
  flex-wrap: wrap;
}
.panel-title {
  font-family: var(--mono); font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .1em; color: var(--ink-2);
}
.panel-body { padding: 14px; }
.panel-body.flush { padding: 0; }

/* A strip of counters inside one bordered plate, divided rather than spaced.
   Dense by intent: these are reference figures, not the headline. */
.statbar {
  display: grid; grid-template-columns: repeat(var(--cols, 4), minmax(0, 1fr));
  background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r);
  box-shadow: var(--shadow); overflow: hidden;
}
.statbar > .metric { border-right: 1px solid var(--line-soft); }
.statbar > .metric:last-child { border-right: 0; }

.metric { padding: 14px; min-width: 0; }
.metric-value {
  font-family: var(--mono); font-size: 27px; font-weight: 600;
  font-variant-numeric: tabular-nums; line-height: 1.05; letter-spacing: -.02em;
}
.metric-value .unit { font-size: 15px; font-weight: 500; color: var(--ink-2); }
.metric-label { font-size: 12.5px; color: var(--ink-2); margin-top: 5px; }
.metric-foot { font-size: 11.5px; color: var(--ink-3); margin-top: 7px; font-family: var(--mono); }
.metric-value.is-pos { color: var(--pos); }
.metric-value.is-warn { color: var(--warn); }
.metric-value.is-neg { color: var(--neg); }
.metric-value.is-info { color: var(--info); }
.metric-value.is-mute { color: var(--mute); }

.tablewrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; font-size: 13px; }
caption { text-align: left; padding: 8px 14px; color: var(--ink-2); font-size: 12px; }
thead th {
  text-align: left;
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .09em; color: var(--ink-3);
  padding: 9px 14px; border-bottom: 1px solid var(--line);
  white-space: nowrap; background: var(--surface);
}
tbody td { padding: 9px 14px; border-bottom: 1px solid var(--line-soft); vertical-align: top; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--surface-sunk); }
th.r, td.r { text-align: right; }
.primary-cell { font-weight: 600; color: var(--ink); }
.sub { color: var(--ink-2); font-size: 12px; }
.hash { font-family: var(--mono); font-size: 11px; color: var(--ink-3); word-break: break-all; }

tr.sev-neg  td:first-child { box-shadow: inset 3px 0 0 var(--neg); }
tr.sev-warn td:first-child { box-shadow: inset 3px 0 0 var(--warn); }

.kv { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 7px 16px; font-size: 13px; margin: 0; }
.kv dt {
  font-family: var(--mono); font-size: 10px; text-transform: uppercase;
  letter-spacing: .09em; color: var(--ink-3); padding-top: 2px; white-space: nowrap;
}
.kv dd { margin: 0; min-width: 0; }

/* ==========================================================================
   Status vocabulary — operational

   Every state here is one an operator can act on: healthy, active, warning,
   critical, expiring, expired, pending, denied, inactive, unknown.

   Colour is never the only channel (WCAG 1.4.1). Each state carries a distinct
   glyph, the word itself, and a distinct border treatment, so the interface
   survives greyscale printing and colour-vision deficiency. The glyphs are
   drawn from different shape families — round, triangular, square, crossed —
   rather than being the same shape in four colours.
   ========================================================================== */

.st {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  padding: 2px 8px; border-radius: 2px; white-space: nowrap;
  border: 1px solid;
}
.st-glyph { font-size: 11px; line-height: 1; }

.st--healthy  { background: var(--pos-soft);  color: var(--pos);  border-color: var(--pos-line);  border-style: solid; }
.st--active   { background: var(--pos-soft);  color: var(--pos);  border-color: var(--pos);       border-style: solid; }
.st--warning  { background: var(--warn-soft); color: var(--warn); border-color: var(--warn-line); border-style: solid; }
.st--expiring { background: var(--warn-soft); color: var(--warn); border-color: var(--warn-line); border-style: dashed; }
.st--critical { background: var(--neg-soft);  color: var(--neg);  border-color: var(--neg);       border-style: solid; }
.st--denied   { background: var(--neg-soft);  color: var(--neg);  border-color: var(--neg-line);  border-style: dotted; }
.st--expired  { background: var(--neg-soft);  color: var(--neg);  border-color: var(--neg-line);  border-style: dashed; }
.st--pending  { background: var(--info-soft); color: var(--info); border-color: var(--info-line); border-style: dashed; }
.st--inactive { background: var(--mute-soft); color: var(--mute); border-color: var(--mute-line); border-style: solid; }
.st--unknown  { background: var(--mute-soft); color: var(--mute); border-color: var(--mute-line); border-style: dotted; }

/* Generic chips for non-status meaning */
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--mono); font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .06em;
  padding: 2px 7px; border-radius: 2px; white-space: nowrap;
  border: 1px solid var(--line);
  background: var(--surface-sunk); color: var(--ink-2);
}
.chip--accent { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-line); }
.chip--pos    { background: var(--pos-soft);  color: var(--pos);  border-color: var(--pos-line); }
.chip--warn   { background: var(--warn-soft); color: var(--warn); border-color: var(--warn-line); }
.chip--neg    { background: var(--neg-soft);  color: var(--neg);  border-color: var(--neg-line); }
.chip--info   { background: var(--info-soft); color: var(--info); border-color: var(--info-line); }

.dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }

/* ==========================================================================
   Controls
   ========================================================================== */

.btn {
  font: inherit; font-size: 12.5px; font-weight: 600;
  padding: 6px 12px; border-radius: var(--r); cursor: pointer;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  white-space: nowrap;
}
.btn:hover { border-color: var(--ink-3); background: var(--surface-sunk); }
.btn--primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn--primary:hover { background: var(--accent-strong); border-color: var(--accent-strong); }
.btn--danger { border-color: var(--neg-line); color: var(--neg); background: var(--neg-soft); }
.btn--danger:hover { background: var(--neg-soft); border-color: var(--neg); }
.btn[disabled] { opacity: .55; cursor: not-allowed; }
.btn[disabled]:hover { border-color: var(--line); background: var(--surface); }
.actions { display: flex; gap: 7px; flex-wrap: wrap; }

.field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.field label {
  font-family: var(--mono); font-size: 10px; text-transform: uppercase;
  letter-spacing: .09em; color: var(--ink-3); font-weight: 700;
}
.field select, .field input {
  font: inherit; font-size: 13px;
  padding: 6px 9px; border-radius: var(--r);
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  min-width: 0;
}

/* Segmented filter buttons carry a glyph + count, never colour alone. */
.segbar { display: flex; gap: 6px; flex-wrap: wrap; }
.seg {
  font: inherit; font-size: 12px; font-weight: 600;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: var(--r); cursor: pointer;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-2);
}
.seg:hover { background: var(--surface-sunk); color: var(--ink); }
.seg[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.seg[aria-pressed="true"] .seg-count { color: var(--on-accent); }
.seg-glyph { font-family: var(--mono); }
.seg-count { font-family: var(--mono); font-size: 11px; color: var(--ink-3); font-variant-numeric: tabular-nums; }

.legend { display: flex; gap: 16px; flex-wrap: wrap; font-size: 12px; color: var(--ink-2); }
.legend > span { display: inline-flex; align-items: center; gap: 6px; }

/* ==========================================================================
   Attention queue — what the Overview leads with

   A card appears only when its count is non-zero, so an empty board is a
   truthful statement that nothing is outstanding rather than a wall of
   zeroes. The whole card is the control, because a number an operator cannot
   click is a number they have to go and find somewhere else.
   ========================================================================== */

.att-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }

.att {
  display: flex; flex-direction: column; gap: 5px; text-align: left;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--mute);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  padding: 13px 14px;
  font: inherit; color: var(--ink);
  cursor: pointer; min-width: 0;
}
.att:hover { border-color: var(--ink-3); background: var(--surface-sunk); }
.att-top { display: flex; align-items: baseline; gap: 9px; }
.att-count {
  font-family: var(--mono); font-size: 26px; font-weight: 700;
  font-variant-numeric: tabular-nums; line-height: 1;
}
.att-glyph { font-family: var(--mono); font-size: 13px; font-weight: 700; margin-left: auto; }
.att-label { font-size: 13px; font-weight: 600; }
.att-detail { font-size: 12px; color: var(--ink-2); }
.att--critical { border-left-color: var(--neg); }
.att--critical .att-count, .att--critical .att-glyph { color: var(--neg); }
.att--warning  { border-left-color: var(--warn); }
.att--warning .att-count, .att--warning .att-glyph { color: var(--warn); }
.att--pending  { border-left-color: var(--info); }
.att--pending .att-count, .att--pending .att-glyph { color: var(--info); }

/* The all-clear. Named checks are listed so "nothing to do" is evidence that
   the checks ran, not an absence of information. */
.allclear {
  display: flex; gap: 13px; align-items: flex-start;
  background: var(--pos-soft); border: 1px solid var(--pos-line);
  border-left: 3px solid var(--pos); border-radius: var(--r);
  padding: 14px 16px;
}
.allclear-glyph { color: var(--pos); font-family: var(--mono); font-size: 17px; font-weight: 700; line-height: 1.2; }
.allclear-title { font-weight: 700; margin-bottom: 3px; }
.allclear-list {
  margin: 7px 0 0; padding: 0; list-style: none;
  display: flex; flex-wrap: wrap; gap: 5px 16px;
  font-size: 12px; color: var(--ink-2);
}
.allclear-list li { display: inline-flex; align-items: center; gap: 6px; }
.allclear-list .tick { color: var(--pos); font-family: var(--mono); font-weight: 700; }

/* ==========================================================================
   Toolbars, sortable tables, empty states
   ========================================================================== */

.toolbar {
  display: flex; gap: 10px; flex-wrap: wrap; align-items: flex-end;
  padding: 11px 14px;
  border-bottom: 1px solid var(--line-soft);
  background: var(--surface);
}
.toolbar .field { flex: 0 1 auto; }
.toolbar .field--grow { flex: 1 1 220px; }
.toolbar-spacer { flex: 1 1 auto; }
.toolbar .actions { align-self: flex-end; }

.tablecount {
  font-family: var(--mono); font-size: 11px; color: var(--ink-3);
  padding: 8px 14px; border-top: 1px solid var(--line-soft);
  font-variant-numeric: tabular-nums;
}

/* A sortable header is a button, so it is reachable by keyboard and announces
   its own state through aria-sort. The arrow is a text glyph rather than a
   background image so it survives greyscale and high-contrast modes. */
th.sortable { padding: 0; }
th.sortable > button {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 9px 14px; background: none; border: 0; cursor: pointer;
  font: inherit; font-family: var(--mono); font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .09em; color: var(--ink-3);
  text-align: left; white-space: nowrap;
}
th.sortable > button:hover { color: var(--ink); background: var(--surface-sunk); }
th.sortable.r > button { justify-content: flex-end; }
.sort-arrow { font-size: 9px; color: var(--ink-3); }
th[aria-sort="ascending"] > button, th[aria-sort="descending"] > button { color: var(--accent); }
th[aria-sort="ascending"] .sort-arrow, th[aria-sort="descending"] .sort-arrow { color: var(--accent); }

.empty {
  padding: 30px 20px; text-align: center; color: var(--ink-2);
}
.empty-glyph { font-family: var(--mono); font-size: 20px; color: var(--ink-3); }
.empty-title { font-weight: 600; color: var(--ink); margin-top: 8px; }
.empty-body { font-size: 12.5px; margin-top: 4px; max-width: 62ch; margin-inline: auto; }
.empty .actions { justify-content: center; margin-top: 12px; }

/* ==========================================================================
   Loading and failure

   The skeleton occupies the same box the data will, so nothing moves when the
   response lands. Panel chrome is drawn immediately and only the cells are
   replaced, which keeps every heading in its final position from the first
   frame.
   ========================================================================== */

.slot { display: block; margin-bottom: 14px; }
.slot:last-child { margin-bottom: 0; }

.sk {
  display: block; height: 11px; border-radius: 2px;
  background: var(--surface-deep);
  animation: sk-pulse 1.4s ease-in-out infinite;
}
.sk--wide { width: 100%; }
.sk--60 { width: 60%; }
.sk--40 { width: 40%; }
.sk--tall { height: 26px; width: 52%; }
@keyframes sk-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
@media (prefers-reduced-motion: reduce) { .sk { animation: none; opacity: .8; } }

.sk-row td { padding: 9px 14px; border-bottom: 1px solid var(--line-soft); }
.sk-metric { padding: 14px; }
.sk-metric .sk--tall { margin-bottom: 9px; }

/* One failed endpoint fails one panel. The rest of the screen keeps working,
   which is the whole point: a privileged access console that goes dark because
   one service is slow is useless during the incident it exists for. */
.panel--failed { border-color: var(--neg-line); }
.panel--failed .panel-head { background: var(--neg-soft); border-bottom-color: var(--neg-line); }
.panel--failed .panel-title { color: var(--neg); }

.errbox { padding: 14px; display: flex; flex-direction: column; gap: 11px; }
.errbox-msg { font-size: 13px; color: var(--ink); max-width: 80ch; }
.errbox-meta {
  font-family: var(--mono); font-size: 11px; color: var(--ink-2);
  display: flex; flex-wrap: wrap; gap: 4px 18px;
}
.errbox-meta b { color: var(--ink-3); font-weight: 700; }

/* Stale strip: the panel is showing the last good answer, and says so with the
   age of it. Silently showing old data on a privileged access screen is worse
   than showing an error. */
.stale {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap;
  padding: 7px 14px; font-size: 12px;
  background: var(--warn-soft);
  border-bottom: 1px solid var(--warn-line);
  color: var(--ink);
}
.stale-glyph { color: var(--warn); font-family: var(--mono); font-weight: 700; }
.stale .btn { padding: 3px 9px; font-size: 11.5px; }

/* ==========================================================================
   Detail disclosure
   ========================================================================== */

details.detail { border-top: 1px solid var(--line-soft); }
details.detail:first-child { border-top: 0; }
details.detail > summary {
  cursor: pointer; padding: 8px 14px; font-size: 12.5px; color: var(--accent);
  font-weight: 600; list-style: none;
}
details.detail > summary::-webkit-details-marker { display: none; }
details.detail > summary::before { content: "▸ "; font-family: var(--mono); }
details.detail[open] > summary::before { content: "▾ "; }
details.detail > summary:hover { background: var(--surface-sunk); }
details.detail .detail-body { padding: 0 14px 13px; }

pre.code {
  margin: 0; padding: 11px 13px; overflow-x: auto;
  background: var(--surface-sunk); border: 1px solid var(--line-soft);
  border-radius: var(--r);
  font-family: var(--mono); font-size: 11.5px; line-height: 1.5; color: var(--ink);
  white-space: pre; tab-size: 4;
}
code.inline {
  font-family: var(--mono); font-size: 11.5px;
  background: var(--surface-sunk); border: 1px solid var(--line-soft);
  border-radius: 2px; padding: 0 4px; word-break: break-all;
}

.taglist { display: flex; flex-wrap: wrap; gap: 4px; }

/* ==========================================================================
   Integrations
   ========================================================================== */

.int-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.int-card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r); padding: 14px; box-shadow: var(--shadow);
  display: flex; flex-direction: column; gap: 9px; min-width: 0;
}
.int-card--primary { border-color: var(--accent-line); border-top: 3px solid var(--accent); }
.int-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.int-name { font-size: 14px; font-weight: 600; }
.int-kind {
  font-family: var(--mono); font-size: 10px; color: var(--ink-3);
  text-transform: uppercase; letter-spacing: .08em; white-space: nowrap;
}
.int-desc { font-size: 12.5px; color: var(--ink-2); flex: 1; }
.int-foot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding-top: 9px; border-top: 1px solid var(--line-soft); flex-wrap: wrap;
}
.int-state { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; }
.int-state-glyph { font-family: var(--mono); font-weight: 700; }
.int-state--no .int-state-glyph { color: var(--mute); }
.int-state--no { color: var(--ink-2); }

/* ==========================================================================
   Licensing
   ========================================================================== */

.meter {
  height: 26px; border-radius: var(--r); overflow: hidden;
  border: 1px solid var(--line); background: var(--surface-sunk);
  display: flex;
}
.meter-used {
  background: var(--accent); color: var(--on-accent);
  display: flex; align-items: center; padding: 0 9px;
  font-family: var(--mono); font-size: 11px; font-weight: 700; white-space: nowrap;
}
.meter-free {
  flex: 1; display: flex; align-items: center; padding: 0 9px;
  font-family: var(--mono); font-size: 11px; color: var(--ink-2); white-space: nowrap;
}
.meter-sm { height: 8px; }

/* ==========================================================================
   Audit chain visualiser
   ========================================================================== */

.chain { display: flex; gap: 3px; flex-wrap: wrap; }
.chain i { width: 13px; height: 26px; border-radius: 1px; background: var(--pos); display: block; }
.chain i.pending {
  background: var(--surface-sunk);
  border: 1px dashed var(--accent);
}
.chain i.broken { background: var(--neg); }

.spark { display: flex; align-items: flex-end; gap: 3px; min-height: 128px; }
.spark i { flex: 1; background: var(--accent-soft); border: 1px solid var(--accent-line); border-bottom: 0; border-radius: 1px 1px 0 0; min-height: 3px; }
.spark i.hi { background: var(--accent); border-color: var(--accent); }

.bar { height: 5px; background: var(--surface-deep); border-radius: 2px; overflow: hidden; margin-top: 5px; min-width: 78px; }
.bar > i { display: block; height: 100%; background: var(--accent); }
.bar > i.warn { background: var(--warn); }
.bar > i.neg { background: var(--neg); }

/* ==========================================================================
   Notes and callouts
   ========================================================================== */

.note {
  font-size: 12.5px; color: var(--ink-2);
  border-left: 2px solid var(--line);
  padding-left: 12px; margin-top: 13px; max-width: 92ch;
}

.callout {
  display: flex; gap: 12px; align-items: flex-start; flex-wrap: wrap;
  border: 1px solid; border-left-width: 3px; border-radius: var(--r);
  padding: 12px 14px; margin-bottom: 14px; font-size: 13px;
}
.callout-title { font-weight: 700; white-space: nowrap; }
.callout-body { flex: 1; min-width: 240px; color: var(--ink); max-width: 92ch; }
.callout--neg  { background: var(--neg-soft);  border-color: var(--neg-line);  border-left-color: var(--neg); }
.callout--neg .callout-title { color: var(--neg); }
.callout--warn { background: var(--warn-soft); border-color: var(--warn-line); border-left-color: var(--warn); }
.callout--warn .callout-title { color: var(--warn); }
.callout--info { background: var(--accent-soft); border-color: var(--accent-line); border-left-color: var(--accent); }
.callout--info .callout-title { color: var(--accent); }
.callout--mute { background: var(--mute-soft); border-color: var(--mute-line); border-left-color: var(--mute); }
.callout--mute .callout-title { color: var(--ink-2); }

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

@media (max-width: 1240px) {
  .c4, .att-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .int-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 1020px) {
  .c3, .c2 { grid-template-columns: 1fr; }
  .link-state { order: 5; }
}

/* The scrim is a small-screen affordance only. It must be display:none at
   desktop and not merely invisible: .shell is a two-column grid, and an
   unstyled button between the rail and the main column consumes column two,
   dropping the whole console into a 268px strip under the navigation. It is
   declared here, outside the media query, so the grid never sees it. */
.rail-scrim { display: none; }

@media (max-width: 900px) {
  .shell { grid-template-columns: minmax(0, 1fr); }
  .menu-btn { display: inline-flex; }
  .rail {
    position: fixed; inset: 55px auto 0 0;
    width: min(300px, 88vw); height: calc(100vh - 55px);
    z-index: 45; box-shadow: 4px 0 22px rgba(20, 24, 31, .14);
    transform: translateX(-102%); transition: transform .16s ease;
  }
  .rail.is-open { transform: translateX(0); }
  .rail-scrim {
    position: fixed; inset: 55px 0 0 0; z-index: 44;
    background: rgba(20, 24, 31, .34); border: 0; padding: 0; margin: 0;
    display: none; cursor: pointer;
  }
  .rail-scrim.is-open { display: block; }
  .whoami { display: none; }
}

@media (max-width: 720px) {
  .c4, .int-grid, .att-grid { grid-template-columns: minmax(0, 1fr); }
  .masthead { gap: 10px; padding: 8px 14px; }
  .masthead-title { font-size: 13px; white-space: normal; }
  :root { --pad: 14px; }
  .kv { grid-template-columns: minmax(0, 1fr); gap: 2px 0; }
  .kv dd { margin-bottom: 8px; }
  .toolbar .field, .toolbar .field--grow { flex: 1 1 100%; }
}

@media (max-width: 420px) {
  .logo-plate img { height: 26px; }
  .masthead-id { display: none; }
  .link-state { flex: 1 1 100%; justify-content: center; }
}

/* 360px is the narrowest device the estate is expected to carry. Nothing may
   overflow horizontally at that width: a table scrolls inside its own wrapper
   and the page body never does. */
@media (max-width: 380px) {
  :root { --pad: 11px; }
  .metric-value { font-size: 23px; }
  .att-count { font-size: 22px; }
  .btn { padding: 6px 9px; }
}

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

@media print {
  .rail, .masthead-actions, .menu-btn, .toolbar, .actions { display: none !important; }
  .shell { grid-template-columns: 1fr; }
  .panel, .module-head, .att { break-inside: avoid; box-shadow: none; }
  .sk { animation: none; }
}
