/* ============================================================
   Feature-modal vignettes — a small looping diagram above the
   "What it is" definition in the pricing capability dialog.

   Grammar shared by every vignette: the faint grid ground,
   green (--accent) = legit / pass / protection, red (--alert)
   = threat / blocked, JetBrains Mono micro-labels.

   Base (un-animated) styles are the RESOLVED end-state of each
   scene, so prefers-reduced-motion shows a finished static
   diagram, not an empty panel.
   ============================================================ */

#capd-vig {
  --alert-soft: rgba(229, 72, 77, .12);
  --alert-line: rgba(229, 72, 77, .30);
  position: relative; height: 150px; margin-top: 20px; overflow: hidden;
  background:
    linear-gradient(var(--line-2) 1px, transparent 1px),
    linear-gradient(90deg, var(--line-2) 1px, transparent 1px),
    var(--bg-2);
  background-size: 28px 28px, 28px 28px, auto;
  border: 1px solid var(--line);
}
#capd-vig[hidden] { display: none; }

.vg { position: absolute; inset: 0; font-family: "JetBrains Mono", ui-monospace, Menlo, monospace; }

/* shared vocabulary ------------------------------------------------ */
.vg .lb {                                   /* micro-label */
  position: absolute; font-size: 9px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--faint); white-space: nowrap;
}
.vg .fl {                                   /* flag chip */
  position: absolute; font-size: 9px; letter-spacing: .12em; text-transform: uppercase;
  padding: 3px 8px; white-space: nowrap;
}
.vg .fl.ok  { color: var(--accent); border: 1px solid var(--accent-line); background: var(--accent-soft); }
.vg .fl.bad { color: var(--alert);  border: 1px solid var(--alert-line);  background: var(--alert-soft); }
.vg .tag {                                  /* live · loop bottom-left */
  position: absolute; left: 10px; bottom: 8px; z-index: 3;
  font-size: 9px; letter-spacing: .14em; text-transform: uppercase; color: var(--faint);
}
.vg .tag::before { content: "●"; color: var(--accent); margin-right: 6px; font-size: 7px;
                   vertical-align: 1px; animation: vg-blink 2s steps(1) infinite; }
@keyframes vg-blink { 50% { opacity: .25; } }
.vg .chip {                                 /* skeleton message chip */
  position: absolute; width: 34px; height: 14px;
  border: 1px solid var(--line); background: var(--surface);
  display: flex; align-items: center; gap: 3px; padding: 0 5px; box-sizing: border-box;
}
.vg .chip i { display: block; height: 2px; background: var(--faint); }
.vg .chip i:nth-child(1) { width: 10px; }
.vg .chip i:nth-child(2) { width: 6px; }

/* =========================================================
   gate — join CAPTCHA: human passes, script doesn't
   ========================================================= */
.vg-gate .gate {
  position: absolute; left: 50%; top: 26px; bottom: 30px; width: 2px;
  background: linear-gradient(var(--line) 0 38%, transparent 38% 62%, var(--line) 62% 100%);
}
.vg-gate .gate::before, .vg-gate .gate::after {
  content: ""; position: absolute; left: -3px; width: 8px; height: 8px;
  border: 1px solid var(--faint); background: var(--bg-2); box-sizing: border-box;
}
.vg-gate .gate::before { top: calc(38% - 4px); }
.vg-gate .gate::after  { bottom: calc(38% - 4px); }
.vg-gate .actor { position: absolute; top: 50%; margin-top: -6px; width: 12px; height: 12px; }
.vg-gate .hum { left: calc(50% + 46px); border-radius: 50%;
                background: var(--accent); box-shadow: 0 0 10px var(--accent-line);
                animation: vg-humanPass 7s cubic-bezier(.4,0,.3,1) infinite; }
.vg-gate .bot { left: calc(50% - 40px); border: 1.5px solid var(--alert);
                background: var(--alert-soft); box-sizing: border-box;
                animation: vg-botBlocked 7s cubic-bezier(.4,0,.3,1) infinite; }
.vg-gate .ok  { top: 22%; left: 56%; }
.vg-gate .bad { top: 60%; right: 62%; }
.vg-gate .fl.ok  { animation: vg-popA 7s infinite; }
.vg-gate .fl.bad { animation: vg-popB 7s infinite; }
@keyframes vg-humanPass {
  0%        { left: -24px; opacity: 0; }
  6%        { opacity: 1; }
  22%, 30%  { left: calc(50% - 6px); }
  46%       { left: 104%; opacity: 1; }
  50%, 100% { left: 104%; opacity: 0; }
}
@keyframes vg-botBlocked {
  0%, 50%   { left: -24px; opacity: 0; transform: translateX(0); }
  56%       { opacity: 1; }
  72%       { left: calc(50% - 18px); transform: translateX(0); }
  75%       { left: calc(50% - 18px); transform: translateX(-4px); }
  78%       { left: calc(50% - 18px); transform: translateX(2px); }
  81%       { left: calc(50% - 18px); transform: translateX(-2px); }
  88%       { left: calc(50% - 18px); opacity: 1; }
  96%, 100% { left: calc(50% - 18px); opacity: 0; }
}
@keyframes vg-popA { 0%, 24% { opacity: 0; } 27%, 44% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes vg-popB { 0%, 74% { opacity: 0; } 77%, 94% { opacity: 1; } 98%, 100% { opacity: 0; } }

/* =========================================================
   flood — anti-flood: rapid fire from one account gets clamped
   ========================================================= */
.vg-flood .src { position: absolute; left: 26px; top: 50%; margin-top: -6px; width: 12px; height: 12px;
                 border-radius: 50%; border: 1.5px solid var(--faint); background: var(--surface);
                 box-sizing: border-box; }
.vg-flood .src::after { content: ""; position: absolute; inset: 3px; border-radius: 50%; background: var(--alert);
                        opacity: .8; }
.vg-flood .chip { top: calc(50% - 7px); left: calc(58% - 40px); opacity: .35; }
.vg-flood .c1 { animation: vg-floodPass 6.5s linear infinite; }
.vg-flood .c2 { animation: vg-floodPass 6.5s linear infinite .45s; }
.vg-flood .c3 { animation: vg-floodPass 6.5s linear infinite .9s; }
.vg-flood .c4 { animation: vg-floodStop 6.5s linear infinite; }
.vg-flood .c5 { animation: vg-floodStop 6.5s linear infinite .5s; }
.vg-flood .clamp { position: absolute; left: 58%; top: 26px; bottom: 30px; width: 2px;
                   background: var(--alert); transform-origin: top; opacity: .8;
                   animation: vg-clampIn 6.5s infinite; }
.vg-flood .lb.top { left: 26px; top: 12px; }
.vg-flood .fl.bad { left: 58%; top: 18px; transform: translateX(-50%); animation: vg-floodFlag 6.5s infinite; }
@keyframes vg-floodPass {
  0%        { left: 40px; opacity: 0; }
  3%        { opacity: 1; }
  26%       { left: 96%; opacity: 1; }
  29%, 100% { left: 96%; opacity: 0; }
}
@keyframes vg-floodStop {
  0%, 33%   { left: 40px; opacity: 0; }
  36%       { opacity: 1; }
  52%       { left: calc(58% - 40px); opacity: 1; }
  64%       { left: calc(58% - 40px); opacity: .35; }
  93%       { left: calc(58% - 40px); opacity: .35; }
  100%      { left: calc(58% - 40px); opacity: 0; }
}
@keyframes vg-clampIn  { 0%, 40% { transform: scaleY(0); } 47%, 94% { transform: scaleY(1); } 100% { transform: scaleY(1); opacity: 0; } }
@keyframes vg-floodFlag { 0%, 52% { opacity: 0; } 58%, 92% { opacity: 1; } 98%, 100% { opacity: 0; } }

/* =========================================================
   raid — anti-raid: the join wave gets cut
   ========================================================= */
.vg-raid .bars { position: absolute; left: 22px; right: 22px; top: 20px; bottom: 30px;
                 display: flex; align-items: flex-end; gap: 6px; }
.vg-raid .bar { flex: 1; background: var(--faint); opacity: .55; transform-origin: bottom;
                animation: vg-barGrow 6s ease-out infinite; }
.vg-raid .bar.raid { background: var(--alert); opacity: .45; transform: scaleY(.12);
                     animation: vg-raidGrow 6s ease-out infinite; }
.vg-raid .threshold { position: absolute; left: 14px; right: 14px; top: 52%;
                      border-top: 1px dashed var(--accent-line); }
.vg-raid .threshold .lb { right: 0; top: -16px; }
.vg-raid .fl.bad { top: 12px; left: 50%; transform: translateX(-50%); animation: vg-raidFlag 6s infinite; }
@keyframes vg-barGrow { 0% { transform: scaleY(0); } 12%, 100% { transform: scaleY(1); } }
@keyframes vg-raidGrow {
  0%, 34%   { transform: scaleY(0); opacity: .9; }
  44%       { transform: scaleY(1); }
  58%       { transform: scaleY(1); opacity: .9; }
  70%, 100% { transform: scaleY(.12); opacity: .45; }
}
@keyframes vg-raidFlag { 0%, 46% { opacity: 0; } 52%, 92% { opacity: 1; } 98%, 100% { opacity: 0; } }

/* =========================================================
   age — account-age screening
   ========================================================= */
.vg-age .row { position: absolute; left: 26px; right: 26px; height: 34px; }
.vg-age .r1 { top: 30px; } .vg-age .r2 { top: 78px; }
.vg-age .row .lb { left: 0; top: 0; }
.vg-age .agebar { position: absolute; left: 0; top: 16px; height: 6px; transform-origin: left; }
.vg-age .r1 .agebar { width: 62%; background: var(--accent-soft); border: 1px solid var(--accent-line);
                      animation: vg-drawX 6.5s ease-out infinite; }
.vg-age .r2 .agebar { width: 26px; background: var(--alert-soft); border: 1px solid var(--alert-line);
                      animation: vg-drawX 6.5s ease-out infinite .5s; }
.vg-age .st { position: absolute; right: 0; top: 12px; font-size: 9px; letter-spacing: .12em; text-transform: uppercase; }
.vg-age .r1 .st { color: var(--faint); }
.vg-age .r2 .st { color: var(--alert); animation: vg-fadeLate 6.5s infinite; }
.vg-age .r2::after { content: ""; position: absolute; left: -8px; right: -8px; top: 8px; bottom: -2px;
                     border: 1px dashed var(--alert-line); animation: vg-fadeLate 6.5s infinite; }
@keyframes vg-drawX { 0% { transform: scaleX(0); } 22%, 100% { transform: scaleX(1); } }
@keyframes vg-fadeLate { 0%, 34% { opacity: 0; } 44%, 94% { opacity: 1; } 100% { opacity: 1; } }

/* =========================================================
   probation — newcomer restrictions lift over the first days
   ========================================================= */
.vg-probation .lb.top { left: 26px; top: 14px; }
.vg-probation .track { position: absolute; left: 26px; right: 26px; top: 64px; height: 6px;
                       border: 1px solid var(--line); background: var(--surface); }
.vg-probation .prog { position: absolute; inset: 0; background: var(--accent-soft);
                      border-right: 2px solid var(--accent); transform-origin: left;
                      animation: vg-probProg 8s linear infinite; }
.vg-probation .lockrow { position: absolute; left: 26px; right: 26px; top: 92px;
                         display: flex; gap: 18px; }
.vg-probation .lk { font-size: 9px; letter-spacing: .12em; text-transform: uppercase;
                    color: var(--faint); text-decoration: line-through; text-decoration-color: var(--faint); }
.vg-probation .lk::before { content: "⊘ "; }
.vg-probation .lk1 { animation: vg-unlock 8s infinite; }
.vg-probation .lk2 { animation: vg-unlock2 8s infinite; }
.vg-probation .lk3 { animation: vg-unlock3 8s infinite; }
.vg-probation .fl.ok { right: 22px; top: 12px; animation: vg-probFlag 8s infinite; }
.vg-probation .d0 { left: 26px; top: 44px; } .vg-probation .d7 { right: 26px; top: 44px; }
@keyframes vg-probProg { 0% { transform: scaleX(0); } 88%, 100% { transform: scaleX(1); } }
/* locked = alert solid, unlocked = struck faint (base) */
@keyframes vg-unlock  { 0%      { color: var(--alert); text-decoration-color: transparent; }
                        28%,100%{ color: var(--faint); text-decoration-color: var(--faint); } }
@keyframes vg-unlock2 { 0%,28%  { color: var(--alert); text-decoration-color: transparent; }
                        56%,100%{ color: var(--faint); text-decoration-color: var(--faint); } }
@keyframes vg-unlock3 { 0%,56%  { color: var(--alert); text-decoration-color: transparent; }
                        86%,100%{ color: var(--faint); text-decoration-color: var(--faint); } }
@keyframes vg-probFlag { 0%, 84% { opacity: 0; } 90%, 100% { opacity: 1; } }

/* =========================================================
   morph — de-obfuscation + OCR: fold the tricks away, then match
   ========================================================= */
.vg-morph .ocr { position: absolute; left: 30px; top: 50%; margin-top: -17px; width: 40px; height: 30px;
                 border: 1px solid var(--line); background: var(--surface); overflow: hidden; }
.vg-morph .ocr .lb { left: 50%; top: 50%; transform: translate(-50%,-50%); }
.vg-morph .scan { position: absolute; left: 0; right: 0; top: 100%; height: 1px; background: var(--accent);
                  box-shadow: 0 0 8px var(--accent); animation: vg-ocrScan 7s infinite; }
.vg-morph .arr { position: absolute; left: 84px; top: 50%; transform: translateY(-50%);
                 color: var(--faint); font-size: 12px; }
.vg-morph .word { position: absolute; left: 108px; top: 50%; transform: translateY(-50%);
                  font-size: 16px; letter-spacing: .1em; display: flex; }
.vg-morph .ch { position: relative; color: var(--fg); }
.vg-morph .ch s { position: absolute; inset: 0; text-decoration: none; color: var(--alert);
                  opacity: 0; }
.vg-morph .ch b { font-weight: 400; }
.vg-morph .ch.sub s { animation: vg-chRaw 7s infinite; }
.vg-morph .ch.sub b { animation: vg-chNorm 7s infinite; }
.vg-morph .ch.sub:nth-child(2) s, .vg-morph .ch.sub:nth-child(2) b { animation-delay: .25s; }
.vg-morph .ch.sub:nth-child(4) s, .vg-morph .ch.sub:nth-child(4) b { animation-delay: .5s; }
.vg-morph .word::after { content: ""; position: absolute; left: -4px; right: -4px; bottom: -6px;
                         border-bottom: 2px solid var(--alert); animation: vg-fadeVeryLate 7s infinite; }
.vg-morph .fl.bad { right: 20px; bottom: 26px; animation: vg-fadeVeryLate 7s infinite; }
@keyframes vg-ocrScan { 0% { top: -2px; } 18% { top: 100%; } 100% { top: 100%; } }
@keyframes vg-chRaw  { 0%, 24% { opacity: 1; } 34%, 100% { opacity: 0; } }
@keyframes vg-chNorm { 0%, 24% { opacity: 0; } 34%, 100% { opacity: 1; } }
@keyframes vg-fadeVeryLate { 0%, 58% { opacity: 0; } 68%, 96% { opacity: 1; } 100% { opacity: 1; } }

/* =========================================================
   lexicon — multilingual scam phrases
   ========================================================= */
.vg-lexicon .lex { position: absolute; left: 30px; right: 26px; display: flex; align-items: center; gap: 12px; }
.vg-lexicon .lr1 { top: 28px; } .vg-lexicon .lr2 { top: 66px; } .vg-lexicon .lr3 { top: 104px; }
.vg-lexicon .lang { font-size: 9px; letter-spacing: .14em; text-transform: uppercase;
                    color: var(--faint); width: 20px; flex: none; }
.vg-lexicon .ph { font-size: 12px; color: var(--muted); text-decoration: line-through;
                  text-decoration-color: var(--alert); }
.vg-lexicon .x { color: var(--alert); font-size: 11px; margin-left: auto; }
.vg-lexicon .lr1 .ph { animation: vg-lexHit 7.5s infinite; }
.vg-lexicon .lr2 .ph { animation: vg-lexHit 7.5s infinite 1.4s; }
.vg-lexicon .lr3 .ph { animation: vg-lexHit 7.5s infinite 2.8s; }
.vg-lexicon .lr1 .x { animation: vg-lexX 7.5s infinite; }
.vg-lexicon .lr2 .x { animation: vg-lexX 7.5s infinite 1.4s; }
.vg-lexicon .lr3 .x { animation: vg-lexX 7.5s infinite 2.8s; }
@keyframes vg-lexHit {
  0%       { opacity: 0; text-decoration-color: transparent; }
  5%       { opacity: 1; text-decoration-color: transparent; }
  16%, 92% { opacity: 1; text-decoration-color: var(--alert); }
  100%     { opacity: 1; text-decoration-color: var(--alert); }
}
@keyframes vg-lexX { 0%, 14% { opacity: 0; } 20%, 100% { opacity: 1; } }

/* =========================================================
   match — pattern blocklists
   ========================================================= */
.vg-match .list { position: absolute; left: 26px; top: 30px; width: 168px; }
.vg-match .lrow { font-size: 10.5px; color: var(--faint); border: 1px solid var(--line);
                  background: var(--surface); padding: 5px 8px; margin-bottom: 6px;
                  white-space: nowrap; overflow: hidden; }
.vg-match .lrow.hit { color: var(--alert); border-color: var(--alert-line); background: var(--alert-soft);
                      animation: vg-rowHit 6.5s infinite; }
.vg-match .lb.top { left: 26px; top: 14px; }
.vg-match .chip { top: 64px; left: calc(100% - 120px); border-color: var(--alert);
                  background: var(--alert-soft); animation: vg-mChip 6.5s infinite; }
.vg-match .chip::after { content: ""; position: absolute; left: -2px; right: -2px; top: 50%;
                         border-top: 1.5px solid var(--alert); animation: vg-fadeMid 6.5s infinite; }
.vg-match .fl.bad { right: 20px; bottom: 26px; animation: vg-fadeMid 6.5s infinite; }
@keyframes vg-mChip {
  0%       { left: 104%; opacity: 0; border-color: var(--line); background: var(--surface); }
  6%       { opacity: 1; }
  34%      { left: calc(100% - 120px); border-color: var(--line); background: var(--surface); }
  44%, 100%{ left: calc(100% - 120px); border-color: var(--alert); background: var(--alert-soft); }
}
@keyframes vg-rowHit { 0%, 34% { color: var(--faint); border-color: var(--line); background: var(--surface); }
                       44%, 100% { color: var(--alert); border-color: var(--alert-line); background: var(--alert-soft); } }
@keyframes vg-fadeMid { 0%, 40% { opacity: 0; } 50%, 100% { opacity: 1; } }

/* =========================================================
   edit — edit re-checks: innocent post, edited into spam, caught
   ========================================================= */
.vg-edit .chip { width: 84px; height: 26px; left: 50%; top: 50%; transform: translate(-50%,-60%); gap: 4px; }
.vg-edit .chip i { height: 3px; }
.vg-edit .chip i:nth-child(1) { width: 22px; }
.vg-edit .chip i:nth-child(2) { width: 30px; }
.vg-edit .chip i:nth-child(3) { width: 14px; }
.vg-edit .chip i { background: var(--alert); animation: vg-editBars 7s infinite; }
.vg-edit .chip { border-color: var(--alert); background: var(--alert-soft); animation: vg-editBox 7s infinite; }
.vg-edit .pen { position: absolute; left: calc(50% + 40px); top: calc(50% - 36px); color: var(--muted);
                font-size: 13px; animation: vg-penBlink 7s infinite; }
.vg-edit .st1 { left: 50%; transform: translateX(-50%); top: 22px; color: var(--accent);
                font-size: 9px; letter-spacing: .12em; text-transform: uppercase; position: absolute;
                animation: vg-editOk 7s infinite; }
.vg-edit .fl.bad { left: 50%; transform: translateX(-50%); bottom: 24px; animation: vg-editBad 7s infinite; }
@keyframes vg-editBars { 0%, 30% { background: var(--faint); } 42%, 100% { background: var(--alert); } }
@keyframes vg-editBox  { 0%, 30% { border-color: var(--line); background: var(--surface); }
                         42%, 100% { border-color: var(--alert); background: var(--alert-soft); } }
@keyframes vg-penBlink { 0%, 26% { opacity: 0; } 30%, 34% { opacity: 1; } 36%, 40% { opacity: .2; }
                         42%, 50% { opacity: 1; } 56%, 100% { opacity: 0; } }
@keyframes vg-editOk  { 0%, 8% { opacity: 0; } 12%, 36% { opacity: 1; } 42%, 100% { opacity: 0; } }
@keyframes vg-editBad { 0%, 54% { opacity: 0; } 62%, 96% { opacity: 1; } 100% { opacity: 1; } }

/* =========================================================
   bayes — chips stream through the node; spam drops out
   ========================================================= */
.vg-bayes .node { position: absolute; left: 50%; top: 46px; width: 22px; height: 22px;
                  transform: translateX(-50%) rotate(45deg); box-sizing: border-box;
                  border: 1px solid var(--accent); background: var(--accent-soft);
                  animation: vg-nodePulse 2s ease-in-out infinite; }
.vg-bayes .lb.n { left: 50%; top: 78px; transform: translateX(-50%); }
.vg-bayes .chip { top: 50px; }
.vg-bayes .chip.ham { left: 12%; animation: vg-hamFlow 9s linear infinite; }
.vg-bayes .chip.ham.d3 { left: 72%; border-color: var(--accent-line); animation-delay: 6s; }
.vg-bayes .chip.spam { left: calc(50% + 40px); transform: translateY(46px); opacity: .8;
                       border-color: var(--alert); background: var(--alert-soft);
                       animation: vg-spamFlow 9s linear infinite 3s; }
.vg-bayes .meter { position: absolute; right: 12px; bottom: 8px; z-index: 3; text-align: right;
                   font-size: 9px; letter-spacing: .12em; text-transform: uppercase; color: var(--faint); }
.vg-bayes .meter b { display: block; width: 72px; height: 3px; background: var(--line);
                     margin-top: 4px; margin-left: auto; overflow: hidden; }
.vg-bayes .meter b s { display: block; height: 100%; background: var(--accent); text-decoration: none;
                       transform: scaleX(.86); transform-origin: left;
                       animation: vg-learn 9s ease-out infinite; }
@keyframes vg-nodePulse { 50% { box-shadow: 0 0 14px var(--accent-line); } }
@keyframes vg-hamFlow {
  0%   { left: -40px; opacity: 0; }
  4%   { opacity: 1; }
  15%  { left: calc(50% - 17px); border-color: var(--accent-line); }
  30%  { left: 104%; opacity: 1; }
  33%, 100% { left: 104%; opacity: 0; }
}
@keyframes vg-spamFlow {
  0%   { left: -40px; opacity: 0; transform: translateY(0); border-color: var(--line); background: var(--surface); }
  4%   { opacity: 1; }
  15%  { left: calc(50% - 17px); transform: translateY(0); border-color: var(--alert); background: var(--alert-soft); }
  28%  { left: calc(50% + 50px); transform: translateY(46px); opacity: .8; }
  33%, 100% { left: calc(50% + 60px); transform: translateY(58px); opacity: 0; }
}
@keyframes vg-learn { 0% { transform: scaleX(.55); } 60%, 100% { transform: scaleX(.86); } }

/* =========================================================
   cadence — behavioral signals: human rhythm vs machine rhythm
   ========================================================= */
.vg-cadence .crow { position: absolute; left: 26px; right: 26px; height: 36px; }
.vg-cadence .cr1 { top: 26px; } .vg-cadence .cr2 { top: 80px; }
.vg-cadence .crow .lb { left: 0; top: 0; }
.vg-cadence .ticks { position: absolute; left: 0; right: 0; top: 16px; height: 12px;
                     border-bottom: 1px solid var(--line); }
.vg-cadence .ticks i { position: absolute; bottom: 0; left: var(--x); width: 2px; height: 10px;
                       background: var(--faint); animation: vg-tickIn 7s infinite; animation-delay: var(--d); }
.vg-cadence .cr2 .ticks i { background: var(--alert); }
.vg-cadence .cr2 .st { position: absolute; right: 0; top: 0; color: var(--alert); font-size: 9px;
                       letter-spacing: .12em; text-transform: uppercase;
                       animation: vg-fadeVeryLate 7s infinite; }
.vg-cadence .cr2::after { content: ""; position: absolute; left: -8px; right: -8px; top: 12px; bottom: 0;
                          border: 1px dashed var(--alert-line); animation: vg-fadeVeryLate 7s infinite; }
@keyframes vg-tickIn { 0% { transform: scaleY(0); } 4%, 100% { transform: scaleY(1); } }

/* =========================================================
   clone — impersonation defense: the near-match admin
   ========================================================= */
.vg-clone .card { position: absolute; top: 44px; width: 132px; height: 44px; box-sizing: border-box;
                  border: 1px solid var(--line); background: var(--surface);
                  display: flex; align-items: center; gap: 8px; padding: 0 10px; }
.vg-clone .card .av { width: 18px; height: 18px; border-radius: 50%; background: var(--line); flex: none; }
.vg-clone .card .nm { font-size: 10.5px; color: var(--muted); display: block; white-space: nowrap; }
.vg-clone .card .nm .diff { color: var(--alert); font-weight: 600; }
.vg-clone .card .rl { display: block; width: 44px; height: 2px; background: var(--line-2); margin-top: 4px; }
.vg-clone .real { left: 26px; }
.vg-clone .real .av { background: var(--accent-soft); border: 1px solid var(--accent-line); box-sizing: border-box; }
.vg-clone .real::after { content: "✓"; position: absolute; right: 8px; top: 4px; color: var(--accent); font-size: 10px; }
.vg-clone .fake { right: 26px; border-color: var(--alert-line); animation: vg-fakeIn 7s infinite; }
.vg-clone .fake::after { content: "✕"; position: absolute; right: 8px; top: 4px; color: var(--alert); font-size: 10px;
                         animation: vg-fadeMid 7s infinite; }
.vg-clone .cmp { position: absolute; left: 166px; right: 166px; top: 65px;
                 border-top: 1px dashed var(--alert-line); animation: vg-fadeMid 7s infinite; }
.vg-clone .lb.t1 { left: 26px; top: 28px; } .vg-clone .lb.t2 { right: 26px; top: 28px; }
.vg-clone .fl.bad { left: 50%; transform: translateX(-50%); bottom: 22px; animation: vg-fadeVeryLate 7s infinite; }
@keyframes vg-fakeIn { 0% { opacity: 0; transform: translateX(16px); }
                       12% { opacity: 1; transform: translateX(0); border-color: var(--line); }
                       40%, 100% { border-color: var(--alert-line); opacity: 1; transform: translateX(0); } }

/* =========================================================
   scan — profile screening: the pitch lives in the bio
   ========================================================= */
.vg-scan .pcard { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
                  width: 190px; height: 84px; box-sizing: border-box;
                  border: 1px solid var(--line); background: var(--surface);
                  display: flex; gap: 12px; padding: 14px; overflow: hidden; }
.vg-scan .av { width: 26px; height: 26px; border-radius: 50%; background: var(--line); flex: none; }
.vg-scan .rows { flex: 1; }
.vg-scan .rows i { display: block; height: 3px; background: var(--line); margin-bottom: 9px; }
.vg-scan .rows .r1 { width: 60%; }
.vg-scan .rows .r2 { width: 92%; background: var(--alert); animation: vg-bioHit 6.5s infinite; }
.vg-scan .rows .r3 { width: 40%; }
.vg-scan .sweep { position: absolute; left: 0; right: 0; top: 100%; height: 1px; background: var(--accent);
                  box-shadow: 0 0 8px var(--accent); animation: vg-sweepY 6.5s infinite; }
.vg-scan .lb.top { left: 50%; transform: translateX(-50%); top: 14px; }
.vg-scan .fl.bad { right: 18px; bottom: 22px; animation: vg-fadeMid 6.5s infinite; }
@keyframes vg-sweepY { 0% { top: -2px; } 34% { top: 100%; } 100% { top: 100%; } }
@keyframes vg-bioHit { 0%, 22% { background: var(--line); } 34%, 100% { background: var(--alert); } }

/* =========================================================
   network — federations / fedcontrols: the ban propagates
   ========================================================= */
.vg-network svg { position: absolute; left: 50%; top: 46%; transform: translate(-50%,-50%);
                  width: 290px; height: 96px; overflow: visible; }
.vg-network .e { stroke: var(--line); stroke-width: 1; }
.vg-network .pulse { stroke: var(--accent); stroke-width: 1.5; stroke-dasharray: 8 130;
                     stroke-dashoffset: 8; animation: vg-pulseEdge 6.5s linear infinite; }
.vg-network .nd { fill: var(--surface); stroke: var(--faint); }
.vg-network .nd.hub { stroke: var(--accent); fill: var(--accent-soft); }
.vg-network .nd.spam { stroke: var(--alert); fill: var(--alert-soft); animation: vg-ndSpam 6.5s infinite; }
.vg-network .nd.armed { animation: vg-ndArm 6.5s infinite; }
.vg-network .lb.hublb { left: 50%; transform: translateX(-50%); bottom: 24px; }
.vg-network .lb.top { left: 26px; top: 14px; }
.vg-network .fl.ok { right: 20px; top: 14px; animation: vg-fadeVeryLate 6.5s infinite; }
@keyframes vg-ndSpam { 0%, 12% { stroke: var(--faint); fill: var(--surface); }
                       20%, 100% { stroke: var(--alert); fill: var(--alert-soft); } }
@keyframes vg-ndArm  { 0%, 40% { stroke: var(--faint); } 55%, 100% { stroke: var(--accent); } }
@keyframes vg-pulseEdge { 0%, 22% { stroke-dashoffset: 8; opacity: 0; }
                          26% { opacity: 1; }
                          55% { stroke-dashoffset: -130; opacity: 1; }
                          60%, 100% { stroke-dashoffset: -130; opacity: 0; } }

/* =========================================================
   rap — cross-chat reputation: the record travels with them
   ========================================================= */
.vg-rap .g { position: absolute; top: 58px; width: 24px; height: 24px; box-sizing: border-box;
             border: 1px solid var(--faint); background: var(--surface); }
.vg-rap .g1 { left: 12%; animation: vg-gFlash 7.5s infinite; }
.vg-rap .g2 { left: 34%; animation: vg-gFlash 7.5s infinite 1.2s; }
.vg-rap .g3 { left: 56%; animation: vg-gFlash 7.5s infinite 2.4s; }
.vg-rap .you { left: 82%; border-color: var(--accent); background: var(--accent-soft); }
.vg-rap .lb.youlb { left: 82%; top: 88px; }
.vg-rap .actor { position: absolute; top: 44px; left: 78%; width: 10px; height: 10px; border-radius: 50%;
                 background: var(--alert); animation: vg-rapWalk 7.5s linear infinite; }
.vg-rap .cnt { position: absolute; left: 12%; top: 24px; font-size: 9px; letter-spacing: .12em;
               text-transform: uppercase; color: var(--faint); }
.vg-rap .cnt s { text-decoration: none; color: var(--alert); position: relative; }
.vg-rap .cnt s i { font-style: normal; position: absolute; left: 0; opacity: 0; }
.vg-rap .cnt s .k0 { animation: vg-k 7.5s infinite; }
.vg-rap .cnt s .k1 { animation: vg-k 7.5s infinite 1.4s; }
.vg-rap .cnt s .k2 { animation: vg-k 7.5s infinite 2.6s; }
.vg-rap .cnt s .k3 { opacity: 1; animation: vg-kLast 7.5s infinite; }
.vg-rap .block { position: absolute; left: calc(82% - 8px); top: 46px; width: 2px; height: 44px;
                 background: var(--alert); animation: vg-fadeMid 7.5s infinite; }
.vg-rap .fl.bad { right: 18px; top: 20px; animation: vg-fadeMid 7.5s infinite; }
@keyframes vg-rapWalk { 0% { left: 6%; } 16% { left: 13%; } 32% { left: 35%; } 48% { left: 57%; }
                        62%, 94% { left: 78%; } 100% { left: 78%; opacity: 0; } }
@keyframes vg-gFlash { 0%, 14% { border-color: var(--faint); background: var(--surface); }
                       22%, 100% { border-color: var(--alert-line); background: var(--alert-soft); } }
@keyframes vg-k { 0% { opacity: 1; } 18% { opacity: 1; } 19%, 100% { opacity: 0; } }
@keyframes vg-kLast { 0%, 42% { opacity: 0; } 46%, 100% { opacity: 1; } }

/* =========================================================
   locks — content locks & night mode
   ========================================================= */
.vg-locks .lrow2 { position: absolute; left: 30px; display: flex; align-items: center; gap: 10px; }
.vg-locks .w1 { top: 30px; } .vg-locks .w2 { top: 64px; } .vg-locks .w3 { top: 98px; }
.vg-locks .lrow2 .lb { position: static; }
.vg-locks .lock { position: relative; width: 10px; height: 8px; background: var(--accent);
                  animation: vg-lockSnap 8s infinite; }
.vg-locks .w2 .lock { animation-delay: .5s; } .vg-locks .w3 .lock { animation-delay: 1s; }
.vg-locks .lock::before { content: ""; position: absolute; left: 2px; top: -5px; width: 6px; height: 5px;
                          border: 1.5px solid var(--accent); border-bottom: none;
                          border-radius: 4px 4px 0 0; box-sizing: border-box; }
.vg-locks .shade { position: absolute; inset: 0; background: rgba(4,5,8,.55); opacity: 0;
                   animation: vg-nightShade 8s infinite; pointer-events: none; }
.vg-locks .moon { position: absolute; right: 46px; top: 34px; width: 22px; height: 22px; border-radius: 50%;
                  box-shadow: inset -6px 3px 0 0 var(--accent); opacity: 0;
                  animation: vg-nightShade 8s infinite; }
.vg-locks .lb.nite { right: 26px; top: 66px; opacity: 0; animation: vg-nightShade 8s infinite; }
@keyframes vg-lockSnap { 0%, 8% { transform: translateY(-6px); opacity: 0; }
                         16%, 100% { transform: translateY(0); opacity: 1; } }
@keyframes vg-nightShade { 0%, 52% { opacity: 0; } 64%, 92% { opacity: 1; } 100% { opacity: 0; } }
.vg-locks .shade { animation-name: vg-nightShadeSoft; }
@keyframes vg-nightShadeSoft { 0%, 52% { opacity: 0; } 64%, 92% { opacity: .45; } 100% { opacity: 0; } }

/* =========================================================
   shadow — observe only: everything logged, nothing touched
   ========================================================= */
.vg-shadow .srow { position: absolute; left: 30px; display: flex; align-items: center; gap: 12px; }
.vg-shadow .s1 { top: 26px; } .vg-shadow .s2 { top: 58px; } .vg-shadow .s3 { top: 90px; }
.vg-shadow .chip { position: static; }
.vg-shadow .wb { font-size: 9px; letter-spacing: .12em; text-transform: uppercase; color: var(--alert);
                 border: 1px dashed var(--alert-line); padding: 2px 7px; }
.vg-shadow .s1 .wb { animation: vg-wbIn 7s infinite .6s; }
.vg-shadow .s2 .wb { animation: vg-wbIn 7s infinite 2s; }
.vg-shadow .s3 .wb { animation: vg-wbIn 7s infinite 3.4s; }
.vg-shadow .s2 .wb.ok2 { color: var(--faint); border-color: var(--line); }
.vg-shadow .sw { position: absolute; right: 24px; bottom: 26px; display: flex; align-items: center; gap: 8px; }
.vg-shadow .sw .lb { position: static; }
.vg-shadow .sw b { width: 24px; height: 12px; border: 1px solid var(--line); position: relative;
                   background: var(--surface); }
.vg-shadow .sw b::after { content: ""; position: absolute; left: 1px; top: 1px; width: 9px; height: 8px;
                          background: var(--faint); }
@keyframes vg-wbIn { 0% { opacity: 0; } 6%, 100% { opacity: 1; } }

/* =========================================================
   undo — banned, then restored in one tap
   ========================================================= */
.vg-undo .chip { width: 84px; height: 26px; left: 50%; top: 50%; transform: translate(-50%,-60%);
                 border-color: var(--accent-line); background: var(--surface);
                 animation: vg-undoChip 7s infinite; }
.vg-undo .chip i { height: 3px; animation: vg-undoBars 7s infinite; }
.vg-undo .chip i:nth-child(1) { width: 22px; } .vg-undo .chip i:nth-child(2) { width: 30px; }
.vg-undo .strike { position: absolute; left: calc(50% - 46px); width: 92px; top: calc(50% - 8px);
                   border-top: 1.5px solid var(--alert); animation: vg-undoStrike 7s infinite; }
.vg-undo .btn { position: absolute; left: calc(50% + 58px); top: calc(50% - 26px); width: 24px; height: 24px;
                border: 1px solid var(--line); background: var(--surface); color: var(--muted);
                font-size: 12px; display: flex; align-items: center; justify-content: center; }
.vg-undo .btn::after { content: ""; position: absolute; inset: -2px; border: 1px solid var(--accent);
                       opacity: 0; animation: vg-tapRing 7s infinite; }
.vg-undo .st1 { position: absolute; left: 50%; transform: translateX(-50%); top: 24px;
                font-size: 9px; letter-spacing: .12em; text-transform: uppercase; color: var(--alert);
                animation: vg-undoBanned 7s infinite; }
.vg-undo .fl.ok { left: 50%; transform: translateX(-50%); bottom: 24px; animation: vg-fadeVeryLate 7s infinite; }
@keyframes vg-undoChip { 0%, 14% { border-color: var(--line); }
                         20%, 48% { border-color: var(--alert); background: var(--alert-soft); }
                         58%, 100% { border-color: var(--accent-line); background: var(--surface); } }
@keyframes vg-undoBars { 0%, 48% { background: var(--faint); } 58%, 100% { background: var(--faint); } }
@keyframes vg-undoStrike { 0%, 16% { opacity: 0; transform: scaleX(0); }
                           22%, 48% { opacity: 1; transform: scaleX(1); }
                           56%, 100% { opacity: 0; transform: scaleX(1); } }
@keyframes vg-tapRing { 0%, 46% { opacity: 0; transform: scale(.6); }
                        52% { opacity: 1; transform: scale(1); }
                        60%, 100% { opacity: 0; transform: scale(1.5); } }
@keyframes vg-undoBanned { 0%, 18% { opacity: 0; } 24%, 50% { opacity: 1; } 56%, 100% { opacity: 0; } }

/* =========================================================
   scorebar — Targa Score: 14 checks become a number
   ========================================================= */
.vg-scorebar .checks { position: absolute; left: 26px; top: 34px; display: flex; gap: 5px; }
.vg-scorebar .checks i { width: 12px; height: 12px; border: 1px solid var(--line); box-sizing: border-box;
                         background: var(--accent-soft); border-color: var(--accent-line);
                         animation: vg-chk 8s infinite; animation-delay: var(--d); }
.vg-scorebar .checks i.miss { background: var(--surface); border-color: var(--line); animation: none; }
.vg-scorebar .lb.top { left: 26px; top: 14px; }
.vg-scorebar .sbar { position: absolute; left: 26px; right: 118px; top: 72px; height: 8px;
                     border: 1px solid var(--line); background: var(--surface); }
.vg-scorebar .sbar i { position: absolute; inset: 0; width: 87%; background: var(--accent);
                       transform-origin: left; animation: vg-scoreFill 8s ease-out infinite; }
.vg-scorebar .num { position: absolute; right: 62px; top: 58px; font-size: 30px; color: var(--accent);
                    font-variant-numeric: tabular-nums; }
.vg-scorebar .fl.ok { right: 24px; top: 66px; animation: vg-probFlag 8s infinite; }
.vg-scorebar .lb.sub { left: 26px; top: 96px; }
@keyframes vg-chk { 0% { background: var(--surface); border-color: var(--line); }
                    8%, 100% { background: var(--accent-soft); border-color: var(--accent-line); } }
@keyframes vg-scoreFill { 0% { transform: scaleX(0); } 62%, 100% { transform: scaleX(1); } }

/* =========================================================
   why — the reasoning behind one removal
   ========================================================= */
.vg-why .cmd { position: absolute; left: 30px; top: 22px; font-size: 12px; color: var(--fg);
               overflow: hidden; white-space: nowrap; width: 12ch;
               animation: vg-typeCmd 8s steps(9, end) infinite; }
.vg-why .cmd::before { content: "$ "; color: var(--faint); }
.vg-why .rl { position: absolute; left: 30px; right: 30px; display: flex; justify-content: space-between;
              font-size: 10.5px; color: var(--muted); }
.vg-why .rl s { text-decoration: none; color: var(--alert); }
.vg-why .r1 { top: 52px; animation: vg-wbIn 8s infinite 1.6s; }
.vg-why .r2 { top: 72px; animation: vg-wbIn 8s infinite 2.4s; }
.vg-why .r3 { top: 92px; animation: vg-wbIn 8s infinite 3.2s; }
.vg-why .tot { position: absolute; left: 30px; right: 30px; top: 116px; font-size: 10.5px;
               color: var(--fg); border-top: 1px solid var(--line); padding-top: 7px;
               animation: vg-wbIn 8s infinite 4.2s; }
.vg-why .tot em { font-style: normal; color: var(--accent); }
@keyframes vg-typeCmd { 0% { width: 2.5ch; } 14%, 100% { width: 12ch; } }

/* =========================================================
   chart — protection analytics
   ========================================================= */
.vg-chart .bars { position: absolute; left: 30px; right: 138px; top: 34px; bottom: 32px;
                  display: flex; align-items: flex-end; gap: 8px; }
.vg-chart .bars i { flex: 1; background: var(--accent); opacity: .75; transform-origin: bottom;
                    animation: vg-barGrow 7s ease-out infinite; animation-delay: var(--d); }
.vg-chart .lb.top { left: 30px; top: 14px; }
.vg-chart .stat { position: absolute; right: 26px; top: 40px; text-align: right; }
.vg-chart .stat .n { display: block; font-size: 22px; color: var(--accent); font-variant-numeric: tabular-nums; }
.vg-chart .stat .lb { position: static; display: block; margin-top: 4px; }
.vg-chart .stat2 { position: absolute; right: 26px; top: 92px; text-align: right; }
.vg-chart .stat2 .n { display: block; font-size: 13px; color: var(--muted); font-variant-numeric: tabular-nums; }
.vg-chart .stat2 .lb { position: static; display: block; margin-top: 3px; }

/* =========================================================
   panels — the web dashboard assembling
   ========================================================= */
.vg-panels .brw { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%);
                  width: 240px; height: 106px; border: 1px solid var(--line); background: var(--surface);
                  box-sizing: border-box; }
.vg-panels .bbar { height: 20px; border-bottom: 1px solid var(--line-2); display: flex;
                   align-items: center; gap: 4px; padding: 0 8px; }
.vg-panels .bbar i { width: 5px; height: 5px; border-radius: 50%; background: var(--line); }
.vg-panels .bbar .url { font-size: 8.5px; color: var(--faint); margin-left: 8px; letter-spacing: .08em; }
.vg-panels .bgrid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; padding: 10px; }
.vg-panels .p { border: 1px solid var(--line-2); background: var(--bg-2); height: 58px; padding: 7px;
                box-sizing: border-box; animation: vg-panelIn 7s infinite; }
.vg-panels .p2 { animation-delay: .5s; } .vg-panels .p3 { animation-delay: 1s; }
.vg-panels .p .n { font-size: 13px; color: var(--accent); display: block; }
.vg-panels .p .lb { position: static; display: block; margin-top: 3px; font-size: 7.5px; }
.vg-panels .pb { display: flex; align-items: flex-end; gap: 3px; height: 26px; margin-top: 6px; }
.vg-panels .pb i { flex: 1; background: var(--accent); opacity: .7; }
.vg-panels .fr { height: 3px; background: var(--line); margin-top: 6px; }
.vg-panels .fr.x { background: var(--alert-soft); }
@keyframes vg-panelIn { 0% { opacity: 0; transform: translateY(6px); }
                        8%, 100% { opacity: 1; transform: translateY(0); } }

/* =========================================================
   chat — support: real humans, the people who build it
   ========================================================= */
.vg-chat .bub { position: absolute; width: 150px; box-sizing: border-box; padding: 9px 11px;
                border: 1px solid var(--line); background: var(--surface); }
.vg-chat .bub i { display: block; height: 2.5px; background: var(--line); margin: 5px 0; }
.vg-chat .q { left: 30px; top: 28px; animation: vg-panelIn 8s infinite; }
.vg-chat .q i:nth-child(1) { width: 80%; } .vg-chat .q i:nth-child(2) { width: 55%; }
.vg-chat .a { right: 30px; top: 76px; border-color: var(--accent-line); background: var(--accent-soft);
              animation: vg-panelIn 8s infinite 2.2s; }
.vg-chat .a i { background: var(--accent); opacity: .55; }
.vg-chat .a i:nth-child(1) { width: 90%; } .vg-chat .a i:nth-child(2) { width: 62%; }
.vg-chat .lb.who { right: 30px; top: 58px; }
.vg-chat .lb.who::before { content: "●"; color: var(--accent); margin-right: 5px; font-size: 7px; }
@keyframes vg-dots { 0%, 20% { opacity: .2; } 30% { opacity: 1; } 40%, 100% { opacity: .2; } }

/* =========================================================
   waterfall — the LLM cascade: cheap first, frontier last
   ========================================================= */
.vg-waterfall .wt { position: absolute; height: 1px; background: var(--line); }
.vg-waterfall .wt1 { left: 26px;  width: 30%; top: 44px; }
.vg-waterfall .wt2 { left: 38%;   width: 26%; top: 80px; }
.vg-waterfall .wt3 { left: 66%;   width: 24%; top: 116px; }
.vg-waterfall .wt .lb { left: 0; top: 4px; }
.vg-waterfall .wt .pc { position: absolute; right: 0; top: 4px; font-size: 9px; letter-spacing: .1em;
                          color: var(--accent); text-transform: uppercase; }
.vg-waterfall .chip { width: 26px; height: 12px; }
.vg-waterfall .ca { left: calc(26px + 6%); top: 28px; border-color: var(--accent-line);
                    animation: vg-wfA 8s infinite; }
.vg-waterfall .cb { left: calc(38% + 6%); top: 64px; border-color: var(--accent-line);
                    animation: vg-wfB 8s infinite; }
.vg-waterfall .cc { left: calc(66% + 6%); top: 100px; border-color: var(--alert);
                    background: var(--alert-soft); animation: vg-wfC 8s infinite; }
@keyframes vg-wfA {
  0%   { left: -30px; top: 28px; opacity: 0; }
  6%   { opacity: 1; }
  16%, 88% { left: calc(26px + 6%); top: 28px; opacity: 1; border-color: var(--accent-line); }
  96%, 100% { opacity: 0; }
}
@keyframes vg-wfB {
  0%   { left: -30px; top: 28px; opacity: 0; }
  8%   { opacity: 1; }
  20%  { left: calc(26px + 18%); top: 28px; border-color: var(--line); }
  34%, 88% { left: calc(38% + 6%); top: 64px; opacity: 1; border-color: var(--accent-line); }
  96%, 100% { opacity: 0; }
}
@keyframes vg-wfC {
  0%   { left: -30px; top: 28px; opacity: 0; border-color: var(--line); background: var(--surface); }
  10%  { opacity: 1; }
  22%  { left: calc(26px + 22%); top: 28px; }
  38%  { left: calc(38% + 18%); top: 64px; border-color: var(--line); background: var(--surface); }
  54%, 88% { left: calc(66% + 6%); top: 100px; opacity: 1; border-color: var(--alert); background: var(--alert-soft); }
  96%, 100% { opacity: 0; }
}

/* =========================================================
   thread — conversational detection: intent builds across messages
   ========================================================= */
.vg-thread .msg { position: absolute; left: 30px; display: flex; align-items: center; gap: 8px; }
.vg-thread .m1 { top: 22px; } .vg-thread .m2 { top: 46px; } .vg-thread .m3 { top: 70px; } .vg-thread .m4 { top: 94px; }
.vg-thread .msg b { width: 8px; height: 8px; border-radius: 50%; background: var(--line); flex: none; }
.vg-thread .msg i { display: block; height: 2.5px; background: var(--faint); opacity: .6; }
.vg-thread .m1 { animation: vg-wbIn 8s infinite .2s; }
.vg-thread .m2 { animation: vg-wbIn 8s infinite 1.4s; }
.vg-thread .m3 { animation: vg-wbIn 8s infinite 2.6s; }
.vg-thread .m4 { animation: vg-wbIn 8s infinite 3.8s; }
.vg-thread .m4 i { background: var(--alert); opacity: .9; }
.vg-thread .im { position: absolute; right: 30px; top: 24px; width: 88px; }
.vg-thread .im .lb { position: static; display: block; }
.vg-thread .im .mb { position: relative; height: 68px; border-left: 1px solid var(--line);
                     border-bottom: 1px solid var(--line); margin-top: 8px; }
.vg-thread .im .th { position: absolute; left: 0; right: 0; top: 22%; border-top: 1px dashed var(--alert-line); }
.vg-thread .im .fillcol { position: absolute; left: 8px; right: 8px; bottom: 0; height: 88%;
                          background: linear-gradient(var(--alert-soft), var(--accent-soft));
                          transform-origin: bottom; animation: vg-intent 8s infinite; }
.vg-thread .fl.bad { right: 26px; bottom: 18px; animation: vg-probFlag 8s infinite; }
@keyframes vg-intent { 0%, 4% { height: 8%; } 18% { height: 24%; } 34% { height: 42%; }
                       52% { height: 64%; } 68%, 100% { height: 88%; } }

/* =========================================================
   lure — hyper-personalized phishing: no template to match
   ========================================================= */
.vg-lure .tmpl { position: absolute; left: 28px; top: 34px; width: 96px; }
.vg-lure .tmpl .lb { position: static; display: block; margin-bottom: 8px; }
.vg-lure .tmpl i { display: block; height: 8px; border: 1px dashed var(--line); margin-bottom: 6px;
                   opacity: .5; }
.vg-lure .tmpl .miss { position: absolute; right: -4px; top: 20px; color: var(--faint); font-size: 10px; }
.vg-lure .chip { width: 76px; height: 24px; left: 52%; top: 56px; gap: 4px;
                 border-color: var(--alert); background: var(--alert-soft); }
.vg-lure .chip i { animation: vg-pieceIn 7.5s infinite; }
.vg-lure .chip i:nth-child(1) { width: 18px; animation-delay: .2s; }
.vg-lure .chip i:nth-child(2) { width: 24px; animation-delay: .6s; }
.vg-lure .chip i:nth-child(3) { width: 12px; animation-delay: 1s; }
.vg-lure .chip { animation: vg-lureBox 7.5s infinite; }
.vg-lure .lb.one { left: 52%; top: 38px; }
.vg-lure .node { position: absolute; right: 34px; top: 58px; width: 18px; height: 18px;
                 transform: rotate(45deg); box-sizing: border-box;
                 border: 1px solid var(--accent); background: var(--accent-soft);
                 animation: vg-nodePulse 2s ease-in-out infinite; }
.vg-lure .lb.jn { right: 26px; top: 88px; }
.vg-lure .fl.bad { left: 52%; bottom: 20px; animation: vg-fadeVeryLate 7.5s infinite; }
@keyframes vg-pieceIn { 0% { transform: translateY(-14px); opacity: 0; }
                        10%, 100% { transform: translateY(0); opacity: 1; } }
@keyframes vg-lureBox { 0%, 16% { border-color: var(--line); background: var(--surface); }
                        60%, 100% { border-color: var(--alert); background: var(--alert-soft); } }

/* =========================================================
   radar — threat intel: warned before the wave arrives
   ========================================================= */
.vg-radar .scope { position: absolute; left: 44px; top: 50%; transform: translateY(-50%);
                   width: 92px; height: 92px; border-radius: 50%; border: 1px solid var(--line);
                   overflow: hidden; }
.vg-radar .scope::before { content: ""; position: absolute; inset: 18px; border-radius: 50%;
                           border: 1px solid var(--line-2); }
.vg-radar .beam { position: absolute; inset: 0; border-radius: 50%;
                  background: conic-gradient(var(--accent-soft) 0 40deg, transparent 40deg);
                  animation: vg-spin 4s linear infinite; }
.vg-radar .blip { position: absolute; width: 5px; height: 5px; border-radius: 50%; background: var(--alert); }
.vg-radar .b1 { left: 24%; top: 30%; animation: vg-blip 4s infinite .4s; }
.vg-radar .b2 { left: 64%; top: 22%; animation: vg-blip 4s infinite 1.1s; }
.vg-radar .b3 { left: 56%; top: 66%; animation: vg-blip 4s infinite 2.6s; }
.vg-radar .feedline { position: absolute; left: 148px; right: 96px; top: 50%;
                      border-top: 1px dashed var(--accent-line); }
.vg-radar .feedline::after { content: ""; position: absolute; right: -1px; top: -3px; width: 5px; height: 5px;
                             border-top: 1px solid var(--accent); border-right: 1px solid var(--accent);
                             transform: rotate(45deg); }
.vg-radar .you { position: absolute; right: 60px; top: calc(50% - 12px); width: 24px; height: 24px;
                 box-sizing: border-box; border: 1px solid var(--accent); background: var(--accent-soft); }
.vg-radar .lb.youlb { right: 44px; top: calc(50% + 18px); }
.vg-radar .lb.top { left: 26px; top: 14px; }
.vg-radar .fl.ok { right: 20px; top: 16px; }
@keyframes vg-spin { to { transform: rotate(360deg); } }
@keyframes vg-blip { 0%, 8% { opacity: .25; } 14%, 40% { opacity: 1; } 70%, 100% { opacity: .25; } }

/* =========================================================
   slots — connected channels: rooms fill as you grow
   ========================================================= */
.vg-slots .srow { position: absolute; left: 50%; top: 54px; transform: translateX(-50%);
                  display: flex; gap: 12px; }
.vg-slots .srow b { width: 26px; height: 26px; box-sizing: border-box; border: 1px solid var(--line);
                    background: var(--surface); }
.vg-slots .srow b.on { border-color: var(--accent-line); background: var(--accent-soft);
                       animation: vg-slotOn 7s infinite; animation-delay: var(--d); }
.vg-slots .cnt { position: absolute; left: 50%; top: 26px; transform: translateX(-50%);
                 font-size: 11px; color: var(--accent); letter-spacing: .1em; }
.vg-slots .lb.ladder { left: 50%; bottom: 24px; transform: translateX(-50%); }
@keyframes vg-slotOn { 0% { border-color: var(--line); background: var(--surface); }
                       10%, 100% { border-color: var(--accent-line); background: var(--accent-soft); } }

/* =========================================================
   meter — messages screened / month (and the monthly reset)
   ========================================================= */
.vg-meter .lb.top { left: 26px; top: 20px; }
.vg-meter .mtr { position: absolute; left: 26px; right: 26px; top: 64px; height: 10px;
                 border: 1px solid var(--line); background: var(--surface); }
.vg-meter .mtr i { position: absolute; inset: 0; width: 100%; background: var(--accent); opacity: .8;
                   transform: scaleX(.62); transform-origin: left;
                   animation: vg-meterFill 8s ease-in-out infinite; }
.vg-meter .cnt { position: absolute; left: 26px; top: 86px; font-size: 10.5px; color: var(--muted);
                 font-variant-numeric: tabular-nums; }
.vg-meter .lb.rst { right: 26px; top: 88px; }
.vg-meter .lb.sub { left: 26px; bottom: 22px; color: var(--accent); }
@keyframes vg-meterFill { 0% { transform: scaleX(0); } 58%, 88% { transform: scaleX(.62); }
                          94% { transform: scaleX(0); } 100% { transform: scaleX(0); } }

/* =========================================================
   meter2 — channels & monthly messages, one plan
   ========================================================= */
.vg-meter2 .row { position: absolute; left: 26px; right: 26px; }
.vg-meter2 .rowa { top: 30px; } .vg-meter2 .rowb { top: 84px; }
.vg-meter2 .row .lb { left: 0; top: 0; }
.vg-meter2 .cells { position: absolute; left: 0; top: 16px; display: flex; gap: 6px; }
.vg-meter2 .cells b { width: 18px; height: 18px; box-sizing: border-box; border: 1px solid var(--line);
                      background: var(--surface); }
.vg-meter2 .cells b.on { border-color: var(--accent-line); background: var(--accent-soft);
                         animation: vg-slotOn 7s infinite; animation-delay: var(--d); }
.vg-meter2 .mtr { position: absolute; left: 0; right: 0; top: 18px; height: 8px;
                  border: 1px solid var(--line); background: var(--surface); }
.vg-meter2 .mtr i { position: absolute; inset: 0; width: 100%; background: var(--accent); opacity: .8;
                    transform: scaleX(.62); transform-origin: left;
                    animation: vg-meterFill2 7s ease-out infinite; }
.vg-meter2 .row .val { position: absolute; right: 0; top: 0; font-size: 9px; letter-spacing: .1em;
                       text-transform: uppercase; color: var(--accent); }
@keyframes vg-meterFill2 { 0% { transform: scaleX(0); } 50%, 100% { transform: scaleX(.62); } }

/* =========================================================
   burst — burst grace: a raid can't starve your protection
   ========================================================= */
.vg-burst .lb.top { left: 26px; top: 16px; }
.vg-burst .mtr { position: absolute; left: 26px; right: 26px; top: 74px; height: 12px;
                 border: 1px solid var(--line); background: var(--surface); }
.vg-burst .cap { position: absolute; left: 72%; top: -5px; bottom: -5px; width: 1px; background: var(--faint); }
.vg-burst .cap .lb { left: -14px; top: -14px; }
.vg-burst .grace { position: absolute; left: 72%; right: 0; top: 0; bottom: 0;
                   background: repeating-linear-gradient(-45deg, var(--accent-soft) 0 4px, transparent 4px 8px); }
.vg-burst .mtr > i { position: absolute; left: 0; top: 0; bottom: 0; width: 88%; background: var(--accent);
                     opacity: .8; transform-origin: left; animation: vg-burstFill 8s ease-in-out infinite; }
.vg-burst .spikes { position: absolute; left: 46%; right: 26%; top: 38px; height: 26px;
                    display: flex; align-items: flex-end; gap: 4px; }
.vg-burst .spikes i { flex: 1; background: var(--alert); opacity: .6; transform-origin: bottom;
                      animation: vg-spikeIn 8s infinite; animation-delay: var(--d); }
.vg-burst .lb.raidlb { left: 46%; top: 24px; color: var(--alert); }
.vg-burst .fl.ok { right: 24px; bottom: 20px; animation: vg-fadeVeryLate 8s infinite; }
@keyframes vg-burstFill { 0% { transform: scaleX(.6); } 30% { transform: scaleX(.72); }
                          64%, 100% { transform: scaleX(1); } }
@keyframes vg-spikeIn { 0%, 26% { transform: scaleY(0); } 38%, 100% { transform: scaleY(1); } }

/* =========================================================
   retention — data ages out on your schedule
   ========================================================= */
.vg-retention .blocks { position: absolute; left: 26px; right: 26px; top: 62px; display: flex; gap: 8px; }
.vg-retention .blocks b { flex: 1; height: 22px; box-sizing: border-box; border: 1px solid var(--line);
                          background: var(--surface); }
.vg-retention .blocks b.gone { opacity: .12; animation: vg-erase 8s infinite; animation-delay: var(--d); }
.vg-retention .bound { position: absolute; left: 44%; top: 46px; bottom: 40px;
                       border-left: 1px dashed var(--accent); }
.vg-retention .bound .lb { left: 8px; top: -4px; color: var(--accent); }
.vg-retention .lb.old { left: 26px; top: 34px; } .vg-retention .lb.new { right: 26px; top: 34px; }
.vg-retention .fl.ok { left: 26px; bottom: 20px; animation: vg-fadeVeryLate 8s infinite; }
@keyframes vg-erase { 0%, 30% { opacity: 1; } 46%, 100% { opacity: .12; } }

/* ---------- narrow phones: the tightest scenes shrink to fit ---------- */
@media (max-width: 480px) {
  .vg-clone .card { width: 110px; }
  .vg-clone .card .rl { width: 30px; }
  .vg-clone .cmp { left: 142px; right: 142px; }
  .vg-network svg { width: 94%; max-width: 290px; }
  .vg-radar .feedline { left: 142px; right: 88px; }
  .vg-radar .you { right: 56px; }
}

/* ---------- reduced motion: freeze every scene on its end-state ---------- */
@media (prefers-reduced-motion: reduce) {
  #capd-vig *, #capd-vig *::before, #capd-vig *::after { animation: none !important; }
}

/* =========================================================
   owner — co-owners & account recovery: the admin reclaims
   ========================================================= */
.vg-owner .grp { position: absolute; left: 7%; top: 50%; margin-top: -14px; width: 28px; height: 28px;
                 box-sizing: border-box; border: 1px solid var(--accent); background: var(--accent-soft); }
.vg-owner .lb.grplb { left: 7%; top: calc(50% + 20px); }
.vg-owner .who { position: absolute; width: 12px; height: 12px; border-radius: 50%; }
.vg-owner .wa { right: 16%; top: 36px; background: var(--faint);
                animation: vg-ownDepart 10s infinite; }
.vg-owner .wb { right: 16%; bottom: 44px; background: var(--accent);
                box-shadow: 0 0 8px var(--accent-line); }
.vg-owner .lb.la { right: 8%; top: 16px; }
.vg-owner .lb.lb2 { right: 8%; bottom: 26px; }
.vg-owner .wa .x { position: absolute; left: 14px; top: -3px; color: var(--alert);
                   font-size: 11px; font-style: normal; animation: vg-fadeMid 10s infinite; }
.vg-owner .linka { position: absolute; left: calc(7% + 30px); right: calc(16% + 16px); top: 41px;
                   border-top: 1px solid var(--line); animation: vg-ownLinkA 10s infinite; }
.vg-owner .linkb { position: absolute; left: calc(7% + 30px); right: calc(16% + 16px); bottom: 49px;
                   border-top: 1px solid var(--accent); transform-origin: left;
                   animation: vg-ownLinkB 10s infinite; }
.vg-owner .proof { position: absolute; right: calc(16% - 4px); bottom: 62px;
                   font-size: 9px; letter-spacing: .12em; text-transform: uppercase;
                   color: var(--accent); animation: vg-ownProof 10s infinite; }
.vg-owner .win { position: absolute; left: 50%; transform: translateX(-50%); top: 12px;
                 font-size: 9px; letter-spacing: .12em; text-transform: uppercase;
                 color: var(--faint); border: 1px dashed var(--line); padding: 2px 7px;
                 animation: vg-ownWin 10s infinite; }
.vg-owner .fl.ok { left: 50%; transform: translateX(-50%); bottom: 12px;
                   animation: vg-ownFlag 10s infinite; }
@keyframes vg-ownDepart { 0%, 14% { background: var(--accent); opacity: 1; }
                          22%, 100% { background: var(--faint); opacity: .45; } }
@keyframes vg-ownLinkA { 0%, 20% { opacity: 1; border-top-style: solid; }
                         30%, 100% { opacity: .18; border-top-style: dashed; } }
@keyframes vg-ownLinkB { 0%, 58% { transform: scaleX(0); } 72%, 100% { transform: scaleX(1); } }
@keyframes vg-ownProof { 0%, 30% { opacity: 0; } 38%, 100% { opacity: 1; } }
@keyframes vg-ownWin   { 0%, 40% { opacity: 0; } 46%, 68% { opacity: 1; } 76%, 100% { opacity: 0; } }
@keyframes vg-ownFlag  { 0%, 74% { opacity: 0; } 82%, 100% { opacity: 1; } }

/* =========================================================
   team — seats & scoped roles: the member sees one, not all
   ========================================================= */
.vg-team .own { position: absolute; left: 10%; width: 11px; height: 11px; border-radius: 50%;
                background: var(--accent); }
.vg-team .o1 { top: 38px; } .vg-team .o2 { top: 58px; }
.vg-team .lb.ownlb { left: 10%; top: 18px; }
.vg-team .mem { position: absolute; left: 10%; top: 108px; width: 11px; height: 11px;
                border-radius: 50%; box-sizing: border-box; border: 1.5px solid var(--accent);
                background: var(--accent-soft); animation: vg-teamMem 8s infinite; }
.vg-team .lb.memlb { left: 10%; top: 88px; }
.vg-team .ch { position: absolute; right: 12%; width: 22px; height: 22px; box-sizing: border-box;
               border: 1px solid var(--faint); background: var(--surface); }
.vg-team .c1 { top: 26px; } .vg-team .c2 { top: 64px; } .vg-team .c3 { top: 102px; }
.vg-team .oline { position: absolute; left: calc(10% + 14px); right: calc(12% + 24px);
                  border-top: 1px solid var(--accent-line); }
.vg-team .ol1 { top: 37px; } .vg-team .ol2 { top: 75px; } .vg-team .ol3 { top: 113px; }
.vg-team .mline { position: absolute; left: calc(10% + 14px); right: calc(12% + 24px); top: 113px;
                  border-top: 1.5px solid var(--accent); transform-origin: left;
                  animation: vg-teamLine 8s infinite; }
.vg-team .mtry { position: absolute; left: calc(10% + 14px); right: calc(12% + 24px);
                 border-top: 1px dashed var(--alert-line); animation: vg-teamTry 8s infinite; }
.vg-team .t1 { top: 37px; } .vg-team .t2 { top: 75px; animation-delay: .5s; }
.vg-team .mtry .x { position: absolute; right: -2px; top: -7px; color: var(--alert);
                    font-size: 10px; font-style: normal; }
.vg-team .fl.ok { left: 50%; transform: translateX(-50%); bottom: 10px;
                  animation: vg-fadeVeryLate 8s infinite; }
@keyframes vg-teamMem  { 0%, 8% { opacity: 0; transform: scale(.5); }
                         16%, 100% { opacity: 1; transform: scale(1); } }
@keyframes vg-teamLine { 0%, 18% { transform: scaleX(0); } 34%, 100% { transform: scaleX(1); } }
@keyframes vg-teamTry  { 0%, 40% { opacity: 0; } 48%, 62% { opacity: .8; }
                         74%, 100% { opacity: .25; } }

/* =========================================================
   ruleset — org baseline: one policy fans out; drift repaired
   ========================================================= */
.vg-ruleset .base { position: absolute; left: 50%; top: 16px; transform: translateX(-50%);
                    width: 130px; height: 22px; box-sizing: border-box;
                    border: 1px solid var(--accent); background: var(--accent-soft);
                    display: flex; align-items: center; justify-content: center;
                    font-size: 9px; letter-spacing: .14em; text-transform: uppercase;
                    color: var(--accent); }
.vg-ruleset .ch { position: absolute; top: 100px; width: 24px; height: 24px; box-sizing: border-box;
                  border: 1px solid var(--faint); background: var(--surface); }
.vg-ruleset .k1 { left: calc(22% - 12px); } .vg-ruleset .k2 { left: calc(50% - 12px); }
.vg-ruleset .k3 { left: calc(78% - 12px); animation: vg-rsDriftBox 10s infinite; }
.vg-ruleset .down { position: absolute; top: 40px; height: 58px; width: 1px; background: var(--line); }
.vg-ruleset .d1 { left: 22%; } .vg-ruleset .d2 { left: 50%; } .vg-ruleset .d3 { left: 78%; }
.vg-ruleset .pulse { position: absolute; width: 5px; height: 5px; border-radius: 50%;
                     background: var(--accent); margin-left: -2px; }
.vg-ruleset .p1 { left: 22%; animation: vg-rsPulse 10s infinite .2s; }
.vg-ruleset .p2 { left: 50%; animation: vg-rsPulse 10s infinite .5s; }
.vg-ruleset .p3 { left: 78%; animation: vg-rsPulse 10s infinite .8s; }
.vg-ruleset .p3b { left: 78%; animation: vg-rsRepair 10s infinite; }
.vg-ruleset .ok { position: absolute; top: 82px; font-size: 11px; font-weight: 600; }
.vg-ruleset .ok1 { left: calc(22% + 10px); color: var(--accent); animation: vg-rsOk 10s infinite .2s; }
.vg-ruleset .ok2 { left: calc(50% + 10px); color: var(--accent); animation: vg-rsOk 10s infinite .5s; }
.vg-ruleset .ok3 { left: calc(78% + 10px); color: var(--accent); animation: vg-rsOk3 10s infinite; }
.vg-ruleset .drift { position: absolute; left: calc(78% + 10px); top: 82px; color: var(--alert);
                     font-size: 11px; font-weight: 600; animation: vg-rsDrift 10s infinite; }
.vg-ruleset .fl.ok { left: 16px; bottom: 10px; animation: vg-rsFlag 10s infinite; }
@keyframes vg-rsPulse  { 0% { top: 40px; opacity: 0; } 4% { opacity: 1; }
                         12% { top: 92px; opacity: 1; } 15%, 100% { top: 92px; opacity: 0; } }
@keyframes vg-rsOk     { 0%, 12% { opacity: 0; } 18%, 100% { opacity: 1; } }
@keyframes vg-rsOk3    { 0%, 12% { opacity: 0; } 18%, 42% { opacity: 1; }
                         46%, 74% { opacity: 0; } 80%, 100% { opacity: 1; } }
@keyframes vg-rsDrift  { 0%, 44% { opacity: 0; } 48%, 72% { opacity: 1; } 76%, 100% { opacity: 0; } }
@keyframes vg-rsDriftBox { 0%, 44% { border-color: var(--faint); }
                           48%, 72% { border-color: var(--alert); }
                           80%, 100% { border-color: var(--faint); } }
@keyframes vg-rsRepair { 0%, 58% { top: 40px; opacity: 0; } 62% { opacity: 1; }
                         72% { top: 92px; opacity: 1; } 76%, 100% { top: 92px; opacity: 0; } }
@keyframes vg-rsFlag   { 0%, 78% { opacity: 0; } 86%, 100% { opacity: 1; } }

/* burst update: the owner-set stop handle + the alert chip */
.vg-burst .stop { position: absolute; right: -1px; top: -7px; bottom: -7px; width: 3px;
                  background: var(--accent); }
.vg-burst .stop .lb { right: -8px; top: -16px; color: var(--accent); }
.vg-burst .alertchip { position: absolute; left: 16px; bottom: 34px;
                       font-size: 9px; letter-spacing: .12em; text-transform: uppercase;
                       color: var(--accent); border: 1px solid var(--accent-line);
                       background: var(--accent-soft); padding: 3px 8px;
                       animation: vg-fadeMid 8s infinite; }
