/* ===== shared (inner pages) ===== */
/* ==== Durjeya site theme — ported from live template (Elementor tokens + recording) ==== */
:root{
  --bg:#0A0A0E; --card:#16171D; --card2:#1A1B23;
  --text:#fff; --muted:rgba(255,255,255,.66); --faint:rgba(255,255,255,.42);
  --line:rgba(255,255,255,.09);
  --vio:#7C3AED; --cy:#2EC5F6; --mag:#FF3EA5; --amber:#f5a623;
  --r:16px;
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{font-family:'Open Sans',sans-serif;background:var(--bg);color:var(--text);line-height:1.7;font-size:1rem;-webkit-font-smoothing:antialiased;overflow-x:hidden}
h1,h2,h3,h4{font-family:'Days One',sans-serif;font-weight:400;line-height:1.18;letter-spacing:.01em}
a{text-decoration:none;color:inherit}
img{max-width:100%}
.wrap{max-width:1140px;margin:0 auto;padding:0 24px}
section{padding:96px 0;position:relative}
.center{text-align:center}
.h2{font-size:3.125rem;margin-bottom:22px}
.sub{color:var(--muted);max-width:46em;margin:0 auto}
.gw-b{background:linear-gradient(90deg,#5b8cff,var(--cy));-webkit-background-clip:text;background-clip:text;color:transparent}
.gw-v{background:linear-gradient(90deg,var(--vio),var(--cy));-webkit-background-clip:text;background-clip:text;color:transparent}
.gw-m{background:linear-gradient(90deg,var(--mag),#c86bff);-webkit-background-clip:text;background-clip:text;color:transparent}

/* reveal animations — up / from-left / from-right (as in the live template) */
.reveal,.rv-l,.rv-r{opacity:0;transition:opacity .8s ease,transform .8s ease}
.reveal{transform:translateY(26px)}
.rv-l{transform:translateX(-64px)}
.rv-r{transform:translateX(64px)}
.reveal.on,.rv-l.on,.rv-r.on{opacity:1;transform:none}
.d1{transition-delay:.1s}.d2{transition-delay:.2s}.d3{transition-delay:.3s}
@media (prefers-reduced-motion: reduce){.reveal,.rv-l,.rv-r{opacity:1;transform:none;transition:none}}

/* buttons */
.btn{display:inline-block;padding:14px 30px;border-radius:7px;font-family:'Open Sans';font-weight:600;font-size:.95rem;transition:.25s;cursor:pointer;border:none;color:#fff}
.btn-g{background:linear-gradient(90deg,var(--vio) 0%,var(--cy) 100%)}
.btn-g:hover{filter:brightness(1.15);transform:translateY(-2px);box-shadow:0 10px 30px rgba(124,58,237,.4)}
.btn-o{border:1px solid rgba(255,255,255,.3)}
.btn-o:hover{border-color:var(--cy);color:var(--cy)}

/* header + mobile hamburger */
header.top{position:fixed;inset:0 0 auto;z-index:100;transition:.3s;padding:16px 0}
header.top.sc{background:rgba(10,10,14,.92);backdrop-filter:blur(12px);border-bottom:1px solid var(--line);padding:10px 0}
.nav-in{display:flex;align-items:center;justify-content:space-between;gap:16px}
.nav-in img{height:44px;background:#fff;padding:6px 12px;border-radius:7px;box-shadow:0 4px 14px rgba(0,0,0,.35)}
.menu{display:flex;gap:32px;font-size:.875rem;font-weight:600;letter-spacing:.06em}
.menu a:hover,.menu a.on{color:var(--cy)}
header .btn{height:44px;padding:0 24px;font-size:.85rem;display:inline-flex;align-items:center;justify-content:center}
.burger{display:none;background:none;border:1px solid var(--line);border-radius:8px;color:#fff;font-size:1.3rem;width:42px;height:42px;cursor:pointer}
.m-menu{display:none;position:fixed;top:64px;left:0;right:0;background:rgba(10,10,14,.98);backdrop-filter:blur(14px);border-bottom:1px solid var(--line);z-index:99;padding:18px 24px}
.m-menu a{display:block;padding:13px 4px;font-weight:600;border-bottom:1px solid rgba(255,255,255,.06)}
.m-menu.open{display:block}

/* page hero (inner pages) */
.page-hero{padding:160px 0 80px;text-align:center;background:
  radial-gradient(560px 360px at 6% -4%,rgba(124,58,237,.32),transparent 65%),
  radial-gradient(560px 360px at 94% 0%,rgba(124,58,237,.26),transparent 65%),
  var(--bg);position:relative}
.page-hero::before{content:"";position:absolute;inset:0;background-image:linear-gradient(rgba(255,255,255,.04) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.04) 1px,transparent 1px);background-size:56px 56px;mask-image:radial-gradient(75% 70% at 50% 30%,#000 30%,transparent 80%);pointer-events:none}
.page-hero .wrap{position:relative;z-index:2}
.page-hero h1{font-size:2.9rem;margin:14px 0 20px}
.page-hero .lead{color:var(--muted);max-width:44em;margin:0 auto}
.eyebrow{display:inline-block;font-size:.8rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--cy)}

/* cards */
.cards4{display:grid;grid-template-columns:repeat(4,1fr);gap:22px;margin-top:56px}
.cards2{display:grid;grid-template-columns:1fr 1fr;gap:22px;margin-top:48px}
.fcard{background:var(--card);border:1px solid rgba(255,255,255,.05);border-radius:var(--r);padding:34px 26px;transition:.3s}
.fcard.center{text-align:center}
.fcard:hover{transform:translateY(-6px);border-color:rgba(124,58,237,.5);box-shadow:0 20px 44px rgba(0,0,0,.5)}
.fcard img{width:84px;height:84px;margin-bottom:20px;filter:drop-shadow(0 0 22px rgba(124,58,237,.45))}
.fcard h3{font-size:1.35rem;margin-bottom:12px}
.fcard p{font-size:.9rem;color:var(--muted)}
.badge{display:inline-block;font-size:.72rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:8px 16px;border-radius:7px;border:1px solid var(--line);background:rgba(22,23,29,.75);color:var(--muted);margin:4px 4px 0 0}
.badge.gold{border-color:rgba(245,166,35,.5);color:var(--amber)}
.chip{display:inline-flex;font-size:.72rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;border-radius:99px;padding:6px 14px;margin-bottom:16px}
.chip.c1{color:#ffd28a;background:rgba(245,166,35,.14)}
.chip.c2{color:#c3b3ff;background:rgba(124,58,237,.18)}
.chip.c3{color:#8fe4ff;background:rgba(46,197,246,.14)}
.chip.c4{color:#ff9fce;background:rgba(255,62,165,.14)}

/* two-column with gradient-outline frame */
.sm{display:grid;grid-template-columns:1fr 1fr;gap:70px;align-items:center}
.sm .txt h2{font-size:2.4rem;margin-bottom:18px}
.sm .txt p{color:var(--muted);margin-bottom:14px}
.frame{position:relative;margin:26px}
.frame::before{content:"";position:absolute;inset:-26px 26px 26px -26px;border-radius:26px;padding:2px;background:linear-gradient(120deg,var(--cy),var(--mag));-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;pointer-events:none}
.frame.rt::before{inset:-26px -26px 26px 26px}
.frame img{position:relative;border-radius:6px;display:block;width:100%;object-fit:cover;aspect-ratio:4/3}

/* accordion */
.acc details{margin-bottom:8px;padding:14px 6px;border-bottom:1px solid rgba(255,255,255,.06)}
.acc summary{cursor:pointer;list-style:none;display:flex;gap:14px;align-items:center;font-weight:700;font-size:.98rem}
.acc summary::before{content:"▾";flex:none;width:24px;height:24px;border-radius:6px;background:linear-gradient(135deg,var(--vio),var(--mag));display:flex;align-items:center;justify-content:center;font-size:.7rem;transition:.2s}
.acc details[open] summary::before{transform:rotate(180deg)}
.acc details p{margin:12px 0 0 38px;color:var(--muted);font-size:.9rem;max-width:46em}

/* checklist */
.checks{display:grid;gap:12px;margin:20px 0}
.checks div{display:flex;gap:12px;align-items:flex-start;font-size:.95rem;color:var(--muted)}
.checks .ok{flex:none;width:22px;height:22px;border-radius:6px;background:linear-gradient(135deg,var(--vio),var(--cy));color:#fff;display:flex;align-items:center;justify-content:center;font-size:.7rem;font-weight:700;margin-top:3px}
.checks b{color:#fff}

/* fact card */
.fact{border:1px solid var(--line);border-left:4px solid var(--vio);border-radius:12px;padding:20px 24px;background:var(--card);font-size:.9rem;color:var(--muted);margin-bottom:14px}
.fact b{color:#fff}

/* galleries */
.gallery{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:48px}
.gtile{aspect-ratio:4/3;border:1px dashed rgba(255,255,255,.22);border-radius:14px;background:var(--card);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;color:var(--faint);font-size:.78rem;text-align:center;padding:14px;transition:.25s}
.gtile:hover{border-color:var(--cy);color:var(--cy)}
.gtile .gi{font-size:28px}
.gtile img{width:100%;height:100%;object-fit:cover;border-radius:12px}

/* timeline */
.timeline{margin-top:48px;border-left:2px solid rgba(255,255,255,.12);padding-left:30px;display:grid;gap:30px}
.tstep{position:relative}
.tstep::before{content:"";position:absolute;left:-37px;top:6px;width:12px;height:12px;border-radius:50%;background:linear-gradient(135deg,var(--vio),var(--cy));box-shadow:0 0 14px rgba(124,58,237,.7)}
.tstep h3{font-size:1.05rem;margin-bottom:6px}
.tstep p{font-size:.88rem;color:var(--muted)}
.tstep .tyear{font-size:.7rem;font-weight:700;letter-spacing:.1em;color:var(--cy);text-transform:uppercase}

/* posts */
.posts{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;margin-top:52px}
.post{background:var(--card);border:1px solid rgba(255,255,255,.05);border-radius:var(--r);overflow:hidden;transition:.3s;display:block}
.post:hover{transform:translateY(-6px);border-color:rgba(46,197,246,.5)}
.post .th{height:150px;display:flex;align-items:flex-end;justify-content:flex-end;padding:16px;font-size:2rem}
.th.a{background:linear-gradient(135deg,#2a1060,#7C3AED)}
.th.b{background:linear-gradient(135deg,#083a4d,#2EC5F6)}
.th.c{background:linear-gradient(135deg,#4d0e33,#FF3EA5)}
.post .bd{padding:24px}
.post .mt{font-size:.7rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-bottom:10px}
.post h3{font-size:1.05rem;line-height:1.45;margin-bottom:10px}
.post p{font-size:.85rem;color:var(--muted)}

/* article prose */
.article{max-width:760px;margin:0 auto;padding:0 24px}
.article .meta{font-size:.75rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--cy);margin-bottom:14px}
.article h1{font-size:2.4rem;margin-bottom:22px}
.article h2{font-size:1.5rem;margin:38px 0 14px}
.article p{color:var(--muted);margin-bottom:18px;font-size:1.02rem}
.article b,.article strong{color:#fff}
.article blockquote{border-left:4px solid var(--mag);padding:14px 20px;background:var(--card);border-radius:0 12px 12px 0;color:#fff;font-family:'Days One';font-size:1.05rem;margin:24px 0}
.article .sources{margin-top:44px;padding-top:22px;border-top:1px solid var(--line);font-size:.82rem;color:var(--faint)}
.article .sources a{color:var(--cy);text-decoration:underline}
.share{display:flex;gap:10px;margin-top:30px;flex-wrap:wrap}
.share a{border:1px solid var(--line);border-radius:8px;padding:9px 16px;font-size:.8rem;font-weight:600;transition:.2s}
.share a:hover{border-color:var(--cy);color:var(--cy)}

/* forms */
.cform input,.cform select,.cform textarea{width:100%;padding:13px 16px;border-radius:8px;border:none;background:#fff;color:#1c1c28;font-family:'Open Sans';font-size:.9rem;margin-bottom:14px}
.cform textarea{min-height:120px;resize:vertical}
.cform ::placeholder{color:#8a8a98}
.cform button{width:100%;padding:14px;border:none;border-radius:8px;background:linear-gradient(90deg,var(--vio),var(--cy));color:#fff;font-weight:700;font-size:1rem;cursor:pointer;transition:.25s}
.cform button:hover{filter:brightness(1.15)}
.fnote{font-size:.75rem;color:var(--faint);margin-top:10px}
.sub-row{display:flex;gap:12px;max-width:520px;margin:0 auto}
.sub-row input{flex:1;padding:14px 16px;border-radius:8px;border:none;background:#fff;color:#1c1c28;font-family:'Open Sans'}
.sub-row .btn{white-space:nowrap}

/* CTA band */
.cta{background:linear-gradient(180deg,#170a22 0%,#0e0714 100%);text-align:center;border-block:1px solid var(--line)}
.cta h2{font-size:2.4rem;margin-bottom:16px}
.cta p{color:var(--muted);max-width:40em;margin:0 auto 30px}

/* footer */
footer{padding:56px 0 40px;background:#0c0712;border-top:1px solid var(--line);color:var(--muted);font-size:.9rem}
.frow{display:grid;grid-template-columns:1.2fr 1fr .8fr;gap:44px;align-items:start}
.frow img{height:44px;margin-bottom:14px;background:#fff;padding:6px 12px;border-radius:7px}
.socials{display:flex;gap:12px;justify-content:flex-end}
.socials a{width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;transition:.2s;font-size:.9rem}
.socials a:hover{transform:translateY(-3px)}
.so-f{background:#1877F2}.so-x{background:#111;border:1px solid #333}.so-i{background:linear-gradient(45deg,#f09433,#e6683c,#dc2743,#cc2366,#bc1888)}.so-y{background:#FF0000}
.fbot{margin-top:36px;padding-top:22px;border-top:1px solid rgba(255,255,255,.07);display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px;font-size:.78rem;color:var(--faint)}

/* Floating WhatsApp affordance. Was a 58px pure-#25d366 disc carrying a speech-balloon
   EMOJI and a 30px green glow - it read as a sticker on a dark, restrained site, and the
   emoji rendered differently per platform. Now: the real WhatsApp mark as inline SVG,
   brand gradient, a neutral shadow instead of a coloured halo, and a label that slides
   out on hover so the control explains itself. Transform/opacity only. */
.wa{position:fixed;bottom:24px;right:24px;height:52px;min-width:52px;border-radius:26px;
  background:linear-gradient(145deg,#25d366,#12a150);display:flex;align-items:center;
  justify-content:center;gap:0;padding:0 15px;z-index:300;text-decoration:none;
  box-shadow:0 6px 20px rgba(0,0,0,.45),0 0 0 1px rgba(255,255,255,.10) inset;
  transition:box-shadow .22s ease,transform .22s ease}
.wa svg{width:26px;height:26px;flex:none;display:block;fill:#fff}
.wa span{max-width:0;overflow:hidden;white-space:nowrap;color:#fff;font-weight:700;
  font-size:.86rem;font-family:'Open Sans';opacity:0;
  transition:max-width .28s ease,opacity .2s ease,margin-left .28s ease}
.wa:hover,.wa:focus-visible{transform:translateY(-2px);box-shadow:0 10px 26px rgba(0,0,0,.5),0 0 0 1px rgba(255,255,255,.18) inset}
.wa:hover span,.wa:focus-visible span{max-width:170px;opacity:1;margin-left:10px}
.wa:focus-visible{outline:3px solid var(--cy);outline-offset:3px}
@media(max-width:600px){ .wa{bottom:16px;right:16px;height:48px;min-width:48px;padding:0 11px}
  .wa svg{width:24px;height:24px} .wa:hover span{max-width:0;opacity:0;margin-left:0} }
@media(prefers-reduced-motion:reduce){ .wa,.wa span{transition:none} }

@media(max-width:920px){
  .h2{font-size:2.1rem}
  .page-hero h1{font-size:2rem}
  .article h1{font-size:1.7rem}
  .cards4{grid-template-columns:1fr 1fr}
  .cards2,.sm,.posts,.frow{grid-template-columns:1fr}
  .gallery{grid-template-columns:1fr 1fr}
  .menu,header .btn-g{display:none}
  .burger{display:block}
  section{padding:70px 0}
  .socials{justify-content:flex-start}
  .sub-row{flex-direction:column}
}


/* ===== homepage ===== */

/* ==== Durjeya template port v2 — tokens from Elementor CSS + UI/UX from screen recording ==== */
:root{
  --bg:#0A0A0E; --card:#16171D; --card2:#1A1B23;
  --text:#fff; --muted:rgba(255,255,255,.66); --faint:rgba(255,255,255,.50);
  --line:rgba(255,255,255,.09);
  --vio:#7C3AED; --cy:#2EC5F6; --mag:#FF3EA5; --amber:#f5a623;
  --grad:linear-gradient(90deg,var(--vio),var(--cy));
  --r:16px;
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{font-family:'Open Sans',sans-serif;background:var(--bg);color:var(--text);line-height:1.7;font-size:1rem;-webkit-font-smoothing:antialiased;overflow-x:hidden}
h1,h2,h3,h4{font-family:'Days One',sans-serif;font-weight:400;line-height:1.18;letter-spacing:.01em}
a{text-decoration:none;color:inherit}
img{max-width:100%}
.wrap{max-width:1140px;margin:0 auto;padding:0 24px}
section{padding:100px 0;position:relative}
.center{text-align:center}
.h2{font-size:3.125rem;margin-bottom:22px}
.sub{color:var(--muted);max-width:46em;margin:0 auto}
.gw-b{background:linear-gradient(90deg,#5b8cff,var(--cy));-webkit-background-clip:text;background-clip:text;color:transparent}
.gw-v{background:linear-gradient(90deg,var(--vio),var(--cy));-webkit-background-clip:text;background-clip:text;color:transparent}
.gw-m{background:linear-gradient(90deg,var(--mag),#c86bff);-webkit-background-clip:text;background-clip:text;color:transparent}
.reveal,.rv-l,.rv-r{opacity:0;transition:opacity .8s ease,transform .8s ease}
.reveal{transform:translateY(24px)}
.rv-l{transform:translateX(-64px)}
.rv-r{transform:translateX(64px)}
.reveal.on,.rv-l.on,.rv-r.on{opacity:1;transform:none}
.d1{transition-delay:.1s}.d2{transition-delay:.2s}.d3{transition-delay:.3s}
@media (prefers-reduced-motion: reduce){.reveal,.rv-l,.rv-r{opacity:1;transform:none;transition:none}}
.burger{display:none;background:none;border:1px solid var(--line);border-radius:8px;color:#fff;font-size:1.3rem;width:42px;height:42px;cursor:pointer}
.m-menu{display:none;position:fixed;top:64px;left:0;right:0;background:rgba(10,10,14,.98);backdrop-filter:blur(14px);border-bottom:1px solid var(--line);z-index:99;padding:18px 24px}
.m-menu a{display:block;padding:13px 4px;font-weight:600;border-bottom:1px solid rgba(255,255,255,.06)}
.m-menu.open{display:block}

/* gradient buttons (from recording) */
.btn{display:inline-block;padding:14px 30px;border-radius:7px;font-family:'Open Sans';font-weight:600;font-size:.95rem;transition:.25s;cursor:pointer;border:none;color:#fff}
.btn-g{background:linear-gradient(90deg,var(--vio) 0%,var(--cy) 100%)}
.btn-g:hover{filter:brightness(1.15);transform:translateY(-2px);box-shadow:0 10px 30px rgba(124,58,237,.4)}
.btn-o{border:1px solid rgba(255,255,255,.3)}
.btn-o:hover{border-color:var(--cy);color:var(--cy)}

/* header */
header.top{position:fixed;inset:0 0 auto;z-index:100;transition:.3s;padding:16px 0}
header.top.sc{background:rgba(10,10,14,.92);backdrop-filter:blur(12px);border-bottom:1px solid var(--line);padding:10px 0}
.nav-in{display:flex;align-items:center;justify-content:space-between;gap:16px}
.nav-in img{height:44px;background:#fff;padding:6px 12px;border-radius:7px;box-shadow:0 4px 14px rgba(0,0,0,.35)}
.menu{display:flex;gap:34px;font-size:.875rem;font-weight:600;letter-spacing:.06em}
.menu a:hover{color:var(--cy)}
header .btn{height:44px;padding:0 24px;font-size:.85rem;display:inline-flex;align-items:center;justify-content:center}

/* hero — dark textured bg + grid + purple corner glows (from recording) */
.hero{min-height:96svh;display:flex;align-items:center;text-align:center;padding:170px 0 110px;background:
  radial-gradient(560px 360px at 6% -4%,rgba(124,58,237,.32),transparent 65%),
  radial-gradient(560px 360px at 94% 0%,rgba(124,58,237,.26),transparent 65%),
  radial-gradient(420px 300px at 50% 110%,rgba(46,197,246,.12),transparent 70%),
  var(--bg)}
.hero::before{content:"";position:absolute;inset:0;background-image:linear-gradient(rgba(255,255,255,.04) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.04) 1px,transparent 1px);background-size:56px 56px;mask-image:radial-gradient(75% 65% at 50% 35%,#000 30%,transparent 80%);pointer-events:none}
.hero .wrap{position:relative;z-index:2}
.hero .hero-kicker{font-family:'Open Sans';font-weight:600;font-size:1rem;margin-bottom:18px}
.hero h1{font-size:3.5rem;max-width:17em;margin:0 auto 34px}
.hero .btns{display:flex;gap:16px;justify-content:center;flex-wrap:wrap;margin-bottom:38px}
/* avatar capsule with gradient border (from recording) */
.cap{display:inline-flex;border-radius:999px;padding:1.5px;background:linear-gradient(90deg,var(--cy),var(--mag))}
.cap .in{display:flex;align-items:center;gap:14px;background:#0d0d13;border-radius:999px;padding:12px 32px 12px 14px;font-size:.95rem;color:var(--muted)}
.cap img{height:78px}
.cap .dot{width:6px;height:6px;border-radius:50%;background:#fff;opacity:.7}
.badges{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-top:30px}
/* hero entrance choreography (load-in, like the live theme) */
@keyframes heroIn{from{opacity:0;transform:translateY(34px)}to{opacity:1;transform:none}}
.hero .wrap>*{opacity:0;animation:heroIn 1s cubic-bezier(.2,.7,.2,1) both}
.hero .wrap>*:nth-child(1){animation-delay:.1s}
.hero .wrap>*:nth-child(2){animation-delay:.28s}
.hero .wrap>*:nth-child(3){animation-delay:.46s}
.hero .wrap>*:nth-child(4){animation-delay:.64s}
.hero .wrap>*:nth-child(5){animation-delay:.82s}
@keyframes capbob{0%,100%{transform:translateY(0)}50%{transform:translateY(-8px)}}
.cap{animation:heroIn 1s .64s cubic-bezier(.2,.7,.2,1) both,capbob 6s 2.2s ease-in-out infinite}
@media (prefers-reduced-motion: reduce){.hero .wrap>*,.cap{animation:none;opacity:1}}

/* animated vault-to-desk relay */
.jchain{position:relative;z-index:2;display:flex;align-items:stretch;max-width:1020px;margin:0 auto}
.jn{flex:1;background:var(--card);border:1px solid rgba(255,255,255,.08);border-radius:16px;padding:24px 14px;text-align:center;transition:.3s}
.jn:hover{transform:translateY(-4px);border-color:rgba(124,58,237,.5)}
.jn .jic{font-size:28px;margin-bottom:10px}
.jn b{font-family:'Days One';font-weight:400;font-size:.9rem;display:block;color:#fff}
.jn span{font-size:.68rem;color:var(--faint);display:block;margin-top:6px;letter-spacing:.04em}
.jn .tagp{display:inline-block;margin-top:10px;font-size:.6rem;font-weight:700;letter-spacing:.08em;padding:3px 10px;border-radius:99px;background:rgba(245,166,35,.14);color:var(--amber)}
.jn .tagp.no{background:rgba(255,255,255,.06);color:var(--faint)}
.jseg{width:64px;flex:none;align-self:center;height:2px;background:rgba(255,255,255,.12);position:relative;overflow:visible}
.jseg i{position:absolute;top:-6px;left:0;width:13px;height:13px;border-radius:4px;background:linear-gradient(135deg,var(--cy),var(--vio));box-shadow:0 0 14px var(--cy);opacity:0;animation:capmove 9s linear infinite}
@keyframes capmove{0%{left:-2px;opacity:0}4%{opacity:1}29%{left:calc(100% - 11px);opacity:1}33%,100%{left:calc(100% - 11px);opacity:0}}
.seal-wrap{position:relative;display:inline-block;margin-top:10px;font-size:.65rem;font-weight:700;letter-spacing:.06em}
.seal-wrap .s-locked,.seal-wrap .s-open{display:inline-block;padding:3px 10px;border-radius:99px}
.seal-wrap .s-locked{background:rgba(255,62,165,.15);color:#ff9fce;animation:sLock 9s linear infinite}
.seal-wrap .s-open{position:absolute;left:0;top:0;background:rgba(43,228,154,.16);color:#7df0c0;opacity:0;animation:sOpen 9s linear infinite}
@keyframes sLock{0%,74%{opacity:1}80%,96%{opacity:0}100%{opacity:1}}
@keyframes sOpen{0%,74%{opacity:0}80%,96%{opacity:1}100%{opacity:0}}
.jcaption{text-align:center;margin-top:30px;color:var(--muted);font-size:.9rem;position:relative;z-index:2}
.badge{font-size:.72rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;padding:8px 16px;border-radius:7px;border:1px solid var(--line);background:rgba(22,23,29,.75);color:var(--muted)}
.badge.gold{border-color:rgba(245,166,35,.5);color:var(--amber)}

/* origin strip */
.origin{background:var(--card2);border-block:1px solid var(--line);padding:74px 0}
.origin .row{display:grid;grid-template-columns:1.15fr .85fr;gap:50px;align-items:center}
.origin h2{font-size:2rem;margin-bottom:14px}
.origin p{color:var(--muted);margin-bottom:16px}
.origin .logos{display:flex;gap:14px;align-items:center;flex-wrap:wrap}
.origin .logos img{height:58px;border-radius:8px;background:#fff;padding:6px 12px;object-fit:contain}
.qcard{background:var(--bg);border:1px solid var(--line);border-left:4px solid var(--mag);border-radius:var(--r);padding:30px}
.qcard blockquote{font-family:'Days One';font-size:1.15rem;line-height:1.55;margin-bottom:14px}
.qcard cite{font-style:normal;font-size:.8rem;color:var(--faint)}
.qcard .after{margin-top:16px;padding-top:16px;border-top:1px solid var(--line);font-size:.88rem;color:var(--muted)}
.qcard .after b{color:#fff}

/* features — dark cards, neon icon badges, centered (from recording) */
.cards4{display:grid;grid-template-columns:repeat(4,1fr);gap:22px;margin-top:60px}
.fcard{background:var(--card);border:1px solid rgba(255,255,255,.05);border-radius:var(--r);padding:38px 24px;text-align:center;transition:.3s}
.fcard:hover{transform:translateY(-6px);border-color:rgba(124,58,237,.5);box-shadow:0 20px 44px rgba(0,0,0,.5)}
.fcard img{width:84px;height:84px;margin-bottom:22px;filter:drop-shadow(0 0 22px rgba(124,58,237,.45))}
.fcard h3{font-size:1.5rem;margin-bottom:12px}
.fcard p{font-size:.9rem;color:var(--muted)}

/* orbit + parallax phone section (from recording) */
.orbit-sec{padding:140px 0 160px;overflow:hidden;background:var(--bg)}
.orbits{position:absolute;inset:0;pointer-events:none}
.orbits i{position:absolute;border:1px solid rgba(255,255,255,.07);border-radius:50%}
.orbits .o1{width:1400px;height:560px;left:50%;top:50%;transform:translate(-50%,-50%)}
.orbits .o2{width:1000px;height:400px;left:50%;top:50%;transform:translate(-50%,-50%) rotate(-4deg)}
.orbits .o3{width:640px;height:260px;left:50%;top:50%;transform:translate(-50%,-50%) rotate(3deg)}
.orbit-sec::before{content:"";position:absolute;width:520px;height:520px;border-radius:50%;background:radial-gradient(circle,rgba(124,58,237,.4),transparent 65%);left:-140px;top:10%}
.orbit-sec::after{content:"";position:absolute;width:460px;height:460px;border-radius:50%;background:radial-gradient(circle,rgba(124,58,237,.3),transparent 65%);right:-120px;top:30%}
.phone{position:relative;z-index:2;width:290px;margin:0 auto;border-radius:38px;border:7px solid #26262e;background:linear-gradient(180deg,#231a4e 0%,#12102b 100%);box-shadow:0 40px 90px rgba(0,0,0,.7);padding:24px 18px 28px;will-change:transform}
.phone .notch{width:110px;height:20px;border-radius:12px;background:#0a0a0e;margin:0 auto 18px}
.phone .tabs{display:flex;gap:16px;font-size:.72rem;color:var(--faint);margin-bottom:12px}
.phone .tabs b{color:#fff;border-bottom:2px solid var(--cy);padding-bottom:3px;font-weight:600}
.phone .datepill{display:inline-block;font-size:.62rem;border:1px solid var(--line);border-radius:6px;padding:3px 10px;color:var(--muted);margin-bottom:10px}
.phone svg{width:100%}
.phone .nums{display:flex;justify-content:space-between;font-family:'Days One';font-size:1.05rem;margin-top:12px;color:#fff;opacity:.9}

/* era */
.era{text-align:center}
.era h2{font-size:3.125rem;max-width:16em;margin:0 auto 18px}
.era p{color:var(--muted);max-width:44em;margin:0 auto 34px}

/* story/mission — offset gradient-outline frames (from recording) */
.sm{display:grid;grid-template-columns:1fr 1fr;gap:70px;align-items:center}
.sm .txt h2{font-size:2.7rem;margin-bottom:18px}
.sm .txt p{color:var(--muted);margin-bottom:14px}
.frame{position:relative;margin:26px}
.frame::before{content:"";position:absolute;inset:-26px 26px 26px -26px;border-radius:26px;padding:2px;background:linear-gradient(120deg,var(--cy),var(--mag));-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;pointer-events:none}
.frame.rt::before{inset:-26px -26px 26px 26px}
.frame img{position:relative;border-radius:6px;display:block;width:100%;object-fit:cover;aspect-ratio:4/3}

/* why — teal glow + gradient accordion toggles + phones (from recording) */
.why{background:radial-gradient(640px 460px at 28% 55%,rgba(0,150,160,.26),transparent 70%),var(--bg)}
.why .row{display:grid;grid-template-columns:1.05fr .95fr;gap:60px;align-items:center;margin-top:40px}
.why h2{font-size:2.7rem;letter-spacing:.03em}
.acc details{margin-bottom:8px;padding:14px 6px;border-bottom:1px solid rgba(255,255,255,.06)}
.acc summary{cursor:pointer;list-style:none;display:flex;gap:14px;align-items:center;font-weight:700;font-size:.98rem}
.acc summary::before{content:"▾";flex:none;width:24px;height:24px;border-radius:6px;background:linear-gradient(135deg,var(--vio),var(--mag));display:flex;align-items:center;justify-content:center;font-size:.7rem;transition:.2s}
.acc details[open] summary::before{transform:rotate(180deg)}
.acc details p{margin:12px 0 0 38px;color:var(--muted);font-size:.9rem;max-width:44em}
.phones{position:relative;min-height:420px}
.phones .blob{position:absolute;inset:8% 4%;background:radial-gradient(circle at 30% 60%,rgba(46,197,246,.5),transparent 60%),radial-gradient(circle at 70% 40%,rgba(255,62,165,.45),transparent 60%);filter:blur(30px);border-radius:50%}
.phones .ellipse{position:absolute;width:120%;height:70%;left:-10%;top:15%;border:1.5px solid;border-image:linear-gradient(90deg,var(--cy),var(--mag)) 1;border-radius:50%;transform:rotate(-8deg);opacity:.6}
.phones .phone{width:220px;position:absolute;left:14%;top:0;padding:16px 12px 20px;border-radius:28px}
.phones .p2{left:auto;right:10%;top:22%;width:180px;transform:rotate(6deg)}
.ring{width:120px;height:120px;border-radius:50%;margin:14px auto;background:conic-gradient(var(--cy) 0 70%,rgba(255,255,255,.12) 70% 100%);display:flex;align-items:center;justify-content:center}
.ring i{width:92px;height:92px;border-radius:50%;background:#171337;display:flex;align-items:center;justify-content:center;font-family:'Days One';font-style:normal;font-size:1.3rem}

/* insights */
.posts{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;margin-top:56px}
.post{background:var(--card);border:1px solid rgba(255,255,255,.05);border-radius:var(--r);overflow:hidden;transition:.3s;display:block}
.post:hover{transform:translateY(-6px);border-color:rgba(46,197,246,.5)}
.post .th{height:150px;display:flex;align-items:flex-end;justify-content:flex-end;padding:16px;font-size:2rem}
.th.a{background:linear-gradient(135deg,#2a1060,#7C3AED)}
.th.b{background:linear-gradient(135deg,#083a4d,#2EC5F6)}
.th.c{background:linear-gradient(135deg,#4d0e33,#FF3EA5)}
.post .bd{padding:24px}
.post .mt{font-size:.7rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);margin-bottom:10px}
.post h3{font-size:1.05rem;line-height:1.45;margin-bottom:10px}
.post p{font-size:.85rem;color:var(--muted)}

/* contact — purple-tinted, white inputs, gradient submit (from recording) */
.contact{background:linear-gradient(180deg,#170a22 0%,#0e0714 60%,var(--bg) 100%);text-align:center}
.contact h2{font-size:3.125rem;max-width:16em;margin:0 auto 44px}
.contact .row{display:grid;grid-template-columns:1fr 1fr;gap:60px;text-align:left;align-items:start;max-width:1000px;margin:0 auto}
.cform input,.cform select,.cform textarea{width:100%;padding:13px 16px;border-radius:8px;border:none;background:#fff;color:#1c1c28;font-family:'Open Sans';font-size:.9rem;margin-bottom:14px}
.cform textarea{min-height:120px;resize:vertical}
.cform ::placeholder{color:#8a8a98}
.cform button{width:100%;padding:14px;border:none;border-radius:8px;background:linear-gradient(90deg,var(--vio),var(--cy));color:#fff;font-weight:700;font-size:1rem;cursor:pointer;transition:.25s}
.cform button:hover{filter:brightness(1.15)}
.cmeta{display:grid;gap:16px;color:var(--muted);font-size:.95rem}
.cmeta b{color:#fff}
.cmeta iframe{width:100%;height:200px;border:1px solid var(--line);border-radius:var(--r);filter:invert(90%) hue-rotate(180deg)}
.fnote{font-size:.75rem;color:var(--faint);margin-top:10px}

/* footer (from recording: logo+©, address, circular colored socials) */
footer{padding:56px 0 40px;background:#0c0712;border-top:1px solid var(--line);color:var(--muted);font-size:.9rem}
.frow{display:grid;grid-template-columns:1.2fr 1fr .8fr;gap:44px;align-items:start}
.frow img{height:44px;margin-bottom:14px;background:#fff;padding:6px 12px;border-radius:7px}
.socials{display:flex;gap:12px;justify-content:flex-end}
.socials a{width:38px;height:38px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-weight:700;transition:.2s;font-size:.9rem;color:#fff}
.socials a:hover{transform:translateY(-3px)}
.so-f{background:#1877F2}.so-x{background:#111;border:1px solid #333}.so-i{background:linear-gradient(45deg,#f09433,#e6683c,#dc2743,#cc2366,#bc1888);}.so-y{background:#FF0000}
.fbot{margin-top:36px;padding-top:22px;border-top:1px solid rgba(255,255,255,.07);display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px;font-size:.78rem;color:var(--faint)}

/* Floating WhatsApp affordance. Was a 58px pure-#25d366 disc carrying a speech-balloon
   EMOJI and a 30px green glow - it read as a sticker on a dark, restrained site, and the
   emoji rendered differently per platform. Now: the real WhatsApp mark as inline SVG,
   brand gradient, a neutral shadow instead of a coloured halo, and a label that slides
   out on hover so the control explains itself. Transform/opacity only. */
.wa{position:fixed;bottom:24px;right:24px;height:52px;min-width:52px;border-radius:26px;
  background:linear-gradient(145deg,#25d366,#12a150);display:flex;align-items:center;
  justify-content:center;gap:0;padding:0 15px;z-index:300;text-decoration:none;
  box-shadow:0 6px 20px rgba(0,0,0,.45),0 0 0 1px rgba(255,255,255,.10) inset;
  transition:box-shadow .22s ease,transform .22s ease}
.wa svg{width:26px;height:26px;flex:none;display:block;fill:#fff}
.wa span{max-width:0;overflow:hidden;white-space:nowrap;color:#fff;font-weight:700;
  font-size:.86rem;font-family:'Open Sans';opacity:0;
  transition:max-width .28s ease,opacity .2s ease,margin-left .28s ease}
.wa:hover,.wa:focus-visible{transform:translateY(-2px);box-shadow:0 10px 26px rgba(0,0,0,.5),0 0 0 1px rgba(255,255,255,.18) inset}
.wa:hover span,.wa:focus-visible span{max-width:170px;opacity:1;margin-left:10px}
.wa:focus-visible{outline:3px solid var(--cy);outline-offset:3px}
@media(max-width:600px){ .wa{bottom:16px;right:16px;height:48px;min-width:48px;padding:0 11px}
  .wa svg{width:24px;height:24px} .wa:hover span{max-width:0;opacity:0;margin-left:0} }
@media(prefers-reduced-motion:reduce){ .wa,.wa span{transition:none} }

@media(max-width:920px){
  .hero h1{font-size:2.3rem}
  .h2,.era h2,.contact h2{font-size:2.1rem}
  .cards4{grid-template-columns:1fr 1fr}
  .origin .row,.sm,.why .row,.posts,.contact .row,.frow{grid-template-columns:1fr}
  .sm.flip .txt{order:-1}
  .menu,header .btn-g{display:none}
  .burger{display:block}
  section{padding:72px 0}
  .vidgrid{grid-template-columns:1fr !important}
  .jchain{flex-direction:column;gap:14px;max-width:420px}
  .jseg{width:2px;height:40px;align-self:center}
  .jseg i{animation:capmoveV 9s linear infinite;left:-6px;top:0}
  .socials{justify-content:flex-start}
  .phones{min-height:380px}
}
@keyframes capmoveV{0%{top:-2px;opacity:0}4%{opacity:1}29%{top:calc(100% - 11px);opacity:1}33%,100%{top:calc(100% - 11px);opacity:0}}

/* ============================================================
   ARTICLE VISUAL SYSTEM — added 29 Jul 2026
   Extends the existing tokens (--vio/--cy/--mag/--amber, Days One).
   Performance rules observed: transform/opacity only, no backdrop-filter,
   no filter:blur, no new infinite animations, no permanent will-change.
   ============================================================ */

/* reading progress bar */
.rprog{position:fixed;top:0;left:0;height:3px;width:0;z-index:400;
  background:linear-gradient(90deg,var(--vio),var(--cy),var(--mag));
  transform-origin:0 50%;transition:width .08s linear}

/* --- article hero --- */
.arthero{position:relative;padding:150px 0 54px;overflow:hidden;
  background:radial-gradient(120% 90% at 50% 0%,#270C37 0%,transparent 62%),var(--bg)}
.arthero::before{content:"";position:absolute;inset:0;
  background-image:linear-gradient(rgba(255,255,255,.04) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.04) 1px,transparent 1px);
  background-size:56px 56px;
  mask-image:radial-gradient(70% 65% at 50% 25%,#000 30%,transparent 80%);
  -webkit-mask-image:radial-gradient(70% 65% at 50% 25%,#000 30%,transparent 80%);
  pointer-events:none}
.arthero .wrap{position:relative;z-index:2;max-width:880px}
.arthero h1{font-size:3rem;line-height:1.14;margin:16px 0 0;max-width:17em}
.arthero .kicker{display:inline-flex;align-items:center;gap:9px;font-size:.72rem;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--cy)}
.arthero .kicker i{width:26px;height:2px;background:linear-gradient(90deg,var(--cy),var(--mag));
  display:inline-block;font-style:normal}
.artmeta{display:flex;flex-wrap:wrap;gap:10px 18px;align-items:center;margin-top:26px;
  font-size:.78rem;color:var(--faint)}
.artmeta .dot{width:4px;height:4px;border-radius:50%;background:var(--faint);display:inline-block}
.artmeta .tag{border:1px solid var(--line);border-radius:999px;padding:5px 13px;
  font-weight:700;letter-spacing:.08em;text-transform:uppercase;font-size:.68rem;color:var(--muted)}
/* accent rule under the hero, colour-keyed per article */
.artrule{height:4px;width:100%;background:linear-gradient(90deg,var(--vio),var(--cy),var(--mag))}
.artrule.a{background:linear-gradient(90deg,#2a1060,#7C3AED,#2EC5F6)}
.artrule.b{background:linear-gradient(90deg,#083a4d,#2EC5F6,#7C3AED)}
.artrule.c{background:linear-gradient(90deg,#4d0e33,#FF3EA5,#7C3AED)}
.artrule.d{background:linear-gradient(90deg,#4a3208,#f5a623,#FF3EA5)}

/* --- lead paragraph + drop cap --- */
.article .lead-p{font-size:1.22rem;line-height:1.62;color:#fff;margin-bottom:26px}
.article .lead-p::first-letter{float:left;font-family:'Days One',sans-serif;font-size:3.4rem;
  line-height:.86;padding:6px 12px 0 0;
  background:linear-gradient(180deg,var(--cy),var(--mag));
  -webkit-background-clip:text;background-clip:text;color:transparent}

/* --- "in short" key-takeaway card --- */
.keybox{position:relative;background:var(--card);border:1px solid var(--line);
  border-radius:14px;padding:24px 26px 22px 30px;margin:30px 0 34px;overflow:hidden}
.keybox::before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px;
  background:linear-gradient(180deg,var(--vio),var(--cy),var(--mag))}
.keybox h4{font-family:'Days One',sans-serif;font-size:.76rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--cy);margin-bottom:14px}
.keybox ul{list-style:none;display:grid;gap:11px}
.keybox li{position:relative;padding-left:24px;font-size:.95rem;color:var(--muted);line-height:1.6}
.keybox li::before{content:"";position:absolute;left:0;top:.55em;width:9px;height:9px;border-radius:3px;
  background:linear-gradient(135deg,var(--cy),var(--vio))}
.keybox li b{color:#fff}

/* --- stat callouts --- */
.statrow{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:32px 0}
.statrow.two{grid-template-columns:1fr 1fr}
.stat{background:var(--card2);border:1px solid var(--line);border-radius:14px;padding:22px 20px;
  text-align:center;transition:.25s}
.stat:hover{border-color:rgba(46,197,246,.45);transform:translateY(-3px)}
.stat .n{font-family:'Days One',sans-serif;font-size:1.9rem;line-height:1.1;
  background:linear-gradient(90deg,var(--cy),var(--mag));
  -webkit-background-clip:text;background-clip:text;color:transparent}
.stat .l{font-size:.76rem;color:var(--faint);margin-top:8px;line-height:1.5}

/* --- pull quote --- */
.pull{position:relative;margin:36px 0;padding:30px 30px 30px 62px;
  background:linear-gradient(135deg,rgba(124,58,237,.14),rgba(46,197,246,.07));
  border:1px solid var(--line);border-radius:16px}
.pull::before{content:"\201C";position:absolute;left:20px;top:6px;font-family:'Days One',sans-serif;
  font-size:4rem;line-height:1;
  background:linear-gradient(180deg,var(--cy),var(--mag));
  -webkit-background-clip:text;background-clip:text;color:transparent}
.pull p{font-family:'Days One',sans-serif;font-size:1.16rem;line-height:1.5;color:#fff;margin:0}
.pull cite{display:block;margin-top:12px;font-style:normal;font-size:.78rem;
  letter-spacing:.06em;text-transform:uppercase;color:var(--faint);font-family:'Open Sans',sans-serif}

/* --- numbered steps / milestones --- */
.steps{display:grid;gap:0;margin:32px 0;padding-left:34px;border-left:1px solid var(--line)}
.step{position:relative;padding:0 0 26px 8px}
.step:last-child{padding-bottom:0}
.step::before{content:"";position:absolute;left:-40px;top:4px;width:13px;height:13px;border-radius:50%;
  background:linear-gradient(135deg,var(--vio),var(--cy));box-shadow:0 0 14px rgba(124,58,237,.6)}
.step .sn{font-size:.7rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--cy)}
.step h4{font-family:'Days One',sans-serif;font-size:1.02rem;margin:5px 0 6px;color:#fff}
.step p{font-size:.92rem;color:var(--muted);margin:0}

/* --- then / now comparison --- */
.vs{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin:32px 0}
.vs .side{border:1px solid var(--line);border-radius:16px;padding:24px;background:var(--card)}
.vs .side.then{opacity:.9}
.vs .side.now{border-color:rgba(46,197,246,.4);
  background:linear-gradient(160deg,rgba(46,197,246,.09),var(--card))}
.vs .side h4{font-family:'Days One',sans-serif;font-size:.74rem;letter-spacing:.14em;
  text-transform:uppercase;margin-bottom:14px}
.vs .side.then h4{color:var(--faint)}
.vs .side.now h4{background:linear-gradient(90deg,var(--cy),var(--mag));
  -webkit-background-clip:text;background-clip:text;color:transparent}
.vs .side p{font-size:.92rem;color:var(--muted);margin:0}
.vs .side ul{list-style:none;display:grid;gap:9px}
.vs .side li{position:relative;padding-left:18px;font-size:.9rem;color:var(--muted);line-height:1.55}
.vs .side li::before{content:"";position:absolute;left:0;top:.6em;width:6px;height:6px;border-radius:50%;
  background:var(--cy)}
.vs .side.then li::before{background:var(--faint)}

/* --- callout / caveat panel --- */
.note{border:1px solid var(--line);border-left:3px solid var(--amber);border-radius:0 12px 12px 0;
  background:rgba(245,166,35,.06);padding:20px 24px;margin:30px 0}
.note h4{font-family:'Days One',sans-serif;font-size:.74rem;letter-spacing:.12em;text-transform:uppercase;
  color:var(--amber);margin-bottom:9px}
.note p{font-size:.92rem;color:var(--muted);margin:0}

/* --- figure tile --- */
.afig{border:1px solid var(--line);border-radius:16px;overflow:hidden;margin:32px 0;background:var(--card)}
.afig .ph{aspect-ratio:16/7;display:flex;align-items:center;justify-content:center;font-size:2.4rem;
  background:linear-gradient(135deg,#2a1060,#7C3AED 55%,#2EC5F6)}
.afig figcaption{padding:14px 20px;font-size:.8rem;color:var(--faint)}

/* --- related articles --- */
.related{border-top:1px solid var(--line);margin-top:52px;padding-top:34px}
.related h3{font-family:'Days One',sans-serif;font-size:.78rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--faint);margin-bottom:20px}
.related .rgrid{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.related a{display:block;border:1px solid var(--line);border-radius:14px;padding:20px;
  background:var(--card);transition:.25s}
.related a:hover{transform:translateY(-4px);border-color:rgba(46,197,246,.5)}
.related .rmt{font-size:.68rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--faint);margin-bottom:8px}
.related h4{font-size:.98rem;line-height:1.45;color:#fff}

@media(max-width:920px){
  .arthero{padding:120px 0 40px}
  .arthero h1{font-size:2.1rem;max-width:none}
  .statrow,.statrow.two{grid-template-columns:1fr 1fr}
  .vs{grid-template-columns:1fr}
  .related .rgrid{grid-template-columns:1fr}
  .pull{padding:26px 22px 26px 52px}
  .article .lead-p{font-size:1.1rem}
}
@media(max-width:560px){
  .statrow,.statrow.two{grid-template-columns:1fr}
}
@media (prefers-reduced-motion: reduce){
  .rprog{transition:none}
  .stat:hover,.related a:hover{transform:none}
}
.th.d{background:linear-gradient(135deg,#4a3208,#f5a623)}

/* ============================================================
   RELAY v3 — one paper, one capsule, one journey  (29 Jul 2026)
   Replaces the v2 "three simultaneous dots", which told the wrong story.

   ONE 20-second narrative, in order:
     0.0-1.6s   a question paper arrives at the Board Vault
     1.6-3.6s   it is split and encrypted into lakhs of sealed capsules
     4.0-6.6s   ONE capsule crosses to the Centre Head  (secure tunnel)
     7.2-9.8s   the SAME capsule crosses to the Invigilator (tap-to-tap)
     10.4-13.0s the SAME capsule crosses to the Candidate  (tap-to-tap)
     13.0-17.0s it sits sealed at the desk while the clock runs to exam hour
     17.0-19.4s it decrypts into a readable paper
     19.4-20s   reset

   All motion is transform/opacity. Everything is gated behind
   .jchain.live so it only runs while the section is on screen.
   ============================================================ */

/* --- icon badges --- */
.jn{position:relative}
.jic{width:58px;height:58px;margin:0 auto 14px;border-radius:50%;padding:1.5px;
  display:flex;align-items:center;justify-content:center;font-size:0}
.jic>span{display:flex;align-items:center;justify-content:center;width:100%;height:100%;
  border-radius:50%;background:#0d0d13}
.jic svg{width:27px;height:27px;fill:none;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round}
.jic.hold{background:linear-gradient(135deg,var(--amber),#ffd79a)}
.jic.hold svg{stroke:var(--amber)}
.jic.dark{background:rgba(255,255,255,.18)}
.jic.dark svg{stroke:rgba(255,255,255,.5)}
.jic.open{background:linear-gradient(135deg,var(--cy),var(--mag))}
.jic.open svg{stroke:var(--cy)}

/* wider segments: room for a label and a longer, more legible travel */
.jseg{width:92px;position:relative;overflow:visible}
.jseg em{position:absolute;top:-30px;left:50%;transform:translateX(-50%);
  font-style:normal;font-size:.56rem;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--faint);white-space:nowrap}

/* ---------- the travelling capsule ---------- */
.jseg i{position:absolute;top:-9px;left:0;width:20px;height:20px;border-radius:6px;
  background:linear-gradient(135deg,var(--cy),var(--vio));
  box-shadow:0 0 18px rgba(46,197,246,.75);
  opacity:0;transform:translateX(-3px);animation:none;
  display:flex;align-items:center;justify-content:center}
.jseg i::after{content:"";position:absolute;top:4px;width:6px;height:5px;
  border:1.5px solid #08131a;border-bottom:none;border-radius:3px 3px 0 0}
.jseg i::before{content:"";width:8px;height:6px;border-radius:1px;background:#08131a;margin-top:3px}

.jchain.live .jseg:nth-of-type(2) i{animation:cap1 20s linear infinite}
.jchain.live .jseg:nth-of-type(4) i{animation:cap2 20s linear infinite}
.jchain.live .jseg:nth-of-type(6) i{animation:cap3 20s linear infinite}

@keyframes cap1{
  0%,19.5%{transform:translateX(-3px);opacity:0}
  21%{transform:translateX(0);opacity:1}
  32%{transform:translateX(75px);opacity:1}
  33.5%,100%{transform:translateX(75px);opacity:0}
}
@keyframes cap2{
  0%,35.5%{transform:translateX(-3px);opacity:0}
  37%{transform:translateX(0);opacity:1}
  48%{transform:translateX(75px);opacity:1}
  49.5%,100%{transform:translateX(75px);opacity:0}
}
@keyframes cap3{
  0%,51.5%{transform:translateX(-3px);opacity:0}
  53%{transform:translateX(0);opacity:1}
  64%{transform:translateX(75px);opacity:1}
  65.5%,100%{transform:translateX(75px);opacity:0}
}

/* ---------- the path fills behind it, and stays filled ---------- */
.jseg::after{content:"";position:absolute;inset:0;border-radius:2px;
  background:linear-gradient(90deg,var(--cy),var(--vio));
  transform:scaleX(0);transform-origin:0 50%;opacity:.95}
.jchain.live .jseg:nth-of-type(2)::after{animation:segf1 20s linear infinite}
.jchain.live .jseg:nth-of-type(4)::after{animation:segf2 20s linear infinite}
.jchain.live .jseg:nth-of-type(6)::after{animation:segf3 20s linear infinite}
@keyframes segf1{0%,20%{transform:scaleX(0)}32%{transform:scaleX(1)}94%{transform:scaleX(1)}97%,100%{transform:scaleX(0)}}
@keyframes segf2{0%,36%{transform:scaleX(0)}48%{transform:scaleX(1)}94%{transform:scaleX(1)}97%,100%{transform:scaleX(0)}}
@keyframes segf3{0%,52%{transform:scaleX(0)}64%{transform:scaleX(1)}94%{transform:scaleX(1)}97%,100%{transform:scaleX(0)}}

/* ---------- node lights when the capsule is there ---------- */
.jn::after{content:"";position:absolute;inset:-1px;border-radius:16px;
  border:1px solid var(--cy);box-shadow:0 0 26px rgba(46,197,246,.32);
  opacity:0;pointer-events:none}
.jchain.live .jn:nth-of-type(1)::after{animation:ring1 20s linear infinite}
.jchain.live .jn:nth-of-type(3)::after{animation:ring2 20s linear infinite}
.jchain.live .jn:nth-of-type(5)::after{animation:ring3 20s linear infinite}
.jchain.live .jn:nth-of-type(7)::after{animation:ring4 20s linear infinite}
@keyframes ring1{0%{opacity:0}3%{opacity:1}18%{opacity:1}21%,100%{opacity:0}}
@keyframes ring2{0%,32%{opacity:0}34%{opacity:1}36%{opacity:1}38%,100%{opacity:0}}
@keyframes ring3{0%,48%{opacity:0}50%{opacity:1}52%{opacity:1}54%,100%{opacity:0}}
@keyframes ring4{0%,64%{opacity:0}66%{opacity:1}94%{opacity:1}97%,100%{opacity:0}}

/* ---------- VAULT: paper arrives, then splits into capsules ---------- */
.vfx{position:absolute;inset:0;pointer-events:none;overflow:hidden;border-radius:16px}
.vfx b{position:absolute;left:50%;top:26px;width:20px;height:26px;margin-left:-10px;
  border-radius:2px;background:#eef3f7;box-shadow:0 0 14px rgba(255,255,255,.5);
  opacity:0;transform:translateY(-46px) rotate(-8deg)}
.jchain.live .vfx b{animation:vpaper 20s linear infinite}
@keyframes vpaper{
  0%{opacity:0;transform:translateY(-46px) rotate(-8deg)}
  3%{opacity:1}
  8%{opacity:1;transform:translateY(0) rotate(0deg)}
  13%{opacity:1;transform:translateY(0) scale(1)}
  17%{opacity:0;transform:translateY(0) scale(.35)}
  100%{opacity:0;transform:translateY(0) scale(.35)}
}
.vfx i{position:absolute;left:50%;top:32px;width:7px;height:7px;margin-left:-3.5px;
  border-radius:2px;background:linear-gradient(135deg,var(--cy),var(--vio));opacity:0}
.jchain.live .vfx i{animation:vcap 20s ease-out infinite}
.vfx i:nth-child(2){--dx:-30px;--dy:-14px}
.vfx i:nth-child(3){--dx:30px;--dy:-14px}
.vfx i:nth-child(4){--dx:-34px;--dy:16px}
.vfx i:nth-child(5){--dx:34px;--dy:16px}
.vfx i:nth-child(6){--dx:-14px;--dy:26px}
.vfx i:nth-child(7){--dx:14px;--dy:26px}
@keyframes vcap{
  0%,14%{opacity:0;transform:translate(0,0) scale(.4)}
  17%{opacity:1;transform:translate(calc(var(--dx)*.6),calc(var(--dy)*.6)) scale(1)}
  19%{opacity:1;transform:translate(var(--dx),var(--dy)) scale(1)}
  22%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(.8)}
  100%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(.8)}
}

/* ---------- DESK: capsule waits, clock runs, then it decrypts ---------- */
.dfx{position:absolute;inset:0;pointer-events:none;overflow:hidden;border-radius:16px}
.dfx b{position:absolute;left:50%;top:26px;width:20px;height:20px;margin-left:-10px;
  border-radius:6px;background:linear-gradient(135deg,var(--cy),var(--vio));
  box-shadow:0 0 16px rgba(46,197,246,.6);opacity:0}
.jchain.live .dfx b{animation:dcap 20s linear infinite}
@keyframes dcap{
  0%,64%{opacity:0}
  66%{opacity:1;border-radius:6px;width:20px;height:20px}
  84%{opacity:1;border-radius:6px;width:20px;height:20px}
  88%{opacity:1;border-radius:2px;width:22px;height:28px;background:#eef3f7}
  95%{opacity:1;border-radius:2px;width:22px;height:28px;background:#eef3f7}
  98%,100%{opacity:0}
}
/* the clock that has to reach exam hour before anything opens */
.dfx u{position:absolute;left:50%;top:24px;margin-left:14px;width:16px;height:16px;
  border-radius:50%;border:1.5px solid var(--amber);opacity:0;text-decoration:none}
.dfx u::after{content:"";position:absolute;left:50%;top:2.5px;width:1.5px;height:6px;
  background:var(--amber);transform-origin:50% 100%;margin-left:-.75px}
.jchain.live .dfx u{animation:dclock 20s linear infinite}
.jchain.live .dfx u::after{animation:dhand 20s linear infinite}
@keyframes dclock{0%,64%{opacity:0}67%{opacity:1}84%{opacity:1}87%,100%{opacity:0}}
@keyframes dhand{0%,66%{transform:rotate(0deg)}85%{transform:rotate(1080deg)}100%{transform:rotate(1080deg)}}

/* seal wording follows the same clock */
.seal-wrap .s-locked,.seal-wrap .s-open{animation:none}
.jchain.live .seal-wrap .s-locked{animation:sLockV3 20s linear infinite}
.jchain.live .seal-wrap .s-open{animation:sOpenV3 20s linear infinite}
@keyframes sLockV3{0%,64%{opacity:1}84%{opacity:1}87%,100%{opacity:0}}
@keyframes sOpenV3{0%,84%{opacity:0}88%{opacity:1}96%{opacity:1}99%,100%{opacity:0}}

@media(max-width:920px){
  .jseg{width:2px;height:74px}
  .jseg em{top:50%;left:16px;transform:translateY(-50%)}
  .jseg i{top:0;left:-9px}
  .jchain.live .jseg:nth-of-type(2) i{animation:capv1 20s linear infinite}
  .jchain.live .jseg:nth-of-type(4) i{animation:capv2 20s linear infinite}
  .jchain.live .jseg:nth-of-type(6) i{animation:capv3 20s linear infinite}
  @keyframes capv1{0%,19.5%{transform:translateY(-3px);opacity:0}21%{transform:translateY(0);opacity:1}32%{transform:translateY(56px);opacity:1}33.5%,100%{transform:translateY(56px);opacity:0}}
  @keyframes capv2{0%,35.5%{transform:translateY(-3px);opacity:0}37%{transform:translateY(0);opacity:1}48%{transform:translateY(56px);opacity:1}49.5%,100%{transform:translateY(56px);opacity:0}}
  @keyframes capv3{0%,51.5%{transform:translateY(-3px);opacity:0}53%{transform:translateY(0);opacity:1}64%{transform:translateY(56px);opacity:1}65.5%,100%{transform:translateY(56px);opacity:0}}
  .jseg::after{background:linear-gradient(180deg,var(--cy),var(--vio));transform:scaleY(0);transform-origin:50% 0}
  @keyframes segf1{0%,20%{transform:scaleY(0)}32%{transform:scaleY(1)}94%{transform:scaleY(1)}97%,100%{transform:scaleY(0)}}
  @keyframes segf2{0%,36%{transform:scaleY(0)}48%{transform:scaleY(1)}94%{transform:scaleY(1)}97%,100%{transform:scaleY(0)}}
  @keyframes segf3{0%,52%{transform:scaleY(0)}64%{transform:scaleY(1)}94%{transform:scaleY(1)}97%,100%{transform:scaleY(0)}}
}
@media (prefers-reduced-motion: reduce){
  .jchain.live .jseg i,.jchain.live .jseg::after,.jchain.live .jn::after,
  .jchain.live .vfx b,.jchain.live .vfx i,.jchain.live .dfx b,.jchain.live .dfx u,
  .jchain.live .dfx u::after,
  .jchain.live .seal-wrap .s-locked,.jchain.live .seal-wrap .s-open{animation:none}
  .jseg::after{transform:scaleX(1);opacity:.5}
  .seal-wrap .s-open{opacity:0}
  .vfx,.dfx{display:none}
}

/* ============================================================
   RELAY v4 additions (29 Jul 2026)
   (a) .jseg.multi  -> a SET of capsules crosses that hop, not one.
       Question paper : Vault -> Centre Head is a set (the centre's whole
       allocation); Centre Head -> Invigilator -> Candidate is ONE capsule.
       Response       : Candidate -> Invigilator -> Centre Head is ONE
       capsule; Centre Head -> Vault is the set (aggregated centre).
   (b) .rchain -> the return journey. Same timeline, no exam-hour clock
       (nothing waits on a clock coming back).
   ============================================================ */

/* --- a set of capsules on one hop --- */
.jseg.multi i{width:13px;height:13px;border-radius:4px;box-shadow:0 0 12px rgba(46,197,246,.6)}
.jseg.multi i::before,.jseg.multi i::after{display:none}
.jseg.multi i:nth-of-type(1){top:-15px}
.jseg.multi i:nth-of-type(2){top:-4px}
.jseg.multi i:nth-of-type(3){top:7px}
.jseg.multi i:nth-of-type(4){top:-9px}
.jseg.multi i:nth-of-type(5){top:2px}
.jchain.live .jseg.multi i:nth-of-type(2){animation-delay:.18s}
.jchain.live .jseg.multi i:nth-of-type(3){animation-delay:.36s}
.jchain.live .jseg.multi i:nth-of-type(4){animation-delay:.10s}
.jchain.live .jseg.multi i:nth-of-type(5){animation-delay:.28s}

/* --- the return journey --- */
.rchain{margin-top:0}
.rchain .dfx u{display:none}          /* no exam-hour clock on the way back */
/* the response is held only briefly at the vault before evaluation opens it */
.jchain.rchain.live .dfx b{animation:dcapR 20s linear infinite}
@keyframes dcapR{
  0%,64%{opacity:0}
  66%{opacity:1;border-radius:6px;width:20px;height:20px}
  78%{opacity:1;border-radius:6px;width:20px;height:20px}
  83%{opacity:1;border-radius:2px;width:22px;height:28px;background:#eef3f7}
  95%{opacity:1;border-radius:2px;width:22px;height:28px;background:#eef3f7}
  98%,100%{opacity:0}
}
.jchain.rchain.live .seal-wrap .s-locked{animation:sLockR 20s linear infinite}
.jchain.rchain.live .seal-wrap .s-open{animation:sOpenR 20s linear infinite}
@keyframes sLockR{0%,64%{opacity:1}78%{opacity:1}82%,100%{opacity:0}}
@keyframes sOpenR{0%,79%{opacity:0}83%{opacity:1}96%{opacity:1}99%,100%{opacity:0}}

/* divider between the two journeys */
.rsplit{display:flex;align-items:center;gap:16px;max-width:1020px;margin:54px auto 30px}
.rsplit::before,.rsplit::after{content:"";flex:1;height:1px;background:var(--line)}
.rsplit span{font-size:.7rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--faint);white-space:nowrap}

/* ============================================================
   RELAY v5 (30 Jul 2026) — the return journey, corrected against the spec
   Source: Nexa_CORTEX_Process_Flows_Reverse_Response_Custody.html,
           SS5B reverse response custody / SS18 final sealed packet / SS19 receipt.

   TWO corrections to v4:
   1. The response does NOT return to the Board Vault. It is encrypted to the
      EVALUATION secure module; intermediaries cannot read it. Scoring happens
      inside that boundary.
   2. The graphic is now a true mirror. Centre Head, Invigilator and Candidate
      stay in the SAME horizontal positions as the outbound chain, and the
      capsule travels RIGHT -> LEFT. Only the far-left node changes identity,
      from Board Vault (out) to Evaluation Intake (back).

   DOM order of .rchain is left-to-right: Evaluation | seg | Centre Head |
   seg | Invigilator | seg | Candidate. So the journey runs from the LAST
   child to the FIRST, and the timing assignments below are inverted
   relative to the outbound chain.
   ============================================================ */

/* travel right -> left */
@keyframes capR1{
  0%,19.5%{transform:translateX(75px);opacity:0}
  21%{transform:translateX(72px);opacity:1}
  32%{transform:translateX(-3px);opacity:1}
  33.5%,100%{transform:translateX(-3px);opacity:0}
}
@keyframes capR2{
  0%,35.5%{transform:translateX(75px);opacity:0}
  37%{transform:translateX(72px);opacity:1}
  48%{transform:translateX(-3px);opacity:1}
  49.5%,100%{transform:translateX(-3px);opacity:0}
}
@keyframes capR3{
  0%,51.5%{transform:translateX(75px);opacity:0}
  53%{transform:translateX(72px);opacity:1}
  64%{transform:translateX(-3px);opacity:1}
  65.5%,100%{transform:translateX(-3px);opacity:0}
}

/* hop 1 is the RIGHTMOST segment; hop 3 (the aggregated upload) is the leftmost */
.jchain.rchain.live .jseg:nth-of-type(6) i{animation:capR1 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(4) i{animation:capR2 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(2) i{animation:capR3 20s linear infinite}

/* the path fills leftward, in the same inverted order */
.jchain.rchain .jseg::after{transform-origin:100% 50%}
.jchain.rchain.live .jseg:nth-of-type(6)::after{animation:segf1 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(4)::after{animation:segf2 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(2)::after{animation:segf3 20s linear infinite}

/* nodes light in journey order: Candidate first, Evaluation last */
.jchain.rchain.live .jn:nth-of-type(7)::after{animation:ring1 20s linear infinite}
.jchain.rchain.live .jn:nth-of-type(5)::after{animation:ring2 20s linear infinite}
.jchain.rchain.live .jn:nth-of-type(3)::after{animation:ring3 20s linear infinite}
.jchain.rchain.live .jn:nth-of-type(1)::after{animation:ring4 20s linear infinite}

/* the receipt each hop emits - SS5B: the return path is not a silent step */
.jseg s{position:absolute;top:16px;left:50%;transform:translateX(-50%) scale(.4);
  width:13px;height:15px;border-radius:2px;background:#eef3f7;opacity:0;
  text-decoration:none;box-shadow:0 0 10px rgba(255,255,255,.35)}
.jseg s::after{content:"";position:absolute;left:2.5px;top:3px;width:8px;height:1px;
  background:#0d0d13;box-shadow:0 3px 0 #0d0d13,0 6px 0 #0d0d13}
.jchain.rchain.live .jseg:nth-of-type(6) s{animation:rcpt1 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(4) s{animation:rcpt2 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(2) s{animation:rcpt3 20s linear infinite}
@keyframes rcpt1{0%,31%{opacity:0;transform:translateX(-50%) scale(.4)}34%{opacity:1;transform:translateX(-50%) scale(1)}92%{opacity:1;transform:translateX(-50%) scale(1)}96%,100%{opacity:0}}
@keyframes rcpt2{0%,47%{opacity:0;transform:translateX(-50%) scale(.4)}50%{opacity:1;transform:translateX(-50%) scale(1)}92%{opacity:1;transform:translateX(-50%) scale(1)}96%,100%{opacity:0}}
@keyframes rcpt3{0%,63%{opacity:0;transform:translateX(-50%) scale(.4)}66%{opacity:1;transform:translateX(-50%) scale(1)}92%{opacity:1;transform:translateX(-50%) scale(1)}96%,100%{opacity:0}}

@media(max-width:920px){
  .jchain.rchain.live .jseg:nth-of-type(6) i{animation:capv1 20s linear infinite}
  .jchain.rchain.live .jseg:nth-of-type(4) i{animation:capv2 20s linear infinite}
  .jchain.rchain.live .jseg:nth-of-type(2) i{animation:capv3 20s linear infinite}
  .jchain.rchain .jseg::after{transform-origin:50% 0}
  .jseg s{top:50%;left:auto;right:14px;transform:translateY(-50%) scale(.4)}
  @keyframes rcpt1{0%,31%{opacity:0}34%{opacity:1}92%{opacity:1}96%,100%{opacity:0}}
  @keyframes rcpt2{0%,47%{opacity:0}50%{opacity:1}92%{opacity:1}96%,100%{opacity:0}}
  @keyframes rcpt3{0%,63%{opacity:0}66%{opacity:1}92%{opacity:1}96%,100%{opacity:0}}
}
@media (prefers-reduced-motion: reduce){
  .jchain.rchain.live .jseg i,.jchain.rchain.live .jseg::after,
  .jchain.rchain.live .jn::after,.jchain.rchain.live .jseg s{animation:none}
  .jseg s{opacity:0}
}

/* ============================================================
   RELAY v6 (30 Jul 2026) — aligned to the verified campaign infographics
   Sources: campaign-03.jpg "What is CORTEX?"  |  campaign-04.jpg "How CORTEX
   protects responses" — both confirmed accurate by Govinda.

   Visual vocabulary adopted from those posters:
     - question capsules are 3-D CUBES, and the set NARROWS at every hop
       (centre-specific set -> exam-hall-specific set -> one device-specific)
     - the response is a RED SEALED ENVELOPE with a white seal, never a capsule
     - intermediaries are phones/tablets labelled "non-decrypting device"
     - Board -> Centre Head runs over Secure Cloud + a WHITELISTED VPN,
       not an invented "secure tunnel"
     - device-to-device is "TAP both devices"
   ============================================================ */

/* ---------- question capsule: isometric cube ---------- */
.jseg i{position:absolute;top:-7px;left:0;width:14px;height:14px;border-radius:2px;
  background:linear-gradient(160deg,#6fd6f7,#3aa9dc);
  box-shadow:0 0 14px rgba(46,197,246,.6);
  opacity:0;transform:translateX(-3px);animation:none;display:block}
.jseg i::before{content:"";position:absolute;top:-5px;left:0;width:14px;height:5px;
  background:#a5e7fb;transform:skewX(-45deg);transform-origin:bottom left;border:none;border-radius:0}
.jseg i::after{content:"";position:absolute;top:0;right:-5px;width:5px;height:14px;
  background:#2589b8;transform:skewY(-45deg);transform-origin:top left;
  border:none;border-radius:0;position:absolute}

/* a SET of cubes, and the set gets smaller as it narrows */
.jseg.multi i{width:11px;height:11px}
.jseg.multi i::before{width:11px;height:4px;top:-4px}
.jseg.multi i::after{width:4px;height:11px;right:-4px}
.jseg.multi i:nth-of-type(1){top:-16px}
.jseg.multi i:nth-of-type(2){top:-4px}
.jseg.multi i:nth-of-type(3){top:8px}
.jseg.multi i:nth-of-type(4){top:-10px}
.jseg.multi i:nth-of-type(5){top:2px}

/* ---------- response: red sealed envelope ---------- */
.rchain .jseg i{width:19px;height:14px;border-radius:2px;
  background:linear-gradient(160deg,#ef5a50,#c9352c);
  box-shadow:0 0 14px rgba(224,72,63,.6)}
.rchain .jseg i::before{content:"";position:absolute;inset:0;width:auto;height:auto;top:0;left:0;
  border-top:7px solid rgba(0,0,0,.22);border-left:9.5px solid transparent;
  border-right:9.5px solid transparent;background:none;transform:none;box-sizing:border-box}
.rchain .jseg i::after{content:"";position:absolute;left:50%;top:50%;right:auto;
  width:7px;height:7px;margin:-3.5px 0 0 -3.5px;border-radius:50%;
  background:#fff;box-shadow:0 0 6px rgba(255,255,255,.7);transform:none}
.rchain .jseg.multi i{width:15px;height:11px}
.rchain .jseg.multi i::before{border-top-width:5.5px;border-left-width:7.5px;border-right-width:7.5px}
.rchain .jseg.multi i::after{width:5px;height:5px;margin:-2.5px 0 0 -2.5px}

/* ---------- "non-decrypting device" reads as a caption, not a badge ---------- */
.jn .tagp.no{background:none;color:var(--faint);font-style:italic;font-weight:600;
  letter-spacing:.02em;text-transform:none;font-size:.66rem;padding:3px 0}

/* ---------- the throughput number, stated like the poster does ---------- */
.jstat{display:flex;align-items:center;justify-content:center;gap:10px;
  max-width:1020px;margin:22px auto 0;font-size:.74rem;color:var(--faint);
  letter-spacing:.04em;text-align:center}
.jstat b{font-family:'Days One',sans-serif;font-weight:400;font-size:.95rem;
  background:linear-gradient(90deg,var(--cy),var(--mag));
  -webkit-background-clip:text;background-clip:text;color:transparent}

/* ---------- candidate device seals the answer trail (response chain) ---------- */
.rchain .vfx i{display:none}
.jchain.rchain.live .vfx b{animation:rsheet 20s linear infinite}
@keyframes rsheet{
  0%{opacity:0;transform:translateY(-40px) rotate(-6deg);border-radius:2px}
  3%{opacity:1;background:#eef3f7;width:20px;height:26px}
  8%{opacity:1;transform:translateY(0) rotate(0deg);background:#eef3f7;width:20px;height:26px}
  12%{opacity:1;background:#eef3f7;width:20px;height:26px}
  16%{opacity:1;background:#ef5a50;width:24px;height:17px;border-radius:2px}
  19%{opacity:1;background:#ef5a50;width:24px;height:17px}
  23%{opacity:0;background:#ef5a50;width:24px;height:17px}
  100%{opacity:0}
}

/* ---------- at the Board: verify the chain BEFORE decrypting ---------- */
.rchain .dfx u{display:block;left:50%;top:24px;margin-left:15px;width:17px;height:17px;
  border-radius:50%;border:1.5px solid #37d39a;opacity:0}
.rchain .dfx u::after{content:"";position:absolute;left:3.4px;top:6.6px;width:6px;height:3px;
  border-left:1.6px solid #37d39a;border-bottom:1.6px solid #37d39a;
  transform:rotate(-45deg);transform-origin:center;background:none;animation:none}
.jchain.rchain.live .dfx u{animation:dverify 20s linear infinite}
.jchain.rchain.live .dfx u::after{animation:none}
@keyframes dverify{0%,64%{opacity:0}67%{opacity:1}74.4%{opacity:1}75.4%,100%{opacity:0}}
/* envelope waits, chain verifies, only then does it open into a readable sheet */
.jchain.rchain.live .dfx b{animation:dcapR6 20s linear infinite}
@keyframes dcapR6{
  0%,64%{opacity:0}
  66%{opacity:1;width:24px;height:17px;border-radius:2px;background:#ef5a50}
  82%{opacity:1;width:24px;height:17px;border-radius:2px;background:#ef5a50}
  87%{opacity:1;width:22px;height:28px;border-radius:2px;background:#eef3f7}
  95%{opacity:1;width:22px;height:28px;border-radius:2px;background:#eef3f7}
  98%,100%{opacity:0}
}

@media(max-width:920px){
  .jseg.multi i:nth-of-type(1){top:0;left:-18px}
  .jseg.multi i:nth-of-type(2){top:0;left:-8px}
  .jseg.multi i:nth-of-type(3){top:0;left:2px}
  .jseg.multi i:nth-of-type(4){top:0;left:-13px}
  .jseg.multi i:nth-of-type(5){top:0;left:-3px}
  .jstat{font-size:.7rem}
}
@media (prefers-reduced-motion: reduce){
  .jchain.rchain.live .vfx b,.jchain.rchain.live .dfx b,.jchain.rchain.live .dfx u{animation:none}
}

/* ============================================================
   RELAY v7 (30 Jul 2026) — 4x element sizes + Govinda's question-paper list
   Layout changed from a 4-across strip to a VERTICAL stack. A horizontal
   strip at 1140px gives each node ~204px, which cannot hold a 4x icon or a
   4x capsule with travel distance. Stacked, each step gets the full column:
   icon 96px (was 58), cubes 44px front face (was 14 -> ~3.1x, ~4x with depth),
   envelope 58x42 (was 19x14), receipt 34x40 (was 13x15).
   ============================================================ */

.jchain{flex-direction:column;align-items:stretch;max-width:820px;gap:0}

/* each step: big icon left, words right */
.jn{display:flex;align-items:center;gap:28px;text-align:left;padding:26px 30px}
.jn:hover{transform:none;border-color:rgba(124,58,237,.5)}
.jstage{flex:none;position:relative;width:96px;height:96px}
.jtxt{flex:1;min-width:0}
.jic{width:96px;height:96px;margin:0;padding:2px}
.jic svg{width:46px;height:46px;stroke-width:1.5}
.jn b{font-size:1.15rem;margin-bottom:4px}
.jn .jtxt span{font-size:.82rem;letter-spacing:.01em;margin-top:2px}
.jn .tagp{margin-top:10px;font-size:.66rem;padding:4px 12px}
.jn .tagp.no{font-size:.76rem;padding:4px 0}

/* the connector is now vertical, and long enough for a big capsule to travel */
.jseg{width:3px;height:132px;align-self:center;margin:0 auto;border-radius:3px}
.jseg em{top:50%;left:calc(50% + 46px);transform:translateY(-50%);white-space:normal;
  max-width:300px;font-size:.72rem;line-height:1.5;text-align:left}
.jseg::after{background:linear-gradient(180deg,var(--cy),var(--vio));
  transform:scaleY(0);transform-origin:50% 0}
.jchain.rchain .jseg::after{transform-origin:50% 100%}

/* ---------- question capsule: big isometric cube ---------- */
.jseg i{width:44px;height:44px;border-radius:5px;top:0;left:-20.5px;
  box-shadow:0 0 26px rgba(46,197,246,.55)}
.jseg i::before{top:-14px;left:0;width:44px;height:14px}
.jseg i::after{top:0;right:-14px;width:14px;height:44px}
.jseg.multi i{width:30px;height:30px;left:-13.5px}
.jseg.multi i::before{width:30px;height:10px;top:-10px}
.jseg.multi i::after{width:10px;height:30px;right:-10px}
.jseg.multi i:nth-of-type(1){left:-46px}
.jseg.multi i:nth-of-type(2){left:-13.5px}
.jseg.multi i:nth-of-type(3){left:19px}
.jseg.multi i:nth-of-type(4){left:-30px}
.jseg.multi i:nth-of-type(5){left:3px}

/* ---------- response: big red sealed envelope ---------- */
.rchain .jseg i{width:58px;height:42px;border-radius:4px;left:-27.5px;
  box-shadow:0 0 26px rgba(224,72,63,.55)}
.rchain .jseg i::before{border-top-width:21px;border-left-width:29px;border-right-width:29px}
.rchain .jseg i::after{width:20px;height:20px;margin:-10px 0 0 -10px}
.rchain .jseg.multi i{width:40px;height:29px;left:-19px}
.rchain .jseg.multi i::before{border-top-width:14.5px;border-left-width:20px;border-right-width:20px}
.rchain .jseg.multi i::after{width:14px;height:14px;margin:-7px 0 0 -7px}
.rchain .jseg.multi i:nth-of-type(1){left:-58px}
.rchain .jseg.multi i:nth-of-type(2){left:-19px}
.rchain .jseg.multi i:nth-of-type(3){left:20px}
.rchain .jseg.multi i:nth-of-type(4){left:-38px}
.rchain .jseg.multi i:nth-of-type(5){left:1px}

/* travel is vertical now, in both directions */
.jchain.live .jseg:nth-of-type(2) i{animation:capV1 20s linear infinite}
.jchain.live .jseg:nth-of-type(4) i{animation:capV2 20s linear infinite}
.jchain.live .jseg:nth-of-type(6) i{animation:capV3 20s linear infinite}
@keyframes capV1{0%,19.5%{transform:translateY(-14px);opacity:0}21%{transform:translateY(-8px);opacity:1}32%{transform:translateY(104px);opacity:1}33.5%,100%{transform:translateY(104px);opacity:0}}
@keyframes capV2{0%,35.5%{transform:translateY(-14px);opacity:0}37%{transform:translateY(-8px);opacity:1}48%{transform:translateY(104px);opacity:1}49.5%,100%{transform:translateY(104px);opacity:0}}
@keyframes capV3{0%,51.5%{transform:translateY(-14px);opacity:0}53%{transform:translateY(-8px);opacity:1}64%{transform:translateY(104px);opacity:1}65.5%,100%{transform:translateY(104px);opacity:0}}
/* response: bottom-up */
.jchain.rchain.live .jseg:nth-of-type(6) i{animation:capRV1 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(4) i{animation:capRV2 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(2) i{animation:capRV3 20s linear infinite}
@keyframes capRV1{0%,19.5%{transform:translateY(104px);opacity:0}21%{transform:translateY(98px);opacity:1}32%{transform:translateY(-14px);opacity:1}33.5%,100%{transform:translateY(-14px);opacity:0}}
@keyframes capRV2{0%,35.5%{transform:translateY(104px);opacity:0}37%{transform:translateY(98px);opacity:1}48%{transform:translateY(-14px);opacity:1}49.5%,100%{transform:translateY(-14px);opacity:0}}
@keyframes capRV3{0%,51.5%{transform:translateY(104px);opacity:0}53%{transform:translateY(98px);opacity:1}64%{transform:translateY(-14px);opacity:1}65.5%,100%{transform:translateY(-14px);opacity:0}}
/* fills grow along the vertical axis */
.jchain.live .jseg:nth-of-type(2)::after{animation:segfV1 20s linear infinite}
.jchain.live .jseg:nth-of-type(4)::after{animation:segfV2 20s linear infinite}
.jchain.live .jseg:nth-of-type(6)::after{animation:segfV3 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(6)::after{animation:segfV1 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(4)::after{animation:segfV2 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(2)::after{animation:segfV3 20s linear infinite}
@keyframes segfV1{0%,20%{transform:scaleY(0)}32%{transform:scaleY(1)}94%{transform:scaleY(1)}97%,100%{transform:scaleY(0)}}
@keyframes segfV2{0%,36%{transform:scaleY(0)}48%{transform:scaleY(1)}94%{transform:scaleY(1)}97%,100%{transform:scaleY(0)}}
@keyframes segfV3{0%,52%{transform:scaleY(0)}64%{transform:scaleY(1)}94%{transform:scaleY(1)}97%,100%{transform:scaleY(0)}}

/* ---------- signed receipt at every hop, BOTH directions (item 6) ---------- */
.jseg s{position:absolute;left:calc(50% - 62px);top:50%;transform:translateY(-50%) scale(.4);
  width:34px;height:40px;border-radius:3px;background:#eef3f7;opacity:0;
  text-decoration:none;box-shadow:0 0 16px rgba(255,255,255,.35)}
.jseg s::after{content:"";position:absolute;left:6px;top:8px;width:22px;height:2px;
  background:#0d0d13;box-shadow:0 7px 0 #0d0d13,0 14px 0 #0d0d13,0 21px 0 -.5px #0d0d13}
.jchain.live .jseg:nth-of-type(2) s{animation:rcptA 20s linear infinite}
.jchain.live .jseg:nth-of-type(4) s{animation:rcptB 20s linear infinite}
.jchain.live .jseg:nth-of-type(6) s{animation:rcptC 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(6) s{animation:rcptA 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(4) s{animation:rcptB 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(2) s{animation:rcptC 20s linear infinite}
@keyframes rcptA{0%,31%{opacity:0;transform:translateY(-50%) scale(.4)}34%{opacity:1;transform:translateY(-50%) scale(1)}92%{opacity:1;transform:translateY(-50%) scale(1)}96%,100%{opacity:0}}
@keyframes rcptB{0%,47%{opacity:0;transform:translateY(-50%) scale(.4)}50%{opacity:1;transform:translateY(-50%) scale(1)}92%{opacity:1;transform:translateY(-50%) scale(1)}96%,100%{opacity:0}}
@keyframes rcptC{0%,63%{opacity:0;transform:translateY(-50%) scale(.4)}66%{opacity:1;transform:translateY(-50%) scale(1)}92%{opacity:1;transform:translateY(-50%) scale(1)}96%,100%{opacity:0}}

/* ---------- vault / desk stage effects, scaled to the 96px stage ---------- */
.vfx,.dfx{border-radius:50%}
.vfx b{top:22px;left:50%;width:34px;height:44px;margin-left:-17px;transform:translateY(-78px) rotate(-8deg)}
/* the paper that arrives is ALREADY encrypted: paper + padlock (item 2) */
.vfx b::after{content:"";position:absolute;left:50%;bottom:5px;margin-left:-9px;
  width:18px;height:13px;border-radius:2px;background:#0d0d13}
.vfx b::before{content:"";position:absolute;left:50%;bottom:16px;margin-left:-6px;
  width:12px;height:9px;border:2.5px solid #0d0d13;border-bottom:none;border-radius:6px 6px 0 0}
@keyframes vpaper{
  0%{opacity:0;transform:translateY(-78px) rotate(-8deg)}
  3%{opacity:1}
  8%{opacity:1;transform:translateY(0) rotate(0deg)}
  13%{opacity:1;transform:translateY(0) scale(1)}
  17%{opacity:0;transform:translateY(0) scale(.3)}
  100%{opacity:0;transform:translateY(0) scale(.3)}
}
.vfx i{top:40px;width:15px;height:15px;margin-left:-7.5px;border-radius:3px}
.vfx i:nth-child(2){--dx:-46px;--dy:-24px}
.vfx i:nth-child(3){--dx:46px;--dy:-24px}
.vfx i:nth-child(4){--dx:-52px;--dy:26px}
.vfx i:nth-child(5){--dx:52px;--dy:26px}
.vfx i:nth-child(6){--dx:-22px;--dy:42px}
.vfx i:nth-child(7){--dx:22px;--dy:42px}
.dfx b{top:22px;left:50%;width:40px;height:40px;margin-left:-20px}
.dfx u{left:50%;top:18px;margin-left:26px;width:28px;height:28px;border-width:2px}
.dfx u::after{top:4px;width:2px;height:11px;margin-left:-1px}
.rchain .dfx u{width:30px;height:30px;margin-left:26px;border-width:2px}
.rchain .dfx u::after{left:6px;top:11px;width:11px;height:6px;border-left-width:2.5px;border-bottom-width:2.5px}
@keyframes dcap{
  0%,64%{opacity:0}
  66%{opacity:1;border-radius:6px;width:40px;height:40px}
  84%{opacity:1;border-radius:6px;width:40px;height:40px}
  88%{opacity:1;border-radius:3px;width:38px;height:48px;background:#eef3f7}
  95%{opacity:1;border-radius:3px;width:38px;height:48px;background:#eef3f7}
  98%,100%{opacity:0}
}
@keyframes rsheet{
  0%{opacity:0;transform:translateY(-70px) rotate(-6deg)}
  3%{opacity:1;background:#eef3f7;width:34px;height:44px}
  8%{opacity:1;transform:translateY(0) rotate(0deg);background:#eef3f7;width:34px;height:44px}
  12%{opacity:1;background:#eef3f7;width:34px;height:44px}
  16%{opacity:1;background:#ef5a50;width:46px;height:33px}
  19%{opacity:1;background:#ef5a50;width:46px;height:33px}
  23%{opacity:0;background:#ef5a50}
  100%{opacity:0}
}
@keyframes dcapR6{
  0%,64%{opacity:0}
  66%{opacity:1;width:46px;height:33px;border-radius:3px;background:#ef5a50}
  82%{opacity:1;width:46px;height:33px;border-radius:3px;background:#ef5a50}
  87%{opacity:1;width:38px;height:48px;border-radius:3px;background:#eef3f7}
  95%{opacity:1;width:38px;height:48px;border-radius:3px;background:#eef3f7}
  98%,100%{opacity:0}
}

.jstat{font-size:.86rem;max-width:820px;margin-top:26px}
.jstat b{font-size:1.15rem}
.jcaption{max-width:820px}

@media(max-width:920px){
  .jchain{max-width:none}
  .jn{gap:20px;padding:22px 20px}
  .jstage,.jic{width:78px;height:78px}
  .jic svg{width:38px;height:38px}
  .jseg{height:118px}
  .jseg em{left:calc(50% + 38px);max-width:190px;font-size:.68rem}
  .jseg s{left:calc(50% - 54px);width:28px;height:33px}
  .jseg s::after{left:5px;top:6px;width:18px;box-shadow:0 6px 0 #0d0d13,0 12px 0 #0d0d13,0 18px 0 -.5px #0d0d13}
}

/* ============================================================
   RELAY v8 (30 Jul 2026) — third graphic: hourly public custody proof
   Govinda: "The hourly custody fingerprint (signed by Board -> countersigned
   by independent witness -> published publicly) SHOULD be represented too,
   on the site - as a separate graphic."
   Spec: SS20/SS20A root publication, witness diversity set, channel diversity
   set (k-of-n public channels), dead-man's-switch - "silence becomes a
   positive alarm."
   Only 3 steps, so this one stays HORIZONTAL - it fits at full size.
   ============================================================ */

.pchain{display:flex;align-items:stretch;max-width:1080px;margin:0 auto;position:relative}
.pn{flex:1;background:var(--card);border:1px solid rgba(255,255,255,.08);
  border-radius:16px;padding:32px 26px;text-align:center;position:relative}
.pn .jic{margin:0 auto 20px}
.pn b{font-family:'Days One',sans-serif;font-weight:400;font-size:1.05rem;
  display:block;color:#fff;margin-bottom:9px;line-height:1.35}
.pn>span{display:block;font-size:.82rem;color:var(--muted);line-height:1.6}
.pn::after{content:"";position:absolute;inset:-1px;border-radius:16px;
  border:1px solid var(--cy);box-shadow:0 0 26px rgba(46,197,246,.3);
  opacity:0;pointer-events:none}
.pchain.live .pn:nth-of-type(1)::after{animation:pring 9s linear infinite}
.pchain.live .pn:nth-of-type(3)::after{animation:pring 9s linear infinite;animation-delay:2.8s}
.pchain.live .pn:nth-of-type(5)::after{animation:pring 9s linear infinite;animation-delay:5.6s}
@keyframes pring{0%{opacity:0}4%{opacity:1}26%{opacity:1}31%,100%{opacity:0}}

.parrow{width:58px;flex:none;align-self:center;height:3px;border-radius:3px;
  background:rgba(255,255,255,.12);position:relative}
.parrow::after{content:"";position:absolute;inset:0;border-radius:3px;
  background:linear-gradient(90deg,var(--cy),var(--mag));
  transform:scaleX(0);transform-origin:0 50%}
.pchain.live .parrow:nth-of-type(2)::after{animation:pfill 9s linear infinite}
.pchain.live .parrow:nth-of-type(4)::after{animation:pfill 9s linear infinite;animation-delay:2.8s}
@keyframes pfill{0%,26%{transform:scaleX(0)}31%{transform:scaleX(1)}94%{transform:scaleX(1)}97%,100%{transform:scaleX(0)}}
/* the fingerprint token that travels the publication path */
.parrow i{position:absolute;top:-11px;left:0;width:25px;height:25px;border-radius:50%;
  background:linear-gradient(135deg,var(--cy),var(--mag));opacity:0;
  box-shadow:0 0 18px rgba(46,197,246,.7)}
.parrow i::after{content:"";position:absolute;left:50%;top:50%;width:11px;height:11px;
  margin:-5.5px 0 0 -5.5px;border-radius:50%;border:1.5px solid #08131a;
  box-shadow:0 0 0 3px transparent,inset 0 0 0 1.5px transparent}
.pchain.live .parrow:nth-of-type(2) i{animation:pmove 9s linear infinite}
.pchain.live .parrow:nth-of-type(4) i{animation:pmove 9s linear infinite;animation-delay:2.8s}
@keyframes pmove{
  0%,22%{transform:translateX(-4px);opacity:0}
  24%{transform:translateX(-2px);opacity:1}
  30%{transform:translateX(35px);opacity:1}
  32%,100%{transform:translateX(35px);opacity:0}
}

/* "every hour" marker above the strip */
.phour{display:flex;align-items:center;justify-content:center;gap:12px;
  max-width:1080px;margin:0 auto 26px}
.phour span{font-size:.72rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase;
  color:var(--amber);border:1px solid rgba(245,166,35,.45);border-radius:999px;padding:7px 18px;
  white-space:nowrap}
.phour::before,.phour::after{content:"";flex:1;height:1px;background:var(--line)}

@media(max-width:920px){
  .pchain{flex-direction:column}
  .parrow{width:3px;height:52px;align-self:center}
  .parrow::after{background:linear-gradient(180deg,var(--cy),var(--mag));
    transform:scaleY(0);transform-origin:50% 0}
  @keyframes pfill{0%,26%{transform:scaleY(0)}31%{transform:scaleY(1)}94%{transform:scaleY(1)}97%,100%{transform:scaleY(0)}}
  .parrow i{top:0;left:-11px}
  @keyframes pmove{0%,22%{transform:translateY(-4px);opacity:0}24%{transform:translateY(-2px);opacity:1}30%{transform:translateY(29px);opacity:1}32%,100%{transform:translateY(29px);opacity:0}}
}
@media (prefers-reduced-motion: reduce){
  .pchain.live .pn::after,.pchain.live .parrow::after,.pchain.live .parrow i{animation:none}
  .parrow::after{transform:scaleX(1);opacity:.5}
}

/* ============================================================
   RELAY v9 (30 Jul 2026) — response chain flipped: Candidate at TOP,
   Board at BOTTOM, so BOTH journeys read downward.

   Because the DOM order is now Candidate | seg | Invigilator | seg |
   Centre-Head | seg | Board, the response chain has the SAME structure as the
   question chain, so it uses the base top-down timing. These rules exist to
   OVERRIDE the earlier bottom-up assignments (capR*/capRV*/segf inversions and
   the ring/receipt swaps from v5 and v7), which are still earlier in the file.
   Same specificity, later in source, so these win. Do not reorder.
   ============================================================ */

/* fills grow downward again, like the question chain */
.jchain.rchain .jseg::after{transform-origin:50% 0}

/* the sealed envelope travels top-down, hop 1 first */
.jchain.rchain.live .jseg:nth-of-type(2) i{animation:capV1 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(4) i{animation:capV2 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(6) i{animation:capV3 20s linear infinite}

.jchain.rchain.live .jseg:nth-of-type(2)::after{animation:segfV1 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(4)::after{animation:segfV2 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(6)::after{animation:segfV3 20s linear infinite}

/* Candidate lights first; the Board holds its ring through verify + decrypt */
.jchain.rchain.live .jn:nth-of-type(1)::after{animation:ring1 20s linear infinite}
.jchain.rchain.live .jn:nth-of-type(3)::after{animation:ring2 20s linear infinite}
.jchain.rchain.live .jn:nth-of-type(5)::after{animation:ring3 20s linear infinite}
.jchain.rchain.live .jn:nth-of-type(7)::after{animation:ring4 20s linear infinite}

/* receipts in journey order: collection, transfer, upload */
.jchain.rchain.live .jseg:nth-of-type(2) s{animation:rcptA 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(4) s{animation:rcptB 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(6) s{animation:rcptC 20s linear infinite}

@media(max-width:920px){
  .jchain.rchain.live .jseg:nth-of-type(2) i{animation:capV1 20s linear infinite}
  .jchain.rchain.live .jseg:nth-of-type(4) i{animation:capV2 20s linear infinite}
  .jchain.rchain.live .jseg:nth-of-type(6) i{animation:capV3 20s linear infinite}
  .jchain.rchain .jseg::after{transform-origin:50% 0}
}

/* ============================================================
   RELAY v10 (30 Jul 2026) â€” device class line on each node.
   Govinda: Invigilator + Candidate are "OFFLINE Kiosk mode Device
   (Tablet/Terminal)"; the Centre-Head is kiosk-mode but NOT offline,
   because it needs the secure tunnel to the Board. That asymmetry is
   deliberate and is shown.
   ============================================================ */
.jn .jtxt .dev{display:block;margin-top:9px;font-size:.75rem;font-weight:600;
  letter-spacing:.03em;color:rgba(46,197,246,.85)}
.jn .jtxt .dev b{color:var(--amber);font-family:'Open Sans',sans-serif;font-weight:700;
  letter-spacing:.09em}
@media(max-width:920px){.jn .jtxt .dev{font-size:.72rem}}

/* ============================================================
   RELAY v11 (30 Jul 2026) - hop label boxes were collapsing.
   The label is absolutely positioned inside a 3px-wide .jseg, so with only
   max-width set it shrink-to-fit against ~0 available width and wrapped to
   one word per line, then got painted over by the next node card.
   Fixes: explicit width, z-index above the following card, and sentence case
   (a full sentence in tracked uppercase at 0.72rem was unreadable).
   ============================================================ */
.jseg{z-index:3}
.jseg em{
  left:calc(50% + 40px);
  width:360px;
  max-width:none;
  text-transform:none;
  letter-spacing:0;
  font-size:.82rem;
  line-height:1.62;
  color:var(--muted);
}
.jseg em b{text-transform:uppercase;letter-spacing:.08em}
@media(max-width:980px){ .jseg em{width:300px;left:calc(50% + 34px)} }
@media(max-width:920px){ .jseg em{width:calc(100vw - 230px);left:calc(50% + 30px);font-size:.78rem} }
@media(max-width:600px){ .jseg em{width:calc(100vw - 170px);left:calc(50% + 22px);font-size:.74rem;line-height:1.5} }

/* ============================================================
   RELAY v12 (30 Jul 2026) - Face-Tap inset: two devices mating via
   CORTEX Relay Cards. Modelled on Govinda's reference photographs: each
   device carries a Relay Card in its port, and the two cards butt
   together face to face and are held for a few seconds.
   Sits on the LEFT of the connector (the label occupies the right).
   Its own 5s loop - it is an explanatory inset, not part of the 20s story.
   ============================================================ */
.ftap{position:absolute;top:50%;right:calc(50% + 80px);transform:translateY(-50%);
  width:208px;height:84px;pointer-events:none}
.ftap span{position:absolute;display:block}
/* the two devices */
.ftap .fa{left:0;top:12px;width:33px;height:60px;border-radius:6px;
  border:2px solid rgba(255,255,255,.55);background:#0f1016}
.ftap .fa::after{content:"";position:absolute;left:50%;top:5px;width:13px;height:2px;
  margin-left:-6.5px;border-radius:2px;background:rgba(255,255,255,.35)}
.ftap .fb{right:0;top:5px;width:45px;height:74px;border-radius:6px;
  border:2px solid rgba(255,255,255,.55);background:#0f1016}
.ftap .fb::after{content:"";position:absolute;left:50%;top:6px;width:4px;height:4px;
  margin-left:-2px;border-radius:50%;background:rgba(255,255,255,.35)}
/* the CORTEX Relay Cards - flanged, like the photographed hardware */
.ftap .ka,.ftap .kb{top:50%;width:50px;height:32px;margin-top:-16px;
  background:#1b1c23;border:1.5px solid rgba(255,255,255,.4);border-radius:3px}
.ftap .ka{left:35px}
.ftap .kb{right:47px}
.ftap .ka::before,.ftap .kb::before{content:"";position:absolute;top:-7px;bottom:-7px;
  width:9px;background:#1b1c23;border:1.5px solid rgba(255,255,255,.4);border-radius:2px}
.ftap .ka::before{left:-1.5px;border-right:none;border-radius:2px 0 0 2px}
.ftap .kb::before{right:-1.5px;border-left:none;border-radius:0 2px 2px 0}
/* contact flash where the two card faces meet */
.ftap .fg{left:50%;top:50%;width:12px;height:36px;margin:-18px 0 0 -6px;border-radius:4px;
  background:linear-gradient(180deg,var(--cy),var(--mag));opacity:0;
  box-shadow:0 0 22px var(--cy)}
.ftap .fl{left:0;right:0;bottom:-19px;width:auto;text-align:center;font-size:.62rem;
  font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--faint)}

.jchain.live .ftap .ka{animation:ftapA 5s ease-in-out infinite}
.jchain.live .ftap .kb{animation:ftapB 5s ease-in-out infinite}
.jchain.live .ftap .fg{animation:ftapG 5s ease-in-out infinite}
@keyframes ftapA{0%,12%{transform:translateX(0)}32%,68%{transform:translateX(19px)}88%,100%{transform:translateX(0)}}
@keyframes ftapB{0%,12%{transform:translateX(0)}32%,68%{transform:translateX(-19px)}88%,100%{transform:translateX(0)}}
@keyframes ftapG{0%,30%{opacity:0}36%{opacity:1}64%{opacity:1}70%,100%{opacity:0}}

@media(max-width:1180px){
  .ftap{width:170px;right:calc(50% + 64px)}
  .ftap .fa{width:28px;height:52px}
  .ftap .fb{width:38px;height:62px}
  .ftap .ka,.ftap .kb{width:40px;height:27px;margin-top:-13.5px}
  .ftap .ka{left:30px} .ftap .kb{right:40px}
  @keyframes ftapA{0%,12%{transform:translateX(0)}32%,68%{transform:translateX(15px)}88%,100%{transform:translateX(0)}}
  @keyframes ftapB{0%,12%{transform:translateX(0)}32%,68%{transform:translateX(-15px)}88%,100%{transform:translateX(0)}}
}
@media(max-width:920px){ .ftap{display:none} }
@media (prefers-reduced-motion: reduce){
  .jchain.live .ftap .ka,.jchain.live .ftap .kb,.jchain.live .ftap .fg{animation:none}
}

/* ============================================================
   RELAY v13 (30 Jul 2026) - FOURTH graphic: the candidate's own verdict.
   Spec SS20A.14 "Candidate one-tap verdict" + SS19 three-way receipt +
   the SS3.4C/SS20A.15A adjudication principle (selective re-examination).
   This is the RESPONSE side's public-verifiable path, the counterpart to the
   hourly custody proof in .pchain.
   Three parallel checks, not a sequence - so a grid, not a chain.
   ============================================================ */
.vgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;max-width:1080px;margin:0 auto}
.vn{background:var(--card);border:1px solid rgba(255,255,255,.08);border-radius:16px;
  padding:34px 26px;text-align:center;position:relative;transition:.3s}
.vn:hover{border-color:rgba(55,211,154,.45)}
.vn .jic{margin:0 auto 20px;opacity:.3;transform:scale(.92)}
.jic.pass{background:linear-gradient(135deg,#37d39a,var(--cy))}
.jic.pass svg{stroke:#37d39a}
.vn b{font-family:'Days One',sans-serif;font-weight:400;font-size:1.08rem;display:block;
  color:#fff;margin-bottom:10px}
.vn>span{display:block;font-size:.83rem;color:var(--muted);line-height:1.6}
.vn u{display:inline-block;margin-top:14px;text-decoration:none;font-size:.66rem;
  font-weight:700;letter-spacing:.12em;text-transform:uppercase;padding:5px 14px;
  border-radius:999px;background:rgba(55,211,154,.14);color:#7ce8bd;opacity:0}

.vgrid.live .vn:nth-child(1) .jic{animation:vpass 9s ease-out infinite}
.vgrid.live .vn:nth-child(2) .jic{animation:vpass 9s ease-out infinite;animation-delay:1s}
.vgrid.live .vn:nth-child(3) .jic{animation:vpass 9s ease-out infinite;animation-delay:2s}
.vgrid.live .vn:nth-child(1) u{animation:vchip 9s ease-out infinite}
.vgrid.live .vn:nth-child(2) u{animation:vchip 9s ease-out infinite;animation-delay:1s}
.vgrid.live .vn:nth-child(3) u{animation:vchip 9s ease-out infinite;animation-delay:2s}
@keyframes vpass{
  0%{opacity:.3;transform:scale(.92)}
  7%{opacity:1;transform:scale(1.07)}
  13%{opacity:1;transform:scale(1)}
  88%{opacity:1;transform:scale(1)}
  96%,100%{opacity:.3;transform:scale(.92)}
}
@keyframes vchip{0%,8%{opacity:0}14%{opacity:1}88%{opacity:1}96%,100%{opacity:0}}

@media(max-width:920px){ .vgrid{grid-template-columns:1fr} }
@media (prefers-reduced-motion: reduce){
  .vgrid.live .vn .jic,.vgrid.live .vn u{animation:none}
  .vn .jic{opacity:1;transform:none}
  .vn u{opacity:1}
}

/* ============================================================
   RELAY v14 (30 Jul 2026) - Face-Tap inset corrected and SYNCED.
   Govinda: the cards were OVERLAPPING. They must EDGE-MATE - the Relay Card
   edge itself is a face, 10mm x 45mm, so the two cards are coplanar and butt
   along that narrow edge. The name stays "Face-Tap"; the depiction is
   edge-face mating.
   Geometry in the 208px box: card A 34-84, gap 84-110, card B 110-160.
   Each card moves exactly 13px inward, so both edges land on x=97 and STOP.
   No overlap. The contact bar sits on that seam.
   Timing: the inset appears just before its capsule starts travelling,
   the bar peaks EXACTLY at the capsule's mid-journey, and the inset clears
   just after the capsule merges into the device below. Three windows, matching
   capV1 (mid 26.5%), capV2 (mid 42.5%) and capV3 (mid 58.5%) of the 20s cycle.
   ============================================================ */
.ftap{opacity:0}
.ftap .ka,.ftap .kb{width:50px;height:36px;margin-top:-18px}
.ftap .ka{left:34px}
.ftap .kb{left:110px;right:auto}
.ftap .fg{left:97px;top:50%;width:9px;height:40px;margin:-20px 0 0 -4.5px}
.ftap .fa{left:0;top:14px;width:32px;height:58px}
.ftap .fb{left:162px;right:auto;top:8px;width:44px;height:70px}
.ftap .fl{bottom:-19px}

/* --- window 1: syncs with capV1, mid-journey at 26.5% --- */
.jchain.rchain.live .jseg:nth-of-type(2) .ftap{animation:ftapShow1 20s linear infinite}
.jchain.rchain.live .jseg:nth-of-type(2) .ftap .ka{animation:ftapA1 20s ease-in-out infinite}
.jchain.rchain.live .jseg:nth-of-type(2) .ftap .kb{animation:ftapB1 20s ease-in-out infinite}
.jchain.rchain.live .jseg:nth-of-type(2) .ftap .fg{animation:ftapG1 20s linear infinite}
@keyframes ftapShow1{0%,19%{opacity:0}20.5%{opacity:1}32.5%{opacity:1}34%,100%{opacity:0}}
@keyframes ftapA1{0%,20.5%{transform:translateX(0)}25%{transform:translateX(13px)}28%{transform:translateX(13px)}32.5%,100%{transform:translateX(0)}}
@keyframes ftapB1{0%,20.5%{transform:translateX(0)}25%{transform:translateX(-13px)}28%{transform:translateX(-13px)}32.5%,100%{transform:translateX(0)}}
@keyframes ftapG1{0%,25.6%{opacity:0}26.5%{opacity:1}27.2%{opacity:1}28%,100%{opacity:0}}

/* --- window 2: syncs with capV2, mid-journey at 42.5% --- */
.jchain.live .jseg:nth-of-type(4) .ftap{animation:ftapShow2 20s linear infinite}
.jchain.live .jseg:nth-of-type(4) .ftap .ka{animation:ftapA2 20s ease-in-out infinite}
.jchain.live .jseg:nth-of-type(4) .ftap .kb{animation:ftapB2 20s ease-in-out infinite}
.jchain.live .jseg:nth-of-type(4) .ftap .fg{animation:ftapG2 20s linear infinite}
@keyframes ftapShow2{0%,35%{opacity:0}36.5%{opacity:1}48.5%{opacity:1}50%,100%{opacity:0}}
@keyframes ftapA2{0%,36.5%{transform:translateX(0)}41%{transform:translateX(13px)}44%{transform:translateX(13px)}48.5%,100%{transform:translateX(0)}}
@keyframes ftapB2{0%,36.5%{transform:translateX(0)}41%{transform:translateX(-13px)}44%{transform:translateX(-13px)}48.5%,100%{transform:translateX(0)}}
@keyframes ftapG2{0%,41.6%{opacity:0}42.5%{opacity:1}43.2%{opacity:1}44%,100%{opacity:0}}

/* --- window 3: syncs with capV3, mid-journey at 58.5% --- */
.jchain.live .jseg:nth-of-type(6) .ftap{animation:ftapShow3 20s linear infinite}
.jchain.live .jseg:nth-of-type(6) .ftap .ka{animation:ftapA3 20s ease-in-out infinite}
.jchain.live .jseg:nth-of-type(6) .ftap .kb{animation:ftapB3 20s ease-in-out infinite}
.jchain.live .jseg:nth-of-type(6) .ftap .fg{animation:ftapG3 20s linear infinite}
@keyframes ftapShow3{0%,51%{opacity:0}52.5%{opacity:1}64.5%{opacity:1}66%,100%{opacity:0}}
@keyframes ftapA3{0%,52.5%{transform:translateX(0)}57%{transform:translateX(13px)}60%{transform:translateX(13px)}64.5%,100%{transform:translateX(0)}}
@keyframes ftapB3{0%,52.5%{transform:translateX(0)}57%{transform:translateX(-13px)}60%{transform:translateX(-13px)}64.5%,100%{transform:translateX(0)}}
@keyframes ftapG3{0%,57.6%{opacity:0}58.5%{opacity:1}59.2%{opacity:1}60%,100%{opacity:0}}

@media(max-width:1180px){
  .ftap{width:176px}
  .ftap .fa{width:27px;height:49px;top:12px}
  .ftap .fb{left:138px;width:37px;height:59px;top:7px}
  .ftap .ka,.ftap .kb{width:42px;height:30px;margin-top:-15px}
  .ftap .ka{left:29px}
  .ftap .kb{left:93px}
  .ftap .fg{left:82px;height:34px;margin-top:-17px}
  @keyframes ftapA1{0%,20.5%{transform:translateX(0)}25%{transform:translateX(11px)}28%{transform:translateX(11px)}32.5%,100%{transform:translateX(0)}}
  @keyframes ftapB1{0%,20.5%{transform:translateX(0)}25%{transform:translateX(-11px)}28%{transform:translateX(-11px)}32.5%,100%{transform:translateX(0)}}
  @keyframes ftapA2{0%,36.5%{transform:translateX(0)}41%{transform:translateX(11px)}44%{transform:translateX(11px)}48.5%,100%{transform:translateX(0)}}
  @keyframes ftapB2{0%,36.5%{transform:translateX(0)}41%{transform:translateX(-11px)}44%{transform:translateX(-11px)}48.5%,100%{transform:translateX(0)}}
  @keyframes ftapA3{0%,52.5%{transform:translateX(0)}57%{transform:translateX(11px)}60%{transform:translateX(11px)}64.5%,100%{transform:translateX(0)}}
  @keyframes ftapB3{0%,52.5%{transform:translateX(0)}57%{transform:translateX(-11px)}60%{transform:translateX(-11px)}64.5%,100%{transform:translateX(0)}}
}
@media (prefers-reduced-motion: reduce){ .ftap{opacity:1} }

/* ============================================================
   RELAY v15 (30 Jul 2026)
   - Candidate Device: the SEALED / OPENS AT EXAM HOUR pill is replaced by the
     caption "decrypting device", in the same italic format as the
     "non-decrypting device" caption on the intermediaries. The two now read as
     a deliberate pair: three devices cannot open it, one can.
   - A BIGGER CLOCK moves to the top-left corner of the Candidate card. It is
     dim until the capsule lands, then lights and sweeps to exam hour, which is
     the moment the paper becomes readable.
   - The small clock that used to live inside the icon stage is retired on the
     question chain (the response chain keeps that slot for its verify tick).
   ============================================================ */
.jn .bigclock{position:absolute;top:15px;left:16px;width:54px;height:54px;border-radius:50%;
  border:2.5px solid var(--amber);background:#0d0d13;z-index:5;opacity:.3}
.jn .bigclock::before{content:"";position:absolute;left:50%;top:4px;width:2px;height:6px;
  margin-left:-1px;background:var(--amber);border-radius:1px;opacity:.85}
.jn .bigclock::after{content:"";position:absolute;left:50%;top:50%;width:5px;height:5px;
  margin:-2.5px 0 0 -2.5px;border-radius:50%;background:var(--amber)}
.jn .bigclock i{position:absolute;left:50%;top:7px;width:2.5px;height:21px;margin-left:-1.25px;
  background:var(--amber);border-radius:2px;transform-origin:50% 100%}
.jchain.live .jn .bigclock{animation:bclock 20s linear infinite}
.jchain.live .jn .bigclock i{animation:bhand 20s linear infinite}
@keyframes bclock{0%,62%{opacity:.3}66%{opacity:1}85%{opacity:1}90%,100%{opacity:.3}}
@keyframes bhand{0%,64%{transform:rotate(0deg)}85%{transform:rotate(1080deg)}100%{transform:rotate(1080deg)}}
/* superseded by the corner badge on the question chain only */
.jchain:not(.rchain) .dfx u{display:none}

@media(max-width:920px){
  .jn .bigclock{width:44px;height:44px;top:12px;left:12px;border-width:2px}
  .jn .bigclock i{height:17px;top:6px}
}
@media (prefers-reduced-motion: reduce){
  .jchain.live .jn .bigclock,.jchain.live .jn .bigclock i{animation:none}
  .jn .bigclock{opacity:1}
}

/* ============================================================
   RELAY v16 (30 Jul 2026) - three envelopes on response hop 2.
   Govinda: three red envelopes travel from Invigilator to Centre Head.
   The response chain now aggregates 1 -> 3 -> 5, mirroring the question
   chain's narrowing 5 -> 3 -> 1.
   The generic .multi offsets are tuned for five items; .m3 spreads three
   and biases them LEFT of the connector so they never cross the hop label,
   which begins at 50% + 40px.
   ============================================================ */
.rchain .jseg.multi.m3 i:nth-of-type(1){left:-58px}
.rchain .jseg.multi.m3 i:nth-of-type(2){left:-30px}
.rchain .jseg.multi.m3 i:nth-of-type(3){left:-2px}
@media(max-width:1180px){
  .rchain .jseg.multi.m3 i:nth-of-type(1){left:-48px}
  .rchain .jseg.multi.m3 i:nth-of-type(2){left:-25px}
  .rchain .jseg.multi.m3 i:nth-of-type(3){left:-2px}
}

/* ============================================================
   RELAY v17 (30 Jul 2026) - the capsule DECRYPTS at the desk instead of
   disappearing. Govinda: "Once the Capsule Cube enters Candidate it should not
   disappear. It should rather get-decrypted into Readable QP. But that should
   happen exactly when the Clock at top left corner stops/halts."

   The clock hand (bhand) reaches 1080deg and HALTS at 85% of the 20s cycle.
   Everything below is pinned to that instant:
     64.5%      the same isometric cube lands at the desk and sits sealed
     85.0%      clock halts -> cube swells and bursts
     85.5%      a ring flashes outward from the burst point
     87.0%      a readable question paper has scaled into its place
     87-96%     the paper stays readable (the exam is running)
     98.5%      reset
   Question chain only - the response chain keeps dcapR6 / dverify.
   ============================================================ */

/* the cube at the desk is the SAME object as the one that travelled:
   isometric, with the two skewed faces */
.jchain:not(.rchain) .dfx b{width:40px;height:40px;border-radius:5px;margin-left:-20px;
  background:linear-gradient(160deg,#6fd6f7,#3aa9dc);
  box-shadow:0 0 24px rgba(46,197,246,.6)}
.jchain:not(.rchain) .dfx b::before{content:"";position:absolute;top:-13px;left:0;
  width:40px;height:13px;background:#a5e7fb;
  transform:skewX(-45deg);transform-origin:bottom left;border:none;border-radius:0}
.jchain:not(.rchain) .dfx b::after{content:"";position:absolute;top:0;right:-13px;
  width:13px;height:40px;background:#2589b8;
  transform:skewY(-45deg);transform-origin:top left;border:none;border-radius:0;
  left:auto;bottom:auto;margin:0}
.jchain:not(.rchain).live .dfx b{animation:dcapQ 20s linear infinite}
@keyframes dcapQ{
  0%,63.5%{opacity:0;transform:scale(.7)}
  65%{opacity:1;transform:scale(1)}
  84%{opacity:1;transform:scale(1)}
  85%{opacity:1;transform:scale(1.18)}
  87.5%{opacity:0;transform:scale(1.75)}
  100%{opacity:0;transform:scale(1.75)}
}

/* the decrypt burst - a ring expanding from where the cube was */
.jchain:not(.rchain) .dfx::after{content:"";position:absolute;left:50%;top:32px;
  width:22px;height:22px;margin-left:-11px;border-radius:50%;
  border:2px solid var(--cy);opacity:0;pointer-events:none}
.jchain:not(.rchain).live .dfx::after{animation:dburstQ 20s linear infinite}
@keyframes dburstQ{
  0%,84.6%{opacity:0;transform:scale(.3)}
  85.6%{opacity:.95;transform:scale(1)}
  88.5%{opacity:0;transform:scale(2.8)}
  100%{opacity:0;transform:scale(2.8)}
}

/* the readable question paper it becomes, and it STAYS readable */
.jchain:not(.rchain) .dfx s{position:absolute;left:50%;top:24px;width:38px;height:48px;
  margin-left:-19px;border-radius:3px;background:#eef3f7;text-decoration:none;opacity:0;
  box-shadow:0 0 26px rgba(255,255,255,.4)}
.jchain:not(.rchain) .dfx s::after{content:"";position:absolute;left:6px;top:7px;
  width:26px;height:2px;background:#0d0d13;
  box-shadow:0 7px 0 #0d0d13,0 14px 0 #0d0d13,0 21px 0 #0d0d13,0 28px 0 -1px #0d0d13}
.jchain:not(.rchain).live .dfx s{animation:dpaperQ 20s linear infinite}
@keyframes dpaperQ{
  0%,84.8%{opacity:0;transform:scale(.45)}
  87%{opacity:1;transform:scale(1.08)}
  88.5%{opacity:1;transform:scale(1)}
  96%{opacity:1;transform:scale(1)}
  98.5%,100%{opacity:0;transform:scale(1)}
}

/* the clock stays lit while the paper is readable, so the halt is legible */
@keyframes bclock{0%,62%{opacity:.3}66%{opacity:1}96%{opacity:1}98.5%,100%{opacity:.3}}

/* ============================================================
   RELAY v18 (31 Jul 2026) - three fixes from Govinda
   1. Board Evaluation Vault: the group of red packets no longer vanishes on
      arrival. Five envelopes land together, SEPARATE into a fan, then ALL
      decrypt at the same instant (85%), after the chain has verified.
   2. The Relay Card caption must sit on ONE line and must never overlay the
      animation - nowrap, smaller, and pushed clear below the box.
   3. The devices move WITH their Relay Cards, because the cards are plugged
      into them. Same keyframes, now applied to .fa / .fb as well.
   ============================================================ */

/* ---------- 1. arrive as a group, fan out, decrypt together ---------- */
.jchain.rchain .dfx b{display:none}          /* superseded by the five envelopes */
.rchain .dfx i{position:absolute;left:50%;top:34px;width:26px;height:19px;margin-left:-13px;
  border-radius:2px;background:linear-gradient(160deg,#ef5a50,#c9352c);opacity:0;
  box-shadow:0 0 12px rgba(224,72,63,.5)}
.rchain .dfx i::after{content:"";position:absolute;left:50%;top:50%;width:6px;height:6px;
  margin:-3px 0 0 -3px;border-radius:50%;background:#fff;opacity:0}
.rchain .dfx i::before{content:"";position:absolute;left:4px;top:5px;width:18px;height:1.5px;
  background:#0d0d13;box-shadow:0 4px 0 #0d0d13,0 8px 0 #0d0d13;opacity:0}
.rchain .dfx i:nth-of-type(1){--dx:-28px;--dy:-18px}
.rchain .dfx i:nth-of-type(2){--dx:28px;--dy:-18px}
.rchain .dfx i:nth-of-type(3){--dx:-30px;--dy:14px}
.rchain .dfx i:nth-of-type(4){--dx:30px;--dy:14px}
.rchain .dfx i:nth-of-type(5){--dx:0px;--dy:-2px}
.jchain.rchain.live .dfx i{animation:renv 20s linear infinite}
.jchain.rchain.live .dfx i::after{animation:renvSeal 20s linear infinite}
.jchain.rchain.live .dfx i::before{animation:renvLines 20s linear infinite}
@keyframes renv{
  0%,63.5%{opacity:0;transform:translate(0,0) scale(.5);background:linear-gradient(160deg,#ef5a50,#c9352c)}
  65.5%{opacity:1;transform:translate(0,0) scale(1);background:linear-gradient(160deg,#ef5a50,#c9352c)}
  73%{opacity:1;transform:translate(var(--dx),var(--dy)) scale(1);background:linear-gradient(160deg,#ef5a50,#c9352c)}
  75.4%{opacity:1;transform:translate(var(--dx),var(--dy)) scale(1);background:linear-gradient(160deg,#ef5a50,#c9352c)}
  76%{opacity:1;transform:translate(var(--dx),var(--dy)) scale(1.16);background:#eef3f7}
  77.2%{opacity:1;transform:translate(var(--dx),var(--dy)) scale(1);background:#eef3f7}
  96%{opacity:1;transform:translate(var(--dx),var(--dy)) scale(1);background:#eef3f7}
  98.5%,100%{opacity:0;transform:translate(var(--dx),var(--dy)) scale(1);background:#eef3f7}
}
@keyframes renvSeal{0%,64%{opacity:0}66%{opacity:1}75.4%{opacity:1}76%,100%{opacity:0}}
@keyframes renvLines{0%,75.6%{opacity:0}77.2%{opacity:1}96%{opacity:1}98.5%,100%{opacity:0}}
/* one decrypt flash for the whole group */
.rchain .dfx::after{content:"";position:absolute;left:50%;top:34px;width:24px;height:24px;
  margin-left:-12px;border-radius:50%;border:2px solid #37d39a;opacity:0;pointer-events:none}
.jchain.rchain.live .dfx::after{animation:rburst 20s linear infinite}
@keyframes rburst{
  0%,75.5%{opacity:0;transform:scale(.3)}
  76.5%{opacity:.9;transform:scale(1)}
  79.2%{opacity:0;transform:scale(3)}
  100%{opacity:0;transform:scale(3)}
}

/* ---------- 2. caption on one line, clear of the artwork ---------- */
.ftap .fl{bottom:-24px;white-space:nowrap;font-size:.55rem;letter-spacing:.06em;line-height:1}

/* ---------- 3. the devices travel with their cards ---------- */
.jchain.rchain.live .jseg:nth-of-type(2) .ftap .fa{animation:ftapA1 20s ease-in-out infinite}
.jchain.rchain.live .jseg:nth-of-type(2) .ftap .fb{animation:ftapB1 20s ease-in-out infinite}
.jchain.live .jseg:nth-of-type(4) .ftap .fa{animation:ftapA2 20s ease-in-out infinite}
.jchain.live .jseg:nth-of-type(4) .ftap .fb{animation:ftapB2 20s ease-in-out infinite}
.jchain.live .jseg:nth-of-type(6) .ftap .fa{animation:ftapA3 20s ease-in-out infinite}
.jchain.live .jseg:nth-of-type(6) .ftap .fb{animation:ftapB3 20s ease-in-out infinite}

@media (prefers-reduced-motion: reduce){
  .jchain.rchain.live .dfx i,.jchain.rchain.live .dfx i::after,
  .jchain.rchain.live .dfx i::before,.jchain.rchain.live .dfx::after{animation:none}
}

/* ============================================================
   RELAY v19 (31 Jul 2026) - Govinda's five corrections
   1. Board Vault -> Board QP Vault (markup).
   2. Candidate circle is EMPTY by default; the cube fills it on arrival
      (icon svg removed in markup).
   3. The sealed item entering the vault is a QUESTION PAPER, not ruled paper:
      three option rows (dot + bar) with a padlock badge at the top right.
   4. The cube is now optically CENTRED in the 96px circle. An isometric cube
      is not centred by centring its front face - the top face adds 13px above
      and the right face 13px to the right, so the whole solid sits up and left.
      Compensated: top 22->34px, margin-left -20->-26px.
   5. Response Candidate: no incoming paper-with-padlock. The red envelope is
      generated in place, which is what actually happens at submit.
   ============================================================ */

/* ---------- 3. the encrypted question paper ---------- */
.vfx b{top:26px;width:36px;height:46px;margin-left:-18px;border-radius:3px;
  background:#eef3f7;box-shadow:0 0 18px rgba(255,255,255,.5)}
/* three option rows: dots ... */
.vfx b em{position:absolute;left:6px;top:12px;width:5px;height:5px;border-radius:50%;
  background:#11131a;box-shadow:0 12px 0 #11131a,0 24px 0 #11131a;font-style:normal}
/* ... and their answer bars */
.vfx b s{position:absolute;left:15px;top:13.5px;width:15px;height:2.5px;border-radius:1px;
  background:#11131a;box-shadow:0 12px 0 #11131a,0 24px 0 #11131a;text-decoration:none}
/* padlock badge, top right - shackle then body, body paints over the shackle foot */
.vfx b::before{content:"";position:absolute;left:27px;top:-11px;width:14px;height:9px;
  box-sizing:border-box;border:2.5px solid #11131a;border-bottom:none;
  border-radius:7px 7px 0 0;background:none}
.vfx b::after{content:"";position:absolute;left:25px;top:-3px;width:18px;height:13px;
  border-radius:2px;background:#11131a;box-shadow:0 0 0 2px #eef3f7;border:none;
  bottom:auto;right:auto;margin:0}

/* ---------- 4. centre the isometric cube in the circle ---------- */
.jchain:not(.rchain) .dfx b{top:34px;margin-left:-26px}

/* ---------- 5. response candidate: envelope only, no incoming paper ---------- */
.rchain .vfx b em,.rchain .vfx b s,.rchain .vfx b::before{display:none}
.rchain .vfx b{top:32px;width:46px;height:33px;margin-left:-23px;border-radius:2px;
  background:linear-gradient(160deg,#ef5a50,#c9352c);box-shadow:0 0 20px rgba(224,72,63,.55)}
.rchain .vfx b::after{content:"";display:block;position:absolute;left:50%;top:50%;
  right:auto;bottom:auto;width:9px;height:9px;margin:-4.5px 0 0 -4.5px;border-radius:50%;
  background:#fff;box-shadow:0 0 7px rgba(255,255,255,.8);border:none}
.jchain.rchain.live .vfx b{animation:rsheetV19 20s linear infinite}
@keyframes rsheetV19{
  0%{opacity:0;transform:scale(.35)}
  4%{opacity:1;transform:scale(1.12)}
  8%{opacity:1;transform:scale(1)}
  19%{opacity:1;transform:scale(1)}
  23%{opacity:0;transform:scale(1)}
  100%{opacity:0;transform:scale(1)}
}

/* ============================================================
   RELAY v20 (31 Jul 2026)
   - The CSS-shape padlock read as a blob at 18x22px. Replaced with a real
     inline SVG lock (body, shackle, keyhole) inside the paper, so it stays
     dark-on-white and never overhangs onto the dark vault background.
   - Paper re-flowed to make room: 36x52, padlock top-right, the three option
     rows moved below it.
   ============================================================ */
.vfx b{top:22px;width:36px;height:52px;margin-left:-18px}
/* the old CSS-shape padlock is retired (the .rchain wax seal keeps ::after) */
.vfx b::before,.vfx b::after{display:none}
/* real padlock, sits fully inside the sheet */
.vfx b u{position:absolute;left:17px;top:3px;width:16px;height:16px;text-decoration:none}
.vfx b u svg{display:block;width:16px;height:16px}
/* option rows, re-flowed under the padlock */
.vfx b em{left:6px;top:26px;box-shadow:0 9px 0 #11131a,0 18px 0 #11131a}
.vfx b s{left:15px;top:27.5px;box-shadow:0 9px 0 #11131a,0 18px 0 #11131a}

/* response candidate keeps the envelope only - no paper, no padlock */
.rchain .vfx b u{display:none}
.rchain .vfx b::after{display:block}

/* ============================================================
   RELAY v21 (31 Jul 2026) - FIFTH graphic: "Watch the answer become evidence"
   Source: campaign-04.jpg section 1 "On the Candidate Device" (Govinda-verified).
   The on-device sealing chain - tap, sign, hash-link, encrypt, seal - was the
   one part of the story the site did not cover. Sits between the hourly public
   proof (.pchain) and the candidate verdict (.vgrid).
   Five lettered steps A-E. No looping animation: a staggered .reveal entrance
   only, so no new selector had to be added to durjeya.js.
   ============================================================ */
.sgrid{display:grid;grid-template-columns:repeat(5,1fr);gap:16px;max-width:1140px;margin:0 auto}
.sgrid .sn{background:var(--card);border:1px solid rgba(255,255,255,.08);border-radius:16px;
  padding:30px 20px 26px;text-align:center;position:relative;transition:.3s}
.sgrid .sn:hover{border-color:rgba(124,58,237,.5);transform:translateY(-4px)}
.sgrid .sn .sl{position:absolute;top:12px;left:14px;width:26px;height:26px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  font-family:'Days One',sans-serif;font-size:.78rem;color:#fff;
  background:rgba(255,255,255,.09);border:1px solid var(--line)}
.sgrid .sn .jic{margin:4px auto 18px}
.sgrid .sn b{font-family:'Days One',sans-serif;font-weight:400;font-size:.96rem;display:block;
  color:#fff;margin-bottom:9px;line-height:1.38}
.sgrid .sn>span{display:block;font-size:.8rem;color:var(--muted);line-height:1.58}
/* badge colours: three build steps, then locked, then sealed */
.jic.step{background:linear-gradient(135deg,var(--vio),var(--cy))}
.jic.step svg{stroke:var(--cy)}
.jic.seal{background:linear-gradient(135deg,#ef5a50,#c9352c)}
.jic.seal svg{stroke:#ef5a50}
/* a fourth stagger step, for the fifth card */
.d4{transition-delay:.4s}

@media(max-width:1100px){
  .sgrid{grid-template-columns:repeat(3,1fr)}
  .sgrid .sn .jic{width:78px;height:78px}
  .sgrid .sn .jic svg{width:38px;height:38px}
}
@media(max-width:720px){ .sgrid{grid-template-columns:1fr} }

/* ============================================================
   RELAY v22 (1 Aug 2026) - standalone Face-Tap demo for the Relay Cards
   article. Reuses every .ftap sub-element style; only the container and the
   loop differ. Gated on .live like every other animated block.
   ============================================================ */
.ftapdemo{position:relative;height:170px;margin:34px 0;background:var(--card);
  border:1px solid var(--line);border-radius:16px;overflow:hidden}
.ftapdemo .ftap{opacity:1;top:50%;left:50%;right:auto;transform:translate(-50%,-50%)}
.ftapdemo .ftap .fl{bottom:-26px}
.ftapdemo.live .ftap .ka,.ftapdemo.live .ftap .fa{animation:ftapDA 5s ease-in-out infinite}
.ftapdemo.live .ftap .kb,.ftapdemo.live .ftap .fb{animation:ftapDB 5s ease-in-out infinite}
.ftapdemo.live .ftap .fg{animation:ftapDG 5s ease-in-out infinite}
@keyframes ftapDA{0%,12%{transform:translateX(0)}32%,68%{transform:translateX(13px)}88%,100%{transform:translateX(0)}}
@keyframes ftapDB{0%,12%{transform:translateX(0)}32%,68%{transform:translateX(-13px)}88%,100%{transform:translateX(0)}}
@keyframes ftapDG{0%,30%{opacity:0}36%{opacity:1}64%{opacity:1}70%,100%{opacity:0}}
@media (prefers-reduced-motion: reduce){
  .ftapdemo.live .ftap .ka,.ftapdemo.live .ftap .kb,.ftapdemo.live .ftap .fa,
  .ftapdemo.live .ftap .fb,.ftapdemo.live .ftap .fg{animation:none}
}
/* amber card for the 5th article */
.th.e{background:linear-gradient(135deg,#083a4d,#2EC5F6)}

/* ============================================================
   ARTICLE PHOTO FIGURES (1 Aug 2026) - real hardware photographs in
   Insights articles. .afig already existed for placeholder tiles; these
   rules make it carry an actual <img>, plus a two-up grid.
   ============================================================ */
.afig img{display:block;width:100%;height:auto}
.afig figcaption{padding:13px 18px;font-size:.8rem;color:var(--faint);line-height:1.55}
.afig figcaption b{color:#fff;font-weight:600}
.afigs{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin:32px 0}
.afigs .afig{margin:0}
.afigs{align-items:stretch}
.afigs .afig{display:flex;flex-direction:column;margin:0}
.afigs .afig img{height:500px;width:auto;max-width:100%;object-fit:contain;margin:0 auto}
.afigs .afig figcaption{margin-top:auto}
@media(max-width:720px){ .afigs{grid-template-columns:1fr} .afigs .afig img{height:auto;width:100%} }
/* ============================================================
   LAN THREAT MAP (1 Aug 2026) - static diagram for the
   "Hidden in plain sight" LAN-based CBT article.
   EVERY selector is scoped to .lanmap. A bare class here would
   collide exactly the way .sn did - see the CSS CLASS COLLISION
   note in CLAUDE.md.
   No .live gating: static .reveal entrance only, so durjeya.js
   does NOT need a fifth selector.
   ============================================================ */
.lanmap{margin:34px 0;padding:28px 18px 16px;border:1px solid var(--line);
  border-radius:16px;background:var(--card);overflow-x:auto}
.lanmap .lmchain{display:grid;grid-template-columns:1.2fr .8fr 1.2fr .8fr 1.2fr .8fr 1.2fr;
  align-items:start;gap:4px;min-width:640px}
.lanmap .lmn{text-align:center;padding:0 2px}
.lanmap .lmg{display:block;width:54px;height:44px;margin:0 auto 12px;position:relative;
  border:2px solid rgba(46,197,246,.5);border-radius:7px;background:rgba(46,197,246,.07);
  color:rgba(46,197,246,.8)}
.lanmap .lmg::before,.lanmap .lmg::after{content:"";position:absolute;left:9px;right:9px;
  height:3px;border-radius:2px;background:currentColor}
/* server: three stacked bars */
.lanmap .lmg.srv::before{top:9px;box-shadow:0 10px 0 currentColor}
.lanmap .lmg.srv::after{top:29px}
/* switch: three port lights */
.lanmap .lmg.sw::before{top:19px;left:14px;right:auto;width:5px;height:5px;border-radius:50%;
  box-shadow:10px 0 0 currentColor,20px 0 0 currentColor}
.lanmap .lmg.sw::after{display:none}
/* terminal: screen over a stand */
.lanmap .lmg.trm::before{top:7px;bottom:13px;left:8px;right:8px;height:auto;
  border:2px solid currentColor;background:transparent;border-radius:3px}
.lanmap .lmg.trm::after{bottom:5px;left:17px;right:17px}
.lanmap .lmn b{display:block;font-family:'Days One',sans-serif;font-weight:400;
  font-size:.78rem;color:#fff;line-height:1.35;margin-bottom:5px}
.lanmap .lmn i{display:block;font-style:normal;font-size:.66rem;color:var(--faint);line-height:1.45}
.lanmap .lmlink{padding-top:16px;text-align:center}
.lanmap .lmpins{min-height:27px}
.lanmap .lmpin{display:inline-block;width:19px;height:19px;line-height:18px;border-radius:50%;
  margin:0 2px 8px;font-size:.64rem;font-weight:700;color:#fff;
  background:#c9352c;border:1px solid rgba(255,255,255,.28)}
.lanmap .lmline{height:2px;border-radius:2px;margin-bottom:9px;
  background:linear-gradient(90deg,rgba(124,58,237,.3),rgba(46,197,246,.65))}
.lanmap .lmlink em{display:block;font-style:normal;font-size:.6rem;letter-spacing:.09em;
  text-transform:uppercase;color:var(--faint);line-height:1.4}
.lanmap .lmcap{margin:18px 0 0;font-size:.74rem;color:var(--faint);text-align:center}
@media(max-width:720px){
  .lanmap{padding:22px 14px 12px}
  .lanmap .lmchain{min-width:600px}
}
/* red colour key - security-threat articles */
.artrule.f{background:linear-gradient(90deg,#4a1410,#c9352c,#f5a623)}
.th.f{background:linear-gradient(135deg,#4a1410,#c9352c)}

/* ============================================================
   SEAM SPOTLIGHT (1 Aug 2026) - animated overlay marking the
   edge-face mating seam on the three Relay Card photographs.
   Visual vocabulary is deliberately identical to the .ftap
   contact bar: a violet -> cyan -> magenta capsule with a glow.

   Geometry was measured off the photographs, not estimated:
     sm1 relay-card-mated  576x1228  seam (156,570)-(276,570) horizontal
     sm2 relay-card-edge  1280x737   seam (568,268)-(443,525) tilt 26.0deg
     sm3 relay-card-detail 1280x526  seam (593,145)-(487,365) tilt 25.8deg
   Each bar is authored VERTICAL and rotated by --rot, so one set of
   keyframes drives all three. Length is a % of container HEIGHT, which
   is what keeps it locked to the seam at every display size.

   Scoped to .afig throughout (see the CSS CLASS COLLISION note).
   Gated on .live - durjeya.js observes .seamfx - so nothing animates
   off screen. transform/opacity only: no filter, no backdrop-filter.
   ============================================================ */
.afig .afigim{display:block;position:relative;line-height:0}
.afigs .afig .afigim{width:-moz-fit-content;width:fit-content;margin:0 auto}
.afig .seamfx{position:absolute;width:6px;pointer-events:none;
  transform:translate(-50%,-50%) rotate(var(--rot,0deg));
  opacity:0;transition:opacity .7s ease .25s}
.afig .seamfx.live{opacity:1;animation:seamCycle 2.85s ease-in-out infinite}
.afig .seamfx.sm1{left:37.5%;top:46.4%;height:9.8%;--rot:90deg}
.afig .seamfx.sm2{left:39.5%;top:53.8%;height:38.8%;--rot:26deg}
.afig .seamfx.sm3{left:41.5%;top:49.1%;height:51.2%;--rot:39.7deg}
/* soft field radiating from the seam */
.afig .seamfx::before{content:"";position:absolute;left:50%;top:50%;
  width:54px;height:114%;transform:translate(-50%,-50%);border-radius:50%;
  background:radial-gradient(ellipse at center,rgba(124,58,237,.46),
    rgba(46,197,246,.18) 46%,transparent 72%)}
/* the ping - spreads ACROSS the seam, never along it */
.afig .seamfx::after{content:"";position:absolute;inset:-2px;border-radius:99px;
  border:1px solid rgba(46,197,246,.9)}
/* the contact bar */
.afig .seamfx i{position:absolute;inset:0;border-radius:99px;
  background:linear-gradient(180deg,var(--vio),var(--cy) 55%,var(--mag));
  box-shadow:0 0 12px rgba(124,58,237,.9),0 0 26px rgba(46,197,246,.55)}
.afig .seamfx.live i{animation:seamGlow 2.85s ease-in-out infinite}
.afig .seamfx.live::before{animation:seamHalo 2.85s ease-in-out infinite}
.afig .seamfx.live::after{animation:seamPing 2.85s ease-out infinite}
/* ONE 2.85s CYCLE, all five layers phase-locked to it:
     0.00 - 0.30s   fade in
     0.30 - 1.80s   bar marks the seam (glow swells)
     1.80 - 2.10s   fade out
     2.10 - 2.85s   FULLY CLEAR - the bare edge-face mating line is visible (0.75s)
   The rest gap is deliberate: the overlay points at the seam, then gets out
   of the way so the reader can actually look at it. */
@keyframes seamCycle{0%{opacity:0}11%{opacity:1}63%{opacity:1}74%{opacity:0}100%{opacity:0}}
@keyframes seamGlow{0%{opacity:.72;transform:scaleX(1)}
  37%{opacity:1;transform:scaleX(1.5)}
  74%,100%{opacity:.72;transform:scaleX(1)}}
@keyframes seamHalo{0%{opacity:.5;transform:translate(-50%,-50%) scale(1)}
  37%{opacity:1;transform:translate(-50%,-50%) scale(1.18)}
  74%,100%{opacity:.5;transform:translate(-50%,-50%) scale(1)}}
@keyframes seamPing{0%{opacity:.85;transform:scaleX(1)}
  49%,100%{opacity:0;transform:scaleX(7)}}
@media(prefers-reduced-motion:reduce){
  .afig .seamfx.live,.afig .seamfx.live i,
  .afig .seamfx.live::before,.afig .seamfx.live::after{animation:none}
}

/* ============================================================
   SEAM LASER DOTS (2 Aug 2026) - two glowing red dots per Relay
   Card, with a laser that emanates from one and merges into the
   dot on the opposite card. Two pairs, firing in OPPOSITE
   directions at the same instant.

   Timings are Govinda's, mapped onto the 2.85s cycle:
     0.60s -> 21.0%   dots appear
     0.90s -> 31.6%   lasers fire
     1.20s -> 42.1%   lasers merge into the opposite dot
     1.50s -> 52.6%   dots disappear

   Geometry: these live INSIDE .seamfx, which is already rotated
   to the seam angle, so local +X is perpendicular to the seam
   IN THE IMAGE PLANE and one rule set serves every seam angle.
   --doff = perpendicular offset. --dang = extra rotation.

   !! --dang exists because image-plane perpendicular is NOT
   perpendicular on the card SURFACE when the photo is oblique.
   relay-card-detail is shot at a steep angle: its card long-edges
   (which really are perpendicular to the seam) run 11.0 deg below
   horizontal, measured by fitting all four card edges, while the
   seamfx local +X points 39.7 deg below horizontal. Hence
   --dang:-28.7deg on sm3 only. sm1 and sm2 are near top-down and
   stay at 0. If a photo is ever replaced, re-measure the card
   edge direction and set --dang = (edge angle) - (--rot).

   Beams grow by CLIP-PATH, not scaleX, because transform is
   already spent on the rotation; clipping also keeps both ends
   locked to the dots regardless of --dang.
   ============================================================ */
.afig .seamfx{--doff:24px;--dang:0deg}
.afig .seamfx.sm1{--doff:15px}          /* mated: only ~49px of card across the seam */
.afig .seamfx.sm3{--dang:-28.7deg}      /* detail: steep oblique view, see above */
.afig .seamfx b{position:absolute;left:50%;width:9px;height:9px;border-radius:50%;
  margin-left:-4.5px;margin-top:-4.5px;opacity:0;pointer-events:none;
  background:radial-gradient(circle at 40% 36%,#fff 0%,#ff6a6a 34%,#d60000 100%);
  box-shadow:0 0 7px rgba(255,40,40,1),0 0 16px rgba(255,40,40,.72),0 0 30px rgba(255,0,0,.4)}
.afig .seamfx b.p1a{top:28%;transform:rotate(var(--dang)) translateX(calc(var(--doff) * -1))}
.afig .seamfx b.p1b{top:28%;transform:rotate(var(--dang)) translateX(var(--doff))}
.afig .seamfx b.p2a{top:72%;transform:rotate(var(--dang)) translateX(calc(var(--doff) * -1))}
.afig .seamfx b.p2b{top:72%;transform:rotate(var(--dang)) translateX(var(--doff))}
/* beams: centred on the seam, rotated about their own centre so both ends
   land exactly on the dots; direction of travel comes from the clip side */
.afig .seamfx s{position:absolute;left:50%;height:3px;border-radius:2px;opacity:0;
  width:calc(var(--doff) * 2);margin-left:calc(var(--doff) * -1);margin-top:-1.5px;
  transform:rotate(var(--dang));transform-origin:50% 50%;pointer-events:none;
  box-shadow:0 0 8px rgba(255,45,45,.95),0 0 18px rgba(255,45,45,.55)}
.afig .seamfx s.l1{top:28%;clip-path:inset(0 100% 0 0);
  background:linear-gradient(90deg,rgba(255,45,45,.5),#ff4d4d 62%,#fff 100%)}
.afig .seamfx s.l2{top:72%;clip-path:inset(0 0 0 100%);
  background:linear-gradient(90deg,#fff 0%,#ff4d4d 38%,rgba(255,45,45,.5))}
.afig.lz-on .seamfx.live b{animation:seamDot 2.85s linear infinite}
.afig.lz-on .seamfx.live s.l1{animation:seamBeamL 2.85s linear infinite}
.afig.lz-on .seamfx.live s.l2{animation:seamBeamR 2.85s linear infinite}
@keyframes seamDot{0%,19%{opacity:0}21%{opacity:1}30%{opacity:.72}38%{opacity:1}
  50%{opacity:1}52.6%,100%{opacity:0}}
@keyframes seamBeamL{0%,31.5%{opacity:0;clip-path:inset(0 100% 0 0)}
  31.6%{opacity:1;clip-path:inset(0 100% 0 0)}
  42.1%{opacity:1;clip-path:inset(0 0 0 0)}
  50%{opacity:1;clip-path:inset(0 0 0 0)}
  52.6%,100%{opacity:0;clip-path:inset(0 0 0 0)}}
@keyframes seamBeamR{0%,31.5%{opacity:0;clip-path:inset(0 0 0 100%)}
  31.6%{opacity:1;clip-path:inset(0 0 0 100%)}
  42.1%{opacity:1;clip-path:inset(0 0 0 0)}
  50%{opacity:1;clip-path:inset(0 0 0 0)}
  52.6%,100%{opacity:0;clip-path:inset(0 0 0 0)}}
@media(prefers-reduced-motion:reduce){
  .afig.lz-on .seamfx.live b{animation:none;opacity:1}
  .afig.lz-on .seamfx.live s{animation:none;opacity:1;clip-path:inset(0 0 0 0)}
}

/* Laser toggle - OFF by default. The button is INJECTED by durjeya.js rather
   than authored into post_content, so WordPress content filtering can never
   strip it and the three article bodies stay untouched. `.lz-on` lands on the
   .afig; the dot/beam base rules already sit at opacity:0, so gating only the
   animation selectors is enough - no display juggling, no !important. */
.afig .lzt{position:absolute;right:10px;bottom:10px;z-index:4;
  display:inline-flex;align-items:center;gap:7px;padding:5px 11px 5px 8px;
  border-radius:99px;cursor:pointer;line-height:1;
  font-family:'Open Sans',sans-serif;font-size:.6rem;font-weight:600;
  letter-spacing:.09em;text-transform:uppercase;color:rgba(255,255,255,.7);
  background:rgba(10,10,14,.6);border:1px solid rgba(255,255,255,.16);
  -webkit-backdrop-filter:none;backdrop-filter:none;transition:.25s}
.afig .lzt:hover{color:#fff;background:rgba(10,10,14,.82);border-color:rgba(255,255,255,.32)}
.afig .lzt:focus-visible{outline:2px solid var(--cy);outline-offset:2px}
.afig .lzt i{position:relative;flex:none;width:22px;height:12px;border-radius:99px;
  background:rgba(255,255,255,.2);transition:.25s}
.afig .lzt i::after{content:"";position:absolute;top:2px;left:2px;width:8px;height:8px;
  border-radius:50%;background:rgba(255,255,255,.8);transition:.25s}
.afig.lz-on .lzt{color:#fff;border-color:rgba(255,45,45,.55)}
.afig.lz-on .lzt i{background:rgba(255,45,45,.5)}
.afig.lz-on .lzt i::after{left:12px;background:#ff3b3b;box-shadow:0 0 7px rgba(255,45,45,.95)}
@media(max-width:600px){ .afig .lzt{right:7px;bottom:7px;font-size:.55rem;padding:4px 9px 4px 7px} }
/* hero pill: the avatar strip is detailed, so it is large on desktop and eased back on small screens */
@media(max-width:760px){ .cap img{height:56px} .cap .in{padding:10px 24px 10px 12px;font-size:.88rem;gap:11px} }
@media(max-width:460px){ .cap img{height:44px} .cap .in{font-size:.8rem} }

/* ============================================================
   RESPONSIVE FIXES (4 Aug 2026) - reported from an iPhone.
   Five separate causes, not one symptom:
     1. inline style="font-size:2.4rem" on .h2 beat EVERY media query,
        so headings stayed 38px on a 390px phone -> .h2j + clamp()
     2. .rsplit span and .phour span were white-space:nowrap, so the
        divider captions ran straight off the right edge
     3. .cards4 stopped at two columns, and grid items default to
        min-width:auto so a long word could push the track wider
        than the viewport -> one column under 600px + min-width:0
     4. .jstat was a non-wrapping flex row
     5. .jseg em was positioned BESIDE a 3px connector at
        left:calc(50% + 22px) with a ~190px width - guaranteed to
        overflow a 390px screen -> centred under the connector
   NOTE: body{overflow-x:hidden} was masking all of this. The page never
   showed a horizontal scrollbar, it just silently clipped. Always fix
   the cause; the hidden overflow makes these faults invisible in testing.
   ============================================================ */

/* 1. fluid heading - one rule, no breakpoints, and beats the inline size
      it replaced because .h2.h2j is (0,2,0) */
.h2.h2j,.h2j{font-size:clamp(1.45rem,5.6vw,2.4rem);line-height:1.16}
/* the About headings are plain <h2 class="reveal"> at an inline 2.2rem - same fault */
.h2k{font-size:clamp(1.35rem,5vw,2.2rem);line-height:1.18}

/* 2. divider captions may wrap */
.rsplit span,.phour span{white-space:normal;text-align:center}
@media(max-width:760px){
  .rsplit{gap:10px;margin:38px auto 22px}
  .rsplit span{font-size:.62rem;letter-spacing:.1em}
  .phour{gap:10px}
  .phour span{font-size:.64rem;letter-spacing:.1em;padding:6px 14px}
}

/* 3. founder / feature cards */
.cards4>*{min-width:0}
@media(max-width:600px){ .cards4{grid-template-columns:1fr} }

/* 4. stat rows wrap instead of overflowing */
.jstat{flex-wrap:wrap}

/* 5. hop labels cannot sit beside a 3px connector on a phone.
      IMPORTANT: .jseg em already carries transform:translateY(-50%) from the
      v6 block, so this override MUST be translate(-50%,-50%) or the label
      loses its vertical centring. The receipt token is hidden at this size
      because a centred full-width label would sit on top of it - the receipts
      are still described in the caption text below each chain. */
@media(max-width:600px){
  .jseg{height:170px}
  .jseg em{left:50%;transform:translate(-50%,-50%);width:calc(100vw - 40px);
    max-width:none;text-align:center}
  .jseg s{display:none}
}

/* ============================================================
   RESPONSIVE FIXES, PART 2 (4 Aug 2026) - from Govinda's marked-up screens.
   Two faults the first pass missed:

   6. THE FACE-TAP INSET WAS SIMPLY SWITCHED OFF ON PHONES.
      `@media(max-width:920px){ .ftap{display:none} }` was added back in v12
      because there is no room BESIDE a 3px connector on a narrow screen.
      But the Face-Tap is the single hardest idea on the page to convey in
      words, so hiding it on the device most readers use was the wrong call.
      It now stacks ABOVE the hop label instead of sitting beside the
      connector. Safe to re-position: the ftapShow1/2/3 keyframes animate
      OPACITY ONLY, so overriding `transform` here cannot break them.

   7. TWO IMAGES COLLIDED ON THE ABOUT PAGE.
      #story is [text][image] but #mission is [image][text] - neither uses
      .sm.flip. Collapsed to one column that yields
      text / image / image / text, so both photographs ended up adjacent and
      "Our Story" sat BELOW its picture while "Our Mission" sat above its own.
      Fixed structurally: on mobile any .sm child that is not .txt goes first,
      so every section reads picture-then-words regardless of DOM order.

   This block supersedes the max-width:600px .jseg rules in part 1 - it is
   later in source, so it wins at every width where both apply.
   ============================================================ */

@media(max-width:920px){
  /* 6. Face-Tap inset, centred above the label */
  .ftap{display:block;left:50%;right:auto;top:12px;transform:translateX(-50%);width:170px}
  .jseg{height:240px}
  .jseg em{top:auto;bottom:6px;left:50%;transform:translateX(-50%);
    width:calc(100vw - 40px);max-width:none;text-align:center}
  /* the receipt token would sit under the centred label; the receipts are
     still named in the caption under each chain */
  .jseg s{display:none}

  /* 7. picture first, then words, in every .sm section */
  .sm{gap:30px}
  .sm > :not(.txt){order:-1}
  .sm.flip .txt{order:0}
}

/* ============================================================
   MOBILE PART 3 (4 Aug 2026)

   (a) REGRESSION I INTRODUCED YESTERDAY. capV1/2/3 translate the capsule a
       FIXED 104px, which was sized for the old .jseg{height:118px}. Part 2
       raised the connector to 240px to fit the stacked Face-Tap, so the
       capsule was stopping less than halfway down. Mobile now has its own
       keyframes with the travel matched to the taller connector.
       LESSON: these chains animate in PIXELS, so any change to .jseg height
       must be paired with new travel keyframes.

   (b) Govinda: a capsule crossing the Face-Tap should go semi-transparent so
       the contact bar and its glow show through, then return to solid.
       Geometry: Face-Tap occupies y 12..96 of the 240px connector; the
       capsule is 44px tall and travels -8px -> 226px across its 11% window.
       It therefore clears the band at (96+8)/234 = 44.4% of its travel, i.e.
       ~4.9% of the cycle after it starts. Dip windows are exactly that.
       Applied ONLY to segments that actually carry a Face-Tap - the two
       secure-tunnel hops keep the plain keyframes.

   (c) The capsule must sit ABOVE the inset for the fade to reveal anything.
   ============================================================ */

@media(max-width:920px){
  /* (c) stacking: capsule over inset */
  .jseg .ftap{z-index:1}
  .jseg i{z-index:2}

  /* (a) plain travel, matched to the 240px connector - no Face-Tap on these
         two hops (both are the Board-Controlled Secure Tunnel) */
  .jchain.live .jseg:nth-of-type(2) i{animation:capM1 20s linear infinite}
  .jchain.rchain.live .jseg:nth-of-type(6) i{animation:capM3 20s linear infinite}

  /* (b) Face-Tap hops: same travel, with the transparency dip */
  .jchain.rchain.live .jseg:nth-of-type(2) i{animation:capM1d 20s linear infinite}
  .jchain.live .jseg:nth-of-type(4) i{animation:capM2d 20s linear infinite}
  .jchain.rchain.live .jseg:nth-of-type(4) i{animation:capM2d 20s linear infinite}
  .jchain.live .jseg:nth-of-type(6) i{animation:capM3d 20s linear infinite}

  /* response hop 2 never had a Face-Tap wired even though the design calls
     for one; ftapShow2 is already the matching 35-50% window */
  .jchain.rchain.live .jseg:nth-of-type(4) .ftap{animation:ftapShow2 20s linear infinite}
}

/* travel keyframes - transform is omitted mid-way on purpose so it keeps
   interpolating linearly; only opacity is being shaped in the dip */
@keyframes capM1{0%,19.5%{transform:translateY(-14px);opacity:0}21%{transform:translateY(-8px);opacity:1}
  32%{transform:translateY(226px);opacity:1}33.5%,100%{transform:translateY(226px);opacity:0}}
@keyframes capM2{0%,35.5%{transform:translateY(-14px);opacity:0}37%{transform:translateY(-8px);opacity:1}
  48%{transform:translateY(226px);opacity:1}49.5%,100%{transform:translateY(226px);opacity:0}}
@keyframes capM3{0%,51.5%{transform:translateY(-14px);opacity:0}53%{transform:translateY(-8px);opacity:1}
  64%{transform:translateY(226px);opacity:1}65.5%,100%{transform:translateY(226px);opacity:0}}

@keyframes capM1d{0%,19.5%{transform:translateY(-14px);opacity:0}
  21%{transform:translateY(-8px);opacity:.28}24.6%{opacity:.28}26.4%{opacity:1}
  32%{transform:translateY(226px);opacity:1}33.5%,100%{transform:translateY(226px);opacity:0}}
@keyframes capM2d{0%,35.5%{transform:translateY(-14px);opacity:0}
  37%{transform:translateY(-8px);opacity:.28}40.6%{opacity:.28}42.4%{opacity:1}
  48%{transform:translateY(226px);opacity:1}49.5%,100%{transform:translateY(226px);opacity:0}}
@keyframes capM3d{0%,51.5%{transform:translateY(-14px);opacity:0}
  53%{transform:translateY(-8px);opacity:.28}56.6%{opacity:.28}58.4%{opacity:1}
  64%{transform:translateY(226px);opacity:1}65.5%,100%{transform:translateY(226px);opacity:0}}

/* ------------------------------------------------------------
   THREE-COLUMN CARD GRIDS ON /nexa/
   page-nexa.php carried style="grid-template-columns:repeat(3,1fr)" INLINE,
   which beats every media query - the same fault class as the inline
   font-size on the headings. The inline style is removed and replaced by
   .c3, so the grid can actually collapse.
   ------------------------------------------------------------ */
.cards4.c3{grid-template-columns:repeat(3,1fr)}
@media(max-width:920px){ .cards4.c3{grid-template-columns:1fr 1fr} }
@media(max-width:600px){ .cards4.c3{grid-template-columns:1fr} }

/* ============================================================
   VIDEO POSTERS (4 Aug 2026)
   The two Google Drive /preview iframes were replaced by a poster image with
   a play button. Three reasons, in order:
     1. FIT. Drive's player has a minimum internal width, so at ~350px it
        rendered wider than its frame and was clipped - the copyright card
        was cut off at both edges on a phone. Nothing in CSS can fix that:
        the overflow happens inside a cross-origin iframe. An <img> with
        object-fit:cover fits any container exactly.
     2. WEIGHT. The homepage was loading two third-party embeds on every
        visit. Now nothing loads from Drive until someone presses play,
        which matters for the Lighthouse >= 85 mobile target.
     3. LOOK. The poster is the film's own frame, so the card is legible
        before playback instead of showing whatever frame Drive picked.
   Pressing play swaps the iframe in, in place - it does not open a new tab.
   ============================================================ */
.vidbox{position:relative;padding-top:56.25%;border-radius:16px;overflow:hidden;
  border:1px solid rgba(255,255,255,.1);background:#0d0d13}
.vidbox img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
/* The player is rendered at a FIXED 640px-wide box and then scaled down to
   fit. Drive's player has a minimum internal width - below roughly 500px it
   lays out wider than its frame and gets clipped, which is what cut the
   copyright card off at both edges on a phone. Scaling the IFRAME (not its
   content) sidesteps that entirely and is allowed cross-origin. JS sets the
   width/height/scale and re-fits on resize. */
.vidbox iframe{position:absolute;left:0;top:0;border:0;transform-origin:0 0}
.vidplay{position:absolute;inset:0;width:100%;height:100%;padding:0;border:0;cursor:pointer;
  background:radial-gradient(ellipse at center,rgba(10,10,14,.30),rgba(10,10,14,.55));
  display:flex;align-items:center;justify-content:center;transition:background .25s}
.vidplay:hover{background:radial-gradient(ellipse at center,rgba(10,10,14,.18),rgba(10,10,14,.45))}
.vidplay:focus-visible{outline:3px solid var(--cy);outline-offset:-3px}
.vidplay i{position:relative;display:block;width:72px;height:72px;border-radius:50%;
  background:linear-gradient(135deg,rgba(124,58,237,.95),rgba(46,197,246,.95));
  box-shadow:0 10px 34px rgba(0,0,0,.5);transition:transform .25s}
.vidplay i::after{content:"";position:absolute;left:50%;top:50%;margin:-12px 0 0 -6px;
  border-left:20px solid #fff;border-top:12px solid transparent;border-bottom:12px solid transparent}
.vidbox:hover .vidplay i{transform:scale(1.08)}
@media(max-width:600px){ .vidplay i{width:58px;height:58px}
  .vidplay i::after{margin:-10px 0 0 -5px;border-left-width:16px;border-top-width:10px;border-bottom-width:10px} }

/* ============================================================
   FORMS - wired 6 Aug 2026
   The contact and subscribe blocks were <div>s of unnamed inputs with a dead
   button: everything a visitor typed was discarded on click. They are real
   <form> elements now. Three things needed styling:
     1. .dj-hp  - the honeypot. Taken out of flow rather than display:none so
        it cannot become a flex item in .sub-row, and so a bot reading the
        computed style still sees a normal field.
     2. .djnote - submission feedback. Without it the page comes back looking
        identical and the visitor cannot tell whether it worked.
     3. .sub-row .btn - was an <a>, is now a <button>; buttons do not inherit
        font or border defaults from the anchor rules.
   ============================================================ */
.dj-hp{position:absolute!important;left:-9999px!important;top:auto;width:1px;height:1px;overflow:hidden}
.djnote{margin:0 0 18px;padding:13px 16px;border-radius:8px;font-size:.9rem;line-height:1.5;
  border:1px solid;text-align:left}
.djnote-ok{background:rgba(46,197,246,.10);border-color:rgba(46,197,246,.45);color:#dff4ff}
.djnote-err{background:rgba(255,62,165,.10);border-color:rgba(255,62,165,.45);color:#ffe3f2}
.sub-row .btn{border:none;cursor:pointer;font-family:'Open Sans';font-size:.95rem;line-height:1.7}
.cform .fnote{margin:14px 0 0;text-align:center}
@media(max-width:600px){ .djnote{font-size:.85rem;padding:11px 13px} }
/* ============================================================
   LEGAL PAGES (6 Aug 2026)
   durjeya-theme.css opens with *{margin:0;padding:0} and the only <ul> rules are
   scoped to .keybox / .vs .side, so a bare list on a legal page has no indent and
   its markers fall outside the box. These pages are plain prose, so they get their
   own minimal typographic reset.
   ============================================================ */
.legal{display:block;margin:0 0 30px}
.legal h2{font-family:'Days One';font-size:1.45rem;color:#fff;margin:34px 0 14px;line-height:1.25}
.legal h2:first-child{margin-top:0}
.legal h3{font-size:1.05rem;color:var(--cy);margin:26px 0 10px}
.legal p{margin:0 0 12px;color:var(--muted);line-height:1.7}
.legal ul{list-style:disc;padding-left:22px;display:grid;gap:8px;margin:14px 0}
.legal li{color:var(--muted);line-height:1.65}
.legal a{color:var(--cy)}
.legal strong,.legal b{color:#fff}
.legal table{width:100%;border-collapse:collapse;margin:14px 0}
.legal th,.legal td{border:1px solid var(--line);padding:9px 11px;text-align:left;
  font-size:.9rem;color:var(--muted)}
.legal th{color:#fff;background:rgba(255,255,255,.03)}
@media(max-width:600px){ .legal h2{font-size:1.2rem} }
/* ============================================================
   PHOTO GALLERY (7 Aug 2026)
   Replaces the placeholder .gallery tiles. Every tile carries a dated caption
   because the build visible in several frames predates the CORTEX naming - a
   dated photograph with honest provenance reads as evidence, an undated one
   reads as marketing. Masonry-free: a plain grid with a fixed tile height and
   object-fit:cover, because the source frames are phone shots at 2.22:1 and
   1:2.22 and nothing is a tidy 3:2.
   ============================================================ */
.gal2{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;margin-top:8px}
.gcard{margin:0;background:var(--card);border:1px solid var(--line);border-radius:14px;
  overflow:hidden;display:flex;flex-direction:column}
.gcard a{display:block;line-height:0}
.gcard img{width:100%;height:230px;object-fit:cover;display:block;
  transition:transform .35s ease}
.gcard a:hover img{transform:scale(1.04)}
.gcard figcaption{padding:14px 16px 16px;display:flex;flex-direction:column;gap:5px;
  font-size:.85rem;line-height:1.5}
.gcard figcaption b{color:#fff;font-weight:600}
.gcard figcaption span{color:var(--faint);font-size:.76rem;letter-spacing:.02em}
@media(max-width:920px){ .gal2{grid-template-columns:1fr 1fr;gap:14px}
  .gcard img{height:190px} }
@media(max-width:600px){ .gal2{grid-template-columns:1fr}
  .gcard img{height:220px} }
@media(prefers-reduced-motion:reduce){ .gcard img,.gcard a:hover img{transition:none;transform:none} }