/* ══════════════════════════════════════════════════════════════════
   THE SURFACE SYSTEM — five surfaces, in elevation order.

   Every panel in the product is one of these. There is no free-form
   background: anywhere. Five is enough, and a fixed five is what stops
   a codebase drifting into forty slightly different card styles.
   ══════════════════════════════════════════════════════════════════ */

/* 1. canvas — the page itself, set on body. No border. */

/* 2. A stat tile nested INSIDE a card. */
.inset-tile {
  background: hsl(var(--foreground) / 0.045);
  border-radius: 10px;
  padding: 14px;
}

/* 3. The standard card. */
.glass {
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border) / 0.09);
  border-radius: var(--r-lg);
  padding: 22px;
  color: hsl(var(--card-foreground));
}
.glass-flush { padding: 0; overflow: hidden; }
.glass-tight { padding: 16px; }

.glass-link { display: block; transition: border-color 0.16s var(--ease), background 0.16s var(--ease); }
.glass-link:hover { border-color: hsl(var(--border) / 0.2); background: hsl(var(--foreground) / 0.02); }

/* 4. Dialogs, popovers, dropdowns, toasts. */
.glass-strong {
  background: hsl(var(--popover));
  border: 1px solid hsl(var(--border) / 0.14);
  border-radius: var(--r-2xl);
  box-shadow: var(--shadow-strong);
  color: hsl(var(--popover-foreground));
}

/* 5. Instrument panels — the lit stage the main instrument sits on.
   These re-declare the mode-dependent tokens inside themselves, so every
   utility used within resolves against the panel's own canvas instead of
   the page's — no dark: variants, no isDark props, no hard-coded rgba().

   The panel always steps AWAY from the surrounding surface in the direction
   of the theme's own extreme: near-white above a grey canvas in light, black
   below grey cards in dark. A black slab on a light page reads as a hole
   punched in the layout rather than as an instrument. */

/* ── Light: a near-white stage lifted off the grey canvas ── */
.panel-dark,
.panel-hero {
  --background: 0 0% 97%;
  /* Cards and chips INSIDE the panel go pure white, so they read as lifted
     off the stage the same way the stage is lifted off the canvas. */
  --card:       var(--brand-white);
  --popover:    var(--brand-white);
  --input:      var(--brand-white);

  background: hsl(0 0% 97%);
  color: hsl(var(--foreground));
  border: 1px solid hsl(var(--border) / 0.07);
  border-radius: var(--r-xl);
}

.panel-hero {
  background:
    radial-gradient(120% 150% at 82% -30%, hsl(var(--signal-ok) / 0.22) 0%, transparent 58%),
    hsl(0 0% 97%);
}

/* ── Dark: the instrument panel drops below the cards around it ── */
.dark .panel-dark,
.dark .panel-hero {
  color-scheme: dark;

  --background:           var(--brand-black);
  --foreground:           var(--brand-light-grey);
  --card:                 var(--brand-dark-grey);
  --card-foreground:      var(--brand-light-grey);
  --popover:              var(--brand-dark-grey);
  --secondary:            var(--brand-light-grey);
  --secondary-foreground: var(--brand-black);
  --accent:               0 0% 16%;
  --muted-foreground:     var(--brand-grey);
  --input:                0 0% 16%;
  --border:               var(--brand-white);

  --signal-ok-ink:    var(--brand-yellow);
  --signal-watch-ink: var(--brand-orange);
  --signal-risk-ink:  351 70% 65%;
  --signal-data-ink:  218 50% 66%;

  background: hsl(var(--brand-black));
  border-color: transparent;
}

/* One warm rake of light, and only one. The glow and the instrument inside it
   are the same signal colour — one accent per component. */
.dark .panel-hero {
  background:
    radial-gradient(120% 150% at 82% -30%, hsl(var(--signal-ok) / 0.16) 0%, transparent 55%),
    hsl(var(--brand-black));
}

/* ══════════════════════════════════════════════════════════════════
   CSS-class components — small reusable shapes used inside one-off
   markup constantly, so they live as classes rather than functions.
   ══════════════════════════════════════════════════════════════════ */

/* The universal chip recipe: fill at 15% alpha, text in the ink token.
   Never set text in a fill token — yellow on light grey is unreadable,
   which is exactly why the ink variants exist. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  border-radius: 6px;
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  background: hsl(var(--foreground) / 0.07);
  color: hsl(var(--muted-foreground));
}
.chip-ok    { background: hsl(var(--signal-ok) / 0.15);    color: hsl(var(--signal-ok-ink)); }
.chip-watch { background: hsl(var(--signal-watch) / 0.15); color: hsl(var(--signal-watch-ink)); }
.chip-risk  { background: hsl(var(--signal-risk) / 0.15);  color: hsl(var(--signal-risk-ink)); }
.chip-data  { background: hsl(var(--signal-data) / 0.15);  color: hsl(var(--signal-data-ink)); }
/* A control with no API is an absence of a result, not a result — so it gets
   a shape (dashed edge), not a fifth colour. */
.chip-none {
  background: transparent;
  color: hsl(var(--muted-foreground));
  border: 1px dashed hsl(var(--border) / 0.28);
  padding: 3px 8px;
}

/* Colour is never the only channel: the dot always travels with its label. */
.chip-dot { width: 6px; height: 6px; border-radius: 99px; background: currentColor; flex: none; }

/* Segmented control — selected thumb is bg-input plus a 1px shadow. */
.seg {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  border-radius: var(--r-md);
  background: hsl(var(--foreground) / 0.05);
}
.seg-item {
  padding: 5px 11px;
  border-radius: calc(var(--r-md) - 4px);
  font-size: 12.5px;
  color: hsl(var(--muted-foreground));
  white-space: nowrap;
  transition: color 0.14s var(--ease), background 0.14s var(--ease);
}
.seg-item:hover { color: hsl(var(--foreground)); }
.seg-item[data-active] {
  background: hsl(var(--input));
  color: hsl(var(--foreground));
  font-weight: 500;
  box-shadow: 0 1px 2px hsl(var(--brand-black) / 0.14);
}

/* Filter pill — selection INVERTS rather than colouring.
   Colour is spent on meaning, not on state. */
.pill {
  padding: 5px 11px;
  border-radius: var(--r-md);
  font-size: 12.5px;
  border: 1px solid hsl(var(--border) / 0.09);
  color: hsl(var(--muted-foreground));
  white-space: nowrap;
  transition: all 0.14s var(--ease);
}
.pill:hover { color: hsl(var(--foreground)); border-color: hsl(var(--border) / 0.2); }
.pill[data-active] {
  background: hsl(var(--secondary));
  color: hsl(var(--secondary-foreground));
  border-color: transparent;
  font-weight: 500;
}

/* ── Buttons ── every one acknowledges the press. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 7px 13px;
  border-radius: 9px;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  border: 1px solid transparent;
  transition: background 0.14s var(--ease), border-color 0.14s var(--ease), transform 0.08s var(--ease);
}
.btn:active:not(:disabled) { transform: scale(0.98); }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.btn svg { width: 15px; height: 15px; flex: none; }

.btn-default   { background: hsl(var(--primary)); color: hsl(var(--primary-foreground)); }
.btn-default:hover:not(:disabled) { background: hsl(var(--primary) / 0.88); }
.btn-secondary { background: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); }
.btn-outline   { border-color: hsl(var(--border) / 0.16); color: hsl(var(--foreground)); }
.btn-outline:hover:not(:disabled) { background: hsl(var(--foreground) / 0.05); }
.btn-ghost     { color: hsl(var(--muted-foreground)); }
.btn-ghost:hover:not(:disabled) { background: hsl(var(--foreground) / 0.06); color: hsl(var(--foreground)); }
.btn-destructive { background: hsl(var(--signal-risk)); color: hsl(var(--brand-white)); }
.btn-sm { padding: 4px 9px; font-size: 12px; }
.btn-icon { padding: 7px; }

.btn-spin { display: inline-block; }
.btn[data-loading] .btn-spin { animation: spin 0.85s linear infinite; }
@keyframes spin { to { rotate: 360deg; } }

/* ══════════════════════════════════════════════════════════════════
   BARS — overflow is drawn, not just recoloured.
   ══════════════════════════════════════════════════════════════════ */

.bar-track {
  position: relative;
  height: 6px;
  border-radius: 99px;
  background: hsl(var(--foreground) / 0.08);
  overflow: hidden;
}
.bar-fill {
  height: 100%;
  border-radius: 99px;
  background: hsl(var(--signal-ok));
  transition: width 0.6s var(--ease);
}
.bar-fill[data-tone='watch'] { background: hsl(var(--signal-watch)); }
.bar-fill[data-tone='risk']  { background: hsl(var(--signal-risk)); }
.bar-fill[data-tone='data']  { background: hsl(var(--signal-data)); }
.bar-fill[data-tone='none']  { background: hsl(var(--foreground) / 0.22); }

/* Over capacity gets a 45° hatch as well as red — pattern, not just hue. */
.bar-fill[data-over] {
  background-image: repeating-linear-gradient(
    45deg,
    hsl(var(--brand-black) / 0.32) 0 4px,
    transparent 4px 8px
  );
}

/* A 1px marker where the budget line falls. */
.bar-marker {
  position: absolute;
  top: -2px;
  bottom: -2px;
  width: 1px;
  background: hsl(var(--foreground) / 0.55);
}

/* ══════════════════════════════════════════════════════════════════
   THE INSTRUMENT — dial, tick ring, orbit.
   ══════════════════════════════════════════════════════════════════ */

/* Interpolating a custom property requires registering it. Without this the
   sweep snaps from 0 to the target instead of ramping. */
@property --dial-sweep {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 0%;
}

.dial-stage {
  position: relative;
  width: 280px;
  height: 280px;
  display: grid;
  place-items: center;
  margin: 0 auto;
}

.dial {
  position: relative;
  width: 208px;
  height: 208px;
  border-radius: 50%;

  /* The finished state is the base style. --dial-sweep resolves to the real
     target here; the keyframe only supplies the starting point. If the
     animation never runs — reduced motion, unsupported browser — the dial
     still shows the correct fill instead of reading empty. */
  --dial-sweep: var(--dial-target, 0%);
  /* from 0deg — the sweep starts at twelve o'clock and runs clockwise, the
     way every gauge a reader has ever seen does. */
  background: conic-gradient(
    from 0deg,
    hsl(var(--dial-color, var(--signal-ok))) 0 var(--dial-sweep),
    hsl(var(--foreground) / 0.09) var(--dial-sweep) 100%
  );
  /* Punch the centre out to make it a ring. */
  mask: radial-gradient(circle at 50% 50%, transparent 0 68px, #000 69px 100%);
  animation: dial-in 1.1s var(--ease);
}
@keyframes dial-in { from { --dial-sweep: 0%; } }

.dial-core {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  text-align: center;
  pointer-events: none;
}

/* Spun with the independent `rotate` property, never `transform` — the ring
   is centred with `translate`, and a transform keyframe would replace that
   outright and throw it hundreds of pixels off-centre for the whole
   revolution. */
.dial-ticks {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 268px;
  height: 268px;
  translate: -50% -50%;
  border-radius: 50%;
  animation: drift 200s linear infinite;
  background:
    repeating-conic-gradient(
      from 0deg,
      hsl(var(--foreground) / 0.28) 0deg 0.35deg,
      transparent 0.35deg 6deg
    );
  mask: radial-gradient(circle at 50% 50%, transparent 0 126px, #000 127px 133px, transparent 134px);
}
@keyframes drift { to { rotate: 360deg; } }
@keyframes drift-back { to { rotate: -360deg; } }

/* Every orbiting chip lives inside ONE 0×0 track at the dial centre.
   Rotating that single element carries them all around without changing
   their arrangement, so they can never collide. */
.orbit-track {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 0;
  height: 0;
  animation: drift 120s linear infinite;
}

/* Counter-spun at the same rate as the track, so the WHOLE PILL stays upright
   as it travels — not just the text inside it. Counter-rotating only the label
   leaves the bordered box tilting around level text, which reads as broken.
   `rotate` and `translate` are independent properties, so the counter-spin
   composes with the centring offset instead of replacing it. */
.orbit-chip {
  position: absolute;
  translate: -50% -50%;
  animation: drift-back 120s linear infinite;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  border-radius: 99px;
  font-size: 11px;
  font-weight: 500;
  white-space: nowrap;
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border) / 0.14);
  color: hsl(var(--foreground));
  transition: border-color 0.16s var(--ease);
}
.orbit-chip:hover { border-color: hsl(var(--border) / 0.4); }

/* Plain layout wrapper now — the uprighting happens on the chip itself. */
.orbit-upright { display: inline-flex; align-items: center; gap: 5px; }

/* An orbiting button you cannot click is a bug: the track, the chips and the
   tick ring all pause together. */
.dial-stage:hover .orbit-track,
.dial-stage:focus-within .orbit-track,
.dial-stage:hover .orbit-chip,
.dial-stage:focus-within .orbit-chip,
.dial-stage:hover .dial-ticks,
.dial-stage:focus-within .dial-ticks {
  animation-play-state: paused;
}

/* ══════════════════════════════════════════════════════════════════
   MOTION — one load moment, then stillness.
   ══════════════════════════════════════════════════════════════════ */

@keyframes fade-up { from { opacity: 0; translate: 0 10px; } }
@keyframes fade-in { from { opacity: 0; } }

.animate-fade-up { animation: fade-up 0.5s var(--ease) both; }
.animate-fade-in { animation: fade-in 0.4s var(--ease) both; }

.delay-1 { animation-delay: 60ms; }
.delay-2 { animation-delay: 120ms; }
.delay-3 { animation-delay: 180ms; }
.delay-4 { animation-delay: 240ms; }
.delay-5 { animation-delay: 300ms; }

/* ══════════════════════════════════════════════════════════════════
   HERO LAYOUT
   ══════════════════════════════════════════════════════════════════ */

.hero {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  padding: 28px;
  min-height: 430px;
}
.hero-readouts { width: 210px; flex: none; display: flex; flex-direction: column; gap: 22px; }
.hero-instrument { flex: 1; min-width: 380px; display: none; }
.hero-feed { width: 264px; flex: none; display: flex; flex-direction: column; gap: 10px; }

/* The instrument is decorative reinforcement, never the only place a number
   lives — below large screens it disappears and the two data columns stack. */
@container content (min-width: 900px) { .hero-instrument { display: block; } }
@container content (max-width: 640px) {
  .hero { padding: 18px; min-height: 0; }
  .hero-readouts, .hero-feed { width: 100%; }
}

/* Dashboard card row: weighted so each card's CONTENT fits, rather than
   each card being equal. */
.dash-row { display: grid; gap: 18px; grid-template-columns: 1fr; margin-top: 18px; }
@container content (min-width: 680px) { .dash-row { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@container content (min-width: 1080px) { .dash-row { grid-template-columns: 1.15fr 1fr 1fr 1.1fr; } }

.dash-card { display: flex; flex-direction: column; }
.dash-card-body { margin-top: 18px; flex: 1; }
/* The last card carries the CTA, pinned to the bottom so the page ends on
   an action. */
.dash-card-cta { margin-top: auto; padding-top: 18px; }

/* Feed row — every signal is a target. */
.feed-item {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  width: 100%;
  text-align: left;
  padding: 10px 12px;
  border-radius: 10px;
  transition: background 0.14s var(--ease);
}
.feed-item:hover:not(:disabled) { background: hsl(var(--foreground) / 0.06); }
.feed-item:disabled { cursor: default; }
.feed-dot { width: 6px; height: 6px; border-radius: 99px; margin-top: 5px; flex: none; }
.feed-body { min-width: 0; flex: 1; }
.feed-title { font-size: 12.5px; font-weight: 500; }
.feed-meta { font-family: var(--font-mono); font-size: 10.5px; color: hsl(var(--muted-foreground)); margin-top: 2px; }

/* ── Domain card — a scored area, linking to its page ── */
.domain-card { display: flex; flex-direction: column; gap: 12px; }
.domain-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.domain-counts { display: flex; gap: 12px; font-family: var(--font-mono); font-size: 10.5px; }
.domain-count { display: inline-flex; align-items: center; gap: 5px; color: hsl(var(--muted-foreground)); }
.domain-count::before { content: ''; width: 6px; height: 6px; border-radius: 99px; background: currentColor; }
.domain-count-fail::before { background: hsl(var(--signal-risk)); }
.domain-count-warn::before { background: hsl(var(--signal-watch)); }
.domain-count-pass::before { background: hsl(var(--signal-ok)); }
.domain-count-gap::before  { background: hsl(var(--signal-data)); }

/* A chip that navigates. */
.chip-link { transition: border-color 0.14s var(--ease), color 0.14s var(--ease); }
.chip-link:hover { color: hsl(var(--signal-ok-ink)); }

/* Stat block used inside a card where an inset tile would be too heavy. */
.stat { display: flex; flex-direction: column; gap: 4px; }
.stat-value { font-family: var(--font-display); font-size: 30px; font-weight: 300; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat-label { font-size: 11px; color: hsl(var(--muted-foreground)); }

/* ══════════════════════════════════════════════════════════════════
   THE GROUNDING SURFACE — one row per source Copilot can reason over.
   Bar WIDTH encodes breadth of reach; bar FILL encodes whether a control
   constrains it. It answers "how far can Copilot see" at a glance, which
   is the real question behind every Copilot review.
   ══════════════════════════════════════════════════════════════════ */

.ground { display: flex; flex-direction: column; }

.ground-row {
  display: grid;
  grid-template-columns: 150px minmax(0, 1fr) 132px;
  gap: 16px;
  align-items: center;
  padding: 14px 18px;
  border-bottom: 1px solid hsl(var(--foreground) / 0.07);
}
.ground-row:last-child { border-bottom: none; }

.ground-source { display: flex; flex-direction: column; gap: 2px; }
.ground-name { font-weight: 500; font-size: 12.5px; }
.ground-kind { font-family: var(--font-mono); font-size: 10px; color: hsl(var(--muted-foreground)); }

.ground-track { position: relative; height: 26px; background: hsl(var(--foreground) / 0.06); border-radius: 7px; overflow: hidden; }
.ground-bar {
  position: absolute; inset: 0 auto 0 0;
  border-radius: 7px;
  display: flex; align-items: center;
  padding: 0 9px;
  font-family: var(--font-mono);
  font-size: 10px;
  white-space: nowrap;
  transition: width 0.6s var(--ease);
}
/* Open — nothing narrows what Copilot may read here. Solid. */
.ground-open { background: hsl(var(--signal-risk) / 0.16); border: 1px solid hsl(var(--signal-risk)); color: hsl(var(--signal-risk-ink)); }
/* Constrained — a control is actively narrowing reach. Hatched, so the
   state reads as a pattern and not only as a hue. */
.ground-constrained {
  background: repeating-linear-gradient(135deg, hsl(var(--signal-ok) / 0.2) 0 5px, transparent 5px 10px);
  border: 1px solid hsl(var(--signal-ok));
  color: hsl(var(--signal-ok-ink));
}
/* Partial — a control exists but does not fully bound the source. */
.ground-partial { background: hsl(var(--signal-watch) / 0.16); border: 1px solid hsl(var(--signal-watch)); color: hsl(var(--signal-watch-ink)); }
/* Unknown — we could not read it. Dashed and uncoloured: never safe-looking. */
.ground-unknown { background: transparent; border: 1px dashed hsl(var(--border) / 0.3); color: hsl(var(--muted-foreground)); }

.ground-control { font-size: 11px; color: hsl(var(--muted-foreground)); text-align: right; }

/* ── The audience ladder ──
   Six discrete steps, filled to the tier this tenant's settings actually
   permit. Deliberately NOT a proportional bar: a continuous fill reads as a
   measurement, and where no tenant-wide setting determines the audience there
   is nothing to measure. Unknown shows as empty outlines, never as zero. */
.ladder { display: flex; gap: 3px; align-items: stretch; height: 16px; }
.ladder-step {
  flex: 1;
  min-width: 6px;
  border-radius: 2px;
  border: 1px solid hsl(var(--border) / 0.16);
  background: transparent;
}
.ladder-on { border-color: transparent; }
.ladder-ok    { background: hsl(var(--signal-ok)); }
.ladder-watch { background: hsl(var(--signal-watch)); }
.ladder-risk  { background: hsl(var(--signal-risk)); }
.ladder-unknown { border-style: dashed; }

.ground-value {
  display: block;
  margin-top: 6px;
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: hsl(var(--muted-foreground));
}

@container content (max-width: 740px) {
  .ground-row { grid-template-columns: 1fr; gap: 8px; }
  .ground-control { text-align: left; }
}

/* ══════════════════════════════════════════════════════════════════
   TABLES, LISTS, DRAWER, OVERLAYS
   ══════════════════════════════════════════════════════════════════ */

.table-wrap { overflow-x: auto; }
.table { font-size: 12.5px; min-width: 640px; }
.table thead th {
  text-align: left;
  padding: 9px 14px;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
  border-bottom: 1px solid hsl(var(--border) / 0.09);
  white-space: nowrap;
  background: hsl(var(--card));
  position: sticky; top: 0; z-index: 2;
}
.table tbody td { padding: 11px 14px; border-bottom: 1px solid hsl(var(--foreground) / 0.07); vertical-align: top; }
.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr[data-clickable] { cursor: pointer; transition: background 0.12s var(--ease); }
.table tbody tr[data-clickable]:hover { background: hsl(var(--foreground) / 0.04); }

.cell-title { font-weight: 500; }
.cell-sub { font-family: var(--font-mono); font-size: 10.5px; color: hsl(var(--muted-foreground)); margin-top: 2px; }
.cell-shrink { width: 1%; white-space: nowrap; }
.cell-value { font-family: var(--font-mono); font-size: 11px; color: hsl(var(--muted-foreground)); }
.cell-arrow { color: hsl(var(--muted-foreground)); padding: 0 4px; }

.list-row {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  text-align: left;
  padding: 13px 18px;
  border-bottom: 1px solid hsl(var(--foreground) / 0.07);
  transition: background 0.12s var(--ease);
}
.list-row:last-child { border-bottom: none; }
.list-row:hover { background: hsl(var(--foreground) / 0.04); }

/* ── Settings row: value + the Graph request that produced it ── */
.settings { display: flex; flex-direction: column; }
.setting {
  display: grid;
  grid-template-columns: minmax(200px, 1.6fr) minmax(130px, 0.9fr) minmax(180px, 1.3fr);
  gap: 16px;
  align-items: start;
  padding: 14px 18px;
  border-bottom: 1px solid hsl(var(--foreground) / 0.07);
}
.setting:last-child { border-bottom: none; }
.setting:hover { background: hsl(var(--foreground) / 0.03); }
.setting-name { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.setting-title { font-weight: 500; font-size: 12.5px; }
.setting-detail { font-size: 11px; color: hsl(var(--muted-foreground)); line-height: 1.45; }
.setting-value { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.setting-raw { font-family: var(--font-mono); font-size: 11px; word-break: break-word; }
.setting-raw-off { color: hsl(var(--muted-foreground)); }
.setting-origin { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.setting-endpoint { font-family: var(--font-mono); font-size: 10px; color: hsl(var(--muted-foreground)); word-break: break-all; line-height: 1.45; }
.setting-endpoint-none { font-family: var(--font-mono); font-size: 10px; color: hsl(var(--muted-foreground)); display: inline-flex; align-items: center; gap: 8px; }
.setting-endpoint-none::before, .setting-endpoint-none::after { content: ''; flex: 1; height: 1px; background: hsl(var(--border) / 0.18); min-width: 8px; }
.setting-where { font-size: 10.5px; color: hsl(var(--muted-foreground)); }
@container content (max-width: 740px) { .setting { grid-template-columns: 1fr; gap: 8px; } }

/* ── Framework tree ── */
.fw-section { border: 1px solid hsl(var(--border) / 0.09); border-radius: var(--r-lg); overflow: hidden; background: hsl(var(--card)); }
.fw-section + .fw-section { margin-top: 14px; }
.fw-section-head { display: flex; align-items: center; gap: 12px; padding: 14px 18px; background: hsl(var(--foreground) / 0.035); border-bottom: 1px solid hsl(var(--foreground) / 0.07); }
.fw-num { font-family: var(--font-mono); font-size: 11px; color: hsl(var(--signal-ok-ink)); min-width: 34px; }
.fw-title { font-family: var(--font-display); font-size: 15px; font-weight: 600; flex: 1; }
.fw-item { display: grid; grid-template-columns: 66px minmax(0, 1fr) 84px 104px; gap: 12px; align-items: baseline; padding: 13px 18px; border-bottom: 1px solid hsl(var(--foreground) / 0.07); width: 100%; text-align: left; transition: background 0.12s var(--ease); }
.fw-item:last-child { border-bottom: none; }
.fw-item:hover { background: hsl(var(--foreground) / 0.04); }
.fw-item-ref { font-family: var(--font-mono); font-size: 11px; color: hsl(var(--muted-foreground)); }
.fw-item-body { min-width: 0; }
.fw-item-title { font-size: 12.5px; font-weight: 500; }
.fw-item-actual { font-family: var(--font-mono); font-size: 10.5px; color: hsl(var(--muted-foreground)); margin-top: 2px; word-break: break-word; }
.fw-item-sev, .fw-item-plan { display: block; }
@container content (max-width: 640px) { .fw-item { grid-template-columns: 44px 1fr; } .fw-item-sev, .fw-item-plan { display: none; } }

/* ── Inputs ── */
.input, .select {
  padding: 6px 11px;
  background: hsl(var(--input));
  border: 1px solid hsl(var(--border) / 0.12);
  border-radius: 9px;
  font-size: 12.5px;
  min-width: 0;
}
.input::placeholder { color: hsl(var(--muted-foreground)); }
.input:focus, .select:focus { outline: none; border-color: hsl(var(--ring) / 0.6); }
textarea.input { width: 100%; resize: vertical; min-height: 62px; line-height: 1.45; font-family: inherit; }
input.input { width: 100%; }
.input-search { flex: 1; min-width: 180px; }
.select { cursor: pointer; }
.filters { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }

/* ── Key/value ── */
.kv { display: grid; grid-template-columns: minmax(110px, auto) 1fr; gap: 6px 16px; font-size: 12.5px; }
.kv dt { color: hsl(var(--muted-foreground)); font-size: 11px; }
.kv dd { margin: 0; word-break: break-word; }

/* ── Drawer ── */
.drawer-overlay { position: fixed; inset: 0; background: hsl(var(--brand-black) / 0.45); z-index: 40; animation: fade-in 0.16s var(--ease); }
.drawer {
  position: fixed; top: 0; right: 0; bottom: 0;
  width: min(560px, 100vw);
  background: hsl(var(--popover));
  border-left: 1px solid hsl(var(--border) / 0.14);
  z-index: 50;
  overflow-y: auto;
  box-shadow: var(--shadow-strong);
  animation: slide-in 0.24s var(--ease);
}
@keyframes slide-in { from { translate: 26px 0; opacity: 0; } }
.drawer-head { position: sticky; top: 0; z-index: 2; display: flex; align-items: flex-start; gap: 12px; padding: 18px; background: hsl(var(--popover)); border-bottom: 1px solid hsl(var(--foreground) / 0.07); }
.drawer-body { padding: 20px; display: flex; flex-direction: column; gap: 24px; }
.drawer-close { color: hsl(var(--muted-foreground)); padding: 4px; flex: none; }
.drawer-close:hover { color: hsl(var(--foreground)); }
.d-section { display: flex; flex-direction: column; gap: 8px; }
.d-section-title { font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: hsl(var(--muted-foreground)); }

.code {
  font-family: var(--font-mono); font-size: 11px;
  background: hsl(var(--foreground) / 0.05);
  border: 1px solid hsl(var(--border) / 0.09);
  border-radius: 9px;
  padding: 12px;
  white-space: pre-wrap; word-break: break-word;
  max-height: 260px; overflow: auto;
}
.code-method { color: hsl(var(--signal-ok-ink)); font-weight: 600; }
.note { border-left: 2px solid hsl(var(--signal-watch)); background: hsl(var(--signal-watch) / 0.1); padding: 8px 12px; border-radius: 0 7px 7px 0; font-size: 11px; }

/* ── Banner ── */
.banner {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 14px 18px;
  border: 1px solid hsl(var(--border) / 0.09);
  border-left: 2px solid hsl(var(--signal-watch));
  border-radius: var(--r-lg);
  background: hsl(var(--card));
  font-size: 12.5px;
}
.banner-info { border-left-color: hsl(var(--signal-data)); }
.banner-risk { border-left-color: hsl(var(--signal-risk)); }
/* The watch tone was already assumed here — .banner-ic below defaults to
   --signal-watch-ink — but the accent rule was never written, so a warn banner
   rendered with the same flat border as its own edges. */
.banner-warn { border-left-color: hsl(var(--signal-watch)); }
.banner-ic { font-family: var(--font-mono); flex: none; color: hsl(var(--signal-watch-ink)); }
.banner-info .banner-ic { color: hsl(var(--signal-data-ink)); }
.banner-risk .banner-ic { color: hsl(var(--signal-risk-ink)); }

/* ── Empty state — designed, never blank ── */
.empty {
  padding: 34px 20px;
  text-align: center;
  border: 1px dashed hsl(var(--border) / 0.16);
  border-radius: var(--r-lg);
  color: hsl(var(--muted-foreground));
  font-size: 12.5px;
}
.empty-ic {
  width: 48px; height: 48px;
  border-radius: 12px;
  background: hsl(var(--foreground) / 0.05);
  display: grid; place-items: center;
  margin: 0 auto 12px;
  color: hsl(var(--muted-foreground));
  font-size: 18px;
}
.empty-title { font-family: var(--font-display); font-size: 14px; font-weight: 600; color: hsl(var(--foreground)); margin-bottom: 5px; }

/* ── Skeleton ── */
.skeleton { background: linear-gradient(90deg, hsl(var(--foreground) / 0.05) 25%, hsl(var(--foreground) / 0.1) 50%, hsl(var(--foreground) / 0.05) 75%); background-size: 200% 100%; animation: shimmer 1.4s infinite linear; border-radius: 7px; }
@keyframes shimmer { to { background-position: -200% 0; } }
.skeleton-line { height: 11px; margin-bottom: 9px; }

/* ── Toast ── */
.toast {
  position: fixed; right: 20px; bottom: 20px; z-index: 60;
  padding: 12px 16px;
  border-radius: var(--r-lg);
  font-size: 12.5px;
  animation: fade-up 0.22s var(--ease);
  max-width: min(420px, calc(100vw - 40px));
  border-left-width: 2px;
}
.toast-ok  { border-left-color: hsl(var(--signal-ok)); }
.toast-err { border-left-color: hsl(var(--signal-risk)); }

/* ── Info tip ──
   Opens on hover AND on keyboard focus and tap — focus-visible alone is a
   browser heuristic that covers only the first of those. */
.tip { position: relative; display: inline-flex; vertical-align: middle; }
.tip-btn {
  width: 15px; height: 15px;
  border-radius: 99px;
  border: 1px solid hsl(var(--border) / 0.28);
  color: hsl(var(--muted-foreground));
  font-family: var(--font-mono); font-size: 9px; line-height: 1;
  display: grid; place-items: center;
  transition: color 0.14s var(--ease), border-color 0.14s var(--ease);
}
.tip-btn:hover, .tip-btn:focus-visible { color: hsl(var(--signal-ok-ink)); border-color: hsl(var(--signal-ok) / 0.6); }
.tip-body {
  position: absolute; top: calc(100% + 8px); left: -8px; z-index: 30;
  width: max-content; max-width: min(360px, 78vw);
  padding: 13px;
  background: hsl(var(--popover));
  border: 1px solid hsl(var(--border) / 0.14);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-strong);
  color: hsl(var(--popover-foreground));
  font-family: var(--font-sans);
  font-size: 11.5px; line-height: 1.5;
  text-transform: none; letter-spacing: 0;
  opacity: 0; visibility: hidden; translate: 0 -3px;
  transition: opacity 0.16s var(--ease), translate 0.16s var(--ease), visibility 0.16s;
  pointer-events: none;
}
.tip:hover .tip-body, .tip:focus-within .tip-body { opacity: 1; visibility: visible; translate: 0 0; pointer-events: auto; }

/* Anchored to the right edge instead. Used by tips in the last column, where a
   360px panel opening leftwards would run off the window on a narrow screen. */
.tip-end .tip-body { left: auto; right: -8px; }

/* Tip internals are SPANS, never dl/hr/div.
   A tip often sits inside a <p> (a kicker, a caption). The HTML parser
   auto-closes a <p> at the first block-level child, which ejects everything
   after it from the absolutely-positioned .tip-body — so the tooltip renders
   inline and permanently open. Inline-level elements made to behave as blocks
   are immune to that wherever the tip is placed. */
.tip-grid { display: grid; grid-template-columns: auto 1fr; gap: 3px 12px; margin-top: 8px; }
.tip-k { font-family: var(--font-mono); color: hsl(var(--muted-foreground)); }
.tip-v { display: block; }
.tip-rule { display: block; border-top: 1px solid hsl(var(--border) / 0.14); margin: 9px 0; }
.tip-p { display: block; margin-top: 8px; }

/* ── Login ── */
.login { min-height: 100vh; display: grid; place-items: center; padding: 20px; }
.login-card { width: min(430px, 100%); display: flex; flex-direction: column; gap: 16px; }
.login-scope { display: flex; gap: 8px; font-size: 11px; color: hsl(var(--muted-foreground)); }
.login-scope-ic { color: hsl(var(--signal-ok-ink)); font-family: var(--font-mono); flex: none; }
.login-err { border-left: 2px solid hsl(var(--signal-risk)); background: hsl(var(--signal-risk) / 0.1); padding: 8px 12px; font-size: 11.5px; border-radius: 0 7px 7px 0; }
.ms-logo { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5px; width: 14px; height: 14px; flex: none; }
.ms-logo span:nth-child(1) { background: #f25022; }
.ms-logo span:nth-child(2) { background: #7fba00; }
.ms-logo span:nth-child(3) { background: #00a4ef; }
.ms-logo span:nth-child(4) { background: #ffb900; }

/* ══════════════════════════════════════════════════════════════════
   KNOWLEDGE BASE
   Two sources, two visual treatments. A page written here is a card on the
   standard surface; a Learn result is a link, and reads like one — the
   difference has to survive a glance, because mistaking a colleague's note
   for Microsoft's documentation is the failure mode that matters.
   ══════════════════════════════════════════════════════════════════ */

.kb-search { position: relative; margin-bottom: 4px; }

.kb-field {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 15px;
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border) / 0.12);
  border-radius: var(--r-lg);
  transition: border-color 0.14s var(--ease);
}
.kb-field:focus-within { border-color: hsl(var(--border) / 0.28); }
.kb-field-ic { display: grid; place-items: center; color: hsl(var(--muted-foreground)); flex: none; }
.kb-field-ic svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }

.kb-input {
  flex: 1;
  min-width: 0;
  border: none;
  background: none;
  outline: none;
  font-size: 14.5px;
  color: hsl(var(--foreground));
}
.kb-input::placeholder { color: hsl(var(--muted-foreground)); }
.kb-input::-webkit-search-cancel-button { -webkit-appearance: none; }

.kb-field-spin { display: grid; place-items: center; color: hsl(var(--muted-foreground)); flex: none; }
.kb-field-spin svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.8; animation: spin 0.9s linear infinite; }

/* Suggestions float over the results rather than pushing them down — the
   list changes on every keystroke and a moving page is unreadable. */
.kb-auto {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  z-index: 30;
  max-height: 340px;
  overflow-y: auto;
  padding: 6px;
  background: hsl(var(--popover));
  border: 1px solid hsl(var(--border) / 0.14);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-strong);
}
.kb-auto-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  cursor: pointer;
}
.kb-auto-row[data-active] { background: hsl(var(--foreground) / 0.07); }
.kb-auto-ic { display: grid; place-items: center; flex: none; color: hsl(var(--muted-foreground)); }
.kb-auto-ic svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.kb-auto-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.kb-auto-label { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kb-auto-meta { font-size: 11px; color: hsl(var(--muted-foreground)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ── A page written here ── */
.kb-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }

.kb-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 16px;
  text-align: left;
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border) / 0.09);
  border-radius: var(--r-lg);
  transition: border-color 0.16s var(--ease), background 0.16s var(--ease);
}
.kb-card:hover { border-color: hsl(var(--border) / 0.2); background: hsl(var(--foreground) / 0.02); }
.kb-card-title { font-family: var(--font-display); font-size: 14px; font-weight: 600; }
.kb-card-sum { font-size: 12px; color: hsl(var(--muted-foreground)); line-height: 1.45; }
.kb-card-foot { display: flex; align-items: center; gap: 5px; flex-wrap: wrap; margin-top: 4px; }
.kb-card-by { font-family: var(--font-mono); font-size: 10px; color: hsl(var(--muted-foreground)); }

.kb-row {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  width: 100%;
  padding: 15px 18px;
  text-align: left;
  background: hsl(var(--card));
  border: 1px solid hsl(var(--border) / 0.09);
  border-radius: var(--r-lg);
  transition: border-color 0.16s var(--ease);
}
.kb-row:hover { border-color: hsl(var(--border) / 0.2); }
.kb-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.kb-row-title { font-family: var(--font-display); font-size: 14px; font-weight: 600; }
.kb-row-sum { font-size: 12px; color: hsl(var(--muted-foreground)); }
.kb-row-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; flex: none; }

/* Compact form, inside a finding drawer. */
.kb-mini {
  display: flex;
  flex-direction: column;
  gap: 3px;
  width: 100%;
  padding: 10px 12px;
  text-align: left;
  border: 1px solid hsl(var(--border) / 0.12);
  border-radius: var(--r-sm);
  transition: border-color 0.14s var(--ease);
}
.kb-mini:hover { border-color: hsl(var(--border) / 0.26); }
.kb-mini-title { font-size: 12.5px; font-weight: 500; }
.kb-mini-sum { font-size: 11px; color: hsl(var(--muted-foreground)); }

/* ── A Microsoft Learn result — a link, and it looks like one ── */
.kb-learn {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 13px 16px;
  border-left: 2px solid hsl(var(--border) / 0.16);
  border-radius: 0 var(--r-sm) var(--r-sm) 0;
  transition: border-color 0.14s var(--ease), background 0.14s var(--ease);
}
.kb-learn:hover { border-left-color: hsl(var(--foreground) / 0.4); background: hsl(var(--foreground) / 0.025); }
/* The result title is a button now — it reads the article inside Guardian
   rather than navigating away — so it has to shed the button defaults and
   look like the link it replaced. */
.kb-learn-head {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: 0;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.kb-learn-title { font-size: 13.5px; font-weight: 500; text-decoration: underline; text-underline-offset: 2px; }
.kb-learn-desc { font-size: 12px; color: hsl(var(--muted-foreground)); line-height: 1.5; }
.kb-learn-url { font-family: var(--font-mono); font-size: 10.5px; color: hsl(var(--muted-foreground)); }
.kb-learn-foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 2px; }


/* ── Attribution on an imported article ──
   This is somebody else's text on your server. The block says whose, under
   what licence, and how old — and it is styled to be read, not skipped. A
   copy with no open licence behind it says so in the warning tone rather
   than looking identical to a licensed one. */
.attrib {
  padding: 14px 16px;
  border-radius: var(--r-sm);
  border-left: 2px solid hsl(var(--signal-ok) / 0.5);
  background: hsl(var(--foreground) / 0.035);
}
.attrib-bare { border-left-color: hsl(var(--signal-watch) / 0.6); }
.attrib-line { font-size: 12.5px; line-height: 1.55; }
.attrib-line a { text-decoration: underline; text-underline-offset: 2px; }
.attrib-meta { margin-top: 6px; font-family: var(--font-mono); font-size: 10.5px; color: hsl(var(--muted-foreground)); }
.attrib-stale {
  margin-top: 8px;
  font-size: 12px;
  color: hsl(var(--signal-watch-ink));
}

/* Tables inside rendered Markdown — Learn leans on them heavily. */
.md-table-wrap { overflow-x: auto; }
.md .md-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.md .md-table th,
.md .md-table td {
  text-align: left;
  vertical-align: top;
  padding: 8px 10px;
  border-bottom: 1px solid hsl(var(--border) / 0.1);
}
.md .md-table th { font-weight: 600; color: hsl(var(--muted-foreground)); font-size: 11px; }

.kb-editor { font-family: var(--font-mono); font-size: 12px; line-height: 1.6; resize: vertical; }

/* ── Rendered Markdown ──
   Deliberately plain. A knowledge page is read for what it says, and every
   flourish here competes with the tenant data on the same screen. */
.md { display: flex; flex-direction: column; gap: 12px; font-size: 13px; line-height: 1.6; }
.md .md-h { font-family: var(--font-display); font-weight: 600; margin-top: 6px; }
.md h2.md-h { font-size: 16px; }
.md h3.md-h { font-size: 14.5px; }
.md h4.md-h, .md h5.md-h { font-size: 13px; }
.md p { color: hsl(var(--card-foreground)); }
.md .md-list { display: flex; flex-direction: column; gap: 5px; padding-left: 20px; }
.md .md-list li { list-style: disc; }
.md ol.md-list li { list-style: decimal; }
.md .md-link { text-decoration: underline; text-underline-offset: 2px; }
.md .md-code {
  font-family: var(--font-mono);
  font-size: 11.5px;
  padding: 2px 5px;
  border-radius: 5px;
  background: hsl(var(--foreground) / 0.07);
}
.md .md-pre {
  margin: 0;
  padding: 13px 15px;
  border-radius: var(--r-sm);
  background: hsl(var(--foreground) / 0.05);
  overflow-x: auto;
  font-family: var(--font-mono);
  font-size: 11.5px;
  line-height: 1.55;
}
.md blockquote {
  margin: 0;
  padding: 2px 0 2px 14px;
  border-left: 2px solid hsl(var(--border) / 0.2);
  color: hsl(var(--muted-foreground));
}
.md .md-hr { border: none; border-top: 1px solid hsl(var(--border) / 0.12); margin: 4px 0; }

/* ══════════════════════════════════════════════════════════════════
   COMMAND PALETTE — ⌘K
   Anchored near the top rather than centred: the list grows downwards, so a
   centred panel would shift the input under the reader's eye as they type.
   ══════════════════════════════════════════════════════════════════ */

.kbd {
  font-family: var(--font-mono);
  font-size: 10px;
  line-height: 1;
  padding: 3px 5px;
  border-radius: 5px;
  border: 1px solid hsl(var(--border) / 0.16);
  background: hsl(var(--foreground) / 0.06);
  color: hsl(var(--muted-foreground));
  white-space: nowrap;
}

.pal-overlay {
  position: fixed;
  inset: 0;
  background: hsl(var(--brand-black) / 0.5);
  z-index: 60;
  animation: fade-in 0.14s var(--ease);
}

.pal {
  position: fixed;
  top: 12vh;
  left: 50%;
  translate: -50% 0;
  width: min(620px, calc(100vw - 32px));
  max-height: 70vh;
  display: flex;
  flex-direction: column;
  background: hsl(var(--popover));
  border: 1px solid hsl(var(--border) / 0.14);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-strong);
  z-index: 70;
  overflow: hidden;
  animation: pal-in 0.16s var(--ease);
}
@keyframes pal-in { from { translate: -50% -8px; opacity: 0; } }

.pal-field {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 13px 15px;
  border-bottom: 1px solid hsl(var(--foreground) / 0.07);
  flex: none;
}
.pal-field-ic { display: grid; place-items: center; color: hsl(var(--muted-foreground)); flex: none; }
.pal-field-ic svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }

.pal-input {
  flex: 1;
  min-width: 0;
  border: none;
  background: none;
  outline: none;
  font-size: 14px;
  color: hsl(var(--foreground));
}
.pal-input::placeholder { color: hsl(var(--muted-foreground)); }

.pal-list { overflow-y: auto; padding: 6px; flex: 1; min-height: 0; }

.pal-group {
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
  padding: 10px 10px 5px;
}
.pal-group:first-child { padding-top: 4px; }

.pal-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--r-sm);
  cursor: pointer;
}
/* Hover is not a second highlight: the pointer moves the same cursor the
   arrow keys move, so there is only ever one selected row. */
.pal-row[data-active] { background: hsl(var(--foreground) / 0.07); }
.pal-row-ic { display: grid; place-items: center; flex: none; color: hsl(var(--muted-foreground)); }
.pal-row-ic svg { width: 15px; height: 15px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.pal-row[data-active] .pal-row-ic { color: hsl(var(--foreground)); }

.pal-row-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pal-row-label { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pal-row-meta {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: hsl(var(--muted-foreground));
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pal-empty { padding: 26px 14px; text-align: center; color: hsl(var(--muted-foreground)); font-size: 12.5px; }

.pal-foot {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 8px 14px;
  border-top: 1px solid hsl(var(--foreground) / 0.07);
  font-size: 11px;
  color: hsl(var(--muted-foreground));
  flex: none;
}
.pal-foot .kbd { margin-right: 3px; }
.pal-foot-fill { flex: 1; text-align: right; font-family: var(--font-mono); font-size: 10.5px; }

/* The search affordance in the top bar — the palette's only visible handle. */
.search-btn { gap: 8px; color: hsl(var(--muted-foreground)); }
.search-btn:hover { color: hsl(var(--foreground)); }
.search-btn svg { width: 14px; height: 14px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
@media (max-width: 1100px) { .search-btn-label, .search-btn .kbd { display: none; } .search-btn { padding: 7px; } }

/* ── Shortcut sheet ── */
.sheet {
  position: fixed;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  width: min(560px, calc(100vw - 32px));
  max-height: 80vh;
  overflow-y: auto;
  background: hsl(var(--popover));
  border: 1px solid hsl(var(--border) / 0.14);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-strong);
  z-index: 70;
  animation: pal-in 0.16s var(--ease);
}
@supports (translate: -50% -50%) { .sheet { animation-name: sheet-in; } }
@keyframes sheet-in { from { opacity: 0; } }

.sheet-head {
  position: sticky;
  top: 0;
  display: flex;
  align-items: flex-start;
  gap: 12px;
  padding: 18px;
  background: hsl(var(--popover));
  border-bottom: 1px solid hsl(var(--foreground) / 0.07);
}
.sheet-ic { display: grid; place-items: center; color: hsl(var(--muted-foreground)); flex: none; margin-top: 2px; }
.sheet-ic svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

.sheet-body { padding: 18px; display: flex; flex-direction: column; gap: 20px; }
.sheet-group { display: flex; flex-direction: column; gap: 2px; }
.sheet-group-title {
  font-family: var(--font-mono);
  font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
  margin-bottom: 6px;
}
.sheet-row { display: flex; align-items: center; gap: 12px; padding: 5px 0; }
.sheet-keys { display: flex; gap: 3px; flex: none; width: 74px; }
.sheet-label { font-size: 12.5px; color: hsl(var(--muted-foreground)); }

/* ══════════════════════════════════════════════════════════════════
   PRINT — the Word / PDF surface.

   Light only, and deliberately NOT the application's palette: this matches
   the company's Word template, so a print-to-PDF and a Word export of the
   same report look like the same document.

   The values here are read from the template itself, not from the written
   spec — the two disagree, and the template is what the company sends:
   H1 is Franie Light 16pt in #F3B61F (not Aptos 18pt in #F3B620), body copy
   is Heebo 11pt, and captions are 9pt. Licensed faces fall back gracefully.
   ══════════════════════════════════════════════════════════════════ */
@media print {
  :root, .dark, .panel-dark, .panel-hero {
    --background: 0 0% 100%;
    --foreground: 0 0% 9%;          /* #181818 ink */
    --card: 0 0% 100%;
    --card-foreground: 0 0% 9%;
    --popover: 0 0% 100%;
    --muted-foreground: 0 0% 50%;   /* #7F7F7F caption */
    --border: 0 0% 50%;
    --accent: 0 0% 96%;
    /* One accent, and it is the template's yellow. */
    --signal-ok-ink: 43 89% 54%;    /* #F3B61F */
    --signal-watch-ink: 17 84% 30%;
    --signal-risk-ink: 351 66% 36%;
    --signal-data-ink: 218 44% 36%;
    color-scheme: light;
  }

  body {
    background: #fff;
    font-family: 'Heebo', 'Aptos', ui-sans-serif, system-ui, sans-serif;
    font-size: 11pt;
    color: #181818;
  }

  /* Headings take the template's display face and its yellow H1. */
  h1, .t-page, .page-header h1 {
    font-family: 'Franie Light', 'Franie', 'Aptos Display', sans-serif;
    font-size: 16pt;
    color: #F3B61F;
  }
  h2, .t-section { font-size: 14pt; color: #181818; }
  h3, .t-title { font-size: 12pt; color: #181818; }

  /* Subtitles and tags: Eurostile, ALL CAPS — this surface's convention, not
     the screen's monospace kicker. */
  .kicker, .page-header .kicker {
    font-family: 'Eurostile Extended', 'Eurostile', 'Aptos Display', sans-serif;
    text-transform: uppercase;
    color: #7F7F7F;
    letter-spacing: 0.08em;
  }

  .t-label, .setting-endpoint, .cell-sub { font-size: 9pt; color: #7F7F7F; }
  .code, .t-mono, pre, code { font-family: 'Consolas', ui-monospace, monospace; font-size: 10pt; }
  .code, pre { background: #DFDFDF; }

  /* Square bullets — never dots or circles on this surface. */
  ul, .md-list { list-style: square; }
  ul li, .md-list li { list-style: square; }

  /* Table headers: the template's yellow, with dark ink on it. */
  .table thead th, .md-table th {
    background: #F3B61F !important;
    color: #181818 !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
  .table, .md-table { border-collapse: collapse; }
  .table td, .table th, .md-table td, .md-table th { border: 1px solid #7F7F7F; }

  .shell { display: block; height: auto; overflow: visible; }
  .shell-main { overflow: visible; }
  .topnav, .sidenav, .filters, .drawer, .drawer-overlay, .pal, .pal-overlay, .sheet, .toast, .tip, .no-print { display: none !important; }
  .shell-inner { max-width: none; padding: 0; }
  .panel-hero, .panel-dark { background: #fff !important; border: 1px solid #7F7F7F; }
  .hero-instrument { display: none !important; }
  .glass, .fw-section, .setting, .feed-item, .dash-card { break-inside: avoid; }
  .table thead th { position: static; }
  a[href^='http']::after { content: ' (' attr(href) ')'; font-size: 0.75em; color: #7F7F7F; }

  /* The classification label, on every printed page. */
  @page { margin: 18mm 16mm 20mm; }
  .shell::after {
    content: 'This document is classified as Nedscaper General Use';
    position: fixed;
    bottom: 8mm;
    left: 0;
    font-size: 8pt;
    color: #7F7F7F;
  }
}

/* A framework card doubles as the selector for the list below it. */
.grc-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  transition: border-color 0.16s var(--ease), background 0.16s var(--ease);
}
.grc-card:hover { border-color: hsl(var(--border) / 0.22); }
.grc-card[data-active] {
  border-color: hsl(var(--border) / 0.3);
  background: hsl(var(--foreground) / 0.03);
}

/* Two equally-weighted figures on a GRC card: coverage and pass rate. One
   without the other misleads — high coverage with a low pass rate is the
   common case, and the one worth seeing at a glance. */
.grc-figures { display: flex; gap: 16px; width: 100%; margin-top: 10px; }
.grc-figure { flex: 1; min-width: 0; display: block; }
.grc-figure-label {
  display: block;
  font-size: 10.5px;
  color: hsl(var(--muted-foreground));
  margin: 2px 0 8px;
}
.grc-card-foot { margin-top: 10px; display: block; text-align: left; }

/* ── Copilot readiness checklist ──
   One row per item, with where its answer comes from stated on the row rather
   than in a legend — a checklist whose provenance you have to look up is a
   checklist people tick. */
.ready-item {
  padding: 15px 18px;
  border-bottom: 1px solid hsl(var(--border) / 0.08);
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.ready-item:last-child { border-bottom: none; }
.ready-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }
.ready-text { font-size: 13px; line-height: 1.45; }
.ready-note { font-size: 12px; color: hsl(var(--muted-foreground)); line-height: 1.5; max-width: 84ch; }
.ready-checks { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.ready-where {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: hsl(var(--muted-foreground));
  padding-left: 10px;
  border-left: 2px solid hsl(var(--border) / 0.16);
}
.ready-record { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 3px; }
.ready-record .input { flex: 1; min-width: 160px; }
.ready-record .ready-by { flex: none; width: 110px; }

/* ── What Microsoft changed ──────────────────────────────────────────
   A diff is not a health signal, so it does not get one of the four
   signal colours as its meaning. The gutter mark and the border weight
   carry the difference; the tints only reinforce it, which is also what
   keeps this readable in monochrome and to a colourblind reader.

   Where a tint is used it reads in the system's own vocabulary: `data`
   for the wording Microsoft used to publish — from somewhere else,
   never ours — and `ok` for the wording now in force. */

.diff { display: flex; flex-direction: column; gap: 14px; }

.diff-hunk {
  border: 1px solid hsl(var(--border) / 0.12);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.diff-hunk-head {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: hsl(var(--muted-foreground));
  padding: 5px 10px;
  background: hsl(var(--border) / 0.06);
  border-bottom: 1px solid hsl(var(--border) / 0.1);
}

.diff-rows { overflow-x: auto; }

.diff-row {
  display: flex;
  gap: 8px;
  font-family: var(--font-mono);
  font-size: 11.5px;
  line-height: 1.55;
  padding: 1px 10px 1px 0;
  border-left: 2px solid transparent;
  white-space: pre;
}

.diff-row .diff-mark {
  flex: none;
  width: 16px;
  text-align: center;
  color: hsl(var(--muted-foreground));
  user-select: none;
}

.diff-row .diff-text { flex: 1; min-width: 0; }

.diff-add {
  border-left-color: hsl(var(--signal-ok));
  background: hsl(var(--signal-ok) / 0.08);
}
.diff-add .diff-mark { color: hsl(var(--signal-ok-ink)); }

.diff-remove {
  border-left-color: hsl(var(--signal-data));
  background: hsl(var(--signal-data) / 0.08);
}
.diff-remove .diff-mark { color: hsl(var(--signal-data-ink)); }
.diff-remove .diff-text { color: hsl(var(--muted-foreground)); }

.diff-context .diff-text { color: hsl(var(--muted-foreground)); }

.diff-empty {
  font-size: 12.5px;
  color: hsl(var(--muted-foreground));
  padding: 10px 0;
}

.change-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  width: 100%;
  text-align: left;
}
.change-size {
  font-family: var(--font-mono);
  font-size: 11px;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.change-added   { color: hsl(var(--signal-ok-ink)); }
.change-removed { color: hsl(var(--signal-data-ink)); }

/* ── An article on its own page ───────────────────────────────────────
   The drawer is a glance from inside a finding. This is the same text
   laid out to actually be read: one measure for prose, full width for
   the tables and code Learn articles are full of. */

.article-page {
  max-width: 78ch;
  margin: 0 auto;
  padding-bottom: 64px;
}

.article-title {
  font-size: clamp(26px, 3.4vw, 34px);
  font-weight: 600;
  line-height: 1.18;
  letter-spacing: -0.015em;
  margin: 6px 0 10px;
  text-wrap: balance;
}

.article-standfirst {
  font-size: 16px;
  line-height: 1.55;
  color: hsl(var(--muted-foreground));
  margin: 0 0 18px;
  max-width: 68ch;
}

/* Prose sits at a comfortable measure; anything that needs the room —
   tables, code, images — is allowed to use all of it and scroll. */
.article-body { margin-top: 22px; font-size: 15.5px; line-height: 1.7; }
.article-body > * { max-width: 72ch; }
.article-body > table,
.article-body > pre,
.article-body > .table-wrap { max-width: none; }
.article-body table { display: block; overflow-x: auto; max-width: 100%; }
.article-body pre { overflow-x: auto; }
.article-body h2 { margin-top: 34px; }
.article-body h3 { margin-top: 26px; }

.article-foot {
  margin-top: 40px;
  padding-top: 16px;
  border-top: 1px solid hsl(var(--border) / 0.12);
}

/* The drawer's sections sit flush; on the page they need air. */
.article-page .d-section { margin-top: 26px; }
.article-page .d-section h3 { margin-bottom: 8px; }

/* ── Who is signed in, bottom-left ────────────────────────────────────
   Collapsed to an initial; opens on hover, focus or click. The width is
   what animates, so the collapsed state is a circle and the open state a
   pill — no layout reflow of anything around it, because it is fixed. */

#userChip {
  position: fixed;
  left: 18px;
  bottom: 18px;
  z-index: 40;
}

.user-chip-face {
  display: flex;
  align-items: center;
  gap: 0;
  max-width: 40px;
  padding: 0;
  border: 1px solid hsl(var(--border) / 0.14);
  border-radius: 999px;
  background: hsl(var(--card));
  color: hsl(var(--card-foreground));
  box-shadow: 0 6px 20px hsl(0 0% 0% / 0.18);
  overflow: hidden;
  transition: max-width 220ms ease, gap 220ms ease, padding 220ms ease;
}

#userChip[data-open] .user-chip-face {
  max-width: 380px;
  gap: 10px;
  padding-right: 12px;
}

/* The identity itself is the button; the chip around it is a container now
   that it also holds a link, since an anchor inside a button is neither valid
   nor operable. */
.user-chip-id {
  display: flex;
  align-items: center;
  gap: inherit;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.user-chip-id:focus-visible,
.user-chip-link:focus-visible {
  outline: 2px solid hsl(var(--ring));
  outline-offset: 2px;
}

/* Appears with the rest of the chip. Kept out of the tab order and out of the
   accessibility tree while collapsed, so a keyboard user cannot land on a link
   that is not visible. */
.user-chip-link {
  flex: none;
  margin-left: 4px;
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid hsl(var(--border) / 0.16);
  font-size: 11.5px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: hsl(var(--muted-foreground));
  text-decoration: none;
  white-space: nowrap;
  opacity: 0;
  visibility: hidden;
  transition: opacity 180ms ease, color 140ms ease, border-color 140ms ease;
}

#userChip[data-open] .user-chip-link {
  opacity: 1;
  visibility: visible;
}

.user-chip-link:hover {
  color: hsl(var(--card-foreground));
  border-color: hsl(var(--border) / 0.4);
}

.user-chip-initials {
  flex: none;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 12.5px;
  letter-spacing: 0.02em;
  background: hsl(var(--signal-ok) / 0.16);
  color: hsl(var(--signal-ok-ink));
}

.user-chip-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 160ms ease;
}

#userChip[data-open] .user-chip-body { opacity: 1; }

.user-chip-name {
  font-size: 13px;
  font-weight: 550;
  line-height: 1.25;
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.user-chip-mail {
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: hsl(var(--muted-foreground));
  max-width: 240px;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* A chip that slides on every open is noise for anyone who asked for less
   motion; it still opens, just without the animation. */
@media (prefers-reduced-motion: reduce) {
  .user-chip-face,
  .user-chip-body { transition: none; }
}

@media print {
  #userChip { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   Page layout utilities.

   Spacing comes from the layout, not from margins on each block. The first
   version of this page set margin-top per element, and every block that
   forgot one sat flush against its neighbour — sections visibly inside each
   other with no air between them. A flex column with one gap cannot have that
   bug: nothing needs to remember anything.
   ═══════════════════════════════════════════════════════════════════ */

.page-stack { display: flex; flex-direction: column; gap: 26px; }

/* Groups that belong to one heading sit closer than separate sections do. */
.pv-group { display: flex; flex-direction: column; gap: 12px; }

/* Side-by-side cards. Never .dash-row — that grid is sized for the four
   readout tiles on the dashboard and squashes prose into columns. */
.pv-pair {
  display: grid;
  gap: 16px;
  grid-template-columns: 1fr;
  align-items: start;
}
@container content (min-width: 780px) { .pv-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

.pv-cards {
  display: grid;
  gap: 14px;
  grid-template-columns: 1fr;
}
@container content (min-width: 820px) { .pv-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* A card's own contents also get their spacing from a gap. */
.pv-card { display: flex; flex-direction: column; gap: 9px; }
.pv-card > * { margin: 0; }
.pv-card-head { display: flex; align-items: center; gap: 9px; flex-wrap: wrap; }

/* The toolbar sticks so the SIT filter stays reachable down a long table. */
.pv-toolbar {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: center;
  position: sticky;
  top: 0;
  z-index: 5;
  padding: 12px 0;
  background: hsl(var(--background));
}

.pv-toolbar .input { flex: 1 1 240px; min-width: 0; }
.pv-count { margin-left: auto; white-space: nowrap; }

/* A table is a container in its own right: it gets the card's border and
   radius, and scrolls inside it rather than pushing the page sideways. */
.table-card { border-radius: var(--r-lg); border: 1px solid hsl(var(--border) / 0.09); overflow: hidden; }
.table-card .table-wrap { max-height: 560px; overflow: auto; }
.table-card .table { min-width: 560px; margin: 0; }

.pv-phase-n {
  flex: none;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border-radius: 999px;
  background: hsl(var(--signal-data) / 0.16);
  color: hsl(var(--signal-data-ink));
  font-family: var(--font-mono);
  font-size: 12px;
}

/* Keyword starter lists — selectable in one gesture, with a copy button. */
.pv-terms {
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.7;
  word-break: break-word;
  padding: 10px 12px;
  border-radius: 10px;
  background: hsl(var(--foreground) / 0.04);
  border: 1px solid hsl(var(--border) / 0.09);
}

.pv-empty { padding: 26px; text-align: center; color: hsl(var(--muted-foreground)); }

/* A copyable block: the label and its button sit above the text, so the text
   itself stays a clean rectangle to select by hand if the clipboard is
   blocked. */
.pv-copy { display: flex; flex-direction: column; gap: 6px; }
.pv-copy-head { display: flex; align-items: center; gap: 10px; }
.pv-copy-btn { margin-left: auto; padding: 3px 10px; font-size: 11.5px; flex: none; }

/* Catalogue rows open a detail view in place. They are buttons, so they say so
   on hover and answer to the keyboard. */
.pv-row { cursor: pointer; }
.pv-row:hover { background: hsl(var(--foreground) / 0.03); }
.pv-row:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: -2px; }
.pv-row-name { color: hsl(var(--signal-data-ink)); }
.pv-detail-head { display: flex; gap: 10px; align-items: center; }

/* Each read sits as its own block so the cmdlet, its label and the reason it
   is the right one stay together rather than running into the next read. */
.pv-read { display: flex; flex-direction: column; gap: 6px; margin-top: 12px; }

/* A button that reads as a link: used where prose points at another part of
   the page, so it answers to the keyboard without looking like a control. */
.pv-inline-link {
  background: none; border: 0; padding: 0; font: inherit; cursor: pointer;
  color: hsl(var(--signal-data-ink)); font-weight: 600;
}
.pv-inline-link:hover { text-decoration: underline; }
.pv-inline-link:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; border-radius: 3px; }

/* Why a row matched a search term that appears nowhere on it. */
.pv-why { margin: 0 0 2px; color: hsl(var(--signal-data-ink)); }

/* A jump bar for the one tab long enough to need it. Buttons rather than
   anchors, so the page does not gain a history entry per section. */
.pv-jump { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 4px; }
.pv-jump-item {
  background: hsl(var(--foreground) / 0.04); border: 1px solid hsl(var(--border) / 0.09);
  border-radius: 999px; padding: 5px 13px; font-size: 12.5px; cursor: pointer;
  color: hsl(var(--muted-foreground)); font-family: inherit;
}
.pv-jump-item:hover { color: hsl(var(--foreground)); background: hsl(var(--foreground) / 0.07); }
.pv-jump-item:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; }

/* Scroll target that clears the sticky header. */
.pv-anchor { display: block; height: 0; scroll-margin-top: 96px; }
