/* erp-map.observer design tokens: the Observatory direction (D42, spec A9), with the values of
   prototype revision 004 (.ai/prototypes/discovery/site/revision-004/styles.css).
   Off-white paper, white cards and ink. Night blue for primary actions and the selected state,
   gold as a highlight only (never text), rust for ⚠ gaps, green for declared. Every text pair is
   AA; graph lines are at least 3:1 on white. Light scheme only.
   Fraunces (self-hosted, OFL: /assets/fonts/OFL.txt) is for headings and the wordmark only; body
   text stays on the system sans, module ids on the system mono.
   This file holds tokens and the @font-face only; components live in base.css. */

@font-face {
  font-family: "Fraunces";
  src: url("/assets/fonts/fraunces-latin.woff2") format("woff2");
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}

:root {
  --color-scheme: light;

  /* colour: surfaces */
  --color-bg: #f7f5ef;
  --color-surface: #ffffff;
  --color-surface-2: #f1eee6;
  --color-surface-3: #e9e5da;
  --color-row-hover: #fbfaf6;
  /* colour: text */
  --color-ink: #1b2330;
  --color-ink-2: #444e5d;
  --color-muted: #5f6877;
  /* colour: lines */
  --color-line: #e3ded2;
  --color-line-strong: #cbc4b4;
  /* colour: roles */
  --color-night: #1e3354;        /* primary actions, the selected state */
  --color-night-hover: #2a4470;
  --color-on-night: #ffffff;
  --color-link: #1d4f8a;
  --color-focus: #1d4f8a;
  --color-gold: #c48a24;         /* the monocle; a highlight only, never text */
  --color-gap: #a8401a;          /* undeclared in requires; always with ⚠ and a word (R14) */
  --color-gap-soft: #fbe9df;
  --color-ok: #24704d;           /* declared */
  --color-ok-soft: #e2f1e8;
  /* colour: code blocks */
  --color-code-bg: #17202c;
  --color-code-text: #e9edf3;
  --color-code-comment: #9fb0c4;
  --color-code-string: #f2c27a;

  /* graph */
  --graph-bg: var(--color-surface);
  --graph-node: var(--color-surface);
  --graph-node-stroke: var(--color-ink);
  /* Line tokens (A10 › UI/UX › Line tokens): each one clears 3:1 on white. D42's gold #c48a24 stays
     in --color-gold for accents that are not lines. */
  --graph-edge: #8a8f98;           /* a declared link, 0.9px; 3.25:1 */
  --graph-gap: #d0683d;            /* a gap, 1.6px with a diamond end mark; 3.67:1 */
  --graph-needs: #1d4f8a;          /* what the hovered module needs; 8.28:1 */
  --graph-used-by: #b8801f;        /* what uses it; 3.42:1 */
  /* the module page's links graph (A9) keeps its names and values */
  --graph-edge-gap: #c0501f;
  --graph-edge-soft: var(--graph-edge);
  --graph-edge-gap-soft: var(--graph-gap);
  --graph-dim-radial: .05;         /* the radial map's lines while one node is hovered or focused */
  /* Area colours (A10 › UI/UX › Area colours): dots and arcs only, never text. The dataviz reference
     order; starter and "Other" are two greys so they read as not part of an area. */
  --graph-area-0: #2a78d6;
  --graph-area-1: #1baf7a;
  --graph-area-2: #eda100;
  --graph-area-3: #e87ba4;
  --graph-area-4: #6250d6;
  --graph-area-starter: #8b8577;   /* 3.67:1 */
  --graph-area-other: #858c99;     /* 3.38:1, a cooler grey than the starter's */

  /* type */
  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif;
  --font-mono: ui-monospace, "SF Mono", "Cascadia Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  --font-heading: var(--font-display);
  --font-wordmark: var(--font-display);
  --font-graph: var(--font-body);
  --font-size-base: 16px;
  --font-line-height: 1.55;
  --font-size-h1: clamp(32px, 4.4vw, 48px);
  --font-size-h2: 26px;
  --font-size-h3: 19px;
  --font-size-wordmark: 21px;
  --font-size-small: 14px;
  --font-size-label: 13px;
  --font-weight-heading: 600;
  --font-weight-wordmark: 600;
  --font-weight-label: 600;
  --font-tracking-heading: -.01em;
  --font-line-height-heading: 1.15;

  /* space */
  --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 24px; --space-6: 32px;
  --space-7: 40px; --space-8: 56px;
  --space-gutter: 24px;
  --space-page-width: 1120px;

  /* shape */
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 14px;               /* speech bubble, chat messages */
  --radius-pill: 999px;
  --shadow-card: 0 1px 2px rgba(27, 35, 48, .05), 0 6px 24px rgba(27, 35, 48, .06);
  --shadow-raised: 0 1px 2px rgba(27, 35, 48, .12);  /* the pressed segment */
  --shadow-knob: 0 1px 2px rgba(27, 35, 48, .25);    /* a switch's knob */

  /* Atlas names base.css still uses, on Observatory values. They go once the A9 Phase 1 Steps
     move base.css onto the names above. */
  --color-surface-raised: var(--color-surface);
  --color-text: var(--color-ink);
  --color-heading: var(--color-ink);
  --color-text-muted: var(--color-muted);
  --color-border: var(--color-line);
  --color-border-strong: var(--color-line-strong);
  --color-accent: var(--color-night);
  --color-accent-soft: var(--color-surface-2);
  --line-height: var(--font-line-height);
  --h1-size: var(--font-size-h1);
  --h2-size: var(--font-size-h2);
  --heading-weight: var(--font-weight-heading);
  --label-size: var(--font-size-label);
  --label-transform: none;
  --label-tracking: 0;
}

@media (max-width: 860px) {
  :root { --space-gutter: 16px; }
}

/* Base layout on top of tokens.css: the document shell (header, nav, main, footer) and plain-page
   typography. A5/A6 add their own component styles beside this file; it stays generic. */

* {
  box-sizing: border-box;
}

html {
  color-scheme: var(--color-scheme);
}

body {
  margin: 0;
  min-height: 100vh;
  /* A flex column pins the footer to the bottom on a short page (main takes the spare height) */
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--font-size-base);
  line-height: var(--line-height);
}

a {
  color: var(--color-link);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
}

a:hover {
  text-decoration-thickness: 2px;
}

a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
}

/* A plain link gets rounded corners on its ring; a component with its own radius (a pill, an input)
   keeps it, because :where() adds no specificity */
:where(a, summary, [tabindex]):focus-visible {
  border-radius: 4px;
}

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

.skip-link {
  position: absolute;
  left: -999px;
  top: auto;
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface);
  color: var(--color-text);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-sm);
}

.skip-link:focus {
  left: var(--space-3);
  top: var(--space-3);
  z-index: 10;
}

/* Shared components (A9 Phase 1, Step 3), from prototype revision 004 and named after the tokens.
   Buttons, inputs, chips, pills, cards and segmented links. Pills and chips say their state in
   words; colour only repeats it (R14, WCAG 1.4.1). */

/* Buttons: primary (night) and quiet. Both are links or buttons. */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: 10px 20px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font: 600 15px / 1.2 var(--font-body);
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
}

.btn-primary {
  background: var(--color-night);
  color: var(--color-on-night);
}

.btn-primary:hover {
  background: var(--color-night-hover);
}

.btn-quiet {
  background: var(--color-surface);
  color: var(--color-ink);
  border-color: var(--color-line-strong);
}

.btn-quiet:hover {
  background: var(--color-surface-2);
}

.btn-sm {
  padding: 6px var(--space-4);
  font-size: var(--font-size-small);
}

/* A control that is on but cannot be switched off, or is not available: the word or state in the
   label carries it, the muted text only repeats it */
.btn[aria-disabled="true"] {
  background: var(--color-surface-2);
  border-color: var(--color-line);
  color: var(--color-muted);
  cursor: default;
}

/* Inputs: one box for text fields, search fields and text areas. The pill modifier is for
   search. */
.input {
  width: 100%;
  padding: 11px var(--space-4);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-ink);
  font: 16px / 1.4 var(--font-body);
}

.input::placeholder {
  color: var(--color-muted);
}

.input:focus-visible {
  border-color: var(--color-focus);
}

.input[aria-invalid="true"] {
  border-color: var(--color-gap);
}

textarea.input {
  resize: vertical;
}

.input-pill {
  border-radius: var(--radius-pill);
}

.hint {
  margin: 6px 0 0;
  font-size: var(--font-size-small);
  color: var(--color-muted);
}

/* Code inside a code block takes the block's font (MCP page); kept above the other `code` rules so the
   later, more specific ones still win where they apply */
.code code {
  font: inherit;
}

/* Chips: a module id or a short label, a link when it points somewhere */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px var(--space-3);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  color: var(--color-ink);
  font-size: var(--font-size-small);
  line-height: 1.3;
  text-decoration: none;
}

a.chip:hover {
  background: var(--color-surface-2);
}

.chip code {
  font-size: var(--font-size-label);
}

.chip .count {
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
}

/* Status pills: the state is a word ("Declared", "Gap"), the colour repeats it */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 10px;
  border-radius: var(--radius-pill);
  font-size: var(--font-size-label);
  font-weight: 600;
  white-space: nowrap;
}

.pill-gap {
  background: var(--color-gap-soft);
  color: var(--color-gap);
}

.pill-ok {
  background: var(--color-ok-soft);
  color: var(--color-ok);
}

.pill-plain,
.pill-starter {
  background: var(--color-surface-2);
  font-weight: 500;
}

.pill-plain {
  color: var(--color-ink-2);
}

.pill-starter {
  color: var(--color-muted);
}

/* Cards */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card);
}

/* Segmented links: every option is a link to the page of that state, so there is no Apply. The
   current option is raised and bold; a toggle that is on is the current option too (aria-current)
   and also carries a check mark (class on), so it does not rest on colour. The options may sit in a list. */
.seg {
  display: inline-flex;
  list-style: none;
  margin: 0;
  padding: 3px;
  background: var(--color-surface-2);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-pill);
}

.seg li {
  display: flex;
}

.seg a {
  padding: 5px 13px;
  border-radius: var(--radius-pill);
  color: var(--color-ink-2);
  font-size: var(--font-size-small);
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}

.seg a:hover {
  background: var(--color-surface);
  color: var(--color-ink);
}

.seg a[aria-current="true"] {
  background: var(--color-surface);
  color: var(--color-ink);
  box-shadow: var(--shadow-raised);
  font-weight: 600;
}

.seg a.on::before {
  content: "\2713  ";
  color: var(--color-ok);
}

.seg a[aria-disabled="true"],
.seg a.off {
  color: var(--color-muted);
}

.seg a[aria-disabled="true"] {
  cursor: default;
}

/* Header: wordmark, pill nav, compact search, pill version switch. The wrap is shared with the
   footer and main so the three line up. */
.wrap {
  max-width: var(--space-page-width);
  margin: 0 auto;
  padding: 0 var(--space-gutter);
}

.site-header {
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-line);
}

.site-header .wrap {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  min-height: 68px;
}

.wordmark {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--color-ink);
  text-decoration: none;
  font-family: var(--font-wordmark);
  font-size: var(--font-size-wordmark);
  font-weight: var(--font-weight-wordmark);
  font-variation-settings: "opsz" 36;
}

.nav {
  display: flex;
  gap: var(--space-1);
  margin-left: auto;
}

.nav a {
  padding: 7px var(--space-4);
  border-radius: var(--radius-pill);
  color: var(--color-ink-2);
  font-weight: 500;
  text-decoration: none;
}

.nav a:hover {
  background: var(--color-surface-2);
  color: var(--color-ink);
}

.nav a[aria-current="page"] {
  background: var(--color-night);
  color: var(--color-on-night);
}

main {
  flex: 1;
  width: 100%;
  max-width: var(--space-page-width);
  margin: 0 auto;
  padding: var(--space-5) var(--space-gutter);
}

main h1 {
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  font-size: var(--h1-size);
  color: var(--color-heading);
}

main h2 {
  font-family: var(--font-heading);
  font-weight: var(--heading-weight);
  font-size: var(--h2-size);
  color: var(--color-heading);
}

.site-footer {
  margin-top: var(--space-7);
  background: var(--color-surface-2);
  border-top: 1px solid var(--color-line);
  color: var(--color-ink-2);
  font-size: var(--font-size-small);
}

.site-footer .wrap {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-2) var(--space-4);
  padding-top: 22px;
  padding-bottom: 22px;
}

.site-footer p {
  margin: 0;
}

/* Map page module list */

.module-list {
  list-style: none;
  margin: var(--space-4) 0;
  padding: 0;
  display: grid;
  gap: var(--space-2);
}

.module-list li {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-line);
}

.module-main {
  display: grid;
  gap: 2px;
  min-width: 0;
}

/* A long title or id wraps instead of widening the row past a phone screen (390px) */
.module-list li a {
  min-width: 0;
  overflow-wrap: anywhere;
}

.module-id {
  font-family: var(--font-mono);
  font-weight: 600;
}

.module-title {
  overflow-wrap: anywhere;
}

.module-area {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-ink-2);
  font-size: var(--font-size-label);
}

/* The area's dot, beside its name (the name is the text; the dot is decoration) */
.area-dot {
  display: inline-block;
  flex: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--area, var(--graph-area-other));
}

.module-counts {
  color: var(--color-muted);
  font-size: var(--font-size-label);
}

.module-pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Header search: a compact pill made of the shared input and button */
.search-form {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.search-form .input {
  width: 168px;
  padding: 6px var(--space-4);
}

/* Wide screens: the placeholder "Find a module" fits in the pill */
@media (min-width: 1100px) {
  .search-form .input {
    width: 200px;
  }
}

/* Module page header */
.module-meta {
  font-family: var(--font-mono);
  color: var(--color-text-muted);
}

.module-meta .chip {
  font-family: var(--font-body);
}

.method-note {
  color: var(--color-text-muted);
  font-size: var(--label-size);
}

/* Header version switch: a pill that opens a list, with no script (a <details>) */
.version-switch {
  position: relative;
}

.version-switch summary {
  list-style: none;
  cursor: pointer;
  padding: 6px var(--space-4);
  border: 1px solid var(--color-line-strong);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  font-size: var(--font-size-small);
  font-weight: 500;
}

.version-switch summary::-webkit-details-marker {
  display: none;
}

.version-switch summary::after {
  content: " \25BE";
  color: var(--color-muted);
}

.version-switch ul {
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  z-index: 5;
  min-width: 170px;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-card);
}

.version-switch li a {
  display: block;
  padding: 6px 10px;
  border-radius: 6px;
  color: var(--color-ink);
  font-size: var(--font-size-small);
  text-decoration: none;
}

.version-switch li a:hover {
  background: var(--color-surface-2);
}

.version-switch li a[aria-current="true"] {
  font-weight: 600;
}

/* Narrow screens: the nav takes its own row, the search another, the version pill stays beside the
   wordmark. Nothing is wider than the viewport (390px, no horizontal page scroll). */
@media (max-width: 859px) {
  .site-header .wrap {
    gap: 10px var(--space-4);
    padding-top: 10px;
    padding-bottom: 10px;
  }

  .nav {
    order: 3;
    width: 100%;
    margin-left: 0;
  }

  .search-form {
    order: 4;
    width: 100%;
  }

  .search-form label {
    flex: 1 1 auto;
    min-width: 0;
  }

  .search-form .input {
    width: 100%;
  }

  .version-switch {
    margin-left: auto;
  }

  .version-switch .long {
    display: none;
  }
}

/* Map graph (A5, spec: .ai/specs/2026-10-30-module-map-graph.md › UI/UX), ported from the
   prototype revision-003 onto tokens. Colour only repeats the line pattern (R14, WCAG 1.4.1):
   the dash pattern carries the class, the --graph-* colour duplicates it */
.notice {
  overflow-wrap: anywhere;
  border: 1px solid var(--color-line);
  border-left: 3px solid var(--color-line-strong);
  border-radius: var(--radius-sm);
  padding: 14px var(--space-4);
  margin: var(--space-3) 0;
  background: var(--color-surface-2);
  color: var(--color-ink-2);
  font-size: var(--font-size-small);
}

/* A message that needs attention keeps its words; the rust edge only repeats it */
.notice[role="alert"] {
  border-left-color: var(--color-gap);
  color: var(--color-ink);
}

.notice p {
  margin: 0 0 var(--space-2);
}

.small {
  font-size: var(--label-size);
}

.muted {
  color: var(--color-text-muted);
}

/* Contact form (A7, spec: .ai/specs/2026-11-07-contact-form.md › UI/UX). Fields are full width at
   every size; the Turnstile widget is data-size="flexible", so it fits 340px with 16px gutters */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: 18px;
  max-width: 720px;
  margin-top: var(--space-5);
}

.contact-form .field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.contact-form label {
  font-size: var(--font-size-small);
  font-weight: 600;
}

.field-error {
  margin: 0;
  color: var(--color-gap);
}

.contact-notice {
  padding: 14px var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--color-surface-2);
  color: var(--color-ink-2);
  font-size: var(--font-size-small);
}

.contact-notice h2 {
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: 600;
  margin: 0 0 var(--space-2);
  color: var(--color-ink);
}

.contact-notice p {
  margin: 0;
}

.contact-form button {
  align-self: flex-start;
}

.map-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  align-items: center;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border);
}

.tb-item {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.tb-item > span {
  font-size: var(--label-size);
  text-transform: var(--label-transform);
  letter-spacing: var(--label-tracking);
  color: var(--color-text-muted);
}

.map-toolbar > * {
  min-width: 0;
}

/* The toolbar's segments may wrap on a narrow screen instead of scrolling the page sideways */
.map-toolbar .seg {
  flex-wrap: wrap;
  max-width: 100%;
}

/* The starter switch (A10, spec: .ai/specs/2026-11-11-radial-module-map.md › What the map shows):
   a link to the other state. The knob only repeats the state, which the link says in words */
.switch {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: var(--space-1) 6px;
  border-radius: var(--radius-sm);
  color: var(--color-ink-2);
  font-size: var(--font-size-small);
  font-weight: 500;
  text-decoration: none;
}

.switch:hover {
  color: var(--color-ink);
  background: var(--color-surface-2);
}

.switch .track {
  position: relative;
  flex: none;
  width: 36px;
  height: 20px;
  border-radius: var(--radius-pill);
  background: var(--color-line-strong);
}

.switch .knob {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--color-surface);
  box-shadow: var(--shadow-knob);
}

.switch.is-on .track {
  background: var(--color-night);
}

.switch.is-on .knob {
  left: 18px;
}

/* Radial map (A10 › Proposed Solution 3–6, UI/UX): modules on a circle by area, links bundled
   through each area's hub. Each node (`a.n`, or a focusable `g.n` for a package) holds its dot,
   its label, copies of its own links (`.hl-out` what it needs, `.hl-in` what uses it) and its
   card (`.tip`), so hover and focus need no script. This block lays the map out, draws it at rest
   and answers hover and focus; the colours are the --graph-* tokens (A10-P2-S4) */
.map-card {
  position: relative;
  margin-top: var(--space-3);
  padding: var(--space-2);
}

/* On a narrow screen with view=graph the map keeps its width and scrolls inside its card */
.map-scroll {
  overflow-x: auto;
}

/* The text takes its size and colour from here; every shape sets its own fill */
svg.radial {
  display: block;
  width: 100%;
  min-width: 760px;
  height: auto;
  font-family: var(--font-graph);
  font-size: 12.5px;
  fill: var(--color-ink-2);
}

.radial .mono {
  font-family: var(--font-mono);
}

/* A declared link is thin and grey; a gap is rust, thicker and ends in a diamond (R14) */
.radial .e,
.radial .k {
  fill: none;
  stroke: var(--graph-edge);
  stroke-width: 0.9;
  pointer-events: none;
}

.radial .e.gap,
.radial .k.gap {
  stroke: var(--graph-gap);
  stroke-width: 1.6;
}

.radial .c-optional {
  stroke-dasharray: 5 4;
}

.radial .c-collaboration {
  stroke-dasharray: 1.5 3.5;
  stroke-linecap: round;
}

.radial .gap-mark {
  fill: var(--graph-gap);
}

.radial .k.k-out {
  stroke: var(--graph-needs);
  stroke-width: 1.8;
}

.radial .k.k-in {
  stroke: var(--graph-used-by);
  stroke-width: 1.8;
}

.radial .head-out {
  fill: var(--graph-needs);
}

.radial .head-in {
  fill: var(--graph-used-by);
}

.radial .hl-out,
.radial .hl-in {
  fill: none;
}

/* The copies and the card are drawn for the hovered or focused node only */
.radial .n .hl-out,
.radial .n .hl-in,
.radial .tip {
  display: none;
  pointer-events: none;
}

/* An area gives its colour to its dots, its arc and the dot in a card, and to the dots of the module
   list, the module header and the links graph, so a module has one colour everywhere. A node with no
   area (the package layer) keeps the ink */
.area-0 {
  --area: var(--graph-area-0);
}

.area-1 {
  --area: var(--graph-area-1);
}

.area-2 {
  --area: var(--graph-area-2);
}

.area-3 {
  --area: var(--graph-area-3);
}

.area-4 {
  --area: var(--graph-area-4);
}

.area-starter {
  --area: var(--graph-area-starter);
}

.area-other {
  --area: var(--graph-area-other);
}

.radial .dot,
.radial .tip-dot {
  fill: var(--area, var(--graph-node-stroke));
  stroke: var(--graph-bg);
  stroke-width: 2;
}

.radial .arc {
  fill: none;
  stroke: var(--area, var(--color-line-strong));
  stroke-width: 4;
  stroke-linecap: round;
}

/* Hover and focus (no script): the node's own links come back in colour, its card appears and the
   ring marks the dot. Keyboard focus gets the same as the pointer. Where :has() is missing the
   highlight and the card still work; only the dimming below is lost */
.radial .n:focus {
  outline: none;
}

.radial .n:is(:hover, :focus-visible) .hl-out {
  display: inline;
  stroke: var(--graph-needs);
  stroke-width: 1.8;
}

.radial .n:is(:hover, :focus-visible) .hl-in {
  display: inline;
  stroke: var(--graph-used-by);
  stroke-width: 1.8;
}

.radial .n:is(:hover, :focus-visible) .tip {
  display: inline;
}

.radial .n:is(:hover, :focus-visible) .dot {
  stroke: var(--color-ink);
  stroke-width: 3;
}

.radial:has(.n:is(:hover, :focus-visible)) .e {
  opacity: var(--graph-dim-radial);
}

/* The swap is instant: nothing on the map is animated */
@media (prefers-reduced-motion: reduce) {
  .radial,
  .radial * {
    transition: none;
  }
}

.radial .area-name {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* The cards in the top corners: the default card or the node's card on the left, the legend on
   the right */
.radial .pane rect {
  fill: var(--color-surface);
  stroke: var(--color-line);
}

.radial .pane {
  font-size: 13px;
}

.radial .pane-head {
  font-weight: 700;
  fill: var(--color-ink);
}

.radial .tip-num {
  font-weight: 600;
  fill: var(--color-ink);
}

.radial .tip-gap {
  fill: var(--color-gap);
}

.radial .tip-hint {
  fill: var(--color-muted);
}

.map-foot {
  margin-top: var(--space-1);
  padding: 14px var(--space-4) 10px;
  border-top: 1px solid var(--color-line);
}

.map-foot p {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-small);
  color: var(--color-ink-2);
}

/* Narrow screens (< 860px): one sentence instead of the map, unless view=graph asked for it */
.map-narrow {
  display: none;
  margin-top: var(--space-3);
  padding: var(--space-4) 18px;
}

.map-narrow p {
  margin: 0 0 var(--space-2);
}

.map-narrow p:last-child {
  margin: 0;
}

@media (max-width: 859px) {
  .map-view:not(.show-narrow) {
    display: none;
  }

  .map-narrow {
    display: block;
  }
}

.skip-graph {
  position: absolute;
  left: -999px;
}

.skip-graph:focus {
  left: var(--space-3);
  top: var(--space-5);
  z-index: 2;
  padding: var(--space-1) var(--space-2);
  background: var(--color-surface);
}

.legend-sample {
  vertical-align: middle;
}

/* Home hero (A9 Phase 2, spec: .ai/specs/2026-11-11-redesign-observatory.md › Proposed Solution 3):
   the question, one large search and four example modules, with the observer owl and its bubble
   (A11) in a second column; under 860px it is one column with the owl row first. */
.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  align-items: center;
  gap: var(--space-5) 40px;
  padding: var(--space-7) 0 var(--space-6);
}

.hero h1 {
  margin: 0;
}

.hero h1 em {
  font-style: italic;
  font-weight: 500;
  color: var(--color-night);
}

.lede {
  max-width: 40em;
  margin: var(--space-4) 0 0;
  font-size: 19px;
  color: var(--color-ink-2);
}

.hero-search {
  display: flex;
  gap: 10px;
  max-width: 620px;
  margin-top: 28px;
}

.hero-search .input {
  width: auto;
  flex: 1 1 auto;
  min-width: 0;
  padding: 14px 18px;
  border-width: 2px;
  font-size: 18px;
}

.hero-search .btn {
  justify-content: center;
  padding: 14px 24px;
  font-size: 16px;
}

.hero-examples {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: 14px;
  font-size: var(--font-size-small);
  color: var(--color-muted);
}

/* An example the version does not have: the same chip, with no link and a quieter word */
.hero-examples .chip:not(a) {
  color: var(--color-muted);
}

/* The owl and its bubble: the bubble is a card with a tail pointing up at the owl. The number in it
   is rust when it counts gaps and green when everything is declared, always with words. */
.hero-owl {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
}

.bubble {
  position: relative;
  max-width: 280px;
  margin: 0;
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  font-size: 15px;
  line-height: 1.45;
}

.bubble::before {
  content: "";
  position: absolute;
  top: -8px;
  left: 50%;
  width: 14px;
  height: 14px;
  margin-left: -7px;
  background: var(--color-surface);
  border-left: 1px solid var(--color-line);
  border-bottom: 1px solid var(--color-line);
  transform: rotate(135deg);
}

/* Module page header: the title block on the left, the owl and its bubble on the right. The
   bubble's tail points left at the owl, the owl is above-left of the text on a narrow screen. */
.module-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-6);
  align-items: start;
}

.module-owl {
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
  max-width: 360px;
}

.module-owl .bubble {
  margin-top: var(--space-4);
}

.module-owl .bubble::before {
  top: 26px;
  left: -8px;
  margin-left: 0;
  transform: rotate(45deg);
}

.bubble-gap strong {
  color: var(--color-gap);
}

.bubble-ok strong {
  color: var(--color-ok);
}

@media (max-width: 859px) {
  .hero {
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
  }

  .module-head {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }

  .module-owl {
    order: -1;
  }

  .hero-owl {
    flex-direction: row;
    order: -1;
  }

  .bubble::before {
    top: 26px;
    left: -8px;
    margin-left: 0;
    transform: rotate(45deg);
  }
}

@media (max-width: 599px) {
  .hero {
    padding: var(--space-5) 0 var(--space-4);
  }

  .hero-search {
    flex-direction: column;
  }

  .hero-search .input {
    width: 100%;
  }
}

/* Stat tiles (A9 Phase 2, spec: .ai/specs/2026-11-11-redesign-observatory.md › Proposed Solution 3):
   three `.card`s under the hero. The gap tile's number is in the gap colour, with its icon and
   words (R14). On a narrow screen each tile is a row: the number, then the words. */
.stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  margin: 0 0 var(--space-5);
}

.stat {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 18px 20px;
}

.stat-value {
  font-family: var(--font-display);
  font-size: 34px;
  font-weight: 600;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.stat-label {
  color: var(--color-ink-2);
  font-size: 15px;
  overflow-wrap: anywhere;
}

.stat-note {
  color: var(--color-muted);
  font-size: var(--font-size-small);
}

.stat-gap .stat-value {
  color: var(--color-gap);
}

@media (max-width: 599px) {
  .stats {
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
  }

  .stat {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: baseline;
    column-gap: var(--space-3);
    padding: 12px 16px;
  }

  .stat-value {
    grid-row: span 2;
    font-size: 26px;
  }

  .stat-label,
  .stat-note {
    grid-column: 2;
  }
}

/* State pages (A9, spec: .ai/specs/2026-11-11-redesign-observatory.md › Proposed Solution 6): a
   centred heading, one sentence and the next steps as chips or buttons, under the observer owl
   (A11) in the mood the state names. */
.state {
  text-align: center;
  padding: var(--space-8) 0 var(--space-6);
}

.state h1 {
  margin: 0;
  font-size: clamp(28px, 5vw, 38px);
}

.state p {
  max-width: 34em;
  margin: 14px auto 0;
  color: var(--color-ink-2);
  font-size: 18px;
  overflow-wrap: anywhere;
}

.state .chips {
  justify-content: center;
  margin-top: 22px;
}

/* Module page body (A6, spec: .ai/specs/2026-11-04-module-pages.md › UI/UX), ported from the
   prototype revision-003 onto tokens. Layers are named columns and classes are words (R10, R14);
   colour only marks the gap word, which the text already says */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Answer cards (A9 Phase 3): the count leads, the pills split it, the chips name the modules.
   Two cards side by side; they stack on a narrow screen. A gap keeps its icon and its word (R14) */
.answers {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-4);
  margin: var(--space-4) 0;
}

.answer {
  min-width: 0;
  padding: var(--space-4) var(--space-5);
  overflow-wrap: anywhere;
}

.answer h2 {
  margin: 0;
  font-size: 21px;
}

.answer h3 {
  margin: var(--space-4) 0 var(--space-2);
  font-family: var(--font-body);
  font-size: var(--font-size-small);
  font-weight: 600;
  color: var(--color-ink-2);
}

.answer p {
  margin: var(--space-2) 0 0;
}

.answer .big {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  margin: var(--space-3) 0 var(--space-1);
}

.answer .big b {
  font-family: var(--font-display);
  font-size: 44px;
  line-height: 1;
  font-weight: 600;
}

.answer .big-unit {
  color: var(--color-ink-2);
}

.answer .split {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.answer .split .pill {
  white-space: normal;
}

@media (max-width: 859px) {
  .answers {
    grid-template-columns: 1fr;
  }
}

/* The module tables sit in a card; pills carry each state in words (the shared .pill variants) */
.tablecard {
  overflow: hidden;
  margin: var(--space-3) 0;
}

.link-table {
  border-collapse: collapse;
  width: 100%;
  margin: 0;
}

.link-table th,
.link-table td {
  text-align: left;
  vertical-align: top;
  padding: 12px 14px;
  overflow-wrap: anywhere;
}

.link-table thead th {
  border-bottom: 1px solid var(--color-line);
  font-size: var(--label-size);
  font-weight: 600;
  text-transform: var(--label-transform);
  letter-spacing: var(--label-tracking);
  color: var(--color-muted);
}

.link-table tbody th {
  font-weight: normal;
}

.link-table tbody th a {
  text-decoration: none;
}

.link-table tbody th a:hover {
  text-decoration: underline;
}

.link-table tbody th code {
  font-family: var(--font-mono);
  font-weight: 600;
}

.link-row {
  border-bottom: 1px solid var(--color-line);
}

.link-table tbody:last-of-type {
  border-bottom: 0;
}

.link-row .ev-row td {
  padding-top: 0;
  font-size: var(--font-size-small);
}

.starter-group {
  margin: var(--space-2) 0;
}

.starter-group > summary {
  cursor: pointer;
  padding: var(--space-2) 0;
  font-weight: 600;
}

.link-row details > summary {
  cursor: pointer;
  color: var(--color-link);
}

.starter-group:target > summary {
  outline: 2px solid var(--color-focus);
  outline-offset: 2px;
}

#facts details > summary {
  cursor: pointer;
  color: var(--color-link);
}

/* A row reached through its #needs-{id} / #used-by-{id} link: an outline and a text marker, not
   colour alone */
.link-row:target {
  outline: 2px solid var(--color-focus);
  outline-offset: -2px;
  background: var(--color-accent-soft);
}

.link-row:target tr:first-child th::before {
  content: "↳ ";
  color: var(--color-accent);
}

.forward {
  display: block;
}

.ev-list {
  margin: var(--space-1) 0;
  padding-left: var(--space-5);
  overflow-wrap: anywhere;
}

.ev-list li {
  margin: var(--space-1) 0;
}

#earlier-gaps ul,
#unresolved ul,
#facts ul {
  overflow-wrap: anywhere;
}

#facts details {
  margin: var(--space-1) 0;
}

.cell-label {
  display: none;
}

/* LLM-written description (R16): the dashed tag says "Written by an LLM" in words */
.llm-description .tag {
  display: inline-block;
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-sm);
  padding: 0 var(--space-1);
  font-size: var(--label-size);
  color: var(--color-text-muted);
  white-space: nowrap;
}

/* Links graph (A9 Phase 3): what uses the module, the module, what it needs. The pattern carries
   the class (solid required, dashed optional, dotted collaboration, dash-dot declared only), the
   colour the gap (R14); every line is at least 3:1 on the card. It keeps its width and scrolls
   inside the card on a narrow screen, so the page never scrolls sideways */
.links-card {
  margin: var(--space-4) 0;
  padding: var(--space-2) var(--space-3) var(--space-1);
}

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

svg.links-svg {
  display: block;
  width: 100%;
  min-width: 640px;
  height: auto;
  font-family: var(--font-graph);
}

svg .ln-edge {
  fill: none;
  stroke: var(--graph-edge-soft);
  stroke-width: 1.5;
  pointer-events: none;
}

svg .ln-edge.ln-optional {
  stroke-dasharray: 6 4;
}

svg .ln-edge.ln-collaboration {
  stroke-dasharray: 1.5 4;
  stroke-linecap: round;
}

svg .ln-edge.ln-requires-only {
  stroke-width: 1;
  stroke-dasharray: 10 3 2 3;
}

svg .ln-edge.gap {
  stroke: var(--graph-edge-gap);
}

/* A gap into a starter module is lighter and thinner than a plain gap (1.5), so it does not differ
   by colour alone (R14, WCAG 1.4.1) */
svg .ln-edge.gap.gap-starter {
  stroke: var(--graph-edge-gap-soft);
  stroke-width: 1;
}

svg .ln-head {
  fill: var(--graph-edge-soft);
}

svg .ln-head.ln-head-gap {
  fill: var(--graph-edge-gap);
}

svg .ln-side {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  fill: var(--color-muted);
}

svg .ln-centre .ln-dot {
  fill: var(--color-night);
  stroke: var(--graph-bg);
  stroke-width: 3;
}

svg .ln-centre .ln-label {
  font-size: 15px;
  font-weight: 700;
  font-family: var(--font-mono);
  fill: var(--color-ink);
}

svg .ln-node .ln-dot {
  fill: var(--area, var(--graph-node));
  stroke: var(--graph-node-stroke);
  stroke-width: 1.5;
}

svg .ln-node.base .ln-dot {
  fill: var(--graph-area-starter);
}

svg .ln-node.gap .ln-dot {
  stroke: var(--graph-edge-gap);
}

svg .ln-node .ln-label,
svg .ln-more .ln-label {
  font-size: 13px;
  fill: var(--color-ink-2);
}

svg .ln-more .ln-label {
  font-style: italic;
}

svg .ln-node.gap .ln-label {
  fill: var(--color-gap);
}

svg .ln-node:hover .ln-label,
svg .ln-more:hover .ln-label {
  text-decoration: underline;
}

svg .ln-node:focus,
svg .ln-more:focus {
  outline: none;
}

svg .ln-node:focus-visible .ln-dot {
  stroke: var(--color-focus);
  stroke-width: 3.5;
}

svg .ln-node:focus-visible .ln-label,
svg .ln-more:focus-visible .ln-label {
  fill: var(--color-focus);
  text-decoration: underline;
  font-weight: 700;
}

.links-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  padding: var(--space-2) var(--space-1) var(--space-1);
  border-top: 1px solid var(--color-line);
  font-size: var(--label-size);
  color: var(--color-ink-2);
}

.links-legend > span {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

/* Narrow screens: each link becomes a stacked block, every cell named by its column (the header
   row stays for screen readers only), so nothing scrolls sideways */
@media (max-width: 599px) {
  .link-table,
  .link-table tbody,
  .link-table tr,
  .link-table th,
  .link-table td {
    display: block;
  }

  .link-table thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
  }

  .link-table tbody th,
  .link-table tbody td {
    padding: var(--space-1) var(--space-2);
  }

  .link-row {
    padding: var(--space-2) 0;
  }

  .state {
    padding-top: var(--space-5);
  }

  .cell-label {
    display: inline;
    font-size: var(--label-size);
    text-transform: var(--label-transform);
    letter-spacing: var(--label-tracking);
    color: var(--color-text-muted);
  }
}

/* MCP page (A9 Phase 4): three numbered steps, code blocks that scroll inside their own box, and a
   card per tool. The code colours are the tokens; no client script (no copy button). */
.steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-4);
  margin: var(--space-6) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
}

.step {
  min-width: 0;
  padding: 20px 22px;
  counter-increment: step;
}

.step h2 {
  display: flex;
  gap: 10px;
  align-items: center;
  margin: 0;
  font-size: var(--font-size-h3);
}

.step h2::before {
  content: counter(step);
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-night);
  color: var(--color-on-night);
  font: 700 14px var(--font-body);
}

.step p {
  margin: var(--space-2) 0 0;
  color: var(--color-ink-2);
  font-size: 15px;
}

pre.code {
  margin: var(--space-3) 0 0;
  padding: 14px 16px;
  overflow-x: auto;
  border-radius: var(--radius-sm);
  background: var(--color-code-bg);
  color: var(--color-code-text);
  font-family: var(--font-mono);
  font-size: 13px;
  line-height: 1.55;
}

.section-note {
  max-width: 44em;
  margin: var(--space-2) 0 0;
  color: var(--color-ink-2);
}

.tools {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
  gap: 14px;
  margin: var(--space-4) 0 0;
  padding: 0;
  list-style: none;
}

.tool {
  min-width: 0;
  padding: 16px 18px;
  overflow-wrap: anywhere;
}

.tool h3 {
  margin: 0;
  font-family: var(--font-body);
  font-size: 15px;
  font-weight: 700;
  color: var(--color-night);
}

.tool p {
  margin: 6px 0 0;
  color: var(--color-ink-2);
  font-size: 15px;
}

.tool .q {
  margin-top: var(--space-2);
  color: var(--color-muted);
  font-size: var(--font-size-small);
  font-style: italic;
}

@media (max-width: 859px) {
  .steps {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* The sample conversation on /mcp: the user's question, the tool call, the assistant's answer */
.convo {
  display: grid;
  gap: 14px;
  margin: var(--space-4) 0 0;
  padding: 22px 24px;
}

.msg {
  max-width: 760px;
  min-width: 0;
  overflow-wrap: anywhere;
}

.msg .who {
  margin-bottom: var(--space-1);
  color: var(--color-muted);
  font-size: var(--font-size-label);
  font-weight: var(--font-weight-label);
}

.msg .body {
  color: var(--color-ink-2);
}

.msg.user .body {
  display: inline-block;
  padding: 10px 14px;
  border-radius: var(--radius-lg);
  background: var(--color-surface-2);
  color: var(--color-ink);
}

.msg.tool .body {
  padding-left: var(--space-3);
  border-left: 3px solid var(--color-gold);
  color: var(--color-ink-2);
  font-family: var(--font-mono);
  font-size: var(--font-size-small);
}

/* The observer owl (A11): a span showing one cell of a 3x3 sprite sheet. The server picks front,
   look-right or look-down-left on the directions sheet, or one of the nine moods on the reactions
   sheet. Cells sit at 0 / 50% / 100%, as revision 004's mascot.css has them. The span keeps its size
   when the sheet fails to load, so the layout does not jump. A direction owl turns its head in
   Phase 2 (the data-look block below). */
.owl {
  --owl-size: 96px;
  display: inline-block;
  flex: none;
  width: var(--owl-size);
  height: var(--owl-size);
  background-image: url("/assets/owl/owl-cartographer-reactions.webp");
  background-repeat: no-repeat;
  background-size: 300% 300%;
}

.owl[data-mood="front"],
.owl[data-mood="look-right"],
.owl[data-mood="look-down-left"] {
  background-image: url("/assets/owl/owl-cartographer-directions.webp");
}

.owl[data-mood="front"] {
  background-position: 50% 50%;
}

.owl[data-mood="look-right"] {
  background-position: 100% 50%;
}

.owl[data-mood="look-down-left"] {
  background-position: 0 100%;
}

.owl[data-mood="blink"] {
  background-position: 0 0;
}

.owl[data-mood="heart"] {
  background-position: 50% 0;
}

.owl[data-mood="sparkles"] {
  background-position: 100% 0;
}

.owl[data-mood="surprised"] {
  background-position: 0 50%;
}

.owl[data-mood="starstruck"] {
  background-position: 50% 50%;
}

.owl[data-mood="bashful"] {
  background-position: 100% 50%;
}

.owl[data-mood="sleepy"] {
  background-position: 0 100%;
}

.owl[data-mood="dizzy"] {
  background-position: 50% 100%;
}

.owl[data-mood="grin"] {
  background-position: 100% 100%;
}

/* Hover shows blink, but only on an owl already showing a mood: the reactions sheet is loaded, so
   nothing flashes blank. An owl showing a direction never blinks and never switches sheet. The swap
   is instant: nothing here is animated, with or without prefers-reduced-motion. */
.owl:not(.owl--avatar):is(
  [data-mood="blink"],
  [data-mood="heart"],
  [data-mood="sparkles"],
  [data-mood="surprised"],
  [data-mood="starstruck"],
  [data-mood="bashful"],
  [data-mood="sleepy"],
  [data-mood="dizzy"],
  [data-mood="grin"]
):hover {
  background-position: 0 0;
}

/* Sizes. The 38px avatar reads its own 96px file (the front cell), so the header on every page
   does not load a sheet. */
.owl.owl--avatar {
  --owl-size: 38px;
  background-image: url("/assets/owl/owl-avatar.webp");
  background-position: 0 0;
  background-size: 100% 100%;
}

.owl--contact {
  --owl-size: 92px;
}

.owl--module {
  --owl-size: 120px;
}

.owl--hero {
  --owl-size: 190px;
}

.owl--mcp {
  --owl-size: 200px;
}

.owl--state {
  --owl-size: 210px;
}

@media (max-width: 859px) {
  .owl--module {
    --owl-size: 84px;
  }

  .owl--hero {
    --owl-size: 96px;
  }

  .owl--mcp {
    --owl-size: 120px;
  }

  /* Under 860px the hero owl sits left of its bubble and looks right at it */
  .owl--hero[data-mood="look-down-left"] {
    background-position: 100% 50%;
  }
}

/* The head turn (A11 Phase 2, D43; spec: .ai/specs/2026-11-11-observer-owl.md › Proposed Solution 5).
   /assets/owl-look.js sets data-look on an owl the server rendered with a direction, and removes it
   when the pointer leaves the window. [data-mood][data-look] is (0,3,0), so a look wins over every
   data-mood cell, the narrow-screen hero rule included, whatever the order. Only a direction owl
   gets data-look, so the sheet never changes and no frame is blank. No transition: the turn is
   instant, with or without prefers-reduced-motion. */
.owl[data-mood][data-look="look-up-left"] {
  background-position: 0 0;
}

.owl[data-mood][data-look="look-up"] {
  background-position: 50% 0;
}

.owl[data-mood][data-look="look-up-right"] {
  background-position: 100% 0;
}

.owl[data-mood][data-look="look-left"] {
  background-position: 0 50%;
}

.owl[data-mood][data-look="front"] {
  background-position: 50% 50%;
}

.owl[data-mood][data-look="look-right"] {
  background-position: 100% 50%;
}

.owl[data-mood][data-look="look-down-left"] {
  background-position: 0 100%;
}

.owl[data-mood][data-look="look-down"] {
  background-position: 50% 100%;
}

.owl[data-mood][data-look="look-down-right"] {
  background-position: 100% 100%;
}

/* The owl above a state page's heading (placed here, after the `.owl` base rule it adjusts). */
.state .owl {
  display: block;
  margin: 0 auto var(--space-2);
}

/* The owl beside the heading on /contact, and in the /mcp hero (spec: .ai/specs/2026-11-11-observer-owl.md
   › Proposed Solution 3): the owl is decorative, the heading is what it says. */
.contact-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.contact-head h1 {
  margin: 0;
}

.mcp-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-6);
}

@media (max-width: 859px) {
  .mcp-hero {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-3);
  }

  .mcp-hero .owl {
    order: -1;
  }
}

@media print {
  .owl {
    display: none;
  }
}
