/* SENTINEL — feeds, map, tools, overlays
   Part of a split stylesheet. Load order is load-bearing:
   tokens.css -> layout.css -> components.css
   Concatenating them in that order reproduces the v10.14 single-file CSS
   byte for byte. Do not reorder the <link> tags. */

/* ══ KEV rows ══ */
  .row.kev { grid-template-columns:124px 1fr auto; cursor:pointer; }
  .row.kev:hover { border-left-color:var(--cyan); }
  .cve { font-weight:700; color:var(--cyan); font-size:12.5px; white-space:nowrap; }
  .kv-t { min-width:0; }
  .kv-t .vp { font-weight:500; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .kv-t .nm { color:var(--ink-dim); font-size:11.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .sev-crit{border-left-color:var(--sev-crit)!important;} .sev-high{border-left-color:var(--sev-high)!important;}
  .sev-med{border-left-color:var(--sev-med)!important;} .sev-low{border-left-color:var(--sev-low)!important;}

  /* ══ Wire (news) ══ */
  .wire .scroller { position:relative; padding-left:24px; }
  .wire .scroller::before { content:""; position:absolute; left:7px; top:6px; bottom:6px; width:2px;
    background:linear-gradient(var(--cyan), transparent 92%); opacity:0.4; }
  .wire-item { position:relative; padding:14px 14px 16px 18px; border-bottom:1px solid var(--line-soft);
    animation:slideIn 0.45s var(--ease) both; }
  .wire-item:last-child{border-bottom:none;}
  .wire-item::before { content:""; position:absolute; left:-22px; top:20px; width:9px; height:9px;
    border-radius:50%; background:var(--bg); border:2px solid var(--src,var(--cyan));
    box-shadow:0 0 10px -1px var(--src,var(--cyan)); transition:transform 0.25s var(--ease); }
  .wire-item:hover::before { transform:scale(1.35); }
  .wire-top { display:flex; align-items:center; gap:9px; margin-bottom:6px; flex-wrap:wrap; }
  .src-badge { font-size:9.5px; letter-spacing:0.08em; text-transform:uppercase; color:var(--src,var(--cyan));
    border:1px solid var(--src,var(--cyan)); padding:2px 7px; border-radius:3px; opacity:0.9; }
  .wire-item h4 { font-family:var(--disp); font-weight:600; font-size:14.5px; line-height:1.35; margin:0 0 4px; }
  .wire-item a.headline { color:var(--ink); text-decoration:none; background-image:linear-gradient(var(--cyan),var(--cyan));
    background-size:0% 1px; background-repeat:no-repeat; background-position:0 100%;
    transition:background-size 0.3s var(--ease), color 0.3s var(--ease); padding-bottom:1px; }
  .wire-item a.headline:hover { color:#fff; background-size:100% 1px; }
  .wire-item p { margin:0; color:var(--ink-dim); font-size:11.5px; line-height:1.55; }

  /* ══ Map ══ */
  .mapcard { position:relative; }
  .map-inner { position:relative; background:var(--screen); box-shadow:inset 0 0 30px -8px #000; }
  /* scope vignette — frames the display well; pointer-events off so markers stay clickable */
  .map-inner::after { content:""; position:absolute; inset:0; pointer-events:none; z-index:1;
    background:radial-gradient(130% 95% at 50% 42%, transparent 58%, rgba(0,0,0,0.34) 100%); }
  .map-stat { z-index:2; }
  .worldmap { display:block; width:100%; height:auto; }
  /* v10.6: land lifted from #16202e — at 1.3:1 against the well it was barely
     readable, which made the night dimming invisible. Marker contrast verified
     against the new fill (all severity colors ≥ 3.5:1). */
  .worldmap .land { fill:#1b2735; stroke:#2e405a; stroke-width:0.6; }
  /* graticule — real 30° lat/lon grid, drawn beneath everything. Gives the
     ocean structure; equator and prime meridian a shade stronger. */
  .worldmap .grat { fill:none; stroke:#182333; stroke-width:0.7; }
  .worldmap .grat-major { fill:none; stroke:#1e2c40; stroke-width:0.9; }
  .c2-pt { cursor:pointer; transition:r 0.2s var(--ease); }
  .c2-ring { fill:none; stroke-width:1.2; opacity:0; transform-origin:center; }
  .c2-ring.pulse { animation:ringPulse 2.6s var(--ease) infinite; }
  @keyframes ringPulse {
    0%   { r:3; opacity:0.75; }
    100% { r:16; opacity:0; }
  }
  .map-stat { position:absolute; top:11px; left:14px; font-size:10.5px; letter-spacing:0.08em;
    color:var(--ink-dim); text-transform:uppercase; }
  .map-stat b { color:var(--sev-crit); font-weight:700; }
  .map-tip { position:absolute; pointer-events:none; z-index:2; background:#0b1119; border:1px solid var(--line);
    border-radius:5px; padding:8px 10px; font-size:10.5px; color:var(--ink); opacity:0;
    transition:opacity 0.15s; z-index:5; white-space:nowrap; box-shadow:0 6px 20px -6px rgba(0,0,0,0.8); }
  .map-tip .mip { color:var(--cyan); font-weight:700; }
  .map-tip .fam { color:var(--ink-dim); }
  .map-legend { display:flex; flex-wrap:wrap; gap:8px; padding:11px 14px; border-top:1px solid var(--line-soft); }
  .fam-chip { display:inline-flex; align-items:center; gap:6px; font-size:10.5px; color:var(--ink-dim);
    border:1px solid var(--line); border-radius:20px; padding:3px 10px; cursor:pointer;
    transition:all 0.2s var(--ease); background:none; font-family:var(--mono); }
  .fam-chip:hover { color:var(--ink); border-color:var(--ink-faint); }
  .fam-chip.off { opacity:0.35; }
  .fam-chip i { width:8px; height:8px; border-radius:50%; background:currentColor; box-shadow:0 0 6px -1px currentColor; }
  .fam-chip .c { color:var(--ink-faint); font-size:9.5px; }

  /* leaderboard */
  .lb-row { display:grid; grid-template-columns:1fr auto; gap:10px; align-items:center;
    padding:9px 14px; border-bottom:1px solid var(--line-soft); font-size:12px; }
  .lb-row:last-child{border-bottom:none;}
  .lb-name { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .lb-bar { height:3px; background:var(--line); border-radius:2px; overflow:hidden; margin-top:5px; }
  .lb-bar span { display:block; height:100%; background:var(--cyan); border-radius:2px;
    transition:width 0.7s var(--ease); }
  .lb-n { font-weight:700; color:var(--ink); font-size:12px; }

  /* ══ Ransomware ══ */
  .row.rw { grid-template-columns:1fr 130px auto; border-left-color:var(--ransom); }
  .rw-v { min-width:0; }
  .rw-v .vn { font-weight:500; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .rw-v .sc { color:var(--ink-faint); font-size:11px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  /* v10.8: the group name is now the entry point to an actor profile.
     Underline-on-hover plus a persistent dotted rule tells you it is
     interactive without shouting; the row itself stays non-clickable so the
     affordance is unambiguous. 44px min tap target per touch guidance. */
  .rw-g { color:var(--ransom); font-size:11.5px; text-transform:uppercase; letter-spacing:0.05em;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

  /* ══ Phishing ══ */
  .row.ph { grid-template-columns:1fr auto; border-left-color:var(--phish); }
  .ph-d { min-width:0; }
  .ph-d .dm { font-weight:500; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .ph-d .meta2 { display:flex; gap:6px; flex-wrap:wrap; margin-top:4px; }
  .tg-brand { color:var(--phish); border-color:var(--phish); }

  /* ══ Malware URLs ══ */
  .row.mu { grid-template-columns:1fr auto; border-left-color:var(--sev-high); }
  .row.mu.offline { border-left-color:var(--ink-faint); opacity:0.7; }
  .mu-h { min-width:0; }
  .mu-h .hs { font-weight:500; color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .mu-h .tgs { display:flex; gap:5px; flex-wrap:wrap; margin-top:4px; }
  .st { text-transform:uppercase; letter-spacing:0.06em; font-size:9.5px; padding:2px 7px; border-radius:3px; }
  .st.online { color:var(--sev-crit); border:1px solid var(--sev-crit); }
  .st.offline { color:var(--ink-faint); border:1px solid var(--line); }

  /* ══ Ports ══ */
  .port-row { display:grid; grid-template-columns:78px 1fr 74px; gap:12px; align-items:center;
    padding:10px 14px; border-bottom:1px solid var(--line-soft); }
  .port-row.wide { grid-template-columns:150px 1fr 80px; }
  .port-row.wide .port-n { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .port-row:last-child{border-bottom:none;}
  .port-n { font-weight:700; color:var(--port); font-size:13px; }
  .port-n small { color:var(--ink-faint); font-weight:400; font-size:10px; display:block; letter-spacing:0.05em; }
  .port-bar { height:7px; background:var(--bg-deep); border-radius:4px; overflow:hidden; border:1px solid var(--line-soft); }
  .port-bar span { display:block; height:100%; background:linear-gradient(90deg,var(--port),var(--cyan));
    border-radius:4px; transition:width 0.8s var(--ease); }
  .port-c { text-align:right; font-size:11px; color:var(--ink-dim); }

  /* ══ Map layer toggles ══ */
  .layer-bar { display:flex; gap:7px; padding:10px 14px; border-bottom:1px solid var(--line-soft); flex-wrap:wrap; }
  .layer-btn { display:inline-flex; align-items:center; gap:7px; font-size:10.5px; font-family:var(--mono);
    color:var(--ink-dim); background:var(--bg-deep); border:1px solid var(--line); border-radius:20px;
    padding:4px 11px; cursor:pointer; transition:all 0.2s var(--ease); letter-spacing:0.05em; }
  .layer-btn:hover { color:var(--ink); border-color:var(--ink-faint); }
  .layer-btn.on { color:var(--ink); border-color:currentColor; }
  .layer-btn i { width:8px; height:8px; border-radius:50%; background:currentColor; box-shadow:0 0 7px -1px currentColor; }
  /* v10.7 glyph language — shape carries the layer, not just color:
     C2 = filled circle (host) · scanner = diamond · ransomware = OPEN square
     (open marks a country AGGREGATE, not a host — the honesty principle,
     rendered). Legend glyphs match the map glyphs exactly. */
  .layer-btn[data-layer="scanners"] i { width:7px; height:7px; border-radius:0; transform:rotate(45deg); }
  .layer-btn[data-layer="ransom"] i { border-radius:0; background:none; border:1.5px solid currentColor;
    box-shadow:none; width:7px; height:7px; }
  .layer-btn .n { color:var(--ink-faint); font-size:9.5px; }
  .layer-btn.off { opacity:0.4; }
  .map-solar { position:absolute; bottom:9px; left:14px; z-index:2; font-family:var(--disp);
    font-size:9px; letter-spacing:0.16em; text-transform:uppercase; color:var(--ink-faint);
    pointer-events:none; }
  .map-solar b { color:var(--ink-dim); font-weight:500; }
  .map-note { padding:9px 14px; font-size:10px; color:var(--ink-faint); line-height:1.6;
    border-top:1px solid var(--line-soft); }

  .ransom-blob { opacity:0.5; }

  /* ══ CVSS badge ══ */
  .cvss { font-family:var(--disp); font-weight:700; font-size:11.5px; padding:2px 7px; border-radius:4px;
    border:1px solid currentColor; white-space:nowrap; }
  .cvss.crit { color:var(--sev-crit); } .cvss.high { color:var(--sev-high); }
  .cvss.med { color:var(--sev-med); }  .cvss.low { color:var(--sev-low); }
  .cvss.na { color:var(--ink-faint); border-style:dashed; }

  /* ══ Asset check ══ */
  .asset-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(190px,1fr)); gap:12px; margin-top:14px; }
  .acard { border:1px solid var(--line); border-radius:7px; background:var(--bg-deep); padding:13px 15px; }
  .acard .t { font-size:9.5px; text-transform:uppercase; letter-spacing:0.12em; color:var(--ink-faint); margin-bottom:6px; }
  .acard .b { font-family:var(--disp); font-weight:700; font-size:20px; line-height:1.1; }
  .acard .s { font-size:10.5px; color:var(--ink-dim); margin-top:4px; }
  .g-A{color:var(--sev-low);} .g-B{color:#7fc98a;} .g-C{color:var(--sev-med);}
  .g-D{color:var(--sev-high);} .g-F{color:var(--sev-crit);}
  .hdr-list { margin-top:14px; }
  .hdr-item { display:grid; grid-template-columns:20px 1fr; gap:10px; padding:8px 0;
    border-bottom:1px solid var(--line-soft); font-size:11.5px; align-items:start; }
  .hdr-item:last-child{border-bottom:none;}
  .hdr-item .mk { font-weight:700; }
  .hdr-item .mk.ok { color:var(--sev-low); } .hdr-item .mk.no { color:var(--sev-high); }
  .hdr-item .nm2 { color:var(--ink); }
  .hdr-item .wy { color:var(--ink-faint); font-size:10.5px; margin-top:2px; }



  /* ══ Public Safety lane ══ */
  .ps-flag { font-family:var(--disp); font-size:9px; letter-spacing:0.14em; text-transform:uppercase;
    color:var(--amber); border:1px solid var(--amber-lo); padding:1px 5px; margin-right:6px; }
  .row.ics { grid-template-columns:120px 1fr auto; border-left-color:var(--band-blue); }
  .row.ics.ps { border-left-color:var(--amber) !important; background:rgba(52,227,212,0.045); }
  .ics-id { font-family:var(--mono); font-size:11.5px; color:var(--band-blue); font-weight:600; white-space:nowrap; }
  .row.ics.ps .ics-id { color:var(--amber); }
  .ics-t { min-width:0; }
  .ics-t .tt { color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .ics-t .sm { color:var(--ink-dim); font-size:11.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .ics-t a { color:inherit; text-decoration:none; }
  .ics-t a:hover { color:var(--amber); }
  .vtag { font-size:9.5px; color:var(--ink-dim); border:1px solid var(--rule); padding:1px 5px; margin-right:4px; }
  .sector-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:10px; }
  .sec-card { border:1px solid var(--rule); background:var(--screen); padding:11px 13px; }
  .sec-card .n { font-family:var(--disp); font-weight:600; font-size:21px; }
  .sec-card .l { font-size:9.5px; letter-spacing:0.14em; text-transform:uppercase; color:var(--ink-faint);
    margin-top:3px; font-family:var(--disp); }
  .sec-card.hot .n { color:var(--alarm); }
  .sec-card.warm .n { color:var(--warn); }
  .sec-card.calm .n { color:var(--ink-dim); }
  .proto-note { font-size:10.5px; color:var(--ink-faint); padding:9px 14px; border-top:1px solid var(--rule-soft); line-height:1.6; }
  .row.port-ps { border-left:3px solid var(--amber) !important; }
  #psPorts .port-row { grid-template-columns:230px 1fr 90px; align-items:center; }
  #psPorts .port-n { overflow:visible; white-space:normal; }
  #psPorts .port-n small { white-space:normal; line-height:1.35; display:block; padding-top:2px; }
  @media (max-width:700px){ #psPorts .port-row { grid-template-columns:150px 1fr 70px; } }


  /* ══ Freshness indicators ══ */
  .fresh { display:inline-flex; align-items:center; gap:5px; font-family:var(--mono);
    font-size:10px; color:var(--ink-faint); white-space:nowrap; }
  .fresh i { width:5px; height:5px; border-radius:50%; background:var(--clear);
    box-shadow:0 0 5px var(--clear); flex:none; }
  .fresh.warn { color:var(--caution); } .fresh.warn i { background:var(--caution); box-shadow:0 0 5px var(--caution); }
  .fresh.stale { color:var(--alarm); } .fresh.stale i { background:var(--alarm); box-shadow:0 0 5px var(--alarm); animation:lamp 1.4s infinite; }
  .stale-banner { display:none; margin:0 0 12px; padding:9px 13px; border:1px solid var(--alarm);
    border-left-width:3px; background:rgba(224,65,79,0.08); font-size:12px; color:var(--ink); }
  .stale-banner.on { display:block; }
  .stale-banner b { color:var(--alarm); }
  .stale-banner .sub2 { color:var(--ink-dim); font-size:11px; margin-top:3px; }
  .refresh-note { font-size:10px; color:var(--ink-faint); letter-spacing:0.06em; }

  /* ══ Daily brief band ══ */
  .brief { margin:14px 0 0; border:1px solid var(--rule); border-left:3px solid var(--amber);
    background:linear-gradient(90deg, rgba(52,227,212,0.05), transparent 60%), var(--case-hi);
    padding:13px 16px; display:none; }
  .brief.on { display:block; animation:fadeUp 0.4s var(--ease) both; }
  .brief h3 { font-family:var(--disp); font-size:12px; letter-spacing:0.24em; text-transform:uppercase;
    margin:0 0 8px; color:var(--amber); }
  .brief .lines { display:flex; flex-wrap:wrap; gap:8px 22px; }
  .brief .bl { font-size:12.5px; color:var(--ink-dim); display:inline-flex; align-items:baseline; gap:7px; }
  .brief .bl b { color:var(--ink); font-weight:500; }
  .brief .bl .num { font-family:var(--disp); font-size:17px; font-weight:600; }
  .brief .bl.hot .num { color:var(--alarm); }
  .brief .bl.warm .num { color:var(--warn); }
  .brief .bl.calm .num { color:var(--clear); }
  .brief .foot { margin-top:9px; font-size:10.5px; color:var(--ink-faint); }

  .stat .d { font-family:var(--mono); font-size:10px; display:block; margin-top:3px; }
  .stat .d.up { color:var(--alarm); } .stat .d.dn { color:var(--clear); } .stat .d.flat { color:var(--ink-faint); }
  .stat .spark { position:absolute; right:10px; bottom:9px; opacity:0.55; pointer-events:none; }

  .newbadge { font-family:var(--disp); font-size:9px; letter-spacing:0.16em; text-transform:uppercase;
    color:var(--amber); border:1px solid var(--amber-lo); padding:1px 5px; margin-right:6px; }

  .due { font-family:var(--mono); font-size:10px; padding:2px 6px; border:1px solid currentColor; white-space:nowrap; }
  .due.over { color:var(--alarm); } .due.soon { color:var(--caution); } .due.ok { color:var(--ink-faint); }

  .stackbar { display:flex; align-items:center; gap:9px; flex-wrap:wrap; margin:0 0 14px;
    padding:9px 12px; border:1px solid var(--rule); background:var(--case-hi); }
  .stackbar .lb { font-family:var(--disp); font-size:10px; letter-spacing:0.2em;
    text-transform:uppercase; color:var(--ink-faint); }
  .vchip { display:inline-flex; align-items:center; gap:6px; font-size:11px; font-family:var(--mono);
    color:var(--ink-dim); border:1px solid var(--rule); padding:3px 8px; cursor:pointer;
    transition:all 0.18s var(--ease); background:var(--screen); }
  .vchip:hover { color:var(--ink); border-color:var(--ink-faint); }
  .vchip.on { color:var(--amber); border-color:var(--amber-lo); background:rgba(52,227,212,0.07); }
  .stack-add { background:var(--screen); border:1px solid var(--rule); color:var(--ink);
    font-family:var(--mono); font-size:11px; padding:4px 9px; outline:none; width:140px; }
  .stack-add:focus { border-color:var(--amber); }
  .stack-note { font-size:10px; color:var(--ink-faint); width:100%; }
  .row.mine { border-left-color:var(--amber) !important; background:rgba(52,227,212,0.045); }
  .mine-tag { font-family:var(--disp); font-size:9px; letter-spacing:0.14em; text-transform:uppercase;
    color:var(--amber); border:1px solid var(--amber-lo); padding:1px 5px; margin-right:6px; }

  .sight { font-family:var(--mono); font-size:10px; padding:2px 6px; border:1px solid currentColor;
    white-space:nowrap; color:var(--ink-faint); }
  .sight.hot { color:var(--alarm); }
  .sight.warm { color:var(--caution); }

  .bulk-in { width:100%; min-height:110px; background:var(--screen); border:1px solid var(--rule);
    color:var(--ink); font-family:var(--mono); font-size:12px; padding:10px 12px; outline:none; resize:vertical; }
  .bulk-in:focus { border-color:var(--amber); }
  .bulk-tbl { width:100%; border-collapse:collapse; margin-top:12px; font-size:11.5px; }
  .bulk-tbl th { text-align:left; font-family:var(--disp); font-size:9.5px; letter-spacing:0.16em;
    text-transform:uppercase; color:var(--ink-faint); padding:7px 10px; border-bottom:1px solid var(--rule); }
  .bulk-tbl td { padding:8px 10px; border-bottom:1px solid var(--rule-soft); }
  .bulk-tbl tr.hit td { background:rgba(224,65,79,0.07); }
  .bulk-tbl .v-hit { color:var(--alarm); font-weight:500; }
  .bulk-tbl .v-clean { color:var(--ink-faint); }


  /* ══ Map animation ══
     Motion here encodes real data: arrival ripples mark nodes that genuinely
     appeared in this refresh; breathing intensity tracks activity. No attack
     arcs — the feeds contain no attacker→target pairs to draw them from. */
  .arrive { fill:none; stroke-width:1.4; transform-origin:center;
    animation:arriveRipple 2.6s var(--ease) 3; pointer-events:none; }
  @keyframes arriveRipple {
    0%   { r:2; opacity:0.95; stroke-width:2; }
    70%  { opacity:0.18; }
    100% { r:26; opacity:0; stroke-width:0.5; }
  }
  .newpt { animation:newFlash 2.4s var(--ease) 3; }
  @keyframes newFlash {
    0%,100% { filter:none; }
    35%     { filter:drop-shadow(0 0 7px currentColor) brightness(1.7); }
  }
  /* breathing — subtle, rate tied to activity */
  .breathe { animation:breathe var(--bt,4s) ease-in-out infinite; }
  @keyframes breathe { 0%,100%{opacity:var(--o1,0.35);} 50%{opacity:var(--o2,0.75);} }

  /* ── Night shading ──
     The real solar terminator, rasterised from the sun's current position and
     drawn beneath the markers. Static: it depicts where night actually is, so
     there is nothing to animate. Replaced the old rotating radar sweep, which
     implied a scanning station at 0°N 0°E that does not exist. */
  #nightImg { pointer-events:none; }

  /* ── Refresh wavefront ──
     Fires only when /mapdata genuinely returns new data. The line crosses along
     longitude — correct for an equirectangular projection — and each C2 marker
     lights as it is passed, because that marker really was just re-fetched. */
  .wavefront { pointer-events:none; animation:waveX var(--wave-ms,2200ms) linear 1 forwards; }
  @keyframes waveX { from { transform:translateX(0); } to { transform:translateX(1092px); } }
  .wavepaint { animation:wavePaint 620ms var(--ease) 1 both; }
  @keyframes wavePaint {
    0%   { filter:none; }
    24%  { filter:drop-shadow(0 0 6px currentColor) brightness(1.85); }
    100% { filter:none; }
  }

  .map-tools { display:flex; gap:7px; align-items:center; margin-left:auto; }
  .mini-toggle { font-family:var(--disp); font-size:9.5px; letter-spacing:0.14em;
    text-transform:uppercase; color:var(--ink-faint); background:none;
    border:1px solid var(--rule); padding:3px 8px; cursor:pointer; border-radius:2px;
    transition:all 0.18s var(--ease); }
  .mini-toggle:hover { color:var(--ink-dim); border-color:var(--ink-faint); }
  .mini-toggle.on { color:var(--amber); border-color:var(--amber-lo); }

  .newflag { font-family:var(--disp); font-size:9.5px; letter-spacing:0.14em;
    text-transform:uppercase; color:var(--amber); border:1px solid var(--amber-lo);
    padding:1px 6px; margin-left:8px; animation:lamp 1.6s infinite; }

  @media (prefers-reduced-motion:reduce){
    /* Night shading is deliberately absent here — it is static information,
       not motion, and removing it would remove data rather than animation. */
    .arrive,.newpt,.breathe,.wavefront,.wavepaint { animation:none !important; }
  }

  /* ══ Triage list ══ */
  .triage-ctl { display:flex; gap:9px; flex-wrap:wrap; align-items:center; margin-bottom:12px; }
  .triage-sum { display:grid; grid-template-columns:repeat(auto-fit,minmax(120px,1fr)); gap:10px; margin-bottom:14px; }
  .tsum { border:1px solid var(--rule); background:var(--screen); padding:10px 13px; }
  .tsum .n { font-family:var(--disp); font-weight:600; font-size:22px; line-height:1; }
  .tsum .l { font-size:9px; letter-spacing:0.16em; text-transform:uppercase; color:var(--ink-faint);
    margin-top:4px; font-family:var(--disp); }
  .tsum.p1 .n { color:var(--alarm); } .tsum.p2 .n { color:var(--warn); }
  .tsum.p3 .n { color:var(--caution); } .tsum.p4 .n { color:var(--ink-dim); }

  .trow { display:grid; grid-template-columns:34px 132px 1fr 76px 104px; gap:12px; align-items:start;
    padding:12px 14px; border-bottom:1px solid var(--rule-soft); background:var(--screen-lo);
    border-left:3px solid transparent; animation:slideIn 0.32s var(--ease) both; }
  .trow:last-child { border-bottom:none; }
  .trow.p1 { border-left-color:var(--alarm); background:rgba(224,65,79,0.05); }
  .trow.p2 { border-left-color:var(--warn); }
  .trow.p3 { border-left-color:var(--caution); }
  .trow.p4 { border-left-color:var(--rule); }
  .trank { font-family:var(--disp); font-size:15px; font-weight:600; color:var(--ink-faint); text-align:right; }
  .trow.p1 .trank { color:var(--alarm); }
  .tcve { font-family:var(--mono); font-size:12.5px; font-weight:600; color:var(--amber); }
  .tcve a { color:inherit; text-decoration:none; }
  .tcve a:hover { text-decoration:underline; }
  .twhy { font-size:10px; color:var(--ink-faint); margin-top:3px; line-height:1.5; }
  .tprod { color:var(--ink); font-size:13px; }
  .tname { color:var(--ink-dim); font-size:11.5px; margin-top:2px; }
  .taction { color:var(--ink-faint); font-size:10.5px; margin-top:5px; line-height:1.5;
    border-left:2px solid var(--rule); padding-left:8px; }
  .tmeta { text-align:right; font-size:11px; }
  @media (max-width:760px){
    .trow { grid-template-columns:28px 1fr; }
    .trow .tmeta { grid-column:2; text-align:left; }
  }

  .lookup { border:1px solid var(--line); border-radius:8px; background:var(--bg-panel); padding:16px; }
  .lookup h3 { font-family:var(--disp); font-size:14px; margin:0 0 4px; }
  .lookup .hint { font-size:10.5px; color:var(--ink-faint); margin-bottom:12px; line-height:1.6; }
  .lookup-in { display:flex; gap:9px; flex-wrap:wrap; }
  .lookup-in input { flex:1 1 240px; background:var(--bg-deep); border:1px solid var(--line);
    border-radius:6px; padding:9px 12px; color:var(--ink); font-family:var(--mono); font-size:12.5px; outline:none; }
  .lookup-in input:focus { border-color:var(--cyan); }
  .lookup-res { margin-top:13px; font-size:12px; }
  .verdict { display:flex; align-items:center; gap:10px; padding:12px 14px; border-radius:6px;
    border:1px solid var(--line); background:var(--bg-deep); }
  .verdict.bad { border-color:var(--sev-crit); }
  .verdict.clean { border-color:var(--sev-low); }
  .verdict .vi { width:26px; height:26px; border-radius:50%; display:grid; place-items:center;
    font-weight:700; font-family:var(--disp); flex:none; }
  .verdict.bad .vi { background:rgba(224,65,79,0.15); color:var(--sev-crit); border:1px solid var(--sev-crit); }
  .verdict.clean .vi { background:rgba(78,163,107,0.13); color:var(--sev-low); border:1px solid var(--sev-low); }
  .verdict .vt { font-weight:500; }
  .verdict .vs { font-size:10.5px; color:var(--ink-dim); margin-top:2px; }
  .match-list { margin-top:10px; }
  .match { padding:9px 12px; border:1px solid var(--line-soft); border-radius:5px;
    margin-bottom:7px; background:var(--bg-deep); font-size:11.5px; }
  .match .mw { color:var(--sev-crit); font-size:9.5px; letter-spacing:0.08em; text-transform:uppercase; }

  /* ══ Drawer ══ */
  /* ══ v10.8 actor profile ══ */
  .actor-btn { background:none; border:none; padding:0; font:inherit; color:var(--ransom);
    letter-spacing:inherit; text-transform:inherit; cursor:pointer; text-align:left;
    border-bottom:1px dotted var(--ransom); line-height:1.5;
    transition:color 0.15s ease, border-color 0.15s ease; }
  .actor-btn:hover { color:#ff8b9c; border-bottom-style:solid; }
  .actor-btn[disabled] { color:var(--ink-dim); border:none; cursor:default; }
  /* Caveat block. Deliberately given real visual weight — it is the honesty
     surface for self-reported criminal claims, not fine print. */
  .actor-caveat { border-left:2px solid var(--caution); background:rgba(217,164,65,0.07);
    padding:9px 12px; margin:14px 0 18px; color:var(--ink-readable); font-size:11.5px; line-height:1.65; }
  .actor-caveat b { color:var(--caution); font-weight:600; display:block; margin-bottom:3px;
    font-family:var(--disp); font-size:9.5px; letter-spacing:0.16em; text-transform:uppercase; }
  .actor-stats { display:grid; grid-template-columns:repeat(2,1fr); gap:10px; margin-bottom:16px; }
  .actor-stat { background:var(--bg-deep); border:1px solid var(--line-soft); padding:9px 11px; }
  .actor-stat .n { font-family:var(--disp); font-size:20px; color:var(--ink); line-height:1.1; }
  .actor-stat .l { font-size:9px; letter-spacing:0.14em; text-transform:uppercase;
    color:var(--ink-readable); margin-top:3px; }
  .actor-bars { margin-bottom:6px; }
  .actor-bar { display:grid; grid-template-columns:1fr 34px; gap:8px; align-items:center;
    padding:3px 0; font-size:11.5px; }
  .actor-bar .lbl { color:var(--ink-readable); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .actor-bar .trk { grid-column:1/-1; height:3px; background:var(--bg-deep); overflow:hidden; }
  .actor-bar .fil { height:100%; background:var(--ransom); opacity:0.75; }
  .actor-bar .cnt { color:var(--ink-readable); font-size:10px; text-align:right;
    font-family:var(--disp); }
  /* 12-month cadence. Bars carry a title so the values are reachable without
     hover on touch, and the axis labels anchor both ends. */
  .actor-spark { display:flex; align-items:flex-end; gap:3px; height:44px; margin:4px 0 5px; }
  .actor-spark div { flex:1; background:var(--ransom); opacity:0.55; min-height:1px; }
  .actor-spark div.now { opacity:0.95; }
  .actor-axis { display:flex; justify-content:space-between; color:var(--ink-readable);
    font-size:9px; letter-spacing:0.1em; }
  .actor-vic { padding:7px 0; border-bottom:1px solid var(--line-soft); font-size:12px; }
  .actor-vic .v { color:var(--ink); }
  .actor-vic .m { color:var(--ink-readable); font-size:10.5px; margin-top:2px; }
  .actor-empty { color:var(--ink-readable); font-size:12px; line-height:1.7; }

  /* Skip link — 8 tabs plus a filter bar sit between the top of the document
     and the data. Keyboard users should not have to traverse all of it. */
  /* ══ v10.9 data integrity ══
     A security dashboard must never render "no data" as "0". During the
     2026-08-12 CORS outage every counter read 0 and the console looked like
     a quiet night. Unknown state now has its own visual language: an em-dash
     glyph, dimmed weight, and a dotted underline that reads as "not measured"
     rather than "measured as none". */
  .stat .n.unknown, .cnt.unknown, [data-mini].unknown {
    /* --ink-faint measures 2.34:1 here and this dash is a MEANINGFUL
       indicator, not chrome — it has to be readable. --ink-readable gives
       5.4:1 while still sitting visibly below --ink, so unknown still reads
       as quieter than a real figure. The dotted rule carries the same
       meaning non-chromatically for anyone who cannot rely on the tone. */
    color:var(--ink-readable); border-bottom:1px dotted var(--ink-readable);
    display:inline-block; line-height:1.1; }
  .stat .n.unknown { border-bottom-width:2px; }

  /* Integrity banner — only ever shown when a feed is actually down. */
  .integrity { display:none; align-items:flex-start; gap:10px; margin:0 0 14px;
    padding:11px 14px; border:1px solid var(--warn);
    background:linear-gradient(180deg, rgba(226,104,63,0.10), rgba(226,104,63,0.04)); }
  .integrity.on { display:flex; }
  .integrity .ico { color:var(--warn); font-size:15px; line-height:1.2; flex:none; }
  .integrity .msg { font-size:12.5px; line-height:1.65; color:var(--ink); }
  .integrity .msg b { font-family:var(--disp); color:var(--warn); font-size:10px;
    letter-spacing:0.16em; text-transform:uppercase; display:block; margin-bottom:3px; }
  .integrity .who { color:var(--ink-readable); }

  /* ══ v10.10 EPSS ══
     CVSS says how bad it is; EPSS says how likely it is to be exploited.
     They disagree constantly. Rendered as a distinct badge so the two are
     never confused for each other. */
  /* v10.11: thresholds recalibrated against the live distribution. The
     v10.10 bands (hot>=10%, warm>=1%) put 70% and 90% of items in those
     buckets respectively — a badge that fires on almost everything is not a
     signal. KEV is a biased sample: every entry is already known-exploited,
     so the median EPSS here is 0.29 and the 75th percentile is 0.83. Bands
     chosen to split the real data: 8 critical / 19 hot / 15 warm / 18 cool. */
  .epss { font-family:var(--disp); font-size:9.5px; letter-spacing:0.08em; padding:1px 5px;
    border:1px solid currentColor; color:var(--ink-faint); white-space:nowrap; }
  .epss.warm { color:var(--ink-readable); }
  .epss.hot  { color:var(--caution); }
  .epss.crit { color:var(--warn); border-color:var(--warn); font-weight:600;
    background:rgba(226,104,63,0.10); }

  /* ══ Command palette ══ */
  .pal-bg { position:fixed; inset:0; background:rgba(4,7,12,0.72); backdrop-filter:blur(3px);
    z-index:70; display:none; }
  .pal-bg.on { display:block; }
  .pal { position:fixed; left:50%; top:12vh; transform:translateX(-50%); width:min(620px,92vw);
    z-index:71; background:var(--case-hi); border:1px solid var(--cyan);
    box-shadow:0 24px 70px -18px #000; display:none; }
  .pal.on { display:block; }
  .pal input { width:100%; box-sizing:border-box; background:var(--bg-deep); border:none;
    border-bottom:1px solid var(--rule); color:var(--ink); font-family:var(--mono);
    font-size:14px; padding:14px 16px; outline:none; }
  .pal input::placeholder { color:var(--ink-faint); }
  .pal-list { max-height:52vh; overflow-y:auto; }
  .pal-item { padding:9px 16px; display:flex; align-items:center; gap:10px; cursor:pointer;
    border-bottom:1px solid var(--rule-soft); }
  .pal-item[aria-selected="true"] { background:rgba(52,227,212,0.10);
    box-shadow:inset 2px 0 0 var(--cyan); }
  .pal-item .k { font-family:var(--disp); font-size:8.5px; letter-spacing:0.16em;
    text-transform:uppercase; color:var(--ink-faint); border:1px solid var(--line-soft);
    padding:1px 5px; flex:none; }
  .pal-item .t { font-size:12.5px; color:var(--ink); overflow:hidden;
    text-overflow:ellipsis; white-space:nowrap; }
  .pal-item .s { font-size:10.5px; color:var(--ink-readable); margin-left:auto; flex:none; }
  .pal-empty { padding:16px; color:var(--ink-readable); font-size:12px; }
  .pal-hint { padding:7px 16px; border-top:1px solid var(--rule-soft); color:var(--ink-faint);
    font-size:9.5px; letter-spacing:0.1em; text-transform:uppercase; display:flex; gap:14px; }

  /* ══ Pivot linkouts ══ */
  .pivots { display:flex; flex-wrap:wrap; gap:6px; margin-top:6px; }
  /* Row-level pivots sit inline and only reveal on hover/focus so they do not
     add permanent visual noise to a dense feed. Always reachable by keyboard:
     :focus-within keeps them open while tabbing through. */
  .pivots.inline { margin-top:4px; opacity:0; transition:opacity .15s ease; }
  .row:hover .pivots.inline, .row:focus-within .pivots.inline { opacity:1; }
  @media (hover:none) { .pivots.inline { opacity:1; } }
  .pivot { font-family:var(--disp); font-size:9px; letter-spacing:0.12em; text-transform:uppercase;
    padding:3px 7px; border:1px solid var(--line-soft); color:var(--ink-readable);
    text-decoration:none; transition:color .15s ease, border-color .15s ease; }
  .pivot:hover { color:var(--cyan); border-color:var(--cyan); }

  .skip-link { position:absolute; left:-9999px; top:0; z-index:60; background:var(--cyan);
    color:#08111a; padding:10px 16px; font-family:var(--disp); font-size:12px;
    letter-spacing:0.1em; text-transform:uppercase; }
  .skip-link:focus { left:8px; top:8px; }

  @media (max-width:380px) { .actor-stats { grid-template-columns:1fr; } }
  /* Touch: the group name is a small inline target. Padding is applied via a
     transparent hit area so the visual size is unchanged but the tappable
     region clears the 44px guidance in the vertical axis. */
  @media (hover:none) {
    .actor-btn { position:relative; }
    .actor-btn::after { content:""; position:absolute; left:0; right:0;
      top:50%; transform:translateY(-50%); height:44px; }
  }

  .drawer-bg { position:fixed; inset:0; background:rgba(4,7,12,0.7); backdrop-filter:blur(2px);
    opacity:0; pointer-events:none; transition:opacity 0.2s; z-index:80; }
  .drawer-bg.open { opacity:1; pointer-events:auto; }
  .drawer { position:fixed; top:0; right:0; bottom:0; width:min(440px,92vw); background:var(--bg-panel);
    border-left:1px solid var(--line); transform:translateX(100%); transition:transform 0.25s var(--ease);
    z-index:81; padding:26px; overflow-y:auto; }
  .drawer.open { transform:none; }
  .drawer h2 { font-family:var(--disp); color:var(--cyan); margin:0 0 4px; font-size:19px; }
  .drawer .dsub { color:var(--ink-dim); font-size:11.5px; margin-bottom:18px; }
  .drawer .field { margin-bottom:15px; }
  .drawer .field .k { font-size:9.5px; text-transform:uppercase; letter-spacing:0.12em;
    color:var(--ink-faint); margin-bottom:4px; }
  .drawer .field .v { color:var(--ink); font-size:12.5px; }
  .drawer a.ext { display:inline-block; margin-top:8px; color:var(--cyan); text-decoration:none;
    border-bottom:1px solid var(--cyan); padding-bottom:1px; font-size:11.5px; }
  .drawer .close { position:absolute; top:18px; right:18px; background:none; border:1px solid var(--line);
    color:var(--ink-dim); border-radius:4px; width:30px; height:30px; cursor:pointer; font-size:16px; }
  .drawer .close:hover { color:var(--ink); border-color:var(--ink-dim); }

/* Build marker — read by the partial-upload guard in index.html. Lives in the
   LAST stylesheet in the chain so it only resolves when every sheet loaded.
   Bump with every release, together with SENTINEL_BUILD in js/sentinel.js. */
#buildProbe { --sentinel-css-build: "11.1"; position:absolute; width:0; height:0;
  overflow:hidden; pointer-events:none; }
