/* J-LAB platform: amber-rose accent + platform pieces on top of node.css /
   desk.css / console.css. Only add what the shared ARGUS system and the
   console layer do not already provide. */
:root {
  --accent:      oklch(0.76 0.15 48);
  --accent-2:    oklch(0.83 0.11 55);
  --accent-h:    48;
  --accent-glow: oklch(0.76 0.15 48 / 0.28);
  --accent-soft: oklch(0.76 0.15 48 / 0.12);
}

/* Provenance accent (STD-010.4). A screen whose tool belongs to the other lab
   wears that lab's colour, so you can see you are using a C-LAB tool without
   leaving your desk. The chrome around it stays J-LAB: only these five
   variables change, and they always change together. Values are copied from
   the tool's own canonical stylesheet, 02-c-lab/exif-check/styles.css. */
[data-view="exif"] {
  --accent:      oklch(0.83 0.13 178);
  --accent-2:    oklch(0.91 0.08 178);
  --accent-h:    178;
  --accent-glow: oklch(0.83 0.13 178 / 0.28);
  --accent-soft: oklch(0.83 0.13 178 / 0.12);
}

/* Sign in with a passkey, under the password form. The password stays first
   because the passkey is an additional door, never the only one. */
#pk-block { margin-top: 14px; }
#pk-block[hidden] { display: none; }
.pk-or {
  display: flex; align-items: center; gap: 10px; margin: 0 0 12px;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--dim);
}
.pk-or::before, .pk-or::after { content: ""; height: 1px; background: var(--line-soft); flex: 1; }
#pk-signin { width: 100%; justify-content: center; }
.pk-msg { margin: 10px 0 0; font-size: 0.8rem; color: oklch(0.7 0.16 25); }
.pk-msg[hidden] { display: none; }

/* Passkeys the journalist has enrolled, listed where they can remove one. */
.pk-list { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }
.pk-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px;
}
.pk-row .pk-name { color: var(--fg); font-size: 0.86rem; }
.pk-row .pk-when {
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 0.66rem; color: var(--mid); margin-left: auto;
}

/* The Toolkit's one prompt: add a passkey. It sits above the fold because it
   is the only thing on that screen the journalist has to decide; everything
   else there is orientation. mesa.js hides it once one is enrolled. */
.hub-passkey {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  padding: 16px 18px; margin-top: 22px;
  border: 1px solid var(--line); border-radius: 12px; background: var(--bg-2);
}
.hub-passkey[hidden] { display: none; }
.hub-passkey .hp-ico { color: var(--accent); flex: none; }
.hub-passkey .hp-ico svg { width: 22px; height: 22px; }
.hub-passkey .hp-text { flex: 1 1 320px; min-width: 0; }
.hub-passkey .hp-text b { display: block; color: var(--fg); font-size: 0.94rem; margin-bottom: 3px; }
.hub-passkey .hp-text span { display: block; color: var(--fg-2); font-size: 0.84rem; line-height: 1.5; }

/* Colour alone is not a signal: it fails for anyone who does not see the
   difference. The lab that owns the tool is also written. */
.lab-chip {
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 0.62rem; letter-spacing: 0.08em;
  padding: 2px 7px; border-radius: 999px;
  color: var(--accent); border: 1px solid var(--accent);
  background: var(--accent-soft);
}

.muted { color: var(--mid); }
.hidden { display: none !important; }
.sm { font-size: .72rem; }

/* ---- shared inputs / buttons (auth + admin pages, disarm-style) ---- */
.purpose {
  width: 100%; box-sizing: border-box; background: var(--bg-3);
  border: 1px solid var(--line); color: var(--fg); border-radius: 6px; padding: 10px 12px;
  font-family: "IBM Plex Mono", monospace; font-size: 12.5px;
}
.purpose:focus { outline: none; border-color: var(--accent); }
.case-input {
  width: 100%; box-sizing: border-box; background: var(--bg-3); border: 1px solid var(--line);
  color: var(--fg); border-radius: 6px; padding: 12px 14px; min-height: 100px;
  font-family: "IBM Plex Mono", monospace; font-size: 12.5px; line-height: 1.55; resize: vertical;
}
.case-input:focus { outline: none; border-color: var(--accent); }
.run-row { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-top: 14px; }
.btn-run {
  display: inline-flex; align-items: center; gap: 8px; background: var(--accent); color: var(--bg);
  border: 0; border-radius: 6px; padding: 11px 20px; font-family: inherit; font-weight: 600;
  font-size: 13px; cursor: pointer; transition: transform .15s, box-shadow .15s;
}
.btn-run:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 12px 30px -12px var(--accent); }
.btn-run:disabled { opacity: .45; cursor: not-allowed; }
.btn-line {
  display: inline-flex; align-items: center; gap: 7px; background: transparent; color: var(--fg-2);
  border: 1px solid var(--line); border-radius: 6px; padding: 9px 14px; font-family: inherit;
  font-size: 12.5px; cursor: pointer; text-decoration: none; transition: border-color .15s, color .15s;
}
.btn-line:hover { border-color: var(--accent); color: var(--accent); }
.btn-line.sm { padding: 6px 10px; font-size: 11px; }
.btn-run svg, .btn-line svg { width: 15px; height: 15px; }

/* desk panel/header (admin + assistant panels; not provided by desk.css) */
.desk .panel { border: 1px solid var(--line); border-radius: 8px;
  background: linear-gradient(180deg, var(--bg-2), var(--bg)); padding: 18px 20px; }
.desk .ph { display: flex; align-items: center; gap: 9px; margin-bottom: 14px;
  font-family: "IBM Plex Mono", monospace; font-size: 11px; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--mid); }

/* ---- assistant ---- */
.chatpanel { display: flex; flex-direction: column; max-width: 860px; }
.chat-log { display: flex; flex-direction: column; gap: 12px; min-height: 220px;
  max-height: 52vh; overflow-y: auto; padding: 4px 2px; }
.chat-msg { max-width: 85%; padding: 10px 14px; border-radius: 8px; font-size: 13px;
  line-height: 1.6; white-space: pre-wrap; word-wrap: break-word; }
.chat-msg.user { align-self: flex-end; background: var(--accent-soft);
  border: 1px solid var(--accent-soft); color: var(--fg); }
.chat-msg.assistant { align-self: flex-start; background: var(--bg-3);
  border: 1px solid var(--line-soft); color: var(--fg-2); }
.chat-msg.system { align-self: center; color: var(--mid);
  font-family: "IBM Plex Mono", monospace; font-size: 11px; }
.chat-empty { color: var(--mid); font-size: 12.5px; line-height: 1.6; padding: 12px;
  border: 1px dashed var(--line-soft); border-radius: 8px; }
.chat-composer { display: flex; gap: 10px; align-items: flex-end; margin-top: 14px; }
.chat-composer textarea { flex: 1; box-sizing: border-box; background: var(--bg-3);
  border: 1px solid var(--line); color: var(--fg); border-radius: 6px; padding: 10px 12px;
  font-family: inherit; font-size: 13px; line-height: 1.5; resize: vertical; min-height: 44px; }
.chat-composer textarea:focus { outline: none; border-color: var(--accent); }
.chat-note { margin: 12px 0 0; font-size: .68rem; line-height: 1.6; }
.chat-thinking { display: inline-flex; gap: 4px; align-items: center; }
.chat-thinking i { width: 5px; height: 5px; border-radius: 50%; background: var(--accent);
  animation: chatdot 1.2s infinite ease-in-out; }
.chat-thinking i:nth-child(2) { animation-delay: .2s; }
.chat-thinking i:nth-child(3) { animation-delay: .4s; }
@keyframes chatdot { 0%, 80%, 100% { opacity: .25; } 40% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .chat-thinking i { animation: none; opacity: .7; }
  .btn-run:hover:not(:disabled) { transform: none; }
}

/* ---- knowledge base ---- */
.kb-section { margin-top: 8px; }
.kb-entries { display: grid; gap: 10px; }
.kb-entry { display: flex; gap: 14px; align-items: flex-start; border: 1px solid var(--line-soft);
  border-radius: 8px; padding: 12px 14px; background: var(--bg-2); }
.kb-type { flex-shrink: 0; width: 74px; font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--accent); margin-top: 3px; }
.kb-body a { color: var(--fg); text-decoration: none; font-weight: 600; font-size: 13.5px; }
.kb-body a:hover { color: var(--accent); }
.kb-body a svg { width: 12px; height: 12px; vertical-align: -1px; }
.kb-title { color: var(--fg); font-weight: 600; font-size: 13.5px; }
.kb-body p { margin: 4px 0 0; font-size: 12.5px; line-height: 1.55; color: var(--fg-2); }

/* ---- guides ---- */
.guides { display: grid; grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
  gap: 16px; margin-top: 20px; }
.guide { border: 1px solid var(--line); border-radius: 8px; padding: 18px;
  background: linear-gradient(180deg, var(--bg-2), var(--bg)); }
.guide-head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.guide-head svg { width: 18px; height: 18px; color: var(--accent); }
.guide-head h3 { margin: 0; font-size: .95rem; }
.guide-sum { margin: 0 0 10px; font-size: 12.5px; color: var(--mid); line-height: 1.5; }
.guide-steps { margin: 0; padding-left: 18px; display: grid; gap: 8px; }
.guide-steps li { font-size: 12.5px; line-height: 1.6; color: var(--fg-2); }
.guide-steps li::marker { color: var(--accent); font-family: "IBM Plex Mono", monospace;
  font-size: 11px; }

/* ==================== ADMIN PANEL ====================
   The admin shell is the same markup as GovScan's, so it needs the same
   component styles. Ported 2026-08-07: without these the panel rendered as
   unstyled text lines. Everything below is accent-driven, so it takes the
   J-LAB hue automatically. */

.admin-row { display: flex; align-items: center; justify-content: space-between; gap: 14px;
  padding: 11px 0; border-top: 1px solid var(--line-soft); font-size: 0.86rem; }
.admin-row:first-of-type { border-top: 0; }
.admin-row .run-row { flex-wrap: nowrap; gap: 8px; }
.admin-row form { margin: 0; }
.ph .spacer { flex: 1; }

.tag { display: inline-block; font-size: 0.62rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.05em; padding: 2px 8px; border-radius: 20px; margin-left: 6px;
  font-family: "IBM Plex Mono", monospace; background: var(--bg-3); color: var(--mid); }
.tag-sent, .tag-accepted, .tag-invited { background: oklch(0.72 0.16 155 / 0.16); color: var(--g-a); }
.tag-created, .tag-pending { background: oklch(0.80 0.13 90 / 0.16); color: var(--g-c); }
.tag-already_user, .tag-already_invited { background: var(--bg-3); color: var(--mid); }
.rail .badge { margin-left: auto; background: var(--accent-soft); color: var(--accent);
  border-radius: 20px; padding: 1px 8px; font-size: 0.68rem; font-family: "IBM Plex Mono", monospace; }

.mail-err { background: oklch(0.62 0.20 25 / 0.10); border-left: 2px solid var(--g-f);
  color: var(--fg-2); font-size: 0.74rem; padding: 8px 10px; margin: 6px 0 2px;
  border-radius: 0 6px 6px 0; word-break: break-word; }

/* ---- usage view ---- */
.usage-range { display: flex; gap: 8px; margin: 20px 0 4px; }
.usage-range .btn-line.on { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }
.stat-row { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-top: 16px; }
.stat-card { background: linear-gradient(180deg, var(--bg-2), var(--bg));
  border: 1px solid var(--line); border-radius: 8px; padding: 14px 16px; }
.stat-card .n { font-size: 1.7rem; font-weight: 700; font-family: "IBM Plex Mono", monospace; }
.stat-card .l { color: var(--mid); font-size: 0.75rem; margin-top: 2px; }
.usage-row { display: grid; grid-template-columns: 1.6fr 1fr 90px 90px; align-items: center;
  gap: 12px; padding: 9px 0; border-top: 1px solid var(--line-soft); font-size: 0.83rem; }
.usage-row.head { border-top: 0; color: var(--mid); font-size: 0.68rem; text-transform: uppercase;
  letter-spacing: 0.08em; font-family: "IBM Plex Mono", monospace; }
.usage-row .ur-name { min-width: 0; }
.usage-row .ur-num { text-align: right; }
.usage-row .ur-date { text-align: right; font-size: 0.75rem; }
.ur-bar { background: var(--bg-3); border-radius: 6px; height: 8px; overflow: hidden; }
.ur-bar span { display: block; height: 100%; background: var(--accent); border-radius: 6px; min-width: 2px; }

/* Long words and wide content must never widen the shell. */
.desk .viewport, .desk .view, .desk .panel { min-width: 0; }
.desk .panel { overflow-wrap: anywhere; }

@media (max-width: 760px) {
  .stat-row { grid-template-columns: repeat(2, 1fr); }
  .usage-row { grid-template-columns: 1fr 70px 80px; }
  .usage-row .ur-bar, .usage-row.head { display: none; }
}
.admin-row.wide { align-items: flex-start; }
.admin-row.wide > div:first-child { min-width: 0; }


/* ==================== TOOL SCREENS (STD-024) ====================
   A tool runs as a native view of the desk, never as a page inside a page.
   The masthead is the prototype's ToolLayout: eyebrow, title, lead, a
   right-aligned action cluster and a row of mono meta chips. Then the tool
   owns a hairline-divided grid underneath. Reused by every tool screen. */

.tool-head { display: flex; align-items: flex-start; justify-content: space-between;
  gap: 32px; flex-wrap: wrap; }
.tool-head > div:first-child { max-width: 640px; min-width: 0; }
.tool-actions { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.tool-meta { display: flex; flex-wrap: wrap; gap: 0; margin-top: 18px;
  padding-bottom: 18px; border-bottom: 1px solid var(--line); }
.tool-meta span { font-family: "IBM Plex Mono", monospace; font-size: 10px;
  letter-spacing: 0.05em; color: var(--mid); text-transform: uppercase;
  padding-right: 12px; margin-right: 12px; border-right: 1px solid var(--line); }
.tool-meta span:last-child { border-right: 0; }

/* two-column workspace: evidence on the left, findings on the right */
.tool-grid { display: grid; grid-template-columns: 360px 1fr; gap: 28px; margin-top: 24px;
  align-items: start; }
@media (max-width: 980px) { .tool-grid { grid-template-columns: 1fr; } }

/* drop zone */
.drop { border: 1px dashed var(--line-strong, var(--line)); border-radius: 8px;
  padding: 28px 18px; text-align: center; cursor: pointer; background: var(--bg-2);
  transition: border-color .15s, background .15s; }
.drop:hover, .drop.over { border-color: var(--accent); background: var(--accent-soft); }
.drop svg { width: 22px; height: 22px; color: var(--accent); }
.drop .dz-t { font-size: 0.9rem; margin-top: 8px; }
.drop .dz-s { font-size: 0.75rem; color: var(--mid); margin-top: 4px; }

/* verdict rows: severity carries the colour, the text carries the meaning */
.vrow { display: grid; grid-template-columns: 1fr auto; gap: 14px; align-items: baseline;
  padding: 11px 0; border-top: 1px solid var(--line-soft); }
.vrow:first-of-type { border-top: 0; }
.vrow .vk { font-size: 0.86rem; }
.vrow .vd { font-family: "IBM Plex Mono", monospace; font-size: 0.72rem; color: var(--mid);
  margin-top: 3px; word-break: break-word; }
.sev { font-family: "IBM Plex Mono", monospace; font-size: 0.6rem; text-transform: uppercase;
  letter-spacing: 0.08em; padding: 2px 8px; border-radius: 20px; border: 1px solid currentColor; }
.sev-critical { color: var(--g-f, var(--sem-scene)); }
.sev-high     { color: var(--sem-scene); }
.sev-medium   { color: var(--sem-facts); }
.sev-low      { color: var(--mid); }

/* metadata dump */
.dump-g { margin-top: 16px; }
.dump-g .dg-h { font-family: "IBM Plex Mono", monospace; font-size: 0.66rem;
  text-transform: uppercase; letter-spacing: 0.1em; color: var(--accent); margin-bottom: 6px; }
.dump-r { display: grid; grid-template-columns: 210px 1fr; gap: 14px; padding: 5px 0;
  border-top: 1px solid var(--line-soft); font-size: 0.78rem; }
.dump-r .dk { font-family: "IBM Plex Mono", monospace; color: var(--fg-2); word-break: break-word; }
.dump-r .dv { color: var(--mid); word-break: break-word; }
.dump-r.hot .dk { color: var(--sem-scene); }
.exif-preview { width: 100%; border-radius: 8px; border: 1px solid var(--line); display: block; }

/* ==================== Mi mesa ====================
   The journalist's own cases. Layout only: every colour and radius comes
   from the design system tokens in node.css, which is canon and untouched. */

.mesa-gate { max-width: 560px; margin-top: 22px; }
.mesa-gate-lead { color: var(--mid); font-size: 0.84rem; margin: 10px 0 14px; line-height: 1.55; }
.mesa-gate-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-top: 10px; }
.mesa-gate-row .purpose { flex: 1 1 200px; margin-top: 0; }
.mesa-err { color: oklch(0.65 0.19 25); font-size: 0.78rem; margin: 10px 0 0; }
.mesa-recover { margin-top: 14px; }
.mesa-recover summary { color: var(--mid); font-size: 0.78rem; cursor: pointer; }

/* The recovery code is shown once, so it is set big enough to copy onto
   paper without squinting, and grouped the way it is generated. */
.mesa-code { font-family: "IBM Plex Mono", monospace; font-size: 1.35rem; letter-spacing: 0.14em;
  color: var(--accent); background: var(--bg-2, rgba(255,255,255,.03));
  border: 1px solid var(--accent); border-radius: 8px; padding: 16px;
  text-align: center; margin: 6px 0 4px; word-break: break-all; }
.mesa-ack { display: flex; align-items: center; gap: 8px; font-size: 0.8rem; color: var(--mid); }

.mesa-cases { display: flex; flex-direction: column; gap: 8px; margin-top: 18px; }
/* Flex, not a fixed grid: the row has an optional "local" badge, and a grid
   with a fixed column count silently misplaces every cell after it the moment
   one row has an extra child. */
.mesa-case { display: flex; align-items: center; gap: 14px;
  width: 100%; text-align: left; background: transparent; border: 1px solid var(--line);
  border-radius: 10px; padding: 13px 16px; cursor: pointer; color: inherit;
  transition: border-color .15s ease, background .15s ease; }
.mesa-case .mc-status { flex: 0 0 auto; min-width: 92px; }
.mesa-case .mc-title { flex: 1 1 auto; min-width: 0; }
.mesa-case .mc-local, .mesa-case .mc-meta, .mesa-case .mc-when { flex: 0 0 auto; }
.mesa-case:hover { border-color: var(--accent); background: rgba(255,255,255,.02); }
.mc-status { font-family: "IBM Plex Mono", monospace; font-size: 0.62rem; text-transform: uppercase;
  letter-spacing: 0.09em; padding: 3px 9px; border-radius: 20px; border: 1px solid currentColor;
  text-align: center; color: var(--mid); }
.mc-status.st-reporting, .mc-status.st-writing { color: var(--accent); }
.mc-status.st-review { color: var(--sem-facts, var(--accent-2)); }
.mc-status.st-published { color: var(--accent-2, var(--accent)); }
.mc-title { font-size: 0.95rem; font-weight: 500; }
.mc-meta, .mc-when { font-family: "IBM Plex Mono", monospace; font-size: 0.7rem; color: var(--mid); }

.mesa-empty { text-align: center; padding: 60px 20px; color: var(--mid); }
.mesa-empty p { margin: 14px 0 18px; font-size: 0.9rem; }

.mesa-detail-head { display: flex; align-items: center; gap: 12px; margin-bottom: 18px; }
.mesa-detail-head .spacer { flex: 1; }
.mesa-danger { color: oklch(0.65 0.19 25); border-color: currentColor; }
.mesa-status { background: transparent; color: var(--fg); border: 1px solid var(--line);
  border-radius: 20px; padding: 6px 12px; font-family: "IBM Plex Mono", monospace;
  font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; }

/* The title behaves like a document title, not a form field: no box until
   you touch it, because a case is a thing you write, not a record you fill. */
.mesa-title { width: 100%; background: transparent; border: none; color: var(--fg);
  font-family: "Space Grotesk", sans-serif; font-size: 1.9rem; font-weight: 600;
  padding: 4px 0; border-bottom: 1px solid transparent; }
.mesa-title:focus { outline: none; border-bottom-color: var(--accent); }
.mesa-summary { width: 100%; background: transparent; border: none; color: var(--mid);
  font-family: inherit; font-size: 0.92rem; resize: vertical; padding: 8px 0 14px; }
.mesa-summary:focus { outline: none; }

.mesa-cols { display: grid; grid-template-columns: 1.35fr 1fr; gap: 18px; margin-top: 10px; }
@media (max-width: 900px) { .mesa-cols { grid-template-columns: 1fr; } }

.mesa-note-new { width: 100%; background: transparent; border: 1px solid var(--line);
  border-radius: 8px; color: var(--fg); font-family: inherit; font-size: 0.86rem;
  padding: 10px; margin: 10px 0; resize: vertical; }
.mesa-note-new:focus { outline: none; border-color: var(--accent); }

.mesa-row { display: flex; align-items: flex-start; gap: 10px; padding: 10px 0;
  border-top: 1px solid var(--line-soft); font-size: 0.85rem; }
.mesa-row:first-child { border-top: none; }
.mesa-row a { color: var(--accent); word-break: break-all; }
.mesa-row .mr-body { flex: 1; line-height: 1.55; white-space: pre-wrap; }
.mesa-row .mr-foot { display: flex; align-items: center; gap: 8px;
  font-family: "IBM Plex Mono", monospace; font-size: 0.66rem; color: var(--mid); }
.mf-tool { font-family: "IBM Plex Mono", monospace; font-size: 0.62rem; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--accent); }

.mesa-item { display: flex; align-items: center; gap: 10px; padding: 9px 0;
  border-top: 1px solid var(--line-soft); font-size: 0.86rem; cursor: pointer; }
.mesa-item:first-of-type { border-top: none; }
.mesa-item span { flex: 1; }
.mesa-item span.done { color: var(--mid); text-decoration: line-through; }

.mesa-x { background: none; border: none; color: var(--mid); cursor: pointer;
  font-size: 1.1rem; line-height: 1; padding: 0 4px; opacity: .5; }
.mesa-x:hover { opacity: 1; color: oklch(0.65 0.19 25); }
.mesa-none { color: var(--mid); font-size: 0.8rem; margin: 12px 0 0; }

/* Save-to-case dialog. Reachable from any tool screen. */
.mesa-dialog { background: var(--bg-1, #0b0d11); color: var(--fg); border: 1px solid var(--line);
  border-radius: 12px; padding: 24px; max-width: 460px; width: calc(100% - 40px); }
.mesa-dialog::backdrop { background: rgba(0,0,0,.62); }
.mesa-dialog h3 { margin: 0 0 4px; font-family: "Space Grotesk", sans-serif; font-size: 1.15rem; }
.mesa-save-what { font-family: "IBM Plex Mono", monospace; font-size: 0.74rem;
  color: var(--accent); margin: 0 0 14px; word-break: break-all; }
.mesa-lbl { display: block; font-family: "IBM Plex Mono", monospace; font-size: 0.64rem;
  text-transform: uppercase; letter-spacing: 0.1em; color: var(--mid); margin: 4px 0 6px; }
.mesa-wide { width: 100%; border-radius: 8px; }
.mesa-dialog .purpose { width: 100%; margin-top: 10px; }

/* ==================== Connections (the case as a graph) ====================
   Colour carries the entity type, so the shape of a case is readable before
   any label is. Every value is a design-system token. */

.mesa-tabs { margin: 4px 0 16px; }
.mesa-graph-wrap { position: relative; border: 1px solid var(--line); border-radius: 10px;
  background: rgba(255,255,255,.015); overflow: hidden; }
.mesa-graph-empty { position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; text-align: center; padding: 0 40px; margin: 0; }
#mesa-graph { display: block; touch-action: none; }

.mg-edge { stroke: var(--line); stroke-width: 1.2; }
.mg-elabel { fill: var(--mid); font-family: "IBM Plex Mono", monospace; font-size: 8.5px;
  text-anchor: middle; letter-spacing: 0.04em; }

.mg-node { cursor: pointer; }
.mg-node circle { fill: var(--bg-1, #0b0d11); stroke: var(--mid); stroke-width: 2;
  transition: r .12s ease, stroke-width .12s ease; }
.mg-node:hover circle, .mg-node:focus circle { stroke-width: 3.5; }
.mg-node:focus { outline: none; }
.mg-label { fill: var(--fg-2, var(--fg)); font-family: "IBM Plex Mono", monospace;
  font-size: 9.5px; text-anchor: middle; }

/* One colour per kind. Place and person are the two that matter most to a
   journalist's safety, so they get the strongest signal. */
.mg-node.k-place circle    { stroke: var(--sem-scene, oklch(0.65 0.19 25)); }
.mg-node.k-person circle   { stroke: var(--accent); }
.mg-node.k-image circle    { stroke: var(--accent-2, var(--accent)); }
.mg-node.k-device circle   { stroke: var(--sem-facts, var(--mid)); }
.mg-node.k-website circle  { stroke: var(--accent-2, var(--accent)); }
.mg-node.k-software circle { stroke: var(--mid); }
.mg-node.k-time circle     { stroke: var(--mid); }

.mesa-node-info { margin-top: 14px; }
.mesa-node-label { font-family: "IBM Plex Mono", monospace; font-size: 0.95rem;
  color: var(--accent); margin: 6px 0 10px; word-break: break-all; }
.mesa-node-info .dump-r { grid-template-columns: 140px 1fr; }

/* `hidden` must win over any display rule we set.
   Without this, `.mesa-cols { display: grid }` and
   `.mesa-graph-empty { display: flex }` beat the attribute, and panes that
   the code believes are hidden stay on screen. Cheap rule, whole class of
   bug removed. */
[hidden] { display: none !important; }

/* ==================== DISARM native screen ==================== */
.ds-tech { display: flex; gap: 12px; align-items: flex-start; padding: 13px 0;
  border-top: 1px solid var(--line-soft); cursor: pointer; }
.ds-tech:first-of-type { border-top: none; }
.ds-tech input { margin-top: 3px; }
.ds-body { flex: 1; }
.ds-t { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; font-size: 0.92rem; }
.ds-id { font-family: "IBM Plex Mono", monospace; font-size: 0.64rem; color: var(--mid);
  border: 1px solid var(--line); border-radius: 20px; padding: 2px 8px; }
.ds-conf { font-family: "IBM Plex Mono", monospace; font-size: 0.6rem; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--accent); }
.ds-tac { display: block; font-family: "IBM Plex Mono", monospace; font-size: 0.66rem;
  text-transform: uppercase; letter-spacing: 0.09em; color: var(--accent); margin-top: 5px; }
.ds-why { display: block; color: var(--mid); font-size: 0.82rem; line-height: 1.55; margin-top: 6px; }

/* ==================== GovScan native screen ====================
   The grade is the headline: a journalist should be able to scan a column of
   letters and know which ministry to call first. */
.gs-attest { align-items: flex-start; gap: 10px; margin: 12px 0 4px; line-height: 1.5; }
.gs-attest input { margin-top: 3px; }
.gs-card { margin-top: 14px; }
.gs-head { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.gs-grade { font-family: "Space Grotesk", sans-serif; font-weight: 700; font-size: 1.25rem;
  width: 42px; height: 42px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 10px; border: 2px solid currentColor; }
.gs-g-A { color: var(--accent-2, var(--accent)); }
.gs-g-B { color: var(--accent); }
.gs-g-C { color: var(--sem-facts, var(--accent)); }
.gs-g-D, .gs-g-E { color: var(--sem-scene, oklch(0.65 0.19 25)); }
.gs-g-F { color: oklch(0.65 0.19 25); }
.gs-domain { font-family: "IBM Plex Mono", monospace; font-size: 0.95rem; flex: 1;
  word-break: break-all; }
.gs-note { font-family: "IBM Plex Mono", monospace; font-size: 0.7rem; color: var(--mid); }
.gs-findings { margin-top: 10px; }
.gs-up { color: var(--accent-2, var(--accent)); font-family: "IBM Plex Mono", monospace;
  font-size: 0.75rem; }
.gs-down { color: oklch(0.65 0.19 25); font-family: "IBM Plex Mono", monospace;
  font-size: 0.75rem; }

/* Kinds introduced by DISARM and GovScan. A weakness on a public site and a
   place a photo was taken share the alarm colour on purpose: both are the
   thing in the case that someone could be hurt by. */
.mg-node.k-weakness circle { stroke: var(--sem-scene, oklch(0.65 0.19 25)); }
.mg-node.k-technique circle { stroke: var(--accent); }
.mg-node.k-tactic circle { stroke: var(--sem-facts, var(--mid)); }

/* ==================== Toolkit: notices, steps, your activity ==================== */
.hub-notice { display: flex; align-items: flex-start; gap: 12px; padding: 13px 16px;
  border: 1px solid var(--line); border-radius: 10px; margin-top: 12px; font-size: 0.85rem; }
.hub-notice.warn { border-color: var(--accent); }
.hub-notice > div { flex: 1; }
.hub-notice b { display: block; margin-bottom: 3px; }
.hub-notice span { color: var(--mid); }
.hub-notice button { flex: 0 0 auto; }

.hub-start { margin-top: 26px; }
.hub-steps { list-style: none; counter-reset: step; padding: 0; margin: 12px 0 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
@media (max-width: 860px) { .hub-steps { grid-template-columns: 1fr; } }
.hub-steps li { counter-increment: step; border: 1px solid var(--line); border-radius: 10px;
  padding: 14px 16px; position: relative; }
.hub-steps li::before { content: counter(step, decimal-leading-zero);
  font-family: "IBM Plex Mono", monospace; font-size: 0.64rem; color: var(--accent);
  letter-spacing: 0.1em; display: block; margin-bottom: 8px; }
.hub-steps b { display: block; font-size: 0.9rem; margin-bottom: 5px; }
.hub-steps span { color: var(--mid); font-size: 0.8rem; line-height: 1.5; }

.hub-row { display: grid; grid-template-columns: 1fr auto auto; gap: 14px; align-items: center;
  width: 100%; text-align: left; background: transparent; color: inherit;
  border: 1px solid var(--line); border-radius: 10px; padding: 12px 16px;
  margin-top: 8px; cursor: pointer; transition: border-color .15s ease; }
.hub-row:hover { border-color: var(--accent); }
.hr-title { font-size: 0.9rem; }
.hr-meta, .hr-when { font-family: "IBM Plex Mono", monospace; font-size: 0.7rem; color: var(--mid); }

/* ==================== who you are on the desk ==================== */
.whoami { display: inline-flex; align-items: center; gap: 9px; background: transparent;
  border: 1px solid transparent; border-radius: 20px; padding: 3px 10px 3px 4px;
  color: inherit; cursor: pointer; font: inherit; }
.whoami:hover { border-color: var(--line); }
.who-name { font-family: "IBM Plex Mono", monospace; font-size: 0.72rem; }
.who-dialog { max-width: 440px; }
.who-row { display: flex; align-items: center; gap: 14px; margin: 14px 0 4px; }
.who-face svg { display: block; }
.who-suggest { margin: 6px 0 10px; flex-wrap: wrap; }
.who-suggest .chip { font-family: "IBM Plex Mono", monospace; }

/* ==================== step flow diagram (guides + hardening) ==================== */
.gv-holder { margin: 12px 0 14px; }
.gv { width: 100%; height: auto; display: block; }
.gv-track { stroke: var(--line); stroke-width: 0.5; }
.gv-node { fill: var(--bg-1, #0b0d11); stroke: var(--accent); stroke-width: 0.9; }
.gv-num { fill: var(--accent); font-family: "IBM Plex Mono", monospace; font-size: 3.4px;
  text-anchor: middle; }
.gv-label { fill: var(--mid); font-family: "IBM Plex Mono", monospace; font-size: 3.6px;
  text-anchor: start; letter-spacing: 0.02em; }

/* ==================== suggested tools ==================== */
.guide-tools { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line-soft); }
.gt-label { font-family: "IBM Plex Mono", monospace; font-size: 0.62rem;
  text-transform: uppercase; letter-spacing: 0.1em; color: var(--mid); }
.gt-note { flex: 1 1 220px; color: var(--mid); font-size: 0.76rem; line-height: 1.5; }

/* ==================== hardening cards ==================== */
.hard-cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin-top: 14px; }
@media (max-width: 1000px) { .hard-cards { grid-template-columns: 1fr; } }
.hard-mins { font-family: "IBM Plex Mono", monospace; font-size: 0.64rem; color: var(--mid); }
.hard-why { color: var(--mid); font-size: 0.82rem; line-height: 1.6; margin: 10px 0 0; }
.hard-steps { margin: 6px 0 0; padding-left: 20px; }
.hard-steps li { font-size: 0.85rem; line-height: 1.6; margin: 5px 0; }
/* A tool we have not finished testing is named, greyed and explained, never
   linked. Handing out an untested security tool is worse than handing out none. */
.hard-soon { font-family: "IBM Plex Mono", monospace; font-size: 0.68rem;
  color: var(--mid); border: 1px dashed var(--line); border-radius: 20px; padding: 4px 10px; }

/* A sensitive case is marked everywhere it appears. Someone filing a finding
   into the wrong kind of case is the failure this label exists to prevent. */
.mesa-case.sensitive { border-style: dashed; }
.mc-local { font-family: "IBM Plex Mono", monospace; font-size: 0.58rem;
  text-transform: uppercase; letter-spacing: 0.09em; color: var(--sem-scene, oklch(0.65 0.19 25));
  border: 1px solid currentColor; border-radius: 20px; padding: 2px 7px; }
.mesa-sensitive-note { margin-top: 14px; max-width: 70ch; line-height: 1.6; }
