/* Systems Observatory (notes.html). Each constellation has its own colour AND
   its own star shape (square, circle, diamond), so it reads without colour. */
.observatory { margin: 40px 0 56px; }
.obs-head h2 { margin: 0 0 8px; }
.obs-head p { max-width: 60ch; color: var(--muted); }
.obs-c[data-c="pcie"], .obs-route-text li[data-c="pcie"] { --c: var(--second); }
.obs-c[data-c="iommu"], .obs-route-text li[data-c="iommu"] { --c: var(--accent); }
.obs-c[data-c="power"], .obs-route-text li[data-c="power"] { --c: var(--warn); }
.obs-picker { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0; }
.obs-picker[hidden] { display: none; }
.obs-picker button { min-height: 44px; padding: 8px 16px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--ink); font: inherit; cursor: pointer; }
.obs-picker button[aria-pressed="true"] { border-color: var(--accent); background: var(--accent); color: var(--button-ink); }

/* The map: stars and lines share one 1000 × 520 coordinate space. */
.obs-stage { position: relative; aspect-ratio: 1000 / 520; margin: 8px 0 24px; border: 1px solid var(--line); border-radius: 4px 24px 4px 4px; background: var(--surface); }
.obs-lines { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.obs-band-names text { font: 10px/1 ui-monospace, Menlo, Consolas, monospace; letter-spacing: .12em; fill: var(--muted); paint-order: stroke; stroke: var(--surface); stroke-width: 4px; }
.obs-edges { fill: none; stroke-width: 2; }
.obs-edges[data-c="pcie"] { stroke: color-mix(in srgb, var(--second) 55%, transparent); }
.obs-edges[data-c="iommu"] { stroke: color-mix(in srgb, var(--accent) 45%, transparent); }
.obs-edges[data-c="power"] { stroke: color-mix(in srgb, var(--warn) 55%, transparent); stroke-dasharray: 6 6; }
.obs-arrow { stroke-dasharray: none; }
.obs-route { fill: none; stroke: var(--ink); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1; stroke-dashoffset: 1; opacity: 0; }
.observatory[data-route="start"] .obs-route[data-r="start"],
.observatory[data-route="detail"] .obs-route[data-r="detail"],
.observatory[data-route="fail"] .obs-route[data-r="fail"] { stroke-dashoffset: 0; opacity: .7; }
html[data-motion=on] .obs-route { transition: stroke-dashoffset 1.4s ease-in-out, opacity .3s; }
/* Gates: one labelled thing handed across each border; every route rides the rail. */
.obs-gates { fill: none; stroke: var(--muted); stroke-width: 1; stroke-dasharray: 2 5; opacity: .7; }
.obs-gate { position: absolute; left: calc(var(--x) / 10 * 1%); top: calc(var(--y) / 5.2 * 1%); transform: translate(-50%, -50%); margin: 0; padding: 2px 8px; border: 1px solid var(--muted); border-radius: 999px; background: var(--surface); color: var(--ink); font: 700 .7rem/1.3 ui-monospace, Menlo, Consolas, monospace; white-space: nowrap; }
.observatory[data-route] .obs-edges { opacity: .5; }
/* Numbered stops on the chosen route (--ns, --nd, --nf on each star). */
.obs-star .obs-label { counter-reset: n var(--n, 0); }
.observatory[data-route="start"] .obs-star[data-routes~="start"] { --n: var(--ns); }
.observatory[data-route="detail"] .obs-star[data-routes~="detail"] { --n: var(--nd); }
.observatory[data-route="fail"] .obs-star[data-routes~="fail"] { --n: var(--nf); }
.obs-label::before { content: counter(n); display: none; place-items: center; min-width: 1.4em; height: 1.4em; margin-right: 6px; border-radius: 50%; background: var(--ink); color: var(--surface); font: 700 .7rem/1 ui-monospace, Menlo, Consolas, monospace; }
.observatory[data-route="start"] .obs-star[data-routes~="start"] .obs-label::before,
.observatory[data-route="detail"] .obs-star[data-routes~="detail"] .obs-label::before,
.observatory[data-route="fail"] .obs-star[data-routes~="fail"] .obs-label::before { display: inline-grid; }
.obs-c { list-style: none; margin: 0; padding: 0; }
.obs-name, .obs-star { position: absolute; left: calc(var(--x) / 10 * 1%); top: calc(var(--y) / 5.2 * 1%); }
#obs-pcie { --x:170; --y:10; }
#obs-iommu { --x:520; --y:10; }
#obs-power { --x:870; --y:10; }
/* fragile: notes.html tooltip ids; a renamed id puts the star at (0,0). Each :has(> #obs-tip-*) rule
   positions the star in notes.html that holds that tooltip id; rename an id in both places. */
.obs-star:has(> #obs-tip-pcie-hub) { --x:170; --y:60; }
.obs-star:has(> #obs-tip-pcie-path) { --x:170; --y:185; --nd:2; }
.obs-star:has(> #obs-tip-pcie-lspci) { --x:260; --y:310; --ns:1; }
.obs-star:has(> #obs-tip-pcie-features) { --x:90; --y:310; --nd:1; }
.obs-star:has(> #obs-tip-pcie-sriov) { --x:90; --y:450; }
.obs-star:has(> #obs-tip-pcie-dma) { --x:260; --y:450; --ns:2; --nf:1; }
.obs-star:has(> #obs-tip-journey) { --x:440; --y:60; --ns:3; }
.obs-star:has(> #obs-tip-edge) { --x:600; --y:60; --nd:3; }
.obs-star:has(> #obs-tip-guide) { --x:440; --y:165; --ns:4; --nf:2; }
.obs-star:has(> #obs-tip-lab) { --x:600; --y:165; }
.obs-star:has(> #obs-tip-cache) { --x:440; --y:270; --nd:4; --nf:3; }
.obs-star:has(> #obs-tip-amdref) { --x:600; --y:270; --nd:5; }
.obs-star:has(> #obs-tip-errors) { --x:440; --y:370; --ns:5; --nf:4; }
.obs-star:has(> #obs-tip-secure-dma) { --x:600; --y:470; }
.obs-star:has(> #obs-tip-confidential-vm) { --x:440; --y:470; }
.obs-star:has(> #obs-tip-active) { --x:941; --y:159; }
.obs-star:has(> #obs-tip-idle) { --x:941; --y:301; }
.obs-star:has(> #obs-tip-sleep) { --x:799; --y:301; --nf:5; }
.obs-star:has(> #obs-tip-wake) { --x:799; --y:159; --ns:6; }
.obs-star:has(> #obs-tip-links) { --x:870; --y:230; --nd:6; }
#obs-gate-rid { --x:345; --y:12; }
#obs-gate-idle { --x:695; --y:12; }

.obs-name { transform: translateX(-50%); font: 700 .75rem/1 ui-monospace, Menlo, Consolas, monospace; letter-spacing: .14em; text-transform: uppercase; color: var(--c); }
.obs-star { width: 0; height: 0; }
.obs-star > a { position: absolute; display: flex; align-items: center; gap: 8px; transform: translate(-9px, -50%); min-height: 44px; color: var(--ink); text-decoration: none; white-space: nowrap; font-size: .8rem; }
.obs-star[data-side="b"] > a { flex-direction: column; gap: 2px; transform: translate(-50%, -11px); }
.obs-glyph { flex: none; width: 14px; height: 14px; background: var(--c); border: 2px solid var(--surface); box-shadow: 0 0 0 1px var(--c); }
.obs-c[data-c="pcie"] .obs-glyph { border-radius: 2px; }
.obs-c[data-c="iommu"] .obs-glyph { border-radius: 50%; }
.obs-c[data-c="power"] .obs-glyph { transform: rotate(45deg); }
.obs-label { padding: 2px 6px; border-radius: 6px; background: var(--surface); }
.obs-star > a:visited .obs-label { color: var(--c); } /* explored stars brighten */
.obs-star > a:is(:hover, :focus-visible) .obs-label { text-decoration: underline; text-underline-offset: 3px; }
.obs-star > a:is(:hover, :focus-visible) .obs-glyph { box-shadow: 0 0 0 1px var(--c), 0 0 12px var(--c); }
.observatory[data-route] .obs-glyph { opacity: .55; } /* dim the mark, never the label or tip text (contrast) */
.observatory[data-route="start"] .obs-star[data-routes~="start"] .obs-glyph,
.observatory[data-route="detail"] .obs-star[data-routes~="detail"] .obs-glyph,
.observatory[data-route="fail"] .obs-star[data-routes~="fail"] .obs-glyph,
.observatory[data-route] .obs-star:is(:hover, :focus-within) .obs-glyph { opacity: 1; }
html[data-motion=on] .obs-glyph { transition: opacity .3s; }
.obs-tip { position: absolute; z-index: 2; top: 26px; left: -9px; width: 240px; margin: 0; padding: 10px 12px; border: 1px solid var(--c); border-radius: 8px; background: var(--bg); font-size: .8rem; line-height: 1.5; color: var(--muted); visibility: hidden; }
.obs-tip b { display: block; color: var(--ink); font-size: .7rem; letter-spacing: .08em; text-transform: uppercase; }
.obs-star[data-side="b"] .obs-tip { top: 44px; left: -120px; }
.obs-star:is(:hover, :focus-within) .obs-tip { visibility: visible; }
.obs-c[data-c="power"] .obs-tip { left: auto; right: -9px; }

/* The route, as steps. Crossings between constellations get their own line. */
.obs-route-text { display: none; }
.observatory:not([data-route]) .obs-route-text,
.observatory[data-route="start"] [data-route-text="start"],
.observatory[data-route="detail"] [data-route-text="detail"],
.observatory[data-route="fail"] [data-route-text="fail"] { display: block; }
.obs-route-text ol { margin: 0; padding-left: 1.4rem; }
.obs-route-text li { margin: 6px 0; padding-left: 4px; color: var(--muted); }
.obs-route-text li[data-c]::marker { color: var(--c); }
.obs-route-text li > a { color: var(--ink); font-weight: 600; margin-right: 6px; }
.obs-cross { list-style: none; margin-left: -1.4rem !important; padding: 6px 12px !important; border-left: 3px solid var(--line); font-style: italic; }

/* Narrow screens: the same stars as three plain lists, tips shown inline. */
@media (max-width: 900px) {
  .obs-stage { aspect-ratio: auto; display: grid; gap: 16px; padding: 16px; }
  .obs-lines, .obs-gate { display: none; }
  .obs-name, .obs-star, .obs-star > a, .obs-tip { position: static; transform: none; }
  .obs-name { display: block; margin-bottom: 4px; }
  .obs-star { width: auto; height: auto; }
  .obs-star > a, .obs-star[data-side="b"] > a { flex-direction: row; transform: none; white-space: normal; }
  .obs-tip { visibility: visible; width: auto; padding: 0 0 8px 22px; border: 0; background: none; }
  .obs-tip b { display: inline; margin-right: 4px; }
}
@media (forced-colors: active) { .obs-glyph { background: CanvasText; } }
.obs-route-text h3 { margin: 0 0 4px; font-size: 1.1rem; }

/* Tron: a grid floor, neon panels, and the route as a light-cycle trail. Glow is dark-canvas only. */
.obs-stage { background-image: linear-gradient(color-mix(in srgb, var(--accent) 9%, transparent) 1px, transparent 1px), linear-gradient(90deg, color-mix(in srgb, var(--accent) 9%, transparent) 1px, transparent 1px); background-size: 32px 32px; }
.obs-bands rect { rx: 3px; fill: color-mix(in srgb, var(--accent) 6%, var(--surface)); stroke: color-mix(in srgb, var(--accent) 35%, transparent); stroke-width: 1; }
.obs-gates { stroke: var(--accent); stroke-dasharray: none; opacity: .5; }
.obs-gate { border-color: var(--accent); }
.obs-route { stroke-width: 3.5; }
:root:not([data-canvas="light"]) .obs-route { filter: drop-shadow(0 0 3px var(--accent)); }
:root:not([data-canvas="light"]) .obs-gate { box-shadow: 0 0 10px color-mix(in srgb, var(--accent) 45%, transparent); }
:root:not([data-canvas="light"]) .obs-gates { filter: drop-shadow(0 0 3px var(--accent)); }
:root:not([data-canvas="light"]) .obs-name { text-shadow: 0 0 10px var(--c); }
:root:not([data-canvas="light"]) .obs-glyph { box-shadow: 0 0 0 1px var(--c), 0 0 8px var(--c); }

/* Where I applied it: one card per constellation, same colour as its stars. */
.obs-applied { margin: 32px 0 0; }
.obs-applied > p { max-width: 62ch; color: var(--muted); }
.obs-applied ul { list-style: none; margin: 16px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 280px), 1fr)); gap: 16px; }
.obs-applied li { --c: var(--accent); padding: 16px; border: 1px solid var(--line); border-top: 4px solid var(--c); border-radius: 4px 16px 4px 4px; background: var(--surface); }
.obs-applied li[data-c="pcie"] { --c: var(--second); }
.obs-applied li[data-c="power"] { --c: var(--warn); }
.obs-applied h4 { margin: 0 0 8px; }
.obs-applied li p { margin: 8px 0; overflow-wrap: anywhere; }
.obs-applied li strong { color: var(--ink); }
