/* assets/ip.css · RIVET IP as the signature visual system (reset Round 1, IP lane, 3 Nov 2026).
   The authored INFINITE mark and the registered figures, rendered from source by tools/build/ip_render.mjs into
   assets/ip/ and into the ip-* partials. This file only colours, lays out and moves them; it never draws geometry.
   API and markup: .research/reset/r1/ip.md.
     .ipm      the mark (inline SVG): variants .ipm--full | --fullDk | --bright | --quiet | --quietH | --quietDk | --loc | --locDk
     .ipm-icon the 24px menu icon (authored outline, currentColor)
     .ipx      K10 The INFINITE scene (pinned, scroll-lit)            · partials/sections/ip-infinite-scene.html
     .ipc      K10 compact (home: lights once, phase reads)           · partials/sections/ip-infinite-compact.html
     .ipk      K13 IP figure island (grid, earned read, caption)     · partials/sections/ip-figure-island.html
   Colour meaning (brief 2.2): cyan AI, gold human, Bright (cyan->gold) the two together = the mark's fill;
   magenta = the one insight here (the hinge, or the active read). Phase colours (2.1): Acquisition purple,
   Expansion green, the bridge in ink. Tokens from assets/brand-tokens.css with literal fallbacks.
   Motion: UI tier tokens only (dur-*, ease-*); reduced motion and no-JS show the end state. */

/* ── 1. IP tokens, per mode ─────────────────────────────────────────────────────────────────────────────────── */
:root,[data-mode="light"]{
  --ip-ink:#000000; --ip-soft:var(--slate,#4A4A68); --ip-paper:#FFFFFF; --ip-ground:var(--ghost-white,#F8F8FA);
  --ip-line:var(--silver,#D1D1D9); --ip-primary:var(--purple,#3B06D4); --ip-insight:var(--magenta,#FF00D4);
  --ip-acq:var(--purple,#3B06D4); --ip-win:#000000; --ip-exp:var(--green-500,#00A763);
  --ip-acq-text:var(--purple,#3B06D4); --ip-exp-text:var(--green-600,#00864F);
  --ip-grid-line:rgba(209,209,217,.55);
  --ip-card-shadow:0 1px 2px rgba(0,0,0,.06),0 8px 24px rgba(0,0,0,.06);
  --ip-sans:var(--font-sans,"IBM Plex Sans",system-ui,sans-serif); --ip-mono:var(--font-mono,"IBM Plex Mono",ui-monospace,monospace);
  --ip-dur:var(--dur-base,320ms); --ip-dur-slow:var(--dur-slow,560ms); --ip-dur-quick:var(--dur-quick,200ms);
  --ip-ease:var(--ease-standard,cubic-bezier(.2,0,0,1)); --ip-ease-em:var(--ease-emphasized,cubic-bezier(.3,0,0,1));
  --ip-focus:var(--purple,#3B06D4);
}
[data-mode="dark"],.ip-dark{
  --ip-ink:#FFFFFF; --ip-soft:var(--slate-on-dark,#9A9BBD); --ip-paper:var(--elev-1,#0A0A0C); --ip-ground:#000000;
  --ip-line:var(--elev-4,#1E1E2A); --ip-primary:var(--cyan,#4CF3FE); --ip-insight:var(--magenta,#FF00D4);
  --ip-acq:var(--purple-500,#7B87FF); --ip-win:#FFFFFF; --ip-exp:var(--green,#00D982);
  --ip-acq-text:var(--purple-500,#7B87FF); --ip-exp-text:var(--green,#00D982);
  --ip-grid-line:var(--elev-3,#1A1A22); --ip-card-shadow:none; --ip-focus:var(--purple-500,#7B87FF);
}

/* ── 2. The mark ────────────────────────────────────────────────────────────────────────────────────────────── */
.ipm{display:block;width:100%;height:auto;overflow:visible}
.ipm text{font-family:var(--ip-sans)}
/* variants read the tokens, so one inline SVG follows its mode (file SVGs carry the same colours as attributes) */
.ipm--full .ipm-room[data-phase="acq"] .ipm-line,.ipm--loc .ipm-room[data-phase="acq"] .ipm-line,
.ipm--full .ipm-dot[data-room="0"],.ipm--full .ipm-dot[data-room="1"],.ipm--full .ipm-dot[data-room="2"]{fill:var(--ip-acq)}
.ipm--full .ipm-room[data-phase="exp"] .ipm-line,.ipm--loc .ipm-room[data-phase="exp"] .ipm-line,
.ipm--full .ipm-dot[data-room="5"],.ipm--full .ipm-dot[data-room="6"],.ipm--full .ipm-dot[data-room="7"]{fill:var(--ip-exp)}
.ipm--full .ipm-room[data-phase="win"] .ipm-line,.ipm--loc .ipm-room[data-phase="win"] .ipm-line{fill:var(--ip-win)}
.ipm--full .ipm-phase[data-phase="acq"],.ipm--loc .ipm-phase[data-phase="acq"]{fill:var(--ip-acq-text)}
.ipm--full .ipm-phase[data-phase="exp"],.ipm--loc .ipm-phase[data-phase="exp"]{fill:var(--ip-exp-text)}
.ipm--full .ipm-lbl,.ipm--full .ipm-phase[data-phase="win"],.ipm--loc .ipm-lbl{fill:var(--ip-ink)}
.ipm--quiet .ipm-line,.ipm--quiet .ipm-dot,.ipm--quiet text,.ipm--quiet .ipm-hinge{fill:var(--ip-ink)}
.ipm--quiet .ipm-bud{stroke:var(--ip-ink)}
.ipm--quietH .ipm-hinge{fill:var(--ip-insight)}
/* Bright is black-ink on both modes (on-duo-ink-light): the fill carries the ink, not the page */
.ipm--bright .ipm-line,.ipm--bright .ipm-dot,.ipm--bright text{fill:#000}
.ipm--bright .ipm-bud{stroke:#000}

/* the menu icon (replaces the Lucide infinity): 24px, currentColor, 1.75px like the Lucide set beside it */
.ipm-icon{display:inline-block;width:24px;height:24px;flex:none;vertical-align:middle}

/* a locator sits on a card as a small, quiet map of where the course lives */
.ip-loc{display:block;width:100%;max-width:220px;height:auto}
.ip-loc--names{max-width:420px}

/* ── 3. Shared section type (falls back when assets/type.css is absent) ────────────────────────────────────── */
.ip-eyebrow{margin:0;font:500 var(--t-meta,.75rem)/1.4 var(--ip-mono);letter-spacing:var(--tr-label,.08em);text-transform:uppercase;color:var(--ip-soft)}
.ip-h2{margin:0;font:600 var(--role-section,clamp(1.75rem,1.4213rem + 1.3483vw,2.5rem))/1.2 var(--ip-sans);letter-spacing:var(--tr-title,-.02em);color:var(--ip-ink);text-wrap:balance}
.ip-lead{margin:0;font:400 var(--t-lead,1.125rem)/1.6 var(--ip-sans);color:var(--ip-soft);text-wrap:pretty;max-width:46ch}
.ip-now{margin:0;font:500 var(--t-meta,.75rem)/1.5 var(--ip-mono);letter-spacing:.04em;color:var(--ip-ink)}
.ip-now b{font-weight:600;letter-spacing:var(--tr-label,.08em);text-transform:uppercase;color:var(--ip-soft);margin-inline-end:.75em}

/* ── 4. K10 The INFINITE scene ──────────────────────────────────────────────────────────────────────────────── */
.ipx{position:relative;background:var(--ip-ground);color:var(--ip-ink);isolation:isolate}
.ipx__stage{max-width:1280px;margin:0 auto;padding:clamp(64px,8vw,96px) 16px;display:grid;gap:clamp(24px,3vw,40px)}
@media (min-width:768px){.ipx__stage{padding-inline:24px}}
.ipx__head{display:grid;gap:12px;align-content:start}
.ipx__fig{margin:0;position:relative;display:grid;gap:16px;align-content:center}
.ipx__mark{position:relative}
.ipx__mark::before{content:"";position:absolute;inset:-8% -4%;z-index:-1;pointer-events:none;
  background-image:linear-gradient(to right,var(--ip-grid-line) 1px,transparent 1px),linear-gradient(to bottom,var(--ip-grid-line) 1px,transparent 1px);
  background-size:32px 32px;-webkit-mask-image:radial-gradient(ellipse at center,#000 30%,transparent 72%);mask-image:radial-gradient(ellipse at center,#000 30%,transparent 72%)}
.ipx__cap{text-align:center}
/* static (no JS, reduced motion, print): the lit mark and every stage as a list */
.ipx__steps{list-style:none;margin:0;padding:0;display:grid;gap:12px;grid-template-columns:repeat(auto-fill,minmax(min(100%,260px),1fr))}
.ipx__step{background:var(--ip-paper);border-radius:12px;box-shadow:var(--ip-card-shadow);padding:20px 20px 18px;display:grid;gap:6px;align-content:start}
.ipx__n{font:500 .75rem/1.4 var(--ip-mono);letter-spacing:.08em;color:var(--ip-soft);font-variant-numeric:tabular-nums}
.ipx__name{margin:0;font:600 var(--role-card,1.375rem)/1.2 var(--ip-sans);letter-spacing:-.01em;color:var(--ip-ink)}
.ipx__line{margin:0;font:400 1rem/1.6 var(--ip-sans);color:var(--ip-ink);text-wrap:pretty}
.ipx__in{margin:6px 0 0;font:500 .75rem/1.45 var(--ip-mono);letter-spacing:.06em;color:var(--ip-soft)}
.ipx__in b{font-weight:600;color:var(--ip-ink);letter-spacing:.02em}
.ipx__step[data-step="0"]{display:none}
.ipx__progress{display:none}
@media (min-width:1024px){
  .ipx__stage{grid-template-columns:minmax(0,5fr) minmax(0,7fr);grid-template-areas:"head fig" "steps steps";column-gap:56px}
  .ipx__head{grid-area:head;align-self:center}.ipx__fig{grid-area:fig}.ipx__steps{grid-area:steps}
}

/* live (assets/ip.js adds .is-live when motion is allowed): a ~260vh track, the stage pinned */
.ipx.is-live .ipx__track{height:260vh;height:260svh}
.ipx.is-live .ipx__stage{position:sticky;top:0;height:100vh;height:100svh;box-sizing:border-box;padding-block:clamp(80px,11vh,112px) clamp(24px,5vh,56px);
  grid-template-rows:auto minmax(0,1fr) auto;align-content:stretch}
.ipx.is-live .ipx__steps{display:grid;grid-template-columns:1fr;grid-template-areas:"s";gap:0}
.ipx.is-live .ipx__step{grid-area:s;opacity:0;transform:translateY(12px);visibility:hidden;
  transition:opacity var(--ip-dur) var(--ip-ease),transform var(--ip-dur) var(--ip-ease),visibility 0s linear var(--ip-dur)}
.ipx.is-live .ipx__step.is-now{opacity:1;transform:none;visibility:visible;transition-delay:0s}
.ipx.is-live .ipx__step[data-step="0"]{display:grid}
.ipx.is-live .ipx__progress{display:flex;gap:6px;align-items:center}
.ipx__tick{flex:1;height:3px;border-radius:2px;background:var(--ip-line);transform-origin:left center;transition:background var(--ip-dur) var(--ip-ease)}
.ipx__tick.is-done{background:var(--ip-ink)}
.ipx__count{font:500 .75rem/1 var(--ip-mono);letter-spacing:.08em;color:var(--ip-soft);font-variant-numeric:tabular-nums;margin-inline-start:10px;white-space:nowrap}
/* the mark in live mode: rooms wait faint, then light in order; Bright fills a lit room, its outline goes to ink */
.ipx.is-live .ipm-fill,.ipx.is-live .ipm-room,.ipx.is-live .ipm-dot,.ipx.is-live .ipm-lbl,.ipx.is-live .ipm-phase,.ipx.is-live .ipm-bud{
  transition:opacity var(--ip-dur-slow) var(--ip-ease-em)}
.ipx.is-live .ipm-fill{opacity:.07}
.ipx.is-live .ipm-room,.ipx.is-live .ipm-bud{opacity:.3}
.ipx.is-live .ipm-dot,.ipx.is-live .ipm-lbl,.ipx.is-live .ipm-phase{opacity:.35}
.ipx.is-live .is-on{opacity:1 !important}
.ipx.is-live .is-off{opacity:.1 !important}
/* an unlit room has no duo under it, so its outline, dot and label take the page ink (black on light, white on dark) */
.ipx.is-live .ipm-room:not(.is-on) .ipm-line,.ipc.is-armed .ipm-room:not(.is-on) .ipm-line,.ipc .ipm-room.is-off .ipm-line,.ipx.is-live .ipm-room.is-off .ipm-line{fill:var(--ip-ink)}
.ipx.is-live :is(.ipm-dot,.ipm-lbl,.ipm-phase):not(.is-on),.ipc.is-armed :is(.ipm-dot,.ipm-lbl,.ipm-phase):not(.is-on),.ipc :is(.ipm-dot,.ipm-lbl,.ipm-phase).is-off,.ipx.is-live :is(.ipm-dot,.ipm-lbl,.ipm-phase).is-off{fill:var(--ip-ink)}
.ipx.is-live .ipm-bud:not(.is-on),.ipc.is-armed .ipm-bud:not(.is-on),.ipc .ipm-bud.is-off{stroke:var(--ip-ink)}
.ipx.is-live .ipm-hinge{fill:var(--ip-ink);transform-box:fill-box;transform-origin:center;transition:fill var(--ip-dur) var(--ip-ease)}
.ipx.is-live[data-hinge="on"] .ipm-hinge{fill:var(--ip-insight);animation:ip-pop var(--ip-dur-slow) var(--ip-ease-em) 1}
.ipx.is-live[data-reentry="on"] .ipm-bud{transform-box:fill-box;transform-origin:center;animation:ip-pop var(--ip-dur-slow) var(--ip-ease-em) 1}
.ipx.is-live .ipx__step.is-now .ipx__name{animation:ip-rise var(--ip-dur) var(--ip-ease) 1}
/* the hinge step points at the mark's hinge with a hollow ink dot: the magenta stays on the mark (one insight) */
.ipx__step--hinge .ipx__n::before{content:"";display:inline-block;width:8px;height:8px;border-radius:50%;box-shadow:inset 0 0 0 1.5px var(--ip-ink);margin-inline-end:8px;vertical-align:-.05em}
@keyframes ip-pop{0%{transform:scale(1)}40%{transform:scale(1.6)}100%{transform:scale(1)}}
@keyframes ip-rise{from{opacity:.4;transform:translateY(6px)}to{opacity:1;transform:none}}
@media (min-width:1024px){
  .ipx.is-live .ipx__stage{grid-template-columns:minmax(0,5fr) minmax(0,7fr);grid-template-rows:auto auto auto;align-content:center;
    grid-template-areas:"head fig" "steps fig" "prog fig";column-gap:64px;row-gap:32px;
    padding-block:calc(var(--header-h,64px) + 24px) 32px}   /* centred in the sticky frame, the step bar 32px under the copy (review P2-3) */
  .ipx.is-live .ipx__fig{align-self:center}
  .ipx.is-live .ipx__steps{grid-area:steps;min-height:11.5em;align-content:start}
  .ipx.is-live .ipx__progress{grid-area:prog;max-width:420px}
  .ipx.is-live .ipx__step{background:none;box-shadow:none;padding:0;gap:10px}
  .ipx.is-live .ipx__name{font-size:var(--role-row,1.75rem)}
  .ipx.is-live .ipx__line{font-size:var(--t-lead,1.125rem)}
}
@media (max-width:1023.98px){
  .ipx.is-live .ipx__stage{grid-template-areas:"head" "fig" "steps" "prog";grid-template-rows:auto minmax(0,1fr) auto auto;gap:16px}
  .ipx.is-live .ipx__head{grid-area:head}.ipx.is-live .ipx__fig{grid-area:fig;min-height:0}
  .ipx.is-live .ipx__steps{grid-area:steps}.ipx.is-live .ipx__progress{grid-area:prog}
  .ipx.is-live .ipx__head .ip-lead{display:none}
  .ipx.is-live .ipx__cap{display:none}
  .ipx.is-live .ipx__step{min-height:9.5em}
}
/* on phones the mark is about 360px wide, so its 17-unit labels would set at 7px: the stage panel names the room instead */
@media (max-width:599.98px){.ipx .ipm-lbl,.ipx .ipm-phase,.ipc .ipm-lbl,.ipc .ipm-phase{display:none}}

/* ── 5. K10 compact (home) ──────────────────────────────────────────────────────────────────────────────────── */
.ipc{background:var(--ip-ground);color:var(--ip-ink)}
.ipc__in{max-width:1280px;margin:0 auto;padding:clamp(64px,8vw,96px) 16px;display:grid;gap:clamp(28px,4vw,56px);align-items:center}
@media (min-width:768px){.ipc__in{padding-inline:24px}}
@media (min-width:1024px){.ipc__in{grid-template-columns:minmax(0,5fr) minmax(0,7fr)}}
.ipc__text{display:grid;gap:14px;align-content:start}
.ipc__phases{list-style:none;margin:10px 0 0;padding:0;display:grid;gap:8px}
.ipc__phase{appearance:none;width:100%;text-align:start;display:grid;grid-template-columns:12px 1fr;column-gap:14px;row-gap:2px;align-items:baseline;
  padding:14px 16px;border:0;border-radius:12px;background:var(--ip-paper);box-shadow:var(--ip-card-shadow);color:var(--ip-ink);font:inherit;cursor:pointer;min-height:44px;
  transition:transform var(--ip-dur-quick) var(--ip-ease),box-shadow var(--ip-dur-quick) var(--ip-ease)}
.ipc__phase:hover{transform:translateY(-2px)}
.ipc__phase[aria-pressed="true"]{box-shadow:inset 0 0 0 1.5px var(--ip-ink),var(--ip-card-shadow)}
.ipc__phase:focus-visible,.ipk__chip:focus-visible,.ipk-part:focus-visible{outline:3px solid var(--ip-focus);outline-offset:2px}
.ipc__sw{width:12px;height:12px;border-radius:4px;align-self:center;grid-row:1 / span 2}
.ipc__phase[data-phase="acq"] .ipc__sw{background:var(--ip-acq)}
.ipc__phase[data-phase="win"] .ipc__sw{background:var(--ip-win)}
.ipc__phase[data-phase="exp"] .ipc__sw{background:var(--ip-exp)}
.ipc__pn{font:600 1rem/1.3 var(--ip-sans)}
.ipc__pl{font:400 .875rem/1.5 var(--ip-sans);color:var(--ip-soft)}
.ipc__fig{margin:0;display:grid;gap:14px}
.ipc__mark{position:relative}
.ipc__mark::before{content:"";position:absolute;inset:-10% -4%;z-index:0;pointer-events:none;
  background-image:linear-gradient(to right,var(--ip-grid-line) 1px,transparent 1px),linear-gradient(to bottom,var(--ip-grid-line) 1px,transparent 1px);
  background-size:32px 32px;-webkit-mask-image:radial-gradient(ellipse at center,#000 30%,transparent 72%);mask-image:radial-gradient(ellipse at center,#000 30%,transparent 72%)}
.ipc__mark .ipm{position:relative}
.ipc .ipm-fill,.ipc .ipm-room,.ipc .ipm-dot,.ipc .ipm-lbl,.ipc .ipm-phase,.ipc .ipm-bud{transition:opacity var(--ip-dur) var(--ip-ease-em)}
.ipc.is-armed .ipm-fill{opacity:.07}.ipc.is-armed .ipm-room,.ipc.is-armed .ipm-dot,.ipc.is-armed .ipm-lbl,.ipc.is-armed .ipm-phase,.ipc.is-armed .ipm-bud{opacity:.3}
.ipc.is-armed .ipm-hinge{fill:var(--ip-ink)}
.ipc .is-on{opacity:1 !important}.ipc .is-off{opacity:.12 !important}
.ipc .ipm-hinge{transform-box:fill-box;transform-origin:center;transition:fill var(--ip-dur) var(--ip-ease)}
.ipc.is-done .ipm-hinge{animation:ip-pop var(--ip-dur-slow) var(--ip-ease-em) 1}

/* ── 6. K13 IP figure island ────────────────────────────────────────────────────────────────────────────────── */
.ipk{--ip-insight-on:var(--magenta,#FF00D4);margin:0;position:relative;display:grid;gap:0;background:var(--ip-paper);border-radius:24px;box-shadow:var(--ip-card-shadow);overflow:hidden;color:var(--ip-ink)}
/* default: no magenta (the screen's insight budget stays free); the active read carries the one magenta */
.ipk__canvas{--ip-insight:var(--ip-primary);position:relative;padding:clamp(24px,4vw,48px) clamp(16px,3vw,40px) clamp(16px,2vw,24px)}
.ipk__canvas::before{content:"";position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(to right,var(--ip-grid-line) 1px,transparent 1px),linear-gradient(to bottom,var(--ip-grid-line) 1px,transparent 1px);
  background-size:32px 32px;-webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 55%,transparent 100%);mask-image:linear-gradient(to bottom,#000 0%,#000 55%,transparent 100%)}
.ipk__canvas svg{position:relative;display:block;width:100%;height:auto;max-width:880px;margin:0 auto}
/* phones: the figure keeps a legible size and scrolls sideways inside its island (the page itself never scrolls sideways) */
@media (max-width:767.98px){.ipk__canvas{overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:thin}.ipk__canvas svg{width:640px;max-width:none}}
.ipk-part{transition:opacity var(--ip-dur-quick) var(--ip-ease);outline:none}
.ipk.is-reading .ipk-part{opacity:.32}
.ipk.is-reading .ipk-part.is-on{opacity:1;--ip-primary:var(--ip-insight-on);--ip-insight:var(--ip-insight-on)}
.ipk__body{display:grid;gap:14px;padding:4px clamp(16px,3vw,40px) clamp(20px,3vw,32px)}
.ipk__reads{display:flex;flex-wrap:wrap;gap:8px}
.ipk__chip{appearance:none;border:0;border-radius:999px;min-height:44px;padding:0 16px;font:500 .875rem/1 var(--ip-sans);cursor:pointer;
  background:var(--ip-ground);color:var(--ip-ink);box-shadow:inset 0 0 0 1px var(--ip-line);transition:background var(--ip-dur-quick) var(--ip-ease),color var(--ip-dur-quick) var(--ip-ease)}
.ipk__chip:hover{box-shadow:inset 0 0 0 1px var(--ip-ink)}
.ipk__chip[aria-pressed="true"]{background:var(--ip-ink);color:var(--ip-paper);box-shadow:none}
.ipk__read{margin:0;min-height:3.2em;font:400 var(--t-lead,1.125rem)/1.6 var(--ip-sans);color:var(--ip-ink);text-wrap:pretty;max-width:62ch}
.ipk__read b{font-weight:600}
.ipk__cap{padding-top:14px;border-top:1px solid var(--ip-line)}

/* ── 7. Reduced motion and print: the end state, nothing moves ─────────────────────────────────────────────── */
@media (prefers-reduced-motion:reduce){
  .ipx *,.ipc *,.ipk *{animation:none !important;transition:none !important}
}
@media print{.ipx .ipx__track{height:auto !important}.ipx .ipx__stage{position:static !important;height:auto !important}}

/* ── 8. Right to left: the mark and its figures never mirror (they are figures, like logos and charts) ────── */
[dir="rtl"] .ipm,[dir="rtl"] .ipk__canvas svg{direction:ltr}
[dir="rtl"] .ipx__step,[dir="rtl"] .ipc__phase{text-align:right}

/* the compact's live region is for screen readers only */
.ipc__live{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
