/* =====================================================================
   guildmerge.css
   ---------------------------------------------------------------------
   Shared brand stylesheet for the Guildmerge HTML Output System.

   Source of truth:
     - .planning/phases/01-brand-shell-template/01-UI-SPEC.md
     - /Projects/DotJess website/BRAND-GUIDE.md (canonical DotJess brand)
     - /Projects/DotJess website/dotjess-visual-brand-guide.md

   If the spec and this file disagree, the spec wins and this file is wrong.
   If the spec and the BRAND-GUIDE disagree, the BRAND-GUIDE wins.

   Last updated: 2026-05-23 (Phase 1, rebrand on DotJess brand)

   Constraints (from project CLAUDE.md and UI-SPEC):
     - Vanilla CSS only, no preprocessors, no build step, no CDN
     - Self-hosted woff2 fonts only (Lato + Anonymous Pro), no Google Fonts
     - No JavaScript references, no @import, no https:// URLs
     - file:// safe, offline-capable from Dropbox
     - Page background is always white. No dark mode.
     - Australian English in comments (colour, behaviour, realise)
     - No em dashes anywhere in comments (en dashes acceptable)

   File layout:
      0. @font-face declarations (self-hosted woff2 in fonts/)
      1. :root tokens (DotJess palette, type scale, spacing)
      2. Universal base + reset
      3. Reduced-motion block (COG-01 ship blocker)
      4. Page shell (topbar, main, footer band)
      5. Wordmark (.wm) and topbar layout
      6. Skip link
      7. Focus styles
      8. Card + surface stripes
      9. Vertical rhythm (.stack)
     10. Typographic components (h1-h4, subtitle, lead, meta, labels)
     11. Prose body measures
     12. Block components (table, callout, code, list, blockquote, kbd,
         per-artefact footer)
     13. Tile (Phase 2 placeholder)
     14. Empty state (Phase 2 placeholder)
     15. Inline components (a, strong, em, code, kbd, abbr, tag pill)
     16. Responsive breakpoints
     17. Transitions (capped 150ms, opacity/colour only, never transform)
   ===================================================================== */


/* ---------------------------------------------------------------------
   0. @font-face declarations
   Self-hosted woff2 files live in _assets/fonts/, alongside this CSS.
   Paths are relative to this stylesheet, so the same files load from
   any artefact location. font-display: swap shows the fallback stack
   while the woff2 loads, which keeps file:// renders instant.
   --------------------------------------------------------------------- */

@font-face {
  font-family: 'Lato';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url('fonts/lato-300.woff2') format('woff2');
}

@font-face {
  font-family: 'Lato';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/lato-400.woff2') format('woff2');
}

@font-face {
  font-family: 'Lato';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/lato-700.woff2') format('woff2');
}

@font-face {
  font-family: 'Lato';
  font-style: normal;
  font-weight: 900;
  font-display: swap;
  src: url('fonts/lato-900.woff2') format('woff2');
}

@font-face {
  font-family: 'Anonymous Pro';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/anonymous-pro-700.woff2') format('woff2');
}


/* ---------------------------------------------------------------------
   1. :root tokens (DotJess brand)
   Page background is always white. No dark mode. Colour values come
   directly from the DotJess BRAND-GUIDE.
   --------------------------------------------------------------------- */

:root {
  /* Spacing scale, 8 stops on a 4px base */
  --space-0: 0;
  --space-1: 0.25rem;   /* 4px  */
  --space-2: 0.5rem;    /* 8px  */
  --space-3: 0.75rem;   /* 12px */
  --space-4: 1rem;      /* 16px */
  --space-5: 1.5rem;    /* 24px */
  --space-6: 2rem;      /* 32px */
  --space-7: 3rem;      /* 48px */
  --space-8: 4rem;      /* 64px */

  /* Type scale (DotJess uses fluid clamps for h1 and h2) */
  --text-xs: 0.75rem;    /* 12px metadata, pills, footer chips */
  --text-sm: 0.875rem;   /* 14px secondary, captions */
  --text-base: 17px;     /* DotJess body floor */
  --text-md: 1.125rem;   /* 18px lead, drafted-email body */
  --text-h3: 1.05rem;    /* h3 per BRAND-GUIDE */
  --text-h2: clamp(1.4rem, 4vw, 2.2rem);
  --text-h1: clamp(2rem, 6vw, 2.8rem);
  --text-3xl: 3rem;      /* Phase 2 hero only */

  /* Line-height tokens (per BRAND-GUIDE) */
  --leading-h1: 1.1;
  --leading-h2: 1.2;
  --leading-h3: 1.3;
  --leading-snug: 1.35;
  --leading-body: 1.65;
  --leading-relaxed: 1.7;

  /* Font stacks (self-hosted, with graceful fallback) */
  --font-sans: 'Lato', system-ui, -apple-system, BlinkMacSystemFont,
               'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-mono: 'Anonymous Pro', ui-monospace, 'SF Mono', Menlo,
               Consolas, 'Liberation Mono', monospace;

  /* Core DotJess palette (BRAND-GUIDE: Core Tokens) */
  --g:  #64bba9;   /* brand green, decorative only, never text on white */
  --gt: #1e7a6a;   /* text green, AA on white (5.19:1) */
  --b:  #6c85c3;   /* blue accent — fill/border only, fails AA as text on white (3.0:1) */
  --p:  #f3766b;   /* pink accent */
  --o:  #f9a12d;   /* orange accent */

  /* Text-safe variants for status semantics on white. AA-passing.
     Phase E fix (Dameon a11y): status colours (--warn, --stop, --info) were
     being used as text on white where they fail AA. Use --*-text below for
     text; reserve --warn, --stop, --info for fills, borders, and pills. */
  --info-text: var(--txt);  /* blue fails as text; use body text instead (Dragon brand verdict 2026-05-25) */
  --warn-text: var(--txt);  /* orange fails as text; use body text instead */
  --stop-text: var(--txt);  /* pink fails as text; use body text instead */

  /* Neutrals */
  --bg:  #ffffff;  /* page background, always white */
  --bdr: #dde8e4;  /* borders */
  --txt: #1a1a1a;  /* primary text, 16.9:1 on white (AAA) */
  --mu:  #5c5c5c;  /* muted text, AA on white (6.69:1) */

  /* Colour-block backgrounds (white-on-colour safe) */
  --bg-green: #3d9d8a;
  --bg-pink:  #e55e52;

  /* Surface stripes (left-edge signature, recoloured to DotJess accents).
     Stripe is always paired with a text label in the meta row so colour
     is never the sole carrier of meaning. */
  --surface-report:   var(--gt);        /* text-green   analytical */
  --surface-email:    var(--bg-green);  /* block-green  communication */
  --surface-brief:    var(--b);         /* blue         research / thinking */
  --surface-decision: var(--bg-pink);   /* block-pink   weighty */
  --surface-index:    var(--mu);        /* muted grey   neutral landing */
  --surface-spec:     var(--txt);       /* near-black   engineering */
  --surface-copy:     var(--o);         /* orange       creative */
  --surface-note:     #7a8a85;          /* warm mid-grey ad-hoc (3.63:1 on white, meets UI ≥3:1; was var(--bdr) #dde8e4 at 1.25:1 — invisible) */

  /* Semantic (status, used sparingly, max one per page) */
  --ok:   var(--gt);
  --warn: var(--o);
  --stop: var(--bg-pink);
  --info: var(--b);  /* alias to --b (#6c85c3) for fills/borders/icons only — never as text (Dragon brand verdict 2026-05-25) */

  /* Borders kept as separate aliases so other components can reference */
  --border-soft: var(--bdr);
  --border-firm: #c9d6d1;

  /* Subtle surface for table stripes, code blocks, callouts */
  --bg-subtle: #f5f8f7;
  --bg-inset:  #f5f8f7;

  /* Elevation */
  --shadow-card: 0 1px 2px rgba(26, 26, 26, 0.04),
                 0 4px 12px rgba(26, 26, 26, 0.05);

  /* Easing (per BRAND-GUIDE) */
  --e: .22s cubic-bezier(.4, 0, .2, 1);

  color-scheme: light;
}


/* ---------------------------------------------------------------------
   2. Universal base
   --------------------------------------------------------------------- */

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

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-base);
  font-weight: 300;
  line-height: var(--leading-body);
  color: var(--txt);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img,
svg {
  max-width: 100%;
  height: auto;
}

hr {
  border: 0;
  border-top: 1px solid var(--border-soft);
  margin: var(--space-5) 0;
}


/* ---------------------------------------------------------------------
   3. Reduced motion (COG-01 ship blocker, MANDATORY)
   --------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}


/* ---------------------------------------------------------------------
   4. Page shell (topbar, main, footer band)
   Three bands on every page. Topbar 56px, footer band 40px, main
   container capped at min(78rem, 100% - 2rem).
   --------------------------------------------------------------------- */

body > header {
  background: var(--bg);
  min-height: 56px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--space-5);
  border-bottom: 1px solid var(--border-soft);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--txt);
}

body > header .topbar-left {
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--txt);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

body > header nav,
body > header .topbar-right {
  display: flex;
  gap: var(--space-4);
  align-items: center;
  font-family: var(--font-mono);
}

body > header nav a,
body > header .topbar-right a {
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--gt);
  text-decoration: none;
}

body > header nav a:hover,
body > header .topbar-right a:hover {
  text-decoration: underline;
}

/* Print button — discoverable Cmd-P trigger lives in the topbar.
   Reset native button chrome so it visually matches the topbar links,
   keep the same monospace 700 styling. Hidden in print via print.css. */
.gm-print-btn {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--gt);
  background: transparent;
  border: 1px solid var(--border-firm);
  padding: var(--space-1) var(--space-3);
  cursor: pointer;
  line-height: 1.4;
  border-radius: 0;
}

.gm-print-btn:hover,
.gm-print-btn:focus-visible {
  background: var(--gt);
  color: #ffffff;
  border-color: var(--gt);
}

main,
body > main {
  /* Lifted 2026-05-24 (Jess feedback, two passes):
     v1: 78rem → 96rem. Still wasted space on Studio Display (~2560 CSS px
         viewport meant 96rem cap = ~60% width, visible margins).
     v2: 96rem → 140rem with edge padding. Truly fills available space on
         wide Mac displays; soft 140rem (~2240px) ceiling prevents insane
         line lengths on 5K+ ultrawides.
     Body measure caps still protect prose readability via .gm-body (68ch);
     dashboards / grids opt out with .gm-body--wide. */
  width: min(140rem, 100% - 2rem);
  margin: 0 auto;
  padding-top: var(--space-7);
  padding-bottom: var(--space-7);
}

body > footer {
  background: var(--bg);
  min-height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-top: 1px solid var(--border-soft);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--mu);
  letter-spacing: 0.04em;
  padding: var(--space-3) var(--space-4);
}


/* ---------------------------------------------------------------------
   5. Wordmark (.wm) — the DotJess mark
   The wordmark IS the logo. Lowercase, Anonymous Pro 700, text-green,
   tight negative letter-spacing. Used in the topbar and anywhere the
   brand needs to sign the page.
   --------------------------------------------------------------------- */

.wm {
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--gt);
  text-transform: lowercase;
  letter-spacing: -0.02em;
  text-decoration: none;
}

a.wm:hover {
  text-decoration: none;
  filter: brightness(0.92);
}


/* ---------------------------------------------------------------------
   6. Skip link
   --------------------------------------------------------------------- */

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 1000;
}

.skip-link:focus {
  left: 0;
  background: var(--txt);
  color: var(--bg);
  padding: var(--space-2) var(--space-4);
  text-decoration: none;
}


/* ---------------------------------------------------------------------
   7. Focus styles
   Visible focus indicator on every focusable element. Never use
   outline: none without a visible replacement.
   --------------------------------------------------------------------- */

:focus-visible {
  outline: 2px solid var(--gt);
  outline-offset: 2px;
  border-radius: 2px;
}


/* ---------------------------------------------------------------------
   8. Card
   One card per page, holds the full artefact. Squared corners, soft
   border, no left stripe. Artefact type is carried by the uppercase
   TYPE label in the meta row, not by a coloured stripe.

   Surface stripe retired 2026-05-24 (Jess): inner components (KPI,
   finding cards, action lanes, callouts) carry their own status
   borders, the outer stripe was visual noise. The body.surface-*
   class is kept as a semantic marker for the artefact type and may
   still be referenced by future component variants.
   --------------------------------------------------------------------- */

.card {
  /* Chrome retired on screen 2026-05-25 (Jess, two passes):
     - Border dropped: white card on white page, the 1px line was inert
     - Shadow dropped: with no border, the shadow was the last bit of
       "wrapped widget" framing — gone now, content sits on the page
     The card is effectively a padding+background wrapper on screen.
     Print restores a hairline border in print.css so the artefact edge
     is preserved on paper. */
  background: var(--bg);
  padding: var(--space-6);
  margin-top: 0;
}


/* ---------------------------------------------------------------------
   9. Vertical rhythm (.stack pattern)
   --------------------------------------------------------------------- */

.stack > * + * {
  margin-top: var(--space-4);
}

.stack-lg > * + * {
  margin-top: var(--space-7);
}


/* ---------------------------------------------------------------------
  10. Typographic components
   Per DotJess BRAND-GUIDE: h1 weight 900 in primary text, h2 weight 900
   in text-green, h3 weight 700, body weight 300.
   --------------------------------------------------------------------- */

h1, h2, h3, h4 {
  page-break-after: avoid;
  break-after: avoid;
  font-family: var(--font-sans);
}

h1 {
  font-size: var(--text-h1);
  font-weight: 900;
  line-height: var(--leading-h1);
  color: var(--txt);
  margin: 0 0 var(--space-3);
  max-width: 100%;
  /* Break long titles cleanly rather than overflowing the card. */
  overflow-wrap: anywhere;
  hyphens: auto;
}

h2 {
  font-size: var(--text-h2);
  font-weight: 900;
  line-height: var(--leading-h2);
  color: var(--gt);
  margin: var(--space-7) 0 var(--space-3);
}

h3 {
  font-size: var(--text-h3);
  font-weight: 700;
  line-height: var(--leading-h3);
  color: var(--txt);
  margin: var(--space-5) 0 var(--space-2);
}

h4 {
  font-size: var(--text-base);
  font-weight: 700;
  line-height: var(--leading-snug);
  color: var(--txt);
  margin: var(--space-4) 0 var(--space-2);
  text-transform: none;
}

p {
  margin: 0 0 var(--space-4);
}

.subtitle {
  font-size: var(--text-md);
  font-weight: 300;
  color: var(--mu);
  line-height: var(--leading-snug);
  margin: 0 0 var(--space-4);
}

.lead {
  font-size: var(--text-md);
  font-weight: 300;
  color: var(--txt);
  line-height: var(--leading-relaxed);
  margin: 0 0 var(--space-5);
}

.caption {
  font-size: var(--text-sm);
  color: var(--mu);
}

/* Label (.lbl) — Anonymous Pro section marker.
   Sits above headings or in meta strips. */
.lbl {
  font-family: var(--font-mono);
  font-size: 1rem;
  font-weight: 700;
  color: var(--gt);
  text-transform: uppercase;
  letter-spacing: 0.12em;
}


/* ---------------------------------------------------------------------
  11. Prose body measure caps
   --------------------------------------------------------------------- */

.gm-body {
  /* Body measure caps at 68ch for readability, but stays FLUSH LEFT
     with the meta row, h1, and subtitle. Centring (margin: 0 auto)
     creates the appearance of a right-shift indent on wide cards. */
  max-width: 68ch;
  margin-left: 0;
  margin-right: auto;
}

.gm-body--narrow {
  max-width: 52ch;
}

/* .gm-body--wide opts the body out of the 68ch prose cap so dashboards,
   matrices, heatmaps, comparison grids, custom editors, and other data /
   layout-heavy templates use the full card width. Use on templates whose
   primary content is structured data, not prose. (Added 2026-05-24 with
   the 96rem main lift to stop wasting horizontal space on wide screens.) */
.gm-body--wide {
  max-width: none;
}


/* ---------------------------------------------------------------------
  12. Block components
   --------------------------------------------------------------------- */

.gm-page-header {
  margin-bottom: var(--space-6);
}

.meta-divider {
  border: 0;
  border-top: 1px solid var(--border-soft);
  margin: var(--space-4) 0;
}

.meta {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--mu);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0;
}

.meta .agent-name {
  color: var(--gt);
  font-weight: 700;
}

/* Table */
table {
  width: 100%;
  border-collapse: collapse;
  margin: var(--space-5) 0;
  font-size: var(--text-base);
  page-break-inside: avoid;
  break-inside: avoid;
}

caption {
  font-size: var(--text-sm);
  color: var(--mu);
  text-align: left;
  padding-bottom: var(--space-2);
  caption-side: top;
}

thead th {
  background: var(--bg-subtle);
  font-weight: 700;
  color: var(--txt);
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-firm);
}

tbody td,
tbody th {
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--border-soft);
  vertical-align: top;
}

tbody th[scope="row"] {
  font-weight: 700;
  color: var(--txt);
}

tbody tr:nth-child(even) {
  background: var(--bg-subtle);
}

.table-scroll {
  overflow-x: auto;
}

.table-scroll:focus-visible {
  outline: 2px solid var(--gt);
  outline-offset: 2px;
}

/* Callout */
.callout {
  background: var(--bg-subtle);
  padding: var(--space-4);
  margin: var(--space-5) 0;
  border-left: 4px solid var(--mu);
  border-radius: 0 4px 4px 0;
  page-break-inside: avoid;
  break-inside: avoid;
}

.callout-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  margin: 0 0 var(--space-2);
  color: var(--txt);
}

.callout-note { border-left-color: var(--info); }
.callout-note .callout-label { color: var(--info-text); }

.callout-warn { border-left-color: var(--warn); }
.callout-warn .callout-label { color: var(--warn-text); }

.callout-stop { border-left-color: var(--stop); }
.callout-stop .callout-label { color: var(--stop-text); }

.callout-info { border-left-color: var(--info); }
.callout-info .callout-label { color: var(--info-text); }

.callout > p:last-child { margin-bottom: 0; }

/* Affordance label — one-sentence hint placed above an interactive surface
   (variant tabs, lanes, slide-deck). Tells the reader what to do before they
   have to discover it. Per Numair Phase E. */
.affordance-label {
  font-size: var(--text-sm);
  color: var(--mu);
  font-style: italic;
  margin: var(--space-2) 0 var(--space-3);
}

/* Slide-deck hint — on the title slide so a reader entering presentation
   mode sees keyboard nav immediately. */
.gm-slide__hint {
  margin-top: var(--space-5);
  font-size: var(--text-sm);
  color: var(--mu);
  font-style: italic;
}

/* Checklist — used inside callouts where each item is a real <input type="checkbox">.
   For runbook pre-flight and verify lists where the operator needs to tick off
   physical steps and have them survive a tab refresh (paired with localStorage). */
.gm-checklist {
  list-style: none;
  padding-left: 0;
  margin: var(--space-2) 0;
}
.gm-checklist li {
  margin-top: var(--space-2);
}
.gm-checklist label {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  cursor: pointer;
  line-height: var(--leading-snug);
}
.gm-checklist input[type="checkbox"] {
  margin-top: 0.25em;
  flex-shrink: 0;
  width: 1.05rem;
  height: 1.05rem;
  cursor: pointer;
}
.gm-checklist input[type="checkbox"]:checked + * ,
.gm-checklist label:has(input:checked) {
  color: var(--mu);
}

/* Link placeholder — template-demo only.
   Use inside templates where the reader sees text that looks like a link
   but the destination doesn't exist yet (e.g. "your client's how-to lives
   here"). Visibly marked as a placeholder so no one clicks expecting a doc.
   Replace with a real <a href="..."> when the project ships. */
.gm-link-placeholder {
  font-style: italic;
  color: var(--mu);
  text-decoration: none;
  border-bottom: 1px dotted var(--mu);
  cursor: not-allowed;
}
.gm-link-placeholder::after {
  content: " (placeholder)";
  font-size: var(--text-xs);
  font-style: normal;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--mu);
  margin-left: 0.25em;
}

/* Code block */
pre {
  background: var(--bg-subtle);
  padding: var(--space-4);
  border-radius: 6px;
  overflow-x: auto;
  margin: var(--space-4) 0;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: var(--leading-snug);
  color: var(--txt);
  page-break-inside: avoid;
  break-inside: avoid;
}

pre code {
  background: transparent;
  padding: 0;
  font-size: inherit;
  color: inherit;
}

/* Lists */
ul, ol {
  margin: var(--space-4) 0;
  padding-left: var(--space-5);
}

li + li {
  margin-top: var(--space-2);
}

dl {
  margin: var(--space-4) 0;
}

dt {
  font-weight: 700;
  color: var(--txt);
}

dd {
  margin-left: var(--space-5);
  margin-bottom: var(--space-3);
}

/* Blockquote */
blockquote {
  margin: var(--space-5) 0;
  padding-left: var(--space-4);
  border-left: 3px solid var(--g);
  color: var(--mu);
  font-size: var(--text-base);
  line-height: var(--leading-relaxed);
}

blockquote p:last-child { margin-bottom: 0; }

/* Per-artefact footer (inside the card) */
.gm-artefact-footer {
  margin-top: var(--space-7);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-soft);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--mu);
  line-height: var(--leading-snug);
}

.gm-artefact-footer p {
  margin: 0 0 var(--space-2);
}

.gm-artefact-footer .file-path {
  font-family: var(--font-mono);
  color: var(--mu);
  word-break: break-all;
  background: var(--bg-subtle);
  padding: 0 0.3em;
  border-radius: 3px;
}

.gm-artefact-footer a {
  min-height: 44px;
  display: inline-block;
  padding: var(--space-2) 0;
  font-size: var(--text-sm);
  color: var(--gt);
}


/* ---------------------------------------------------------------------
  13. Tile (Phase 2 placeholder)
   --------------------------------------------------------------------- */

.tile-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: var(--space-4);
  margin: var(--space-5) 0;
}

.tile {
  /* Squared like .card: 4px surface stripe runs full height, no radius. */
  display: block;
  background: var(--bg);
  padding: var(--space-5);
  border: 1px solid var(--border-soft);
  box-shadow: var(--shadow-card);
  text-decoration: none;
  color: var(--txt);
  border-left: 4px solid var(--surface-note);
}

.tile:hover,
.tile:focus-visible {
  box-shadow: 0 2px 4px rgba(26, 26, 26, 0.06),
              0 8px 20px rgba(26, 26, 26, 0.08);
  border-color: var(--g);
  /* No transform on hover, motion budget bans transform jiggle. */
}

.tile .tile-title {
  font-weight: 700;
  color: var(--txt);
  margin: 0 0 var(--space-2);
}

.tile .tile-meta {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--mu);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}


/* ---------------------------------------------------------------------
  14. Empty state (Phase 2 placeholder)
   --------------------------------------------------------------------- */

.empty-state {
  border: 1px dashed var(--border-soft);
  background: var(--bg-subtle);
  color: var(--mu);
  padding: var(--space-7);
  text-align: center;
  border-radius: 12px;
  margin: var(--space-5) 0;
}


/* ---------------------------------------------------------------------
  15. Inline components
   Links default to text-green. Underline stays on hover (Dameon a11y).
   <em> is a soft brand-green wash, not italic.
   --------------------------------------------------------------------- */

a {
  color: var(--gt);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}

a:hover {
  color: var(--txt);
  text-decoration: underline;
}

a:visited {
  color: var(--gt);
}

strong {
  font-weight: 700;
  color: var(--txt);
}

em {
  /* No italic. Subtle highlight on key terms (BRAND-GUIDE green wash). */
  font-style: normal;
  background: rgba(100, 187, 169, 0.18);
  padding: 0 0.15em;
  border-radius: 2px;
}

code {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  background: var(--bg-subtle);
  padding: 0 0.3em;
  border-radius: 3px;
  color: var(--txt);
}

kbd {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  background: var(--bg-subtle);
  border: 1px solid var(--border-firm);
  border-radius: 3px;
  padding: 0.05em 0.4em;
  color: var(--txt);
}

abbr[title] {
  text-decoration: underline dotted;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
  cursor: help;
}

/* Type badge / tag pill */
.tag-pill,
.type-badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  background: var(--bg-subtle);
  color: var(--gt);
  padding: var(--space-1) var(--space-2);
  border-radius: 3px;
}


/* ---------------------------------------------------------------------
  16. Responsive breakpoints
   --------------------------------------------------------------------- */

@media (max-width: 600px) {
  .card {
    padding: var(--space-4);
  }

  pre,
  pre code {
    font-size: var(--text-xs);
  }

  body > header {
    padding: 0 var(--space-4);
    flex-wrap: wrap;
    gap: var(--space-2);
  }
}


/* ---------------------------------------------------------------------
  17. Transitions
   Capped at 150ms. Opacity, colour, box-shadow, border-colour only.
   No transform in any transition property (motion budget).
   --------------------------------------------------------------------- */

a,
.tile,
.skip-link,
button {
  transition: color 150ms ease, background-color 150ms ease,
              border-color 150ms ease, box-shadow 150ms ease,
              opacity 150ms ease;
}


/* =====================================================================
  18. Component library — Phase A
   ---------------------------------------------------------------------
   16 reusable building blocks per Dragon's PHASE-A-COMPONENT-SPEC.
   BEM with gm- prefix. Status modifiers use shared vocabulary:
   ok / warn / stop / info / neutral. Never colour words in class names.

   Each subsection is preceded by a banner with purpose and HTML shape.
   Tokens only. No new hex values. Component CSS never overrides the
   global focus ring or the reduced-motion block.
   ===================================================================== */


/* ---------------------------------------------------------------------
  18.1 Badges and pills (.gm-badge, .gm-pill)
   ---------------------------------------------------------------------
   Purpose: inline metadata. Badge = subtle (category/owner/type).
   Pill = solid (severity/status). Intent text always visible.
   Shape:
     <span class="gm-badge">Security</span>
     <span class="gm-pill gm-pill--stop">High</span>
   --------------------------------------------------------------------- */

.gm-badge {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  background: var(--bg-subtle);
  color: var(--gt);
  padding: var(--space-1) var(--space-2);
  border: 1px solid transparent;
  white-space: nowrap;
  line-height: 1.4;
}

.gm-badge--category {
  /* default styling, explicit class for grep clarity */
}

.gm-badge--owner {
  background: var(--bg);
  border-color: var(--border-firm);
  color: var(--txt);
}

.gm-pill {
  display: inline-block;
  min-width: 56px;
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: var(--space-1) var(--space-3);
  background: var(--mu);
  color: #ffffff;
  line-height: 1.4;
  white-space: nowrap;
}

.gm-pill--ok       { background: var(--ok);   color: #ffffff; }
.gm-pill--warn     { background: var(--warn); color: var(--txt); }
.gm-pill--stop     { background: var(--stop); color: #ffffff; }
.gm-pill--info     { background: var(--info); color: var(--txt); }
.gm-pill--neutral  { background: var(--mu);   color: #ffffff; }


/* ---------------------------------------------------------------------
  18.2 KPI strip (.gm-kpi-strip, .gm-kpi)
   ---------------------------------------------------------------------
   Purpose: 3-6 single-number truths at top of a dashboard.
   Shape: <dl class="gm-kpi-strip"><div class="gm-kpi">...
   --------------------------------------------------------------------- */

.gm-kpi-strip {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-4);
  margin: var(--space-5) 0;
  padding: 0;
}

.gm-kpi {
  background: var(--bg-subtle);
  border-left: 4px solid var(--mu);
  padding: var(--space-4) var(--space-5);
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.gm-kpi__label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--mu);
  margin: 0;
}

.gm-kpi__value {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 2.2rem;
  line-height: 1;
  color: var(--txt);
  margin: 0;
}

.gm-kpi__delta {
  font-size: var(--text-sm);
  color: var(--mu);
  margin: 0;
}

.gm-kpi--ok      { border-left-color: var(--ok); }
.gm-kpi--ok    .gm-kpi__value { color: var(--ok); }
.gm-kpi--warn    { border-left-color: var(--warn); }
.gm-kpi--warn  .gm-kpi__value { color: var(--warn-text); }
.gm-kpi--stop    { border-left-color: var(--stop); }
.gm-kpi--stop  .gm-kpi__value { color: var(--stop-text); }
.gm-kpi--info    { border-left-color: var(--info); }
.gm-kpi--info  .gm-kpi__value { color: var(--info-text); }
.gm-kpi--neutral { border-left-color: var(--mu); }


/* ---------------------------------------------------------------------
  18.3 Status matrix (.gm-status-matrix)
   ---------------------------------------------------------------------
   Purpose: compact tabular comparison. Same shape per row.
   Shape: <div class="gm-status-matrix table-scroll" role="region"...>
   --------------------------------------------------------------------- */

.gm-status-matrix table {
  margin: 0;
}

.gm-status-matrix--compact thead th,
.gm-status-matrix--compact tbody td,
.gm-status-matrix--compact tbody th {
  padding: var(--space-2) var(--space-3);
}


/* ---------------------------------------------------------------------
  18.4 Action lanes (.gm-action-lanes, .gm-action-lane, .gm-action-item)
   ---------------------------------------------------------------------
   Purpose: force the reader to see what to do, by whom, by when.
   Default stacked. --columns modifier for kanban.
   --------------------------------------------------------------------- */

.gm-action-lanes {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  margin: var(--space-5) 0;
}

.gm-action-lanes--columns {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-5);
}

.gm-action-lane {
  /* container */
}

.gm-action-lane__title {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--mu);
  margin: 0 0 var(--space-3);
}

.gm-action-lane__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.gm-action-item {
  display: grid;
  grid-template-columns: 24px 1fr auto;
  gap: var(--space-3);
  align-items: start;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--border-soft);
}

.gm-action-item:last-child {
  border-bottom: 0;
}

.gm-action-item__dot {
  display: inline-block;
  width: 12px;
  height: 12px;
  margin-top: 0.35em;
  background: var(--mu);
  border-radius: 50%;
  box-shadow: 0 0 0 4px var(--bg);
}

.gm-action-item__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.gm-action-item__title {
  font-size: var(--text-base);
  font-weight: 700;
  color: var(--txt);
  margin: 0;
}

.gm-action-item__why {
  font-size: var(--text-sm);
  color: var(--mu);
  margin: 0;
}

.gm-action-item--ok   .gm-action-item__dot { background: var(--ok); }
.gm-action-item--warn .gm-action-item__dot { background: var(--warn); }
.gm-action-item--stop .gm-action-item__dot { background: var(--stop); }
.gm-action-item--info .gm-action-item__dot { background: var(--info); }


/* ---------------------------------------------------------------------
  18.5 Finding cards (.gm-finding-grid, .gm-finding-card)
   ---------------------------------------------------------------------
   Purpose: replace long h3+p+p with a structured triage-ready card.
   --------------------------------------------------------------------- */

.gm-finding-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: var(--space-4);
  margin: var(--space-5) 0;
}

.gm-finding-card {
  background: var(--bg);
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--mu);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.gm-finding-card--ok    { border-left-color: var(--ok); }
.gm-finding-card--warn  { border-left-color: var(--warn); }
.gm-finding-card--stop  { border-left-color: var(--stop); }
.gm-finding-card--info  { border-left-color: var(--info); }

.gm-finding-card__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

.gm-finding-card__id {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--mu);
  margin-left: auto;
}

.gm-finding-card__title {
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--txt);
  line-height: var(--leading-snug);
  margin: 0;
}

.gm-finding-card__impact {
  font-size: var(--text-base);
  color: var(--txt);
  margin: 0;
}

.gm-finding-card__evidence {
  background: var(--bg-subtle);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
}

.gm-finding-card__evidence p { margin: 0 0 var(--space-2); }
.gm-finding-card__evidence ul,
.gm-finding-card__evidence ol {
  margin: 0;
  padding-left: var(--space-5);
}

.gm-finding-card__action {
  border-top: 1px solid var(--border-soft);
  padding-top: var(--space-3);
  font-size: var(--text-sm);
  color: var(--mu);
}


/* ---------------------------------------------------------------------
  18.6 Evidence blocks (.gm-evidence)
   ---------------------------------------------------------------------
   Purpose: labelled supporting material distinct from prose.
   Modes: code / log / diff / paths / quote (+ --collapsed).
   --------------------------------------------------------------------- */

.gm-evidence {
  background: var(--bg-subtle);
  border-left: 3px solid var(--mu);
  padding: var(--space-3) var(--space-4);
  margin: var(--space-4) 0;
}

.gm-evidence__label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--mu);
  margin: 0 0 var(--space-2);
  display: block;
}

.gm-evidence pre {
  background: transparent;
  padding: 0;
  margin: 0;
  border-radius: 0;
}

.gm-evidence ul,
.gm-evidence ol {
  margin: 0;
  padding-left: 0;
  list-style: none;
}

.gm-evidence__line {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--mu);
  padding-left: var(--space-2);
}

.gm-evidence--log mark {
  background: rgba(249, 161, 45, 0.30);
  color: var(--txt);
  padding: 0 0.2em;
}

.gm-evidence--diff .gm-evidence__add {
  background: rgba(30, 122, 106, 0.12);
  display: block;
  padding: 0 var(--space-3);
}

.gm-evidence--diff .gm-evidence__del {
  background: rgba(229, 94, 82, 0.12);
  display: block;
  padding: 0 var(--space-3);
}

.gm-evidence--paths ul,
.gm-evidence--paths ol {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

.gm-evidence--paths li + li {
  margin-top: var(--space-1);
}

.gm-evidence--quote blockquote {
  border-left: 0;
  margin: 0;
  padding-left: 0;
  color: var(--txt);
}

.gm-evidence--collapsed details {
  margin: 0;
}

.gm-evidence--collapsed summary {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--gt);
}


/* ---------------------------------------------------------------------
  18.7 Coverage bars (.gm-coverage-bar)
   ---------------------------------------------------------------------
   Purpose: ratio where both number and proportion matter.
   --------------------------------------------------------------------- */

.gm-coverage-bar {
  margin: var(--space-3) 0;
}

.gm-coverage-bars > .gm-coverage-bar + .gm-coverage-bar {
  margin-top: var(--space-4);
}

.gm-coverage-bar__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

.gm-coverage-bar__label {
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--txt);
}

.gm-coverage-bar__ratio {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--mu);
}

.gm-coverage-bar__track {
  width: 100%;
  height: 10px;
  background: var(--bg-subtle);
  overflow: hidden;
}

.gm-coverage-bar__fill {
  height: 100%;
  background: var(--mu);
}

.gm-coverage-bar--ok   .gm-coverage-bar__fill { background: var(--ok); }
.gm-coverage-bar--warn .gm-coverage-bar__fill { background: var(--warn); }
.gm-coverage-bar--stop .gm-coverage-bar__fill { background: var(--stop); }
.gm-coverage-bar--info .gm-coverage-bar__fill { background: var(--info); }


/* ---------------------------------------------------------------------
  18.8 Heatmap (.gm-heatmap)
   ---------------------------------------------------------------------
   Purpose: two-dimensional pattern, row x column with intent cells.
   Alpha overlays on white, never solid colour cells.
   --------------------------------------------------------------------- */

.gm-heatmap table {
  margin: 0;
}

.gm-heatmap thead th,
.gm-heatmap tbody td,
.gm-heatmap tbody th {
  padding: var(--space-3);
  text-align: center;
}

.gm-heatmap tbody th[scope="row"] {
  text-align: left;
}

/* override the global zebra so cell intent reads clearly */
.gm-heatmap tbody tr:nth-child(even) {
  background: transparent;
}

.gm-heatmap__cell {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: var(--text-base);
  text-align: center;
  vertical-align: middle;
  color: var(--txt);
}

.gm-heatmap__cell--ok      { background: rgba(30, 122, 106, 0.18); }
.gm-heatmap__cell--warn    { background: rgba(249, 161, 45, 0.22); }
.gm-heatmap__cell--stop    { background: rgba(229, 94, 82, 0.22); }
.gm-heatmap__cell--info    { background: rgba(108, 133, 195, 0.18); }
.gm-heatmap__cell--neutral { background: var(--bg-subtle); color: var(--mu); }
.gm-heatmap__cell--empty   { background: var(--bg); color: var(--mu); }


/* ---------------------------------------------------------------------
  18.9 Timeline (.gm-timeline)
   ---------------------------------------------------------------------
   Purpose: events along a time axis with what / who / impact.
   --------------------------------------------------------------------- */

.gm-timeline {
  list-style: none;
  padding-left: 0;
  margin: var(--space-5) 0;
  position: relative;
}

.gm-timeline::before {
  content: "";
  position: absolute;
  left: calc(80px + var(--space-3) + 12px);
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--border-soft);
}

.gm-timeline__item {
  display: grid;
  grid-template-columns: 80px 24px 1fr;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  position: relative;
}

.gm-timeline__time {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--mu);
  text-align: right;
  padding-top: 0.15em;
}

.gm-timeline__marker {
  display: block;
  width: 14px;
  height: 14px;
  margin: 0.3em auto 0;
  background: var(--mu);
  border-radius: 50%;
  box-shadow: 0 0 0 4px var(--bg);
  position: relative;
  z-index: 1;
}

.gm-timeline__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

.gm-timeline__title {
  font-size: var(--text-base);
  font-weight: 700;
  color: var(--txt);
  margin: 0;
}

.gm-timeline__meta {
  font-size: var(--text-sm);
  color: var(--mu);
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.gm-timeline__body p { margin: 0; }

.gm-timeline__item--ok   .gm-timeline__marker { background: var(--ok); }
.gm-timeline__item--warn .gm-timeline__marker { background: var(--warn); }
.gm-timeline__item--stop .gm-timeline__marker { background: var(--stop); }
.gm-timeline__item--info .gm-timeline__marker { background: var(--info); }


/* ---------------------------------------------------------------------
  18.10 Comparison grid (.gm-comparison-grid, .gm-comparison-card)
   ---------------------------------------------------------------------
   Purpose: 2-4 options side-by-side, same shape of facts on each.
   --------------------------------------------------------------------- */

.gm-comparison-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-4);
  margin: var(--space-5) 0;
}

.gm-comparison-card {
  background: var(--bg);
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--mu);
  padding: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.gm-comparison-card--recommended {
  border-left-color: var(--ok);
  box-shadow: var(--shadow-card);
}

.gm-comparison-card--alternative {
  border-left-color: var(--info);
}

.gm-comparison-card--rejected {
  border-left-color: var(--stop);
  opacity: 0.75;
}

.gm-comparison-card__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.gm-comparison-card__title {
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--txt);
  margin: 0;
}

.gm-comparison-card__summary {
  font-size: var(--text-base);
  margin: 0;
}

.gm-comparison-card__facts {
  margin: 0;
}

.gm-comparison-card__facts dt {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--mu);
  margin-top: var(--space-2);
}

.gm-comparison-card__facts dt:first-child { margin-top: 0; }

.gm-comparison-card__facts dd {
  margin: var(--space-1) 0 var(--space-3) 0;
  font-size: var(--text-sm);
}


/* ---------------------------------------------------------------------
  18.11 Decision matrix (.gm-decision-matrix)
   ---------------------------------------------------------------------
   Purpose: score options against weighted criteria. Show the working.
   --------------------------------------------------------------------- */

.gm-decision-matrix table { margin: 0; }

.gm-decision-matrix thead th,
.gm-decision-matrix tbody td,
.gm-decision-matrix tbody th {
  padding: var(--space-2) var(--space-3);
}

.gm-decision-matrix thead th:last-child,
.gm-decision-matrix tbody td:last-child {
  border-left: 1px solid var(--border-firm);
}

.gm-decision-matrix__verdict {
  font-family: var(--font-mono);
  font-weight: 700;
}


/* ---------------------------------------------------------------------
  18.12 Process flow (.gm-process-flow)
   ---------------------------------------------------------------------
   Purpose: workflow: start -> steps -> decisions -> success/failure.
   --------------------------------------------------------------------- */

.gm-process-flow {
  list-style: none;
  padding: 0;
  margin: var(--space-5) 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-items: center;
}

.gm-process-flow__node {
  width: 100%;
  max-width: 32rem;
  background: var(--bg);
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--mu);
  padding: var(--space-3) var(--space-4);
  position: relative;
}

.gm-process-flow__node p { margin: var(--space-1) 0 0; }

.gm-process-flow__node:not(:last-child)::after {
  content: "▼";
  display: block;
  text-align: center;
  color: var(--mu);
  font-size: var(--text-sm);
  margin: var(--space-2) 0 calc(-1 * var(--space-2));
  position: absolute;
  left: 50%;
  bottom: calc(-1 * var(--space-3) - 0.4em);
  transform: translateX(-50%);
  line-height: 1;
}

.gm-process-flow__node--start { border-left-color: var(--ok); }
.gm-process-flow__node--step  { border-left-color: var(--mu); }
.gm-process-flow__node--decision { border-left-color: var(--info); }
.gm-process-flow__node--end   { border-left-color: var(--ok); }

.gm-process-flow__node--branch {
  border: 0;
  padding: 0;
  background: transparent;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
}

.gm-process-flow__node--branch::after { display: none; }

.gm-process-flow__branch {
  background: var(--bg);
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--mu);
  padding: var(--space-3) var(--space-4);
}

.gm-process-flow__branch--ok   { border-left-color: var(--ok); }
.gm-process-flow__branch--warn { border-left-color: var(--warn); }
.gm-process-flow__branch--stop { border-left-color: var(--stop); }

.gm-process-flow__label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--mu);
}

.gm-process-flow__node--decision .gm-process-flow__label {
  color: var(--info-text);
}


/* ---------------------------------------------------------------------
  18.13 Annotated diff (.gm-diff)
   ---------------------------------------------------------------------
   Purpose: code review surface: file list + diff + annotations.
   --------------------------------------------------------------------- */

.gm-diff {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: var(--space-5);
  margin: var(--space-5) 0;
}

@media (max-width: 720px) {
  .gm-diff { grid-template-columns: 1fr; }
}

.gm-diff__filelist {
  align-self: start;
  background: var(--bg-subtle);
  padding: var(--space-3) var(--space-4);
  position: sticky;
  top: var(--space-4);
}

.gm-diff__filelist h3 { margin-top: 0; }

.gm-diff__filelist ol,
.gm-diff__filelist ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.gm-diff__file {
  margin-bottom: var(--space-6);
}

.gm-diff__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.gm-diff__head h3 { margin: 0; }

.gm-diff__hunk {
  border-radius: 0;
  margin: var(--space-3) 0;
}

.gm-diff__hunk code { white-space: pre; }

.gm-diff__line {
  display: block;
  padding: 0 var(--space-3);
}

.gm-diff__line--add { background: rgba(30, 122, 106, 0.12); }
.gm-diff__line--del { background: rgba(229, 94, 82, 0.12); }

.gm-diff__annotation {
  background: var(--bg-subtle);
  padding: var(--space-3) var(--space-4);
  margin-top: var(--space-2);
  border-left: 3px solid var(--mu);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.gm-diff__annotation--blocking    { border-left-color: var(--stop); }
.gm-diff__annotation--nonblocking { border-left-color: var(--info); }

.gm-diff__annotation p { margin: 0; }


/* ---------------------------------------------------------------------
  18.14 Module map (.gm-module-map)
   ---------------------------------------------------------------------
   Purpose: code architecture: entry points, modules, hot path, read first.
   --------------------------------------------------------------------- */

.gm-module-map {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  margin: var(--space-5) 0;
}

.gm-module-map h3 { margin-top: 0; }

.gm-module-map__modules {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: var(--space-4);
}

.gm-module-map__module {
  background: var(--bg);
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--mu);
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.gm-module-map__module--hot {
  border-left-color: var(--warn);
}

.gm-module-map__role {
  font-size: var(--text-sm);
  color: var(--mu);
  margin: 0;
}

.gm-module-map__files {
  list-style: none;
  padding: 0;
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.gm-module-map__readfirst {
  background: var(--bg-subtle);
  padding: var(--space-4) var(--space-5);
}


/* ---------------------------------------------------------------------
  18.15 Contact sheet (.gm-contact-sheet)
   ---------------------------------------------------------------------
   Purpose: design system reference: swatches, type scale, spacing.
   --------------------------------------------------------------------- */

.gm-contact-sheet {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

.gm-contact-sheet__swatches {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--space-3);
}

.gm-contact-sheet__swatch {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.gm-contact-sheet__chip {
  display: inline-block;
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  border: 1px solid var(--border-soft);
}

.gm-contact-sheet__swatch code {
  display: block;
  margin-bottom: var(--space-1);
}

.gm-contact-sheet__swatch p {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--mu);
}

.gm-contact-sheet__scale td:last-child { width: 50%; }


/* ---------------------------------------------------------------------
  18.16 Editor surface (.gm-editor)
   ---------------------------------------------------------------------
   Purpose: bounded interactive workspace. Static fallback mandatory.
   JS contract: inline only, no externals, no network, no globals.
   --------------------------------------------------------------------- */

.gm-editor {
  margin: var(--space-5) 0;
  border: 1px solid var(--border-soft);
  padding: var(--space-5);
  background: var(--bg);
}

.gm-editor__head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-4);
}

.gm-editor__head h2 {
  margin: 0;
  font-size: var(--text-h3);
  color: var(--txt);
}

.gm-editor__controls {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.gm-editor__export {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 700;
  background: var(--bg-subtle);
  border: 1px solid var(--border-firm);
  color: var(--txt);
  padding: var(--space-2) var(--space-4);
  cursor: pointer;
  border-radius: 0;
}

.gm-editor__export:hover,
.gm-editor__export:focus-visible {
  background: var(--gt);
  color: #ffffff;
  border-color: var(--gt);
}

.gm-editor__surface {
  min-height: 120px;
}

.gm-editor__surface .gm-action-item {
  background: var(--bg);
  border: 1px solid var(--border-soft);
  border-bottom: 1px solid var(--border-soft);
  padding: var(--space-2) var(--space-3);
}

.gm-editor__move {
  display: inline-flex;
  flex-direction: column;
  gap: 2px;
  margin-left: var(--space-2);
}

.gm-editor__move button {
  font-family: var(--font-mono);
  font-size: 10px;
  background: var(--bg-subtle);
  border: 1px solid var(--border-firm);
  color: var(--txt);
  padding: 0 var(--space-2);
  cursor: pointer;
  line-height: 1.4;
}

.gm-editor__move button:hover,
.gm-editor__move button:focus-visible {
  background: var(--gt);
  color: #ffffff;
}

.gm-editor__readout {
  display: block;
  margin-top: var(--space-4);
  background: var(--bg-subtle);
  padding: var(--space-3) var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  white-space: pre-wrap;
  min-height: 2em;
  border: 1px solid var(--border-soft);
}

.gm-editor--dragging { cursor: grabbing; }


/* ---------------------------------------------------------------------
  18.17 Slide (.gm-slide, .gm-slides)
   ---------------------------------------------------------------------
   Purpose: full-viewport presentation primitive. One slide = one viewport.
   When to use: inside slide-deck only.
   When NOT to use: as a hero/layout wrapper in any non-deck template.
   JS contract: enhancement only. Static fallback is mandatory and
   shows every slide stacked. JS adds .gm-slides--active, .gm-slide--current,
   and unhides nav. Esc exits presentation mode.
   Shape:
     <main class="gm-slides" aria-roledescription="slideshow" data-gm-slides>
       <section class="gm-slide gm-slide--title">
         <div class="gm-slide__inner">...</div>
       </section>
       <nav class="gm-slide__nav" hidden data-gm-slide-nav>...</nav>
     </main>
   --------------------------------------------------------------------- */

.gm-slides {
  display: block;
  margin: 0;
  padding: 0;
}

.gm-slide {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  padding: var(--space-7) var(--space-6);
  background: var(--bg);
  border-bottom: 1px solid var(--border-soft);
  scroll-snap-align: start;
}

.gm-slide__inner {
  width: 100%;
  max-width: 64rem;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  text-align: left;
  overflow-y: auto;
  max-height: calc(100vh - (var(--space-7) * 2));
}

.gm-slide__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--mu);
  margin: 0;
}

.gm-slide__title {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: clamp(2rem, 6vw, 3.6rem);
  line-height: 1.1;
  color: var(--txt);
  margin: 0;
}

.gm-slide__subtitle {
  font-size: 1.25rem;
  font-weight: 400;
  color: var(--mu);
  margin: 0;
}

.gm-slide--title {
  justify-content: center;
  align-items: center;
  background: var(--bg-subtle);
}

.gm-slide--title .gm-slide__inner { text-align: center; align-items: center; }

.gm-slide--divider {
  justify-content: center;
  align-items: center;
  background: var(--gt);
}

.gm-slide--divider .gm-slide__inner { text-align: center; align-items: center; }
.gm-slide--divider .gm-slide__title { color: var(--bg); }
.gm-slide--divider .gm-slide__eyebrow { color: var(--bg); opacity: 0.85; }

.gm-slide--close {
  justify-content: center;
  align-items: center;
  background: var(--bg-subtle);
}

.gm-slide--close .gm-slide__inner { text-align: center; align-items: center; }

/* Active (JS-on) presentation mode. */
.gm-slides--active {
  position: relative;
  height: 100vh;
  overflow: hidden;
}

.gm-slides--active .gm-slide {
  display: none;
  border-bottom: 0;
}

.gm-slides--active .gm-slide--current {
  display: flex;
}

.gm-slide__nav {
  position: fixed;
  bottom: var(--space-4);
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-4);
  background: var(--bg-subtle);
  border: 1px solid var(--border-soft);
  z-index: 10;
}

.gm-slide__nav[hidden] { display: none; }

.gm-slide__nav button {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 700;
  background: var(--bg);
  border: 1px solid var(--border-firm);
  color: var(--txt);
  padding: var(--space-2) var(--space-4);
  cursor: pointer;
}

.gm-slide__nav button:hover,
.gm-slide__nav button:focus-visible {
  background: var(--gt);
  color: var(--bg);
  border-color: var(--gt);
}

.gm-slide__counter {
  font-family: var(--font-mono);
  font-size: 14px;
  font-weight: 700;
  color: var(--mu);
  min-width: 4em;
  text-align: center;
}


/* ---------------------------------------------------------------------
  18.18 Reference header (.gm-reference-header)
   ---------------------------------------------------------------------
   Purpose: identification strip at the top of commercial documents.
   Reader knows in three seconds: reference, version, date, recipient.
   When to use: inside quote and scope only. Once per artefact.
   When NOT to use: internal reports (use .gm-page-header + .meta).
   Status pill vocabulary: Draft (info) / Final (ok) / Superseded (neutral).
   Shape:
     <header class="gm-reference-header">
       <div class="gm-reference-header__primary">
         <p class="gm-reference-header__eyebrow">Quote</p>
         <p class="gm-reference-header__ref">QT-2026-014</p>
         <p class="gm-reference-header__status">
           <span class="gm-pill gm-pill--ok">Final</span>
         </p>
       </div>
       <dl class="gm-reference-header__meta">
         <div><dt>Issued</dt><dd><time datetime="...">...</time></dd></div>
       </dl>
     </header>
   --------------------------------------------------------------------- */

.gm-reference-header {
  display: block;
  padding: var(--space-5) var(--space-6);
  background: var(--bg-subtle);
  border-top: 4px solid var(--gt);
  border-bottom: 1px solid var(--border-soft);
  border-radius: 0;
  margin: 0 0 var(--space-6);
}

.gm-reference-header__primary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-4);
}

.gm-reference-header__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--mu);
  margin: 0;
}

.gm-reference-header__ref {
  font-family: var(--font-mono);
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--txt);
  margin: 0;
}

.gm-reference-header__status {
  margin: 0 0 0 auto;
}

.gm-reference-header__meta {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-3) var(--space-5);
  margin: var(--space-4) 0 0;
}

.gm-reference-header__meta > div {
  margin: 0;
}

.gm-reference-header__meta dt {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--mu);
  margin: 0 0 var(--space-1);
}

.gm-reference-header__meta dd {
  font-size: 15px;
  font-weight: 400;
  color: var(--txt);
  margin: 0;
}


/* ---------------------------------------------------------------------
  18.19 Line items (.gm-line-items)
   ---------------------------------------------------------------------
   Purpose: itemised cost/scope table with sections, subtotals, and a
   prominent grand total.
   When to use: inside quote (primary), scope (totals summary). Once.
   When NOT to use: generic data table (use base <table>).
   Totals: STATIC TEXT. No JS math. The agent writes every number.
   Print: rows must not split, header/footer repeat per page, never
   orphan a section head at the bottom of a page.
   Shape:
     <figure class="gm-line-items" role="region" tabindex="0">
       <table>
         <caption class="visually-hidden">...</caption>
         <thead>...</thead>
         <tbody class="gm-line-items__section">
           <tr class="gm-line-items__section-head"><th colspan="5">...</th></tr>
           <tr>...line...</tr>
           <tr class="gm-line-items__subtotal">...</tr>
         </tbody>
         <tfoot class="gm-line-items__totals">
           <tr>...subtotal...</tr>
           <tr class="gm-line-items__grand-total"><th>Total</th><td>$...</td></tr>
         </tfoot>
       </table>
     </figure>
   --------------------------------------------------------------------- */

.gm-line-items {
  margin: var(--space-6) 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.gm-line-items table {
  width: 100%;
  border-collapse: collapse;
  font-size: 15px;
}

.gm-line-items thead th {
  font-family: var(--font-mono);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--mu);
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border-bottom: 2px solid var(--border-firm);
  background: transparent;
}

.gm-line-items__col-qty,
.gm-line-items__col-unit,
.gm-line-items__col-rate,
.gm-line-items__col-total {
  text-align: right;
  white-space: nowrap;
  width: auto;
}

.gm-line-items tbody td {
  padding: var(--space-3) var(--space-4);
  vertical-align: top;
  border-bottom: 1px solid var(--border-soft);
}

.gm-line-items tbody td:nth-child(2),
.gm-line-items tbody td:nth-child(3),
.gm-line-items tbody td:nth-child(4),
.gm-line-items tbody td:nth-child(5) {
  text-align: right;
  white-space: nowrap;
}

.gm-line-items__note {
  display: block;
  font-size: 13px;
  color: var(--mu);
  margin-top: var(--space-1);
}

.gm-line-items__section-head th {
  background: var(--bg-subtle);
  font-family: var(--font-mono);
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--gt);
  text-align: left;
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--border-firm);
  border-bottom: 1px solid var(--border-soft);
}

.gm-line-items__subtotal td {
  font-weight: 700;
  background: var(--bg-subtle);
  border-top: 1px solid var(--border-firm);
}

.gm-line-items__totals td,
.gm-line-items__totals th {
  padding: var(--space-3) var(--space-4);
  text-align: right;
  border-bottom: 1px solid var(--border-soft);
}

.gm-line-items__totals tr:first-child td {
  border-top: 2px solid var(--border-firm);
}

.gm-line-items__discount td {
  color: var(--mu);
  font-style: italic;
}

.gm-line-items__grand-total th,
.gm-line-items__grand-total td {
  font-family: var(--font-mono);
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--txt);
  border-top: 3px solid var(--gt);
  border-bottom: 0;
  padding: var(--space-4) var(--space-5);
  background: var(--bg-subtle);
  text-align: right;
}


/* ---------------------------------------------------------------------
  18.20 Acceptance block (.gm-acceptance-block)
   ---------------------------------------------------------------------
   Purpose: sign-off cell at the end of a commercial document. Two halves:
   electronic acceptance instructions, real ink signature lines. Optional
   decline path. Border (not fill) — reads as a form panel on screen and
   on paper without colour-management headaches.
   When to use: end of quote and scope. Once per artefact.
   Shape:
     <section class="gm-acceptance-block" aria-labelledby="ab-title">
       <h2 id="ab-title" class="gm-acceptance-block__title">Acceptance</h2>
       <div class="gm-acceptance-block__electronic">
         <p class="gm-acceptance-block__lead">...</p>
         <p class="gm-acceptance-block__expires"><time datetime="...">...</time></p>
       </div>
       <div class="gm-acceptance-block__sign">
         <div class="gm-acceptance-block__field">
           <span class="gm-acceptance-block__line" aria-hidden="true"></span>
           <span class="gm-acceptance-block__label">Signed — Recipient</span>
         </div>
         <div class="gm-acceptance-block__field">...Date...</div>
       </div>
       <p class="gm-acceptance-block__decline">...</p>
     </section>
   --------------------------------------------------------------------- */

.gm-acceptance-block {
  display: block;
  padding: var(--space-6);
  border: 2px solid var(--gt);
  border-radius: 0;
  background: var(--bg);
  margin: var(--space-7) 0 var(--space-5);
}

.gm-acceptance-block__title {
  font-family: var(--font-mono);
  font-size: 1.25rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--gt);
  margin: 0 0 var(--space-4);
}

.gm-acceptance-block__electronic {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
}

.gm-acceptance-block__lead {
  font-size: 16px;
  color: var(--txt);
  line-height: 1.5;
  margin: 0;
}

.gm-acceptance-block__expires {
  font-size: 14px;
  color: var(--mu);
  margin: 0;
}

.gm-acceptance-block__sign {
  display: grid;
  grid-template-columns: 2fr 1fr;
  gap: var(--space-5);
  margin-top: var(--space-4);
}

.gm-acceptance-block__field {
  display: flex;
  flex-direction: column;
}

.gm-acceptance-block__line {
  /* Empty signable region. The visible rule is drawn by border-bottom so
     the element itself can be 2.5em tall (room for a pen on screen) and
     swap to 1.8cm tall in print without redefining the rule colour. */
  display: block;
  width: 100%;
  height: 2.5em;
  background: transparent;
  border-bottom: 1px solid var(--txt);
  margin: var(--space-6) 0 var(--space-2);
}

.gm-acceptance-block__label {
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--mu);
}

.gm-acceptance-block__decline {
  font-size: 14px;
  color: var(--mu);
  margin: var(--space-5) 0 0;
  border-top: 1px solid var(--border-soft);
  padding-top: var(--space-3);
}


/* =====================================================================
  Shared utility: .visually-hidden
  ---------------------------------------------------------------------
  Used by table captions, screen-reader-only labels (e.g. the confidence
  pip label in §18.21 / §18.27). Standard sr-only pattern. Lives here
  because multiple components reference it; no token cost.
  ===================================================================== */

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


/* =====================================================================
  Shared utility: .gm-confidence
  ---------------------------------------------------------------------
  Three-step qualitative confidence indicator. Used by Assumption Ledger
  (§18.21) and Source Quality Panel (§18.27). Same scale (low/medium/
  high), same intent mapping (--stop / --warn / --ok), same markup.

  Shape:
    <span class="gm-confidence gm-confidence--high">
      <span class="gm-confidence__pip gm-confidence__pip--on" aria-hidden="true"></span>
      <span class="gm-confidence__pip gm-confidence__pip--on" aria-hidden="true"></span>
      <span class="gm-confidence__pip gm-confidence__pip--on" aria-hidden="true"></span>
      <span class="visually-hidden">Confidence: high</span>
    </span>

  Pips are circles by design (border-radius: 50%) — pips are not surfaces
  so the squared-card rule does not apply. Colour is never the sole
  carrier of meaning; the visually-hidden label is mandatory.

  Status mapping:
    --low    → --stop   (1 pip filled)
    --medium → --warn   (2 pips filled)
    --high   → --ok     (3 pips filled)
  ===================================================================== */

.gm-confidence {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 0;
}

.gm-confidence__pip {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--bg-subtle);
  border: 1px solid var(--border-firm);
  box-sizing: border-box;
}

.gm-confidence__pip--on {
  background: var(--mu);
  border-color: var(--mu);
}

.gm-confidence--low .gm-confidence__pip--on {
  background: var(--stop);
  border-color: var(--stop);
}

.gm-confidence--medium .gm-confidence__pip--on {
  background: var(--warn);
  border-color: var(--warn);
}

.gm-confidence--high .gm-confidence__pip--on {
  background: var(--ok);
  border-color: var(--ok);
}


/* =====================================================================
  18.21 Assumption ledger (.gm-assumption-ledger)
  ---------------------------------------------------------------------
  Purpose: surface the working assumptions behind an artefact so the
  reader can challenge any of them before approving the work.

  When to use: scopes, quotes, implementation plans, decision briefs,
  research briefs, tech-stacks where ownership/credentials are inferred.

  When NOT to use: for verified facts (use prose or status matrix), for
  things the agent doesn't know (use Open Questions §18.22), or as a
  defensive disclaimer dump.

  Required shape: <section class="gm-assumption-ledger"> containing a
  title, optional lead, and a real <table> wrapped in .table-scroll.
  Confidence uses the shared .gm-confidence utility (above).
  ===================================================================== */

.gm-assumption-ledger {
  margin: var(--space-6) 0;
}

.gm-assumption-ledger__title {
  /* inherits <h2> styling */
  margin: 0 0 var(--space-3);
}

.gm-assumption-ledger__lead {
  font-size: 15px;
  color: var(--mu);
  margin: 0 0 var(--space-4);
  max-width: 64ch;
}

.gm-assumption-ledger__table {
  overflow-x: auto;
}

.gm-assumption-ledger__table:focus-visible {
  outline: 2px solid var(--gt);
  outline-offset: 2px;
}

.gm-assumption-ledger table th[scope="row"] {
  text-align: left;
  font-weight: 700;
  line-height: 1.4;
  max-width: 24rem;
}

/* --compact modifier drops the Source column for tight layouts */
.gm-assumption-ledger--compact table thead th:nth-child(2),
.gm-assumption-ledger--compact table tbody td:nth-child(2) {
  display: none;
}


/* =====================================================================
  18.22 Open questions (.gm-open-questions)
  ---------------------------------------------------------------------
  Purpose: surface every unresolved question the artefact depends on —
  who can answer, why it matters, whether it blocks, when it's needed.

  When to use: discovery questionnaires, implementation plans, proposals
  with provisional scope, tech-stacks during onboarding.

  When NOT to use: for assumptions already made (use §18.21), action
  items (use §18.4 action lanes), or long FAQs (use glossary or prose).

  Required shape: <section class="gm-open-questions"> with header, an
  <ol> of items. Use --blocking modifier on items that block downstream
  work. Order conveys priority (blocking first).
  ===================================================================== */

.gm-open-questions {
  margin: var(--space-6) 0;
}

.gm-open-questions__head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin: 0 0 var(--space-4);
}

.gm-open-questions__title {
  margin: 0;
}

.gm-open-questions__counter {
  display: flex;
  gap: var(--space-2);
  margin: 0;
  flex-wrap: wrap;
}

.gm-open-questions__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.gm-open-questions__item {
  background: var(--bg);
  border: 1px solid var(--border-soft);
  border-left: 4px solid var(--mu);
  padding: var(--space-4) var(--space-5);
  border-radius: 0;
}

.gm-open-questions__item--blocking {
  border-left-color: var(--stop);
}

.gm-open-questions__item-head {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  margin: 0 0 var(--space-3);
  flex-wrap: wrap;
}

.gm-open-questions__id {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 12px;
  color: var(--mu);
  margin-left: auto;
}

.gm-open-questions__question {
  font-size: 16px;
  font-weight: 700;
  color: var(--txt);
  margin: 0 0 var(--space-2);
  line-height: 1.4;
}

.gm-open-questions__why {
  font-size: 15px;
  color: var(--mu);
  margin: 0 0 var(--space-3);
  line-height: 1.5;
}

.gm-open-questions__meta {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  flex-wrap: wrap;
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-soft);
}

.gm-open-questions__due {
  font-size: 14px;
  color: var(--mu);
}


/* =====================================================================
  18.23 Change summary (.gm-change-summary)
  ---------------------------------------------------------------------
  Purpose: compact "what changed since last version" block at the top of
  an artefact that supersedes a previous one. Always paired with
  .gm-reference-header citing the same version number.

  When to use: quote v2, scope v3, change-order, revised proposal.

  When NOT to use: on v1 artefacts, for internal commit log, or as a
  changelog longer than five rows (start fresh instead).

  Required shape: <aside class="gm-change-summary"> with head, then a
  real <table> wrapped in .table-scroll. Effect cell uses tinted text
  (not background) to stay legible; intent reinforces value already in
  the text ("+$340", "−$420").
  ===================================================================== */

.gm-change-summary {
  background: var(--bg-subtle);
  padding: var(--space-5) var(--space-6);
  border-left: 4px solid var(--info);
  border-radius: 0;
  margin: 0 0 var(--space-6);
}

.gm-change-summary__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin: 0 0 var(--space-4);
}

.gm-change-summary__title {
  margin: 0;
}

.gm-change-summary__since {
  font-size: 14px;
  color: var(--mu);
  margin: 0;
}

.gm-change-summary__table {
  overflow-x: auto;
}

.gm-change-summary__table:focus-visible {
  outline: 2px solid var(--gt);
  outline-offset: 2px;
}

.gm-change-summary table {
  background: var(--bg);
}

.gm-change-summary table th[scope="row"] {
  text-align: left;
  font-weight: 700;
  line-height: 1.4;
}

.gm-change-summary__effect {
  display: inline-block;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 14px;
  padding: 2px var(--space-2);
  background: var(--bg-subtle);
  color: var(--mu);
  white-space: nowrap;
}

.gm-change-summary__effect--ok { color: var(--ok); }
.gm-change-summary__effect--warn { color: var(--warn-text); }
.gm-change-summary__effect--stop { color: var(--stop-text); }
.gm-change-summary__effect--neutral { color: var(--mu); }


/* =====================================================================
  18.24 Glossary (.gm-glossary)
  ---------------------------------------------------------------------
  Purpose: translate technical/industry terms into plain English in
  context, so a client doesn't leave the document to understand it.

  When to use: client how-tos, tech-stacks shared with clients, feature
  explainers, client-audits, training lessons, decision helpers.

  When NOT to use: internal artefacts, long alphabetical dictionaries,
  or words the reader already knows (over-glossing reads as condescending).

  Required shape: <dl class="gm-glossary__list"> with one <div> per
  term/definition pair (valid HTML5).
  ===================================================================== */

.gm-glossary {
  margin: var(--space-6) 0;
}

.gm-glossary__title {
  margin: 0 0 var(--space-3);
}

.gm-glossary__lead {
  font-size: 15px;
  color: var(--mu);
  margin: 0 0 var(--space-4);
  max-width: 64ch;
}

.gm-glossary__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin: 0;
  padding: 0;
}

.gm-glossary__entry {
  padding: var(--space-4) var(--space-5);
  background: var(--bg-subtle);
  border-left: 3px solid var(--info);
  border-radius: 0;
}

.gm-glossary__term {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--gt);
  letter-spacing: 0.01em;
  margin: 0 0 var(--space-2);
}

.gm-glossary__body {
  margin: 0;
}

.gm-glossary__meaning {
  font-size: 16px;
  color: var(--txt);
  line-height: 1.5;
  margin: 0 0 var(--space-3);
}

.gm-glossary__why {
  font-size: 14px;
  color: var(--txt);
  margin: 0 0 var(--space-2);
  line-height: 1.5;
}

.gm-glossary__why-label {
  display: block;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--mu);
  margin: 0 0 2px;
}

.gm-glossary__related {
  font-size: 13px;
  color: var(--mu);
  margin: 0;
}

/* --compact modifier drops the why and related rows */
.gm-glossary--compact .gm-glossary__why,
.gm-glossary--compact .gm-glossary__related {
  display: none;
}


/* =====================================================================
  18.25 Before / after (.gm-before-after)
  ---------------------------------------------------------------------
  Purpose: show a single change as a two-column "was → is" panel, with
  reason and downstream impact below. The delta as a picture, not prose.

  When to use: project closeouts, change-orders, UX reviews, maintenance
  reports, debugging diaries, accessibility reviews.

  When NOT to use: three or more options (use .gm-comparison-grid),
  numeric trend (use coverage bar or KPI delta), code diffs (use .gm-diff).

  Required shape: <figure class="gm-before-after"> with figcaption, a
  __pair grid (1fr auto 1fr) of two __side panels and an __arrow, plus
  a __meta <dl> for why-changed / impact. Use --neutral modifier when
  neither side is "good" (e.g. debugging symptom before/after).
  ===================================================================== */

.gm-before-after {
  margin: var(--space-5) 0;
  padding: 0;
}

.gm-before-after__title {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--mu);
  margin: 0 0 var(--space-3);
}

.gm-before-after__pair {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  gap: var(--space-4);
  align-items: stretch;
}

.gm-before-after__side {
  padding: var(--space-4) var(--space-5);
  border: 1px solid var(--border-soft);
  background: var(--bg);
  border-radius: 0;
}

.gm-before-after__side--before {
  border-left: 4px solid var(--stop);
}

.gm-before-after__side--after {
  border-left: 4px solid var(--ok);
}

.gm-before-after--neutral .gm-before-after__side--before,
.gm-before-after--neutral .gm-before-after__side--after {
  border-left-color: var(--mu);
}

.gm-before-after__label {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--mu);
  margin: 0 0 var(--space-2);
}

.gm-before-after__body {
  font-size: 15px;
  color: var(--txt);
  margin: 0;
  line-height: 1.5;
}

.gm-before-after__body p { margin: 0 0 var(--space-2); }
.gm-before-after__body p:last-child { margin-bottom: 0; }

.gm-before-after__arrow {
  align-self: center;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 1.5rem;
  color: var(--mu);
  padding: 0 var(--space-2);
}

.gm-before-after__meta {
  margin: var(--space-4) 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-3) var(--space-5);
}

.gm-before-after__meta > div { margin: 0; }

.gm-before-after__meta dt {
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--mu);
  margin: 0 0 var(--space-1);
}

.gm-before-after__meta dd {
  font-size: 14px;
  color: var(--txt);
  margin: 0;
  line-height: 1.5;
}


/* =====================================================================
  18.26 Cause / effect chain (.gm-cause-effect)
  ---------------------------------------------------------------------
  Purpose: make a propagating failure or system risk visible as a
  directed chain — cause → effect → downstream impact → mitigation.

  When to use: incident reports, debugging diaries, tech-stack
  dependency-risk sections, accessibility reviews, audit findings where
  a single root issue cascades.

  When NOT to use: sequential workflows (use .gm-process-flow §18.12),
  timelines (use .gm-timeline §18.9), single-step chains (use a card).

  Required shape: <section class="gm-cause-effect"> with title, an <ol>
  of nodes (--cause / --effect / --downstream), plus an <aside>
  mitigation block. Node stripes are FIXED by type (not optional) so
  readers learn the grammar after two encounters.
  ===================================================================== */

.gm-cause-effect {
  margin: var(--space-5) 0;
  padding: var(--space-5);
  border: 1px solid var(--border-soft);
  background: var(--bg);
  border-radius: 0;
}

.gm-cause-effect__title {
  margin: 0 0 var(--space-4);
}

.gm-cause-effect__chain {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.gm-cause-effect__node {
  position: relative;
  padding: var(--space-3) var(--space-4);
  border-left: 4px solid var(--mu);
  background: var(--bg-subtle);
  border-radius: 0;
}

.gm-cause-effect__node--cause { border-left-color: var(--stop); }
.gm-cause-effect__node--effect { border-left-color: var(--warn); }
.gm-cause-effect__node--downstream { border-left-color: var(--info); }

.gm-cause-effect__chain > .gm-cause-effect__node:not(:last-child)::after {
  content: "↓";
  position: absolute;
  left: var(--space-4);
  bottom: calc(var(--space-3) * -1);
  transform: translateY(50%);
  font-family: var(--font-mono);
  font-weight: 700;
  color: var(--mu);
  line-height: 1;
  pointer-events: none;
}

.gm-cause-effect__node p {
  font-size: 15px;
  color: var(--txt);
  margin: 0;
  line-height: 1.5;
}

.gm-cause-effect__node ul {
  margin: 0;
  padding-left: var(--space-5);
  font-size: 15px;
  color: var(--txt);
  line-height: 1.5;
}

.gm-cause-effect__node ul li + li { margin-top: var(--space-1); }

.gm-cause-effect__label {
  display: block;
  font-family: var(--font-mono);
  font-weight: 700;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--mu);
  margin: 0 0 var(--space-1);
}

.gm-cause-effect__mitigation {
  margin: var(--space-4) 0 0;
  padding: var(--space-4) var(--space-5);
  background: var(--bg-subtle);
  border-left: 4px solid var(--ok);
}

.gm-cause-effect__mitigation p {
  font-size: 15px;
  color: var(--txt);
  margin: 0;
  line-height: 1.5;
}

.gm-cause-effect__label--mitigation {
  color: var(--ok);
}


/* =====================================================================
  18.27 Source quality panel (.gm-source-quality)
  ---------------------------------------------------------------------
  Purpose: tell the reader where the artefact's claims come from and
  how trustworthy each source is.

  When to use: research briefs, decision briefs, client decision
  helpers, tech-stacks, client-audits.

  When NOT to use: inline evidence for one claim (use .gm-evidence
  §18.6), assumptions (use §18.21), or long-form bibliography.

  Type → status mapping (rendered as a .gm-pill, never colour alone):
    primary    → --ok     direct observation; highest trust
    secondary  → --info   reliable but one step removed
    inferred   → --warn   agent reasoning fills a gap; needs validation
    unverified → --stop   not checked; do not act on alone

  Confidence reuses the shared .gm-confidence utility (above) so agents
  and readers don't context-switch between two grammars for the same
  idea.
  ===================================================================== */

.gm-source-quality {
  margin: var(--space-6) 0;
}

.gm-source-quality__title {
  margin: 0 0 var(--space-3);
}

.gm-source-quality__lead {
  font-size: 15px;
  color: var(--mu);
  margin: 0 0 var(--space-4);
  max-width: 64ch;
}

.gm-source-quality__table {
  overflow-x: auto;
}

.gm-source-quality__table:focus-visible {
  outline: 2px solid var(--gt);
  outline-offset: 2px;
}

.gm-source-quality table th[scope="row"] {
  text-align: left;
  font-weight: 400;
  line-height: 1.4;
  max-width: 24rem;
}


/* =====================================================================
  19. Component-level responsive overrides
   ===================================================================== */

@media (max-width: 600px) {
  .gm-kpi__value { font-size: 1.8rem; }

  .gm-timeline__item {
    grid-template-columns: 56px 20px 1fr;
  }

  .gm-timeline::before {
    left: calc(56px + var(--space-3) + 10px);
  }

  .gm-process-flow__node--branch {
    grid-template-columns: 1fr;
  }

  .gm-finding-card { padding: var(--space-4); }

  .gm-editor__head { flex-direction: column; align-items: flex-start; }

  .gm-acceptance-block__sign { grid-template-columns: 1fr; }

  .gm-reference-header { padding: var(--space-4) var(--space-5); }
  .gm-reference-header__status { margin-left: 0; }
  .gm-reference-header__ref { font-size: 1.25rem; }

  .gm-slide { padding: var(--space-6) var(--space-4); }
  .gm-slide__nav button { padding: var(--space-2) var(--space-3); }

  /* 18.25 Before/after — stack pair vertically, rotate arrow 90deg */
  .gm-before-after__pair {
    grid-template-columns: 1fr;
  }

  .gm-before-after__arrow {
    transform: rotate(90deg);
    padding: var(--space-2) 0;
    justify-self: center;
  }

  /* 18.21, 18.23, 18.27 — tighten table padding inside cards on narrow */
  .gm-change-summary {
    padding: var(--space-4) var(--space-5);
  }
}


/* =====================================================================
  19. Cover-note (Phase B addition)
   Wraps client-facing artefacts. Carries Jess's voice: warm opener,
   warm closer. Rendered above the card on client-facing templates;
   forbidden on internal templates. Lives once here, used by every
   client recipe (client-handover, client-proposal, client-audit,
   quote, scope) and the optional client-mode variants of design-
   exploration, decision-brief, process-flow, slide-deck, feature-
   explainer, custom-editor, runbook, research-brief).
   ===================================================================== */

.gm-cover-note {
  display: block;
  max-width: 68ch;
  margin: 0 0 var(--space-5);
  padding: var(--space-4) var(--space-5);
  background: var(--bg-subtle);
  border-left: 4px solid var(--gt);
  border-radius: 0 6px 6px 0;
  font-size: var(--text-base);
  color: var(--txt);
}

.gm-cover-note--closer {
  margin: var(--space-5) 0 0;
}

.gm-cover-note__opener,
.gm-cover-note__closer {
  font-weight: 700;
  color: var(--gt);
  margin: 0 0 var(--space-2);
}

.gm-cover-note--closer .gm-cover-note__closer {
  margin: var(--space-2) 0 0;
}

.gm-cover-note__sign {
  font-weight: 700;
  margin: 0;
  color: var(--txt);
}

.gm-cover-note__body p {
  margin: 0 0 var(--space-2);
}

.gm-cover-note__body p:last-child {
  margin-bottom: 0;
}


/* =====================================================================
  20. Component-level print overrides
   These live here (not in print.css) so the component CSS stays
   self-contained. print.css handles global chrome hiding.
   ===================================================================== */

@media print {
  .gm-editor__controls,
  .gm-editor__readout,
  .gm-editor__move {
    display: none;
  }

  .gm-kpi-strip,
  .gm-finding-grid,
  .gm-action-lanes--columns,
  .gm-comparison-grid,
  .gm-module-map__modules {
    /* keep grid layouts but avoid breaks mid-tile */
    page-break-inside: avoid;
    break-inside: avoid;
  }

  .gm-finding-card,
  .gm-comparison-card,
  .gm-process-flow__node,
  .gm-evidence,
  .gm-timeline__item,
  .gm-kpi,
  .gm-status-matrix tbody tr,
  .gm-heatmap tbody tr {
    page-break-inside: avoid;
    break-inside: avoid;
  }

  /* Coverage bars: percent text is already in .gm-coverage-bar__ratio
     (e.g. "13/14 (93%)") so meaning survives greyscale. Force the
     fill colour to print so the visual signal also lands, and give
     the track a 1px outline so the bar shape is unambiguous on paper. */
  .gm-coverage-bar__track {
    border: 1px solid #c9d6d1;
  }

  .gm-coverage-bar__fill {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .gm-diff__filelist { position: static; }

  .gm-cover-note {
    border: 1px solid #c9d6d1;
    background: #ffffff;
    page-break-inside: avoid;
    break-inside: avoid;
  }

  /* Alpha overlays print legibly already, but force colour-adjust so
     heatmap and diff cells keep their tint on paper. */
  .gm-heatmap__cell,
  .gm-diff__line--add,
  .gm-diff__line--del {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* 18.18 Reference header — keep the top stripe and subtle fill on paper. */
  .gm-reference-header {
    page-break-inside: avoid;
    break-inside: avoid;
    background: var(--bg-subtle) !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* 18.19 Line items — commercial print contract. Rows never split,
     header and footer repeat per page, section heads never orphan,
     grand total never separates from the preceding row. */
  .gm-line-items {
    overflow: visible;
    break-inside: auto;
  }

  .gm-line-items tr {
    page-break-inside: avoid;
    break-inside: avoid;
  }

  .gm-line-items thead {
    display: table-header-group;
  }

  .gm-line-items tfoot {
    display: table-footer-group;
  }

  .gm-line-items__section-head {
    page-break-after: avoid;
    break-after: avoid;
  }

  .gm-line-items__grand-total {
    page-break-before: avoid;
    break-before: avoid;
  }

  .gm-line-items__grand-total th,
  .gm-line-items__grand-total td,
  .gm-line-items__section-head th,
  .gm-line-items__subtotal td {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* 18.20 Acceptance block — the signable surface. Never split. Real ink
     line. 1.8cm of headroom above the rule so a pen has somewhere to go. */
  .gm-acceptance-block {
    page-break-inside: avoid;
    break-inside: avoid;
    page-break-before: avoid;
    break-before: avoid;
    padding: 1.2cm;
    border: 1.5pt solid var(--gt);
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .gm-acceptance-block__sign {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 1cm;
  }

  .gm-acceptance-block__line {
    margin-top: 1.8cm;
    height: 1.8cm;
    background: transparent;
    border-bottom: 0.5pt solid #000;
  }

  .gm-acceptance-block__decline { display: block; }

  /* 18.17 Slide — strip presentation mode for print. One slide per page. */
  .gm-slides--active {
    display: block;
    height: auto;
    overflow: visible;
    position: static;
  }

  .gm-slides--active .gm-slide,
  .gm-slide {
    display: flex !important;
    min-height: auto;
    page-break-after: page;
    break-after: page;
    padding: 2cm;
    border-bottom: 0;
  }

  .gm-slide:last-child {
    page-break-after: auto;
    break-after: auto;
  }

  .gm-slide__nav { display: none !important; }

  .gm-slide--divider {
    background: var(--gt) !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* 18.21 Assumption ledger, 18.27 Source quality — keep table rows
     intact across printed pages; let header repeat. */
  .gm-assumption-ledger__table,
  .gm-source-quality__table {
    overflow: visible;
  }

  .gm-assumption-ledger table tr,
  .gm-source-quality table tr {
    page-break-inside: avoid;
    break-inside: avoid;
  }

  .gm-assumption-ledger table thead,
  .gm-source-quality table thead {
    display: table-header-group;
  }

  /* Confidence pips: force fill so the colour signal survives greyscale
     adjacent to the visually-hidden text label. */
  .gm-confidence__pip,
  .gm-confidence__pip--on {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* 18.23 Change summary — info stripe must survive print. */
  .gm-change-summary {
    page-break-inside: avoid;
    break-inside: avoid;
    background: var(--bg-subtle) !important;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .gm-change-summary__table { overflow: visible; }

  /* 18.24 Glossary — each entry holds together. */
  .gm-glossary__entry {
    page-break-inside: avoid;
    break-inside: avoid;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* 18.25 Before/after — never split a pair, keep meta with it. */
  .gm-before-after {
    page-break-inside: avoid;
    break-inside: avoid;
  }

  .gm-before-after__side {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  /* 18.26 Cause/effect — keep the chain together if possible; if it
     must break, never orphan the mitigation aside. */
  .gm-cause-effect {
    page-break-inside: avoid;
    break-inside: avoid;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .gm-cause-effect__node,
  .gm-cause-effect__mitigation {
    page-break-inside: avoid;
    break-inside: avoid;
  }

  /* 18.22 Open questions — keep each item intact. */
  .gm-open-questions__item {
    page-break-inside: avoid;
    break-inside: avoid;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}
