/* DOAR Framework — design system */
:root{
  --bg:#0a0e14; --surface:#111823; --surface-2:#161f2c; --border:#202b3a;
  --text:#e6edf3; --muted:#8b98a8; --dim:#5d6b7d; --nav-bg:rgba(10,14,20,.88);
  --accent:#3b82f6; --accent-dim:#1d4ed8;
  --f1:#64748b; --f2:#0ea5e9; --f3:#6366f1; --f4:#a855f7; --f5:#ec4899;
  --t0:#6b7280; --t1:#3b82f6; --t2:#f59e0b; --t3:#f97316; --t4:#ef4444;
  --strong:#22c55e; --moderate:#eab308; --weak:#f97316; --flawed:#ef4444;
  --radius:10px; --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,monospace;
  --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,sans-serif;
  --maxw:1180px;
}
:root[data-theme="light"]{
  --bg:#f8fafc; --surface:#ffffff; --surface-2:#f1f5f9; --border:#e2e8f0;
  --text:#0f172a; --muted:#51607a; --dim:#8493a8; --nav-bg:rgba(248,250,252,.88);
  --accent:#2563eb; --accent-dim:#1d4ed8;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--bg);color:var(--text);font-family:var(--sans);
     font-size:15.5px;line-height:1.65;-webkit-font-smoothing:antialiased;
     transition:background-color .15s ease,color .15s ease;
     min-height:100vh;display:flex;flex-direction:column}
/* content grows to fill short pages, so the footer always sits at the bottom of the screen */
main.page{flex:1 0 auto;min-width:0}
a{color:var(--accent);text-decoration:none}
a:hover{text-decoration:underline}
code{font-family:var(--mono);font-size:.88em;background:var(--surface-2);
     padding:.12em .4em;border-radius:4px;border:1px solid var(--border);overflow-wrap:anywhere}
pre{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
    padding:16px;overflow-x:auto;font-size:13px}
pre code{background:none;border:none;padding:0}
h1,h2,h3,h4{line-height:1.25;font-weight:650;letter-spacing:-.015em}
h1{font-size:2.1rem;margin:0 0 .5rem}
h2{font-size:1.45rem;margin:2.4rem 0 .8rem}
h3{font-size:1.12rem;margin:1.8rem 0 .5rem}
hr{border:none;border-top:1px solid var(--border);margin:2.5rem 0}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px}
.narrow{max-width:800px}
/* nav */
.nav{position:sticky;top:0;z-index:50;background:var(--nav-bg);
     backdrop-filter:blur(12px);border-bottom:1px solid var(--border)}
.nav-in{display:flex;align-items:center;gap:8px;height:58px;max-width:var(--maxw);
        margin:0 auto;padding:0 24px}
/* the wordmark uses Archivo (self-hosted, OFL) — the homepage intro lands on this exact shape */
@font-face{font-family:"Archivo";font-style:normal;font-weight:700 900;font-stretch:100% 125%;font-display:swap;
  src:url("fonts/archivo-latin.woff2") format("woff2")}
.brand{font-family:"Archivo",var(--sans);font-weight:850;font-stretch:118%;letter-spacing:.02em;color:var(--text);
  font-size:1.02rem;line-height:1;margin-right:14px}
.brand span{color:var(--accent)}
/* two-word labels must never break mid-phrase — "Deception Techniques" wrapping to two lines
   reads as if the item had changed to "Deception" */
.nav a.nl{color:var(--muted);padding:6px 11px;border-radius:7px;font-size:.9rem;font-weight:500;
  white-space:nowrap}
.nav a.nl:hover{color:var(--text);background:var(--surface-2);text-decoration:none}
.nav a.nl.on{color:var(--text);background:var(--surface-2)}
.nav .spacer{flex:1}
.nav-links{display:contents}
.nav .nav-toggle{display:none;font-size:1rem}
@media(max-width:900px){
  .nav-in{padding:0 16px}
  .brand{margin-right:auto}
  .nav .nav-toggle{display:inline-flex}
  .nav-links{display:none;position:absolute;top:100%;left:0;right:0;flex-direction:column;gap:2px;
    padding:8px 16px 14px;background:var(--bg);border-bottom:1px solid var(--border)}
  .nav.open .nav-links{display:flex}
  .nav-links .spacer{display:none}
  .nav a.nl{padding:10px 11px;font-size:1rem}
}
/* deception page: list + fidelity rail; the rail drops below the list on narrow screens */
.dec-grid{display:grid;grid-template-columns:1fr 310px;gap:36px;align-items:start;margin-top:32px}
.dec-grid #rail{position:sticky;top:78px}
@media(max-width:860px){.dec-grid{grid-template-columns:1fr}.dec-grid #rail{position:static}}
.theme-btn{appearance:none;-webkit-appearance:none;background-color:transparent;
  border:1px solid var(--border);border-radius:7px;color:var(--muted);
  width:32px;height:32px;display:inline-flex;align-items:center;justify-content:center;
  cursor:pointer;margin-left:10px;font-size:1rem;line-height:1}
.theme-btn:hover{color:var(--text);border-color:var(--accent)}
.theme-btn .i-sun{display:none}.theme-btn .i-moon{display:inline}
:root[data-theme="light"] .theme-btn .i-sun{display:inline}
:root[data-theme="light"] .theme-btn .i-moon{display:none}
/* hero + cards */
.hero{padding:64px 0 40px;border-bottom:1px solid var(--border)}
.hero p.lead{font-size:1.12rem;color:var(--muted);max-width:660px;margin:.8rem 0 0}
.kicker{font-family:var(--mono);font-size:.74rem;letter-spacing:.14em;text-transform:uppercase;
        color:var(--dim);margin-bottom:.9rem}
.grid{display:grid;gap:16px}
.g2{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.g4{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:20px}
a.card{display:block;color:inherit;transition:border-color .15s,transform .15s}
a.card:hover{border-color:var(--accent);text-decoration:none;transform:translateY(-1px)}
.card h3{margin:0 0 .35rem;font-size:1.05rem}
.card p{margin:0;color:var(--muted);font-size:.9rem}
.pillar-n{font-family:var(--mono);font-size:.72rem;color:var(--accent);letter-spacing:.1em}
/* stats */
.stat{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:18px}
.stat .n{font-size:1.9rem;font-weight:700;letter-spacing:-.03em;font-variant-numeric:tabular-nums}
.stat .l{font-size:.8rem;color:var(--muted);margin-top:2px}
.stat .s{font-size:.74rem;color:var(--dim);margin-top:6px;font-family:var(--mono)}
/* badges */
.b{display:inline-flex;align-items:center;gap:5px;font-family:var(--mono);font-size:.7rem;
   font-weight:600;padding:2px 7px;border-radius:5px;border:1px solid;letter-spacing:.03em;
   white-space:nowrap;vertical-align:middle}
.bF1{color:var(--f1);border-color:var(--f1)}.bF2{color:var(--f2);border-color:var(--f2)}
.bF3{color:var(--f3);border-color:var(--f3)}.bF4{color:var(--f4);border-color:var(--f4)}
.bF5{color:var(--f5);border-color:var(--f5)}
.bT0{color:var(--t0);border-color:var(--t0)}.bT1{color:var(--t1);border-color:var(--t1)}
.bT2{color:var(--t2);border-color:var(--t2)}.bT3{color:var(--t3);border-color:var(--t3)}
.bT4{color:var(--t4);border-color:var(--t4)}
.b-strong{color:var(--strong);border-color:var(--strong)}
.b-moderate{color:var(--moderate);border-color:var(--moderate)}
.b-weak{color:var(--weak);border-color:var(--weak)}
.b-flawed{color:var(--flawed);border-color:var(--flawed)}
.b-plain{color:var(--muted);border-color:var(--border);background:var(--surface-2)}
.b-confirmed{color:var(--strong);border-color:var(--strong)}
.b-theoretical{color:var(--moderate);border-color:var(--moderate)}
/* warning */
.warn{border:1px solid var(--t4);background:rgba(239,68,68,.07);border-radius:var(--radius);
      padding:14px 16px;margin:18px 0}
.warn strong{color:var(--t4);display:block;margin-bottom:4px;font-size:.88rem}
.warn p{margin:0;font-size:.88rem;color:var(--muted)}
.note{border-left:3px solid var(--border);padding:2px 0 2px 14px;color:var(--muted);font-size:.9rem;margin:14px 0}
/* tables */
table{width:100%;border-collapse:collapse;font-size:.88rem;margin:1.2rem 0}
th,td{text-align:left;padding:9px 12px;border-bottom:1px solid var(--border);vertical-align:top}
th{color:var(--muted);font-weight:600;font-size:.76rem;text-transform:uppercase;letter-spacing:.06em}
tbody tr:hover{background:var(--surface)}
/* footer */
footer{border-top:1px solid var(--border);margin-top:72px;padding:28px 0 48px;
       color:var(--dim);font-size:.85rem}
.muted{color:var(--muted)}.dim{color:var(--dim)}.mono{font-family:var(--mono)}
.small{font-size:.85rem}.tiny{font-size:.78rem}
.row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.mt0{margin-top:0}.mb0{margin-bottom:0}
/* category accordion */
.cat-block{border-bottom:1px solid var(--border)}
.cat-block:first-child{border-top:1px solid var(--border)}
.cat-head{display:flex;align-items:center;gap:10px;width:100%;appearance:none;-webkit-appearance:none;
  background-color:transparent;border:none;font-size:1em;
  cursor:pointer;padding:16px 4px;text-align:left;color:var(--text);font-family:var(--sans)}
.cat-head:hover{background:var(--surface-2)}
.cat-head h2{margin:0;font-size:1.15rem;flex:1}
.cat-chevron{display:inline-block;color:var(--dim);font-size:.8rem;transition:transform .15s;width:.8em}
.cat-block[data-open="true"] .cat-chevron{transform:rotate(90deg)}
.cat-body{padding:4px 4px 24px}
/* alerting+response preview: sidebar nav + content pane */
.ar{display:grid;grid-template-columns:250px minmax(0,1fr);gap:40px;align-items:start;margin-top:30px}
.ar-nav{position:sticky;top:78px;display:flex;flex-direction:column;gap:1px;
  max-height:calc(100vh - 96px);overflow-y:auto;padding-right:6px}
.ar-nav a{display:flex;align-items:center;gap:8px;padding:6px 10px;border-radius:0 7px 7px 0;
  border-left:2px solid transparent;color:var(--muted);font-size:.88rem;line-height:1.35}
.ar-nav a:hover{color:var(--text);background:var(--surface-2);text-decoration:none}
.ar-nav a.sub{padding-left:24px;font-size:.84rem}
.ar-nav a[aria-current]{color:var(--text);background:var(--surface-2);border-left-color:var(--accent)}
/* pillar headings in the sidebar: clickable, open the pillar's overview */
.ar-nav a.ar-group{justify-content:space-between;align-items:baseline;margin:18px 0 4px;
  font-size:.95rem;font-weight:700;letter-spacing:-.005em;color:var(--text)}
.ar-nav a.ar-group:first-child{margin-top:0}
.ar-nav a.ar-group span{font-family:var(--mono);font-size:.7rem;font-weight:400;color:var(--dim);letter-spacing:.06em}
.ar-nav a.ar-group.in-group{color:var(--accent)}
/* platform switcher at the top of each real-time platform section */
.rt-pick{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 18px}
.rt-pick a{padding:4px 10px;border:1px solid var(--border);border-radius:999px;font-size:.8rem;color:var(--muted)}
.rt-pick a:hover{color:var(--text);background:var(--surface-2);text-decoration:none}
.rt-pick a[aria-current]{color:var(--text);border-color:var(--accent);background:var(--surface-2)}
/* pillar overview video (or a placeholder until one is added) */
.ar-video{margin:16px 0 4px;max-width:760px;aspect-ratio:16/9;border:1px solid var(--border);
  border-radius:var(--radius);overflow:hidden;background:var(--surface)}
.ar-video video{display:block;width:100%;height:100%;object-fit:contain;background:var(--surface-2)}
.ar-sec{scroll-margin-top:76px}
.ar-sec>h2:first-child{margin-top:0}
.ar-sec h3{font-size:1rem;margin:1.3rem 0 .3rem}
.ar-foot{display:flex;justify-content:space-between;gap:12px;margin-top:34px;padding-top:14px;
  border-top:1px solid var(--border);font-size:.88rem}
.ar-foot a:only-child{margin-left:auto}
.tmatrix{margin:0}
.tmatrix th,.tmatrix td{padding:7px 8px}
.tmatrix tbody tr:hover{background:transparent}
a.tcell{display:inline-block;padding:4px 7px;border:1px solid transparent;border-radius:7px;line-height:1;
  transition:border-color .12s,background-color .12s}
a.tcell:hover{border-color:var(--border);background:var(--surface-2);text-decoration:none}
.ar-head{padding-top:36px}
/* desktop: an app layout. The page itself never scrolls — the title block and sidebar are
   fixed, and only the content column scrolls. The footer lives at the end of that column, so it
   can never push the sidebar out of place. The page script forwards the mouse wheel from
   anywhere on the page to the content column. */
@media(min-width:861px){
  .ar-shell{height:calc(100vh - 59px);display:flex;flex-direction:column}
  .ar-head{flex:none;padding:24px 0 16px;border-bottom:1px solid var(--border)}
  .ar-shell .ar{flex:1;min-height:0;margin-top:0;align-items:stretch;grid-template-rows:minmax(0,1fr)}
  .ar-shell .ar-nav{position:static;max-height:none;min-height:0;overflow:hidden;padding:22px 0 0}
  .ar-shell .ar-nav a{padding-top:5px;padding-bottom:5px}
  .ar-shell .ar-nav a.ar-group{margin:14px 0 2px}
  .ar-shell .ar-nav a.ar-group:first-child{margin-top:0}
  .ar-pane{min-height:0;overflow-y:auto;padding:22px 12px 32px 0}
  .ar-pane:focus{outline:none}
}
/* very short windows: tighten the title block's padding so the sidebar still fits — never hide text */
@media(min-width:861px) and (max-height:800px){
  .ar-head{padding:14px 0 10px}
  .ar-shell .ar-nav a{padding-top:4px;padding-bottom:4px}
  .ar-shell .ar-nav a.ar-group{margin:10px 0 2px}
}
@media(max-width:860px){
  .ar{grid-template-columns:1fr;gap:22px}
  .ar-nav{position:static;max-height:none;flex-direction:row;flex-wrap:wrap;gap:6px;padding:0}
  .ar-nav a,.ar-nav a.sub{border:1px solid var(--border);border-radius:7px;padding:5px 9px}
  .ar-nav a[aria-current]{border-color:var(--accent)}
  .ar-nav a.ar-group{width:100%;margin:10px 0 2px;padding:2px 0;border:0;background:none}
}
ul.clean{list-style:none;padding:0;margin:0}
ul.tight li{margin:.3rem 0}
@media print{.nav,footer{display:none}body{background:#fff;color:#000}}
/* ---- pillar explainer animations (drawn, no video file) ---- */
.ar-anim{margin:16px 0 4px;max-width:760px}
.ar-anim svg{display:block;width:100%;aspect-ratio:16/9;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--radius)}
.ar-anim text{font-family:var(--mono);font-size:11px;fill:var(--muted)}
.ar-anim .sc,.ar-anim .stage>g,.ar-anim .scale{opacity:0}
.ar-anim .sc.on,.ar-anim .stage>g.on,.ar-anim .scale.on{opacity:1}
.ar-anim .sc,.ar-anim .stage>g,.ar-anim .scale,.ar-anim .node rect,.ar-anim .node .ic,
.ar-anim .rung rect,.ar-anim .rung text,.ar-anim .boundary{transition:opacity .45s ease,fill .5s ease,stroke .5s ease}
.ar-anim-cap{margin:10px 2px 0;min-height:2.6em;font-size:.9rem;color:var(--muted)}
.ar-anim-ctl{display:flex;align-items:center;gap:10px;margin-top:6px}
.ar-anim-play{appearance:none;-webkit-appearance:none;background:transparent;cursor:pointer;
  border:1px solid var(--border);border-radius:7px;color:var(--muted);width:26px;height:26px;
  font-size:.62rem;line-height:1;display:flex;align-items:center;justify-content:center}
.ar-anim-play:hover{color:var(--text);border-color:var(--accent)}
.ar-anim-dots{display:flex;gap:6px}
.ar-anim-dots button{appearance:none;-webkit-appearance:none;cursor:pointer;padding:0;
  width:7px;height:7px;border-radius:50%;border:1px solid var(--dim);background:transparent}
.ar-anim-dots button[aria-selected="true"]{background:var(--accent);border-color:var(--accent)}
.ar-anim-note{margin-left:auto}

/* shared by both animations: the world, its people and their hardware */
.ar-anim .divider{stroke:var(--border);stroke-width:1;stroke-dasharray:4 6}
.ar-anim .figure .head,.ar-anim .figure .body{fill:none;stroke:var(--muted);stroke-width:1.8}
.ar-anim .laptop .screen,.ar-anim .laptop .base{fill:var(--surface-2);stroke:var(--border);stroke-width:1.5}
.ar-anim .pnode rect{fill:var(--surface-2);stroke:var(--t1);stroke-width:1.5}
.ar-anim .pnode .ic{fill:none;stroke:var(--t1);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.ar-anim .wire{fill:none;stroke-width:1.5;stroke-dasharray:3 5;opacity:0}
.ar-anim .term .tl{fill:var(--strong);opacity:.42}
.ar-anim .note rect{fill:var(--surface);stroke:var(--strong);stroke-width:1.4}
.ar-anim .note .dot{fill:var(--strong)}
.ar-anim .note .ln{fill:var(--muted);opacity:.65}
.ar-anim .lbl{font-size:10px;fill:var(--dim);text-anchor:middle}

/* alerting — six-scene story: build the estate, hide the decoys, trip one, follow the alert */
.ar-anim .hd tspan{font-size:13px;font-weight:700;fill:var(--text);opacity:0;letter-spacing:.01em}
.ar-anim[data-scene="1"] .hd .h1,.ar-anim[data-scene="2"] .hd .h2,.ar-anim[data-scene="3"] .hd .h3,
.ar-anim[data-scene="4"] .hd .h4,.ar-anim[data-scene="5"] .hd .h5,.ar-anim[data-scene="6"] .hd .h6{opacity:1}

/* the estate: blue is real, red is a decoy — but only while the defender is looking */
.ar-anim .node rect,.ar-anim .pnode rect{fill:var(--surface-2);stroke:var(--t1);stroke-width:1.5}
.ar-anim .node .ic,.ar-anim .pnode .ic{fill:none;stroke:var(--t1);stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round}
.ar-anim[data-scene="2"] .node.decoy rect{stroke:var(--t4);fill:var(--t4);fill-opacity:.1}
.ar-anim[data-scene="2"] .node.decoy .ic{stroke:var(--t4)}
.ar-anim .node{opacity:0}
.ar-anim[data-scene="1"] .node.real{animation:al-in .5s ease-out forwards var(--d)}
.ar-anim[data-scene="2"] .node.real,.ar-anim[data-scene="3"] .node,
.ar-anim[data-scene="2"] .node.decoy{opacity:1}
.ar-anim[data-scene="2"] .node.decoy{animation:al-drop .55s cubic-bezier(.3,1.5,.5,1) backwards var(--d)}
.ar-anim[data-scene="1"] .node.decoy{opacity:0;animation:none}
@keyframes al-in{from{opacity:0;transform:scale(.88)}to{opacity:1;transform:scale(1)}}
@keyframes al-drop{from{opacity:0;transform:translateY(-26px) scale(.9)}to{opacity:1;transform:none}}
.ar-anim .node{transform-box:fill-box;transform-origin:center}

/* scene 3: a sweep passes and the decoys stop looking like decoys */
.ar-anim .sweep rect{fill:var(--t1);fill-opacity:.12}
.ar-anim .sweep{opacity:0}
.ar-anim[data-scene="3"] .sweep{opacity:1;animation:al-sweep 1.7s ease-in-out forwards}
@keyframes al-sweep{from{transform:translateX(0)}to{transform:translateX(790px)}}

/* scenes 4-5 share one 1280-wide world; scene 5 pans the camera right */
.ar-anim .world{transition:transform 1.1s cubic-bezier(.65,0,.35,1)}
.ar-anim[data-scene="5"] .world{transform:translateX(-640px)}
/* the attacker's terminal: dim, small, scrolling — deliberately unlike the alert */
.ar-anim .term .tl{fill:var(--strong);opacity:.42;animation:al-type 2.6s steps(1) infinite var(--d)}
@keyframes al-type{0%,45%{opacity:0}50%,100%{opacity:.42}}
.ar-anim[data-scene="5"] .term .tl{opacity:.16;animation:none}

/* the probe: three real resources answer, the fourth gives itself away */
.ar-anim .probe{fill:none;stroke:var(--strong);stroke-width:1.6;opacity:.5;
  stroke-dasharray:300;stroke-dashoffset:300}
.ar-anim .probe.hit{stroke-width:2.2;opacity:.9}
.ar-anim[data-scene="4"] .p1{animation:al-reach .7s ease-out forwards .2s}
.ar-anim[data-scene="4"] .p2{animation:al-reach .7s ease-out forwards 1.1s}
.ar-anim[data-scene="4"] .p3{animation:al-reach .7s ease-out forwards 2.0s}
.ar-anim[data-scene="4"] .p4{animation:al-reach .7s ease-out forwards 2.9s}
.ar-anim[data-scene="5"] .probe{stroke-dashoffset:0;opacity:.28}
.ar-anim[data-scene="5"] .p4{opacity:.6}
@keyframes al-reach{from{stroke-dashoffset:300}to{stroke-dashoffset:0}}
.ar-anim .pnode rect{transition:stroke .25s ease,fill .25s ease}
.ar-anim[data-scene="4"] .n0 rect{animation:al-tap 1s ease-out .7s}
.ar-anim[data-scene="4"] .n5 rect{animation:al-tap 1s ease-out 1.6s}
.ar-anim[data-scene="4"] .n6 rect{animation:al-tap 1s ease-out 2.5s}
@keyframes al-tap{0%,100%{fill:var(--surface-2)}40%{fill:var(--t1);fill-opacity:.28}}
/* the decoy snaps red the moment it is touched, and stays red */
.ar-anim[data-anim="alerting"][data-scene="4"] .pnode.trap rect{animation:al-trip .5s ease-out forwards 3.5s}
.ar-anim[data-anim="alerting"][data-scene="4"] .pnode.trap .ic{animation:al-trip-ic .5s ease-out forwards 3.5s}
.ar-anim[data-anim="alerting"][data-scene="5"] .pnode.trap rect{stroke:var(--t4);fill:var(--t4);fill-opacity:.14}
.ar-anim[data-anim="alerting"][data-scene="5"] .pnode.trap .ic{stroke:var(--t4)}
@keyframes al-trip{to{stroke:var(--t4);fill:var(--t4);fill-opacity:.14}}
@keyframes al-trip-ic{to{stroke:var(--t4)}}

/* the signal: bright, glowing, travelling a drawn wire — the loud cousin of the terminal green */
.ar-anim .wire{fill:none;stroke:var(--strong);stroke-width:1.5;opacity:0;stroke-dasharray:3 5}
.ar-anim[data-scene="5"] .wire{opacity:.45}
.ar-anim .sig,.ar-anim .sig-glow{opacity:0}
.ar-anim .sig{fill:var(--strong)}
.ar-anim[data-scene="4"] .sig,.ar-anim[data-scene="4"] .sig-glow{animation:al-sig-born 1.1s ease-out forwards 3.5s}
@keyframes al-sig-born{0%{opacity:0;cx:468px;cy:204px}30%{opacity:1}100%{opacity:1;cx:468px;cy:204px}}
.ar-anim[data-scene="5"] .sig,.ar-anim[data-scene="5"] .sig-glow{animation:al-travel 1.5s cubic-bezier(.4,0,.5,1) forwards}
@keyframes al-travel{from{opacity:1;cx:468px;cy:204px}to{opacity:1;cx:902px;cy:204px}}

/* the defender's screen lights up */
.ar-anim .laptop .screen.lit{transition:stroke .4s ease}
.ar-anim[data-scene="5"] .laptop .screen.lit{stroke:var(--strong)}
.ar-anim .note{opacity:0}
.ar-anim .note rect{fill:var(--surface);stroke:var(--strong);stroke-width:1.4}
.ar-anim .note .dot{fill:var(--strong)}
.ar-anim .note .ln{fill:var(--muted);opacity:.65}
.ar-anim[data-scene="5"] .note{animation:al-note .5s ease-out forwards 1.25s}
@keyframes al-note{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
.ar-anim .ping{fill:none;stroke:var(--strong);stroke-width:2;opacity:0}
.ar-anim[data-scene="5"] .ping{animation:al-ping 1.5s ease-out infinite 1.4s}
@keyframes al-ping{from{r:14;opacity:.7}to{r:52;opacity:0}}
.ar-anim .lbl{font-size:10px;fill:var(--dim);text-anchor:middle;opacity:0}
.ar-anim[data-scene="5"] .lbl{animation:al-in .4s ease-out forwards 1.5s}

/* scene 6: severity */
.ar-anim .cell rect{fill:none;stroke:var(--border)}
.ar-anim .cell text{font-weight:700;text-anchor:middle}
.ar-anim .cell.hit rect{stroke:var(--t2);fill:var(--t2);fill-opacity:.14;animation:al-hit 1.6s ease-in-out infinite}
@keyframes al-hit{0%,100%{fill-opacity:.1}50%{fill-opacity:.26}}
.ar-anim .axis text{font-size:10px;fill:var(--dim)}
.ar-anim .tT0{fill:var(--t0)}.ar-anim .tT1{fill:var(--t1)}.ar-anim .tT2{fill:var(--t2)}
.ar-anim .tT3{fill:var(--t3)}.ar-anim .tT4{fill:var(--t4)}

/* response — the sequel: read the alert, pick T4, kill the session, cut the attacker off */
.ar-anim[data-anim="response"][data-scene="1"] .hd .h1,
.ar-anim[data-anim="response"][data-scene="2"] .hd .h2,
.ar-anim[data-anim="response"][data-scene="3"] .hd .h3,
.ar-anim[data-anim="response"][data-scene="4"] .hd .h4,
.ar-anim[data-anim="response"][data-scene="5"] .hd .h5,
.ar-anim[data-anim="response"][data-scene="6"] .hd .h6{opacity:1}

/* the camera: opens on the analyst, pans LEFT back to the attacker — the reverse of Alerting */
.ar-anim[data-anim="response"] .world{transform:translateX(-640px)}
.ar-anim[data-anim="response"][data-scene="5"] .world,
.ar-anim[data-anim="response"][data-scene="6"] .world{transform:translateX(0)}

/* scene 1: the alert is still arriving, exactly as Alerting left it */
.ar-anim[data-anim="response"] .laptop .screen.lit{stroke:var(--strong)}
.ar-anim[data-anim="response"] .note,.ar-anim[data-anim="response"] .lbl{opacity:1}
.ar-anim[data-anim="response"] .ping{fill:none;stroke:var(--strong);stroke-width:2;opacity:0}
.ar-anim[data-anim="response"][data-scene="1"] .ping{animation:al-ping 1.5s ease-out infinite}
.ar-anim[data-anim="response"] .wire{stroke:var(--t2)}
.ar-anim[data-anim="response"][data-scene="5"] .wire{opacity:.45}

/* scenes 2-4: the analyst's monitor, zoomed up out of the laptop and back down into it */
.ar-anim .screen-zoom{opacity:0;transform:scale(.42) translate(560px,330px);
  transform-origin:center;transition:transform .55s cubic-bezier(.3,0,.2,1),opacity .4s ease}
.ar-anim[data-scene="2"] .screen-zoom,.ar-anim[data-scene="3"] .screen-zoom,
.ar-anim[data-scene="4"] .screen-zoom{opacity:1;transform:none}
/* the hardware: two bezel lines, speakers either side, camera and mic on the chin */
.ar-anim .mon-bezel{fill:var(--surface);stroke:var(--border);stroke-width:1.5}
.ar-anim .mon-screen{fill:var(--surface-2);stroke:var(--strong);stroke-width:1.5}
.ar-anim .mon-chin path,.ar-anim .mon-chin circle{fill:none;stroke:var(--dim);stroke-width:1.4;stroke-linecap:round}
.ar-anim .mon-chin .lens{fill:var(--dim);stroke:none}
.ar-anim .mon-chin .mic rect{fill:none;stroke:var(--dim);stroke-width:1.4}
.ar-anim .screen-zoom text{font-family:var(--mono)}
.ar-anim .pl{font-size:8.5px;fill:var(--dim);letter-spacing:.08em;text-transform:uppercase}
.ar-anim .pv{font-size:10px;fill:var(--text)}

/* scene 2: what fired, and the correlation that ties it to one actor */
.ar-anim .panels{opacity:0}
.ar-anim[data-scene="2"] .panels{opacity:1}
.ar-anim .panel rect{fill:var(--surface);stroke:var(--border)}
.ar-anim[data-scene="2"] .panel{animation:re-slide .45s ease-out backwards var(--d)}
@keyframes re-slide{from{opacity:0;transform:translateX(-14px)}to{opacity:1;transform:none}}
.ar-anim .corr circle{fill:var(--t2)}
.ar-anim .corr path{fill:none;stroke:var(--t2);stroke-width:1.5;stroke-dasharray:160;stroke-dashoffset:160}
.ar-anim[data-scene="2"] .corr path{animation:re-link .9s ease-out forwards 1.1s}
@keyframes re-link{to{stroke-dashoffset:0}}
.ar-anim .corr{opacity:0}
.ar-anim[data-scene="2"] .corr{animation:al-in .4s ease-out forwards .9s}

/* scene 3: the selection steps up the tiers and settles on T4 */
.ar-anim[data-anim="response"] .ladder{opacity:0}
.ar-anim[data-scene="3"] .ladder,.ar-anim[data-scene="4"] .ladder{opacity:1}
.ar-anim[data-anim="response"] .rung rect{fill:var(--surface);stroke:var(--border)}
.ar-anim[data-anim="response"] .rung .k{font-size:9.5px;font-weight:700;fill:var(--dim)}
.ar-anim[data-anim="response"] .rung .n{font-size:9px;fill:var(--dim)}
.ar-anim[data-scene="3"] .rung{animation:re-rise .4s ease-out backwards var(--d)}
@keyframes re-rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
/* the selection steps up the boxes themselves — each lights amber in turn, no sliding line */
.ar-anim[data-scene="3"] .r0 rect{animation:re-step .52s ease-out .25s}
.ar-anim[data-scene="3"] .r1 rect{animation:re-step .52s ease-out .67s}
.ar-anim[data-scene="3"] .r2 rect{animation:re-step .52s ease-out 1.09s}
.ar-anim[data-scene="3"] .r3 rect{animation:re-step .52s ease-out 1.51s}
.ar-anim[data-scene="3"] .r0 .k,.ar-anim[data-scene="3"] .r0 .n{animation:re-step-text .52s ease-out .25s}
.ar-anim[data-scene="3"] .r1 .k,.ar-anim[data-scene="3"] .r1 .n{animation:re-step-text .52s ease-out .67s}
.ar-anim[data-scene="3"] .r2 .k,.ar-anim[data-scene="3"] .r2 .n{animation:re-step-text .52s ease-out 1.09s}
.ar-anim[data-scene="3"] .r3 .k,.ar-anim[data-scene="3"] .r3 .n{animation:re-step-text .52s ease-out 1.51s}
@keyframes re-step{0%,100%{stroke:var(--border);fill:var(--surface);fill-opacity:1}
  22%,78%{stroke:var(--t2);fill:var(--t2);fill-opacity:.22}}
@keyframes re-step-text{0%,100%{fill:var(--dim)}22%,78%{fill:var(--t2)}}
/* the selection reaches T4 last: it lights amber like the rest, then settles red and holds */
.ar-anim[data-scene="3"] .r4 rect{animation:re-step-final .95s ease-out forwards 1.93s}
.ar-anim[data-scene="3"] .r4 .k,.ar-anim[data-scene="3"] .r4 .n{animation:re-step-final-text .95s ease-out forwards 1.93s}
@keyframes re-step-final{0%{stroke:var(--border);fill:var(--surface);fill-opacity:1}
  20%,52%{stroke:var(--t2);fill:var(--t2);fill-opacity:.22}
  100%{stroke:var(--t4);fill:var(--t4);fill-opacity:.14}}
@keyframes re-step-final-text{0%{fill:var(--dim)}20%,52%{fill:var(--t2)}100%{fill:var(--t4)}}
/* T4 stays red through the action scene */
.ar-anim[data-anim="response"][data-scene="4"] .r4 rect{stroke:var(--t4);fill:var(--t4);fill-opacity:.14}
.ar-anim[data-anim="response"][data-scene="4"] .r4 .k,
.ar-anim[data-anim="response"][data-scene="4"] .r4 .n{fill:var(--t4)}
/* scene 4: the rejected tiers recede so the choice and the action carry the frame */
.ar-anim[data-anim="response"] .rung{transition:opacity .35s ease}
.ar-anim[data-scene="4"] .r0,.ar-anim[data-scene="4"] .r1,
.ar-anim[data-scene="4"] .r2,.ar-anim[data-scene="4"] .r3{opacity:.3}

/* scene 4: cursor travels to the button and presses it */
.ar-anim .kill{opacity:0}
.ar-anim[data-scene="4"] .kill{opacity:1}
.ar-anim .btn{transform-box:fill-box;transform-origin:center}
.ar-anim .btn rect{fill:var(--t4);fill-opacity:.16;stroke:var(--t4);stroke-width:1.5}
.ar-anim .btn text{font-size:11px;font-weight:700;fill:var(--t4);text-anchor:middle}
.ar-anim[data-scene="4"] .btn{animation:re-press .4s ease-out 1.5s}
@keyframes re-press{0%,100%{transform:none}45%{transform:scale(.95)}}
.ar-anim .cursor{fill:var(--text);stroke:var(--surface);stroke-width:1}
.ar-anim[data-scene="4"] .cursor-wrap{animation:re-point 1.6s cubic-bezier(.3,0,.2,1) forwards}
@keyframes re-point{from{transform:translate(430px,200px)}to{transform:translate(322px,256px)}}

/* the decoy already fired in the Alerting story, so it reads red for the whole of this one */
.ar-anim[data-anim="response"] .pnode.trap rect{stroke:var(--t4);fill:var(--t4);fill-opacity:.12}
.ar-anim[data-anim="response"] .pnode.trap .ic{stroke:var(--t4)}

/* scene 5: the attacker is mid-probe when the order arrives */
.ar-anim .probe-live{fill:none;stroke:var(--strong);stroke-width:2;opacity:0;
  stroke-dasharray:300;stroke-dashoffset:300}
.ar-anim[data-scene="5"] .probe-live{animation:re-live 2.6s ease-out forwards}
@keyframes re-live{0%{opacity:.8;stroke-dashoffset:300}55%{opacity:.8;stroke-dashoffset:0}
  88%{opacity:.8}100%{opacity:0;stroke-dashoffset:0}}

/* the order: amber, travelling right to left under the grid to the attacker's laptop */
.ar-anim .ord,.ar-anim .ord-glow{opacity:0}
.ar-anim .ord{fill:var(--t2)}
.ar-anim .ord-wrap{opacity:0}
.ar-anim[data-scene="5"] .ord,.ar-anim[data-scene="5"] .ord-glow{opacity:1}
.ar-anim[data-scene="5"] .ord-wrap{animation:re-travel 2.2s cubic-bezier(.4,0,.45,1) forwards .15s}
@keyframes re-travel{
  0%  {opacity:0;transform:translate(902px,204px)}
  10% {opacity:1}
  33% {transform:translate(640px,204px)}
  44% {transform:translate(604px,300px)}
  52% {transform:translate(576px,328px)}
  80% {transform:translate(250px,328px)}
  95% {opacity:1}
  100%{opacity:0;transform:translate(180px,240px)}
}

/* it lands on the attacker: the error is the moment the kill takes effect */
.ar-anim .err{opacity:0}
.ar-anim .err rect{fill:var(--t4);fill-opacity:.18;stroke:var(--t4);stroke-width:1.2}
.ar-anim .err .x{stroke:var(--t4);stroke-width:2;stroke-linecap:round}
.ar-anim .err .eln{fill:var(--t4);opacity:.75}
.ar-anim[data-scene="5"] .err{animation:re-err .35s ease-out forwards 2.4s}
.ar-anim[data-scene="6"] .err{opacity:1}
@keyframes re-err{from{opacity:0;transform:scale(.9)}to{opacity:1;transform:none}}
.ar-anim[data-anim="response"] .term .tl{animation:al-type 2.6s steps(1) infinite var(--d)}
.ar-anim[data-anim="response"][data-scene="6"] .term .tl{opacity:.14;animation:none}

/* scene 6: the retry recoils off a resource it can no longer reach */
.ar-anim .retry{fill:none;stroke:var(--strong);stroke-width:2;opacity:0;
  stroke-dasharray:300;stroke-dashoffset:300}
.ar-anim[data-scene="6"] .retry{animation:re-retry 2.4s ease-out forwards .4s}
@keyframes re-retry{0%{opacity:.7;stroke-dashoffset:300}40%{opacity:.7;stroke-dashoffset:60}
  58%{opacity:.7;stroke-dashoffset:150}100%{opacity:.18;stroke-dashoffset:180}}

@media(prefers-reduced-motion:reduce){
  .ar-anim *{animation:none!important;transition:none!important}
}

/* principles + per-platform real-time tables (data/principles.json, data/alerting-platforms.json) */
.pr{padding:12px 0;border-top:1px solid var(--border)}.pr:first-child{border-top:0}
.pr p{margin:.35rem 0 0}
details.pf{border:1px solid var(--border);border-radius:8px;padding:10px 14px;margin:10px 0;background:var(--surface)}
details.pf>summary{cursor:pointer;font-weight:600}
details.pf[open]>summary{margin-bottom:6px}
.rt td{vertical-align:top}
