/* DarkWeb Scanner. Two themes: classic (light, serious) and console (dark, hacker). */
:root{
  --violet:#291459;--violet-700:#1d0e42;--violet-500:#3b2380;--violet-100:#ece8f5;
  --cyan:#36d4ff;--cyan-600:#0aa9d6;--green:#3fe08f;--green-100:#e2f9ee;--green-700:#137a4a;
  --amber:#f2b134;--amber-100:#fff4dc;--amber-700:#8a5a00;--red:#d6335a;--red-100:#fde6ec;--red-700:#a11d3d;
  --bg:#f3f4f8;--surface:#ffffff;--surface-2:#fafbfd;--line:#e4e6ee;--line-2:#cfd3de;--fg:#1c1b2e;--fg-2:#4f4e66;--muted:#7d7c93;
  --accent:var(--violet);--accent-fg:#fff;--brand:var(--violet);--link:var(--violet-500);--chip:var(--violet-100);--chip-fg:var(--violet);
  --side-bg:linear-gradient(180deg,#291459 0%,#1d0e42 100%);--side-fg:rgba(255,255,255,.78);--side-active:rgba(54,212,255,.14);
  --font:-apple-system,BlinkMacSystemFont,"SF Pro Text","Inter","Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --mono:"SF Mono",ui-monospace,Menlo,Consolas,monospace;--body-font:var(--font);
  --r:8px;--shadow:0 1px 2px rgba(29,14,66,.06),0 1px 1px rgba(29,14,66,.04);--console-bg:#f2f4f9;--console-fg:#1c1b2e;
  --console-panel:#ffffff;--console-panel2:#f7f8fc;--console-line:#dde1ea;--console-mut:#5b5a72;--console-mut2:#8b8aa0;
  --console-acc:#1f5fbf;--console-scan:rgba(41,20,89,.045);--console-warn:#8a5a00;--console-bad:#a11d3d}
[data-theme="console"]{
  --bg:#070a0f;--surface:#0e141b;--surface-2:#111923;--line:#1d2733;--line-2:#2b3846;--fg:#d7e3ea;--fg-2:#9fb0bd;--muted:#6f8090;
  --accent:#3fe08f;--accent-fg:#06110b;--brand:#3fe08f;--link:#36d4ff;--chip:#14202b;--chip-fg:#7ff0b2;
  --violet-100:#14202b;--violet:#7ff0b2;--violet-500:#36d4ff;--green-100:#0f2a1d;--green-700:#3fe08f;--amber-100:#2a2410;--amber-700:#f2b134;--red-100:#2a1018;--red-700:#ff5d7d;
  --side-bg:linear-gradient(180deg,#0b1118 0%,#070a0f 100%);--side-fg:#9fb0bd;--side-active:rgba(63,224,143,.14);
  --body-font:var(--mono);--shadow:0 0 0 1px rgba(63,224,143,.06);--console-bg:#050709;--console-fg:#d7e3ea;
  --console-panel:#0a1017;--console-panel2:#0d141c;--console-line:#1d2733;--console-mut:#9fb0bd;--console-mut2:#6f8090;
  --console-acc:#3fe08f;--console-scan:rgba(63,224,143,.07);--console-warn:#f2b134;--console-bad:#ff5d7d}
*{box-sizing:border-box}
/* The browser hides a `hidden` element with a plain `display:none` that any author `display:`
   beats -- so a hidden `.grid` stayed a grid and the dashboard's tiles stood above a search
   result they had nothing to do with. The attribute exists to win; here it does. */
[hidden]{display:none!important}
html,body{margin:0;min-height:100%}
body{font:14.5px/1.55 var(--body-font);color:var(--fg);background:var(--bg);-webkit-font-smoothing:antialiased}
[data-theme="console"] body{font-size:13.5px}
a{color:var(--link);text-decoration:none}a:hover{text-decoration:underline}
code{font-family:var(--mono);font-size:.85em;background:var(--chip);color:var(--chip-fg);padding:.1em .35em;border-radius:4px}

/* shell */
.shell{display:grid;grid-template-columns:240px minmax(0,1fr);min-height:100vh}
.side{background:var(--side-bg);color:#fff;padding:1.4rem 1rem;display:flex;flex-direction:column;gap:1.2rem;position:sticky;top:0;height:100vh;border-right:1px solid rgba(255,255,255,.06)}
.brand{display:flex;align-items:center;gap:.7rem;padding:.2rem .5rem;color:#fff}.brand:hover{text-decoration:none}
.brand .mark{width:34px;height:34px;color:var(--cyan);display:grid;place-items:center;flex:none}
[data-theme="console"] .brand .mark{color:#3fe08f}
.brand .name{font-weight:700;font-size:.98rem;letter-spacing:.01em;line-height:1.15}
.brand .name small{display:block;font-weight:500;font-size:.68rem;color:rgba(255,255,255,.6);letter-spacing:.08em;text-transform:uppercase;margin-top:.15rem}
.side nav{display:flex;flex-direction:column;gap:.15rem}
.side nav .group{font-size:.64rem;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.4);padding:.9rem .75rem .35rem}
.side nav a{display:flex;align-items:center;gap:.65rem;padding:.55rem .75rem;border-radius:6px;color:var(--side-fg);font-weight:500}
.side nav a::before{content:"";width:6px;height:6px;border-radius:50%;background:rgba(255,255,255,.18)}
.side nav a:hover{background:rgba(255,255,255,.07);color:#fff;text-decoration:none}
.side nav a.active{background:var(--side-active);color:#fff}.side nav a.active::before{background:var(--cyan)}
[data-theme="console"] .side nav a.active::before{background:#3fe08f}
.side .foot{margin-top:auto;padding:.9rem .75rem 0;border-top:1px solid rgba(255,255,255,.1);font-size:.8rem;color:rgba(255,255,255,.7)}
.side .foot .who{display:block;color:#fff;font-weight:600;font-size:.8rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.side .foot .role{display:inline-block;margin:.25rem 0 .6rem;padding:.05rem .5rem;border-radius:999px;background:rgba(255,255,255,.12);font-size:.66rem;letter-spacing:.08em;text-transform:uppercase}
.side .foot button{width:100%;background:transparent;color:#fff;border:1px solid rgba(255,255,255,.3)}
.side .foot button:hover{background:rgba(255,255,255,.1)}
.langs{display:flex;gap:.3rem;margin:.2rem 0 .6rem}.langs button{width:auto!important;padding:.15rem .5rem;font-size:.7rem;letter-spacing:.08em;border-color:rgba(255,255,255,.25)}
.langs button.on{background:rgba(255,255,255,.18)}
.auth .langs{justify-content:center;margin-top:.6rem}.auth .langs button{color:#fff}
.content{min-width:0}
main{padding:2rem 2.6rem 3rem;max-width:1240px}
/* --- the operator's API budget, in the top bar ------------------------------------ */
/* Small and quiet until it is not. WhiteIntel gets 500 calls a day; on the day this
   was built that budget was gone by the afternoon and nothing on screen said so. The
   fill is set from `data-width` through the CSSOM -- the CSP forbids style attributes. */
.topbar{display:flex;align-items:center;justify-content:space-between;gap:1rem}
#budget-bar{min-width:0}
.budget{display:flex;align-items:center;gap:.9rem;flex-wrap:wrap;font-size:.72rem}
.budget-item{display:inline-flex;align-items:center;gap:.4rem;min-width:0}
.budget-name{color:var(--muted);white-space:nowrap}
.budget-track{display:inline-block;width:6rem;height:6px;border-radius:3px;
  background:var(--line-2);overflow:hidden;flex:none}
.budget-fill{display:block;height:100%;border-radius:3px;background:var(--green-700);
  transition:width .4s ease}
.budget-count{font-family:var(--mono);white-space:nowrap;color:var(--fg-2)}
.lvl-low .budget-fill{background:var(--amber)}
.lvl-low .budget-count{color:var(--amber-700)}
.lvl-spent .budget-fill{background:var(--red)}
.lvl-spent .budget-count{color:var(--red-700);font-weight:700}
.budget-flag{padding:0 .35rem;border-radius:4px;background:var(--red-100);
  color:var(--red-700);font-weight:700;text-transform:uppercase;letter-spacing:.06em}
.budget-close{margin:0}
.budget-close button{padding:0 .35rem;background:transparent;border:0;color:var(--muted);
  font-size:1rem;line-height:1;cursor:pointer}
.budget-close button:hover{color:var(--fg)}
.page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:1rem;margin-bottom:1.4rem;flex-wrap:wrap}
h1{font-size:1.55rem;font-weight:700;letter-spacing:-.015em;color:var(--brand);margin:0}
h1 small{display:block;font-size:.9rem;font-weight:400;color:var(--muted);letter-spacing:0;margin-top:.25rem}
h2 small{display:block;font-size:.85rem;font-weight:400;color:var(--muted);letter-spacing:0;text-transform:none;margin-top:.2rem}
h2{font-size:.76rem;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--fg-2);margin:1.6rem 0 .7rem}
.card h2:first-child{margin-top:0}p{margin:.3rem 0 .8rem}

/* cards */
/* A notice about something that is currently broken, not merely worth knowing. Same
   shape as `.notice`, red instead of amber, so the two never read alike. */
.notice.bad{background:var(--red-100);color:var(--red-700);
  border-color:color-mix(in srgb,var(--red-700) 30%,transparent)}
.notice .hold-list{margin:.35rem 0;padding-left:1.1rem}
.notice .hold-list li{margin:.15rem 0}
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);padding:1.2rem 1.4rem;margin-bottom:1.1rem}
/* A wide table scrolls inside its own card. `overflow:hidden` clipped it instead, so a
   narrow window silently cut the last column off at the edge with nothing to say so.
   The y axis stays hidden to keep the rounded corners; a modal dialog inside a row is
   in the top layer and is not clipped by either. */
.card.flush{padding:0;overflow:auto hidden}.card.flush table{margin:0}
.card.flush .card-head{padding:.9rem 1.2rem;border-bottom:1px solid var(--line);display:flex;align-items:center;justify-content:space-between;gap:1rem}
.card-head h2{margin:0}.card.wip{opacity:.55}
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:1rem;margin-bottom:1.1rem}
.add-grid{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}
.stat{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);padding:1.05rem 1.25rem}
.stat .label{font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-weight:600}
.stat .value{font-size:2rem;font-weight:700;color:var(--brand);letter-spacing:-.02em;line-height:1.15;margin:.3rem 0 .35rem}
.stat .value.warn{color:var(--red-700)}.stat .hint{font-size:.82rem;color:var(--muted)}.stat .hint a{font-weight:600}

/* hero / smart input */
.hero{padding:1.6rem 1.6rem 1.2rem;background:linear-gradient(135deg,var(--surface) 0%,var(--surface-2) 100%);position:relative;overflow:hidden}
.hero::after{content:"";position:absolute;right:-60px;top:-60px;width:220px;height:220px;border-radius:50%;border:1px solid var(--line-2);opacity:.6;pointer-events:none}
.hero::before{content:"";position:absolute;right:-20px;top:-20px;width:140px;height:140px;border-radius:50%;border:1px solid var(--line-2);opacity:.6;pointer-events:none}
.hero h1{margin-bottom:.9rem}
.smart-row{display:flex;gap:.6rem}.smart-row input{flex:1;font-size:1.15rem;padding:.8rem 1rem;border-radius:10px;border:2px solid var(--line-2);background:var(--surface)}
.smart-row input:focus{border-color:var(--accent);outline:none;box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 18%,transparent)}
.smart-row button{padding:.8rem 1.4rem;font-size:1rem;border-radius:10px}
.smart-meta{display:flex;gap:1.2rem;align-items:center;margin-top:.6rem;min-height:1.6rem;flex-wrap:wrap}
.check{display:flex;gap:.5rem;align-items:center;font-size:.9rem;cursor:pointer}.check.big{align-items:flex-start;font-size:1rem}.check.wip{opacity:.55;cursor:not-allowed}
.channels{display:flex;gap:1.2rem;flex-wrap:wrap;margin:.4rem 0}
.indicator{display:none;margin-top:.8rem}.htmx-request .indicator,.indicator.htmx-request{display:block}
.bar{height:6px;border-radius:3px;background:var(--line);overflow:hidden;position:relative}
.bar i{display:block;height:100%;background:linear-gradient(90deg,var(--cyan),var(--green));border-radius:3px;transition:width .6s ease}
.indicator .bar i{width:40%;animation:sweep 1.1s ease-in-out infinite}
@keyframes sweep{0%{transform:translateX(-100%)}100%{transform:translateX(260%)}}

/* console */
.console{background:var(--console-bg);color:var(--console-fg);border-radius:10px;padding:1rem 1.2rem;font-family:var(--mono);font-size:.82rem;border:1px solid rgba(63,224,143,.25);box-shadow:inset 0 0 40px rgba(63,224,143,.06)}
.console .bar{background:rgba(255,255,255,.08);margin-bottom:.8rem}.console .bar i{background:linear-gradient(90deg,#3fe08f,#36d4ff)}
.console pre{margin:0;white-space:pre-wrap;line-height:1.5;min-height:6rem}.console.compact pre{min-height:3rem}
.console .cursor{animation:blink 1s steps(1) infinite}@keyframes blink{50%{opacity:0}}
.console .actions{margin-top:.8rem}

/* tables */
table{width:100%;border-collapse:collapse;font-size:.9rem}
th,td{text-align:left;padding:.62rem .9rem;border-bottom:1px solid var(--line);vertical-align:middle}
th{font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-weight:600;background:var(--surface-2)}
tbody tr:last-child td{border-bottom:0}tbody tr:hover td{background:var(--surface-2)}
td.num{font-variant-numeric:tabular-nums}.empty{color:var(--muted);text-align:center;padding:1.6rem}

/* badges */
.badge{display:inline-flex;align-items:center;gap:.3rem;padding:.12rem .55rem;border-radius:999px;font-size:.68rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;white-space:nowrap;margin-right:.3rem;background:var(--chip);color:var(--chip-fg)}
.badge.mock{background:var(--amber-100);color:var(--amber-700)}.badge.live{background:var(--green-100);color:var(--green-700)}
.badge.ep{background:var(--surface-2);color:var(--fg-2);text-transform:none;letter-spacing:0;font-weight:600;border:1px solid var(--line)}
.sev{display:inline-block;padding:.12rem .55rem;border-radius:4px;font-size:.7rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}
.sev-low{background:var(--surface-2);color:var(--fg-2);border:1px solid var(--line)}.sev-medium{background:var(--amber-100);color:var(--amber-700)}
.sev-high{background:var(--red-100);color:var(--red-700)}.sev-critical{background:var(--red);color:#fff}
.st{display:inline-flex;align-items:center;gap:.4rem;font-weight:600;font-size:.85rem}.st::before{content:"";width:8px;height:8px;border-radius:50%}
.st-new::before{background:var(--red)}.st-seen::before{background:var(--amber)}.st-resolved::before{background:var(--green-700)}
.conf{display:inline-block;min-width:80px;height:6px;border-radius:3px;background:var(--line);position:relative;vertical-align:middle;margin-right:.4rem}
.conf i{position:absolute;left:0;top:0;bottom:0;border-radius:3px;background:var(--accent)}
.validate{font-size:.8rem;align-self:center;min-width:8rem}.validate.ok{color:var(--green-700)}.validate.bad{color:var(--red-700)}

/* messages */
.flash{padding:.7rem 1rem;border-radius:var(--r);margin-bottom:1rem;background:var(--green-100);color:var(--green-700);border:1px solid color-mix(in srgb,var(--green-700) 30%,transparent);font-weight:500}
.flash.err{background:var(--red-100);color:var(--red-700);border-color:color-mix(in srgb,var(--red-700) 30%,transparent)}
/* The way out of a refusal. An arrow rather than a sentence: the message already says what
   is missing, and repeating "record the decision" as link text would say it twice. Big
   enough to hit on a touch screen, which a bare glyph is not. */
.flash .go,small.danger .go{display:inline-block;margin-left:.35rem;padding:0 .3rem;
  border-radius:4px;font-weight:700;text-decoration:none;line-height:1.4;color:inherit;
  border:1px solid color-mix(in srgb,currentColor 35%,transparent)}
.flash .go:hover,small.danger .go:hover{background:color-mix(in srgb,currentColor 12%,transparent);
  text-decoration:none}
/* A schema that is behind is not a warning, it is broken writes. Red, not amber. */
.notice.err{background:var(--red-100);color:var(--red-700);border-color:color-mix(in srgb,var(--red-700) 35%,transparent)}
.notice code{font-family:var(--mono);font-size:.82rem;background:color-mix(in srgb,currentColor 10%,transparent);padding:.05rem .3rem;border-radius:4px}
.notice{display:flex;gap:.7rem;align-items:flex-start;padding:.7rem 1rem;border-radius:var(--r);background:var(--amber-100);color:var(--amber-700);border:1px solid color-mix(in srgb,var(--amber-700) 30%,transparent);margin-bottom:1rem;font-size:.88rem}
.hint{font-size:.85rem;color:var(--muted)}.muted{color:var(--muted)}small{color:var(--muted)}
.result-ok{color:var(--green-700);font-weight:600}.result-bad{color:var(--red-700);font-weight:600}

/* forms */
input,select,textarea,button{font:inherit}
input,select,textarea{padding:.5rem .7rem;border:1px solid var(--line-2);border-radius:6px;background:var(--surface);color:var(--fg);min-width:0}
input[type="checkbox"],input[type="radio"]{width:16px;height:16px;min-width:16px;flex:none;padding:0;margin:0;
  border:0;border-radius:0;background:none;accent-color:var(--accent);vertical-align:middle}
.check input[type="checkbox"]{margin-top:.15rem}
.check.big input[type="checkbox"]{margin-top:.2rem}
input:focus,select:focus,textarea:focus{outline:2px solid var(--accent);outline-offset:0;border-color:var(--accent)}
input::placeholder{color:var(--muted)}input:disabled,button:disabled{opacity:.5;cursor:not-allowed}
input.sm,select.sm{padding:.3rem .5rem;font-size:.82rem}
button,.btn{display:inline-block;padding:.5rem 1rem;border-radius:6px;border:1px solid var(--accent);background:var(--accent);color:var(--accent-fg);font-weight:600;cursor:pointer;white-space:nowrap;text-decoration:none!important}
button:hover,.btn:hover{filter:brightness(1.08)}
button.accent,.btn.accent{background:var(--cyan);border-color:var(--cyan);color:var(--violet-700)}
[data-theme="console"] button.accent,[data-theme="console"] .btn.accent{background:#3fe08f;border-color:#3fe08f;color:#06110b}
button.ghost,.btn.ghost{background:var(--surface);color:var(--fg);border-color:var(--line-2)}button.ghost:hover{background:var(--surface-2)}
button.danger{background:var(--surface);color:var(--red-700);border-color:color-mix(in srgb,var(--red-700) 40%,transparent)}button.danger:hover{background:var(--red);border-color:var(--red);color:#fff}
button.sm,.btn.sm{padding:.3rem .65rem;font-size:.8rem}
form.inline{display:inline-flex;gap:.4rem;align-items:center;margin:0}
.row{display:flex;gap:.8rem;flex-wrap:wrap;align-items:flex-end}
.row label{display:flex;flex-direction:column;gap:.3rem;font-size:.7rem;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:600}
.row label input,.row label select{font-size:.92rem;letter-spacing:0;text-transform:none;font-weight:400}
.row label.check{flex-direction:row;text-transform:none;letter-spacing:0;font-size:.9rem;font-weight:500;color:var(--fg);align-self:center}
.w-md{width:260px;max-width:100%}.w-lg{width:380px;max-width:100%}
.actions{display:flex;gap:.4rem;flex-wrap:wrap;align-items:center}.actions.end{justify-content:flex-end;margin-top:1rem}
/* The monitoring table has eight columns and the last one is a stack of buttons. Measured
   at a 1280px window: the table wanted 1082px inside a 955px card, so 127px of the actions
   column was cut off -- and the horizontal scroll that catches it is a rescue, not a fit.
   Below the width where it fits on its own, the buttons stack full-width in a narrow column
   and the cells give back some padding. That is ~170px, which is more than the shortfall. */
@media (max-width:1439px){
  th,td{padding:.55rem .6rem}
  td.actions{flex-direction:column;align-items:stretch;max-width:8.5rem}
  /* `button` is nowrap everywhere else, which is right for a row of buttons and wrong
     for a narrow stack: it is what clipped "Continue verification" mid-word. */
  td.actions button,td.actions .btn{width:100%;text-align:center;white-space:normal;
    line-height:1.25;padding-top:.35rem;padding-bottom:.35rem}
  td.actions form.inline{display:flex}
  td.actions form.inline button{width:100%}
  /* A badge is nowrap so its own text never breaks mid-phrase. In the attack-surface cell
     that made three badges one unbreakable run; here they may wrap between each other. */
  td .badge{margin-right:.2rem}
  .surface-cell{display:flex;flex-wrap:wrap;gap:.25rem;max-width:11rem}
  td.num{white-space:normal}
  /* The verification badge carries a whole phrase ("attested by customer"). Below the
     width where the table fits, it may break across lines like any other text. */
  td .badge.ep{white-space:normal}
}
.kv{width:auto;font-size:.86rem}.kv th{width:200px;background:transparent;font-size:.7rem}.kv td{font-family:var(--mono);font-size:.8rem;word-break:break-all}
.source-hit{border-left:3px solid var(--accent)}
.choices{display:flex;gap:.8rem;flex-wrap:wrap}
.choice{display:flex;gap:.6rem;align-items:flex-start;padding:.8rem 1rem;border:1px solid var(--line-2);border-radius:8px;cursor:pointer;min-width:220px}
.choice.on{border-color:var(--accent);box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 25%,transparent)}
.choice small{display:block;margin-top:.15rem}

/* wizard */
.wizard{max-width:860px}
.steps{list-style:none;display:flex;gap:.4rem;padding:0;margin:0;flex-wrap:wrap}
.steps li{font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);padding:.3rem .7rem;border-radius:999px;border:1px solid var(--line)}
.steps li.on{background:var(--accent);color:var(--accent-fg);border-color:var(--accent)}.steps li.done{color:var(--green-700);border-color:var(--green-700)}
.chips{list-style:none;padding:0;margin:1rem 0 0;display:flex;flex-wrap:wrap;gap:.5rem}
.chips li{display:inline-flex;align-items:center;gap:.5rem;padding:.35rem .4rem .35rem .8rem;border:1px solid var(--line-2);border-radius:999px;background:var(--surface-2)}
.chips small{font-size:.7rem}

/* dialogs */
dialog.breach-dialog{border:0;border-radius:10px;padding:1.4rem 1.6rem;max-width:640px;width:calc(100% - 2rem);box-shadow:0 30px 80px rgba(0,0,0,.4);color:var(--fg);background:var(--surface);font-family:var(--body-font)}
dialog.breach-dialog::backdrop{background:rgba(7,10,15,.6)}
.dialog-head{display:flex;justify-content:space-between;align-items:center;gap:1rem;margin-bottom:.8rem}
.dialog-head h3{margin:0;font-size:1.15rem;color:var(--brand)}.dialog-text{margin:1rem 0 .6rem;line-height:1.6}

/* auth */
.auth{min-height:100vh;display:grid;place-items:center;background:#1d0e42;background-image:radial-gradient(ellipse 60% 50% at 80% 20%,rgba(54,212,255,.35),transparent 60%),radial-gradient(ellipse 50% 40% at 10% 90%,rgba(63,224,143,.22),transparent 60%);padding:2rem}
[data-theme="console"] .auth{background:#050709;background-image:radial-gradient(ellipse 60% 50% at 80% 20%,rgba(63,224,143,.18),transparent 60%),repeating-linear-gradient(0deg,transparent 0 2px,rgba(63,224,143,.025) 2px 3px)}
.auth .brand{margin-bottom:1.4rem;justify-content:center}
.auth .card{width:100%;max-width:400px;padding:1.8rem 1.8rem 1.6rem;box-shadow:0 24px 60px rgba(0,0,0,.35)}
.auth h1{font-size:1.25rem;margin-bottom:1rem}
.auth label{display:block;font-size:.7rem;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);font-weight:600;margin:.7rem 0 .3rem}
.auth input{width:100%}.auth button{width:100%;margin-top:1.1rem;padding:.65rem}
.auth .foot{margin-top:1.2rem;text-align:center;font-size:.78rem;color:rgba(255,255,255,.6)}
@media (max-width:900px){.shell{grid-template-columns:1fr}.side{position:static;height:auto}main{padding:1.2rem}}

/* toast bubbles for outgoing API calls */
.toasts{position:fixed;right:1rem;bottom:1rem;display:flex;flex-direction:column;gap:.5rem;z-index:50;max-width:min(560px,calc(100vw - 2rem));pointer-events:none}
.toast{display:flex;align-items:flex-start;gap:.55rem;padding:.5rem .7rem;border-radius:8px;background:var(--surface);border:1px solid var(--line-2);box-shadow:0 8px 24px rgba(0,0,0,.18);font-family:var(--mono);font-size:.74rem;color:var(--fg);animation:toast-in .25s ease;transition:opacity .5s,transform .5s}
.toast .dot{width:8px;height:8px;border-radius:50%;flex:none;margin-top:.35rem}
/* the whole URL is shown, wrapping instead of truncating */
.toast .ep{flex:1;min-width:0;word-break:break-all;line-height:1.4}
.toast .code{flex:none;font-weight:700;padding:.05rem .4rem;border-radius:4px;letter-spacing:.02em;margin-top:.1rem}
.toast .meta{color:var(--muted);flex:none;margin-top:.15rem}
.toast.ok .dot{background:var(--green-700);box-shadow:0 0 8px var(--green-700)}
.toast.ok .code{background:var(--green-100);color:var(--green-700)}
.toast.bad .dot{background:var(--red);box-shadow:0 0 8px var(--red)}
.toast.bad .code{background:var(--red-100);color:var(--red-700)}
/* A hold is server-rendered and has no timer of its own: the CSP allows no inline script,
   and the poll's timers belong to the toasts the poll made. Thirty seconds, then it fades
   and stops taking hit-tests -- the column is pointer-events:none anyway, and `visibility`
   rather than `display` keeps the animation cheap. Long enough to read twice; a hold is
   not news that repeats every two seconds. */
.toast.hold{animation:toast-in .25s ease,toast-hold-out .6s ease 29.4s forwards}
@keyframes toast-hold-out{to{opacity:0;visibility:hidden}}
@media (prefers-reduced-motion:reduce){.toast.hold{animation:toast-hold-out .01s linear 30s forwards}}
.notice .hold-list .used{font-weight:600;white-space:nowrap}
.toast.none .dot{background:var(--muted)}
.toast.none .code{background:var(--surface-2);color:var(--fg-2);border:1px solid var(--line)}
.toast.none .ep{color:var(--fg-2)}
.toast.warn .dot{background:var(--amber);box-shadow:0 0 8px var(--amber)}
.toast.warn .code{background:var(--amber-100);color:var(--amber-700)}
.toast.out{opacity:0;transform:translateX(12px)}
@keyframes toast-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
[data-theme="console"] .toast{background:#0b1118;border-color:rgba(63,224,143,.3);color:#c9d6de}

/* wizard progress */
.progress{list-style:none;display:flex;padding:0;margin:1rem 0 .4rem;counter-reset:step}
.progress li{flex:1;position:relative;text-align:center;font-size:.68rem;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);padding-top:2rem}
.progress li .num{position:absolute;top:0;left:50%;transform:translateX(-50%);width:26px;height:26px;border-radius:50%;background:var(--surface);border:2px solid var(--line-2);display:grid;place-items:center;font-size:.72rem;font-weight:700;color:var(--muted);z-index:1;letter-spacing:0}
.progress li::before{content:"";position:absolute;top:12px;left:-50%;width:100%;height:2px;background:var(--line-2)}
.progress li:first-child::before{display:none}
.progress li.done .num{background:var(--green-700);border-color:var(--green-700);color:#fff}
.progress li.done::before,.progress li.on::before{background:var(--green-700)}
.progress li.on .num{background:var(--accent);border-color:var(--accent);color:var(--accent-fg);box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 22%,transparent)}
.progress li.on{color:var(--fg);font-weight:700}

.recs ol,.recs-list{margin:.4rem 0 0;padding-left:1.3rem;line-height:1.6}.recs li,.recs-list li{margin-bottom:.35rem}
.recs li:first-child{font-weight:600}.dialog-sub{margin:1rem 0 .2rem;font-size:.72rem;letter-spacing:.1em;text-transform:uppercase;color:var(--fg-2)}

/* critical findings */
tr.crit td:first-child{box-shadow:inset 3px 0 0 var(--red)}
tr.crit td{background:color-mix(in srgb,var(--red) 6%,transparent)}
tbody tr.crit:hover td{background:color-mix(in srgb,var(--red) 10%,transparent)}
.stat.crit{border-color:color-mix(in srgb,var(--red) 45%,var(--line))}
.sev-critical{background:var(--red);color:#fff;box-shadow:0 0 0 2px color-mix(in srgb,var(--red) 25%,transparent)}
.alarm{display:flex;gap:.7rem;align-items:center;padding:.8rem 1.1rem;border-radius:var(--r);background:var(--red-100);color:var(--red-700);border:1px solid color-mix(in srgb,var(--red-700) 35%,transparent);margin-bottom:1.1rem;font-size:.92rem}
.alarm .pulse{width:10px;height:10px;border-radius:50%;background:var(--red);flex:none;animation:pulse 1.6s ease-out infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--red) 60%,transparent)}70%{box-shadow:0 0 0 10px transparent}100%{box-shadow:0 0 0 0 transparent}}


/* invoice */
.invoice{max-width:820px}
.inv-head{display:flex;justify-content:space-between;gap:2rem;flex-wrap:wrap;margin-bottom:1.6rem}
.inv-issuer{line-height:1.5}
.inv-meta .kv th{width:150px}
.inv-to{margin:1rem 0 1.6rem;line-height:1.5}
.inv-to .label{font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-weight:600;margin-bottom:.3rem}
.inv-items{margin-top:.5rem}
.inv-items tfoot th{font-size:.95rem;text-transform:none;letter-spacing:0;color:var(--fg);background:transparent;border-top:2px solid var(--line-2)}
@media print{.side,.page-head .actions,.notice,.flash,#toasts{display:none!important}.shell{display:block}main{padding:0;max-width:none}.card{border:0;box-shadow:none}}

/* utilities (no inline style attributes: our CSP forbids them) */
.u-center{margin-top:1rem;text-align:center}
.u-lg{font-size:1.4rem}.u-md{font-size:1.3rem}.u-sm{font-size:1.25rem}
.u-w100{width:100px}.u-wfull{width:100%}.u-block{display:block}.u-flat{margin:0;padding:0 0 .8rem}.u-m0{margin:0}
.u-mt-xs{margin-top:.4rem;line-height:1.5}.u-mt-sm{margin-top:.5rem}.u-mt-md{margin-top:.8rem}
.u-mb-xs{margin-bottom:.5rem}.u-mb-sm{margin-bottom:.6rem}

/* htmx indicator rules: we ship them ourselves because the CSP forbids htmx's inline style tag */
.htmx-indicator{opacity:0;transition:opacity .2s}
.htmx-request .htmx-indicator,.htmx-request.htmx-indicator{opacity:1}

/* risk score */
.risk{display:inline-flex;align-items:center;gap:.4rem;font-variant-numeric:tabular-nums}
.risk .risk-dot{width:10px;height:10px;border-radius:50%;flex:none}
.risk strong{font-size:1.05rem}
.risk .risk-band{font-size:.7rem;letter-spacing:.06em;text-transform:uppercase;font-weight:700;padding:.1rem .45rem;border-radius:4px}
.risk-low .risk-dot{background:var(--green-700)}.risk-low .risk-band{background:var(--green-100);color:var(--green-700)}
.risk-medium .risk-dot{background:var(--amber)}.risk-medium .risk-band{background:var(--amber-100);color:var(--amber-700)}
.risk-high .risk-dot{background:var(--red)}.risk-high .risk-band{background:var(--red-100);color:var(--red-700)}
.risk-critical .risk-dot{background:var(--red);box-shadow:0 0 0 3px color-mix(in srgb,var(--red) 30%,transparent)}
.risk-critical .risk-band{background:var(--red);color:#fff}
.risk-value.risk-low{color:var(--green-700)}.risk-value.risk-medium{color:var(--amber-700)}
.risk-value.risk-high,.risk-value.risk-critical{color:var(--red-700)}
dialog.breach-dialog.wide{max-width:860px}

/* top bar: the console lives here as a compact icon */
.topbar{display:flex;justify-content:flex-end;align-items:center;gap:.5rem;padding:.7rem 2.6rem 0;position:sticky;top:0;z-index:20;pointer-events:none}
.topbar > *{pointer-events:auto}
.console-btn{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:8px;
  border:1px solid var(--line-2);background:var(--surface);color:var(--fg-2);font-family:var(--mono);font-size:.9rem;font-weight:700;
  box-shadow:var(--shadow);text-decoration:none!important;transition:color .15s,border-color .15s,background .15s}
.console-btn:hover{color:var(--accent);border-color:var(--accent);background:var(--surface-2)}
.console-btn.active{color:var(--accent-fg);background:var(--accent);border-color:var(--accent)}
.content main{padding-top:.6rem}
/* account area at the bottom of the sidebar */
.side .foot-nav{display:flex;flex-direction:column;gap:.15rem;margin:0 -.75rem .8rem}
.side .foot-nav a{display:flex;align-items:center;gap:.65rem;padding:.45rem .75rem;border-radius:6px;color:var(--side-fg);font-weight:500;font-size:.9rem}
.side .foot-nav a::before{content:"";width:6px;height:6px;border-radius:50%;background:rgba(255,255,255,.18)}
.side .foot-nav a:hover{background:rgba(255,255,255,.07);color:#fff;text-decoration:none}
.side .foot-nav a.active{background:var(--side-active);color:#fff}
.side .foot-nav a.active::before{background:var(--cyan)}
[data-theme="console"] .side .foot-nav a.active::before{background:#3fe08f}
@media (max-width:900px){.topbar{padding:.7rem 1.2rem 0}}

/* terms */
.terms-page .card{max-width:820px}
.terms{max-width:820px;line-height:1.65}
.terms .terms-h{font-size:.95rem;font-weight:700;letter-spacing:0;text-transform:none;color:var(--brand);margin:1.4rem 0 .3rem}
.terms .terms-h:first-child{margin-top:0}
.terms ul{margin:.3rem 0 .8rem;padding-left:1.2rem}.terms li{margin-bottom:.3rem}
.terms.scroll{max-height:46vh;overflow-y:auto}
.check.terms-check{align-items:flex-start;margin:.8rem 0;font-size:.9rem}
.check.big span{line-height:1.5}

.card.flush .inset{padding:0 1.2rem 1rem}
.card.flush .empty{padding:1.2rem}
.exposure-grid{margin:1rem 1.2rem}

.inv-items tfoot th{border-top:0}
.inv-items tfoot tr.total th{border-top:2px solid var(--line-2);font-size:1rem}

/* Attack-surface cell: a row of small badges, wrapping on narrow screens */
.surface-cell { display: flex; flex-wrap: wrap; gap: .25rem; align-items: center; }
.surface-cell .badge { white-space: nowrap; }
p.attribution { margin-top: .5rem; opacity: .8; }
ul.plain { list-style: none; margin: 0; padding: 0; }
ul.plain li { padding: .1rem 0; }

/* Source catalogue: the evaluation note runs under its own row, full width */
tr.note-row td { padding-top: 0; border-top: 0; }
tr.note-row + tr td { border-top: 1px solid var(--line); }

/* Attack-surface cell: the address reads as data, not as prose */
.surface-cell code.ip { font-size: .78rem; opacity: .85; }

/* Customer list: rows with something open are tinted, not shouted at */
tr.row-attention td { background: color-mix(in srgb, var(--amber-700) 6%, transparent); }
button.as-button { border: 0; cursor: pointer; font: inherit; }
.danger { color: var(--red-700); }

/* --- SOC: work queue on the left, live picture on the right ------------------------- */
.soc-split { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 1rem; align-items: start; }
@media (max-width: 1100px) { .soc-split { grid-template-columns: minmax(0, 1fr); } }
.soc-main { min-width: 0; }

.alert-card { border-left: 3px solid transparent; }
.sev-border-critical { border-left-color: var(--red); }
.sev-border-high { border-left-color: var(--red-700); }
.sev-border-medium { border-left-color: var(--amber-700); }
.sev-border-low { border-left-color: var(--line-2); }

.mitigation { display: flex; flex-direction: column; gap: .6rem; }
.mitigation-row { display: flex; flex-wrap: wrap; gap: 1rem; }
.mitigation-row .check { flex: 0 1 auto; }
.mitigation label.reason { display: block; width: 100%; }
.mitigation textarea { display: block; width: 100%; box-sizing: border-box; min-height: 3.4rem; resize: vertical; font: inherit; padding: .5rem; }

/* the feed reads like a ticker: dense, monospaced accents, a quiet pulse */
.soc-feed { position: sticky; top: 1rem; border: 1px solid var(--line); border-radius: 10px; overflow: hidden; background: var(--surface); }
.feed-head { padding: .7rem .8rem; border-bottom: 1px solid var(--line); display: grid; grid-template-columns: auto 1fr; gap: .4rem .5rem; align-items: center; }
.feed-head h2 { margin: 0; font-size: .95rem; }
.feed-head small { grid-column: 1 / -1; opacity: .7; font-size: .72rem; }
.feed-head .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--red-700); animation: feed-pulse 2.4s ease-in-out infinite; }
@keyframes feed-pulse { 0%, 100% { opacity: .35; } 50% { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .feed-head .dot { animation: none; opacity: .8; } }
ol.feed { list-style: none; margin: 0; padding: 0; max-height: 30rem; overflow-y: auto; }
.feed-item { display: grid; grid-template-columns: 1.4rem 1fr auto; gap: .5rem; padding: .55rem .8rem; border-bottom: 1px solid var(--line); border-left: 2px solid transparent; }
.feed-item:last-child { border-bottom: 0; }
.feed-icon { font-size: .9rem; line-height: 1.4; }
.feed-body { min-width: 0; display: flex; flex-direction: column; }
.feed-body strong { font-size: .82rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed-sub { font-size: .72rem; opacity: .75; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.feed-detail { font-size: .7rem; opacity: .6; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed-item time { font-size: .68rem; opacity: .55; white-space: nowrap; }

table.compliance td small { display: block; max-width: 34rem; }

/* Source list: one table, the inactive half visibly quieter */
table.sources tr.section td { background: var(--line); font-size: .72rem; letter-spacing: .08em;
  text-transform: uppercase; opacity: .75; padding: .35rem .6rem; }
table.sources tr.row-inactive td { opacity: .68; }
table.sources tr.note-row td { padding-top: 0; }

/* --- Introduction cards: one message, one decision ---------------------------------- */
.guide { max-width: 44rem; }
.guide-dots { display: flex; gap: .4rem; list-style: none; margin: 0 0 .9rem; padding: 0; }
.guide-dots li { width: 1.9rem; height: 3px; border-radius: 2px; background: var(--line);
  transition: background .25s ease; }
.guide-dots li.on { background: var(--accent); }
.guide-card { border: 1px solid var(--line); border-radius: 12px; padding: 1.6rem 1.7rem;
  background: var(--surface); }
.guide-card.tone-urgent { border-left: 3px solid var(--red); }
.guide-card.tone-support { border-left: 3px solid var(--accent); }
.guide-step { font-size: .7rem; letter-spacing: .1em; text-transform: uppercase; opacity: .55; }
.guide-icon { font-size: 1.9rem; line-height: 1; margin: .5rem 0 .3rem; }
.guide-card h3 { margin: 0 0 .3rem; font-size: 1.25rem; }
.guide-lead { font-weight: 600; margin: 0 0 .8rem; }
.guide-card p { margin: 0 0 .7rem; line-height: 1.55; }

/* The support number is the one thing on the page that should be impossible to miss. */
.support-box { margin: 1.1rem 0 .4rem; padding: 1.1rem 1.2rem; border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent); text-align: center; }
.support-label { font-size: .7rem; letter-spacing: .12em; text-transform: uppercase; opacity: .7; }
.support-number { display: block; margin: .25rem 0 .2rem; font-size: 1.85rem; font-weight: 700;
  letter-spacing: .02em; color: var(--accent); text-decoration: none; }
.support-number:hover { text-decoration: underline; }
.support-note { font-size: .82rem; opacity: .8; }
@media (max-width: 560px) { .support-number { font-size: 1.5rem; } }
.compact-scan { margin-top: .8rem; }
.compact-scan h3 { margin: 0 0 .5rem; font-size: .95rem; opacity: .8; }

/* --- IT hygiene reference: a topic, a reason, and what to do -------------------------- */
.hygiene { display: grid; gap: 1.1rem; }
.hyg-section { border: 1px solid var(--line); border-radius: var(--r); background: var(--surface);
  box-shadow: var(--shadow); padding: 1.1rem 1.3rem; }
.hyg-section > h3 { display: flex; align-items: center; gap: .55rem; margin: 0 0 .2rem;
  font-size: 1.1rem; }
.hyg-icon { font-size: 1.2rem; }
.practice { padding: .85rem 0; border-top: 1px solid var(--line); }
.hyg-section .practice:first-of-type { border-top: 0; padding-top: .4rem; }
.practice h4 { margin: 0 0 .2rem; font-size: .98rem; }
.practice-why { margin: 0 0 .5rem; color: var(--fg-2); line-height: 1.5; }
.practice-steps { margin: 0; padding-left: 1.1rem; }
.practice-steps li { margin-bottom: .25rem; line-height: 1.5; }
.practice-ours { margin: .55rem 0 0; padding: .4rem .6rem; border-radius: 8px; font-size: .85rem;
  background: color-mix(in srgb, var(--green) 12%, transparent); color: var(--green-700); }
.u-mt-lg { margin-top: 2rem; }

/* --- API documentation: a wide, readable page for a partner without an account ------- */
.doc-body{background:var(--bg)}
.doc-top{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.9rem 1.6rem;background:var(--side-bg);color:#fff;position:sticky;top:0;z-index:5}
.doc-brand{display:flex;align-items:center;gap:.65rem;color:#fff;font-weight:700}
.doc-brand:hover{text-decoration:none}
.doc-brand .mark{color:var(--cyan);display:grid;place-items:center}
.doc-brand small{display:block;font-weight:500;font-size:.66rem;letter-spacing:.09em;text-transform:uppercase;color:rgba(255,255,255,.6);margin-top:.1rem}
.doc-topnav{display:flex;align-items:center;gap:1.1rem;font-size:.85rem}
.doc-topnav a{color:rgba(255,255,255,.8)}
.doc-topnav .langs{margin:0}
.doc-shell{display:grid;grid-template-columns:230px minmax(0,1fr);gap:2rem;max-width:1180px;margin:0 auto;padding:1.8rem 1.6rem 3rem}
.doc-nav{position:sticky;top:4.4rem;align-self:start;max-height:calc(100vh - 6rem);overflow:auto}
.doc-nav nav{display:flex;flex-direction:column;gap:.1rem}
.doc-nav .group{font-size:.64rem;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);padding:.9rem .5rem .3rem}
.doc-nav a{padding:.35rem .5rem;border-radius:6px;color:var(--fg-2);font-size:.86rem}
.doc-nav a:hover{background:var(--surface);color:var(--fg);text-decoration:none}
.doc-main{min-width:0;max-width:820px}
.doc-head h1{margin:0 0 .5rem;font-size:1.7rem}
.doc-lead{font-size:1.02rem;line-height:1.65;color:var(--fg-2);margin:0 0 .9rem}
.doc-base{margin:0 0 1.6rem}
.doc-section{margin:0 0 2.4rem;scroll-margin-top:5rem}
.doc-section h2{margin:0 0 .3rem;font-size:1.22rem;letter-spacing:0;text-transform:none;font-weight:700;color:var(--fg)}
.doc-sub{margin:0 0 .9rem;font-weight:600;color:var(--fg-2)}
.doc-section p{line-height:1.62;margin:0 0 .75rem;max-width:70ch}
.doc-code{margin:.9rem 0 1.1rem}
.doc-code pre{margin:0;padding:.85rem 1rem;background:var(--surface);border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:var(--r);overflow-x:auto;font-family:var(--mono);font-size:.8rem;line-height:1.55;white-space:pre}
.doc-code figcaption{font-size:.78rem;color:var(--muted);margin-top:.35rem}
.doc-ep{border:1px solid var(--line);border-radius:var(--r);background:var(--surface);padding:1rem 1.15rem;margin:0 0 1rem;scroll-margin-top:5rem}
.doc-ep h3{margin:0 0 .45rem;font-size:.95rem;display:flex;align-items:center;gap:.55rem;flex-wrap:wrap}
.doc-ep h3 code{background:transparent;color:var(--fg);padding:0;font-size:.92rem;font-weight:600}
.doc-ep-scope{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap;margin:0 0 .5rem!important}
.badge.ep.m-post{border-color:var(--amber-700);color:var(--amber-700)}
.doc-params{margin:.6rem 0 0}
.doc-params th{width:150px;vertical-align:top}
.doc-params td{font-family:var(--body-font);word-break:normal}
.doc-params .req{color:var(--red-700)}
/* The reference tables are four columns of prose wide and fit on no phone. Each one
   scrolls inside its own box -- the same rule as a wide table in `.card.flush` -- rather
   than making the document 178px wider than the window and pushing the body sideways.
   `width:auto` lets the table reach its own width instead of the container's; `min-width`
   keeps the header row spanning the whole box on the days the content does fit. */
.doc-table{overflow-x:auto}
.doc-table table{min-width:100%;width:auto}
.doc-rules{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:.9rem}
.doc-rule{border:1px solid var(--line);border-left:3px solid var(--line-2);border-radius:var(--r);background:var(--surface);padding:.85rem 1rem}
.doc-rule h4{margin:0 0 .35rem;font-size:.92rem}
.doc-rule p{margin:0;font-size:.88rem;line-height:1.55;color:var(--fg-2)}
.doc-foot{border-top:1px solid var(--line);padding-top:1.1rem;margin-top:2rem;font-size:.9rem}
.doc-foot p{margin:0 0 .3rem}
@media (max-width:880px){.doc-shell{grid-template-columns:minmax(0,1fr)}.doc-nav{display:none}}
@media (max-width:640px){
  .doc-top{flex-wrap:wrap;gap:.55rem;padding:.7rem 1rem}
  .doc-topnav{width:100%;justify-content:flex-start;gap:.9rem;font-size:.8rem}
  .doc-topnav .langs{margin-left:auto}
}

/* --- API keys: the scope picker on the issue form ------------------------------------ */
.scopes{border:1px solid var(--line);border-radius:var(--r);background:var(--surface-2);padding:.7rem .9rem .8rem;margin:.9rem 0 .6rem;display:flex;flex-direction:column;gap:.45rem}
.scopes legend{font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);padding:0 .35rem}
.scopes .check span{display:flex;align-items:baseline;gap:.5rem;flex-wrap:wrap}
.scopes .check code{flex:none}

/* --- Zweiter Faktor: Code scannen oder abtippen -------------------------------------- */
.enroll{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:1.6rem;align-items:start}
.enroll-steps ol{margin:0 0 .9rem;padding-left:1.2rem}
.enroll-steps li{margin-bottom:.45rem;line-height:1.55}
.enroll-secret{display:inline-block;margin-top:.3rem;font-size:.95rem;letter-spacing:.06em}
.enroll-qr{display:flex;flex-direction:column;align-items:center;gap:.5rem;max-width:230px}
/* Immer dunkel auf weiss, unabhängig vom Thema: eine Kamera braucht den Kontrast, und ein
   QR-Code, der dem dunklen Thema folgt, ist ein QR-Code, der nicht scannt. */
.enroll-qr .qr{background:#fff;padding:.7rem;border-radius:var(--r);border:1px solid var(--line-2);line-height:0}
.enroll-qr .qr svg{width:190px;height:190px;display:block}
.enroll-qr .hint{text-align:center;font-size:.78rem;line-height:1.4}
@media (max-width:720px){.enroll{grid-template-columns:minmax(0,1fr)}.enroll-qr{max-width:none}}

/* --- SOC: der Zeitstempel der Selbstaktualisierung ------------------------------------ */
.soc-stamp{grid-column:1/-1;margin:0 0 .2rem;font-size:.76rem;color:var(--muted);letter-spacing:.02em}
.soc-stamp-note{opacity:.7}
.soc-stamp-note::before{content:"· "}

/* --- Zustimmung auf der Anmeldekarte -------------------------------------------------
   `.auth label` ist die Regel für Feldbeschriftungen: block, versal, gesperrt. Sie traf
   auch die Checkbox-Labels — das Häkchen stand dadurch über statt neben dem Text, und der
   Text war in Versalien grösser gesetzt als die Beschriftungen darüber. Das hier ist
   Fliesstext neben einem Kästchen und wird auch so gesetzt. */
.auth label.check{display:flex;align-items:flex-start;gap:.5rem;margin:.75rem 0 0;
  font-size:.75rem;line-height:1.45;font-weight:400;letter-spacing:0;text-transform:none;
  color:var(--fg-2)}
/* `.auth input{width:100%}` gilt sonst auch für das Kästchen: es nimmt die ganze Zeile
   und drückt den Text aus der Karte. */
.auth label.check input[type="checkbox"]{flex:none;width:auto;margin:.12rem 0 0}
.auth label.check a{text-decoration:underline}

/* --- Telegram im Wizard: die drei Handgriffe, die sonst niemand kennt ---------------- */
.tg-setup{margin:.2rem 0 .9rem 1.9rem;padding-left:.9rem;border-left:2px solid var(--line)}
.tg-steps{margin:.6rem 0 .5rem;padding-left:1.1rem;font-size:.85rem;line-height:1.5;color:var(--fg-2)}
.tg-steps li{margin-bottom:.2rem}
.tg-setup .hint{margin:0;font-size:.8rem}

/* --- plans, pricing page, subscription ------------------------------------------------ */
.pricing-main{max-width:1100px;margin:0 auto;padding:2rem 1.5rem 4rem}
.plan-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(255px,1fr));gap:1rem;align-items:stretch}
.plan-grid.compact{margin-top:1rem}
.plan-card{position:relative;display:flex;flex-direction:column;border:1px solid var(--line-2);border-radius:12px;padding:1.3rem 1.3rem 1.1rem;background:var(--surface)}
.plan-card.featured{border-color:var(--accent);box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 22%,transparent)}
.plan-card.current{border-color:var(--green-700);background:var(--surface-2)}
.plan-flag{position:absolute;top:-.7rem;left:1.2rem;background:var(--accent);color:var(--accent-fg);font-size:.66rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;padding:.2rem .6rem;border-radius:999px}
.plan-card h2,.plan-card h3{margin:0;font-size:1.2rem;color:var(--brand)}
.plan-who{margin:.15rem 0 .6rem;font-size:.82rem;color:var(--muted)}
.plan-price{margin:.2rem 0 .7rem;display:flex;align-items:baseline;gap:.4rem}
.plan-price strong{font-size:1.7rem;letter-spacing:-.02em}
.plan-price span{font-size:.8rem;color:var(--muted)}
.plan-lead{margin:0 0 .8rem;font-size:.88rem;line-height:1.5}
.plan-limits{width:100%;margin:0 0 1rem;font-size:.84rem}
.plan-limits th{width:auto;font-size:.74rem;text-transform:none;letter-spacing:0;font-weight:400;color:var(--fg-2);padding:.28rem 0}
.plan-limits td{font-family:var(--body-font);font-size:.86rem;font-weight:600;padding:.28rem 0}
.plan-cta{margin-top:auto;text-align:center;display:block;width:100%}
.pricing-note{margin:1.2rem 0 0;max-width:70ch}
.feature-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:.9rem}
.feature{border:1px solid var(--line);border-radius:10px;padding:.9rem 1rem;background:var(--surface)}
.feature h3{margin:0 0 .3rem;font-size:.95rem;color:var(--brand)}
.feature p{margin:0;font-size:.86rem;line-height:1.5;color:var(--fg-2)}
.bar i.over{background:var(--red)}
.copy-row{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}
.copy-row code{flex:1 1 auto;min-width:0;word-break:break-all}
.copy-row button{flex:none}
.copy-row button.ok{border-color:var(--green-700);color:var(--green-700)}

/* --- SOC: customer clusters and the yes/no contact questions -------------------------- */
.soc-cluster{border-left:3px solid var(--line-2);padding-left:.9rem;margin:1.4rem 0}
.cluster-head{display:flex;align-items:baseline;justify-content:space-between;gap:1rem;flex-wrap:wrap;margin-bottom:.5rem}
.cluster-head h2{margin:0;font-size:1.05rem;color:var(--brand)}
.cluster-domain{font-weight:400;color:var(--muted);font-family:var(--mono);font-size:.85rem}
.soc-notice-state{margin:.5rem 0 .2rem;font-size:.83rem;color:var(--fg-2)}
.contact-grid{display:flex;gap:.8rem;flex-wrap:wrap;margin:.6rem 0 .2rem}
.contact-q{flex:1 1 15rem;border:1px solid var(--line-2);border-radius:8px;padding:.5rem .7rem .6rem;margin:0}
.contact-q.must{border-color:color-mix(in srgb,var(--red-700) 45%,transparent)}
.contact-q legend{font-size:.74rem;letter-spacing:.05em;text-transform:uppercase;color:var(--fg-2);font-weight:600;padding:0 .25rem}
.contact-q .yn{display:inline-flex;align-items:center;gap:.35rem;margin-right:.9rem;font-size:.9rem;cursor:pointer}
.contact-q .yn input{margin:0}
.check.waiver{border:1px dashed var(--line-2);border-radius:8px;padding:.5rem .7rem;margin-top:.5rem}
/* The probe column carries three different answers, and an error message is prose in a
   column of numbers -- it needs to wrap and to stop being right-aligned. */
td.probe{min-width:9rem}
.probe-err{display:block;text-align:left;white-space:normal;overflow-wrap:anywhere;
  font-family:var(--mono);font-size:.7rem;line-height:1.4;margin-top:.15rem}
/* --- commercial sources ---------------------------------------------------------- */
.comm-grid{grid-template-columns:repeat(auto-fit,minmax(320px,1fr));margin-bottom:0}
.card.comm{margin-bottom:0}
.card.comm.crit{border-color:var(--red-700)}
.comm-head{display:flex;align-items:baseline;justify-content:space-between;gap:.6rem;margin-bottom:.6rem}
.comm-price{font-family:var(--mono);font-size:.86rem;white-space:nowrap}
.comm-price small{color:var(--muted);font-size:.72rem}
/* Fourteen days of calls. Heights come from `data-width` through the CSSOM, because
   the CSP forbids style attributes -- the same mechanism every other dynamic width
   in this application uses. A day with no calls keeps a visible stub, so a gap reads
   as "nothing happened" rather than as a rendering fault. */
.comm-bars{display:flex;align-items:flex-end;gap:2px;height:2.6rem;
  padding:.3rem .4rem;background:var(--surface-2);border-radius:6px}
.comm-bars .bar{flex:1;min-width:3px;background:var(--accent);border-radius:2px 2px 0 0;
  align-self:flex-end;height:100%}
.comm-bars .bar.zero{background:var(--line-2);height:2px}
.comm-scale{display:flex;justify-content:space-between;margin:.2rem .1rem .7rem;font-size:.68rem}
.comm-kv{display:grid;grid-template-columns:max-content 1fr;gap:.25rem .8rem;margin:0;font-size:.82rem}
.comm-kv dt{color:var(--muted)}
.comm-kv dd{margin:0}
.run-detail{min-width:16rem}
/* --- the run drill-down on /ops/sources ------------------------------------------------ */
/* Raw request and response, each behind its own button. `pre` and not a table: this is the
   provider's own wording and its own shape, and reformatting it into our columns would be
   the one place where a debugging view stops showing what actually happened. */
pre.json{margin:.4rem 0 0;padding:.7rem .9rem;background:var(--surface);border:1px solid var(--line);
  border-left:3px solid var(--accent);border-radius:var(--r);overflow:auto;max-height:22rem;
  font-family:var(--mono);font-size:.76rem;line-height:1.5;white-space:pre;tab-size:2}
.json-head{margin:.9rem 0 0;font-size:.72rem;font-weight:600;color:var(--muted);
  text-transform:none;letter-spacing:0;overflow-wrap:anywhere}
.json-head code{font-size:.72rem}
td.raw{white-space:nowrap}
.raw-btn{padding:.1rem .45rem;font-size:.85rem;line-height:1.2;min-width:1.8rem}
.raw-btn + .raw-btn{margin-left:.25rem}
/* A body is only there while the process that fetched it is still running. Saying so on the
   button saves opening a popup to find out it has nothing extra in it. */
.raw-btn.has-body{border-color:var(--accent);color:var(--accent);font-weight:700}
.run-source{display:inline-flex;flex-direction:column;gap:.1rem;margin:0 .5rem .3rem 0;vertical-align:top}
.run-source small{font-size:.7rem;color:var(--muted);white-space:nowrap}
.call-samples{list-style:none;margin:.2rem 0 .4rem;padding:0 0 0 .4rem;display:flex;flex-direction:column;gap:.2rem}
.call-samples li{font-size:.76rem;display:flex;align-items:center;gap:.4rem;flex-wrap:wrap}
.call-samples code{font-size:.74rem;word-break:break-all;color:var(--fg-2)}

/* --- handbook ------------------------------------------------------------------------- */
.hb-step{margin:1.3rem 0 .2rem;font-size:1rem;color:var(--fg)}
.hb-group{margin:1.6rem 0 .6rem;font-size:1rem;color:var(--brand)}
.hb-limits{margin:1.1rem 0 0;padding:.8rem 1rem;border-left:3px solid var(--amber);background:var(--surface-2);border-radius:0 8px 8px 0}
.hb-limits h4{margin:0 0 .35rem;font-size:.78rem;letter-spacing:.08em;text-transform:uppercase;color:var(--amber-700)}
.hb-limits ul{margin:0;padding-left:1.1rem;font-size:.88rem;line-height:1.55}
/* Whose number the strip is showing. Two counts exist and they differ on purpose. */
.budget-whose{margin-left:.3rem;font-size:.62rem;letter-spacing:.04em;text-transform:uppercase;opacity:.65;font-weight:600}
/* per-figure info boxes on the paid-source card: the formula, not a restatement */
/* The panel is taken out of flow. `.comm-kv` is a grid whose first column is `max-content`,
   so an open <details> inside a <dt> sized that column to the width of the formula -- the
   card grew to 2427px and the page scrolled sideways. Absolute keeps the marker inline and
   lets the panel overhang. */
.fnote{display:inline-block;vertical-align:baseline;margin-left:.3rem;position:relative}
.fnote summary{cursor:pointer;list-style:none;display:inline-grid;place-items:center;width:1.05rem;height:1.05rem;border-radius:50%;border:1px solid var(--line-2);color:var(--muted);font-size:.68rem;font-weight:700;font-style:italic;font-family:var(--font);line-height:1}
.fnote summary::-webkit-details-marker{display:none}
.fnote summary:hover{border-color:var(--accent);color:var(--accent)}
.fnote[open] summary{background:var(--accent);color:var(--accent-fg);border-color:var(--accent)}
.fnote-body{position:absolute;left:0;top:1.5rem;z-index:20;width:max-content;max-width:min(52ch,78vw);padding:.6rem .75rem;background:var(--surface);border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:0 8px 8px 0;box-shadow:var(--shadow)}
.fnote-body code{display:block;font-family:var(--mono);font-size:.76rem;line-height:1.5;color:var(--fg);margin-bottom:.35rem;white-space:normal;overflow-wrap:anywhere}
.fnote-body p{margin:0 0 .3rem;font-size:.8rem;line-height:1.55;color:var(--fg-2)}
.fnote-src{font-size:.7rem;letter-spacing:.05em;text-transform:uppercase;color:var(--muted)}
/* per-endpoint traffic matrix under each source row */
.traffic-row td{padding:0 .6rem .5rem}
.traffic summary{cursor:pointer;font-size:.85rem;font-weight:600;padding:.3rem 0;list-style:none;color:var(--fg-2)}
.traffic summary::-webkit-details-marker{display:none}
.traffic summary::before{content:"+";display:inline-block;width:1.1rem;color:var(--accent);font-weight:700}
.traffic[open] summary::before{content:"–"}
.traffic table.matrix{width:100%;font-size:.82rem;border-collapse:collapse;margin:.35rem 0 .2rem}
.traffic table.matrix th,.traffic table.matrix td{padding:.32rem .5rem;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}
.traffic table.matrix th{font-weight:600;color:var(--muted);font-size:.76rem;letter-spacing:.03em;text-transform:uppercase}
.traffic table.matrix td.num,.traffic table.matrix th.num{text-align:right;font-variant-numeric:tabular-nums}
.traffic table.matrix tfoot td{border-bottom:0;border-top:2px solid var(--line-2);font-weight:600}
.traffic table.matrix code{font-family:var(--mono);font-size:.78rem}
.traffic .badge{font-size:.7rem;padding:.1rem .35rem}
.matrix-note{margin:.2rem 0 .3rem;max-width:min(80ch,100%);line-height:1.5}
/* incident playbook: numbered mistakes, the "better" line, the ordered first-hour list */
.pb-no{display:inline-block;min-width:2.2rem;color:var(--muted);font-family:var(--mono);font-size:.82rem;font-weight:600}
.pb-better{margin:.2rem 0 .9rem;padding:.5rem .85rem;border-left:3px solid var(--accent);background:var(--surface-2);border-radius:0 8px 8px 0;font-size:.9rem;line-height:1.55;max-width:70ch}
.pb-better b{color:var(--accent)}
.pb-steps{counter-reset:pb;list-style:none;margin:.5rem 0 1.1rem;padding:0;max-width:70ch}
.pb-steps li{counter-increment:pb;position:relative;padding:.1rem 0 .75rem 2.5rem;line-height:1.62}
.pb-steps li::before{content:counter(pb);position:absolute;left:0;top:.05rem;width:1.65rem;height:1.65rem;border-radius:50%;background:var(--accent);color:var(--accent-fg);display:grid;place-items:center;font-size:.8rem;font-weight:700}
.pb-list{margin:.4rem 0 1.1rem;padding-left:1.15rem;max-width:70ch}
.pb-list li{line-height:1.62;margin-bottom:.45rem}
.pb-dont{margin:.4rem 0 1.1rem;padding:.8rem 1rem .85rem;border-left:3px solid var(--red);background:var(--surface-2);border-radius:0 8px 8px 0}
.pb-dont ul{margin:0;padding-left:1.1rem;max-width:70ch}
.pb-dont li{line-height:1.6;margin-bottom:.45rem;font-size:.92rem}
.pb-dont li:last-child{margin-bottom:0}
.pb-close{font-weight:600}
.faq{display:flex;flex-direction:column;gap:.4rem}
.faq-item{border:1px solid var(--line);border-radius:8px;background:var(--surface)}
.faq-item summary{cursor:pointer;padding:.7rem .9rem;font-weight:600;font-size:.92rem;list-style:none}
.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary::before{content:"+";display:inline-block;width:1.1rem;color:var(--accent);font-weight:700}
.faq-item[open] summary::before{content:"–"}
.faq-item[open] summary{border-bottom:1px solid var(--line)}
.faq-item p{margin:0;padding:.7rem .9rem .8rem 2rem;font-size:.9rem;line-height:1.6;color:var(--fg-2)}

/* --- lookalike group in the ad-hoc search --------------------------------------------- */
/* One sweep finds dozens of typo domains. As one row each they push the leaks that need
   acting on off the first screen, so they fold into one row that opens. <details>, not a
   script: CSP forbids evaluated code, and the browser does this on its own. */
.ll-group summary{cursor:pointer;list-style:none;display:flex;align-items:center;gap:.4rem;flex-wrap:wrap}
.ll-group summary::-webkit-details-marker{display:none}
.ll-group summary::before{content:"▸";color:var(--accent);font-size:.8rem;flex:none}
.ll-group[open] summary::before{content:"▾"}
.ll-list{list-style:none;margin:.5rem 0 .2rem;padding:0 0 0 1rem;display:flex;flex-direction:column;gap:.3rem}
.ll-list li{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap;font-size:.82rem}
.ll-list code{font-size:.8rem;word-break:break-all}

/* --- demonstration mode: masks off ---------------------------------------------------- */
/* The switch lives in the sidebar and shows its own state; there is no banner over
   the page any more. It stays admin-only and dev-only -- see deps.unmasking. */
.demo-toggle{margin:.2rem 0 .4rem}
.demo-toggle button{width:100%;font-size:.76rem;padding:.25rem .5rem;
  border-color:rgba(255,255,255,.25)}
.demo-toggle button.on{background:var(--amber);color:#1c1b2e;border-color:var(--amber)}

/* --- one incident, one person, a card per application --------------------------------- */
.app-list{list-style:none;margin:0;padding:0}
.app-card{padding:.85rem 1.1rem;border-top:1px solid var(--line);border-left:3px solid transparent}
.app-card:first-child{border-top:0}
.app-card.current{background:var(--surface-2)}
.app-head{display:flex;align-items:baseline;justify-content:space-between;gap:.8rem;flex-wrap:wrap}
.app-head strong{font-size:.95rem;word-break:break-all}
.app-kv{display:grid;grid-template-columns:max-content 1fr;gap:.15rem .8rem;margin:.5rem 0 0}
.app-kv dt{font-size:.72rem;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);
  align-self:center}
.app-kv dd{margin:0;font-size:.86rem;display:flex;align-items:center;gap:.4rem;flex-wrap:wrap}
@media (max-width:640px){.app-kv{grid-template-columns:1fr;gap:.05rem}.app-kv dd{margin-bottom:.35rem}}
.eye{background:none;border:0;padding:.1rem .25rem;cursor:pointer;color:var(--muted);
  display:inline-flex;align-items:center;border-radius:5px}
.eye:hover{color:var(--fg);background:var(--surface-2)}
.secret-shown{font-size:.86rem;background:var(--red-100);color:var(--red-700);
  padding:.1rem .4rem;border-radius:5px;word-break:break-all;user-select:all}

/* --- alerts: two views, grouped rows that open -------------------------------------- */
/* The rule for these two tables: one tag per cell, words where a word does the job, colour
   only where it carries meaning -- whose account, how bad. Everything else is type on a
   quiet surface, so the page reads like a ledger and not like a badge wall. The list is the
   one page that is a table first, so it takes the width it can get. */
:root{--tag-emp:#3b2380;--tag-emp-bg:#f1eefa;--tag-emp-line:#d9d1ef;
  --tag-cli:#0f6b45;--tag-cli-bg:#e7f6ee;--tag-cli-line:#c7e8d6;
  --tag-fg:#4f4e66;--tag-line:#d9dce6;--crit-tint:4%}
[data-theme="console"]{--tag-emp:#b9aef2;--tag-emp-bg:rgba(185,174,242,.09);--tag-emp-line:rgba(185,174,242,.32);
  --tag-cli:#86d3ad;--tag-cli-bg:rgba(134,211,173,.09);--tag-cli-line:rgba(134,211,173,.32);
  --tag-fg:#9fb0bd;--tag-line:#2b3846;--crit-tint:7%}
main.wide{max-width:none;padding-left:1.8rem;padding-right:1.8rem}
.mode-tabs{display:inline-flex;border:1px solid var(--line-2);border-radius:7px;overflow:hidden;background:var(--surface)}
.mode-tabs a{display:inline-flex;align-items:center;gap:.4rem;padding:.35rem .85rem;font-weight:500;font-size:.82rem;
  color:var(--fg-2);border-right:1px solid var(--line-2)}
.mode-tabs a:last-child{border-right:0}
.mode-tabs a:hover{text-decoration:none;background:var(--surface-2)}
.mode-tabs a.on{background:var(--accent);color:var(--accent-fg);font-weight:600}
.mode-tabs .pill{padding:0 .4rem;border-radius:999px;font-size:.68rem;font-weight:600;background:var(--red);color:#fff;line-height:1.35}
.mode-tabs a.on .pill{background:rgba(255,255,255,.22)}
.mode-hint{margin:-.6rem 0 1rem;font-size:.82rem}
.mode-hint .danger{margin-left:.4rem}

/* the two tables share one quiet typography: light header, tabular dates, no header fill */
table.alerts,table.events{font-size:.86rem;table-layout:auto}
table.alerts th,table.events th{font-size:.62rem;letter-spacing:.06em;font-weight:600;color:var(--muted);
  background:transparent;padding:.45rem .6rem;border-bottom:1px solid var(--line-2);white-space:nowrap}
table.alerts td,table.events td{padding:.34rem .6rem;vertical-align:middle;line-height:1.35}
table.alerts td.app,table.events td.app{min-width:12rem;max-width:26rem;overflow-wrap:anywhere}
table.alerts td.app strong{font-weight:600}
table.alerts td.app a,table.events td.app a{color:var(--fg)}
table.alerts td.app a:hover,table.events td.app a:hover{color:var(--link)}
table.alerts td.affected{overflow-wrap:anywhere;min-width:12rem;max-width:22rem}
table.alerts td.when,table.events td.ev-when{white-space:nowrap;font-variant-numeric:tabular-nums}
table.alerts th.x,table.alerts td.x{width:2rem;padding-right:0;padding-left:.6rem}
th.col-scope,td.col-scope{white-space:nowrap;width:1%}
td.col-scope .tag{margin:.1rem 0}
td.types{white-space:normal}
/* Critical rows: a thin bar and the faintest tint. The word in the severity column carries
   the rest; a red band across the row is what made the old table shout. */
table.alerts tr.crit td,table.events tr.crit td{background:color-mix(in srgb,var(--red) var(--crit-tint),transparent)}
table.alerts tr.crit td:first-child,table.events tr.crit td:first-child{box-shadow:inset 2px 0 0 var(--red)}
table.alerts tbody tr:hover td,table.events tbody tr:hover td{background:var(--surface-2)}
table.alerts tbody tr.crit:hover td,table.events tbody tr.crit:hover td{background:color-mix(in srgb,var(--red) calc(var(--crit-tint) + 3%),transparent)}

/* tags: a word in a thin frame, sentence case, medium weight -- never uppercase, never bold */
.tag{display:inline-flex;align-items:center;gap:.32rem;padding:.04rem .42rem;border-radius:4px;font-size:.7rem;
  font-weight:500;letter-spacing:0;line-height:1.5;white-space:nowrap;color:var(--tag-fg);
  border:1px solid var(--tag-line);background:transparent;margin-right:.3rem}
.tag:last-child{margin-right:0}
.tag.scope-employee{color:var(--tag-emp);background:var(--tag-emp-bg);border-color:var(--tag-emp-line)}
.tag.scope-client{color:var(--tag-cli);background:var(--tag-cli-bg);border-color:var(--tag-cli-line)}
.tag.warn{color:var(--amber-700);border-color:color-mix(in srgb,var(--amber-700) 40%,transparent)}
.tag.rt::before{content:"";width:6px;height:6px;border-radius:50%;background:var(--line-2);flex:none}
.tag.rt-stealer::before{background:var(--red)}
.tag.rt-combolist::before{background:var(--amber)}
.tag.rt-database::before{background:var(--fg-2)}
.tag.rt-paste::before{background:var(--cyan-600)}

/* severity as a marked word, not a filled chip; only critical keeps a filled dot */
table.alerts .sev,table.events .sev{display:inline-flex;align-items:center;gap:.4rem;padding:0;border:0;
  background:transparent;box-shadow:none;font-size:.78rem;font-weight:600;letter-spacing:.02em;text-transform:none}
table.alerts .sev::before,table.events .sev::before{content:"";width:8px;height:8px;border-radius:50%;flex:none}
table.alerts .sev-low,table.events .sev-low{color:var(--muted)}
table.alerts .sev-low::before,table.events .sev-low::before{background:var(--line-2)}
table.alerts .sev-medium,table.events .sev-medium{color:var(--amber-700)}
table.alerts .sev-medium::before,table.events .sev-medium::before{background:var(--amber)}
table.alerts .sev-high,table.events .sev-high{color:var(--red-700)}
table.alerts .sev-high::before,table.events .sev-high::before{background:var(--red)}
table.alerts .sev-critical,table.events .sev-critical{color:var(--red-700)}
table.alerts .sev-critical::before,table.events .sev-critical::before{background:var(--red);box-shadow:0 0 0 3px color-mix(in srgb,var(--red) 22%,transparent)}
table.alerts .st,table.events .st{font-weight:500;font-size:.8rem}

/* password: one word, coloured only when it matters */
.pw{font-size:.78rem;font-weight:500}
.pw-yes{color:var(--red-700);font-weight:600}
.pw-no,.pw-unknown{color:var(--muted)}
code.pw-mask{font-size:.74rem;background:transparent;color:var(--fg-2);padding:0 .1rem}

/* the fold-out */
.expand{width:1.45rem;height:1.45rem;padding:0;border-radius:4px;border:1px solid transparent;background:transparent;
  color:var(--muted);font-weight:500;line-height:1;cursor:pointer;font-size:1rem;display:inline-grid;place-items:center}
.expand:hover{color:var(--fg);border-color:var(--line-2);background:var(--surface);filter:none}
.expand.all{font-size:.85rem}
tr[data-grp].open td{background:var(--surface-2)}
tr[data-grp].open .expand{color:var(--fg)}
tr.grp-detail td{padding:.35rem .75rem .9rem 2.6rem;background:var(--surface-2)}
.foldout{width:0;min-width:100%;overflow-x:auto}
.foldout>table{min-width:100%;width:max-content;max-width:none}
tbody tr.grp-detail:hover td{background:var(--surface-2)}
table.events.nested,table.alerts.nested{font-size:.83rem;background:var(--surface);border:1px solid var(--line);border-radius:6px;overflow:hidden;width:100%}
table.events.nested th,table.alerts.nested th{font-size:.6rem;border-bottom-color:var(--line)}
table.events.nested td,table.alerts.nested td{padding:.3rem .6rem}
table.alerts.nested tr.grp-detail td{padding-left:1.6rem}
tr.grp-detail p.more{margin:.5rem 0 0;font-size:.8rem}
/* An address breaks after the @ if it must, a domain at its hyphen -- never mid-word. */
table.events td.who{font-family:var(--mono);font-size:.8rem;white-space:nowrap}
table.events td.device code{font-size:.76rem;background:transparent;color:var(--fg-2);padding:0}
td .url{display:block;font-size:.72rem;color:var(--muted);word-break:break-all;font-family:var(--mono)}
td .sub{display:block;font-size:.72rem;color:var(--muted)}
td .note{font-size:.72rem;color:var(--muted);white-space:nowrap;margin-left:.35rem}
td .note.url{font-family:var(--mono)}
td .note.pw-note{color:var(--red-700)}
.st-cell{display:inline-flex;align-items:center;gap:.35rem}
td.stc{white-space:nowrap}
button.st{background:transparent;border:0;padding:0 .1rem;cursor:pointer;font:inherit;font-weight:500;font-size:.8rem;color:var(--fg);border-radius:4px}
button.st:hover{background:var(--surface-2);filter:none}
button.st.busy{opacity:.5}
.foldout-bar{display:flex;align-items:center;gap:.4rem;margin:.1rem 0 .45rem;font-size:.76rem;color:var(--muted)}
.foldout-bar span{margin-right:.4rem}
button.bulk{padding:0 .4rem;font-size:.68rem;font-weight:500;color:var(--muted);background:var(--surface);border:1px solid var(--line);border-radius:4px;line-height:1.5}
button.bulk:hover{color:var(--fg);border-color:var(--line-2);filter:none}
.st-cell form.inline button.sm{padding:.05rem .4rem;font-size:.68rem;font-weight:500;color:var(--muted);border-color:var(--line)}
.st-cell form.inline button.sm:hover{color:var(--fg);border-color:var(--line-2)}
.st-cell .danger{display:block;font-size:.72rem}
.pager{display:flex;gap:.7rem;align-items:center;justify-content:flex-end;margin-top:.8rem}
/* Narrower than the columns need: the capture date goes first, then the fold-out keeps its
   own scroll. The card scrolls sideways only as the last resort. */
table.events.nested th.col-captured,table.events.nested td.col-captured{display:none}
@media (max-width:1500px){th.col-captured,td.col-captured{display:none}}
@media (max-width:900px){table.alerts td.app,table.alerts td.affected,table.events td.app{min-width:0;max-width:none}}

/* --- the short tour ------------------------------------------------------------------ */
h1 .tour-link{display:inline-block;margin-left:.7rem;font-size:.78rem;font-weight:500;letter-spacing:0;vertical-align:middle}
.tour-link{font-size:.8rem}
.tour-pop{position:absolute;z-index:60;width:min(340px,calc(100vw - 2rem));background:var(--surface);color:var(--fg);
  border:1px solid var(--line-2);border-radius:10px;box-shadow:0 18px 50px rgba(0,0,0,.28);padding:.9rem 1rem;font-size:.86rem;line-height:1.5}
.tour-pop h4{margin:0 0 .25rem;font-size:.95rem;color:var(--brand)}
.tour-pop p{margin:0}
.tour-pop .actions{margin-top:.7rem;justify-content:flex-end}
.tour-pop .tour-count{margin-right:auto;font-size:.72rem;color:var(--muted)}
.tour-focus{outline:2px solid var(--accent);outline-offset:3px;border-radius:6px}


/* --- sales monitor ------------------------------------------------------------------ */
/* Pipeline stages. Muted for the states nothing happens in, colour for the ones that do. */
.stage{display:inline-block;padding:.12rem .55rem;border-radius:999px;font-size:.68rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;white-space:nowrap;background:var(--surface-2);color:var(--fg-2);border:1px solid var(--line)}
.stage-contacted{background:var(--violet-100);color:var(--violet);border-color:transparent}
.stage-meeting,.stage-proposal{background:var(--amber-100);color:var(--amber-700);border-color:transparent}
.stage-won{background:var(--green-100);color:var(--green-700);border-color:transparent}
.stage-lost,.stage-not_interested{opacity:.6}
tr.closed td{opacity:.55}
/* Lead score as a small meter next to the number, so a column of numbers reads as a shape. */
.lead{display:inline-flex;align-items:center;gap:.5rem;font-variant-numeric:tabular-nums}
.lead .meter{width:54px;height:6px;border-radius:3px;background:var(--line);overflow:hidden;flex:none}
.lead .meter i{display:block;height:100%;background:var(--muted);border-radius:3px}
.lead-hot .meter i{background:var(--red)}.lead-warm .meter i{background:var(--amber)}.lead-cool .meter i{background:var(--cyan-600)}
.lead strong{min-width:2ch;text-align:right}
/* Segment overview: one row per segment, the bar is the checked share. */
.seg-table td .meter{display:inline-block;width:90px;height:6px;border-radius:3px;background:var(--line);vertical-align:middle;overflow:hidden;margin-right:.5rem}
.seg-table td .meter i{display:block;height:100%;background:linear-gradient(90deg,var(--cyan),var(--green))}
/* Talking points: the sentences said on the phone. Tone on the left edge, nothing else. */
.talk{list-style:none;margin:0;padding:0;display:grid;gap:.5rem}
.talk li{padding:.65rem .9rem .65rem 1.1rem;border-radius:var(--r);background:var(--surface-2);border:1px solid var(--line);position:relative;line-height:1.5}
.talk li::before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px;border-radius:var(--r) 0 0 var(--r);background:var(--line-2)}
.talk li.tone-critical::before{background:var(--red)}.talk li.tone-high::before{background:var(--amber)}.talk li.tone-medium::before{background:var(--cyan-600)}
/* Monthly timeline as bars. Heights go through data-height in app.js; the CSP forbids style attributes. */
.tl-chart{display:flex;align-items:flex-end;gap:.35rem;height:120px;padding:.4rem 0 0;border-bottom:1px solid var(--line)}
.tl-chart .col{flex:1;display:flex;flex-direction:column;justify-content:flex-end;align-items:stretch;height:100%;min-width:0}
.tl-chart .col i{display:block;background:linear-gradient(180deg,var(--cyan),var(--violet-500));border-radius:3px 3px 0 0;min-height:2px}
.tl-chart .col i.stealer{background:var(--red)}
.tl-labels{display:flex;gap:.35rem;margin-top:.3rem}.tl-labels span{flex:1;font-size:.62rem;color:var(--muted);text-align:center;letter-spacing:.02em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mail-list{list-style:none;margin:0;padding:0}.mail-list li{display:grid;grid-template-columns:auto 1fr;gap:.6rem 1rem;padding:.45rem 0;border-bottom:1px solid var(--line);align-items:baseline}
.mail-list li:last-child{border-bottom:0}.mail-list .why{color:var(--fg-2);font-size:.88rem}
.detail-head{display:flex;align-items:flex-start;justify-content:space-between;gap:1rem;flex-wrap:wrap}
.detail-head .who h1{margin:0 0 .2rem}.detail-head .who .sub{color:var(--muted);display:flex;gap:.6rem;align-items:center;flex-wrap:wrap}
.pager{display:flex;gap:.4rem;align-items:center}.pager a{font-size:.85rem}
th a{color:inherit}th a.on{color:var(--brand);text-decoration:underline}


/* ============================================================================
   Showroom: the full-screen animated deck shown to a prospect. Its own visual
   world -- dark, cinematic, big type. No source names, nothing masked. Driven by
   app.js `showroom`; every animation is a class or keyframe (CSP: no inline style,
   no eval). Honours prefers-reduced-motion by showing final states instantly.
   ============================================================================ */
body.showroom{margin:0;min-height:100vh;background:radial-gradient(1200px 800px at 70% -10%,#3b2380 0%,#1d0e42 45%,#0c0722 100%);color:#fff;font-family:var(--font);overflow:hidden}
[data-theme="console"] body.showroom{background:radial-gradient(1200px 800px at 70% -10%,#0f2a1d 0%,#08131b 45%,#050709 100%)}
.sr-deck{position:fixed;inset:0}
.slide{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;gap:1.2rem;padding:6vh 8vw;opacity:0;visibility:hidden;transform:translateY(24px) scale(.99);transition:opacity .5s ease,transform .6s cubic-bezier(.16,.84,.44,1),visibility .5s;pointer-events:none}
.slide.active{opacity:1;visibility:visible;transform:none;pointer-events:auto}
.slide.leaving{opacity:0;transform:translateY(-24px) scale(.99)}
/* slide moods */
.sr-tone-bad{background:radial-gradient(900px 600px at 80% 0%,rgba(214,51,90,.28),transparent 60%)}
.sr-tone-warn{background:radial-gradient(900px 600px at 80% 0%,rgba(242,177,52,.22),transparent 60%)}
.sr-tone-ok{background:radial-gradient(900px 600px at 80% 0%,rgba(63,224,143,.18),transparent 60%)}

.sr-eyebrow{font-size:clamp(.72rem,1vw,.9rem);letter-spacing:.22em;text-transform:uppercase;color:rgba(255,255,255,.55);font-weight:700}
.slide h2{font-size:clamp(1.9rem,4vw,3.4rem);margin:0;letter-spacing:-.02em;line-height:1.05;font-weight:800}
.slide h3{font-size:clamp(.9rem,1.3vw,1.1rem);letter-spacing:.04em;color:rgba(255,255,255,.7);margin:0 0 .9rem;text-transform:uppercase}
.sr-lede{font-size:clamp(1rem,1.7vw,1.5rem);color:rgba(255,255,255,.8);max-width:60ch;line-height:1.45;margin:0}

/* cover */
.sr-cover{gap:.6rem}
.sr-hero{font-size:clamp(2.6rem,8vw,6.5rem);margin:.2rem 0;font-weight:850;letter-spacing:-.04em;line-height:.98;background:linear-gradient(120deg,#fff 30%,#8fe3ff 70%,#3fe08f);-webkit-background-clip:text;background-clip:text;color:transparent}
.sr-cover-score{display:flex;align-items:baseline;gap:.5rem;margin-top:1.4rem}
.sr-score-num{font-size:clamp(3rem,7vw,6rem);font-weight:850;font-variant-numeric:tabular-nums;letter-spacing:-.03em}
.sr-score-max{font-size:1.4rem;color:rgba(255,255,255,.55)}
.sr-band{margin-left:1rem;align-self:center;padding:.3rem .9rem;border-radius:999px;font-size:.8rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase}
.sr-band-low{background:rgba(63,224,143,.2);color:#8affc4}.sr-band-medium{background:rgba(242,177,52,.22);color:#ffd483}
.sr-band-high{background:rgba(255,93,125,.22);color:#ff9db1}.sr-band-critical{background:var(--red);color:#fff;box-shadow:0 0 32px rgba(214,51,90,.6)}
.sr-cover-hint{margin-top:2.4rem;color:rgba(255,255,255,.5);font-size:.9rem}
.sr-cover-hint kbd,.sr-controls kbd{display:inline-block;padding:.1rem .5rem;border:1px solid rgba(255,255,255,.35);border-radius:6px;font-family:var(--mono);font-size:.8rem}

/* verdict + gauge */
.sr-two{display:grid;grid-template-columns:minmax(240px,1fr) 1.4fr;gap:clamp(1.5rem,4vw,4rem);align-items:center}
.sr-gauge-wrap{position:relative;width:min(38vh,340px);aspect-ratio:1;justify-self:center}
.sr-gauge{width:100%;height:100%;transform:rotate(-90deg)}
.sr-gauge-track{fill:none;stroke:rgba(255,255,255,.12);stroke-width:14}
.sr-gauge-fill{fill:none;stroke:#3fe08f;stroke-width:14;stroke-linecap:round;stroke-dasharray:540;stroke-dashoffset:540;transition:stroke-dashoffset 1.3s cubic-bezier(.16,.84,.44,1)}
.sr-tone-bad .sr-gauge-fill{stroke:#ff5d7d}.sr-tone-warn .sr-gauge-fill{stroke:#f2b134}.sr-tone-ok .sr-gauge-fill{stroke:#3fe08f}
.sr-gauge-center{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
.sr-gauge-num{font-size:clamp(2.4rem,6vw,4.4rem);font-weight:850;font-variant-numeric:tabular-nums;line-height:1}
.sr-gauge-center small{color:rgba(255,255,255,.5);font-size:1rem}
.sr-verdict-copy h2{margin:.3rem 0 .6rem}
.sr-point-lead{margin-top:1.2rem;font-size:clamp(1.05rem,1.6vw,1.4rem);font-weight:600;padding-left:1rem;border-left:4px solid rgba(255,255,255,.3);line-height:1.4}
.sr-point-lead.sr-tone-critical{border-left-color:#ff5d7d}.sr-point-lead.sr-tone-high{border-left-color:#f2b134}

/* number stats with count-up */
.sr-stat-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:clamp(1rem,2vw,1.6rem);margin-top:1rem}
.sr-stat{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);border-radius:18px;padding:clamp(1.2rem,2.4vw,2rem);display:flex;flex-direction:column;gap:.3rem;backdrop-filter:blur(6px)}
.sr-stat-num{font-size:clamp(2.6rem,6vw,4.6rem);font-weight:850;font-variant-numeric:tabular-nums;line-height:1;letter-spacing:-.03em}
.sr-stat.tone-bad .sr-stat-num{color:#ff7a95}.sr-stat.tone-warn .sr-stat-num{color:#ffd062}.sr-stat.tone-ok .sr-stat-num{color:#7dffb6}
.sr-stat-label{font-weight:700;font-size:1.02rem}.sr-stat-hint{color:rgba(255,255,255,.55);font-size:.86rem}
.sr-foot-note{margin-top:1.4rem;color:rgba(255,255,255,.65)}

/* timeline */
.sr-chart{display:flex;align-items:flex-end;justify-content:center;gap:min(1.2vw,14px);height:34vh;margin-top:1rem}
.sr-col{flex:1 1 0;max-width:84px;display:flex;flex-direction:column;justify-content:flex-end;min-width:0;height:100%}
.sr-bar{display:block;width:100%;height:0;border-radius:5px 5px 0 0;background:linear-gradient(180deg,#36d4ff,#3b2380);transition:height .9s cubic-bezier(.16,.84,.44,1)}
.sr-bar-stealer{background:linear-gradient(180deg,#ff5d7d,#a11d3d);border-radius:5px 5px 0 0}
.sr-chart-labels{display:flex;justify-content:center;gap:min(1.2vw,14px);margin-top:.4rem}.sr-chart-labels span{flex:1 1 0;max-width:84px;text-align:center;font-size:.7rem;color:rgba(255,255,255,.5)}
.sr-chart-labels b{color:rgba(255,255,255,.8);font-weight:700}
.sr-legend{margin-top:1.2rem;color:rgba(255,255,255,.65);font-size:.9rem;display:flex;align-items:center;gap:.5rem}
.sr-key{display:inline-block;width:14px;height:14px;border-radius:4px;margin:0 .2rem 0 1rem;vertical-align:middle}
.sr-key-total{background:#36d4ff;margin-left:0}.sr-key-stealer{background:#ff5d7d}

/* ranked bars (entry points, malware, services) */
.sr-two-cols{display:grid;grid-template-columns:1fr 1fr;gap:clamp(1.5rem,4vw,4rem);margin-top:1rem}
.sr-rank{display:grid;grid-template-columns:1fr 2fr auto;align-items:center;gap:.8rem;margin:.55rem 0;font-size:clamp(.85rem,1.1vw,1rem)}
.sr-rank-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:rgba(255,255,255,.85)}
.sr-rank-bar{background:rgba(255,255,255,.1);border-radius:6px;height:12px;overflow:hidden}
.sr-rank-bar i{display:block;height:100%;width:0;border-radius:6px;background:linear-gradient(90deg,#36d4ff,#3fe08f);transition:width 1s cubic-bezier(.16,.84,.44,1)}
.sr-rank-bar i.warn{background:linear-gradient(90deg,#f2b134,#ff5d7d)}
.sr-rank-val{font-variant-numeric:tabular-nums;font-weight:700;color:rgba(255,255,255,.7);min-width:3ch;text-align:right}

/* email spoofing */
.sr-spoof-verdict{font-size:clamp(1.15rem,2vw,1.7rem);font-weight:600;max-width:56ch;line-height:1.4;margin:.4rem 0 1rem}
.sr-mail-demo{background:#fff;color:#1c1b2e;border-radius:14px;overflow:hidden;max-width:640px;box-shadow:0 30px 80px rgba(0,0,0,.45)}
.sr-mail-from{display:flex;align-items:center;gap:.8rem;padding:.9rem 1.1rem;border-bottom:1px solid #eee}
.sr-mail-avatar{width:38px;height:38px;border-radius:50%;background:var(--violet-100);color:var(--violet);display:grid;place-items:center;flex:none;font-size:1.1rem}
.sr-mail-from strong{display:block;font-size:.95rem}.sr-mail-from small{color:#7d7c93}
.sr-mail-badge{margin-left:auto;background:var(--red-100);color:var(--red-700);font-size:.68rem;font-weight:700;padding:.2rem .5rem;border-radius:6px;text-align:center;line-height:1.3}
.sr-mail-body{padding:1.1rem;color:#3a3950;font-size:1rem;line-height:1.5}
.sr-chips{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:1.2rem}
.sr-chip{background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.18);border-radius:999px;padding:.25rem .75rem;font-size:.82rem;font-weight:600}

/* the chain: what one credential leads to. Numbered, escalating, connected by a rail so it
   reads as one sequence rather than five bullet points. */
.sr-chain h2{margin-bottom:.2rem}
.sr-chain-framing{font-size:clamp(.95rem,1.35vw,1.2rem);color:rgba(255,255,255,.72);max-width:78ch;margin:.2rem 0 .8rem;line-height:1.45}
.sr-chain-steps{list-style:none;margin:0;padding:0;display:grid;gap:.5rem;position:relative}
.sr-chain-steps li{display:flex;align-items:flex-start;gap:.9rem;padding:.55rem .9rem;border-radius:12px;background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);position:relative}
.sr-chain-num{flex:none;width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-weight:800;font-size:.9rem;background:rgba(255,255,255,.12);color:#fff;font-variant-numeric:tabular-nums}
.sr-chain-steps li.tone-high .sr-chain-num{background:rgba(242,177,52,.3);color:#ffd483}
.sr-chain-steps li.tone-critical .sr-chain-num{background:var(--red);color:#fff;box-shadow:0 0 22px rgba(214,51,90,.55)}
.sr-chain-body{display:flex;flex-direction:column;gap:.1rem;min-width:0}
.sr-chain-body strong{font-size:clamp(.95rem,1.25vw,1.1rem)}
.sr-chain-body span{color:rgba(255,255,255,.75);font-size:clamp(.85rem,1.15vw,1.02rem);line-height:1.4}
.sr-chain-steps li.tone-critical{border-color:rgba(255,93,125,.4);background:rgba(255,93,125,.09)}
/* the rail linking the steps into one sequence */
.sr-chain-steps li::after{content:"";position:absolute;left:calc(.9rem + 15px);top:100%;height:.5rem;width:2px;background:rgba(255,255,255,.18)}
.sr-chain-steps li:last-child::after{display:none}
.sr-chain-closing{margin-top:1rem;font-size:clamp(1rem,1.5vw,1.3rem);font-weight:700;color:#ff9db1;max-width:80ch;line-height:1.4}

/* solution */
.sr-solve-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:clamp(1rem,2vw,1.6rem);margin-top:1rem}
.sr-solve-card{background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.12);border-radius:18px;padding:1.6rem;display:flex;flex-direction:column;gap:.5rem}
.sr-solve-icon{font-size:2rem}.sr-solve-card strong{font-size:1.15rem}.sr-solve-card span{color:rgba(255,255,255,.7);line-height:1.45}
.sr-cta{margin-top:2rem;font-size:clamp(1.2rem,2.2vw,1.8rem);font-weight:700;background:linear-gradient(120deg,#8fe3ff,#3fe08f);-webkit-background-clip:text;background-clip:text;color:transparent}

/* entry animations: children rise in when their slide becomes active */
.slide.active .sr-anim{animation:srRise .6s cubic-bezier(.16,.84,.44,1) both}
.sr-stat,.sr-solve-card,.sr-rank,.sr-chip,.sr-chain-steps li{opacity:0}
.slide.active .sr-stat,.slide.active .sr-solve-card,.slide.active .sr-rank,.slide.active .sr-chip,.slide.active .sr-chain-steps li{animation:srRise .55s cubic-bezier(.16,.84,.44,1) both}
.slide.active .sr-chain-steps li:nth-child(2){animation-delay:.12s}
.slide.active .sr-chain-steps li:nth-child(3){animation-delay:.24s}
.slide.active .sr-chain-steps li:nth-child(4){animation-delay:.36s}
.slide.active .sr-chain-steps li:nth-child(5){animation-delay:.48s}
.slide.active .sr-stat:nth-child(2),.slide.active .sr-solve-card:nth-child(2){animation-delay:.08s}
.slide.active .sr-stat:nth-child(3),.slide.active .sr-solve-card:nth-child(3){animation-delay:.16s}
.slide.active .sr-stat:nth-child(4){animation-delay:.24s}
@keyframes srRise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}

/* presenter chrome */
.sr-chrome{position:fixed;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:space-between;padding:1rem 1.4rem;gap:1rem;z-index:5;transition:opacity .4s}
body.showroom.is-fullscreen .sr-chrome{opacity:0}body.showroom.is-fullscreen:hover .sr-chrome{opacity:1}
.sr-dots{display:flex;gap:.5rem}
.sr-dot{width:9px;height:9px;border-radius:50%;background:rgba(255,255,255,.28);border:0;padding:0;cursor:pointer;transition:background .3s,transform .3s}
.sr-dot.on{background:#3fe08f;transform:scale(1.3)}
.sr-controls{display:flex;align-items:center;gap:.4rem}
.sr-counter{color:rgba(255,255,255,.6);font-variant-numeric:tabular-nums;font-size:.85rem;min-width:2.5ch;text-align:center}
.sr-btn{display:inline-grid;place-items:center;min-width:36px;height:36px;padding:0 .5rem;border:1px solid rgba(255,255,255,.25);background:rgba(255,255,255,.04);color:rgba(255,255,255,.8);border-radius:9px;font-size:1rem;cursor:pointer;text-decoration:none;transition:color .15s,border-color .15s,background .15s}
.sr-btn:hover{color:#fff;border-color:#fff;background:rgba(255,255,255,.1);text-decoration:none}
.sr-exit:hover{border-color:#ff5d7d;color:#ff5d7d}

@media (max-width:720px){.sr-two,.sr-two-cols{grid-template-columns:1fr}.sr-gauge-wrap{width:min(40vw,220px)}}
@media (prefers-reduced-motion:reduce){
  .slide{transition:opacity .01s}
  .sr-bar,.sr-rank-bar i,.sr-gauge-fill{transition:none}
  .slide.active .sr-stat,.slide.active .sr-solve-card,.slide.active .sr-rank,.slide.active .sr-chip,.slide.active .sr-chain-steps li{animation:none;opacity:1}
}
@media print{body.showroom{background:#fff;color:#111}.slide{position:static;opacity:1;visibility:visible;transform:none;page-break-after:always;min-height:90vh}.sr-chrome{display:none}}
