/* refarch.css — interactive reference-architecture pages.
   Extracted from the standalone interactive builds so these pages ship under the
   site's strict CSP (no inline <style>, no style="" attributes).
   Load order matters: this file must come AFTER style.css and enhance.css.
   Base = the Local Healthcare build (the superset); per-page deltas are scoped
   by the body class .ra-<key> at the bottom of this file. */

  :root{
    --bg0:#0A1320; --bg1:#0E1A2B; --panel:#16263F; --panel2:#1B2E4A;
    --line:#2A3D5C; --ink:#EAF1FA; --muted:#9DB0C7; --faint:#8093AA;
    --blue:#3B82F6; --blue2:#60A5FA; --teal:#22C7C7; --mint:#34D399;
    --amber:#F6C453; --slate:#7E93B0; --rose:#F472B6;
/* --blue as a FILL behind white text, which is a different job from --blue as a
   line or a label. White on #3B82F6 is 3.68:1 — under the 4.5:1 that 12.5px/700
   button text needs. Darkening it 86% toward black preserves hue and saturation
   exactly (a color-mix with black in sRGB is a scalar multiply) and lands at
   4.76:1 for the white text while still holding 3.19:1 against the --panel the
   control sits on, which is what WCAG 1.4.11 asks of a fill that signals "this
   segment is the selected one". Those two pull in opposite directions — darker
   helps the text and hurts the state cue — and 86% is close to the widest gap
   where both clear. Anything past 82% fails the state cue instead. */
    --blue-fill:#3370D4;
    --glow:0 0 0 1px rgba(255,255,255,.04), 0 10px 30px rgba(0,0,0,.35);
  }
  *{box-sizing:border-box}
  html,body{margin:0;height:100%}
  body{
    background:radial-gradient(1200px 700px at 80% -10%, #15263f 0%, var(--bg1) 45%, var(--bg0) 100%);
    color:var(--ink); font-family:"Inter",system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
    -webkit-font-smoothing:antialiased; overflow-x:hidden; min-height:100%;
  }
  .wrap{max-width:1240px; margin:0 auto; padding:22px 22px 40px}
  .top{display:flex; align-items:flex-end; justify-content:space-between; gap:18px; flex-wrap:wrap; margin-bottom:14px}
  .title h1{font-size:calc(clamp(20px,2.6vw,30px) * var(--fs, 1)); margin:0; letter-spacing:-.02em; font-weight:800}
  .title h1 .accent{color:var(--blue2)}
  .title p{margin:4px 0 0; color:var(--muted); font-size:calc(clamp(12px,1.4vw,15px) * var(--fs, 1))}
  .mission{margin:8px 0 0; font-size:calc(clamp(12px,1.42vw,14.5px) * var(--fs, 1)); color:var(--amber); font-weight:600; max-width:800px; line-height:1.4}
  .toolbar{display:flex; gap:8px; align-items:center}
  .seg{display:flex; background:var(--panel); border:1px solid var(--line); border-radius:11px; padding:3px}
  .seg button{background:transparent; border:0; color:var(--muted); font-weight:700; font-size:calc(12.5px * var(--fs, 1)); padding:7px 12px; border-radius:8px; cursor:pointer}
  .seg button.on{background:var(--blue-fill); color:#fff}
  .stage{position:relative; background:linear-gradient(180deg, rgba(27,46,74,.45), rgba(14,26,43,.55));
    border:1px solid var(--line); border-radius:20px; padding:16px; box-shadow:var(--glow); overflow:hidden}
  .canvasWrap{display:flex; justify-content:center}
/* container-type is the fix for the node-overlap defect. Node POSITIONS are
   percentages of this box; node SIZES used to be viewport-relative (vw), so the
   two drifted apart and nodes collided — badly at phone widths, where the canvas
   collapses to ~312px while a 12.5vw node stays ~96px. Sizing everything inside
   in cqw (1% of this box) makes the diagram behave like a vector drawing: the
   geometry is fixed, so if it clears at one width it clears at every width. */
  .canvas{position:relative; width:100%; aspect-ratio:16/9; max-height:72vh;
    container-type:inline-size}
  .vertical .canvas{aspect-ratio:9/16; max-height:78vh; max-width:440px}
/* Phone widths: rows are percentages of canvas height, and below ~300px of
   canvas the labels hit their px floor and wrap to four or five lines, so the
   boxes grow taller than the gaps between rows. Give the drawing more height
   instead of shrinking the type further — a tall diagram you scroll is a normal
   phone reading experience; two boxes on top of each other is not. */
  @media (max-width:480px){
    .vertical .canvas{aspect-ratio:9/21; max-height:none}
  }
/* Below ~940px of canvas the label type hits its px floor: the boxes keep
   shrinking but the words stop, so long labels ("Procure-to-Pay",
   "Differentiation") no longer fit and get broken mid-word. Rather than shrink
   the type past legibility, hold the 16:9 canvas at the width its type needs
   and let the wrapper scroll — the reader pans the real drawing instead of
   reading a squashed one. 1000px covers every viewport whose canvas would fall
   under 940. flex-start, not center — a centred flex item that overflows is
   unreachable at the start edge in several browsers. */
  @media (max-width:1000px){
    .canvasWrap{overflow-x:auto; overscroll-behavior-x:contain; justify-content:flex-start}
    .stage:not(.vertical) .canvas{min-width:940px}
  }
/* 320px (iPhone SE 1st gen and the oldest Androids) needs one more step: the
   canvas is only ~242px wide there, so labels wrap further still — measured at
   up to eight lines in a 45px box, against three at 430px. Node heights are set
   by that wrapped text while the gaps between rows are percentages of the
   canvas, so every extra line is taken out of the gap: the intake node ends up
   9px above the next row where the zone below it needs 24px to hold its name,
   and the name gets painted over. There is no horizontal room to widen the
   boxes instead — the three-across rows leave 3px between neighbours — so the
   only lever is height. 9/28 buys back the ~7px the top gaps are short by, at
   the cost of a drawing about a tenth taller on a screen that already scrolls. */
  @media (max-width:340px){
    .vertical .canvas{aspect-ratio:9/28}
  }
  svg.links{position:absolute; inset:0; width:100%; height:100%; z-index:2; pointer-events:none}
  .zone{position:absolute; z-index:1; border-radius:16px; border:1px dashed rgba(255,255,255,.13); background:rgba(255,255,255,.022)}
/* The pill is sized by its own text but positioned against a zone whose size
   comes from node coordinates, and nothing couples the two: a two-member column
   gives "Safeguards" a 94px zone for a 110px label. Straddling the border at
   top:-10px then pushed the overhang into the zone above, where a node covered
   it (.node z-index 3 beats .zone 1) — measured as a 24px-tall hit on the erp
   "Governed action boundary" pill at 390px, i.e. the whole label hidden.
   placeZones() already reserves a band for the label: it offsets the zone up by
   6px and adds 6px of height on top of an 18px pad, so there are 24px of empty
   space between the zone's top edge and its topmost member. The pill is 23px
   tall, so sitting it inside that band at top:1px fits exactly — it stops
   reaching into the zone above without moving a single node.
   nowrap because a zone name broken across two lines reads as a rendering fault
   and, being twice as tall, reaches further into the row above; a label that
   overhangs its dashed rectangle by a few pixels still reads as a label. */
  .zone .zlabel{position:absolute; top:1px; left:14px; font-size:calc(11px * var(--fs, 1)); font-weight:800; letter-spacing:.08em;
    white-space:nowrap; text-transform:uppercase; padding:2px 8px; border-radius:999px;
    background:var(--bg1); color:var(--muted); border:1px solid var(--line)}
/* The 9:16 canvas is at most 440px wide and about 290px on a small phone, and a
   zone name is the longest string in the drawing. Scaling the pill with the
   canvas the way the node type already scales buys back roughly a fifth of its
   width there, so placeZones() has far less to claw back — and where it still
   has to nudge, the pill lands nearer the region it names. The 11px ceiling is
   the desktop size, so nothing changes above ~355px of canvas. */
  .vertical .zone .zlabel{font-size:calc(clamp(9px,3.1cqw,11px) * var(--fs, 1)); letter-spacing:.06em; padding:2px 6px}
/* Widths are a share of the canvas, not the viewport. The budget is the tightest
   same-row centre gap in the six diagrams' own coordinates: 11% horizontally
   (hq guard~critic, erp event~orch, education-ai guard~integrity, local-*
   learner/patient~planner) and 20% in the 9:16 set (erp a2~a3). Only one node
   is lit at a time and .node.active scales 1.06, so the worst case is one lit
   node beside a resting one: (1.06 x 10.5 + 10.5) / 2 = 10.8 < 11, and
   (1.06 x 18.6 + 18.6) / 2 = 19.2 < 20. Both sit just under the ceiling on
   purpose — every 1% of width is a percent more room for a long word. */
  .node{position:absolute; transform:translate(-50%,-50%); z-index:3; width:10.5cqw;
    background:var(--panel); border:1px solid var(--line); border-radius:10px; padding:.85cqw .68cqw; cursor:pointer;
    transition:transform .35s cubic-bezier(.2,.8,.2,1), box-shadow .35s, border-color .35s, opacity .35s, background .35s; opacity:.5}
  .vertical .node{width:18.6cqw; padding:1.6cqw .9cqw; border-radius:9px}
/* A node is as tall as its wrapped label, and on a phone a one-line label makes
   a box 20-23px tall — under the 24px WCAG 2.5.8 floor for a pointer target.
   The obvious fix, min-height:24px, is the wrong one here: .node is centred with
   translate(-50%,-50%), so it grows symmetrically about its own centre, and the
   measured clearance between a node and the zone pill above it is as little as
   0.2px. Growing the box would walk straight into the pill placement that
   placeZones() spends its 24px band protecting.
   2.5.8 sizes the region that ACCEPTS the pointer action, not the painted box,
   and a pseudo-element hits its originating element — so an invisible,
   out-of-flow ::before enlarges the target without moving a single pixel of
   layout. max(100%, 24px) is self-limiting: it expands only as far as the floor
   requires and no further, which on the tightest pair (a 24.6px vertical gap)
   costs 1.85px a side and leaves ~21px still clear between hit areas. */
  .node::before{content:""; position:absolute; left:50%; top:50%;
    width:max(100%, 24px); height:max(100%, 24px); transform:translate(-50%,-50%)}
/* Type scales with the node so labels wrap the same way at every width, with a
   px floor so it stays legible once the canvas is small.
   The 9:16 layout puts four agents across a canvas that is ~310px wide on a
   phone; at that scale a 15-character word cannot fit its box at any readable
   size, so it has to break. The labels carry U+00AD soft hyphens at ordinary
   syllable divisions so that break is a typographic one ("Differen-tiation")
   rather than a severed one ("Differentiat/ion").
   Hyphenation is switched off in the 16:9 layout, and that is the point of
   these two rules rather than an oversight. The pannable canvas holds the
   horizontal drawing at 940px minimum, where every word already fits its box —
   so a break opportunity there is never needed, only taken. A greedy line
   breaker takes the last opportunity that fits, so an inert soft hyphen turns
   "Teacher / Request" into "Teacher / Re-" + "quest" where it would otherwise
   have broken at the space. hyphens:none suppresses soft hyphens as well as
   dictionary hyphenation, which is exactly the scope wanted: the words are
   whole in the wide layout and breakable in the narrow one.
   overflow-wrap stays on in both as the last resort for compounds no
   hyphenation covers. */
  .node .nlabel{font-size:calc(clamp(10px,1.07cqw,13.5px) * var(--fs, 1)); font-weight:800; line-height:1.12; letter-spacing:-.01em;
    hyphens:none; overflow-wrap:anywhere}
  .vertical .node .nlabel{font-size:calc(clamp(9.5px,2.55cqw,12px) * var(--fs, 1)); hyphens:auto}
  .node .ntag{font-size:calc(clamp(8px,.72cqw,9.5px) * var(--fs, 1)); text-transform:uppercase; letter-spacing:.07em; color:var(--muted); margin-top:2px; font-weight:700}
  .vertical .node .ntag{display:none}
  .node .dot{width:7px;height:7px;border-radius:50%;background:var(--accent,#3B82F6);position:absolute;top:7px;right:7px;opacity:.5}
  .node.seen{opacity:1}
  .node.active{opacity:1; border-color:var(--accent,#3B82F6); background:var(--panel2);
    box-shadow:0 0 0 1px var(--accent,#3B82F6), 0 0 26px -4px var(--accent,#3B82F6), 0 14px 34px rgba(0,0,0,.4);
    transform:translate(-50%,-50%) scale(1.06)}
  .node.active .dot{opacity:1; box-shadow:0 0 12px 2px var(--accent)}
/* The hub keeps its ~1.11x emphasis. Its tightest neighbour is 14% away (erp
   approve~writeback), and (1.06 x 11.6 + 10.5) / 2 = 11.4% clears that; in the
   9:16 set the nearest is 22% (local-* llm~cag) against 20.3%. */
  .node.hub{width:11.6cqw}
  .vertical .node.hub{width:20.6cqw}
  .g-io{--accent:var(--slate)} .g-core{--accent:var(--blue)} .g-agent{--accent:var(--blue2)}
  .g-retrieval{--accent:var(--teal)} .g-engine{--accent:var(--rose)} .g-verify{--accent:var(--mint)} .g-human{--accent:var(--amber)}
  path.link{fill:none; stroke:var(--line); stroke-width:2; opacity:.55}
  path.link.lit{stroke:var(--blue); opacity:.85}
  path.link.flow{stroke:var(--blue2); stroke-width:3; opacity:1; stroke-dasharray:7 9; animation:flow .7s linear infinite}
  @keyframes flow{to{stroke-dashoffset:-32}}
  circle.pulse{fill:#fff; filter:drop-shadow(0 0 6px var(--blue2))}
  .gov{display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin-top:14px; padding:11px 12px; background:var(--panel); border:1px solid var(--line); border-radius:13px}
  .gov .gtitle{font-size:calc(12px * var(--fs, 1)); font-weight:800; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); margin-right:4px}
  .chip{display:inline-flex; align-items:center; gap:6px; font-size:calc(12px * var(--fs, 1)); font-weight:700; color:var(--muted);
    background:rgba(255,255,255,.03); border:1px solid var(--line); border-radius:999px; padding:6px 11px; cursor:default; transition:.3s}
/* #6a7b96, not the authored #52617a: this dot carries state (control not yet
   exercised at this step), so WCAG 1.4.11 wants 3:1 against the chip fill.
   #52617a measured 2.22:1; this measures 3.25:1 — the least-light passing value,
   so it still reads as "off" beside the lit chips. */
  .chip i{width:7px;height:7px;border-radius:50%;background:#6a7b96; transition:.3s}
  .chip.on{color:#0A1320; background:var(--amber); border-color:var(--amber)}
  .chip.on i{background:#0A1320}
  .cap{margin-top:14px; min-height:64px; display:flex; gap:14px; align-items:center;
    background:linear-gradient(180deg,var(--panel),rgba(22,38,63,.5)); border:1px solid var(--line); border-radius:13px; padding:13px 16px}
  .cap .num{font-size:calc(12px * var(--fs, 1));font-weight:800;color:var(--blue2); white-space:nowrap}
  .cap .txt{font-size:calc(clamp(14px,1.7vw,18px) * var(--fs, 1)); font-weight:600; line-height:1.3}
  .cap .txt b{color:var(--blue2)}
  .controls{display:flex; align-items:center; gap:12px; margin-top:12px; flex-wrap:wrap}
  .btn{background:var(--panel); border:1px solid var(--line); color:var(--ink); width:42px;height:42px;border-radius:11px; cursor:pointer; font-size:calc(15px * var(--fs, 1)); display:grid; place-items:center; transition:.2s}
  .btn:hover{border-color:var(--blue); color:var(--blue2)}
  .btn.play{background:var(--blue-fill); border-color:var(--blue-fill); color:#fff; width:48px;height:48px}
  .timeline{flex:1; min-width:220px; height:34px; position:relative; display:flex; align-items:center}
  .track{position:absolute; left:0; right:0; height:6px; background:var(--line); border-radius:999px; top:50%; transform:translateY(-50%)}
  .fill{position:absolute; left:0; height:6px; background:linear-gradient(90deg,var(--blue),var(--blue2)); border-radius:999px; top:50%; transform:translateY(-50%); width:0%}
  .ticks{position:absolute; inset:0; display:flex; justify-content:space-between}
  .tick{width:13px;height:13px;border-radius:50%; background:var(--bg1); border:2px solid var(--line); cursor:pointer; align-self:center; transition:.2s; z-index:2}
  .tick.done{border-color:var(--blue)} .tick.cur{border-color:var(--blue2); background:var(--blue2); box-shadow:0 0 10px var(--blue2)}
  .speed{background:var(--panel); border:1px solid var(--line); color:var(--muted); border-radius:9px; padding:8px 10px; font-weight:700; font-size:calc(12.5px * var(--fs, 1)); cursor:pointer}
  .foot{display:flex; justify-content:space-between; gap:12px; flex-wrap:wrap; margin-top:16px; color:var(--muted); font-size:calc(12.5px * var(--fs, 1))}
  .foot .stack{font-family:"JetBrains Mono",ui-monospace,Menlo,Consolas,monospace; font-size:calc(12px * var(--fs, 1))}
  .legend{display:flex;gap:14px;flex-wrap:wrap;margin-top:10px;font-size:calc(12px * var(--fs, 1));color:var(--muted)}
  .legend span{display:inline-flex;align-items:center;gap:6px}
  .legend i{width:9px;height:9px;border-radius:3px;display:inline-block}
  .drawer{position:fixed; top:0; right:0; height:100%; width:min(380px,86vw); background:var(--bg1);
    border-left:1px solid var(--line); box-shadow:-20px 0 50px rgba(0,0,0,.45); transform:translateX(102%);
/* visibility (not just the off-screen transform) so the closed drawer leaves
   the tab order and the a11y tree; the 0s-delayed toggle preserves the slide. */
    transition:transform .35s cubic-bezier(.2,.8,.2,1), visibility 0s linear .35s;
    visibility:hidden; z-index:30; padding:24px; overflow-y:auto}
  .drawer.open{transform:translateX(0); visibility:visible;
    transition:transform .35s cubic-bezier(.2,.8,.2,1), visibility 0s}
  .drawer .x{position:absolute; top:16px; right:16px; cursor:pointer; color:var(--muted); font-size:calc(20px * var(--fs, 1)); background:none;border:0}
  .drawer .dtag{display:inline-block; font-size:calc(12px * var(--fs, 1));font-weight:800;text-transform:uppercase;letter-spacing:.08em; color:#0A1320; padding:4px 10px; border-radius:999px; margin-bottom:12px}
  .drawer h3{margin:0 0 8px; font-size:calc(22px * var(--fs, 1)); letter-spacing:-.02em}
  .drawer p{color:var(--muted); line-height:1.55; font-size:calc(14.5px * var(--fs, 1))}
  .backdrop{position:fixed; inset:0; background:rgba(5,10,18,.5); opacity:0; pointer-events:none; transition:.3s; z-index:29}
  .backdrop.open{opacity:1; pointer-events:auto}
  .hint{font-size:calc(12px * var(--fs, 1));color:var(--faint)}
  .caps{margin-top:24px}
  .caps h2{font-size:calc(clamp(15px,2vw,21px) * var(--fs, 1));margin:0;font-weight:800;letter-spacing:-.01em}
  .caps h2 .b{color:var(--blue2)}
  .caps .sub{color:var(--muted);font-size:calc(12.5px * var(--fs, 1));margin:3px 0 0}
  .targets{display:flex;gap:8px;flex-wrap:wrap;margin:12px 0 2px}
  .targets .t{font-size:calc(12px * var(--fs, 1));font-weight:700;color:var(--muted);background:rgba(255,255,255,.03);border:1px solid var(--line);border-radius:8px;padding:5px 10px}
  .targets .t b{color:var(--ink)}
  .capgroup{margin-top:16px}
  .capgroup h3{font-size:calc(12px * var(--fs, 1));font-weight:800;letter-spacing:.09em;text-transform:uppercase;color:var(--muted);margin:0 0 9px;display:flex;align-items:center;gap:9px}
  .capgroup h3 .bar{width:22px;height:4px;border-radius:3px;background:var(--accent,#3B82F6)}
  .capgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(236px, 100%),1fr));gap:10px}
  .capcard{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:12px 13px;cursor:pointer; transition:transform .18s,box-shadow .18s,border-color .18s,background .18s;border-left:3px solid var(--accent,#3B82F6)}
  .capcard:hover{border-color:var(--accent,#3B82F6);transform:translateY(-2px);box-shadow:0 10px 24px rgba(0,0,0,.3)}
  .capcard.sel{background:var(--panel2);box-shadow:0 0 0 1px var(--accent,#3B82F6),0 10px 24px rgba(0,0,0,.35)}
  .capcard h4{margin:0 0 4px;font-size:calc(13.5px * var(--fs, 1));font-weight:800;letter-spacing:-.01em;color:var(--ink)}
  .capcard p{margin:0;font-size:calc(12px * var(--fs, 1));line-height:1.42;color:var(--muted)}
  .capcard .maps{margin-top:8px;font-size:calc(12px * var(--fs, 1));font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:var(--accent,#60A5FA)}
  @media (max-width:640px){ .toolbar{width:100%; justify-content:space-between} }

  .drawer .lead{color:var(--muted); line-height:1.55; font-size:calc(14.5px * var(--fs, 1)); margin:0 0 4px}
  .drawer h5{margin:15px 0 5px; font-size:calc(12px * var(--fs, 1)); font-weight:800; letter-spacing:.07em; text-transform:uppercase; color:var(--blue2)}
  .drawer ul{margin:0; padding-left:18px}
  .drawer li{color:var(--muted); line-height:1.5; font-size:calc(13.5px * var(--fs, 1)); margin-bottom:5px}
  .drawer .ex{margin:12px 0 2px; background:rgba(246,196,83,.08); border:1px solid rgba(246,196,83,.32); border-radius:10px; padding:10px 13px}
  .drawer .ex h5{margin:0 0 4px; color:var(--amber)}
  .drawer .ex p{margin:0; color:#EBDDB4; font-size:calc(13.6px * var(--fs, 1)); line-height:1.5}
  .drawer .fin{margin:10px 0 2px; background:rgba(52,199,199,.07); border:1px solid rgba(52,199,199,.30); border-radius:10px; padding:10px 13px}
  .drawer .fin h5{margin:0 0 4px; color:#34D399}
  .drawer .fin p{margin:0; color:#BFE9D6; font-size:calc(13.6px * var(--fs, 1)); line-height:1.5}
  .drawer .fb{margin:10px 0 2px; background:rgba(244,114,182,.07); border:1px solid rgba(244,114,182,.30); border-radius:10px; padding:10px 13px}
  .drawer .fb h5{margin:0 0 4px; color:var(--rose)}
  .drawer .fb p{margin:0; color:#F2CCE0; font-size:calc(13.6px * var(--fs, 1)); line-height:1.5}
  .drawer li code{font-family:"JetBrains Mono",ui-monospace,Menlo,Consolas,monospace; font-size:calc(12px * var(--fs, 1)); color:var(--ink); background:rgba(255,255,255,.05); padding:1px 5px; border-radius:5px}

/* ---- per-page deltas ------------------------------------------------------ */
  .ra-erp .drawer, .ra-hq .drawer{width:min(440px,90vw); padding:24px 26px 40px}
  .ra-edu .zone, .ra-teacher .zone{background:rgba(255,255,255,.025)}
  .ra-edu .mission, .ra-teacher .mission{max-width:780px}

/* ---- utilities replacing the former inline style="" attributes ------------ */
  .legend i.c-slate{background:#7E93B0}
  .legend i.c-blue {background:#3B82F6}
  .legend i.c-blue2{background:#60A5FA}
  .legend i.c-teal {background:#22C7C7}
  .legend i.c-mint {background:#34D399}
  .legend i.c-amber{background:#F6C453}
  .legend i.c-rose {background:#F472B6}
  .foot b.ink{color:var(--ink)}
  .hint.mt-6{margin-top:6px}
  .caps .sub.mt-3{margin-top:3px}

/* ---- site chrome integration ---------------------------------------------- */
/* Scope guard: the shared style.css also defines .timeline, .pulse and .track —
   keep this page's canvas controls and SVG pulses unaffected. */
  .ra .timeline{padding-left:0}
  .ra .timeline::before{content:none}
  circle.pulse{width:auto; height:auto; border-radius:0; background:none; box-shadow:none; animation:none}
/* The site nav is fixed at z-index 50 — let the modal drawer sit above it. */
  .drawer{z-index:60}
  .backdrop{z-index:55}
/* Clear the fixed site header. */
  .ra .wrap{padding-top:88px}
  @media (max-width:640px){ .ra .wrap{padding-top:78px} }
/* Breadcrumb (article.css is not loaded on these pages). */
  .ra-crumb{font-size:calc(12.5px * var(--fs, 1)); color:var(--faint); letter-spacing:.01em; margin:0 0 14px}
  .ra-crumb a{color:var(--teal); text-decoration:none}
  .ra-crumb a:hover{text-decoration:underline}
  .ra-crumb span{margin:0 6px}
/* Downloads row under the canvas. */
  .ra-downloads{display:flex; flex-wrap:wrap; gap:10px; margin-top:18px}

  .ra-downloads a{display:inline-flex; align-items:center; gap:7px; font-size:calc(12.5px * var(--fs, 1)); font-weight:700;
    color:var(--ink); text-decoration:none; background:var(--panel); border:1px solid var(--line);
    border-radius:10px; padding:8px 13px; transition:border-color .2s, background .2s, transform .2s}
  .ra-downloads a:hover{border-color:var(--blue); background:var(--panel2); transform:translateY(-1px)}
  .ra-downloads a .k{color:var(--faint); font-weight:700; font-size:calc(12px * var(--fs, 1)); text-transform:uppercase; letter-spacing:.07em}

/* ---- light theme ----------------------------------------------------------
   The site's theme toggle flips `html[data-scheme="light"]`, which repaints the
   page background and the shared chrome. These builds were authored dark-only,
   so without this block the page goes light while every panel and label stays
   light-on-dark — i.e. unreadable.

   The approach: remap this file's own custom properties for the PAGE-LEVEL
   chrome (title, legend, controls, caption, downloads), and deliberately keep
   the diagram canvas and the detail drawer DARK in both themes. They are
   figures, not chrome — a dark figure on a light page reads the way a code
   block or a screenshot does, and it means every hand-tuned accent, glow and
   pastel inside them keeps the contrast it was designed for. */

  html[data-scheme="light"] .ra{
    --bg0:#e2eaf2; --bg1:#f5f8fb; --panel:#ffffff; --panel2:#eef3f8;
    --line:#cdd9e6; --ink:#0a1929; --muted:#3e5870; --faint:#50697f;
    --blue:#2563eb; --blue2:#1d4ed8; --teal:#0a6675; --mint:#0f7a55;
    --amber:#8a5800; --slate:#4b5f77; --rose:#b02a6b;
/* The light --blue is already dark enough to carry white text: 5.17:1, and the
   same 5.17:1 against the white --panel behind the control. No separate fill
   value is needed here — but the token must still exist, or the controls would
   inherit the dark theme's #3370D4 on a light page. */
    --blue-fill:#2563eb;
    --glow:0 0 0 1px rgba(10,25,41,.05), 0 12px 30px rgba(10,25,41,.10);
  }
/* Hardcoded (non-variable) colours that assume a dark backdrop. */
/* :not(.on) matters — these selectors outrank the plain `.chip.on` rule above,
   so without it the lit-up governance chips would lose their amber fill. */
  html[data-scheme="light"] .ra .chip:not(.on){background:rgba(10,25,41,.035)}
/* #7a8ca2 rather than a lighter grey: the dot carries state (control not yet
   exercised at this step), so it needs WCAG 1.4.11's 3:1 against the chip fill.
   It measures 3.21:1 composited over the panel; #8496ab measured 2.82:1. */
  html[data-scheme="light"] .ra .chip:not(.on) i{background:#7a8ca2}
  html[data-scheme="light"] .ra .chip.on{color:#fff}
  html[data-scheme="light"] .ra .chip.on i{background:#fff}
  html[data-scheme="light"] .ra .targets .t{background:rgba(10,25,41,.035)}
  html[data-scheme="light"] .ra .cap{background:linear-gradient(180deg,var(--panel),var(--panel2))}
  html[data-scheme="light"] .ra .capcard:hover{box-shadow:0 10px 24px rgba(10,25,41,.12)}
  html[data-scheme="light"] .ra .capcard.sel{box-shadow:0 0 0 1px var(--accent,#2563eb),0 10px 24px rgba(10,25,41,.14)}

/* The canvas and the drawer stay dark — restore the authored palette inside
   them so nodes, edges, zone labels, pulses and the drawer's pastel callouts
   keep their intended contrast. */
  html[data-scheme="light"] .ra .stage,
  html[data-scheme="light"] .ra .drawer{
    --bg0:#0A1320; --bg1:#0E1A2B; --panel:#16263F; --panel2:#1B2E4A;
    --line:#2A3D5C; --ink:#EAF1FA; --muted:#9DB0C7; --faint:#8093AA;
    --blue:#3B82F6; --blue2:#60A5FA; --teal:#22C7C7; --mint:#34D399;
    --amber:#F6C453; --slate:#7E93B0; --rose:#F472B6;
    --blue-fill:#3370D4;
    --glow:0 0 0 1px rgba(255,255,255,.04), 0 10px 30px rgba(0,0,0,.35);
/* `color` is set once on <body> and inherits, so re-declaring --ink here is not
   enough on its own — node labels and drawer headings would inherit the light
   theme's dark ink and disappear against these dark surfaces. */
    color:var(--ink);
  }
/* Opaque, so the canvas no longer composites its alpha over a light page. */
  html[data-scheme="light"] .ra .stage{background:linear-gradient(180deg,#1b2e4a,#0e1a2b)}
