/* ════════════════════════════════════════════════════════
   CyberWorldOps — design tokens
   ════════════════════════════════════════════════════════ */
:root {
  --bg: #07080c;
  --bg-2: #0a0c12;
  --surface: #0f1118;
  --surface-2: #151824;
  --surface-3: #1c2030;
  --text: #eef0f6;
  --text-2: #d5d9e4;
  --muted: #969db1;
  /* Lightened from #6d7488, which measured 4.04-4.29:1 against the surfaces it
     sits on — just under the 4.5:1 required for text this small. It is used by
     the tagline, language switcher, timestamps, counters and rank numbers, so
     one variable fixed ten of the thirteen contrast failures. */
  --dim: #838a9e;
  --accent: #ff2e3f;
  --accent-2: #ff7a45;
  --border: #222736;
  --border-2: #2e3446;
  --radius: 12px;
  --radius-sm: 8px;
  --maxw: 1260px;
  --sans: system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, 'SF Mono', 'Cascadia Code', 'Roboto Mono', Menlo, Consolas, monospace;
  --shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
  /* Per-category accent hue. Overridden inline on cards/pages. */
  --cat-h: 352;
  --nav-h: 104px;
  /* "As much contrast as this text can get." White on a near-black page, black
     on a white one — which is exactly why it cannot be a literal. Used as #fff
     it made every emphasised heading and hovered title invisible the moment the
     palette inverted. */
  --text-max: #ffffff;
}

/* Intelligence sections reuse the site's surface and typography tokens. */
.intel-hub {
  margin: 2rem 0;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.intel-hub h2,
.intel-card h2,
.intel-card h3 {
  margin: 0.5rem 0;
}
.intel-hub p,
.intel-card p,
.intel-method p,
.intel-timeline p {
  color: var(--text-2);
  line-height: 1.7;
}
.intel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 250px), 1fr));
  gap: 1rem;
  margin: 1.25rem 0;
}
.intel-card {
  padding: 1.25rem;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  min-width: 0;
}
.intel-card a,
.intel-timeline a {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}
.intel-link {
  display: inline-block;
  margin-top: 1rem;
  text-decoration: underline;
}
.intel-links {
  margin: 1.5rem 0;
  color: var(--muted);
}
.intel-method {
  margin: 1.5rem 0;
  padding: 1rem;
  border-left: 3px solid var(--border-2);
}
.intel-method summary {
  cursor: pointer;
  font-weight: 600;
}
.intel-timeline {
  list-style: none;
  padding: 0 0 0 1.25rem;
  margin: 2rem 0;
  border-left: 2px solid var(--border-2);
}
.intel-timeline li {
  padding: 0 0 1.75rem 0.5rem;
  max-width: 850px;
}
.intel-timeline time {
  color: var(--muted);
  font-size: 0.9rem;
}
.intel-timeline h3 {
  margin: 0.5rem 0;
}
.intel-number {
  font-size: 2rem;
}
.intel-products {
  list-style: none;
  padding: 0;
}
.intel-products li {
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--border);
}
@media (max-width: 600px) {
  .intel-hub {
    padding: 1rem;
  }
}

/* ── Light theme ──────────────────────────────────────────────────────────── */
/*
 * An opt-in, not a system-preference default.
 *
 * `prefers-color-scheme: light` is the majority setting, so honouring it would
 * silently flip the site's identity for most first-time readers — a dark
 * cybersecurity publication would become a white one for anyone who never asked.
 * Dark stays the default; the toggle is remembered for whoever wants otherwise.
 *
 * Contrast measured, not eyeballed. Every pair below clears WCAG AA for its use:
 * text 15.9:1, text-2 11.2:1, muted 4.9:1, dim 4.6:1, accent 4.6:1 against the
 * page background. The accent is darkened from #ff2e3f, which measures 3.0:1 on
 * white and fails for text — the same red that carries 5.45:1 on the dark theme.
 * A token cannot be reused across inverted backgrounds just because it is the
 * brand colour.
 */
:root[data-theme='light'] {
  --bg: #fbfbfd;
  --bg-2: #f4f5f8;
  --surface: #ffffff;
  --surface-2: #f2f3f7;
  --surface-3: #e8eaf0;
  --text: #12141a;
  --text-2: #33384a;
  --muted: #5c637a;
  /* #676e85 cleared 4.5 against the page and the plain surfaces, and dropped to
     4.38 on the tinted filter chips, where a count sits on a coloured wash.
     Darkened until the worst case passes rather than the average one. */
  --dim: #5e657c;
  /* Darkened for white: the dark theme's #ff2e3f measures 3.0:1 here. */
  --accent: #d40d1e;
  --accent-2: #c2410c;
  --border: #e2e5ec;
  --border-2: #cdd2de;
  --shadow: 0 12px 32px rgba(18, 20, 26, 0.1);
  /* Chart colours are semantic — amber warns, blue is telemetry — so they change
     value to keep meaning rather than keeping their hex. #f5a524 is 1.9:1 on
     white and unreadable as anything but a large block. */
  /* #b26a00 measured 4.10:1 on this background: enough for a bar fill, which
     needs 3.0, and short of the 4.5 the .kev-lag line needs as text. Darkened
     until one value serves both, rather than splitting the token and having to
     remember which is which. */
  --chart-warn: #9a5b00;
  --chart-sensor: #1a5c96;
  --text-max: #000000;
}
/* Named on the dark side too, so the charts stop carrying literals. */
:root {
  --chart-warn: #f5a524;
  --chart-sensor: #1f6fb2;
}

/*
 * Dark covers on a white page.
 *
 * Every cover this site generates is a dark, neon, cinematic illustration. On a
 * white background an unframed one reads as a hole punched through the layout —
 * which was the objection to having a light theme at all. Print solved this
 * centuries ago: a dark photograph on white paper is framed, and framing makes
 * it deliberate. So in light mode the cover sits on a dark mat with a border
 * instead of bleeding into the page.
 */
:root[data-theme='light'] .cover-photo,
:root[data-theme='light'] .kev-band-dot {
  border-radius: var(--radius-sm);
}
:root[data-theme='light'] .hero-slot,
:root[data-theme='light'] .card-media,
:root[data-theme='light'] .post-cover {
  background: #0f1118;
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  overflow: hidden;
}

/* ── Theme toggle ─────────────────────────────────────────────────────────── */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid var(--border-2);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--dim);
  cursor: pointer;
  transition:
    color 120ms ease,
    border-color 120ms ease;
}
.theme-toggle:hover {
  color: var(--text);
  border-color: var(--muted);
}
.theme-toggle svg {
  width: 14px;
  height: 14px;
}
/* Only one icon is ever shown: the sun offers light, the moon offers dark. */
:root:not([data-theme='light']) .theme-icon-moon,
:root[data-theme='light'] .theme-icon-sun {
  display: none;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /**
   * Stop iOS WebViews resizing text on their own.
   *
   * Safari with a width=device-width viewport leaves text alone, but the
   * embedded browsers inside apps — Telegram, Instagram, Slack — run WKWebView
   * with different defaults and can inflate it. Measured on the category bar,
   * text at 160% widens the row from 678px to 1083px: it scrolls correctly, but
   * every other measurement in the layout shifts under it for no reason the page
   * asked for.
   *
   * A large share of a news site's traffic arrives through exactly those
   * in-app browsers, from a shared link.
   */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

html,
body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body {
  background-image:
    radial-gradient(900px 420px at 12% -160px, rgba(255, 46, 63, 0.1), transparent 70%),
    radial-gradient(760px 380px at 88% -120px, rgba(64, 120, 255, 0.07), transparent 70%),
    linear-gradient(180deg, #0a0c12 0%, var(--bg) 620px);
  background-repeat: no-repeat;
}

a {
  color: inherit;
  text-decoration: none;
}

img,
svg {
  max-width: 100%;
}

::selection {
  background: rgba(255, 46, 63, 0.35);
  color: var(--text-max);
}

:focus-visible {
  outline: 2px solid hsl(var(--cat-h) 95% 65%);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ── Navbar ─────────────────────────────────────────── */
/**
 * Solid background, no backdrop-filter.
 *
 * The bar was rgba(7, 8, 12, 0.86) over a blur. On iOS Safari, reported from an
 * iPhone, article text was legible straight through it: the logo and the search
 * box floating over paragraphs halfway down a page. Safari does support
 * backdrop-filter, so feature detection is no defence — it simply fails to
 * composite the layer inside a sticky element under conditions that are not
 * worth chasing.
 *
 * A frosted header is decoration. A header you can read the article through is
 * a defect, and it is the first thing a stranger arriving from a shared link
 * sees. Opaque wins.
 */
.nav {
  position: sticky;
  top: 0;
  z-index: 60;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.nav-top {
  border-bottom: 1px solid rgba(255, 255, 255, 0.045);
}
.nav-inner {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0.7rem 1.25rem;
  display: flex;
  align-items: center;
  gap: 1.25rem;
}
.brand {
  display: inline-flex;
  align-items: baseline;
  gap: 0.45rem;
  font-weight: 800;
  font-size: 1.22rem;
  letter-spacing: -0.025em;
  white-space: nowrap;
}
.brand-mark {
  color: var(--accent);
  font-size: 0.8em;
  filter: drop-shadow(0 0 10px rgba(255, 46, 63, 0.65));
}
.brand-accent {
  color: var(--accent);
}
.nav-tagline {
  flex: 1;
  min-width: 0;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-left: 0.5rem;
  border-left: 1px solid var(--border);
}
.nav-right {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.nav-date {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--muted);
  white-space: nowrap;
}
.nav-about {
  font-size: 0.74rem;
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 1px solid transparent;
}
.nav-about:hover {
  color: var(--text);
  border-bottom-color: var(--accent);
}
.lang-switcher {
  display: flex;
  gap: 0.2rem;
}
.lang {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Was 17x15. Two characters need help reaching a usable tap target. */
  min-width: 30px;
  min-height: 26px;
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--dim);
  padding: 0.22rem 0.42rem;
  border-radius: 6px;
  border: 1px solid transparent;
  transition:
    color 0.15s ease,
    background 0.15s ease,
    border-color 0.15s ease;
}
.lang:hover {
  color: var(--text);
  background: var(--surface-2);
}
.lang.active {
  color: var(--text-max);
  border-color: var(--border-2);
  background: var(--surface-3);
}

.nav-bar {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.02), transparent);
}
.nav-inner-cats {
  padding-top: 0;
  padding-bottom: 0;
  gap: 1rem;
}
.nav-cats {
  display: flex;
  align-items: stretch;
  gap: 0.75rem;
  flex: 1;
  min-width: 0;
  overflow-x: auto;
  font-size: 0.82rem;
  font-weight: 650;
  letter-spacing: 0.01em;
  color: var(--muted);
  scrollbar-width: none;
}
.nav-cats::-webkit-scrollbar {
  display: none;
}
.nav-cats a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  white-space: nowrap;
  /**
   * flex: 0 0 auto — the row scrolls, the labels do not squeeze.
   *
   * Without it each link inherits flex-shrink: 1 and gives up width when the
   * row is too narrow. Combined with white-space: nowrap the text then spills
   * out of its own box and paints over its neighbour, which on a phone rendered
   * the bar as ".TVMEneral MalRansomwaAPData BreachSecuritAI" — every label on
   * top of the next. The overflow-x: auto above never engaged because nothing
   * overflowed: the items shrank instead of pushing the container wider.
   */
  flex: 0 0 auto;
  /* Horizontal padding and a floor, because a two-letter label like "AI" was
     14px wide. The gap shrinks to compensate, so the bar looks unchanged. */
  min-width: 24px;
  padding: 0.7rem 0.3rem;
  border-bottom: 2px solid transparent;
  transition:
    color 0.16s ease,
    border-color 0.16s ease;
}
.nav-cats a:hover {
  color: var(--text);
  border-bottom-color: var(--accent);
}
.nav-cat-home {
  color: var(--text);
  text-transform: uppercase;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
}
.nav-live {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  color: var(--muted);
}
.live-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 0 rgba(255, 46, 63, 0.6);
  animation: pulse 2.4s infinite;
  flex: none;
}
@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(255, 46, 63, 0.5);
  }
  70% {
    box-shadow: 0 0 0 7px rgba(255, 46, 63, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(255, 46, 63, 0);
  }
}

/* ── Page shell ─────────────────────────────────────── */
.container {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 1.9rem 1.25rem 3.5rem;
}
.section-head {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding-bottom: 0.9rem;
  margin-bottom: 1.4rem;
  border-bottom: 1px solid var(--border);
}
/* The home page puts the follow links in the dead space to the right of the
   title. Opt-in, because this header is also the one on the legal pages and the
   search results, where they would be noise. */
.section-head.is-split {
  flex-direction: row;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}
.section-follow {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.section-follow > span {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--dim);
}
/* Under ~560px the title alone fills the row; letting the cluster wrap under it
   left-aligned reads as part of the header rather than a stray pair of icons. */
@media (max-width: 560px) {
  .section-head.is-split {
    align-items: flex-start;
  }
}
.kicker {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: hsl(var(--cat-h) 95% 68%);
  letter-spacing: 0.13em;
  text-transform: uppercase;
}
.page-title {
  font-size: clamp(1.5rem, 2.6vw, 2.05rem);
  font-weight: 800;
  letter-spacing: -0.028em;
  line-height: 1.12;
  margin: 0.15rem 0 0;
}

.home-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 328px;
  gap: 2.25rem;
  align-items: start;
  margin-top: 1.75rem;
}
.home-main {
  min-width: 0;
}
.hero-slot {
  margin-bottom: 0.5rem;
}

.rail-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 0.6rem;
  margin-bottom: 1.1rem;
  border-bottom: 2px solid var(--border-2);
}
.rail-title {
  position: relative;
  font-size: 0.98rem;
  font-weight: 800;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  margin: 0;
  padding-left: 0.65rem;
}
.rail-title::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.15em;
  bottom: 0.15em;
  width: 3px;
  border-radius: 2px;
  background: var(--accent);
}
.rail-count {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--dim);
}

/* ── Badges ─────────────────────────────────────────── */
.badge {
  display: inline-block;
  font-family: var(--mono);
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: hsl(var(--cat-h) 95% 74%);
  background: hsl(var(--cat-h) 90% 52% / 0.14);
  border: 1px solid hsl(var(--cat-h) 90% 60% / 0.38);
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  transition:
    background 0.15s ease,
    color 0.15s ease;
}
a.badge:hover {
  background: hsl(var(--cat-h) 90% 52% / 0.26);
  color: var(--text-max);
}
.badge-live {
  color: #fff;
  /* Darker than --accent: white on the brand red measured 3.67:1, and at 10px
     bold this needs 4.5:1. Deep enough to pass, close enough to read as the
     same red beside the accent used everywhere else. */
  background: #c20f20;
  border-color: #c20f20;
  box-shadow: 0 4px 14px rgba(255, 46, 63, 0.35);
}

/* ── Generated cover art ────────────────────────────── */
.cover {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ── Cards ──────────────────────────────────────────── */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
  gap: 1.35rem 1.15rem;
}
.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition:
    transform 0.18s ease,
    border-color 0.18s ease,
    box-shadow 0.18s ease;
}
.card:hover,
.card:focus-within {
  transform: translateY(-3px);
  border-color: hsl(var(--cat-h) 85% 55% / 0.55);
  box-shadow: var(--shadow);
}
.card-link {
  display: block;
  height: 100%;
}
.card-media {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.card-media .cover {
  position: absolute;
  inset: 0;
  transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.3, 1);
}
.card:hover .card-media .cover {
  transform: scale(1.05);
}
.card-media-tag {
  position: absolute;
  left: 0.7rem;
  bottom: 0.7rem;
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: #fff;
  /* Was 85% 40% at 0.9 alpha — 2.95:1 against white. Darker and fully opaque:
     it sits on top of a photograph, so any transparency lets the image
     underneath decide the contrast, and photographs are not a constant. */
  background: hsl(var(--cat-h) 80% 24%);
  border: 1px solid hsl(var(--cat-h) 90% 65% / 0.5);
  padding: 0.18rem 0.45rem;
  border-radius: 4px;
  backdrop-filter: blur(4px);
}
.card-body {
  padding: 0.85rem 0.95rem 0.9rem;
}
.card-title {
  font-size: 1.02rem;
  font-weight: 700;
  line-height: 1.32;
  letter-spacing: -0.014em;
  margin: 0 0 0.4rem;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card:hover .card-title {
  color: var(--text-max);
}
.card-excerpt {
  margin: 0;
  color: var(--muted);
  font-size: 0.865rem;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* ── Cover photos (AI-generated article images) ──────── */
/* Sits in the same slots as the generated SVG art, so it must fill them the same way. */
.cover-photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
.cover-credit {
  margin: 0.5rem 0 0;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  color: var(--dim);
  text-align: right;
}

/* AI Act art. 50(4) disclosure. Deliberately not styled as fine print: it is a
   legal statement that has to be noticed, so it gets a tinted bar and sits with
   the byline rather than trailing the article. */
.ai-notice {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0.9rem 0 0;
  padding: 0.55rem 0.75rem;
  border-left: 2px solid hsl(var(--cat-h, 200) 70% 55% / 0.65);
  background: hsl(var(--cat-h, 200) 70% 55% / 0.06);
  border-radius: 0 4px 4px 0;
  font-family: var(--mono);
  font-size: 0.72rem;
  line-height: 1.5;
  letter-spacing: 0.02em;
  color: var(--dim);
}

.ai-notice-mark {
  color: hsl(var(--cat-h, 200) 70% 60%);
  font-size: 0.6rem;
}

.ai-notice a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
}

.ai-notice a:hover {
  color: var(--fg);
}

.footer-ai-link {
  display: inline-block;
  padding: 0.15rem 0;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ── CVE database ───────────────────────────────────── */
.mono-dim {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--dim);
}
.nav-cat-cve {
  font-family: var(--mono);
  letter-spacing: 0.08em;
}
/* Tinted, unlike every other item in the bar. The distinction it draws —
   "exploited now" rather than "catalogued" — is the one worth a colour. */
.nav-cat-kev {
  color: var(--accent);
}
.nav-cat-kev:hover {
  color: var(--accent);
}

.cve-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--mono);
  font-size: 0.64rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  color: hsl(var(--cat-h) 95% 74%);
  background: hsl(var(--cat-h) 90% 52% / 0.15);
  border: 1px solid hsl(var(--cat-h) 90% 60% / 0.42);
  padding: 0.16rem 0.45rem;
  border-radius: 4px;
  white-space: nowrap;
}
.cve-badge strong {
  color: var(--text-max);
}

.cve-filter-bar {
  display: grid;
  gap: 0.55rem;
  padding: 0.9rem 1rem;
  margin-bottom: 1.35rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.cve-filter-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem;
}
.cve-filter-label {
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--dim);
  min-width: 5.5rem;
}

/* ── Legal / editorial pages ────────────────────────── */
.legal {
  max-width: 760px;
  margin: 0 auto;
}
.legal-intro {
  font-size: 1.02rem;
  color: var(--text-2);
  margin: 0 0 2rem;
}
.legal-section {
  margin-bottom: 1.9rem;
}
.legal-section h2 {
  font-size: 1.08rem;
  font-weight: 800;
  margin: 0 0 0.7rem;
  padding-left: 0.7rem;
  border-left: 3px solid var(--accent);
}
.legal-section p {
  margin: 0 0 0.8rem;
  color: var(--text-2);
  font-size: 0.94rem;
  line-height: 1.72;
}
.legal-updated {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--dim);
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}

/* ── Search ─────────────────────────────────────────── */
.searchbox {
  display: flex;
  align-items: center;
  gap: 0;
  background: var(--surface-2);
  border: 1px solid var(--border-2);
  border-radius: 999px;
  overflow: hidden;
  transition: border-color 0.15s ease;
}
.searchbox:focus-within {
  border-color: rgba(255, 46, 63, 0.55);
}
.searchbox input {
  width: 190px;
  max-width: 40vw;
  padding: 0.34rem 0.7rem;
  background: transparent;
  border: 0;
  color: var(--text);
  font-size: 0.8rem;
  outline: none;
}
.searchbox input::placeholder {
  color: var(--dim);
}
.searchbox button {
  background: transparent;
  border: 0;
  color: var(--muted);
  font-size: 1rem;
  /* 24px minimum: it measured 22x22, below the tap target Lighthouse asks for. */
  min-width: 24px;
  min-height: 24px;
  padding: 0.2rem 0.6rem 0.2rem 0.2rem;
  cursor: pointer;
  line-height: 1;
}
.searchbox button:hover {
  color: var(--accent);
}
.search-page-box {
  margin-bottom: 1.5rem;
}
.search-page-box .searchbox input {
  width: 100%;
  max-width: none;
  padding: 0.55rem 1rem;
  font-size: 0.92rem;
}
.search-page-box .searchbox {
  max-width: 560px;
}

@media (max-width: 720px) {
  .searchbox input {
    width: 130px;
  }
}
.cve-filter {
  font-family: var(--mono);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.3rem 0.7rem;
  transition:
    color 0.14s ease,
    border-color 0.14s ease,
    background 0.14s ease;
}
.cve-filter:hover {
  color: var(--text);
  border-color: var(--border-2);
}
.cve-filter.is-on {
  color: var(--text-max);
  background: rgba(255, 46, 63, 0.18);
  border-color: rgba(255, 46, 63, 0.5);
}

.cve-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}
/* ── CISA KEV page ─────────────────────────────────────────────────────── */

/* The pointer from the CVE browser to the shortlist. */
.kev-callout {
  display: block;
  background: linear-gradient(180deg, rgba(255, 46, 63, 0.09), transparent);
  border: 1px solid rgba(255, 46, 63, 0.32);
  border-radius: var(--radius-sm);
  padding: 0.85rem 1rem;
  margin-bottom: 1.4rem;
  transition: border-color 0.15s ease;
}
.kev-callout:hover {
  border-color: var(--accent);
}
.kev-callout strong {
  display: block;
  color: var(--accent);
  font-size: 0.95rem;
  margin-bottom: 0.15rem;
}
.kev-callout span {
  color: var(--muted);
  font-size: 0.84rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* The count of new entries this week. It is the one number on the page that
   changes, so it gets the weight — but stays type, not a banner: on a week when
   the answer is "none" a banner would be shouting about nothing. */
.kev-headline {
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent);
  margin: 0 0 1.2rem;
}
.kev-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin-bottom: 1.4rem;
}
.kev-stats > div {
  flex: 1 1 8rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.75rem 0.9rem;
}
.kev-stats strong {
  display: block;
  font-size: 1.5rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
}
.kev-stats span {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
}
.kev-intro {
  color: var(--text-2);
  max-width: 68ch;
  margin: 0 0 2rem;
}
.kev-section {
  font-size: 0.72rem;
  font-family: var(--mono);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
  margin: 2rem 0 1rem;
}
.kev-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.6rem;
}
.kev-row {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.9rem 1rem;
}
.kev-row-top {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 0.35rem;
}
/* Reserved for the one fact on a row that changes the priority of the work:
   this is being used by ransomware crews right now. */
.kev-ransom {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.15rem 0.45rem;
  border-radius: 999px;
  color: #ffd7db;
  background: rgba(255, 46, 63, 0.16);
  border: 1px solid rgba(255, 46, 63, 0.4);
}
.kev-product {
  font-family: var(--mono);
  font-size: 0.74rem;
  color: var(--muted);
  margin: 0 0 0.35rem;
}
.kev-row-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 1.1rem;
  margin-top: 0.55rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--dim);
}
.kev-about {
  margin-top: 2.5rem;
  padding-top: 1.4rem;
  border-top: 1px solid var(--border);
  color: var(--muted);
  font-size: 0.88rem;
  max-width: 72ch;
}
.kev-about h2 {
  font-size: 1rem;
  margin: 0 0 0.6rem;
}

.cve-row {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  transition:
    border-color 0.15s ease,
    transform 0.15s ease;
}
.cve-row:hover {
  border-color: var(--border-2);
  transform: translateY(-1px);
}
.cve-row-link {
  display: block;
  padding: 0.85rem 1rem;
}
.cve-row-top {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 0.4rem;
}
.cve-id {
  font-family: var(--mono);
  font-size: 0.86rem;
  font-weight: 700;
  color: var(--text);
  letter-spacing: 0.01em;
}
.cve-date {
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--dim);
  margin-left: auto;
}
.cve-summary {
  margin: 0 0 0.5rem;
  color: var(--muted);
  font-size: 0.86rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.cve-row-meta {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}
.cve-has-articles {
  font-family: var(--mono);
  font-size: 0.66rem;
  color: hsl(148 70% 62%);
  border: 1px solid hsl(148 60% 45% / 0.4);
  background: hsl(148 60% 40% / 0.14);
  border-radius: 999px;
  padding: 0.15rem 0.5rem;
}

/* Detail page */
.cve-detail {
  max-width: 900px;
  margin: 0 auto;
}
.crumbs {
  display: flex;
  gap: 0.45rem;
  align-items: center;
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--dim);
  margin-bottom: 1rem;
}
.crumbs a:hover {
  color: var(--accent);
}
.cve-head {
  border-bottom: 1px solid var(--border);
  padding-bottom: 1.25rem;
  margin-bottom: 1.5rem;
}
.cve-title {
  font-family: var(--mono);
  font-size: clamp(1.5rem, 3.5vw, 2.2rem);
  font-weight: 800;
  letter-spacing: -0.02em;
  margin: 0 0 0.6rem;
}
.cve-head-meta {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
  margin-bottom: 0.9rem;
}
.cve-abstract {
  margin: 0;
  color: var(--text-2);
  font-size: 1rem;
  max-width: 78ch;
}
.cve-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 0.7rem;
  margin-bottom: 2rem;
}
.fact {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid hsl(var(--cat-h) 90% 55%);
  border-radius: var(--radius-sm);
  padding: 0.75rem 0.9rem;
  display: grid;
  gap: 0.2rem;
}
.fact-label {
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--dim);
}
.fact-value {
  font-weight: 700;
  font-size: 0.95rem;
}
.fact-extra {
  font-family: var(--mono);
  font-size: 0.64rem;
  color: var(--muted);
  word-break: break-all;
}
.cve-block {
  margin-bottom: 2.25rem;
}
.cve-block h2 {
  font-size: 1.05rem;
  font-weight: 800;
  margin: 0 0 0.85rem;
  padding-left: 0.7rem;
  border-left: 3px solid hsl(var(--cat-h) 90% 55%);
}
.cve-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.84rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.cve-table th {
  text-align: left;
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--dim);
  padding: 0.5rem 0.7rem;
  border-bottom: 1px solid var(--border-2);
}
.cve-table td {
  padding: 0.45rem 0.7rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.cve-table tr:last-child td {
  border-bottom: 0;
}

/* Source attribution inside an article */
.post-sources {
  margin: 2.25rem 0 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}
.post-sources h2 {
  font-size: 0.95rem;
  font-weight: 800;
  margin: 0 0 0.4rem;
  padding-left: 0.6rem;
  border-left: 3px solid var(--accent);
}
.post-sources-note {
  margin: 0 0 0.7rem;
  color: var(--dim);
  font-size: 0.8rem;
}
.post-sources ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
}

/* Marks the issuer's own record — a vendor PSIRT, CISA, a GitHub advisory —
   apart from the outlets that reported on it. Small and quiet: it is a
   qualifier on the name beside it, not a badge competing with it. */
.post-sources li:has(.source-primary) {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35rem;
}
.source-primary {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--accent);
  opacity: 0.85;
  white-space: nowrap;
}
.post-sources a {
  display: inline-block;
  font-size: 0.82rem;
  color: var(--text-2);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.3rem 0.75rem;
  transition:
    border-color 0.15s ease,
    color 0.15s ease;
}
.post-sources a:hover {
  color: var(--text-max);
  border-color: rgba(255, 46, 63, 0.5);
}

/* CVE list inside an article */
.post-cves {
  margin: 2.25rem 0 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}
.post-cves h2 {
  font-size: 0.95rem;
  font-weight: 800;
  margin: 0 0 0.75rem;
  padding-left: 0.6rem;
  border-left: 3px solid var(--accent);
}
.post-cves ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* minmax(0, …) rather than the default 1fr: a grid item's implicit
     min-width is auto, so a long nowrap summary made the row wider than the
     track and pushed the whole page into horizontal scroll. */
  grid-template-columns: minmax(0, 1fr);
  gap: 0.45rem;
}
.post-cve {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  min-width: 0;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.55rem 0.75rem;
  transition: border-color 0.15s ease;
}
.post-cve:hover {
  border-color: rgba(255, 46, 63, 0.5);
}
.post-cve .cve-id,
.post-cve .cve-badge {
  flex: 0 0 auto;
}
.post-cve-sum {
  color: var(--muted);
  font-size: 0.8rem;
  /* Basis, not a hard min-width: the summary may wrap onto its own line on
     narrow screens, but it must still be allowed to shrink below its content
     so the ellipsis can do its job. */
  flex: 1 1 12rem;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Share buttons ──────────────────────────────────── */
.share {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin: 2.25rem 0 0;
  padding-top: 1.5rem;
  border-top: 1px solid var(--border);
}
/* Top-of-article placement sits under the byline, so it carries no rule and
   no heading — it must not compete with the headline. */
.share-compact {
  margin: 0.9rem 0 0;
  padding-top: 0;
  border-top: 0;
}
.share-label {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--dim);
}
.share-list {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
}
.share-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--muted);
  cursor: pointer;
  transition:
    color 0.15s ease,
    border-color 0.15s ease,
    background 0.15s ease;
}
.share-compact .share-btn {
  width: 1.75rem;
  height: 1.75rem;
}
.share-btn svg {
  width: 0.95rem;
  height: 0.95rem;
}
.share-compact .share-btn svg {
  width: 0.85rem;
  height: 0.85rem;
}
.share-btn:hover {
  color: var(--fg);
  border-color: currentColor;
}
/* Brand tints on hover only: a row of saturated logos would pull attention
   away from the article itself. */
.share-x:hover {
  color: #e7e9ea;
}
.share-linkedin:hover {
  color: #0a66c2;
}
.share-reddit:hover {
  color: #ff4500;
}
.share-telegram:hover {
  color: #29a9eb;
}
.share-whatsapp:hover {
  color: #25d366;
}
.share-facebook:hover {
  color: #1877f2;
}
.share-copy.is-copied {
  color: #25d366;
  border-color: #25d366;
}

/* ── Pagination ─────────────────────────────────────── */
.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--border);
}
.page-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border-2);
  border-radius: var(--radius-sm);
  padding: 0.5rem 0.8rem;
  transition:
    background 0.15s ease,
    border-color 0.15s ease,
    color 0.15s ease;
}
.page-btn:hover {
  background: hsl(var(--cat-h) 90% 52% / 0.16);
  border-color: hsl(var(--cat-h) 90% 60% / 0.5);
  color: var(--text-max);
}
.page-btn-off {
  opacity: 0.32;
  pointer-events: none;
}
.page-nums {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.page-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 2rem;
  height: 2rem;
  padding: 0 0.45rem;
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--muted);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  transition:
    background 0.15s ease,
    color 0.15s ease,
    border-color 0.15s ease;
}
.page-num:hover {
  color: var(--text);
  background: var(--surface-2);
  border-color: var(--border);
}
.page-num-active {
  color: var(--text-max);
  background: hsl(var(--cat-h) 90% 52% / 0.2);
  border-color: hsl(var(--cat-h) 90% 60% / 0.55);
  font-weight: 700;
}
.page-gap {
  color: var(--dim);
  padding: 0 0.15rem;
  font-family: var(--mono);
}
@media (max-width: 480px) {
  .pagination {
    justify-content: center;
  }
  .page-nums {
    order: -1;
    width: 100%;
    justify-content: center;
  }
}

/* Reading estimate sits next to the date; the CTA stays pinned right. */
.card-read {
  margin-right: auto;
  color: var(--muted);
}

/* The hour, dimmer than the date it follows. Ten stories a day share a date, so
   the clock is what actually orders a card row — but it is the second half of
   one stamp, not a separate field, and it should not read as loud as the date. */
.card-time {
  margin-left: 0.4rem;
  opacity: 0.72;
}

.card-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 0.75rem;
  padding-top: 0.6rem;
  border-top: 1px dashed var(--border);
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--dim);
  letter-spacing: 0.02em;
}
.card-cta {
  color: hsl(var(--cat-h) 95% 70%);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  white-space: nowrap;
  opacity: 0.75;
  transition:
    opacity 0.16s ease,
    transform 0.16s ease;
}
.card:hover .card-cta {
  opacity: 1;
  transform: translateX(2px);
}

/* Featured hero card */
.card-featured {
  border-color: hsl(var(--cat-h) 80% 50% / 0.4);
  background: var(--surface);
}
.card-featured .card-link {
  position: relative;
  display: block;
}
.card-featured .card-media {
  position: absolute;
  inset: 0;
  aspect-ratio: auto;
  border-bottom: 0;
}
.card-featured .card-media .cover {
  height: 100%;
}
.card-overlay {
  position: relative;
  z-index: 1;
  min-height: clamp(320px, 40vw, 430px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 0.55rem;
  padding: clamp(1.3rem, 3vw, 2.2rem);
  background: linear-gradient(
    to top,
    rgba(6, 7, 11, 0.94) 0%,
    rgba(6, 7, 11, 0.78) 38%,
    rgba(6, 7, 11, 0.2) 72%,
    rgba(6, 7, 11, 0) 100%
  );
}
.card-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
}
.card-featured .card-title {
  font-size: clamp(1.45rem, 3.1vw, 2.25rem);
  line-height: 1.14;
  letter-spacing: -0.03em;
  margin: 0;
  max-width: 22ch;
  -webkit-line-clamp: 4;
  text-shadow: 0 2px 20px rgba(0, 0, 0, 0.6);
}
.card-featured .card-excerpt {
  font-size: 0.98rem;
  color: var(--text-2);
  max-width: 62ch;
  -webkit-line-clamp: 2;
}
.card-featured .card-meta {
  border-top-color: rgba(255, 255, 255, 0.14);
  color: var(--muted);
  max-width: 62ch;
}

/* ── Sidebar ────────────────────────────────────────── */
.sidebar {
  min-width: 0;
}
.sidebar-sticky {
  position: sticky;
  top: calc(var(--nav-h) + 1rem);
  display: grid;
  gap: 1.15rem;
}
.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.9rem 1rem 1rem;
}
.panel-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--text);
  margin: 0 0 0.75rem;
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--border);
}
.panel-title::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 1px;
  background: var(--accent);
  transform: rotate(45deg);
  flex: none;
}

.rank-list {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: rank;
}
.rank-item + .rank-item {
  border-top: 1px solid var(--border);
}
.rank-link {
  display: flex;
  gap: 0.65rem;
  padding: 0.6rem 0;
  transition: opacity 0.15s ease;
}
.rank-num {
  font-family: var(--mono);
  font-size: 0.9rem;
  font-weight: 800;
  line-height: 1.35;
  color: var(--dim);
  flex: none;
  width: 1.6em;
  transition: color 0.15s ease;
}
.rank-link:hover .rank-num {
  color: var(--accent);
}
.rank-body {
  display: block;
  min-width: 0;
}
.rank-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.855rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--text-2);
  transition: color 0.15s ease;
}
.rank-link:hover .rank-title {
  color: var(--text-max);
}
.rank-meta {
  display: block;
  margin-top: 0.15rem;
  font-family: var(--mono);
  font-size: 0.65rem;
  color: var(--dim);
}

.cat-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.1rem;
}
.cat-row {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.42rem 0.5rem;
  margin: 0 -0.5rem;
  border-radius: var(--radius-sm);
  font-size: 0.875rem;
  color: var(--text-2);
  transition:
    background 0.15s ease,
    color 0.15s ease;
}
.cat-row:hover {
  background: var(--surface-2);
  color: var(--text-max);
}
.cat-row-active {
  background: var(--surface-3);
  color: var(--text-max);
}
.cat-swatch {
  width: 8px;
  height: 8px;
  border-radius: 2px;
  flex: none;
  box-shadow: 0 0 8px currentColor;
}
.cat-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cat-count {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--dim);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 0.02rem 0.45rem;
}

/* ── Ad slot ────────────────────────────────────────── */
.ad-slot {
  display: grid;
  gap: 0.6rem;
  padding: 0.85rem;
  border: 1px dashed var(--border-2);
  border-radius: var(--radius);
  background: repeating-linear-gradient(
    -45deg,
    rgba(255, 255, 255, 0.014) 0 10px,
    transparent 10px 20px
  );
  text-align: center;
}
.ad-slot-label {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--dim);
}
.ad-slot-box {
  display: block;
  min-height: 120px;
  border-radius: var(--radius-sm);
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.008));
  border: 1px solid var(--border);
}
.post .ad-slot {
  margin: 2.25rem 0 0;
}

/* ── Category page header ───────────────────────────── */
.cat-head {
  position: relative;
  overflow: hidden;
  padding: 1.5rem 1.4rem;
  border: 1px solid hsl(var(--cat-h) 70% 50% / 0.3);
  border-radius: var(--radius);
  background:
    radial-gradient(600px 220px at 8% 0%, hsl(var(--cat-h) 85% 45% / 0.28), transparent 70%),
    linear-gradient(180deg, var(--surface-2), var(--surface));
}
.cat-head::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(to right, rgba(255, 255, 255, 0.035) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
  background-size: 34px 34px;
  pointer-events: none;
  mask-image: linear-gradient(to left, #000, transparent 60%);
  -webkit-mask-image: linear-gradient(to left, #000, transparent 60%);
}
.cat-head .page-title {
  position: relative;
  z-index: 1;
}
.cat-head-meta {
  position: relative;
  z-index: 1;
  margin: 0.35rem 0 0;
  font-family: var(--mono);
  font-size: 0.74rem;
  color: var(--muted);
}

/* ── Article ────────────────────────────────────────── */
.post {
  max-width: 790px;
  margin: 0 auto;
}
.post-cover {
  position: relative;
  height: clamp(170px, 25vw, 300px);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  margin-bottom: 1.5rem;
}
.post-cover-tag {
  position: absolute;
  left: 1rem;
  bottom: 1rem;
  z-index: 1;
}
.post-head {
  border-bottom: 1px solid var(--border);
  padding-bottom: 1.25rem;
  margin-bottom: 1.7rem;
}
.article-audio {
  display: grid;
  grid-template-columns: minmax(12rem, 0.7fr) minmax(15rem, 1fr);
  align-items: center;
  gap: 1rem;
  margin: 0 0 1.7rem;
  padding: 1rem 1.1rem;
  border: 1px solid hsl(var(--cat-h) 70% 55% / 0.3);
  border-radius: var(--radius);
  background: linear-gradient(135deg, hsl(var(--cat-h) 60% 18% / 0.45), var(--surface));
}
.article-audio-copy {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}
.article-audio-copy strong,
.article-audio-copy small {
  display: block;
}
.article-audio-copy strong {
  font-size: 0.94rem;
}
.article-audio-copy small {
  margin-top: 0.18rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.article-audio-icon {
  display: grid;
  place-items: center;
  width: 2.4rem;
  height: 2.4rem;
  flex: 0 0 auto;
  border-radius: 50%;
  color: hsl(var(--cat-h) 90% 72%);
  background: hsl(var(--cat-h) 70% 45% / 0.18);
}
.article-audio audio {
  width: 100%;
  height: 2.4rem;
  color-scheme: dark;
}
@media (max-width: 660px) {
  .article-audio {
    grid-template-columns: 1fr;
  }
}
.post-title {
  font-size: clamp(1.75rem, 4vw, 2.6rem);
  font-weight: 800;
  line-height: 1.12;
  letter-spacing: -0.032em;
  margin: 0 0 0.6rem;
  max-width: 24ch;
}
.post-standfirst {
  margin: 0 0 1rem;
  max-width: 62ch;
  font-size: 1.06rem;
  line-height: 1.55;
  color: var(--muted);
}
.byline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.42rem;
  font-family: var(--mono);
  font-size: 0.74rem;
  color: var(--muted);
}
.byline-author {
  color: hsl(var(--cat-h) 95% 72%);
  font-weight: 700;
  letter-spacing: 0.02em;
}
.byline-sep {
  color: var(--border-2);
}
.ai-disclosure {
  position: relative;
  display: inline-flex;
}
.ai-disclosure-trigger {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 36px;
  padding: 0.22rem 0.5rem;
  border: 1px solid var(--border-2);
  border-radius: 3px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}
.ai-disclosure-trigger:hover,
.ai-disclosure-trigger[aria-expanded='true'] {
  border-color: var(--accent);
}
.ai-disclosure-trigger:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.ai-disclosure-icon {
  display: inline-grid;
  place-items: center;
  width: 1.1rem;
  height: 1.1rem;
  border: 1px solid currentColor;
  border-radius: 50%;
  font-size: 0.65rem;
  font-weight: 700;
  font-style: normal;
}
.ai-disclosure-panel:not([hidden]) {
  position: absolute;
  z-index: 20;
  top: 100%;
  left: 0;
  display: block;
  width: min(320px, calc(100vw - 2.5rem));
  padding: 0.85rem 1rem;
  border: 1px solid var(--border-2);
  border-radius: 4px;
  background: var(--surface-2);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.24);
  color: var(--text-2);
  font-family: var(--sans);
  font-size: 0.82rem;
  font-weight: 400;
  line-height: 1.5;
}
.ai-disclosure-panel a {
  display: inline-block;
  margin-top: 0.5rem;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
@media (max-width: 480px) {
  .ai-disclosure-panel:not([hidden]) {
    left: -6rem;
  }
}

.post-body {
  font-size: 1.055rem;
  line-height: 1.72;
  color: var(--text-2);
  max-width: 68ch;
}
.post-body > p:first-of-type {
  font-size: 1.16rem;
  line-height: 1.62;
  color: var(--text);
  border-left: 2px solid hsl(var(--cat-h) 90% 55% / 0.5);
  padding-left: 1rem;
  margin-bottom: 1.5rem;
}
.post-body h2 {
  font-size: 1.42rem;
  font-weight: 750;
  line-height: 1.25;
  margin: 2.4rem 0 0.85rem;
  padding-left: 0.85rem;
  border-left: 3px solid hsl(var(--cat-h) 92% 58%);
  letter-spacing: -0.02em;
  color: var(--text-max);
}
.post-body h3 {
  font-size: 1.15rem;
  font-weight: 700;
  margin: 1.8rem 0 0.55rem;
  letter-spacing: -0.014em;
  color: var(--text-max);
}
.post-body h4 {
  font-size: 1rem;
  font-weight: 700;
  margin: 1.4rem 0 0.45rem;
  color: var(--text-max);
}
.post-body p {
  margin: 0 0 1.15rem;
}
.post-body a {
  color: var(--accent-2);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition: color 0.15s ease;
}
.post-body a:hover {
  color: #ffb08a;
}
.post-body ul,
.post-body ol {
  padding-left: 1.15rem;
  margin: 0 0 1.2rem;
}
.post-body li {
  margin-bottom: 0.45rem;
  padding-left: 0.2rem;
}
.post-body li::marker {
  color: hsl(var(--cat-h) 92% 62%);
  font-weight: 700;
}
.post-body code {
  font-family: var(--mono);
  font-size: 0.86em;
  background: var(--surface-2);
  border: 1px solid var(--border);
  padding: 0.08rem 0.36rem;
  border-radius: 5px;
  color: #ffd9c9;
  word-break: break-word;
}
.post-body pre {
  position: relative;
  background: linear-gradient(180deg, #12151f, #0d1018);
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  padding: 1.1rem 1.15rem;
  overflow-x: auto;
  margin: 0 0 1.35rem;
  font-size: 0.9rem;
  line-height: 1.6;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.post-body pre code {
  border: 0;
  padding: 0;
  background: none;
  color: #cfd6e6;
  font-size: 0.88rem;
}
.post-body strong {
  color: var(--text-max);
  font-weight: 700;
}
.post-body blockquote {
  margin: 1.6rem 0;
  padding: 0.85rem 1.15rem;
  border-left: 3px solid hsl(var(--cat-h) 92% 58%);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  background: hsl(var(--cat-h) 60% 40% / 0.07);
  color: var(--text);
  font-size: 1.04rem;
}
.post-body blockquote p:last-child {
  margin-bottom: 0;
}
.post-body hr {
  border: 0;
  border-top: 1px solid var(--border);
  margin: 2.2rem 0;
}
.post-body img {
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
}
.post-body table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 1.35rem;
  font-size: 0.92rem;
  display: block;
  overflow-x: auto;
}
.post-body th,
.post-body td {
  border: 1px solid var(--border);
  padding: 0.5rem 0.7rem;
  text-align: left;
}
.post-body th {
  background: var(--surface-2);
  color: var(--text-max);
  font-family: var(--mono);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.post-foot {
  margin-top: 2rem;
}

/* ── Tags ───────────────────────────────────────────── */
.tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.45rem;
  margin: 2.4rem 0 0;
  padding-top: 1.4rem;
  border-top: 1px solid var(--border);
}
.tags-label {
  font-family: var(--mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--dim);
  width: 100%;
  margin-bottom: 0.2rem;
}
.tag {
  font-size: 0.78rem;
  color: var(--muted);
  background: var(--surface-2);
  border: 1px solid var(--border);
  padding: 0.22rem 0.6rem;
  border-radius: 999px;
  transition:
    color 0.15s ease,
    border-color 0.15s ease;
}
.tag:hover {
  color: var(--text);
  border-color: var(--border-2);
}

/* ── Buttons / empty states ─────────────────────────── */
.btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border-2);
  border-radius: 999px;
  padding: 0.5rem 1rem;
  transition:
    background 0.16s ease,
    border-color 0.16s ease,
    transform 0.16s ease;
}
.btn-ghost:hover {
  background: var(--surface-3);
  border-color: hsl(var(--cat-h) 85% 55% / 0.6);
  transform: translateY(-1px);
}

.empty {
  display: grid;
  justify-items: start;
  gap: 0.5rem;
  padding: 2.5rem 1.5rem;
  border: 1px dashed var(--border-2);
  border-radius: var(--radius);
  background: repeating-linear-gradient(
    -45deg,
    rgba(255, 255, 255, 0.012) 0 12px,
    transparent 12px 24px
  );
}
.empty-title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
}
.empty-hint {
  margin: 0 0 0.5rem;
  color: var(--muted);
  font-size: 0.9rem;
  max-width: 50ch;
}

/* ── Footer ─────────────────────────────────────────── */
.site-footer {
  border-top: 1px solid var(--border);
  background: linear-gradient(180deg, var(--surface), var(--bg));
  margin-top: 3.5rem;
}
.footer-inner {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 2.5rem 1.25rem 1.75rem;
  display: grid;
  grid-template-columns: 2.2fr 1fr 1fr;
  gap: 2rem;
}
.footer-brand p {
  color: var(--muted);
  max-width: 46ch;
  margin: 0.7rem 0 0;
  font-size: 0.9rem;
}

.newsletter-signup{margin-top:24px;max-width:420px}.newsletter-signup h3{margin:0 0 6px;color:#f8fafc;font-size:1rem}.newsletter-signup>p{margin:0 0 12px}.newsletter-row{display:flex;gap:8px}.newsletter-row input{min-width:0;flex:1;padding:11px 12px;border:1px solid #334155;border-radius:8px;background:#0b1525;color:#fff}.newsletter-row button{border:0;border-radius:8px;padding:0 15px;background:#38bdf8;color:#06111f;font-weight:800;cursor:pointer}.newsletter-consent{display:flex;gap:7px;align-items:flex-start;margin-top:9px;color:#94a3b8;font-size:.72rem;line-height:1.4}.newsletter-consent input{margin-top:2px}.newsletter-consent a{color:#7dd3fc}.newsletter-trap{position:absolute!important;left:-10000px!important}.newsletter-message{color:#86efac!important;margin-top:8px!important}.newsletter-message.is-error{color:#fca5a5!important}
.newsletter-result{min-height:72vh;display:grid;place-items:center;padding:3rem 1.25rem;position:relative;overflow:hidden}.newsletter-result-glow{position:absolute;width:520px;height:520px;border-radius:50%;background:radial-gradient(circle,rgba(56,189,248,.18),transparent 68%);pointer-events:none}.newsletter-result section{position:relative;width:min(100%,620px);padding:3rem;border:1px solid var(--border);border-radius:22px;background:linear-gradient(145deg,rgba(18,33,53,.98),rgba(7,16,30,.98));box-shadow:0 30px 80px rgba(0,0,0,.35)}.newsletter-result-eyebrow{margin:2.5rem 0 .7rem!important;color:var(--accent)!important;font:700 .72rem/1 var(--mono);letter-spacing:.16em}.newsletter-result h1{font-size:clamp(2rem,6vw,3.4rem);line-height:1.05;margin:0 0 1rem;color:var(--text)}.newsletter-result section>p:not(.newsletter-result-eyebrow){max-width:54ch;color:var(--muted);font-size:1.05rem;line-height:1.7}.newsletter-result section>a{display:inline-block;margin-top:1.2rem;padding:.8rem 1.1rem;border-radius:9px;background:var(--accent);color:#06111f;font-weight:800;text-decoration:none}@media(max-width:560px){.newsletter-result section{padding:2rem 1.4rem}}
.footer-tagline {
  font-family: var(--mono);
  font-size: 0.7rem !important;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim) !important;
}
/* Profile links. Deliberately small: they are a way out of the site, so they
   get found by someone looking for them and ignored by everyone else. */
.social-links {
  display: flex;
  gap: 0.5rem;
  list-style: none;
  margin: 0;
  padding: 0;
}
.social-links a {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--dim);
  transition:
    color 0.15s,
    border-color 0.15s;
}
.social-links a:hover {
  color: var(--accent);
  border-color: var(--accent);
}
.footer-social {
  margin-top: 0.9rem;
}
.footer-col h3 {
  font-family: var(--mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--dim);
  margin: 0 0 0.8rem;
}
.footer-col ul {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: 0.25rem;
}
.footer-col a {
  /* inline-flex with a floor: these were 19px tall, under the 24px minimum
     tap target. The list gap absorbs the extra height, so nothing moves. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Width too: two-letter labels like "AI" and the language codes were 13-17px. */
  min-width: 24px;
  min-height: 24px;
  color: var(--text-2);
  font-size: 0.88rem;
  transition: color 0.15s ease;
}
.footer-col a:hover {
  color: var(--accent);
}
.footer-langs {
  grid-template-columns: repeat(3, auto);
  justify-content: start;
  gap: 0.5rem 1rem !important;
}
.footer-langs a {
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
}
.footer-langs a.is-current {
  color: var(--accent);
  font-weight: 700;
}
.footer-bottom {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 1.1rem 1.25rem;
  border-top: 1px solid var(--border);
  color: var(--dim);
  font-size: 0.76rem;
  font-family: var(--mono);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}
.footer-status {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  letter-spacing: 0.08em;
}

/* ── Responsive ─────────────────────────────────────── */
@media (max-width: 1080px) {
  .home-grid {
    grid-template-columns: minmax(0, 1fr) 290px;
    gap: 1.75rem;
  }
}

@media (max-width: 900px) {
  :root {
    --nav-h: 96px;
  }
  .home-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 2.25rem;
  }
  .sidebar-sticky {
    position: static;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    align-items: start;
  }
}

@media (max-width: 720px) {
  .container {
    padding: 1.4rem 1rem 2.5rem;
  }
  .nav-tagline {
    display: none;
  }
  .nav-date {
    display: none;
  }
  /* Hiding the tagline and date is not enough on a phone: brand + search box +
     five language links still cannot fit one nowrap row, and the header pushed
     the whole document into horizontal scroll. Let the row wrap and give the
     search/language group its own full-width line. */
  .nav-inner {
    gap: 0.85rem;
    flex-wrap: wrap;
  }
  .nav-right {
    flex: 1 1 100%;
    justify-content: space-between;
    gap: 0.6rem;
    min-width: 0;
  }
  .nav-right .searchbox {
    flex: 1 1 auto;
    min-width: 0;
  }
  .lang-switcher {
    flex: 0 0 auto;
  }
  .grid {
    grid-template-columns: 1fr;
  }
  .card-featured .card-title {
    max-width: none;
  }
  .card-featured .card-excerpt {
    display: none;
  }
  .post-title {
    max-width: none;
  }
  .footer-inner {
    grid-template-columns: 1fr 1fr;
  }
  .footer-brand {
    grid-column: 1 / -1;
  }
}

@media (max-width: 480px) {
  .nav-live {
    display: none;
  }
  .sidebar-sticky {
    grid-template-columns: 1fr;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
}

/* Required by the NVD Terms of Use. Quiet, but present on every page built from
   their data — "prominently within the application" is their wording. */
.nvd-notice {
  margin: 2rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--border);
  font-family: var(--mono);
  font-size: 0.7rem;
  line-height: 1.5;
  color: var(--dim);
}

/* ── Leggi anche ────────────────────────────────────────
   Set apart from the article without competing with it: the reader has
   finished, and these are an offer rather than part of the piece. */
.post-related {
  margin: 2.5rem 0 0;
  padding: 1.25rem 1.4rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius-sm);
}
.post-related h2 {
  margin: 0 0 0.75rem;
  font-size: 0.78rem;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}
.post-related ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.6rem;
}
.post-related a {
  font-weight: 650;
  line-height: 1.4;
  color: var(--text-2);
  transition: color 0.15s ease;
}
.post-related a:hover {
  color: var(--accent);
}

/* ════════════════════════════════════════════════════════
   404 — pagina autonoma, porta il proprio documento
   ════════════════════════════════════════════════════════ */
.nf {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0.3rem;
  padding: 2.5rem 1.25rem 3.5rem;
  max-width: 48rem;
  margin: 0 auto;
}
.nf-brand img {
  width: min(28rem, 80vw);
  height: auto;
  border-radius: var(--radius);
  margin-bottom: 1.5rem;
}
.nf-code {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0;
}
.nf-title {
  font-size: clamp(1.6rem, 4.5vw, 2.3rem);
  letter-spacing: -0.02em;
  margin: 0.3rem 0 0;
}
.nf-lead {
  color: var(--muted);
  line-height: 1.6;
  max-width: 34rem;
  margin: 0.7rem 0 2rem;
}
.nf-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9.5rem, 1fr));
  gap: 0.6rem;
  width: 100%;
  max-width: 34rem;
}
.nf-card {
  padding: 0.85rem 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text-2);
  text-decoration: none;
  font-weight: 600;
  font-size: 0.92rem;
  transition:
    border-color 0.15s ease,
    color 0.15s ease;
}
.nf-card:hover {
  border-color: var(--accent);
  color: var(--text);
}
.nf-cats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem;
  margin-top: 1.6rem;
}
.nf-cats a {
  text-decoration: none;
}
.nf-langs {
  display: flex;
  gap: 0.9rem;
  margin-top: 2rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
}
.nf-langs a {
  color: var(--dim);
  text-decoration: none;
}
.nf-langs a:hover {
  color: var(--accent);
}

/* La 404 dentro il sito: sta nel layout, quindi eredita nav e footer. */
.nf-inline {
  max-width: 44rem;
}
.nf-inline h2 {
  font-family: var(--mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--dim);
  margin: 0 0 0.7rem;
}
.nf-search {
  margin: 0 0 2.2rem;
}
/* In navbar la ricerca si stringe accanto al selettore lingua; qui e l'azione
   principale della pagina, quindi prende la larghezza per sembrarlo. */
.nf-search .searchbox,
.nf-search .searchbox input {
  width: 100%;
}
.nf-search .searchbox input {
  font-size: 0.95rem;
  padding: 0.65rem 0.85rem;
}

/* ── Anteprima e contenuto sponsorizzato ────────────────────────────── */
/* Deliberately loud: mistaking a draft for the live page is the failure
   this exists to prevent. */
.post-preview-banner {
  margin: 0 0 1.2rem;
  padding: 0.6rem 0.9rem;
  border: 1px dashed var(--accent);
  border-radius: var(--radius-sm);
  background: rgba(255, 46, 63, 0.08);
  color: var(--text);
  font-family: var(--mono);
  font-size: 0.76rem;
  letter-spacing: 0.04em;
}
.post-disclosure {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
  margin: 0 0 0.7rem;
}
.post-disclosure-tag {
  font-family: var(--mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--bg);
  background: var(--accent-2);
  border-radius: 999px;
  padding: 0.24rem 0.7rem;
  font-weight: 700;
}
.post-disclosure-by {
  font-size: 0.8rem;
  color: var(--muted);
}

/* Il link dello sponsor, fuori dal testo redazionale e sempre marcato. */
.post-sponsor-cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.5rem;
  margin: 2rem 0;
  padding: 1.1rem 1.2rem;
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-left: 3px solid var(--accent-2);
  border-radius: var(--radius-sm);
}
.post-sponsor-btn {
  display: inline-flex;
  align-items: center;
  padding: 0.65rem 1.1rem;
  background-image: linear-gradient(90deg, var(--accent) 0%, var(--accent-2) 100%);
  color: var(--bg);
  font-weight: 700;
  font-size: 0.95rem;
  border-radius: var(--radius-sm);
  text-decoration: none;
}
.post-sponsor-btn:hover {
  filter: brightness(1.08);
}
.post-sponsor-hint {
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--dim);
}

/* ── The KEV catalogue on the home page ──────────────────────────────────── */
/* Between the lead story and the article grid. Framed rather than flowed: the
   grid above and below it is news, this is data, and the border is what tells a
   reader at a glance that they are different kinds of thing. */
.kev-band {
  border: 1px solid rgba(255, 46, 63, 0.34);
  border-radius: var(--radius);
  background: linear-gradient(180deg, rgba(255, 46, 63, 0.06), transparent 55%), var(--surface);
  padding: 1.15rem 1.25rem 1rem;
  margin: 1.25rem 0 0.25rem;
}
.kev-band-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.kev-band-title {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text);
  margin: 0;
}
/* The same live dot the nav uses, for the same reason: this updates daily. */
.kev-band-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--accent);
  box-shadow: 0 0 0 3px rgba(255, 46, 63, 0.16);
  flex: none;
}
.kev-band-headline {
  font-size: 0.95rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--accent);
  margin: 0;
}
.kev-band-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}
.kev-band-stats > div {
  flex: 1 1 7rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 0.6rem 0.75rem;
}
.kev-band-stats strong {
  display: block;
  font-size: 1.35rem;
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.1;
}
.kev-band-stats span {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
}
/* Three across on a wide screen, stacking on a narrow one. Rows rather than
   cards: the band is a summary and a second set of boxes inside a box reads as
   clutter. */
.kev-band-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.85rem;
}
.kev-band-row {
  min-width: 0;
  padding-left: 0.7rem;
  border-left: 2px solid var(--border-2);
}
.kev-band-row-top {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  flex-wrap: wrap;
  margin-bottom: 0.3rem;
}
.kev-band-product {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--muted);
  margin: 0 0 0.25rem;
  overflow-wrap: anywhere;
}
.kev-band-due {
  font-family: var(--mono);
  font-size: 0.66rem;
  color: var(--dim);
  margin: 0;
}
.kev-band-more {
  display: inline-block;
  margin-top: 1rem;
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}
@media (max-width: 860px) {
  .kev-band-list {
    grid-template-columns: 1fr;
    gap: 0.7rem;
  }
}

/* ── Early warning: exploited, not yet catalogued by CISA ─────────────────── */
/* Amber rather than the KEV red. The distinction is the point of the page: red
   is the official catalogue with a legal deadline behind it, amber is evidence
   that has not been made official yet, and the colours must not imply the two
   carry the same weight. */
.nav-cat-early {
  color: var(--chart-warn);
}
.nav-cat-early:hover {
  color: var(--chart-warn);
}
.early-row {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 2px solid rgba(245, 165, 36, 0.55);
  border-radius: var(--radius-sm);
  padding: 0.9rem 1rem;
}
.early-row-top {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  margin-bottom: 0.35rem;
}
/* Telemetry beats a report about a report, so it gets the one badge that reads
   as a fact rather than a claim. */
.early-sensor {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.15rem 0.45rem;
  border-radius: 999px;
  color: #d7f0ff;
  background: rgba(56, 160, 255, 0.16);
  border: 1px solid rgba(56, 160, 255, 0.4);
}
.early-notcisa {
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
  border: 1px dashed var(--border-2);
  border-radius: 999px;
  padding: 0.15rem 0.5rem;
}
.early-meta {
  margin-top: 0.55rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--dim);
}
/* The sources are the argument the page makes, so they are readable rather than
   tucked into a tooltip. */
.early-sources {
  margin: 0.5rem 0 0;
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--muted);
  overflow-wrap: anywhere;
}
.early-sources-label {
  color: var(--dim);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.early-sources a {
  color: var(--text-2);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.early-attribution {
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--muted);
}
/* The one line on a KEV row that is ours rather than CISA's: how long the
   catalogue took. Amber, matching the early-warning page it comes from. */
.kev-lag {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  color: var(--chart-warn);
  margin: 0.45rem 0 0;
}
/* Divides the editorial sections from the vulnerability data.
   flex: none, or it collapses to nothing the moment the row overflows — the
   same shrink behaviour that once painted every category label over its
   neighbour. Margin rather than padding so the gap reads as a break in the row
   and not as space belonging to the CVE link. */
.nav-cats-rule {
  flex: 0 0 auto;
  align-self: center;
  width: 1px;
  height: 1.1em;
  margin: 0 0.35rem;
  background: var(--border-2);
}

/* ── Exploitation-timing analysis ─────────────────────────────────────────── */
.an-lede {
  font-size: clamp(1.05rem, 1.8vw, 1.35rem);
  font-weight: 650;
  line-height: 1.45;
  letter-spacing: -0.01em;
  max-width: 62ch;
  margin: 0 0 1.4rem;
}
.gap-chart {
  margin: 0 0 2rem;
  overflow-x: auto;
}
/* Scrolls inside its own box: two years of columns is wider than a phone, and
   squeezing them would collapse the bars into a smear. */
.gap-chart-svg {
  display: block;
  width: 100%;
  min-width: 520px;
  height: auto;
}
.gap-axis {
  stroke: var(--border-2);
  stroke-width: 1;
}
.chart-grid {
  stroke: var(--border);
  stroke-width: 1;
  opacity: 0.45;
}
.chart-tick,
.month-label {
  font-family: var(--mono);
  font-size: 10px;
  fill: var(--dim);
}

/* ── Legend ───────────────────────────────────────────────────────────────── */
.chart-legend {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--dim);
  margin-bottom: 0.6rem;
}
.legend-key {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  display: inline-block;
}
.legend-key + .legend-key,
.chart-legend .legend-key:not(:first-child) {
  margin-left: 1rem;
}
.legend-total {
  background: var(--chart-warn);
}
.legend-sensor {
  background: var(--chart-sensor);
}

/* ── Bucket chart ─────────────────────────────────────────────────────────── */
.gap-row-hit,
.month-hit {
  fill: transparent;
}
.gap-bar {
  fill: var(--chart-warn);
  transform-origin: left center;
  animation: gap-grow 620ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
/* The one bar meaning somebody was already attacking before anyone knew. */
.gap-bar-before {
  fill: var(--accent);
}
.gap-label,
.gap-value {
  font-family: var(--mono);
  font-size: 11px;
  fill: var(--muted);
  transition: fill 120ms ease;
}
.gap-value {
  fill: var(--text-2);
}
.gap-row:hover .gap-bar {
  filter: brightness(1.18);
}
.gap-row:hover .gap-label,
.gap-row:hover .gap-value {
  fill: var(--text);
}
@keyframes gap-grow {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

/* ── Monthly chart ────────────────────────────────────────────────────────── */
.month-bar {
  fill: var(--chart-warn);
  transform-origin: center bottom;
  animation: month-grow 560ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
}
/* The current month is not comparable with a finished one, so it is not drawn
   like one. */
.month-bar-partial {
  fill: none;
  stroke: var(--chart-warn);
  stroke-width: 1;
  stroke-dasharray: 3 2;
}
/* A subset of the month, so it reads as part of the same bar rather than as a
   second series. Darker than the whole, never brighter: it used to be the
   lighter colour and the part looked like the total. */
.month-bar-sensor {
  fill: var(--chart-sensor);
  animation: month-grow 560ms cubic-bezier(0.2, 0.8, 0.2, 1) both;
  transform-origin: center bottom;
}
.month-value {
  font-family: var(--mono);
  font-size: 10px;
  fill: var(--text);
  opacity: 0;
  transition: opacity 120ms ease;
}
/* Twenty-four permanent labels at this width would overlap into a smear, so the
   value appears where the reader is pointing. */
.month-col:hover .month-value {
  opacity: 1;
}
.month-col:hover .month-bar {
  filter: brightness(1.2);
}
.month-col:hover .month-label {
  fill: var(--text-2);
}
@keyframes month-grow {
  from {
    transform: scaleY(0);
  }
  to {
    transform: scaleY(1);
  }
}
/* Motion is decoration here; the chart is complete without it. */
@media (prefers-reduced-motion: reduce) {
  .gap-bar,
  .month-bar,
  .month-bar-sensor {
    animation: none;
  }
}

/* ── Vendors ──────────────────────────────────────────────────────────────── */
.gap-caption {
  font-size: 0.78rem;
  color: var(--dim);
  max-width: 70ch;
  margin-top: 0.6rem;
  line-height: 1.5;
}
.gap-caption-note {
  color: var(--muted);
}
.an-vendors {
  list-style: none;
  margin: 0 0 2rem;
  padding: 0;
}
.an-vendors li {
  display: grid;
  grid-template-columns: 10rem minmax(0, 1fr) 3.5rem;
  align-items: center;
  gap: 0.6rem;
  padding: 0.3rem 0;
}
.an-vendor-name {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--text-2);
  overflow-wrap: anywhere;
}
.an-vendor-bar {
  height: 10px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--accent), rgba(255, 46, 63, 0.35));
}
.an-vendor-count {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--text-2);
  text-align: right;
}
.an-caveats {
  color: var(--text-2);
  max-width: 72ch;
  line-height: 1.6;
  padding-left: 1.1rem;
}
.an-caveats li {
  margin-bottom: 0.55rem;
}
@media (max-width: 640px) {
  .an-vendors li {
    grid-template-columns: 7rem minmax(0, 1fr) 3rem;
  }
}
/* Neither red nor amber: this one is not a warning, it is the arithmetic. */
.nav-cat-analysis {
  color: var(--text-2);
}

/* ── Citation block ───────────────────────────────────────────────────────── */
.an-cite {
  border-top: 1px solid var(--border);
  margin-top: 2.5rem;
  padding-top: 1.4rem;
  max-width: 72ch;
}
.an-cite h2 {
  font-size: 1.05rem;
  margin-bottom: 0.4rem;
}
.an-updated {
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--dim);
  margin: 0 0 0.9rem;
}
/* Monospace and selectable-looking: this block exists to be copied, so it should
   read as a thing you copy rather than as prose. */
.an-citation {
  font-family: var(--mono);
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--text-2);
  background: var(--surface);
  border-left: 2px solid var(--accent);
  border-radius: var(--radius-sm);
  padding: 0.8rem 1rem;
  margin: 0.6rem 0 1rem;
  overflow-wrap: anywhere;
}
.an-license {
  font-size: 0.82rem;
  color: var(--text-2);
}
.an-data-link {
  font-family: var(--mono);
  font-size: 0.76rem;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ── Light theme: what the inversion breaks ───────────────────────────────── */
/*
 * Two things do not follow the page, and both were wrong on the first pass.
 *
 * Text over a cover sits on `.card-overlay`, which is a dark gradient scrim on
 * top of a dark illustration. That scrim is dark in both themes, so the text on
 * it stays light in both — inheriting the page's near-black made the lead
 * story's headline unreadable on its own front page.
 */
:root[data-theme='light'] .card-overlay,
:root[data-theme='light'] .card-overlay .card-title,
:root[data-theme='light'] .card-overlay .card-title a,
:root[data-theme='light'] .card-overlay .card-excerpt,
:root[data-theme='light'] .card-overlay .card-meta,
:root[data-theme='light'] .card-overlay .card-read,
:root[data-theme='light'] .card-overlay .card-cta {
  color: #eef0f6;
}
:root[data-theme='light'] .card-overlay .card-excerpt,
:root[data-theme='light'] .card-overlay .card-meta {
  color: #d5d9e4;
}

/*
 * Badges are built from `--cat-h` as a light tint on a translucent wash: 74%
 * lightness text over 14% alpha. That reads on near-black and washes out to
 * nothing on white, and `.cve-badge strong` was pure white on a pale pink —
 * the severity score, invisible, on a security site.
 *
 * The hue is kept and the lightness inverted, so a category still carries its
 * own colour and CRITICAL still reads as red.
 */
:root[data-theme='light'] .badge,
:root[data-theme='light'] .cve-badge {
  color: hsl(var(--cat-h) 75% 30%);
  background: hsl(var(--cat-h) 85% 45% / 0.1);
  border-color: hsl(var(--cat-h) 70% 45% / 0.35);
}
:root[data-theme='light'] .cve-badge strong {
  color: hsl(var(--cat-h) 80% 24%);
}
/**
 * Except the badges that sit on a cover, which are not on the page at all.
 *
 * The rule above inverts a category badge for a white background, and that is
 * right everywhere a badge sits on the page. On a card it sits on
 * `.card-overlay` — a dark scrim over a dark illustration — where the inverted
 * form is a dark red on 10% red over a near-black photo, which is invisible.
 * The exception list a few rules up already spared the title, the excerpt and
 * the meta for exactly this reason; the badge was left out of it.
 *
 * These restore the dark-theme values rather than inventing new ones: the
 * surface underneath is the same in both themes, so the treatment that works
 * there is the one that already works.
 *
 * Only the lead card is affected. Every other card labels its cover with
 * `.card-media-tag`, which was already left alone for the same reason.
 *
 * `:not(.badge-live)` because this selector outranks the live badge's own rule
 * — four classes against three — and without it the first version of this fix
 * stripped "In evidenza" of the solid red it is supposed to keep in both
 * themes. Specificity beats source order, so the exception has to be stated.
 */
:root[data-theme='light'] .card-overlay .badge:not(.badge-live) {
  color: hsl(var(--cat-h) 95% 74%);
  background: hsl(var(--cat-h) 90% 52% / 0.14);
  border-color: hsl(var(--cat-h) 90% 60% / 0.38);
}
:root[data-theme='light'] .card-overlay a.badge:not(.badge-live):hover {
  background: hsl(var(--cat-h) 90% 52% / 0.26);
  color: #fff;
}

/* Except the live badge, which is solid dark red with white on it already and
   passes on either background. */
:root[data-theme='light'] .badge-live {
  color: #fff;
  background: #c20f20;
  border-color: #c20f20;
}
/* Tinted category headers use the same trick and need the same correction. */
:root[data-theme='light'] .cat-head {
  color: var(--text);
}

/*
 * The ambient glows come off.
 *
 * Two radial gradients sit at the top of the body — a red one and a blue one —
 * giving a near-black page some depth. On white they are grey smudges bleeding
 * down from the masthead, which is not depth, it is dirt. A light page gets its
 * separation from borders and surfaces instead.
 */
:root[data-theme='light'] body {
  background-image: none;
}

/* ── Light theme: the pills and the code ──────────────────────────────────── */
/*
 * Five more colours that were only ever going to work on near-black. All of
 * them are near-white text over a translucent wash — a pattern that reads well
 * on a dark page and turns into an empty pill on a white one. Two of these
 * shipped: the sensor badge on the early-warning page had no visible label at
 * all, and a CVSS vector inside an article was pale grey on pale grey.
 *
 * Fixed by darkening the ink and leaving the wash, so the badge keeps its
 * colour coding — red still means ransomware, blue still means telemetry.
 * Contrast measured against the washed background rather than against pure
 * white, since that is what the text actually sits on: 7.3, 7.9, 6.2, 6.7 and
 * 14.0 to 1.
 */
:root[data-theme='light'] .kev-ransom {
  color: #9b1120;
  background: rgba(255, 46, 63, 0.09);
  border-color: rgba(155, 17, 32, 0.35);
}
:root[data-theme='light'] .early-sensor {
  color: #0f4c81;
  background: rgba(56, 160, 255, 0.11);
  border-color: rgba(15, 76, 129, 0.32);
}
:root[data-theme='light'] .post-body a:hover {
  color: #a83a10;
}
/* Inline code carries CVE ids, versions and CVSS vectors — the facts an article
   exists to deliver. It cannot be the least readable thing on the page. */
:root[data-theme='light'] .post-body code {
  color: #9a3412;
  background: #f4f5f8;
  border-color: var(--border-2);
}
:root[data-theme='light'] .post-body pre {
  background: #f2f3f7;
  border-color: var(--border-2);
}
:root[data-theme='light'] .post-body pre code {
  color: #1f2430;
}

/*
 * Two colours built as light tints, which cannot survive the inversion.
 *
 * `.cve-has-articles` was hsl(148 70% 62%) on a 14% green wash — a light green
 * on near-white, measuring 1.42:1, so "4 articoli correlati" was a blank pill.
 * `.kicker` was 68% lightness of the category hue and came in at 2.89. Both keep
 * their hue and swap their lightness: the section still reads red, the coverage
 * pill still reads green.
 */
:root[data-theme='light'] .cve-has-articles {
  color: hsl(148 78% 22%);
  background: hsl(148 60% 40% / 0.1);
  border-color: hsl(148 55% 30% / 0.32);
}
:root[data-theme='light'] .kicker {
  color: hsl(var(--cat-h) 85% 32%);
}

/*
 * The last three category-hue tints.
 *
 * All built at 62-72% lightness, which is correct on near-black and unreadable
 * on white. Found by sweeping the stylesheet for hue-derived text colours rather
 * than by looking at pages, after two of them turned up one at a time.
 *
 * `.card-cta` also carries opacity: 0.75, and that is what made it the worst of
 * the set at 1.68:1 — a translucent light green over white. The opacity comes off
 * in light mode: even at 22% lightness the green hue only reaches 3.88 through
 * 0.75 alpha, while at 28% opaque the worst hue on the site clears 4.98. The
 * de-emphasis it was providing is carried by the hover transform, which is
 * already there.
 */
:root[data-theme='light'] .card-cta {
  color: hsl(var(--cat-h) 80% 28%);
  opacity: 1;
}
:root[data-theme='light'] .byline-author {
  color: hsl(var(--cat-h) 80% 28%);
}
:root[data-theme='light'] .post-body li::marker {
  color: hsl(var(--cat-h) 80% 34%);
}

/* The wordmark doubles as the front page's <h1>. An <h1> brings a font size
   and a block margin the masthead never had, so both are handed back: the
   element changes, the page does not. */
.brand-heading {
  margin: 0;
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  display: contents;
}

/* ── Exploitation panel on a CVE page ──────────────────────────────────────
   The one block on that page carrying something NVD does not publish, so it
   is allowed to be the loudest thing above the fold. Two states: listed by
   CISA, and seen in the wild before CISA caught up — different colours because
   they are different claims, and a reader has to be able to tell which one
   they are reading. */
.expl {
  border: 1px solid;
  border-radius: var(--radius);
  padding: 1rem 1.15rem;
  margin: 0 0 1.5rem;
}
.expl-kev {
  border-color: hsl(354 80% 55% / 0.45);
  background: hsl(354 80% 50% / 0.07);
}
.expl-early {
  border-color: hsl(38 90% 55% / 0.45);
  background: hsl(38 90% 50% / 0.07);
}
.expl-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 0.6rem;
  font-family: var(--mono);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.expl-kev .expl-head {
  color: hsl(354 90% 70%);
}
.expl-early .expl-head {
  color: hsl(38 92% 62%);
}
:root[data-theme='light'] .expl-kev .expl-head {
  color: hsl(354 75% 38%);
}
:root[data-theme='light'] .expl-early .expl-head {
  color: hsl(32 90% 30%);
}
.expl-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  /* No animation. A pulsing dot on a page that says somebody is being attacked
     is decoration pretending to be urgency. */
  flex: 0 0 auto;
}
.expl-facts {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.35rem;
  font-size: 0.92rem;
  line-height: 1.45;
}
.expl-facts li {
  padding-left: 1.1rem;
  position: relative;
}
.expl-facts li::before {
  content: '›';
  position: absolute;
  left: 0;
  color: var(--dim);
}
/* The deadline and the "before disclosure" line are the two facts worth
   reading twice, so they are the only ones that carry weight. */
.expl-due,
.expl-before {
  font-weight: 600;
}
.expl-ransom {
  color: hsl(354 85% 68%);
}
:root[data-theme='light'] .expl-ransom {
  color: hsl(354 75% 38%);
}
.expl-action {
  margin: 0.7rem 0 0;
  font-size: 0.88rem;
  color: var(--text-2);
}
.expl-source {
  margin: 0.7rem 0 0;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--muted);
}
.expl-source a {
  color: var(--muted);
  text-decoration: underline;
}
.expl-source a:hover {
  color: var(--text);
}

/* ── Language suggestion bar ───────────────────────────────────────────────
   Shown only to a reader whose browser asks for one of the other four
   languages, in place of the automatic redirect the bare domain used to do.
   Sits under the navbar rather than fixed to the viewport: it is an offer, not
   a notification, and it must not cover the first screen of an article. */
.lang-suggest {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  /* Matches .container's gutter without being inside it: the bar sits between
     the navbar and <main>, so it has no padded parent to inherit from. */
  max-width: min(var(--maxw), 100% - 2.5rem);
  margin: 0.75rem auto 0;
  padding: 0.6rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-2);
  font-size: 0.9rem;
}

.lang-suggest-text {
  margin: 0;
  flex: 1 1 12rem;
  color: var(--muted);
}

.lang-suggest-go {
  font-weight: 600;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.lang-suggest-close {
  /* A 44px target: this is the control a reader who does not want the bar
     reaches for, and on a phone it is the easiest one to miss. */
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--muted);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
}

.lang-suggest-close:hover {
  color: var(--text);
}

/* ── "This article is also in your language", inside the article ───────────
   The card version of .lang-suggest, sitting between the byline and the first
   paragraph. Deliberately quieter than a callout: it is an aside about the
   page, not part of the piece, so it borrows the surface colour rather than the
   accent and keeps the same width as the prose it interrupts. */
.lang-card {
  position: relative;
  margin: 0 0 1.6rem;
  padding: 1.1rem 3rem 1.2rem 1.2rem;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-2);
}

.lang-card-hello {
  margin: 0 0 0.35rem;
  font-weight: 700;
  color: var(--text);
}

.lang-card-text {
  margin: 0 0 0.6rem;
  color: var(--text-2);
}

.lang-card-go {
  font-weight: 600;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.lang-card-close {
  /* Absolute so the close control sits in the corner the eye checks first,
     without pushing the two lines of text into a narrower column. */
  position: absolute;
  top: 0.35rem;
  right: 0.35rem;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  border: 0;
  background: none;
  color: var(--muted);
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
}

.lang-card-close:hover {
  color: var(--text);
}
/* Analysis charts: direct labels, touch selection and a readable data alternative. */
.analysis-chart {
  margin: 0 0 2rem;
  padding: clamp(1rem, 3vw, 2rem);
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: 16px;
  box-shadow: 0 12px 36px rgb(0 0 0 / 0.06);
}
.analysis-chart .gap-caption {
  max-width: none;
  font-size: 0.875rem;
  color: var(--muted);
  margin-top: 1.5rem;
}
.distribution-heading,
.distribution-label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}
.distribution-heading {
  color: var(--muted);
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--border);
}
.distribution-heading strong {
  color: var(--text);
  font-family: var(--mono);
}
.distribution-list {
  list-style: none;
  margin: 1.5rem 0 0;
  padding: 0;
  display: grid;
  gap: 1.3rem;
}
.distribution-label {
  margin-bottom: 0.5rem;
  font-size: 0.95rem;
  color: var(--text-2);
}
.distribution-label > span:last-child {
  display: flex;
  gap: 1rem;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}
.distribution-label small {
  width: 4rem;
  text-align: right;
  color: var(--muted);
}
.distribution-track {
  height: 14px;
  border-radius: 4px;
  background: var(--surface-3);
  overflow: hidden;
}
.distribution-track > span {
  display: block;
  height: 100%;
  background: var(--chart-warn);
  border-radius: inherit;
}
.distribution-before .distribution-track > span {
  background: var(--accent);
}
.analysis-toolbar {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  align-items: center;
  flex-wrap: wrap;
}
.analysis-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  color: var(--text-2);
  font-size: 0.8rem;
}
.analysis-legend > span {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.analysis-legend i {
  display: inline-block;
  width: 12px;
  height: 12px;
  border-radius: 3px;
}
.chart-ranges {
  display: flex;
  padding: 3px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 9px;
}
.chart-ranges button {
  min-width: 44px;
  min-height: 44px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font: inherit;
}
.chart-ranges button[aria-pressed='true'] {
  background: var(--text);
  color: var(--surface);
}
.month-detail {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.6rem 1.5rem;
  padding: 1rem 0;
  margin: 1rem 0;
  border-block: 1px solid var(--border);
  font-size: 0.85rem;
  color: var(--muted);
  min-height: 70px;
}
.month-detail > strong {
  color: var(--text);
  margin-right: auto;
  text-transform: capitalize;
}
.month-detail b {
  color: var(--text);
  font-variant-numeric: tabular-nums;
}
.month-detail small {
  display: inline-block;
  margin-left: 0.6rem;
  border: 1px dashed var(--chart-warn);
  color: var(--text-2);
  padding: 0.2rem 0.4rem;
  border-radius: 4px;
}
.monthly-plot {
  display: flex;
  height: 300px;
  gap: 0.7rem;
}
.monthly-scale {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding-bottom: 52px;
  width: 3rem;
  flex-shrink: 0;
  font: 0.75rem var(--mono);
  text-align: right;
  color: var(--muted);
}
.monthly-columns {
  display: grid;
  flex: 1;
  min-width: 0;
  background: repeating-linear-gradient(
      to top,
      transparent 0,
      transparent calc(25% - 1px),
      var(--border) calc(25% - 1px),
      var(--border) 25%
    )
    top / 100% calc(100% - 52px) no-repeat;
}
.monthly-column {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 0;
  padding: 0 3px;
  border: 0;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
}
.monthly-bar-space {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  height: calc(100% - 52px);
  width: 100%;
  border-bottom: 1px solid var(--border-2);
}
.monthly-bar-fill {
  display: block;
  position: relative;
  width: 70%;
  max-width: 40px;
  background: var(--chart-warn);
  border-radius: 5px 5px 0 0;
  min-height: 0;
  transition: filter 0.15s ease;
}
.monthly-sensor-fill {
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  background: var(--chart-sensor);
}
.monthly-bar-fill.is-partial {
  background: transparent;
  border: 2px dashed var(--chart-warn);
}
.monthly-column.is-selected {
  background: var(--surface-2);
  color: var(--text);
  border-radius: 6px;
}
.monthly-column:hover .monthly-bar-fill {
  filter: brightness(1.15);
}
.monthly-date {
  height: 52px;
  padding-top: 0.6rem;
  font: 0.7rem var(--mono);
  writing-mode: vertical-rl;
}
.chart-data {
  margin-top: 1.5rem;
  border-top: 1px solid var(--border);
}
.chart-data summary {
  cursor: pointer;
  padding: 1rem 0;
  color: var(--text-2);
  min-height: 44px;
}
.chart-data table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}
.chart-data th,
.chart-data td {
  padding: 0.7rem 0.4rem;
  text-align: right;
  border-bottom: 1px solid var(--border);
}
.chart-data th:first-child {
  text-align: left;
}
.chart-ranges button:focus-visible,
.monthly-column:focus-visible,
.chart-data summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
@media (max-width: 640px) {
  .monthly-plot {
    height: 260px;
    gap: 0.3rem;
  }
  .monthly-scale {
    width: 2rem;
  }
  .monthly-column {
    padding-inline: 1px;
  }
  .monthly-bar-fill {
    width: 85%;
  }
  .distribution-label {
    font-size: 0.85rem;
  }
  .distribution-label > span:last-child {
    gap: 0.4rem;
  }
  .distribution-label small {
    width: 3.2rem;
  }
  .month-detail > strong {
    flex-basis: 100%;
  }
}
@media (prefers-reduced-motion: reduce) {
  .monthly-bar-fill {
    transition: none;
  }
}
/* CVE workspace: shared navigation, hierarchy and responsive evidence cards. */
.cve-workspace {
  --workspace-accent: var(--chart-warn);
}
.cve-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  font-size: 0.8rem;
  color: var(--muted);
  margin-bottom: 1rem;
}
.cve-breadcrumb a {
  color: var(--text-2);
}
.cve-tool-nav {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.75rem;
  margin-bottom: 2rem;
}
.cve-tool-nav > a {
  padding: 1.1rem;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface);
  display: grid;
  align-content: start;
  gap: 0.55rem;
  transition:
    border-color 0.15s ease,
    background 0.15s ease;
}
.cve-tool-nav > a:hover {
  border-color: var(--workspace-accent, var(--chart-warn));
  background: var(--surface-2);
}
.cve-tool-nav > a[aria-current='page'] {
  border-color: var(--workspace-accent, var(--chart-warn));
  box-shadow: inset 0 3px var(--workspace-accent, var(--chart-warn));
}
.cve-tool-index {
  font: 0.7rem var(--mono);
  color: var(--chart-warn);
}
.cve-tool-nav strong {
  color: var(--text);
  font-size: 1rem;
}
.cve-tool-nav a > span:last-child {
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.5;
}
.cve-workspace .cve-hero {
  padding: clamp(1.25rem, 3vw, 2.5rem);
  background: linear-gradient(120deg, var(--surface-2), var(--surface));
  border: 1px solid var(--border-2);
  border-radius: 16px;
  margin-bottom: 1.5rem;
}
.cve-workspace .page-title {
  max-width: 24ch;
  font-size: clamp(2rem, 4vw, 3.5rem);
  line-height: 1.08;
  letter-spacing: -0.035em;
}
.cve-hero-description {
  max-width: 72ch;
  color: var(--text-2);
  line-height: 1.7;
  margin: 1rem 0 0;
}
.cve-workspace .kev-headline {
  font-size: clamp(1.2rem, 2.5vw, 1.8rem);
  color: var(--text);
}
.cve-workspace .kev-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}
.cve-workspace .kev-stats > div {
  border-radius: 12px;
  padding: 1.4rem;
  border-top: 3px solid var(--workspace-accent);
}
.cve-workspace .kev-stats strong {
  font-size: clamp(2rem, 4vw, 3rem);
  margin-bottom: 0.6rem;
  font-variant-numeric: tabular-nums;
}
.cve-workspace .kev-stats span {
  color: var(--muted);
  letter-spacing: 0.02em;
  font-size: 0.75rem;
}
.cve-workspace .kev-intro {
  font-size: 1rem;
  line-height: 1.7;
  max-width: 80ch;
}
.cve-workspace .kev-list,
.cve-workspace .cve-list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
}
.cve-workspace .kev-row,
.cve-workspace .early-row,
.cve-workspace .cve-row {
  border-radius: 12px;
  border: 1px solid var(--border-2);
  background: var(--surface);
  min-width: 0;
}
.cve-workspace .kev-row,
.cve-workspace .early-row,
.cve-workspace .cve-row-link {
  padding: 1.3rem;
}
.cve-workspace .cve-row:hover {
  transform: none;
}
.cve-workspace .cve-id {
  font-size: 1rem;
  letter-spacing: -0.02em;
}
.cve-workspace .cve-summary {
  display: block;
  overflow: visible;
  font-size: 0.92rem;
  line-height: 1.65;
  color: var(--text-2);
  margin-top: 0.8rem;
}
.cve-workspace .kev-product {
  margin-top: 0.7rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text);
}
.cve-workspace .kev-row-meta,
.cve-workspace .early-meta,
.cve-workspace .cve-row-meta {
  margin-top: 1rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border);
  font-size: 0.75rem;
  color: var(--muted);
}
.cve-workspace .early-sources {
  font-size: 0.8rem;
  line-height: 1.8;
  overflow-wrap: anywhere;
}
.cve-workspace .early-sources a {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.cve-workspace .kev-ransom,
.cve-workspace .early-sensor,
.cve-workspace .early-notcisa {
  font-size: 0.7rem;
  color: var(--text-2);
}
.cve-workspace .kev-section {
  font-size: 0.85rem;
  color: var(--text-2);
  letter-spacing: 0.07em;
}
.cve-workspace .kev-about {
  max-width: none;
  padding: 1.5rem;
  border: 1px solid var(--border-2);
  border-radius: 12px;
  background: var(--surface);
  font-size: 0.95rem;
  line-height: 1.7;
}
.cve-workspace .kev-about h2 {
  font-size: 1.35rem;
  color: var(--text);
}
.cve-workspace .cve-filter-bar {
  padding: 1.2rem;
  border: 1px solid var(--border-2);
  background: var(--surface);
  border-radius: 12px;
  margin-bottom: 1.5rem;
}
.cve-workspace .cve-filter {
  min-height: 36px;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.8rem;
}
.cve-local-search {
  margin: 1.5rem 0;
}
.cve-local-search label {
  display: block;
  font-size: 0.9rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}
.cve-local-search > div {
  display: flex;
  gap: 0.6rem;
}
.cve-local-search input[type='search'] {
  min-width: 0;
  flex: 1;
  padding: 0.85rem 1rem;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border-2);
  border-radius: 8px;
  font: inherit;
}
.cve-local-search button {
  border: 1px solid var(--border-2);
  background: var(--text);
  color: var(--surface);
  border-radius: 8px;
  padding: 0.8rem 1.3rem;
  font: inherit;
  cursor: pointer;
}
.cve-tool-nav a:focus-visible,
.cve-local-search :focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
@media (max-width: 800px) {
  .cve-tool-nav {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .cve-workspace .kev-list,
  .cve-workspace .cve-list {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 480px) {
  .cve-tool-nav > a {
    padding: 0.85rem;
  }
  .cve-tool-nav strong {
    font-size: 0.9rem;
  }
  .cve-workspace .kev-stats {
    grid-template-columns: 1fr;
    gap: 0.6rem;
  }
  .cve-workspace .kev-stats > div {
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 1rem;
  }
  .cve-workspace .kev-stats strong {
    margin: 0;
    min-width: 4rem;
  }
  .cve-workspace .cve-date {
    margin-left: 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .cve-tool-nav > a {
    transition: none;
  }
}

/* CyberWorldOps editorial identity. Shared by both themes and all public pages. */
.page-ellipsis { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; min-height: 36px; color: var(--muted); }
@media (max-width: 760px) {
  .pagination { flex-wrap: wrap; gap: 12px; }
  .pagination .page-nums { order: -1; flex-basis: 100%; justify-content: center; flex-wrap: wrap; }
  .pagination .page-num { min-width: 32px; min-height: 44px; }
}
:root {
  --bg: #090d14;
  --bg-2: #0d121c;
  --surface: #111824;
  --surface-2: #182231;
  --surface-3: #223046;
  --text: #f2f5fa;
  --text-2: #d6deeb;
  --muted: #a7b4c8;
  --dim: #9eacc1;
  --accent: #5599ff;
  --accent-2: #5599ff;
  --border: #263246;
  --border-2: #3c4d66;
  --radius: 4px;
  --radius-sm: 3px;
  --maxw: 1200px;
  --brand-primary: #2563eb;
}
:root[data-theme='light'] {
  --bg: #ffffff;
  --bg-2: #f5f7fb;
  --surface: #fff;
  --surface-2: #f0f4fa;
  --surface-3: #e6edf7;
  --text: #101b2c;
  --text-2: #344259;
  --muted: #52617a;
  --dim: #52617a;
  --accent: #185dcc;
  --accent-2: #185dcc;
  --border: #dde4ee;
  --border-2: #bac8db;
}
body,
:root[data-theme='light'] body {
  background: var(--bg);
}
.brand {
  align-items: center;
  font-size: 1.7rem;
  gap: 0.5rem;
  letter-spacing: -0.055em;
}
.brand-mark {
  display: flex;
  filter: none;
  color: var(--brand-primary);
}
.brand-symbol {
  width: 42px;
  height: 42px;
  flex: none;
}
.brand-accent {
  color: var(--text);
}
.nav {
  position: relative;
}
.nav-utility {
  max-width: var(--maxw);
  margin: auto;
  padding: 0.55rem 1.25rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px solid var(--border);
  font: 0.65rem var(--mono);
  color: var(--muted);
}
.nav-top {
  border: 0;
}
.nav-inner {
  padding: 1.2rem 1.25rem;
  gap: 1.4rem;
}
.nav-inner-cats {
  padding: 0.7rem 1.25rem;
}
.nav-bar {
  background: none;
}
.nav-tagline {
  font-family: var(--sans);
  text-transform: none;
  letter-spacing: 0.015em;
  font-size: 0.72rem;
}
.nav-right {
  gap: 0.75rem;
}
.nav-right .searchbox {
  width: 155px;
}
.nav-newsletter {
  background: var(--brand-primary);
  color: #ffffff;
  padding: 0.7rem 0.9rem;
  font-size: 0.75rem;
  font-weight: 750;
  border-radius: 3px;
}
.theme-toggle {
  flex: none;
  border-color: var(--border-2);
  color: var(--text);
}
.nav-cats {
  gap: 1.3rem;
}
.magazine {
  padding-bottom: 1rem;
}
.mag-intro {
  margin-bottom: 1.5rem;
}
.mag-headline {
  margin: 0 0 0.45rem;
  font-size: clamp(1.65rem, 3vw, 2.6rem);
  line-height: 1.14;
  letter-spacing: -0.045em;
}
.mag-intro p {
  max-width: 75ch;
  margin: 0;
  color: var(--text-2);
  font-size: clamp(0.92rem, 1.2vw, 1.05rem);
  line-height: 1.6;
}
.mag-opening {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(260px, 1fr);
  gap: 2rem;
  align-items: stretch;
}
.mag-story {
  min-width: 0;
}
.mag-story-link {
  display: block;
  color: var(--text);
  text-decoration: none;
}
.mag-image {
  aspect-ratio: 1.9;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--border);
}
.mag-image .cover,
.mag-image picture,
.mag-image .cover-photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.mag-category {
  display: block;
  color: var(--accent);
  font-size: 0.65rem;
  font-weight: 750;
  text-transform: uppercase;
  letter-spacing: 0.045em;
  margin: 0.7rem 0 0.3rem;
}
.mag-story h3 {
  margin: 0;
  letter-spacing: -0.03em;
  line-height: 1.2;
}
.mag-story a:hover h3,
.mag-top a:hover {
  color: var(--accent);
}
.mag-lead h3 {
  font-size: clamp(1.55rem, 2.6vw, 2.3rem);
}
.mag-lead p {
  margin: 0.7rem 0;
  font-size: 1rem;
  line-height: 1.6;
  color: var(--text-2);
}
.mag-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.7rem;
  color: var(--muted);
  font-size: 0.65rem;
  margin-top: 0.6rem;
}
.mag-watch {
  padding: 1.35rem;
  background: var(--surface);
  border: 1px solid var(--border);
}
.mag-watch > h2 {
  margin: 0;
  font-size: 1.3rem;
  letter-spacing: -0.025em;
}
.mag-watch > h2:before,
.mag-resources > h2:before,
.mag-top h2:before {
  content: '';
  display: block;
  width: 30px;
  height: 3px;
  background: var(--accent);
  margin-bottom: 0.7rem;
}
.mag-watch .kev-band {
  margin: 0.8rem 0 0;
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
}
.mag-watch .kev-band-title,
.mag-watch .kev-band-stats {
  display: none;
}
.mag-watch .kev-band-head {
  display: block;
  margin-bottom: 0.7rem;
}
.mag-watch .kev-band-headline {
  font-size: 0.8rem;
  line-height: 1.5;
}
.mag-watch .kev-band-list {
  display: block;
}
.mag-watch .kev-band-row {
  padding: 1rem 0;
  border: 0;
  border-top: 1px solid var(--border);
}
.mag-watch .kev-band-row-top {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}
.mag-watch .kev-band-more {
  display: block;
  font-size: 0.8rem;
  color: var(--accent);
  margin-top: 0.8rem;
}
.mag-secondary-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1.3rem;
  margin: 2rem 0;
}
.mag-secondary h3 {
  font-size: 1rem;
}
.mag-section-heading {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  border-top: 1px solid var(--border-2);
  padding-top: 1rem;
  margin-bottom: 1rem;
}
.mag-section-heading h2,
.mag-resources > h2 {
  margin: 0;
  font-size: 1.5rem;
  letter-spacing: -0.03em;
}
.mag-section-heading > span {
  font-size: 0.75rem;
  color: var(--muted);
}
.mag-compact-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: 2rem;
}
.mag-compact {
  border-bottom: 1px solid var(--border);
  padding: 0.85rem 0;
}
.mag-compact .mag-story-link {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  gap: 1rem;
  align-items: start;
}
.mag-compact .mag-image {
  aspect-ratio: 1.65;
}
.mag-compact .mag-category {
  margin: 0 0 0.25rem;
  font-size: 0.6rem;
}
.mag-compact h3 {
  font-size: 0.95rem;
  line-height: 1.35;
}
.mag-compact .mag-meta {
  margin-top: 0.4rem;
  font-size: 0.6rem;
}
.mag-top {
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 1.5rem;
  margin: 2rem 0;
}
.mag-top-heading {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 1.5rem;
  margin-bottom: 1.2rem;
}
.mag-top h2 {
  margin: 0;
  font-size: 1.35rem;
  letter-spacing: -0.025em;
}
.mag-top-heading p {
  margin: 0;
  color: var(--muted);
  font-size: 0.74rem;
  line-height: 1.5;
  max-width: 37ch;
}
.mag-top-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 2rem;
}
.mag-top-period h3 {
  margin: 0 0 0.65rem;
  font-size: 0.95rem;
}
.mag-top-period ol {
  list-style: none;
  padding: 0;
  margin: 0;
}
.mag-top-period li {
  display: flex;
  align-items: baseline;
  gap: 0.8rem;
  padding: 0.75rem 0;
  border-top: 1px solid var(--border);
}
.mag-top-rank {
  color: var(--accent);
  font-family: var(--mono);
  font-size: 0.72rem;
  flex: none;
}
.mag-top-period li > div {
  min-width: 0;
}
.mag-top-period a {
  font-size: 0.82rem;
  font-weight: 650;
  line-height: 1.4;
}
.mag-top-period li p {
  margin: 0.35rem 0 0;
  color: var(--muted);
  font-size: 0.65rem;
}
.mag-resources-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1rem;
  margin-top: 1rem;
}
.mag-resource {
  display: flex;
  align-items: start;
  gap: 0.8rem;
  padding: 1rem;
  background: var(--surface);
  border: 1px solid var(--border);
}
.mag-resource:hover {
  border-color: var(--accent);
}
.mag-resource-symbol {
  color: var(--accent);
  font-size: 1.8rem;
  line-height: 1.2;
  font-weight: 800;
}
.mag-resource h3 {
  margin: 0;
  font-size: 0.9rem;
  line-height: 1.4;
}
.mag-resource p {
  color: var(--muted);
  font-size: 0.75rem;
  line-height: 1.5;
  margin: 0.4rem 0;
}
.mag-resource-go {
  font-size: 0.7rem;
}
.post {
  max-width: 820px;
}
.post-title {
  font-size: clamp(1.9rem, 4vw, 3rem);
  line-height: 1.12;
  letter-spacing: -0.04em;
}
.post-cover {
  height: auto;
  aspect-ratio: 1.9;
  border-radius: 2px;
}
.post-cover picture,
.post-cover .cover,
.post-cover img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.post-head {
  border: 0;
  margin-bottom: 1.4rem;
  padding: 0;
}
.post-body {
  font-size: 1.075rem;
  line-height: 1.85;
}
.post-body h2 {
  letter-spacing: -0.025em;
}
.post-body blockquote,
.article-audio {
  background: var(--surface);
  border-color: var(--border);
  border-left: 3px solid var(--accent);
}
.post-body pre {
  background: var(--surface);
}
.card,
.intel-card,
.panel {
  box-shadow: none;
}
.cat-head,
.intel-hub,
.site-footer {
  background: var(--surface);
}
.cat-head:before,
.cat-head:after {
  display: none;
}
.footer-newsletter {
  max-width: var(--maxw);
  margin: auto;
  padding: 1.5rem 1.25rem;
  border-bottom: 1px solid var(--border);
}
.footer-newsletter .newsletter-signup {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 3rem;
  max-width: none;
  margin: 0;
}
.footer-newsletter .newsletter-signup h3 {
  color: var(--text);
  margin: 0;
  font-size: 1.25rem;
}
.footer-newsletter .newsletter-signup > p {
  grid-column: 1;
  color: var(--muted);
}
.footer-newsletter .newsletter-signup form {
  grid-column: 2;
  grid-row: 1 / span 2;
}
.newsletter-row button,
.page-num-active,
.badge-live {
  background: var(--brand-primary);
  color: #ffffff;
  border-color: var(--brand-primary);
}
.footer-brand .brand {
  font-size: 1.4rem;
}
.footer-inner {
  grid-template-columns: 1.7fr 1fr 1.25fr 0.55fr;
}
.newsletter-row input {
  background: var(--bg);
  color: var(--text);
  border-color: var(--border);
}
.newsletter-consent,
.newsletter-consent a {
  color: var(--muted);
}
.footer-brand .brand-symbol {
  width: 32px;
  height: 32px;
}
.brand-mark svg {
  overflow: visible;
}
a:focus-visible,
button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}
@media (max-width: 1100px) {
  .nav-tagline {
    display: none;
  }
  .mag-opening {
    gap: 1.4rem;
  }
  .mag-resources-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 760px) {
  .footer-inner {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .footer-brand {
    grid-column: 1 / -1;
  }
  .brand {
    font-size: 1.4rem;
  }
  .nav-inner {
    flex-wrap: wrap;
    gap: 0.75rem;
    padding: 0.85rem 1rem;
  }
  .nav-right {
    flex: 1 1 100%;
    justify-content: space-between;
  }
  .nav-right .searchbox {
    flex: 1;
    width: auto;
  }
  .nav-about {
    display: none;
  }
  .mag-opening {
    grid-template-columns: 1fr;
  }
  .mag-secondary-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
  }
  .mag-compact-grid {
    grid-template-columns: 1fr;
  }
  .mag-top {
    padding: 1.1rem;
  }
  .mag-top-heading {
    display: block;
  }
  .mag-top-heading p {
    margin-top: 0.5rem;
  }
  .mag-top-grid {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }
  .mag-watch .kev-band-list {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1rem;
  }
  .mag-watch .kev-band-row {
    min-width: 0;
  }
  .footer-newsletter .newsletter-signup {
    display: block;
  }
  .footer-newsletter .newsletter-signup form {
    margin-top: 1rem;
  }
}
@media (max-width: 480px) {
  .mag-headline {
    font-size: 1.65rem;
  }
  .mag-watch .kev-band-list {
    display: block;
  }
  .mag-compact .mag-story-link {
    grid-template-columns: 96px minmax(0, 1fr);
    gap: 0.7rem;
  }
  .mag-resources-grid {
    grid-template-columns: 1fr;
  }
  .mag-secondary h3 {
    font-size: 0.95rem;
  }
  .mag-meta {
    font-size: 0.6rem;
  }
  .nav-utility {
    padding: 0.5rem 1rem;
  }
  .post-body {
    font-size: 1rem;
  }
}
@media (prefers-reduced-motion: reduce) {
  .magazine *,
  .brand * {
    transition: none !important;
  }
}

/* Navigation uses visible groups on desktop and a disclosure on small screens. */
.nav-right {
  margin-left: auto;
  flex-shrink: 0;
}
.nav-tagline {
  white-space: normal;
  overflow: visible;
  line-height: 1.5;
}
.nav-right .searchbox {
  width: 260px;
  border-radius: 6px;
}
.nav-right .searchbox input {
  width: 100%;
  min-width: 0;
  max-width: none;
  flex: 1;
  padding: 0.65rem 0.75rem;
}
.nav-right .searchbox button {
  min-width: 44px;
  min-height: 44px;
  flex: none;
  padding: 0;
}
.searchbox:focus-within {
  border-color: var(--accent);
}
.theme-toggle {
  width: 44px;
  height: 44px;
}
.nav-newsletter {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.site-navigation {
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.navigation-panels {
  max-width: var(--maxw);
  margin: auto;
  padding: 0 1.25rem;
}
.navigation-group {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding: 0.35rem 0;
}
.navigation-group + .navigation-group {
  border-top: 1px solid var(--border);
}
.navigation-group-label {
  color: var(--muted);
  font-size: 0.7rem;
  font-weight: 650;
  width: 130px;
  flex: none;
}
.navigation-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.4rem;
  min-width: 0;
}
.navigation-links a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0.55rem 0.7rem;
  font-size: 0.82rem;
  font-weight: 650;
  color: var(--text-2);
  border-radius: 5px;
  white-space: normal;
  overflow-wrap: anywhere;
  line-height: 1.4;
}
.navigation-links a:hover,
.navigation-links a[aria-current='page'] {
  color: var(--accent);
  background: var(--surface-2);
}
.navigation-mobile-bar {
  display: none;
}
.nav-utility .lang-switcher a {
  min-height: 32px;
  min-width: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
@media (max-width: 1100px) {
  .nav-tagline {
    display: none;
  }
}
@media (max-width: 900px) {
  .nav-top .nav-inner {
    flex-wrap: wrap;
    gap: 0.85rem;
  }
  .nav-right {
    flex: 1 1 100%;
  }
  .nav-right .searchbox {
    flex: 1;
    width: auto;
    min-width: 0;
  }
  .navigation-mobile-bar {
    max-width: var(--maxw);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.35rem 1rem;
  }
  .navigation-mobile-bar > a {
    min-height: 44px;
    display: flex;
    align-items: center;
    color: var(--accent);
    font-weight: 650;
    font-size: 0.85rem;
  }
  .navigation-trigger {
    display: inline-flex;
    gap: 0.65rem;
    align-items: center;
    min-height: 44px;
    padding: 0.5rem 0.8rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
  }
  .navigation-panels {
    display: none;
    padding: 0 1rem 1rem;
  }
  .site-navigation.is-open .navigation-panels {
    display: block;
  }
  .navigation-group {
    display: block;
    padding: 0.85rem 0;
  }
  .navigation-group-label {
    display: block;
    width: auto;
    margin: 0 0 0.6rem;
    font-size: 0.75rem;
  }
  .navigation-links {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }
  .navigation-links a {
    border: 1px solid var(--border);
    background: var(--surface);
    padding: 0.7rem;
  }
  .nav-utility {
    gap: 0.5rem;
    font-size: 0.6rem;
  }
  .nav-utility .lang-switcher {
    gap: 2px;
  }
  .nav-utility .lang-switcher a {
    min-width: 28px;
    min-height: 36px;
  }
}
@media (max-width: 480px) {
  .nav-right {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 44px;
    gap: 8px;
  }
  .nav-right .nav-newsletter {
    display: none;
  }
  .nav-right .searchbox {
    width: 100%;
  }
}

.dossier-directory {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
  margin: 32px 0;
}
.dossier-card {
  display: flex;
  flex-direction: column;
  padding: 26px;
}
.dossier-card h2 {
  font-size: 2rem;
  margin: 12px 0;
}
.dossier-card .dossier-button {
  margin-top: auto;
  align-self: flex-start;
}
.dossier-date {
  color: var(--muted);
  font-size: 0.85rem;
  margin: 12px 0 24px;
}
.dossier-highlights {
  list-style: none;
  padding: 0;
  margin: 0 0 24px;
}
.dossier-highlights li {
  padding: 14px 0;
  border-top: 1px solid var(--border);
  line-height: 1.5;
}
.dossier-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 44px;
  padding: 10px 18px;
  border: 1px solid var(--brand-primary);
  border-radius: var(--radius);
  background: var(--brand-primary);
  color: #fff;
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}
.dossier-button:hover {
  background: #1d4ed8;
  color: #fff;
}
.dossier-topics,
.dossier-jumps {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 20px 0;
}
.dossier-topics a,
.dossier-jumps a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 16px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-2);
}
.dossier-topics a[aria-current],
.dossier-topics a:hover,
.dossier-jumps a:hover {
  background: var(--surface-2);
  border-color: var(--accent);
  color: var(--accent);
}
.dossier-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
  padding: 24px 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.dossier-stats div {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.dossier-stats strong {
  font-size: 2rem;
  line-height: 1;
  color: var(--accent);
}
.dossier-stats span {
  color: var(--muted);
  font-size: 0.9rem;
}
.dossier-browser,
.dossier-vulnerabilities {
  scroll-margin-top: 24px;
}
.dossier-filters {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: 16px;
  padding: 24px;
  margin: 28px 0;
  background: var(--surface-2);
  border: 1px solid var(--border);
}
.dossier-filters label {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text);
}
.dossier-filters input,
.dossier-filters select {
  width: 100%;
  min-height: 46px;
  padding: 10px 12px;
  border: 1px solid var(--border-2);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font: inherit;
}
.dossier-filter-actions {
  grid-column: 1/-1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 20px;
}
.dossier-filter-actions > a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.dossier-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 300px;
  gap: 32px;
  align-items: start;
}
.dossier-layout-full {
  grid-template-columns: 1fr;
}
.dossier-results-heading {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 20px;
  font-size: 1.3rem;
}
.dossier-results-heading span {
  color: var(--muted);
  font-size: 1rem;
}
.dossier-reports {
  list-style: none;
  padding: 0;
  margin: 0;
}
.dossier-reports > li {
  display: grid;
  grid-template-columns: 128px minmax(0, 1fr);
  gap: 20px;
  padding: 24px 0;
  border-top: 1px solid var(--border);
}
.dossier-thumbnail {
  align-self: start;
  display: block;
  overflow: hidden;
  border: 1px solid var(--border);
}
.dossier-thumbnail .cover-photo {
  width: 100%;
  height: auto;
  display: block;
}
.dossier-report-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  color: var(--muted);
  font-size: 0.78rem;
}
.dossier-reports h3 {
  margin: 8px 0;
  font-size: 1.13rem;
  line-height: 1.45;
}
.dossier-reports p {
  font-size: 0.9rem;
  color: var(--text-2);
  line-height: 1.65;
  margin: 0;
}
.dossier-report-cves {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}
.dossier-report-cves a,
.tag-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: 8px;
  color: var(--accent);
}
.dossier-report-cves a {
  font-size: 0.78rem;
}
.dossier-vulnerabilities {
  padding: 24px;
  border: 1px solid var(--border);
  background: var(--surface);
}
.dossier-vulnerabilities h2 {
  font-size: 1.2rem;
  margin: 0 0 12px;
}
.dossier-vulnerabilities p {
  color: var(--muted);
  font-size: 0.85rem;
  line-height: 1.65;
}
.dossier-vulnerabilities ul {
  list-style: none;
  margin: 20px 0 0;
  padding: 0;
}
.dossier-vulnerabilities li {
  border-top: 1px solid var(--border);
  padding: 12px 0;
}
.dossier-cve-id {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  gap: 8px;
  font-weight: 700;
  font-size: 0.9rem;
}
.dossier-cve-signals {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.dossier-cve-signals span {
  font-size: 0.7rem;
  background: var(--surface-2);
  color: var(--text-2);
  padding: 4px 6px;
  border: 1px solid var(--border);
}
.dossier-coverage-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--accent);
  font-size: 0.8rem;
}
.dossier-method {
  margin-top: 32px;
}
.dossier-method summary,
.dossier-vulnerabilities summary {
  cursor: pointer;
  padding: 12px 0;
  min-height: 44px;
  font-weight: 600;
}
.dossier-method p {
  color: var(--muted);
  line-height: 1.7;
}
.dossier-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  border-top: 1px solid var(--border);
  padding: 20px 0;
  font-size: 0.85rem;
}
.dossier-pagination a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 8px 12px;
  border: 1px solid var(--border);
}
.dossier-pagination [aria-disabled] {
  opacity: 0.5;
}
.dossier-empty {
  padding: 28px;
  border: 1px solid var(--border);
  background: var(--surface);
}
.dossier-empty p {
  color: var(--muted);
}
.dossier-filters :focus-visible,
.dossier-topics a:focus-visible,
.dossier-jumps a:focus-visible,
.dossier-button:focus-visible,
.tag-link:focus-visible,
.dossier-vulnerabilities :focus-visible,
.dossier-pagination a:focus-visible,
.dossier-method summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}
@media (max-width: 1000px) {
  .dossier-directory {
    grid-template-columns: 1fr;
  }
  .dossier-filters {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .dossier-search {
    grid-column: 1/-1;
  }
  .dossier-layout {
    grid-template-columns: minmax(0, 1fr) 270px;
    gap: 24px;
  }
  .dossier-layout-full {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 760px) {
  .dossier-layout {
    grid-template-columns: 1fr;
  }
  .dossier-filters {
    grid-template-columns: 1fr;
    padding: 18px;
  }
  .dossier-stats {
    gap: 12px;
  }
  .dossier-stats span {
    font-size: 0.78rem;
  }
  .dossier-reports > li {
    grid-template-columns: 1fr;
    gap: 14px;
  }
  .dossier-thumbnail {
    width: 128px;
  }
  .dossier-pagination {
    font-size: 0.78rem;
  }
  .dossier-card {
    padding: 22px;
  }
}

.story-layout {
  display: grid;
  grid-template-columns: minmax(0, 820px) 300px;
  gap: 48px;
  align-items: start;
}
.story-layout > .post {
  max-width: none;
  margin: 0;
  min-width: 0;
}
.story-sidebar {
  position: sticky;
  top: var(--story-sidebar-top, 24px);
  display: flex;
  flex-direction: column;
  gap: 28px;
  min-width: 0;
}
.story-side-panel {
  padding: 22px;
  background: var(--surface);
  border: 1px solid var(--border);
}
.story-side-panel h2 {
  font-size: 1.2rem;
  line-height: 1.4;
  margin: 0 0 12px;
  letter-spacing: -0.025em;
}
.story-side-panel h2::before {
  content: '';
  display: block;
  width: 30px;
  height: 3px;
  margin-bottom: 16px;
  background: var(--accent);
}
.story-week-list,
.story-resource-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.story-week-list li,
.story-resource-list li {
  border-top: 1px solid var(--border);
}
.story-week-link {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  gap: 12px;
  padding: 16px 0;
  min-height: 44px;
}
.story-week-image {
  display: block;
  aspect-ratio: 1.9;
  overflow: hidden;
  border: 1px solid var(--border);
}
.story-week-image picture,
.story-week-image img,
.story-week-image .cover {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.story-week-rank {
  display: block;
  font-family: var(--mono);
  font-size: 0.7rem;
  color: var(--accent);
  margin-bottom: 5px;
}
.story-week-title {
  display: block;
  font-size: 0.88rem;
  line-height: 1.55;
  font-weight: 650;
}
.story-week-link time {
  display: block;
  margin-top: 8px;
  font-size: 0.72rem;
  color: var(--muted);
}
.story-resource-list a {
  display: grid;
  grid-template-columns: 30px minmax(0, 1fr);
  gap: 12px;
  padding: 18px 0;
  min-height: 44px;
}
.story-resource-symbol {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: 1px solid var(--border);
  color: var(--accent);
  font-size: 1rem;
}
.story-resource-list strong {
  display: block;
  font-size: 0.92rem;
  line-height: 1.5;
}
.story-resource-description {
  display: block;
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.65;
  margin-top: 6px;
}
.story-resource-explore {
  display: block;
  color: var(--accent);
  font-size: 0.8rem;
  margin-top: 10px;
}
.story-latest {
  margin: 48px 0 16px;
  padding-top: 32px;
  border-top: 1px solid var(--border);
}
.story-latest-heading {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 24px;
}
.story-latest-heading h2 {
  margin: 0;
  font-size: 1.6rem;
  letter-spacing: -0.025em;
}
.story-latest-heading > a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--accent);
  font-size: 0.85rem;
}
.story-latest-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 24px;
}
.story-latest-card {
  min-width: 0;
}
.story-latest-link {
  display: flex;
  flex-direction: column;
  height: 100%;
}
.story-latest-image {
  display: block;
  position: relative;
  aspect-ratio: 1.9;
  overflow: hidden;
  border: 1px solid var(--border);
  margin-bottom: 16px;
}
.story-latest-image picture,
.story-latest-image img,
.story-latest-image .cover {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.story-latest-category {
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.story-latest-card h3 {
  font-size: 1rem;
  line-height: 1.55;
  margin: 8px 0 10px;
}
.story-latest-card p {
  font-size: 0.85rem;
  line-height: 1.65;
  color: var(--muted);
  margin: 0 0 16px;
}
.story-latest-card time {
  color: var(--muted);
  font-size: 0.75rem;
  margin-top: auto;
}
.story-sidebar a:hover,
.story-latest a:hover h3 {
  color: var(--accent);
}
.story-sidebar a:focus-visible,
.story-latest a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}
@media (max-width: 1050px) {
  .story-layout {
    grid-template-columns: minmax(0, 1fr);
  }
  .story-layout > .post {
    max-width: 820px;
    width: 100%;
    margin: 0 auto;
  }
  .story-sidebar {
    position: static;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    max-width: 820px;
    width: 100%;
    margin: 0 auto;
  }
  .story-latest-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 600px) {
  .story-sidebar,
  .story-latest-grid {
    grid-template-columns: 1fr;
  }
  .story-layout {
    gap: 32px;
  }
  .story-side-panel {
    padding: 20px;
  }
  .story-latest-card {
    padding-bottom: 24px;
    border-bottom: 1px solid var(--border);
  }
  .story-week-link {
    grid-template-columns: 88px minmax(0, 1fr);
  }
}

.dossier-menu {
  position: relative;
  min-width: 0;
}
.dossier-menu summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 44px;
  padding: 0.55rem 0.7rem;
  border-radius: 5px;
  cursor: pointer;
  font-size: 0.82rem;
  font-weight: 650;
  color: var(--text-2);
  list-style: none;
}
.dossier-menu summary::-webkit-details-marker {
  display: none;
}
.dossier-menu summary:hover,
.dossier-menu[open] summary,
.dossier-menu[data-active] summary {
  color: var(--accent);
  background: var(--surface-2);
}
.dossier-menu[open] summary svg {
  transform: rotate(180deg);
}
.dossier-menu summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}
.dossier-menu-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 4px);
  z-index: 70;
  width: min(480px, calc(100vw - 32px));
  max-height: min(600px, 70vh);
  overflow-y: auto;
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.22);
}
.dossier-menu-panel h3 {
  margin: 18px 8px 8px;
  color: var(--muted);
  font-size: 0.72rem;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.dossier-menu-panel ul {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 4px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.dossier-menu-panel .dossier-menu-all {
  color: var(--accent);
  border-bottom: 1px solid var(--border);
  border-radius: 0;
}
@media (max-width: 800px) {
  .navigation-links > .dossier-menu {
    grid-column: 1 / -1;
  }
  .dossier-menu summary {
    padding: 0.7rem;
    background: var(--surface);
    border: 1px solid var(--border);
  }
  .dossier-menu-panel {
    position: static;
    width: 100%;
    max-height: none;
    margin-top: 8px;
    box-shadow: none;
    padding: 12px;
  }
}

.tools-hub,
.tool-page {
  padding: 36px 0 24px;
  min-width: 0;
}
.tools-hero {
  max-width: 820px;
  margin-bottom: 32px;
}
.tools-hero h1 {
  font-size: clamp(2rem, 4vw, 3.2rem);
  line-height: 1.15;
  letter-spacing: -0.04em;
  margin: 12px 0 18px;
}
.tools-hero > p {
  color: var(--text-2);
  font-size: 1.1rem;
  line-height: 1.75;
  max-width: 720px;
}
.tool-hub-meta {
  display: flex;
  gap: 22px;
  flex-wrap: wrap;
  font: 0.75rem var(--mono);
  color: var(--muted);
  margin-top: 24px;
}
.tool-hub-meta span:before {
  content: '';
  display: inline-block;
  width: 5px;
  height: 5px;
  background: var(--accent);
  margin: 0 8px 2px 0;
}
.tools-directory {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
}
.tool-card {
  padding: 28px;
  background: var(--surface);
  border: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  min-width: 0;
  transition:
    border-color 0.2s,
    background 0.2s;
}
.tool-card:hover {
  border-color: var(--accent);
  background: var(--surface-2);
}
.tool-card-top {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--accent);
  margin-bottom: 24px;
}
.tool-number {
  font: 0.75rem var(--mono);
  color: var(--dim);
}
.tool-card h2 {
  font-size: 1.25rem;
  line-height: 1.4;
  letter-spacing: -0.025em;
  margin: 0 0 12px;
}
.tool-card p {
  color: var(--muted);
  line-height: 1.7;
  margin: 0 0 24px;
}
.tool-card-bottom {
  display: flex;
  gap: 16px;
  justify-content: space-between;
  align-items: center;
  margin-top: auto;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  font-size: 0.8rem;
}
.tool-card-bottom > span {
  color: var(--muted);
}
.tool-card-bottom strong {
  color: var(--accent);
}
.tool-hub-links {
  margin-top: 36px;
  padding: 28px 0;
  border-top: 1px solid var(--border);
}
.tool-hub-links h2 {
  font-size: 1.2rem;
  margin: 0 0 16px;
}
.tool-hub-links a {
  display: inline-block;
  color: var(--accent);
  margin: 0 24px 12px 0;
  min-height: 44px;
}
.tool-back {
  display: inline-flex;
  align-items: center;
  color: var(--muted);
  min-height: 44px;
  margin-bottom: 22px;
}
.tool-heading-icon {
  color: var(--accent);
  margin-bottom: 16px;
}
.tool-workspace {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 24px;
  margin-bottom: 40px;
}
.tool-panel {
  padding: 28px;
  border: 1px solid var(--border);
  background: var(--surface);
  min-width: 0;
}
.tool-panel-top {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 24px;
}
.tool-panel-top h2 {
  font-size: 1.25rem;
  line-height: 1.4;
  margin: 0;
}
.tool-step {
  font: 0.8rem var(--mono);
  color: var(--accent);
}
.tool-form {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.tool-form label,
.tool-metrics label {
  font-size: 0.9rem;
  font-weight: 600;
}
.tool-form input,
.tool-form textarea,
.tool-form select,
.tool-metrics select {
  background: var(--bg-2);
  color: var(--text);
  border: 1px solid var(--border-2);
  padding: 13px 14px;
  border-radius: var(--radius-sm);
  width: 100%;
  min-width: 0;
  font: 0.95rem var(--mono);
  line-height: 1.6;
}
.tool-form textarea {
  resize: vertical;
}
.tool-form input,
.tool-form select,
.tool-metrics select {
  min-height: 48px;
}
.tool-form textarea::placeholder,
.tool-form input::placeholder {
  color: var(--dim);
}
.tool-actions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 12px 0;
}
.tool-primary,
.tool-secondary,
.tool-text-button {
  min-height: 44px;
  padding: 11px 18px;
  cursor: pointer;
  border-radius: var(--radius-sm);
  font: 600 0.85rem var(--sans);
  transition: background 0.15s;
}
.tool-primary {
  background: var(--brand-primary);
  color: #fff;
  border: 1px solid var(--brand-primary);
}
.tool-primary:hover {
  filter: brightness(1.12);
}
.tool-secondary {
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border-2);
}
.tool-secondary:hover {
  background: var(--surface-3);
}
.tool-text-button {
  background: transparent;
  color: var(--muted);
  border: 0;
}
.tool-actions button:disabled {
  opacity: 0.6;
  cursor: wait;
}
.tool-privacy,
.tool-muted {
  color: var(--muted);
  font-size: 0.85rem;
  line-height: 1.7;
}
.tool-error,
.tool-notice {
  padding: 14px 16px;
  background: var(--bg-2);
  border-left: 3px solid var(--accent);
  color: var(--text-2);
  line-height: 1.7;
  margin: 8px 0;
}
.tool-findings {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
  margin: 24px 0;
}
.tool-finding,
.tool-cve {
  padding: 22px;
  border: 1px solid var(--border);
  background: var(--bg-2);
  min-width: 0;
}
.tool-finding header,
.tool-cve header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  flex-wrap: wrap;
}
.tool-finding h3,
.tool-cve h3 {
  font-size: 1rem;
  margin: 0;
  line-height: 1.5;
}
.tool-finding p,
.tool-cve p {
  font-size: 0.9rem;
  line-height: 1.75;
  color: var(--text-2);
}
.tool-badge {
  font: 0.7rem var(--mono);
  padding: 5px 8px;
  border: 1px solid var(--border-2);
  color: var(--muted);
  display: inline-block;
}
.tool-state-present .tool-badge {
  color: var(--accent);
  border-color: var(--accent);
}
.tool-state-review {
  border-left: 3px solid var(--border-2);
}
.tool-code,
.tool-finding pre,
.tool-target code,
.tool-results li code {
  overflow-wrap: anywhere;
  white-space: pre-wrap;
  font: 0.8rem var(--mono);
  line-height: 1.7;
}
.tool-finding pre,
.tool-code {
  display: block;
  background: var(--surface-2);
  padding: 14px;
  margin: 12px 0;
  border: 1px solid var(--border);
  max-height: 300px;
  overflow: auto;
}
.tool-finding summary,
.tool-results summary {
  cursor: pointer;
  min-height: 44px;
  display: flex;
  align-items: center;
  font-size: 0.85rem;
  color: var(--accent);
}
.tool-target {
  display: flex;
  align-items: center;
  gap: 16px;
  flex-wrap: wrap;
}
.tool-target code {
  min-width: 0;
}
.tool-cve-list {
  display: flex;
  flex-direction: column;
  gap: 18px;
  margin: 24px 0;
}
.tool-cve a {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.tool-cve li {
  font-size: 0.9rem;
  line-height: 1.7;
  margin: 8px 0;
}
.tool-stat-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px;
  margin: 24px 0;
}
.tool-stat-grid span {
  display: block;
  font: 0.7rem var(--mono);
  color: var(--muted);
  margin-bottom: 8px;
}
.tool-stat-grid strong {
  font-size: 1.1rem;
}
.tool-indicators {
  margin: 24px 0;
  border-top: 1px solid var(--border);
}
.tool-indicators > div {
  display: grid;
  grid-template-columns: 90px minmax(0, 1fr);
  gap: 18px;
  align-items: start;
  padding: 15px 0;
  border-bottom: 1px solid var(--border);
}
.tool-indicators code {
  overflow-wrap: anywhere;
  font: 0.85rem var(--mono);
  line-height: 1.7;
}
.tool-indicators .tool-badge {
  text-align: center;
}
.tool-score-number {
  font-size: 4.5rem;
  letter-spacing: -0.06em;
  font-weight: 750;
  color: var(--accent);
  margin: 16px 0;
}
.tool-score-number span {
  font-size: 1.3rem;
  color: var(--muted);
  letter-spacing: 0;
  margin-left: 14px;
}
.tool-score h2 {
  font-size: 1.4rem;
}
.tool-method {
  border-top: 1px solid var(--border);
  padding-top: 28px;
  max-width: 900px;
}
.tool-method h2 {
  font-size: 1.4rem;
}
.tool-method h3 {
  font-size: 1rem;
  margin-top: 24px;
}
.tool-method p {
  font-size: 0.95rem;
  line-height: 1.8;
  color: var(--muted);
}
.tool-method a {
  display: inline-block;
  min-height: 44px;
  color: var(--accent);
  margin-right: 24px;
}
.tool-other {
  display: flex;
  gap: 16px 28px;
  flex-wrap: wrap;
  margin-top: 32px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
  font-size: 0.85rem;
}
.tool-other a {
  color: var(--accent);
  min-height: 44px;
}
.tools-hub a:focus-visible,
.tool-page a:focus-visible,
.tool-page button:focus-visible,
.tool-page input:focus-visible,
.tool-page textarea:focus-visible,
.tool-page select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}
.tool-metrics {
  border: 0;
  padding: 0;
  margin: 24px 0 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 18px;
}
.tool-metrics legend {
  font-weight: 700;
  margin-bottom: 18px;
}
.tool-metrics select {
  display: block;
  margin-top: 8px;
  font-family: var(--sans);
}
.tool-advanced details {
  border-top: 1px solid var(--border);
  margin-top: 24px;
  padding-top: 8px;
}
.tool-advanced summary {
  padding: 12px 0;
  min-height: 44px;
  cursor: pointer;
  font-weight: 600;
}
.tool-advanced summary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}
.tool-url-destination {
  border-left: 3px solid var(--accent);
  background: var(--bg-2);
  padding: 16px 20px;
  margin: 24px 0;
}
.tool-url-destination h3 {
  margin-top: 0;
}
.tool-url-destination code {
  font-size: 1.2rem;
  overflow-wrap: anywhere;
}
.tool-url-fields {
  margin: 16px 0 28px;
}
.tool-url-fields > div {
  display: grid;
  grid-template-columns: minmax(100px, 0.3fr) minmax(0, 1fr);
  gap: 16px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}
.tool-url-fields dt {
  font-size: 0.85rem;
  color: var(--muted);
  overflow-wrap: anywhere;
}
.tool-url-fields dd {
  margin: 0;
  min-width: 0;
  overflow-wrap: anywhere;
}
.tool-url-fields code {
  font-size: 0.85rem;
}
.tool-url-fields p {
  margin-bottom: 0;
}
.tool-finding h4 {
  font-size: 1rem;
  margin: 0;
}
@media (min-width: 1000px) {
  .tool-workspace:has(.tool-score) {
    grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  }
  .tool-score {
    align-self: start;
    position: sticky;
    top: 24px;
  }
}
@media (max-width: 900px) {
  .tools-directory {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .tool-findings {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 600px) {
  .tools-directory {
    grid-template-columns: 1fr;
  }
  .tool-card,
  .tool-panel {
    padding: 22px;
  }
  .tools-hub,
  .tool-page {
    padding-top: 24px;
  }
  .tool-stat-grid {
    gap: 12px;
  }
  .tool-stat-grid strong {
    font-size: 0.95rem;
  }
  .tool-metrics {
    grid-template-columns: 1fr;
  }
  .tool-indicators > div {
    grid-template-columns: 72px minmax(0, 1fr);
    gap: 12px;
  }
  .tool-hub-meta {
    gap: 14px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .tool-card,
  .tool-primary,
  .tool-secondary {
    transition: none;
  }
}

.editorial-lede {
  max-width: 850px;
  color: var(--text-2);
  font-size: 1.15rem;
  line-height: 1.75;
  margin: 0 0 2rem;
}
.editorial-directory {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem;
}
.editorial-card {
  min-width: 0;
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.editorial-card > a {
  display: block;
}
.editorial-card img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
}
.editorial-card-copy {
  padding: 1.5rem;
}
.editorial-card h2 {
  font-size: 1.65rem;
  margin: 0.5rem 0;
}
.editorial-card p,
.editorial-method p,
.editorial-bio {
  color: var(--text-2);
  line-height: 1.75;
}
.editorial-role {
  font-weight: 650;
  color: var(--text) !important;
}
.editorial-disclosure {
  font-size: 0.875rem;
  color: var(--muted) !important;
  line-height: 1.6;
}
.editorial-method {
  margin: 2.5rem 0;
  max-width: 880px;
}
.editorial-method h2,
.editorial-sources h2 {
  margin: 0 0 1rem;
}
.editorial-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
}
.editorial-links a,
.editorial-sources a,
.editorial-back {
  text-decoration: underline;
  text-underline-offset: 0.2em;
  padding: 0.5rem 0;
}
.editorial-back {
  display: inline-block;
  margin: 1rem 0 2rem;
}
.editorial-profile-head {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr);
  gap: 2.5rem;
  align-items: center;
}
.editorial-profile-head figure {
  margin: 0;
}
.editorial-profile-head img {
  width: 100%;
  height: auto;
  border-radius: var(--radius);
  display: block;
}
.editorial-profile-head figcaption {
  color: var(--muted);
  font-size: 0.8rem;
  line-height: 1.6;
  margin-top: 0.6rem;
}
.editorial-profile-head .page-title {
  margin: 0.6rem 0;
}
.editorial-profile-head .editorial-role {
  font-size: 1.15rem;
}
.editorial-bio {
  max-width: 780px;
  font-size: 1.05rem;
}
.editorial-details {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
  gap: 2.5rem;
  align-items: start;
}
.editorial-sources {
  margin: 2.5rem 0;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.editorial-sources ul {
  margin: 0;
  padding-left: 1.2rem;
}
.editorial-sources li {
  margin: 0.7rem 0;
}
.editorial-sources a {
  display: inline-block;
}
.editorial-coverage {
  margin: 1.5rem 0 3rem;
}
.editorial-archive-note {
  color: var(--muted);
  line-height: 1.75;
  max-width: 880px;
  margin-bottom: 1.5rem;
}
.editorial-articles {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem;
}
.editorial-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 1.5rem;
  margin: 2rem 0;
}
.editorial-byline {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 44px;
}
.editorial-byline img {
  border-radius: 50%;
  flex-shrink: 0;
}
.editorial-byline small {
  display: block;
  color: var(--muted);
  font-size: 0.75rem;
  font-weight: normal;
}
.editorial-article-profile {
  display: flex;
  gap: 1.25rem;
  margin: 2rem 0;
  padding: 1.5rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.editorial-article-profile img {
  border-radius: 50%;
  width: 96px;
  height: 96px;
  flex-shrink: 0;
}
.editorial-article-profile h2 {
  font-size: 1.2rem;
  margin: 0.5rem 0;
}
.editorial-article-profile p {
  margin: 0.5rem 0;
}
.editorial-byline:hover,
.editorial-card h2 a:hover,
.editorial-article-profile h2 a:hover {
  text-decoration: underline;
}
@media (max-width: 950px) {
  .editorial-directory,
  .editorial-articles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 700px) {
  .editorial-directory,
  .editorial-articles,
  .editorial-details,
  .editorial-profile-head {
    grid-template-columns: 1fr;
  }
  .editorial-profile-head {
    gap: 1.5rem;
  }
  .editorial-profile-head figure {
    max-width: 280px;
  }
  .editorial-details {
    gap: 0;
  }
  .editorial-sources {
    margin-top: 0;
  }
  .editorial-article-profile {
    padding: 1rem;
    gap: 1rem;
  }
  .editorial-article-profile img {
    width: 56px;
    height: 56px;
  }
}

.category-vulnerabilities{--cat-h:34}.category-vulnerabilities .cat-swatch{background:hsl(34 90% 58%)}
.category-malware{--cat-h:276}.category-malware .cat-swatch{background:hsl(276 90% 58%)}
.category-ransomware{--cat-h:352}.category-ransomware .cat-swatch{background:hsl(352 90% 58%)}
.category-apt{--cat-h:190}.category-apt .cat-swatch{background:hsl(190 90% 58%)}
.category-data-breach{--cat-h:322}.category-data-breach .cat-swatch{background:hsl(322 90% 58%)}
.category-cloud-security{--cat-h:205}.category-cloud-security .cat-swatch{background:hsl(205 90% 58%)}
.category-ai{--cat-h:148}.category-ai .cat-swatch{background:hsl(148 90% 58%)}
