@font-face{font-family:"IBM Plex Mono";src:url("/assets/ibm-plex-mono-400-d803141a.woff2") format("woff2");font-weight:400;font-style:normal;font-display:swap;}
@font-face{font-family:"IBM Plex Mono";src:url("/assets/ibm-plex-mono-500-3f7bbac1.woff2") format("woff2");font-weight:500;font-style:normal;font-display:swap;}
/* =========================================================================
   orqo — warm landing prototype
   Editorial / document aesthetic forked from the SR promo page.
   Two changes from that source: a warm (cream + terracotta) palette, and
   Rotis carrying display + body. A mono stays only on the system labels.
   ========================================================================= */

/* --- Rotis family (local woff2) ------------------------------------------ */
@font-face{
  font-family:"Rotis Serif";
  src:url("/assets/rotis-serif-std-font-webfont-0b2354c3.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Rotis Serif";
  src:url("/assets/rotis-serif-std-bold-webfont-d429d51f.woff2") format("woff2");
  font-weight:700;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Rotis Sans";
  src:url("/assets/rotis_sans_serif_55-webfont-6e375638.woff2") format("woff2");
  font-weight:400;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Rotis Sans";
  src:url("/assets/rotis_sans_serif_bold_65-webfont-3fb3aadf.woff2") format("woff2");
  font-weight:600;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Rotis Sans";
  src:url("/assets/rotis_sans_serif_extra_bold_75-webfont-6c869a7d.woff2") format("woff2");
  font-weight:800;font-style:normal;font-display:swap;
}
@font-face{
  font-family:"Rotis Semi";
  src:url("/assets/rotis_semisans_light_45-webfont-c63d6ce9.woff2") format("woff2");
  font-weight:300;font-style:normal;font-display:swap;
}

/* --- Warm palette (the whole look lives here) ---------------------------- */
:root{
  --ink:#2A2014;        /* warm near-black brown for body text             */
  --ink-soft:#5C4A36;
  --muted:#8C7A63;
  --paper:#F4ECDD;      /* warm cream — MUST match the shader bg vec3      */
  --card:#FFFCF5;       /* warm white for cards                            */
  --line:#E6D9C4;
  --gold:#B05518;       /* terracotta — primary accent (eyebrows, links)  */
  --gold-soft:#F3E4CD;
  --gold-line:#E2C18A;
  --teal:#7A6A2E;       /* bronze-olive — secondary accent                */
  --teal-soft:#ECE6CF;
  --teal-line:#C8BC86;
}

*{box-sizing:border-box;}
html{scroll-behavior:smooth;}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:"Rotis Sans",system-ui,sans-serif;
  font-size:16px;
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
}

.wrap-wide{max-width:1080px;margin:0 auto;padding:0 28px;}

/* =========================================================================
   Top navigation
   ========================================================================= */
.nav{
  position:sticky;top:0;z-index:50;
  background:rgba(244,236,221,.86);
  backdrop-filter:saturate(140%) blur(8px);
  border-bottom:1px solid var(--line);
}
.nav-inner{display:flex;align-items:center;gap:22px;height:60px;}
.nav-brand{display:flex;align-items:center;text-decoration:none;flex:none;}
.nav-brand img{height:20px;width:auto;display:block;}
.nav-links{display:flex;align-items:center;gap:4px;margin-left:auto;flex-wrap:wrap;}
.nav-links a{
  font-family:"IBM Plex Mono",monospace;font-size:12px;letter-spacing:.06em;
  color:var(--ink-soft);text-decoration:none;
  padding:7px 11px;border-radius:5px;white-space:nowrap;
}
.nav-links a:hover{color:var(--ink);background:rgba(42,32,20,.05);}
.nav-links a[aria-current="page"]{color:var(--gold);}
.nav-links a.cta{color:#fff;background:var(--ink);}
.nav-links a.cta:hover{background:#3a2c1a;color:#fff;}

/* Capabilities dropdown */
.nav-dd{position:relative;display:flex;align-items:center;}
.nav-dd-trigger::after{content:"\25BE";font-size:9px;margin-left:5px;opacity:.6;}
.nav-dd-menu{
  display:none;position:absolute;top:100%;left:0;min-width:232px;
  background:var(--card);border:1px solid var(--line);border-radius:8px;
  box-shadow:0 14px 30px rgba(42,32,20,.13);padding:6px;z-index:60;
}
.nav-dd:hover .nav-dd-menu,.nav-dd:focus-within .nav-dd-menu{display:block;}
.nav-dd-menu a{display:block;padding:9px 12px;border-radius:6px;color:var(--ink-soft);white-space:nowrap;}
.nav-dd-menu a:hover{background:rgba(42,32,20,.05);color:var(--ink);}

/* =========================================================================
   Masthead — full-bleed living rings behind a left reading column
   ========================================================================= */
header.top{
  position:relative;overflow:hidden;
  min-height:82vh;display:flex;align-items:center;
  border-bottom:1px dashed var(--ink);
}
header.top canvas{position:absolute;inset:0;width:100%;height:100%;z-index:0;}
header.top .wrap-wide{position:relative;z-index:1;width:100%;}
.hero-copy{max-width:640px;}
.hero-mark{display:block;height:clamp(60px,8vw,88px);width:auto;margin-bottom:22px;}

.brand{
  font-family:"IBM Plex Mono",monospace;font-size:13px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--gold);font-weight:500;margin-bottom:22px;
}
/* On the landing hero the eyebrow reads INTO the headline rather than labelling
   it, so it sits close enough to scan as one sentence. Scoped to header.top —
   everywhere else .brand is a standalone label ("FAQ", "orqo vs CrewAI") and
   keeps its full 22px. */
header.top .brand{margin-bottom:8px;}
h1{
  font-family:"Rotis Serif",Georgia,serif;font-weight:400;
  font-size:clamp(40px,6.2vw,66px);line-height:1.03;letter-spacing:-.012em;
  margin:0 0 20px;max-width:15ch;
}
.dek{font-size:18.5px;color:var(--ink-soft);max-width:60ch;margin:0 0 28px;line-height:1.5;}
.dek strong{color:var(--ink);font-weight:600;}
/* The punchline that closes a demonstration — never opens one. Set at heading
   weight so it reads as the conclusion of the paragraph above it, not a claim. */
.punch{
  font-family:"Rotis Serif",Georgia,serif;font-weight:500;
  font-size:clamp(22px,2.8vw,30px);letter-spacing:-.012em;line-height:1.15;
  color:var(--ink);margin:0 0 30px;
}
/* One row of chips. No max-width here — 60ch is narrower than three chips need,
   which pushed the third onto its own line. The parent (.hero-copy, .wrap-wide)
   does the constraining; flex-wrap is left in place for narrow screens only. */
.meta{
  display:flex;flex-wrap:wrap;gap:0;font-family:"IBM Plex Mono",monospace;
  font-size:12px;color:var(--muted);border-top:1px solid var(--line);
}
.meta div{padding:11px 22px 0 0;margin-right:22px;border-right:1px solid var(--line);}
.meta div:last-child{border-right:none;margin-right:0;}
.meta span{display:block;color:var(--ink);font-weight:500;letter-spacing:.02em;margin-top:2px;}

/* =========================================================================
   Child-page masthead (no rings) — used by security/why/thesis pages
   ========================================================================= */
header.page-top{padding:60px 0 32px;border-bottom:1px dashed var(--ink);}
header.page-top h1{max-width:20ch;}
header.page-top .dek{margin-top:6px;}

/* =========================================================================
   Sections / type
   ========================================================================= */
section{padding:54px 0;border-bottom:1px solid var(--line);}
.eyebrow{
  font-family:"IBM Plex Mono",monospace;font-size:11.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);display:flex;align-items:center;gap:12px;margin-bottom:18px;
}
.eyebrow::before{content:"";width:26px;height:0;border-top:1px dashed var(--ink);opacity:.5;}
h2{
  font-family:"Rotis Serif",Georgia,serif;font-weight:400;font-size:clamp(27px,3.6vw,35px);
  line-height:1.12;letter-spacing:-.01em;margin:0 0 18px;
}
h3{font-size:15px;font-weight:600;margin:0 0 6px;letter-spacing:.005em;}
/* Two-part headline: a small muted jab, then the answer at full headline size.
   Both forced onto their own lines so the antithesis never breaks mid-clause,
   and the size gap keeps the answer — not the setup — reading as the headline. */
h2.antithesis .setup,h2.antithesis .answer{display:block;}
h2.antithesis .setup{
  font-size:.62em;line-height:1.15;letter-spacing:0;
  color:var(--ink-soft);max-width:34ch;margin-bottom:.3em;
}
h2.antithesis .answer{color:var(--ink);font-weight:500;}
/* Run-in beat label — names the turn out loud (Problem / Solution) so a reader
   who skims still gets the structure. Muted for the setup, gold for the answer. */
.beat{
  font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;font-weight:500;color:var(--muted);
  margin-right:10px;white-space:nowrap;
}
.beat.solve{color:var(--gold);}
/* Subheadline — the serif-italic "answer" line under a main headline. */
.subhead{font-family:"Rotis Serif",Georgia,serif;font-weight:400;font-style:italic;font-size:clamp(19px,2.4vw,25px);line-height:1.25;color:var(--gold);margin:-6px 0 18px;}
p{margin:0 0 16px;color:var(--ink-soft);}
p.lead{color:var(--ink);font-size:17px;max-width:64ch;}
a{color:var(--gold);text-decoration:underline;text-underline-offset:2px;text-decoration-thickness:1px;}

/* =========================================================================
   Legal pages (privacy / terms / data-deletion) — long-form prose in the warm
   system: numbered <h2> sections separated by a hairline rule, <h3> sub-heads,
   readable lists and links. Same chrome (nav/footer) as the rest of the site.
   ========================================================================= */
.legal-prose{max-width:74ch;}
.legal-prose h2{font-size:clamp(21px,2.4vw,25px);margin:42px 0 12px;padding-top:24px;border-top:1px solid var(--line);}
.legal-prose > h2:first-child{margin-top:0;padding-top:0;border-top:none;}
.legal-prose h3{font-size:16px;font-weight:600;color:var(--ink);margin:22px 0 6px;}
.legal-prose p{max-width:74ch;line-height:1.6;}
.legal-prose ul{margin:0 0 16px;padding-left:22px;max-width:74ch;}
.legal-prose li{margin:0 0 7px;color:var(--ink-soft);line-height:1.55;}
.legal-prose strong{color:var(--ink);font-weight:600;}

/* timeline (the 2022 → 2025 ladder) */
.timeline{list-style:none;margin:2px 0 26px;padding:0;max-width:60ch;}
.timeline li{display:flex;gap:18px;padding:7px 0;border-top:1px solid var(--line);}
.timeline li:first-child{border-top:none;}
.timeline .yr{
  font-family:"IBM Plex Mono",monospace;font-size:13px;color:var(--gold);
  flex:none;width:3.2em;font-weight:500;
}
.timeline .ev{color:var(--ink-soft);font-size:15px;}
/* The timeline's payoff: the pattern completing (one:one -> one:many ->
   many:many : one harness), set at h1 scale because it is the sentence the whole
   section builds to.
   Terracotta, NOT the brand orange #F67835 — that scores 2.34 against --paper
   and fails WCAG's 3.0 for large text, so it is unreadable here at any size.
   --gold is 4.30. */
.now{
  font-family:"Rotis Serif",Georgia,serif;font-weight:400;
  font-size:clamp(40px,6.2vw,66px);line-height:1;letter-spacing:-.012em;
  color:var(--gold);margin:28px 0 4px;padding-top:24px;
  border-top:1px dashed var(--ink);max-width:60ch;
}
/* The statement the year lands on — a step under the year, in ink, so the two
   read as one milestone rather than competing for the same weight. */
.now-sub{
  font-family:"Rotis Serif",Georgia,serif;font-weight:500;
  font-size:clamp(23px,3.1vw,34px);line-height:1.12;letter-spacing:-.012em;
  color:var(--ink);margin:0;max-width:40ch;
}

/* arrow link */
.arrow{
  display:inline-flex;align-items:center;gap:7px;font-family:"IBM Plex Mono",monospace;
  font-size:12.5px;letter-spacing:.04em;text-transform:uppercase;text-decoration:none;font-weight:500;color:var(--gold);
}
.arrow::after{content:"\2192";font-size:15px;transition:transform .15s ease;}
.arrow:hover::after{transform:translateX(3px);}

/* =========================================================================
   Pillars (Context management + Convictions)
   ========================================================================= */
.pillars{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;margin-top:8px;}
.pillar{
  display:flex;flex-direction:column;border:1px solid var(--line);border-radius:7px;
  padding:26px 24px 24px;background:var(--card);
}
.pillar.cap{border-top:3px solid var(--gold);}
.pillar.exp{border-top:3px solid var(--teal);}
.pillar.intel{border-top:3px solid var(--ink);}
.pillar .label{
  font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  margin-bottom:12px;font-weight:500;
}
.pillar.cap .label{color:var(--gold);}
.pillar.exp .label{color:var(--teal);}
.pillar.intel .label{color:var(--ink);}
.pillar .name{
  font-family:"Rotis Serif",Georgia,serif;font-weight:500;font-size:23px;letter-spacing:-.01em;
  margin:0 0 8px;color:var(--ink);
}
.pillar p{font-size:14.5px;margin:0;}

/* =========================================================================
   Compact feature list — a lighter, scannable counterpart to the value grid
   ========================================================================= */
.feature-list{list-style:none;margin:26px 0 0;padding:0;border-top:1px solid var(--line);}
.feature-list li{display:grid;grid-template-columns:240px 1fr;gap:20px;align-items:baseline;padding:15px 2px;border-bottom:1px solid var(--line);}
.feature-list .f-name{font-family:"Rotis Serif",Georgia,serif;font-size:18px;font-weight:500;letter-spacing:-.01em;color:var(--ink);}
.feature-list .f-desc{font-size:14.5px;line-height:1.55;color:var(--ink-soft);}
@media (max-width:680px){.feature-list li{grid-template-columns:1fr;gap:3px;}}

/* =========================================================================
   Door grid (links into the deep-dive pages)
   ========================================================================= */
.doors{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:8px;}
.door{
  display:flex;flex-direction:column;border:1px solid var(--line);border-radius:8px;
  padding:22px 22px 20px;background:var(--card);text-decoration:none;
  transition:transform .15s ease,box-shadow .15s ease,border-color .15s ease;
}
.door:hover{transform:translateY(-2px);box-shadow:0 10px 24px rgba(42,32,20,.10);border-color:var(--gold-line);}
.door .d-name{font-family:"Rotis Serif",Georgia,serif;font-weight:500;font-size:20px;letter-spacing:-.01em;color:var(--ink);margin:0 0 7px;}
.door .d-desc{font-size:14px;color:var(--ink-soft);margin:0 0 16px;flex:1;line-height:1.5;}
.door .d-go{
  font-family:"IBM Plex Mono",monospace;font-size:11.5px;letter-spacing:.04em;text-transform:uppercase;
  color:var(--gold);display:inline-flex;align-items:center;gap:6px;
}
.door .d-go::after{content:"\2192";font-size:14px;transition:transform .15s ease;}
.door:hover .d-go::after{transform:translateX(3px);}
@media (max-width:760px){.doors{grid-template-columns:1fr;}}

/* =========================================================================
   Principles grid (What your team gets)
   ========================================================================= */
.principles{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--line);border:1px solid var(--line);margin-top:8px;border-radius:7px;overflow:hidden;}
.principles .cell{background:var(--card);padding:24px 24px 26px;}
.principles .num{font-family:"IBM Plex Mono",monospace;font-size:12px;color:var(--gold);margin-bottom:10px;}
.principles p{margin:0;font-size:14.5px;}
.principles p strong{color:var(--ink);font-weight:600;}
.principles + p{margin-top:26px;}

/* =========================================================================
   Diagram figure (Security)
   ========================================================================= */
.figure{background:var(--card);border:1px solid var(--line);border-radius:8px;padding:26px 26px 14px;margin:8px 0 22px;}
.figure svg{width:100%;height:auto;display:block;}
.figure figcaption{font-size:13px;color:var(--muted);padding:12px 4px 6px;font-style:italic;}

/* Borderless diagram: a transparent SVG floats on the page, anchored only by
   the nodes' own shadows — no card, no background (that would just be a screenshot). */
.diagram{margin:18px 0 8px;}
.diagram svg,.diagram img{width:100%;height:auto;display:block;}

/* Image beside text — a product shot in a fixed left column, copy on the right */
/* -------------------------------------------------------------------------
   Animated diagrams. The reveal controller adds .play once on scroll-in; the
   animation then loops on one shared cycle. Resting state is the finished
   diagram, so a reader with prefers-reduced-motion (who never gets .play, and
   whose animations the media query kills anyway) sees the complete picture.
   ------------------------------------------------------------------------- */
/* ONE 14s master cycle, following the real execution order:
     stage goes active and STAYS active for the whole run (it is the container,
     not a step) -> entry hook fires -> Researcher works and emits research_data
     -> Outcome Checker judges and declares fail -> Researcher works again ->
     Checker judges again, this time it passes -> exit hook posts out -> rest.
   Every part keys off the same duration; mismatched durations drift out of
   phase within a few passes. Marching ants mark whoever is active right now. */

/* --- the data moving along the wires ------------------------------------- */
.diagram-anim .wf-packet,.diagram-anim .wf-drop{opacity:0;}
.diagram-anim.armed .wf-packet{
  offset-path:path("M216,302 H405 V386 C405,400 418,408 440,408 H540 C580,408 592,396 592,362 C592,336 574,326 540,326 H400 V302 H610");
  offset-distance:0%;offset-rotate:0deg;opacity:0;
}
.diagram-anim.play .wf-packet{
  animation:wf-travel 14s cubic-bezier(.45,0,.25,1) .3s infinite,
            wf-pulse 1.2s ease-in-out .3s infinite;
}
@keyframes wf-pulse{
  0%,100%{r:6;   filter:drop-shadow(0 0 3px rgba(246,120,53,.45));}
  50%    {r:8.5; filter:drop-shadow(0 0 10px rgba(246,120,53,.75));}
}
@keyframes wf-travel{
  0%   {offset-distance:0%;   opacity:0;}
  3%   {offset-distance:0%;   opacity:1;}   /* entry hook fires */
  10%  {offset-distance:21%;  opacity:1;}   /* into the stage */
  38%  {offset-distance:21%;  opacity:1;}   /* the agents work inside it */
  43%  {offset-distance:31%;  opacity:1;}   /* down to the decision node */
  47%  {offset-distance:31%;  opacity:1;}
  54%  {offset-distance:45%;  opacity:1;}   /* fail */
  60%  {offset-distance:76%;  opacity:1;}   /* looped back into the stage */
  84%  {offset-distance:76%;  opacity:1;}   /* redone, and this time it passes */
  90%  {offset-distance:100%; opacity:1;}   /* out through the exit hook */
  93%  {offset-distance:100%; opacity:0;}
  100% {offset-distance:100%; opacity:0;}   /* rest, then round again */
}

/* Each assignment drops its output down its own wire while it is working. */
.diagram-anim.armed .wf-drop[data-drop="a"]{offset-path:path("M300,118 C300,168 320,206 357,232");}
.diagram-anim.armed .wf-drop[data-drop="b"]{offset-path:path("M630,118 C630,180 528,198 453,232");}
.diagram-anim .wf-drop{offset-distance:0%;offset-rotate:0deg;}
.diagram-anim.play .wf-drop[data-drop="a"]{animation:wf-drop-a 14s ease-in-out .3s infinite;}
.diagram-anim.play .wf-drop[data-drop="b"]{animation:wf-drop-b 14s ease-in-out .3s infinite;}
@keyframes wf-drop-a{
  0%,13%{offset-distance:0%;opacity:0;}
  15%{opacity:1;} 24%{offset-distance:100%;opacity:1;} 26%{offset-distance:100%;opacity:0;}
  27%,57%{offset-distance:0%;opacity:0;}
  59%{opacity:1;} 68%{offset-distance:100%;opacity:1;} 70%{offset-distance:100%;opacity:0;}
  71%,100%{offset-distance:0%;opacity:0;}
}
@keyframes wf-drop-b{
  0%,31%{offset-distance:0%;opacity:0;}
  33%{opacity:1;} 42%{offset-distance:100%;opacity:1;} 44%{offset-distance:100%;opacity:0;}
  45%,75%{offset-distance:0%;opacity:0;}
  77%{opacity:1;} 85%{offset-distance:100%;opacity:1;} 87%{offset-distance:100%;opacity:0;}
  88%,100%{offset-distance:0%;opacity:0;}
}

/* --- who is active right now --------------------------------------------- */
/* Marching ants. Each outline is a SIBLING of its card, never a child: inside
   the group the card drop-shadow filter smears the dashes into a blur. */
.diagram-anim .wf-busy{opacity:0;}
.diagram-anim.play .wf-busy{animation-name:wf-ants;animation-duration:1.1s;
  animation-timing-function:linear;animation-iteration-count:infinite;}
@keyframes wf-ants{to{stroke-dashoffset:-26;}}

.diagram-anim.play .wf-busy[data-busy="stage"]{
  animation:wf-ants 1.1s linear infinite, wf-busy-stage 14s linear .3s infinite;}
.diagram-anim.play .wf-busy[data-busy="entry"]{
  animation:wf-ants 1.1s linear infinite, wf-busy-entry 14s linear .3s infinite;}
.diagram-anim.play .wf-busy[data-busy="agent-a"]{
  animation:wf-ants 1.1s linear infinite, wf-busy-a 14s linear .3s infinite;}
.diagram-anim.play .wf-busy[data-busy="agent-b"]{
  animation:wf-ants 1.1s linear infinite, wf-busy-b 14s linear .3s infinite;}
.diagram-anim.play .wf-busy[data-busy="exit"]{
  animation:wf-ants 1.1s linear infinite, wf-busy-exit 14s linear .3s infinite;}

/* The stage is lit for the whole run — it is the container the work happens in. */
@keyframes wf-busy-stage{0%,1%{opacity:0;} 3%,91%{opacity:.9;} 94%,100%{opacity:0;}}
@keyframes wf-busy-entry{0%,2%{opacity:0;} 4%,10%{opacity:.9;} 12%,100%{opacity:0;}}
@keyframes wf-busy-a{
  0%,11%{opacity:0;} 13%,25%{opacity:.9;} 27%,55%{opacity:0;}
  57%,69%{opacity:.9;} 71%,100%{opacity:0;}}
@keyframes wf-busy-b{
  0%,29%{opacity:0;} 31%,43%{opacity:.9;} 45%,73%{opacity:0;}
  75%,86%{opacity:.9;} 88%,100%{opacity:0;}}
@keyframes wf-busy-exit{0%,86%{opacity:0;} 88%,92%{opacity:.9;} 94%,100%{opacity:0;}}

/* A shade of scale on whoever is working, so activity reads even at a glance. */
.diagram-anim .wf-card,.diagram-anim .wf-agent{transform-box:fill-box;transform-origin:center;}
.diagram-anim.play .wf-agent[data-agent="1"]{animation:wf-lean-a 14s ease-in-out .3s infinite;}
.diagram-anim.play .wf-agent[data-agent="2"]{animation:wf-lean-b 14s ease-in-out .3s infinite;}
@keyframes wf-lean-a{
  0%,12%{transform:scale(1);} 16%,24%{transform:scale(1.012);}
  28%,56%{transform:scale(1);} 60%,68%{transform:scale(1.012);}
  72%,100%{transform:scale(1);}}
@keyframes wf-lean-b{
  0%,30%{transform:scale(1);} 34%,42%{transform:scale(1.012);}
  46%,74%{transform:scale(1);} 78%,85%{transform:scale(1.012);}
  89%,100%{transform:scale(1);}}

/* The stage keeps its resting shadow throughout. That shadow is the SVG
   filter="url(#wfSh)" ATTRIBUTE, and a CSS filter overrides it outright, so any
   filter keyframe here must chain url(#wfSh) or the card goes flat. */
.diagram-anim.play .wf-card[data-stage="1"]{animation:wf-working 14s ease-in-out .3s infinite;}
@keyframes wf-working{
  0%,2%{filter:url(#wfSh);}
  5%,90%{filter:url(#wfSh) drop-shadow(0 5px 15px rgba(42,32,20,.15));}
  94%,100%{filter:url(#wfSh);}
}

/* --- margin notes --------------------------------------------------------- */
/* A reader annotation, not product chrome, so they get a hand and the terracotta
   accent rather than the canvas palette. They do NOT loop: an annotation appears
   once and then belongs to the page.
   ⚠ No handwriting face is vendored yet, so this falls through to whatever script
   font the OS happens to have and will look different per platform. Drop a woff2
   into app/assets/fonts, @font-face it, and put it first here. */
.diagram-anim .wf-note-text{
  font-family:"Caveat","Bradley Hand","Segoe Script","Brush Script MT",cursive;
  font-size:20px;letter-spacing:.01em;
}
.diagram-anim.armed .wf-note{opacity:0;}
.diagram-anim.play .wf-note{animation:wf-fade .7s ease-out 1.1s forwards;}

/* --- what each step leaves behind ---------------------------------------- */
/* research_data lands when the Researcher finishes its first pass. */
.diagram-anim.armed .wf-chip{opacity:0;}
.diagram-anim.play .wf-chip{animation:wf-chip-cycle 14s linear .3s infinite;}
@keyframes wf-chip-cycle{0%,22%{opacity:0;} 26%,92%{opacity:1;} 96%,100%{opacity:0;}}

/* The verdict only exists once the Outcome Checker has declared it. */
.diagram-anim.armed .wf-route{opacity:.25;}
.diagram-anim.play .wf-route{animation:wf-route-cycle 14s linear .3s infinite;}
@keyframes wf-route-cycle{0%,41%{opacity:.25;} 45%,92%{opacity:1;} 96%,100%{opacity:.25;}}

.diagram-anim.armed .wf-loop{opacity:0;}
.diagram-anim.play .wf-loop{animation:wf-loop-cycle 14s linear .3s infinite;}
@keyframes wf-loop-cycle{0%,44%{opacity:0;} 48%,92%{opacity:1;} 96%,100%{opacity:0;}}

.diagram-anim.armed .wf-out{opacity:.25;}
.diagram-anim.play .wf-out{animation:wf-out-cycle 14s linear .3s infinite;}
@keyframes wf-out-cycle{0%,84%{opacity:.25;} 88%,92%{opacity:1;} 96%,100%{opacity:.25;}}

@keyframes wf-fade{to{opacity:1;}}

/* Belt and braces: even if .play is somehow applied, honour the OS setting. */
@media (prefers-reduced-motion:reduce){
  .diagram-anim *,.diagram-anim.play *{animation:none !important;}
  .diagram-anim .wf-packet{opacity:0;}
  .diagram-anim .wf-route,.diagram-anim .wf-loop,.diagram-anim .wf-note,
  .diagram-anim .wf-chip,.diagram-anim .wf-out{opacity:1;}
}

/* -------------------------------------------------------------------------
   Integrations diagram — one 12s cycle, both directions on the same wires.
   Outbound leaves orqo and lands on a system; inbound comes back up from a
   different one, so the two are never mistaken for one dot bouncing.
   ------------------------------------------------------------------------- */
.diagram-anim .ig-sig{opacity:0;offset-distance:0%;offset-rotate:0deg;}
.diagram-anim.armed .ig-sig[data-w="1"][data-d="out"]{offset-path:path("M450,98 C450,126 412,162 366,162");}
.diagram-anim.armed .ig-sig[data-w="2"][data-d="out"]{offset-path:path("M450,98 C450,152 486,222 534,222");}
.diagram-anim.armed .ig-sig[data-w="3"][data-d="in"]{offset-path:path("M366,282 C404,282 450,196 450,98");}
.diagram-anim.armed .ig-sig[data-w="4"][data-d="in"]{offset-path:path("M534,342 C490,342 450,236 450,98");}
.diagram-anim.armed .ig-sig[data-w="1"][data-d="in"]{offset-path:path("M366,162 C412,162 450,126 450,98");}
.diagram-anim.armed .ig-sig[data-w="5"][data-d="out"]{offset-path:path("M450,98 C450,286 400,402 366,402");}
.diagram-anim.armed .ig-sig[data-w="5"][data-d="in"]{offset-path:path("M366,402 C400,402 450,286 450,98");}
.diagram-anim.armed .ig-sig[data-w="6"][data-d="out"]{offset-path:path("M450,98 C450,330 492,462 534,462");}
.diagram-anim.play .ig-sig{animation:ig-fire 12s cubic-bezier(.4,0,.3,1) infinite;}
.diagram-anim.play .ig-sig[data-t="0"]{animation-delay:0.0s;}
.diagram-anim.play .ig-sig[data-t="1"]{animation-delay:1.5s;}
.diagram-anim.play .ig-sig[data-t="2"]{animation-delay:3.0s;}
.diagram-anim.play .ig-sig[data-t="3"]{animation-delay:4.5s;}
.diagram-anim.play .ig-sig[data-t="4"]{animation-delay:6.0s;}
.diagram-anim.play .ig-sig[data-t="5"]{animation-delay:7.5s;}
.diagram-anim.play .ig-sig[data-t="6"]{animation-delay:9.0s;}
.diagram-anim.play .ig-sig[data-t="7"]{animation-delay:10.5s;}
@keyframes ig-fire{
  0%  {offset-distance:0%;   opacity:0;}
  4%  {offset-distance:0%;   opacity:1;}
  22% {offset-distance:100%; opacity:1;}
  26% {offset-distance:100%; opacity:0;}
  100%{offset-distance:100%; opacity:0;}
}

/* The hub answers whatever reaches it. */
.diagram-anim .ig-hub{transform-box:fill-box;transform-origin:center;}
.diagram-anim.play .ig-hub{animation:ig-hub 3s ease-in-out infinite;}
@keyframes ig-hub{
  0%,100%{filter:drop-shadow(0 0 3px rgba(214,94,10,.18));}
  50%    {filter:drop-shadow(0 0 11px rgba(214,94,10,.42));}
}

/* The sixth tile is the only one that moves: dashed and empty, then a plus,
   then solid with a name. It is the claim the other five cannot make. */
.diagram-anim .ig-build-name{opacity:0;}
.diagram-anim .ig-build-plus{opacity:1;}
.diagram-anim.play .ig-build-box {animation:ig-box  12s linear .3s infinite;}
.diagram-anim.play .ig-build-plus{animation:ig-plus 12s ease-in-out .3s infinite;}
.diagram-anim.play .ig-build-name{animation:ig-name 12s ease-in-out .3s infinite;}
@keyframes ig-box{
  0%,54%   {stroke-dasharray:7 6;  stroke:#D65E0A;}
  66%,92%  {stroke-dasharray:7 0;  stroke:#DCC18A;}
  97%,100% {stroke-dasharray:7 6;  stroke:#D65E0A;}
}
@keyframes ig-plus{
  0%,52%  {opacity:1;transform:none;}
  58%     {opacity:1;}
  64%,92% {opacity:0;}
  97%,100%{opacity:1;}
}
@keyframes ig-name{
  0%,60%  {opacity:0;}
  68%,92% {opacity:1;}
  96%,100%{opacity:0;}
}

@media (prefers-reduced-motion:reduce){
  .diagram-anim .ig-sig{opacity:0;}
  .diagram-anim .ig-build-name{opacity:1;}
  .diagram-anim .ig-build-plus{opacity:0;}
}

/* -------------------------------------------------------------------------
   Compaction — one 12s clock, two bars that must be read together. The context
   bar is a sawtooth: fill, compact, fill, never crossing the limit. The work
   bar only climbs. Four compactions, four multiples of work, same budget.
   ------------------------------------------------------------------------- */
.diagram-anim.armed .cx-live,.diagram-anim.armed .cx-packed,.diagram-anim.armed .cx-work{width:0;}
.diagram-anim.play .cx-live  {animation:cx-live   12s ease-in-out .3s infinite;}
.diagram-anim.play .cx-packed{animation:cx-packed 12s ease-in-out .3s infinite;}
.diagram-anim.play .cx-work  {animation:cx-work   12s ease-in-out .3s infinite;}
/* The drop at each compaction is instant (1% apart) — compaction is an event,
   not a slow leak, and easing it would read as the context draining away. */
@keyframes cx-live{
  0%{width:0;}
  18%{width:620px;} 19%{width:200px;}
  37%{width:640px;} 38%{width:250px;}
  56%{width:660px;} 57%{width:300px;}
  75%{width:680px;} 76%{width:340px;}
  92%,96%{width:600px;} 100%{width:0;}
}
@keyframes cx-packed{
  0%,18%{width:0;}
  19%,37%{width:120px;}
  38%,56%{width:172px;}
  57%,75%{width:224px;}
  76%,96%{width:276px;}
  100%{width:0;}
}
@keyframes cx-work{
  0%{width:0;}
  18%,19%{width:175px;}
  37%,38%{width:350px;}
  56%,57%{width:525px;}
  75%,96%{width:700px;}
  100%{width:0;}
}
@media (prefers-reduced-motion:reduce){
  .diagram-anim .cx-live{width:600px;}
  .diagram-anim .cx-packed{width:276px;}
  .diagram-anim .cx-work{width:700px;}
}

/* -------------------------------------------------------------------------
   Sharing — one 11s cycle read left to right: the canvas assembles, it is
   shared on stated terms, the card appears, someone presses it, and the run
   lands on the record. The two panels are never both "new" at once; the left
   settles before the right begins, so the eye is led rather than split.
   ------------------------------------------------------------------------- */
.diagram-anim.armed .sh-build,.diagram-anim.armed .sh-wire,
.diagram-anim.armed .sh-perm,.diagram-anim.armed .sh-card,
.diagram-anim.armed .sh-run,.diagram-anim.armed .sh-track{opacity:0;}
.diagram-anim .sh-dot{opacity:0;}

.diagram-anim.play .sh-build[data-b="1"]{animation:sh-in 11s ease-out .3s infinite;}
.diagram-anim.play .sh-build[data-b="2"]{animation:sh-in 11s ease-out .9s infinite;}
.diagram-anim.play .sh-build[data-b="3"]{animation:sh-in 11s ease-out 1.5s infinite;}
.diagram-anim.play .sh-wire {animation:sh-in 11s ease-out 1.9s infinite;}
.diagram-anim.play .sh-track{animation:sh-in 11s ease-out 2.6s infinite;}
.diagram-anim.play .sh-perm {animation:sh-in 11s ease-out 2.9s infinite;}
.diagram-anim.play .sh-card {animation:sh-in 11s ease-out 4.2s infinite;}
.diagram-anim.play .sh-run  {animation:sh-in 11s ease-out 7.4s infinite;}
/* Each element holds from its own delay to the shared 94% fade, so the whole
   picture is complete and still for the last second of every pass. */
@keyframes sh-in{
  0%{opacity:0;} 4%{opacity:1;} 94%{opacity:1;} 99%,100%{opacity:0;}
}

/* the share itself, travelling the arrow */
.diagram-anim.armed .sh-dot{offset-path:path("M404,150 H492");offset-distance:0%;offset-rotate:0deg;}
.diagram-anim.play .sh-dot{animation:sh-send 11s ease-in-out 3.3s infinite;}
@keyframes sh-send{
  0%{offset-distance:0%;opacity:0;} 2%{opacity:1;}
  7%{offset-distance:100%;opacity:1;} 10%,100%{offset-distance:100%;opacity:0;}
}

/* pressed — the one action the recipient ever takes */
.diagram-anim .sh-btn{transform-box:fill-box;transform-origin:center;}
.diagram-anim.play .sh-btn{animation:sh-press 11s ease-in-out .3s infinite;}
@keyframes sh-press{
  0%,58%{transform:scale(1);filter:none;}
  62%{transform:scale(.92);}
  66%,94%{transform:scale(1);filter:drop-shadow(0 0 10px rgba(28,43,74,.35));}
  100%{transform:scale(1);filter:none;}
}

@media (prefers-reduced-motion:reduce){
  .diagram-anim .sh-build,.diagram-anim .sh-wire,.diagram-anim .sh-perm,
  .diagram-anim .sh-card,.diagram-anim .sh-run,.diagram-anim .sh-track{opacity:1;}
  .diagram-anim .sh-dot{opacity:0;}
}

/* -------------------------------------------------------------------------
   Knowledge — one 13s cycle, read left to right: a source connects, files land,
   each gains its unit count, the counts travel the wire, and the graph draws
   itself node by node and edge by edge. The tallies arrive last, once there is
   something to count. Nothing here is a screenshot of the finished graph — the
   part nobody believes is that no one tagged any of it.
   ------------------------------------------------------------------------- */
.diagram-anim.armed .kg-src,.diagram-anim.armed .kg-file,
.diagram-anim.armed .kg-badge,.diagram-anim.armed .kg-tally{opacity:0;}
.diagram-anim.armed .kg-node circle{opacity:0;transform-box:fill-box;transform-origin:center;}
.diagram-anim.armed .kg-edge path{stroke-dasharray:400;stroke-dashoffset:400;}
.diagram-anim .kg-move{opacity:0;offset-path:path("M312,168 H432");offset-distance:0%;offset-rotate:0deg;}

.diagram-anim.play .kg-src{animation:kg-in 13s ease-out .3s infinite;}
.diagram-anim.play .kg-live{animation:kg-blink 2.6s ease-in-out infinite;}
.diagram-anim.play .kg-file[data-f="1"]{animation:kg-in 13s ease-out 0.78s infinite;}
.diagram-anim.play .kg-file[data-f="1"] .kg-badge{animation:kg-in 13s ease-out 1.98s infinite;}
.diagram-anim.play .kg-file[data-f="2"]{animation:kg-in 13s ease-out 1.06s infinite;}
.diagram-anim.play .kg-file[data-f="2"] .kg-badge{animation:kg-in 13s ease-out 2.26s infinite;}
.diagram-anim.play .kg-file[data-f="3"]{animation:kg-in 13s ease-out 1.34s infinite;}
.diagram-anim.play .kg-file[data-f="3"] .kg-badge{animation:kg-in 13s ease-out 2.54s infinite;}
.diagram-anim.play .kg-file[data-f="4"]{animation:kg-in 13s ease-out 1.62s infinite;}
.diagram-anim.play .kg-file[data-f="4"] .kg-badge{animation:kg-in 13s ease-out 2.82s infinite;}
.diagram-anim.play .kg-move[data-m="1"]{animation:kg-send 13s ease-in-out 2.9s infinite;}
.diagram-anim.play .kg-move[data-m="2"]{animation:kg-send 13s ease-in-out 3.8s infinite;}
.diagram-anim.play .kg-move[data-m="3"]{animation:kg-send 13s ease-in-out 4.7s infinite;}
.diagram-anim.play .kg-move[data-m="4"]{animation:kg-send 13s ease-in-out 5.6s infinite;}
.diagram-anim.play .kg-node circle[data-n="1"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 2.92s infinite;}
.diagram-anim.play .kg-node circle[data-n="2"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 3.24s infinite;}
.diagram-anim.play .kg-node circle[data-n="3"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 3.56s infinite;}
.diagram-anim.play .kg-node circle[data-n="4"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 3.88s infinite;}
.diagram-anim.play .kg-node circle[data-n="5"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 4.2s infinite;}
.diagram-anim.play .kg-node circle[data-n="6"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 4.52s infinite;}
.diagram-anim.play .kg-node circle[data-n="7"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 4.84s infinite;}
.diagram-anim.play .kg-node circle[data-n="8"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 5.16s infinite;}
.diagram-anim.play .kg-node circle[data-n="9"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 5.48s infinite;}
.diagram-anim.play .kg-node circle[data-n="10"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 5.8s infinite;}
.diagram-anim.play .kg-node circle[data-n="11"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 6.12s infinite;}
.diagram-anim.play .kg-node circle[data-n="12"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 6.44s infinite;}
.diagram-anim.play .kg-node circle[data-n="13"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 6.76s infinite;}
.diagram-anim.play .kg-node circle[data-n="14"]{animation:kg-pop 13s cubic-bezier(.34,1.56,.64,1) 7.08s infinite;}
.diagram-anim.play .kg-edge path:nth-child(1){animation:kg-draw 13s ease-out 3.7s infinite;}
.diagram-anim.play .kg-edge path:nth-child(2){animation:kg-draw 13s ease-out 4.0s infinite;}
.diagram-anim.play .kg-edge path:nth-child(3){animation:kg-draw 13s ease-out 4.3s infinite;}
.diagram-anim.play .kg-edge path:nth-child(4){animation:kg-draw 13s ease-out 4.6s infinite;}
.diagram-anim.play .kg-edge path:nth-child(5){animation:kg-draw 13s ease-out 4.9s infinite;}
.diagram-anim.play .kg-edge path:nth-child(6){animation:kg-draw 13s ease-out 5.2s infinite;}
.diagram-anim.play .kg-edge path:nth-child(7){animation:kg-draw 13s ease-out 5.5s infinite;}
.diagram-anim.play .kg-edge path:nth-child(8){animation:kg-draw 13s ease-out 5.8s infinite;}
.diagram-anim.play .kg-edge path:nth-child(9){animation:kg-draw 13s ease-out 6.1s infinite;}
.diagram-anim.play .kg-edge path:nth-child(10){animation:kg-draw 13s ease-out 6.4s infinite;}
.diagram-anim.play .kg-edge path:nth-child(11){animation:kg-draw 13s ease-out 6.7s infinite;}
.diagram-anim.play .kg-edge path:nth-child(12){animation:kg-draw 13s ease-out 7.0s infinite;}
.diagram-anim.play .kg-edge path:nth-child(13){animation:kg-draw 13s ease-out 7.3s infinite;}
.diagram-anim.play .kg-edge path:nth-child(14){animation:kg-draw 13s ease-out 7.6s infinite;}
.diagram-anim.play .kg-edge path:nth-child(15){animation:kg-draw 13s ease-out 7.9s infinite;}
.diagram-anim.armed .kg-key{opacity:0;}
.diagram-anim.play .kg-key{animation:kg-in 13s ease-out 3.4s infinite;}
.diagram-anim.play .kg-tally{animation:kg-in 13s ease-out 9.4s infinite;}

/* the causal chain and the direction vocabulary, after the graph has settled */
.diagram-anim.armed .kg-hop,.diagram-anim.armed .kg-chip{opacity:0;}
.diagram-anim.play .kg-hop{animation:kg-in 13s ease-out 9.5s infinite;}
.diagram-anim.play .kg-chip[data-c="1"]{animation:kg-in 13s ease-out 10.15s infinite;}
.diagram-anim.play .kg-chip[data-c="2"]{animation:kg-in 13s ease-out 10.3s infinite;}
.diagram-anim.play .kg-chip[data-c="3"]{animation:kg-in 13s ease-out 10.45s infinite;}
.diagram-anim.play .kg-chip[data-c="4"]{animation:kg-in 13s ease-out 10.6s infinite;}
.diagram-anim.play .kg-chip[data-c="5"]{animation:kg-in 13s ease-out 10.75s infinite;}
.diagram-anim.play .kg-chip[data-c="6"]{animation:kg-in 13s ease-out 10.9s infinite;}
.diagram-anim.play .kg-chip[data-c="7"]{animation:kg-in 13s ease-out 11.05s infinite;}
.diagram-anim.play .kg-chip[data-c="8"]{animation:kg-in 13s ease-out 11.2s infinite;}
.diagram-anim.play .kg-chip[data-c="9"]{animation:kg-in 13s ease-out 11.35s infinite;}
@keyframes kg-in{0%{opacity:0;} 3%{opacity:1;} 94%{opacity:1;} 99%,100%{opacity:0;}}
@keyframes kg-blink{0%,100%{opacity:.35;} 50%{opacity:1;}}
/* Nodes overshoot slightly on arrival — a settling graph, not a slide show. */
@keyframes kg-pop{
  0%{opacity:0;transform:scale(.2);}
  4%{opacity:1;transform:scale(1);}
  94%{opacity:1;transform:scale(1);}
  99%,100%{opacity:0;transform:scale(.2);}
}
@keyframes kg-draw{
  0%{stroke-dashoffset:400;} 6%,94%{stroke-dashoffset:0;} 99%,100%{stroke-dashoffset:400;}
}
@keyframes kg-send{
  0%{offset-distance:0%;opacity:0;} 1%{opacity:1;}
  5%{offset-distance:100%;opacity:1;} 7%,100%{offset-distance:100%;opacity:0;}
}

@media (prefers-reduced-motion:reduce){
  .diagram-anim .kg-src,.diagram-anim .kg-file,.diagram-anim .kg-badge,
  .diagram-anim .kg-tally,.diagram-anim .kg-node circle,
  .diagram-anim .kg-hop,.diagram-anim .kg-chip,.diagram-anim .kg-key{opacity:1;}
  .diagram-anim .kg-edge path{stroke-dashoffset:0;}
  .diagram-anim .kg-move{opacity:0;}
}

/* -------------------------------------------------------------------------
   Circles — one 13s cycle that deliberately ENDS by taking the sharing back.
   Rooms appear locked, one invite crosses, it is accepted, a circle opens
   across that room alone, and then it is revoked. Holding the shared state
   to the end would show consent as a switch flipped once; the point is that
   it is a thing you can withdraw.
   ------------------------------------------------------------------------- */
.diagram-anim.armed .ci-you,.diagram-anim.armed .ci-them,.diagram-anim.armed .ci-room,
.diagram-anim.armed .ci-spoke,.diagram-anim.armed .ci-mech,
.diagram-anim.armed .ci-circle,.diagram-anim.armed .ci-accept,
.diagram-anim.armed .ci-private{opacity:0;}
.diagram-anim .ci-invite,.diagram-anim .ci-revoke{opacity:0;}

.diagram-anim.play .ci-you{animation:ci-in 13s ease-out .3s infinite;}
.diagram-anim.play .ci-spoke{animation:ci-in 13s ease-out .7s infinite;}
.diagram-anim.play .ci-room[data-r="1"]{animation:ci-in 13s ease-out 1.12s infinite;}
.diagram-anim.play .ci-room[data-r="2"]{animation:ci-in 13s ease-out 1.34s infinite;}
.diagram-anim.play .ci-room[data-r="3"]{animation:ci-in 13s ease-out 1.56s infinite;}
.diagram-anim.play .ci-room[data-r="4"]{animation:ci-in 13s ease-out 1.78s infinite;}
.diagram-anim.play .ci-them{animation:ci-in 13s ease-out 2.2s infinite;}
.diagram-anim.play .ci-mech[data-m="1"]{animation:ci-in 13s ease-out 8.74s infinite;}
.diagram-anim.play .ci-mech[data-m="2"]{animation:ci-in 13s ease-out 8.88s infinite;}
.diagram-anim.play .ci-mech[data-m="3"]{animation:ci-in 13s ease-out 9.02s infinite;}
.diagram-anim.play .ci-mech[data-m="4"]{animation:ci-in 13s ease-out 9.16s infinite;}
.diagram-anim.play .ci-mech[data-m="5"]{animation:ci-in 13s ease-out 9.3s infinite;}
.diagram-anim.play .ci-mech[data-m="6"]{animation:ci-in 13s ease-out 9.44s infinite;}
.diagram-anim.play .ci-mech[data-m="7"]{animation:ci-in 13s ease-out 9.58s infinite;}
@keyframes ci-in{0%{opacity:0;} 3%{opacity:1;} 93%{opacity:1;} 98%,100%{opacity:0;}}

/* the invite crosses from your Work room to theirs */
.diagram-anim.armed .ci-invite{offset-path:path("M288,110 H612");offset-distance:0%;offset-rotate:0deg;}
.diagram-anim.play .ci-invite{animation:ci-send 13s ease-in-out 3.2s infinite;}
@keyframes ci-send{
  0%{offset-distance:0%;opacity:0;} 2%{opacity:1;}
  9%{offset-distance:100%;opacity:1;} 12%,100%{offset-distance:100%;opacity:0;}
}
.diagram-anim.play .ci-accept{animation:ci-beat 13s ease-out 4.6s infinite;}
@keyframes ci-beat{0%{opacity:0;} 3%{opacity:1;} 62%{opacity:1;} 68%,100%{opacity:0;}}

/* the circle opens only after the invite is accepted, and closes before the end */
.diagram-anim.play .ci-circle{animation:ci-open 13s ease-out 5.4s infinite;}
@keyframes ci-open{0%{opacity:0;} 4%{opacity:1;} 54%{opacity:1;} 60%,100%{opacity:0;}}

/* the locked-rooms line holds while shared; the revoke line replaces it */
.diagram-anim.play .ci-private{animation:ci-open 13s ease-out 5.8s infinite;}
.diagram-anim.play .ci-revoke{animation:ci-late 13s ease-out .3s infinite;}
@keyframes ci-late{0%,84%{opacity:0;} 87%,95%{opacity:1;} 99%,100%{opacity:0;}}
/* the shared room's own lock comes back on when the circle closes */
.diagram-anim.play .ci-lock[data-l="1"]{animation:ci-relock 13s ease-out .3s infinite;}
@keyframes ci-relock{0%,38%{opacity:1;} 42%,82%{opacity:0;} 86%,100%{opacity:1;}}

@media (prefers-reduced-motion:reduce){
  .diagram-anim .ci-you,.diagram-anim .ci-them,.diagram-anim .ci-room,
  .diagram-anim .ci-spoke,.diagram-anim .ci-mech,.diagram-anim .ci-circle,
  .diagram-anim .ci-accept,.diagram-anim .ci-private{opacity:1;}
  .diagram-anim .ci-invite,.diagram-anim .ci-revoke{opacity:0;}
  .diagram-anim .ci-lock[data-l="1"]{opacity:0;}
}

/* -------------------------------------------------------------------------
   Sneak-preview corner ribbon. Anchored to the masthead (which is already
   position:relative + overflow:hidden), so it clips to the hero and scrolls
   away with it rather than pinning over the page.
   Sits BELOW the sticky nav (z-index 2 against the nav's 50) so it passes
   under the bar instead of covering the logo.
   ⚠ Temporary — it comes off when the preview graduates.
   ------------------------------------------------------------------------- */
.ribbon{
  position:absolute;top:0;left:0;width:300px;height:300px;
  overflow:hidden;pointer-events:none;z-index:2;
}
.ribbon span{
  position:absolute;display:block;width:440px;
  /* 4.5% of the WIDTH, so the band scales with the ribbon on small screens */
  padding:13px 0;top:78px;left:-104px;
  transform:rotate(-45deg);transform-origin:center;
  background:#D65E0A;color:#FCF6EA;
  font-family:"Rotis Serif",Georgia,serif;font-size:26px;line-height:1.06;
  letter-spacing:-.01em;text-align:center;
  box-shadow:0 6px 18px rgba(42,32,20,.18);
}
@media (max-width:860px){
  .ribbon{width:210px;height:210px;}
  .ribbon span{width:320px;top:52px;left:-78px;padding:9px 0;font-size:18px;}
}
/* A decorative flag, not motion anyone needs — but it is a solid block of
   colour, so honour the setting by dropping the shadow's weight only. */
@media (prefers-reduced-motion:reduce){.ribbon span{box-shadow:none;}}

/* -------------------------------------------------------------------------
   Small screens. Two things break at phone width: the corner ribbon lands on
   the logo and the headline (the hero content starts in that same corner),
   and the nav's six items wrap to a second row that then eats the viewport
   permanently, because the bar is sticky.
   ------------------------------------------------------------------------- */
.preview-pill{display:none;}

@media (max-width:820px){
  /* The diagonal has nowhere to go on a narrow hero — every corner is
     occupied. Swap it for a pill in the normal flow, which cannot collide. */
  .ribbon{display:none;}
  .preview-pill{
    display:inline-block;margin-bottom:16px;padding:5px 13px;border-radius:999px;
    background:#D65E0A;color:#FCF6EA;
    font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.14em;
    text-transform:uppercase;font-weight:500;
  }

  /* One row that scrolls, rather than two rows that stay. Every item stays
     reachable — nothing is hidden behind a breakpoint — and the sticky bar
     keeps a single 60px height. */
  .nav-links{
    flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;
    -webkit-overflow-scrolling:touch;margin-left:12px;
  }
  .nav-links::-webkit-scrollbar{display:none;}
  .nav-links a{padding:7px 9px;flex:0 0 auto;}
  /* Capabilities is a hover dropdown — useless on touch, and its trigger is a
     real link, so let the tap navigate instead of opening nothing. */
  .nav-dd-menu{display:none !important;}
}

@media (max-width:560px){
  .nav-inner{gap:10px;}
  .nav-links a{font-size:11.5px;padding:7px 8px;}
}

@media (max-width:820px){
  /* The hero is min-height:82vh and vertically centred, which on a phone puts
     the mark hard under the sticky bar. Give it room and let the hero grow
     instead of centring in a viewport it no longer fits. */
  header.top{min-height:auto;padding:38px 0 44px;align-items:flex-start;}
  .hero-mark{margin-bottom:18px;}
}

/* Screenshots of real output — lifted off the page so they read as artefacts
   sitting ON it rather than as flat inserts. Diagrams keep no shadow: they are
   drawings in the page, not objects on it. */
.diagram.shot img{
  border-radius:8px;
  box-shadow:0 18px 40px rgba(42,32,20,.16), 0 3px 10px rgba(42,32,20,.10);
}

.media-row{display:grid;grid-template-columns:320px 1fr;gap:40px;align-items:center;margin-top:26px;}
.media-row .diagram{margin:0;}
.media-row p{margin:0;}
.diagram figcaption{font-size:13px;color:var(--muted);padding:14px 4px 6px;font-style:italic;text-align:center;}

/* =========================================================================
   Split-plane paths (Security)
   ========================================================================= */
.paths{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-top:24px;}
.paths + p{margin-top:26px;}
.path{border:1px solid var(--line);border-radius:6px;padding:22px 22px 24px;background:var(--card);}
.path.a{border-top:3px solid var(--gold);}
.path.b{border-top:3px solid var(--teal);}
.path .label{
  font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.1em;text-transform:uppercase;
  margin-bottom:10px;font-weight:500;
}
.path.a .label{color:var(--gold);}
.path.b .label{color:var(--teal);}
.path h3{margin-bottom:0;font-size:17px;font-family:"Rotis Serif",Georgia,serif;font-weight:500;letter-spacing:-.01em;line-height:1.2;}
.path h3 + p{margin-top:12px;}

/* =========================================================================
   Claim / CTA
   ========================================================================= */
.callout{background:var(--gold-soft);border:1px solid var(--gold-line);border-radius:6px;padding:26px 26px;margin-top:8px;max-width:none;}
.callout h2{margin-top:0;}
.callout p{color:#6b3f12;margin:0 0 20px;font-size:15.5px;max-width:60ch;}

/* Footnote — a muted aside tied to a * marker in body copy */
.footnote{font-size:12.5px;color:var(--muted);max-width:66ch;margin:18px 0 4px;line-height:1.55;}
.fn{color:var(--gold);font-weight:600;}
.btn-claim{
  display:inline-block;background:var(--ink);color:#fff;text-decoration:none;
  font-family:"IBM Plex Mono",monospace;font-size:13px;letter-spacing:.04em;
  padding:13px 22px;border-radius:6px;
}
.btn-claim:hover{background:#3a2c1a;}

/* =========================================================================
   Footer
   ========================================================================= */
/* Rich site footer — logo + tagline, link columns, the Agent-Standard line. */
.site-foot{padding:56px 0 64px;}
.site-foot .foot-top{display:grid;grid-template-columns:1.5fr 1.7fr 0.8fr;gap:48px;}
.foot-brand .foot-mark{height:30px;width:auto;display:block;margin-bottom:16px;}
.foot-tag{font-size:13.5px;color:var(--muted);max-width:34ch;line-height:1.5;margin:0;}
.foot-col .k{font-family:"IBM Plex Mono",monospace;font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:13px;}
.foot-col ul{list-style:none;margin:0;padding:0;font-size:13.5px;}
.foot-col li{margin-bottom:8px;}
.foot-col a{color:var(--ink);text-decoration:none;}
.foot-col a:hover{color:var(--gold);}
.foot-why ul{display:grid;grid-template-columns:1fr 1fr;gap:8px 26px;}
.site-foot .foot-fine{margin-top:40px;padding-top:22px;border-top:1px solid var(--line);}
.foot-gem{font-size:12.5px;color:var(--ink-soft);max-width:82ch;line-height:1.55;margin:0 0 8px;}
.foot-gem a{color:var(--ink);}
.foot-copy{font-size:12px;color:var(--muted);margin:0;}
.foot-copy a{color:var(--muted);}
@media (max-width:760px){.site-foot .foot-top{grid-template-columns:1fr;gap:32px;}}

/* FAQ — answer-first Q&A blocks (also emitted as FAQPage structured data). */
.faq{max-width:80ch;margin-top:8px;}
.faq-item{padding:22px 0;border-top:1px solid var(--line);}
.faq-item:first-child{border-top:none;padding-top:6px;}
.faq-q{font-family:"Rotis Serif",Georgia,serif;font-weight:500;font-size:19px;color:var(--ink);margin:0 0 8px;letter-spacing:-.01em;line-height:1.25;}
.faq-a{margin:0;color:var(--ink-soft);line-height:1.6;max-width:76ch;}
/* Accordion: <details> so the answers stay crawlable without the scroll cost.
   No JS — the disclosure is native, which also keeps it keyboard-accessible. */
summary.faq-q{cursor:pointer;list-style:none;display:flex;gap:12px;align-items:baseline;}
summary.faq-q::-webkit-details-marker{display:none;}
summary.faq-q::before{content:"+";color:var(--gold);font-family:"IBM Plex Mono",monospace;font-size:16px;line-height:1.4;}
details[open] > summary.faq-q::before{content:"\2212";}
details.faq-item[open]{padding-bottom:26px;}

/* Mid-page conversion break — one line and a button, so the long scroll has a
   door in the middle instead of only at the end. */
.cta-inline{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:20px;padding:22px 24px;border:1px solid var(--gold-line);
  background:var(--gold-soft);border-radius:6px;
}
.cta-inline p{margin:0;color:#6b3f12;font-size:15.5px;max-width:52ch;}

/* =========================================================================
   Responsive
   ========================================================================= */
@media (max-width:760px){
  .pillars{grid-template-columns:1fr;}
  header.top{min-height:74vh;}
}
@media (max-width:680px){
  .principles{grid-template-columns:1fr;}
  .paths{grid-template-columns:1fr;}
  .media-row{grid-template-columns:1fr;gap:20px;}
  .meta div{border-right:none;margin-right:0;}
  .nav-inner{height:auto;padding:10px 16px;flex-wrap:wrap;gap:10px;}
  .nav-links{gap:2px;}
  .nav-links a{padding:6px 8px;font-size:11.5px;}
}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto;}}
:focus-visible{outline:2px solid var(--gold);outline-offset:2px;}

/* --- Sign-in modal (shared auth-modal), warm-themed --------------------- */
/* The modal markup lives in shared/_auth_modal; its chrome normally comes from
   the app's application.css, which the warm layout doesn't load. Ported here in
   the warm palette: transparent backdrop + blur, cream panel. */
.auth-modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);margin:0;border:none;padding:0;background:transparent;max-width:26rem;width:calc(100% - 2rem);border-radius:1rem;}
.auth-modal::backdrop{background:rgba(244,236,221,.6);backdrop-filter:blur(8px);}
.auth-modal-panel{position:relative;padding:2.25rem;background:var(--card);border:1px solid var(--line);border-radius:1rem;box-shadow:0 24px 60px rgba(42,32,20,.22);}
.auth-modal-close{position:absolute;top:1rem;right:1rem;display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border-radius:9999px;color:var(--muted);background:transparent;border:none;cursor:pointer;transition:background-color .15s ease,color .15s ease;}
.auth-modal-close:hover{background:var(--gold-soft);color:var(--ink);}
.auth-modal-title{font-size:1.5rem;font-weight:700;letter-spacing:-.01em;color:var(--ink);margin:0;}
.auth-modal-subtitle{margin-top:.375rem;font-size:.875rem;color:var(--muted);}
.auth-provider-btn{display:flex;align-items:center;justify-content:center;gap:.75rem;width:100%;padding:.75rem 1rem;border:1px solid var(--line);border-radius:.625rem;font-size:.875rem;font-weight:500;color:var(--ink-soft);background:var(--card);text-decoration:none;transition:background-color .15s ease,border-color .15s ease;}
.auth-provider-btn:hover{background:var(--gold-soft);border-color:var(--gold-line);}
/* minimal utilities the shared sign-in-options partial expects (no Tailwind here) */
.auth-modal .space-y-3>*+*{margin-top:.75rem;}
.auth-modal .mt-5{margin-top:1.25rem;}
.auth-modal .mt-6{margin-top:1.5rem;}
.auth-modal .text-xs{font-size:.75rem;line-height:1rem;}
.auth-modal .text-center{text-align:center;}
.auth-modal .text-surface-400{color:var(--muted);}
.auth-modal .w-5{width:1.25rem;}
.auth-modal .h-5{height:1.25rem;}
