/**
 * THE OVERLOOK — nav layout 3's stylesheet. Ported from mega-nav round 12
 * (prototypes/mega-nav-v2/round12/build/index.html at ac17149e).
 *
 * THIS SHEET IS A GUEST, NEVER A LANDLORD. Every selector below starts with an
 * `.ovk` token or `body.hpc-ovk-open`. There is no `:root`, no `*`, no bare
 * `html`, `body`, `a`, `button` or `[hidden]` subject.
 *
 * That is not style, it is the AUDIT-2026-08-04 P0-3 defect written down: v25.0.1
 * shipped `*{box-sizing}`, `html,body{margin:0}`, `body{background:…}` and
 * `a{color:inherit;text-decoration:none}` UNSCOPED in hpc-nav-atlas.css. Loaded
 * on every themed page and all 323 canvas pages, the `body` rule beat each canvas
 * document's own background on the cascade and the bare `a` rule stripped
 * underlines it did not own. The prototype this file is ported from carries
 * exactly those five rules, plus generic class names (`.micro`, `.brand`,
 * `.segment`, `.note-title`) that the theme is likely to reuse. Both are fixed
 * here, and gated: tests/test_nav_overlook_scope.py.
 *
 * NAMESPACE: classes `ovk__*`, ids `ovk-*`, data attributes `data-ovk-*`. State
 * classes keep their names (`is-active`, `is-selected`, `is-viewing`,
 * `is-searching`, `is-morphing`, `mobile-detail`, `media-failed`) but are NEVER a
 * selector subject on their own.
 *
 * TOKENS live on `.ovk`, not on `:root`. The panel is a descendant, so it
 * inherits them; the host document keeps its own root untouched.
 *
 * LOADED BLOCKING, unlike hpc-nav-atlas.css's print-media swap. The Overlook
 * trigger has no critical block in hpc-header.css yet, so a swapped sheet would
 * flash it unstyled. Layout 3 is opt-in and has no readers; the critical block is
 * increment 3's work.
 */

.ovk {
  /* --header-h is gone: the plugin measures the real header into
     --hpc-header-h (assets/js/hpc-header.js), with a 120px CSS fallback, and
     the Atlas panel already positions itself against that same variable. */
  --ground: #070b14;
  --panel: #0e1628;
  --panel-deep: #090f1d;
  --panel-raised: #16233d;
  --panel-soft: #121c31;
  --ink: #f3f5fb;
  --ink-hero: #f0f0f0;
  --ink-soft: rgba(243,245,251,.78);
  --ink-muted: rgba(243,245,251,.62);
  --ink-faint: rgba(243,245,251,.38);
  --line: rgba(243,245,251,.12);
  --line-strong: rgba(243,245,251,.25);
  --panel-wash: rgba(14,22,40,.92);
  --scrim-deep: rgba(7,11,20,.96);
  --scrim-clear: rgba(7,11,20,.08);
  --shadow-color: rgba(0,0,0,.48);
  --shadow-panel: 0 24px 50px var(--shadow-color);
  --shadow-selected: inset 0 0 0 1px var(--line-strong);
  --shadow-viewing: inset 3px 0 0 var(--ink);
  --shadow-current: inset 3px 0 0 var(--gold);
  --gold: #ffcb05;
  --focus: #ffffff;
  --bio: #73b191;
  --flow: #60a5fa;
  --decisions: #ccc06f;
  --learning: #988cb5;
  --habits: #96a67a;
  --identity: #b88892;
  --leadership: #8898a0;
  --arena: #c47358;
  --nutri: #a89f68;
  --social: #6aa2cc;

  /* THE SHEEN: each pillar's own hue and saturation, lifted in LIGHTNESS ONLY
     until it clears 6.2:1 on the brightest pixel its own photograph shows
     through the scrim. Not a new palette — the same ten colours, raised to
     where a photograph can carry them. Maximising chroma instead produced
     #33ff96 and #ffe533, which is neon, and this estate is not neon.
     Derived, not eyeballed: the token's HUE is held exactly, and lightness and
     saturation are solved together for a consistent chroma of ~100 against the
     measured ground per vista. The first set held the token's own saturation
     too and came out at chroma 19-70 — owner: "I don't notice the colours at
     all". The blues cap lower than the warms and that is physics, not
     inconsistency: a blue dark enough to be saturated cannot hold 4.5:1 on a
     photograph, so the only blue available is a pale one. */
  --bio-sheen: #9afeca;
  --flow-sheen: #cee3fd;
  --decisions-sheen: #fef19a;
  --learning-sheen: #d7c7ff;
  --habits-sheen: #dafe9a;
  --identity-sheen: #ff9eb2;
  --leadership-sheen: #9addfe;
  --arena-sheen: #ffd9cc;
  --nutri-sheen: #fef09a;
  --social-sheen: #d6edff;
  --transparent: transparent;
  --system-canvas: Canvas;
  --system-text: CanvasText;
  --system-link: LinkText;
  --system-highlight: Highlight;
  --system-highlight-text: HighlightText;
  --ease-out: cubic-bezier(.16,1,.3,1);
  --ease-settle: cubic-bezier(.22,.72,.18,1);
  --panel-h: min(540px, 62vh);
  --pad: clamp(20px,2.6vw,40px);
  /* The prototype set the panel's body face on `body`, unscoped. That rule
     cannot ship (see the file header), so the face is a token the panel applies
     to itself — otherwise it inherits whatever the host document happens to
     use, which on a canvas page is a serif. */
  --ovk-sans: Inter, system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* The reset, scoped. The prototype's `*`, `html`, `body`, `a` and `button`
   rules cannot ship as written — see the file header. */
.ovk, .ovk *, .ovk *::before, .ovk *::after { box-sizing: border-box; }
.ovk__panel a { color: inherit; text-decoration: none; }
.ovk button, .ovk input, .ovk summary { font: inherit; }
.ovk button { color: inherit; }
.ovk [hidden] { display: none !important; }
body.hpc-ovk-open { overflow: hidden; }

.ovk__panel, .ovk > summary.ovk__trigger { font-family: var(--ovk-sans); }

/* HISTORICAL OVK-06 GUARD. Before the heading-outline fix, the host document's
   bare `h2` rule repainted Overlook labels dark grey on the dark panel. The
   pillar labels are now <p> elements because navigation labels are not document
   headings. This selector is retained rather than silently deleted; it matches
   no current Overlook label, while the class rules below preserve their colour. */
.ovk__panel h1, .ovk__panel h2, .ovk__panel h3, .ovk__panel h4 { color: var(--ink); }
.ovk__panel p, .ovk__panel span, .ovk__panel strong,
.ovk__panel label, .ovk__panel li, .ovk__panel button,
.ovk__panel input { color: inherit; }

.ovk :focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }

/* ── The trigger ─────────────────────────────────────────── */
.ovk { justify-self: start; }
.ovk > summary.ovk__trigger { position: relative; z-index: 26; list-style: none; cursor: pointer; min-width: 116px; min-height: 48px; display: inline-flex; align-items: center; gap: 13px; padding: 0 12px; margin-left: -12px; font: 500 12px/1 JetBrains Mono, monospace; letter-spacing: 2px; text-transform: uppercase; }
.ovk > summary.ovk__trigger::-webkit-details-marker { display: none; }
.ovk__bars { width: 22px; height: 14px; display: grid; align-content: space-between; flex: 0 0 auto; }
.ovk__bars::before,
.ovk__bars::after { content: ""; display: block; width: 100%; height: 1px; background: currentColor; transform-origin: center; }
.ovk__copy.is-close { display: none; }
.ovk[open] .ovk__copy.is-open { display: none; }
.ovk[open] .ovk__copy.is-close { display: inline; }
.ovk[open] .ovk__bars { align-content: center; }
.ovk[open] .ovk__bars::before { transform: translateY(.5px) rotate(45deg); }
.ovk[open] .ovk__bars::after { transform: translateY(-.5px) rotate(-45deg); }

/* ── The panel ───────────────────────────────────────────── */
.ovk__panel { position: fixed; z-index: 25; inset: var(--hpc-header-h, 120px) 0 auto; height: var(--panel-h); min-height: 0; color: var(--ink); background: var(--panel); border-top: 1px solid var(--line-strong); border-bottom: 1px solid var(--line-strong); box-shadow: var(--shadow-panel); isolation: isolate; overflow: clip; transform-origin: 0 0; }
/* The sightline gives width to the plane (owner, 2026-08-29: "make this box
   small and cede more space to the content to the right"). Ten short labels do
   not need 292px; five route names and two field notes do. The minmax floor
   drops with the fraction so the column cannot be squeezed under its own
   two-line names at 975px. */
.ovk__grid { position: relative; z-index: 1; height: 100%; display: grid; grid-template-columns: minmax(310px,.98fr) minmax(246px,.5fr) minmax(600px,1.44fr); transform: none; }
.ovk__scene { position: relative; margin: 0; min-width: 0; overflow: clip; isolation: isolate; border-right: 1px solid var(--line-strong); background: var(--panel-deep); transform-origin: 0 0; backface-visibility: hidden; }
.ovk__scene::before { content: ""; position: absolute; z-index: 2; inset: 0; background: linear-gradient(90deg,rgba(7,11,20,.30) 0,rgba(7,11,20,.08) 40%,rgba(7,11,20,0) 72%); clip-path: polygon(0 0,94% 0,100% 50%,94% 100%,0 100%); }
/* the seam. It used to draw a hard 1px line of its own ON TOP of the border
   .ovk__scene already carries, so the picture ended at two edges instead of
   one. The line is dropped and the wash widened: the picture now dissolves
   into the column beside it. */
.ovk__scene::after { content: ""; position: absolute; z-index: 3; inset: 0 0 0 auto; width: 96px; background: linear-gradient(90deg,rgba(14,22,40,0) 0%,rgba(14,22,40,.04) 26%,rgba(14,22,40,.16) 48%,rgba(14,22,40,.40) 68%,rgba(14,22,40,.66) 85%,rgba(14,22,40,.88) 100%); pointer-events: none; }
.ovk__vista { position: absolute; z-index: 1; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: saturate(1.04) contrast(1.05); }
/* round12: the vista is the subject. Type carries its own scrim so the
picture stays open.

WHY THIS IS NO LONGER THREE BANDS. Each type run used to sit on its own
absolutely-placed plate, sized in `em` off its host's font and feathered
top and bottom by a mask. Three plates read as three stickers laid on a
photograph: the picture showed through between them, and each one drew
an edge the eye could find. The panel's ground and the picture met at a
seam instead of blending.

They are now TWO scrims on the plate itself — one pooling down from the
head, one rising from the foot — in the panel's own ground colour, each
with a six-stop falloff so no stop is a visible step. They meet nothing:
the middle of the frame, where the picture is worth looking at, is left
entirely clear.

Anchored to .ovk__scene-copy (the full plate) and sized in PERCENT of it,
NOT in `em` off a text node — an oversized pseudo-element on a text node
overflows its host and inflates scrollWidth, which a gate reads as
clipped text. Neither scrim is ever animated, and neither carries a mask:
mask-image is paint, not compositor. */
.ovk__scene-copy { isolation: isolate; }
.ovk__scene-copy::before,
.ovk__scene-copy::after { content: ""; position: absolute; z-index: -1; left: 0; right: 0; pointer-events: none; }
/* MAX PHOTOGRAPH. These numbers are not taste, they are the open end of a
   measured sweep: the scrims were opened in steps and the type's contrast read
   off the painted pixels of the brightest vista (habits) at each step, until
   the margin over the 4.5 floor stopped being one worth having. 46%/.95 held
   13.3:1 - nine stops of picture paid for nothing. Below roughly a third of the
   plate the falloff has no room left to hide in and contrast drops off a cliff:
   27%/.66 is 4.54:1, one bad photograph from illegal.
   Held by tests/test_nav_overlook_scrim.py, which gates BOTH the 4.5 floor and
   the 6.0 margin - so the picture cannot creep open later without saying so. */
.ovk__scene-copy::before { top: 0; height: 33%; background: linear-gradient(180deg, rgba(7,11,20,.80) 0%, rgba(7,11,20,.77) 24%, rgba(7,11,20,.62) 46%, rgba(7,11,20,.38) 66%, rgba(7,11,20,.14) 84%, rgba(7,11,20,0) 100%); }
.ovk__scene-copy::after { bottom: 0; height: 32%; background: linear-gradient(0deg, rgba(7,11,20,.80) 0%, rgba(7,11,20,.77) 24%, rgba(7,11,20,.62) 46%, rgba(7,11,20,.38) 66%, rgba(7,11,20,.14) 84%, rgba(7,11,20,0) 100%); }
.ovk__scene-copy { position: relative; z-index: 4; height: 100%; display: flex; flex-direction: column; justify-content: space-between; padding: 24px 35px 22px 24px; }
.ovk__micro { margin: 0; color: var(--ink-soft); font: 400 11px/1.35 JetBrains Mono, monospace; letter-spacing: 1.8px; text-transform: uppercase; }
/* THE NAME IS STRUCK IN THE PILLAR'S OWN METAL (owner, 2026-08-29).
   A flat tint on a photograph reads as tinted text. Metal reads as an object:
   it needs a specular event — one band where the surface catches the light —
   and the eye supplies the rest. The ramp runs VERTICALLY, which is how a
   polished edge actually behaves under a sky, and how chrome type has been cut
   since letterpress: bright crown, tinted body, a hard specular at the optical
   centre, tinted again, bright base.

   EVERY STOP IS LIGHT. That is not timidity, it is the photograph: the deepest
   stop still has to clear 4.5:1 against the brightest pixel the scrim lets
   through, with the 6.0 margin this estate traded for. Metal made of dark bands
   is unavailable here at any price — measured, 60% ink already breaks the
   margin on habits — so the depth comes from HUE and from the specular, not
   from darkness. tests/test_nav_overlook_scrim.py now reads the stops, not the
   computed colour, because a gradient-filled glyph has no `color` to read.

   The flat tint stays as the first declaration: a browser without
   background-clip:text keeps the design it had this morning rather than a
   transparent word. */
.ovk__scene-title { max-width: 310px; margin: 0; font: 400 clamp(30px,2.5vw,38px)/.98 DM Serif Display, Georgia, serif; letter-spacing: .3px; text-wrap: balance; }

/* `.ovk__panel .ovk__scene-title`, NOT `.ovk__scene-title`. The title is a <p>
   after the heading-outline fix, and `.ovk__panel p { color: inherit }` is
   0,1,1, which still beats a bare class at 0,1,0. The paired class selector
   keeps the same flat tint and metal treatment on the new semantic element. */
.ovk__panel .ovk__scene-title { color: color-mix(in oklab, var(--ink-hero) 72%, var(--pillar, var(--ink-hero))); }

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .ovk__panel .ovk__scene-title {
    /* HARD EDGES ARE THE WHOLE EFFECT. The first cut of this ramp was a smooth
       blend between white and a 71% tint, and at 38px it was invisible — a
       gradient that reads as antialiasing is not an effect, it is a rounding
       error. Metal is a SPECULAR EVENT: a band where the surface catches the
       light, with an edge you can see. Two stops at almost the same position
       make that edge; the eye supplies the curvature. */
    /* THE COLOUR CARRIES THE WORD; THE WHITE IS ONLY THE HIGHLIGHT. The first
       ramp was roughly 40% white and read as white type with a faint cast. The
       fix costs nothing: contrast is set by the DARKEST stop, so widening the
       sheen and narrowing the specular to a 2% band changes how coloured the
       word is without moving the floor by a thousandth. Every stop here is the
       sheen or a lighter mix of it. */
    background-image: linear-gradient(177deg,
      color-mix(in oklab, var(--sheen, var(--ink-hero)) 62%, #ffffff) 0%,
      var(--sheen, var(--ink-hero)) 26%,
      var(--sheen, var(--ink-hero)) 46%,
      #ffffff 48%,
      #ffffff 50%,
      var(--sheen, var(--ink-hero)) 52%,
      var(--sheen, var(--ink-hero)) 84%,
      color-mix(in oklab, var(--sheen, var(--ink-hero)) 55%, #ffffff) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    /* drop-shadow, NOT text-shadow, and the difference is not stylistic.
       With background-clip:text the fill is the ELEMENT'S BACKGROUND LAYER,
       and a text-shadow paints with the text — i.e. ABOVE that layer. The
       first cut used text-shadow and put 55% black straight over the metal:
       glyph interiors measured rgb(83,97,96) and 1.35:1, a handsome bevel that
       was illegal on every photograph. `filter` applies to the element's
       composited output, so the shadow lands behind all of it.
       It costs a layer for a static effect, which is the price of the edge that
       keeps this legible on the pale vistas.
       ONE tight shadow, not a halo: a 14px blur bleeds dark across a serif's
       thin strokes from both sides at once, and cost the ramp ~0.3:1 of
       measured contrast on every plate. The edge is 1px because that is what
       an edge is. */
    filter: drop-shadow(0 1px 1px rgba(7,11,20,.6));
  }
}
.ovk__readout { display: grid; gap: 9px; max-width: 320px; }
.ovk__vista-region { margin: 0; color: var(--ink-soft); text-align: right; font: 400 11px/1.25 JetBrains Mono, monospace; letter-spacing: 1.6px; text-transform: uppercase; }
.ovk__readout-line { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 12px; }
.ovk__vista-count { font: 400 11px/1 JetBrains Mono, monospace; letter-spacing: 1px; }

/* THE RAIL. Ten dashes that used to paint a position the reader could not
   act on; each is now the control for its own viewpoint.

   The DASH stays 2px — it is a rail, not a row of buttons, and the picture
   pays for every pixel it grows. The TARGET does not: each button is a
   26px-tall box with the dash centred in it and no gap between boxes, so
   the whole strip is live and every cell clears WCAG 2.5.8 AA's 24px
   minimum. The `gap` that used to separate the dashes is now transparent
   padding INSIDE each button, which buys the separation back without
   punching dead lanes through the target.

   The rail sits under the counter it belongs to, so it is pulled up by its
   own padding — growing the hit area must not grow the readout. */
.ovk__segments { display: grid; grid-template-columns: repeat(10,1fr); margin: -12px 0; }
.ovk__segment { -webkit-appearance: none; appearance: none; display: flex; align-items: center; min-height: 26px; padding: 12px 2px; border: 0; background: var(--transparent); cursor: pointer; }
.ovk__segment-mark { display: block; width: 100%; height: 2px; background: var(--ink-faint); }
.ovk__segment:hover .ovk__segment-mark { height: 3px; background: var(--ink-soft); }
.ovk__segment.is-active .ovk__segment-mark { height: 4px; background: var(--ink); }
.ovk__segment:focus-visible { outline: 2px solid var(--focus); outline-offset: -6px; }
/* T1 invariant: settled layout surfaces use only --panel/--panel-deep. */
/* One row now, not 55px + 1fr: the head is gone and its height belongs to the
   ten viewpoints. */
.ovk__sightline { min-width: 0; display: grid; grid-template-rows: 1fr; background: var(--panel-deep); border-right: 1px solid var(--line-strong); }
/* Visually hidden, still announced. clip-path WITHOUT overflow:hidden — a 1px
   box with hidden overflow is what the clipped-text gate flags. */
.ovk__sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; clip-path: inset(50%); white-space: nowrap; }
/* .ovk__sightline-head: deleted with the row it styled. The instruction it
   carried is now .ovk__sr, and this rule still reaches it — a hidden element's
   ::after is still announced, which is the whole point of keeping it. */
.ovk__sightline:focus-within #ovk-instruction::after { content: " · → routes"; }
.ovk__pillars { display: grid; grid-template-rows: repeat(10,1fr); min-height: 0; }
.ovk__pillar { --pillar: var(--bio); position: relative; display: grid; grid-template-columns: 28px 1fr; align-items: center; gap: 6px; min-width: 0; padding: 3px 12px 3px 14px; border-bottom: 1px solid var(--line); font-size: 13px; line-height: 1.15; }
.ovk__pillar::before { content: ""; position: absolute; inset: 9px auto 9px 0; width: 3px; background: var(--pillar); }
.ovk__pillar:last-child { border-bottom: 0; }
.ovk__pillar.is-selected { background: var(--panel-raised); box-shadow: var(--shadow-selected); }
.ovk__pillar-no { color: var(--ink-muted); font: 400 11px/1 JetBrains Mono, monospace; letter-spacing: 1px; }
.ovk__pillar-names { min-width: 0; display: grid; }
/* the row's only name, so it is the row's primary voice — it was a 10px
   muted sub-line under the short name that is now the picture's job. */
.ovk__pillar-full { min-width: 0; color: var(--ink-soft); font-size: 13px; line-height: 1.2; letter-spacing: -.1px; text-wrap: balance; }
.ovk__pillar.is-selected .ovk__pillar-full { color: var(--ink); }
/* THE WORD "SELECTED" IS OFF-SCREEN AT EVERY WIDTH NOW, not just on a phone.
   It used to be `visibility: hidden` on the nine unselected rows — which hides
   a word but KEEPS ITS BOX, so all ten rows reserved ~65px to say nothing. That
   was affordable in a 292px column. In a 246px one it pushed
   "Mental Models & Decision Science" onto three lines.
   The row already says it three other ways: it is raised, it is ringed, and it
   carries its pillar's bar. The word stays in the accessible name, which is the
   same trade the 390px row made one round ago and for the same reason. */
.ovk__selected { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; clip-path: inset(50%); white-space: nowrap; }
.ovk__pillar[data-ovk-pillar="bio"] { --pillar: var(--bio); }
.ovk__pillar[data-ovk-pillar="flow"] { --pillar: var(--flow); }
.ovk__pillar[data-ovk-pillar="decisions"] { --pillar: var(--decisions); }
.ovk__pillar[data-ovk-pillar="learning"] { --pillar: var(--learning); }
.ovk__pillar[data-ovk-pillar="habits"] { --pillar: var(--habits); }
.ovk__pillar[data-ovk-pillar="identity"] { --pillar: var(--identity); }
.ovk__pillar[data-ovk-pillar="leadership"] { --pillar: var(--leadership); }
.ovk__pillar[data-ovk-pillar="arena"] { --pillar: var(--arena); }
.ovk__pillar[data-ovk-pillar="nutri"] { --pillar: var(--nutri); }
.ovk__pillar[data-ovk-pillar="social"] { --pillar: var(--social); }
.ovk__plane { position: relative; min-width: 0; display: grid; grid-template-rows: minmax(0,1fr) 140px; background: var(--panel); }
.ovk__back { display: none; min-height: 44px; border: 0; border-bottom: 1px solid var(--line); background: var(--transparent); padding: 0 16px; cursor: pointer; color: var(--ink); font: 400 11px/1 JetBrains Mono, monospace; letter-spacing: 1.6px; text-transform: uppercase; }
.ovk__stack { min-height: 0; display: grid; grid-template: minmax(0,1fr) / minmax(0,1fr); }
.ovk__detail { --pillar: var(--bio); height: 100%; min-width: 0; grid-area: 1 / 1; display: grid; grid-template-columns: minmax(300px,1.08fr) minmax(250px,.92fr); content-visibility: auto; contain-intrinsic-size: 620px 340px; opacity: 0; pointer-events: none; z-index: 0; }
.ovk__detail.is-active { opacity: 1; pointer-events: auto; z-index: 1; }
.ovk__panel.is-searching .ovk__detail.is-active { opacity: 0; pointer-events: none; }
.ovk__detail[data-ovk-pillar="bio"] { --pillar: var(--bio); }
.ovk__detail[data-ovk-pillar="flow"] { --pillar: var(--flow); }
.ovk__detail[data-ovk-pillar="decisions"] { --pillar: var(--decisions); }
.ovk__detail[data-ovk-pillar="learning"] { --pillar: var(--learning); }
.ovk__detail[data-ovk-pillar="habits"] { --pillar: var(--habits); }
.ovk__detail[data-ovk-pillar="identity"] { --pillar: var(--identity); }
.ovk__detail[data-ovk-pillar="leadership"] { --pillar: var(--leadership); }
.ovk__detail[data-ovk-pillar="arena"] { --pillar: var(--arena); }
.ovk__detail[data-ovk-pillar="nutri"] { --pillar: var(--nutri); }
.ovk__detail[data-ovk-pillar="social"] { --pillar: var(--social); }
.ovk__panel[data-ovk-pillar="bio"] { --pillar: var(--bio); }
.ovk__panel[data-ovk-pillar="flow"] { --pillar: var(--flow); }
.ovk__panel[data-ovk-pillar="decisions"] { --pillar: var(--decisions); }
.ovk__panel[data-ovk-pillar="learning"] { --pillar: var(--learning); }
.ovk__panel[data-ovk-pillar="habits"] { --pillar: var(--habits); }
.ovk__panel[data-ovk-pillar="identity"] { --pillar: var(--identity); }
.ovk__panel[data-ovk-pillar="leadership"] { --pillar: var(--leadership); }
.ovk__panel[data-ovk-pillar="arena"] { --pillar: var(--arena); }
.ovk__panel[data-ovk-pillar="nutri"] { --pillar: var(--nutri); }
.ovk__panel[data-ovk-pillar="social"] { --pillar: var(--social); }
.ovk__panel[data-ovk-pillar="bio"] { --sheen: var(--bio-sheen); }
.ovk__panel[data-ovk-pillar="flow"] { --sheen: var(--flow-sheen); }
.ovk__panel[data-ovk-pillar="decisions"] { --sheen: var(--decisions-sheen); }
.ovk__panel[data-ovk-pillar="learning"] { --sheen: var(--learning-sheen); }
.ovk__panel[data-ovk-pillar="habits"] { --sheen: var(--habits-sheen); }
.ovk__panel[data-ovk-pillar="identity"] { --sheen: var(--identity-sheen); }
.ovk__panel[data-ovk-pillar="leadership"] { --sheen: var(--leadership-sheen); }
.ovk__panel[data-ovk-pillar="arena"] { --sheen: var(--arena-sheen); }
.ovk__panel[data-ovk-pillar="nutri"] { --sheen: var(--nutri-sheen); }
.ovk__panel[data-ovk-pillar="social"] { --sheen: var(--social-sheen); }
.ovk__intro { min-width: 0; display: flex; flex-direction: column; padding: 16px 20px 12px; transform-origin: 0 22%; backface-visibility: hidden; }
.ovk__intro::before { content: ""; width: 34px; height: 3px; margin-bottom: 10px; background: var(--pillar); }
/* THE PILLAR NAME CARRIES ITS OWN INK (owner, 2026-08-29: "a twinge of the
   category colour"). A twinge, not a colour: 72% ink to 28% pillar, which on
   this deliberately muted palette shifts the hue without turning a serif
   heading into a coloured label. Measured on --panel for all ten: the worst
   is arena at 12.34:1 against a 4.5 floor, so contrast never constrained the
   choice — legibility of the TINT did. 82% was invisible on a dark ground,
   62% read as a coloured label.

   `.ovk__panel .ovk__title`, not `.ovk__title`, and the extra class is the
   whole point: after the heading-outline fix, `.ovk__panel p { color: inherit }`
   is 0,1,1 and would beat a bare 0,1,0 class. The paired class selector keeps
   the title's established tint on its new non-heading element.

   The plain `color` first is the fallback: a browser without color-mix keeps
   pure ink, which is the design without the twinge, not a broken one. */
.ovk__title { margin: 0 0 4px; font: 400 clamp(26px,2vw,32px)/1 DM Serif Display, Georgia, serif; letter-spacing: .25px; text-wrap: balance; }
.ovk__panel .ovk__title { color: var(--ink); color: color-mix(in oklab, var(--ink) 72%, var(--pillar, var(--ink))); }
.ovk__full { margin: 0 0 8px; color: var(--ink-muted); font-size: 13px; line-height: 1.45; }
/* UNUSED since 2026-08-29: the intro column's Viewing block was deleted on the
   owner's ruling (it repeated the spine row immediately to its left). These
   three rules now match nothing. Noted rather than deleted, per the estate's
   rule on dead code, and kept together with the two media-query overrides
   below so whoever revives the block revives its whole behaviour or none of
   it. They cost ~230 bytes on a stylesheet that ships to every reader, which
   is the argument for eventually cutting them — an owner's call, not a
   side effect of this one. */
.ovk__viewing { margin-top: 12px; padding: 8px 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.ovk__viewing .ovk__micro { display: block; margin-bottom: 5px; }
.ovk__viewing-name { display: block; font: 400 17px/1.16 Bodoni Moda, Georgia, serif; }
/* THE COLUMN REACHES THE FOOTER (owner, 2026-08-29: "move everything up to
   the footer"). Deleting the find bar gave the grid 48px, and all of it landed
   in this column as a hole between the pillar link and the field notes — the
   sightline and the routes both distribute their rows with 1fr and closed up
   on their own, but .ovk__intro is a flex column with its content at the top,
   so it grew a tail instead. `margin-top: auto` on the LAST child only: the
   title, the full name and the viewing block keep their own rhythm at the top
   and the link anchors to the notes below it. `justify-content: space-between`
   would have spread all four and pulled the name off its title. */
.ovk__hub { margin-top: auto; min-height: 52px; display: flex; align-items: center; justify-content: space-between; gap: 12px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); font: 400 11px/1.25 JetBrains Mono, monospace; letter-spacing: 1.4px; text-transform: uppercase; }
/* ── THE SPINE (owner pick, 2026-08-29) ───────────────────────────────────
   The five subcategories, and the panel's first column now that they lead it.
   NO RULES. The rows were separated by a hairline between every pair; they are
   separated by rhythm and by the pillar's own colour instead — a 3px spine per
   row, lit when the row is the one being read. Five rules across 400px was five
   lines drawn to say something the spacing already said, and the sightline one
   column over is already a ruled list: two ruled lists side by side is a
   spreadsheet, not a panel.
   The colour doing the work here is the same colour the title is struck in, so
   the two halves of the panel finally name the same pillar the same way. */
.ovk__routes { min-width: 0; margin: 0; padding: 0; list-style: none; display: grid; grid-template-rows: repeat(5,1fr); border-right: 1px solid var(--line); transform-origin: 0 28%; backface-visibility: hidden; }
.ovk__routes li { min-width: 0; }
.ovk__route { position: relative; min-height: 100%; display: grid; grid-template-columns: 1fr auto; grid-template-rows: auto auto; align-content: center; column-gap: 10px; row-gap: 5px; padding: 6px 16px 6px 22px; }
.ovk__route::before { content: ""; position: absolute; left: 0; top: 12px; bottom: 12px; width: 3px; background: var(--pillar); opacity: .3; }
.ovk__route-no,
.ovk__route-state { color: var(--ink-faint); font: 400 10px/1 JetBrains Mono, monospace; letter-spacing: 1.6px; text-transform: uppercase; }
.ovk__route-no { grid-column: 1; grid-row: 1; }
.ovk__route-state { grid-column: 2; grid-row: 1; }
.ovk__route-name { min-width: 0; font: 400 20px/1.08 Bodoni Moda, Georgia, serif; letter-spacing: -.2px; overflow-wrap: anywhere; }
.ovk__route-name { grid-column: 1 / -1; grid-row: 2; }
/* The chip is kept from THE INDEX on purpose: with the rules gone, the lit
   spine is the only other thing marking the row being read, and state carried
   by colour alone is state a colour-blind reader cannot have. */
.ovk__route.is-viewing { background: var(--panel-soft); box-shadow: none; }
.ovk__route.is-viewing::before { opacity: 1; width: 5px; }
.ovk__route.is-viewing .ovk__route-no { color: var(--pillar); }
.ovk__route[aria-current="page"] { color: var(--gold); box-shadow: none; }
.ovk__route[aria-current="page"]::before { background: var(--gold); opacity: 1; width: 5px; }
.ovk__route[aria-current="page"] .ovk__route-no,
.ovk__route[aria-current="page"] .ovk__route-state { color: var(--gold); }
.ovk__results { height: 100%; grid-area: 1 / 1; padding: 20px 22px; overflow: auto; z-index: 2; }
.ovk__result-list { margin: 12px 0 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); border-top: 1px solid var(--line); }
.ovk__result { min-height: 52px; display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 8px 12px; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); font-size: 13px; line-height: 1.3; }
.ovk__result[aria-current="page"] { color: var(--gold); box-shadow: var(--shadow-current); }
.ovk__result-meta { color: var(--ink-muted); font: 400 11px/1 JetBrains Mono, monospace; letter-spacing: 1px; text-transform: uppercase; }
.ovk__empty { color: var(--ink-soft); font: italic 400 18px/1.4 Bodoni Moda, Georgia, serif; }
/* .ovk__find / .ovk__key: the bar was deleted 2026-08-29, and its rules with
   it. The panel's own height maths changed with them — .ovk__grid is 100%. */
.ovk__notes { height: 140px; display: grid; grid-template-columns: repeat(2,1fr); border-top: 1px solid var(--line-strong); background: var(--panel-deep); content-visibility: auto; contain-intrinsic-size: 620px 140px; }
.ovk__note { min-width: 0; display: grid; grid-template-columns: 104px 1fr; gap: 12px; padding: 10px; border-right: 1px solid var(--line); }
.ovk__note:last-child { border-right: 0; }
.ovk__note-media { min-width: 0; height: 118px; background: var(--panel-raised); position: relative; overflow: hidden; }
.ovk__note-media::after { content: "MEDIA UNAVAILABLE"; position: absolute; inset: 0; display: none; place-items: center; padding: 8px; text-align: center; color: var(--ink-muted); font: 400 11px/1.4 JetBrains Mono, monospace; letter-spacing: 1px; }
.ovk__note.media-failed .ovk__note-media::after { display: grid; }
.ovk__note.media-failed img { display: none; }
.ovk__note-media img { width: 100%; height: 100%; object-fit: cover; }
.ovk__note-copy { min-width: 0; display: flex; flex-direction: column; }
.ovk__note-kind,
.ovk__note-date { color: var(--ink-muted); font: 400 11px/1.25 JetBrains Mono, monospace; letter-spacing: 1.2px; text-transform: uppercase; }
.ovk__note-title { margin: 5px 0; font: 400 14px/1.15 Bodoni Moda, Georgia, serif; overflow-wrap: anywhere; }
.ovk__note-date { margin-top: auto; }

/* ── Adaptation ──────────────────────────────────────────── */
@media (hover: hover) and (pointer: fine) {
  .ovk__pillar:hover { background: var(--panel-soft); }
  .ovk__route:hover { background: var(--panel-raised); }
  .ovk__hub:hover { background: var(--panel-raised); }
}
@media (prefers-reduced-motion: no-preference) {
  .ovk__bars::before,
  .ovk__bars::after { transition: transform 140ms var(--ease-out); }
  .ovk__segment-mark { transition: height 140ms var(--ease-settle), background-color 140ms var(--ease-settle); }
  .ovk__panel.is-morphing { will-change: transform, clip-path; }
}
@media (max-width: 1161px) and (min-width: 975px) {
  .ovk__grid { grid-template-columns: minmax(250px,.72fr) minmax(212px,.5fr) minmax(510px,1.45fr); }
  .ovk__detail { grid-template-columns: minmax(210px,.8fr) minmax(260px,1.2fr); }
  .ovk__intro { padding-inline: 16px; }
  .ovk__route { padding-inline: 10px; }
  .ovk__note { grid-template-columns: 1fr; }
  .ovk__note .ovk__note-media { display: none; }
}
@media (max-height: 780px) and (min-width: 975px) {
  .ovk__intro { padding-block: 12px; }
  .ovk__intro > p.ovk__micro:last-of-type { display: none; }
  .ovk__title { font-size: 26px; }
  .ovk__full { margin-bottom: 8px; }
  .ovk__viewing { margin-top: 8px; padding-block: 8px; } /* UNUSED since 2026-08-29 — see the block rule above */
  .ovk__hub { margin-top: 8px; }
}
@media (max-height: 759px) and (min-width: 975px) {
  .ovk__panel { overflow-x: clip; overflow-y: auto; overscroll-behavior: contain; }
  .ovk__grid { height: auto; min-height: 495px; }
  .ovk__plane { grid-template-rows: minmax(0,1fr) 104px; }
  .ovk__viewing { display: none; } /* UNUSED since 2026-08-29 — the block it hid here is now gone at every height */
  .ovk__notes { height: 104px; overflow-y: auto; }
  .ovk__note { min-height: 104px; grid-template-columns: 1fr; padding: 8px 10px; }
  .ovk__note .ovk__note-media { display: none; }
  .ovk__note-title { margin-block: 3px; font-size: 13px; line-height: 1.15; }
}
@media (max-width: 974px) {
  .ovk__panel { min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding-bottom: env(safe-area-inset-bottom); }
  .ovk__grid { height: auto; min-height: 100%; display: block; }
  .ovk__scene { display: block; height: 96px; border-right: 0; border-bottom: 1px solid var(--line-strong); }
  .ovk__scene-copy { display: grid; align-items: center; padding: 11px 16px 12px; }
  .ovk__scene-title { max-width: 280px; font-size: 24px; line-height: 1; }
  .ovk__readout { display: none; }
  /* 154px was 96px of scene plus the 58px find bar. The bar is gone, so this
     is 96px — the number is the sum of what actually sits above the sightline,
     and leaving it at 154 left 57px of dead space under the viewpoint grid at
     390px. Caught by "the viewpoint grid fills the sightline", which exists
     because this exact arithmetic went wrong once before (OVK-01). */
  .ovk__sightline { min-height: calc(var(--panel-h) - 96px); display: grid; grid-template-rows: minmax(260px,1fr); border-right: 0; }
  .ovk__pillars { display: grid; grid-template-columns: repeat(2,minmax(0,1fr)); grid-template-rows: repeat(5,minmax(52px,1fr)); min-height: 260px; }
  .ovk__pillar { min-height: 52px; grid-template-columns: 28px minmax(0,1fr); gap: 4px; padding: 6px 10px 6px 12px; font-size: 13px; }
  .ovk__pillar:nth-child(odd) { border-right: 1px solid var(--line); }
  .ovk__pillar:nth-last-child(-n+2) { border-bottom: 0; }
  .ovk__pillar-full { font-size: 12.5px; line-height: 1.15; }
  .ovk__plane { position: absolute; inset: 0; display: block; min-height: 100%; opacity: 0; pointer-events: none; transform: translate3d(100%,0,0); }
  .ovk__panel.mobile-detail .ovk__sightline { opacity: 0; pointer-events: none; transform: translate3d(-100%,0,0); }
  .ovk__panel.mobile-detail .ovk__plane { opacity: 1; pointer-events: auto; transform: translate3d(0,0,0); }
  .ovk__back { display: flex; align-items: center; width: 100%; position: sticky; top: 0; z-index: 6; background: var(--panel-deep); }
  .ovk__stack { height: auto; }
  .ovk__detail { height: auto; min-height: 100%; display: block; }
  .ovk__intro { min-height: 190px; border-right: 0; border-bottom: 1px solid var(--line); }
  .ovk__title { font-size: 32px; }
  .ovk__full { font-size: 13px; }
  .ovk__hub { min-height: 48px; }
  .ovk__routes { display: block; border-right: 0; }
  .ovk__routes li { min-height: 58px; border-bottom: 1px solid var(--line); }
  .ovk__route { min-height: 58px; grid-template-columns: 1fr auto; padding-block: 10px; }
  .ovk__route-name { font-size: 18px; line-height: 1.18; }
  .ovk__route-no,
  .ovk__route-state { font-size: 10px; }
  .ovk__notes { position: static; height: auto; grid-template-columns: 1fr; transform: none; visibility: visible; pointer-events: auto; }
  .ovk__note { min-height: 116px; grid-template-columns: 112px 1fr; border-right: 0; border-bottom: 1px solid var(--line); }
  .ovk__note-title { font-size: 16px; line-height: 1.2; }
  .ovk__results { min-height: 400px; overflow: visible; }
  .ovk__result-list { grid-template-columns: 1fr; }
  .ovk__result { min-height: 52px; font-size: 13px; }
}
@media (max-width: 760px) {
  .ovk { --panel-h: min(62dvh, calc(100dvh - var(--hpc-header-h, 120px))); }
  /* Five links do not fit 390px. Inside a fixed 45px row they wrapped
  mid-label ("THE / LEDGER"), which no gate caught because wrapping is
  not clipping. Scroll the row instead: every link keeps its shape, the
  header keeps its height, and nothing is hidden from assistive tech. */
  .ovk > summary.ovk__trigger { min-width: 102px; min-height: 48px; padding-inline: 8px; margin-left: 0; font-size: 11px; }
}
@media (max-width: 320px) {
  .ovk__scene-title { max-width: 100%; font-size: 20px; }
  .ovk__pillars { grid-template-columns: 1fr; grid-template-rows: none; grid-auto-rows: minmax(52px,auto); }
  .ovk__pillar:nth-child(odd) { border-right: 0; }
  .ovk__pillar:nth-last-child(2) { border-bottom: 1px solid var(--line); }
}
@media (pointer: coarse) {
  .ovk > summary.ovk__trigger,
  .ovk__pillar,
  .ovk__route,
  .ovk__hub,
  .ovk__back,
  .ovk__note { min-height: 44px; }
  .ovk__pillar,
  .ovk__route,
  .ovk__result,
  .ovk__note,
  .ovk__full { font-size: max(13px,1em); }
  .ovk__pillar-full { font-size: 13px; }
  .ovk__pillar:hover,
  .ovk__route:hover,
  .ovk__hub:hover { transform: none; }
}
@media (pointer: coarse) and (min-width: 975px) {
  .ovk__panel { overflow-x: clip; overflow-y: auto; overscroll-behavior: contain; }
  .ovk__grid { height: auto; min-height: 495px; }
}
@media (forced-colors: active) {
  .ovk { --ground: var(--system-canvas); --panel: var(--system-canvas); --panel-deep: var(--system-canvas); --panel-raised: var(--system-highlight); --panel-soft: var(--system-canvas); --ink: var(--system-text); --ink-hero: var(--system-text); --ink-soft: var(--system-text); --ink-muted: var(--system-text); --ink-faint: var(--system-text); --line: var(--system-text); --line-strong: var(--system-text); --gold: var(--system-link); --focus: var(--system-text); --bio: var(--system-text); --flow: var(--system-text); --decisions: var(--system-text); --learning: var(--system-text); --habits: var(--system-text); --identity: var(--system-text); --leadership: var(--system-text); --arena: var(--system-text); --nutri: var(--system-text); --social: var(--system-text); --shadow-panel: none; }
  .ovk__vista { forced-color-adjust: none; opacity: .18; }
  .ovk__route[aria-current="page"] { text-decoration: underline; text-decoration-thickness: 2px; }
  .ovk__pillar.is-selected { color: var(--system-highlight-text); }
  .ovk__pillar.is-selected .ovk__pillar-full,
  .ovk__pillar.is-selected .ovk__selected { color: var(--system-highlight-text); }
  .ovk__panel,
  .ovk__sightline,
  .ovk__plane,
  .ovk__notes { background: var(--system-canvas); }
  .ovk__panel a { text-decoration: underline; }
}

/* OVK-02 · the worded trigger overlapped the wordmark on a phone.
   The plugin's mobile masthead is built around a 44px ICON trigger: the
   wordmark keeps its full 202px and the bar's outer grid columns are 70px.
   The prototype could afford "MENU"/"CLOSE" in words because ITS brand shrank
   to "H·P·C" below 760px; this masthead's does not. Measured at 390px: the live
   Atlas trigger is 44px wide and clears the wordmark; the ported 102px worded
   trigger overlapped it by 24px, open AND closed, with every gate green —
   overlap is not clipping and not a sub-44px target.
   The word goes below 761px, the bars stay, and nothing is lost to assistive
   technology: the summary's own aria-label is "Menu" and aria-expanded carries
   the state, which is exactly how layout 2's icon-only trigger already works. */
@media (max-width: 760px) {
  .ovk > summary.ovk__trigger { min-width: 44px; gap: 0; padding-inline: 0; margin-left: 0; }
  /* Both halves of the copy, and at this specificity on purpose: the trigger
     block's own `.ovk[open] .ovk__copy.is-close { display: inline }` is more
     specific than a bare `.ovk__copy`, so a plain rule here hid MENU and left
     CLOSE showing — a 65px trigger when open, 44px when closed. */
  .ovk > summary.ovk__trigger .ovk__copy,
  .ovk[open] > summary.ovk__trigger .ovk__copy.is-close { display: none; }
}

/* ── The masthead's standing-head row, for layout 3 only ───────────────────
   MOVED OUT OF THIS SHEET, 2026-08-29, and the move is the point. The owner
   ruled OVK-03 the way that admits this row below 901px for layout 3, which
   makes it part of the header's first paint — and this sheet now loads via the
   print-media swap, i.e. after it. Rules that decide the header's HEIGHT cannot
   live in a deferred sheet: the row would appear late, or wrap mid-label until
   the scroll treatment arrived, and the header would grow under the reader's
   thumb on every phone page load.
   They are in assets/css/hpc-header.css beside the Overlook's critical block,
   scoped to .hpc-header--overlook exactly as they were here. One source of
   truth; search that file for OVK-03. */


/* ── Port corrections ───────────────────────────────────────────────────────
   Fixes for defects the port INHERITED, kept here rather than in the generated
   sections above so regenerating from the prototype cannot silently lose them.

   OVK-01 · the tenth viewpoint fell out of the panel on a 13" laptop.
   `.ovk__sightline` is a grid item with the default `min-height: auto`, so it
   cannot shrink below its content's min-content height. At 1440x780 its ten
   rows want 465px, the panel offers 434, and the extra 31px went under
   `overflow-y: clip` — "Relationship Neuroscience" simply gone, with every gate
   green, because clipping by an ancestor is not `scrollWidth > clientWidth` and
   the viewpoint census only ever ran at 390px.
   `min-height: 0` lets the 1fr row do what 1fr already promised. The prototype
   still has this at every height between 651px (where the panel starts
   scrolling) and ~830px; measured at 30.7px of overhang, identical to the port
   before this rule.

   SCOPED TO >=975px, and the scoping is the second half of the fix. Unscoped,
   this rule also beat the <=974px block's own
   `.ovk__sightline { min-height: calc(var(--panel-h) - 154px) }`, which mobile
   needs: the 2x5 viewpoint grid collapsed from 65px rows to 52px and left 64px
   of dead space under the list at 390px. Measured against the prototype, which
   keeps 369.3px there. The desktop defect and the mobile layout want opposite
   things from the same property. */
@media (min-width: 975px) {
  .ovk__sightline { min-height: 0; }
  .ovk__plane { min-height: 0; }
}
