/* VigilForge Newsroom ("Veille & Actualités") — RADAR layout
   Extends graph.css's design tokens and control classes (.kg-controls,
   .kg-status-btn, .kg-search, .kg-slider, .kg-difficulty-*) rather than
   inventing a second design system — see templates/lessons/lesson_graph.html
   and static/css/graph.css. Loaded only on /veille/. */

/* ── Page / header ───────────────────────────────────────────────────────── */
.veille-page { max-width: 1100px; margin: 0 auto; }
.veille-last-update { font-size: 0.78rem; font-family: var(--font-mono); color: var(--text-muted); white-space: nowrap; }

/* ── Controls ────────────────────────────────────────────────────────────── */
/* .veille-controls no longer carries its own card chrome — only the search
   row (below) is sticky/boxed. Tab chips and window chips sit in normal
   flow underneath, each already self-contained via .veille-chip-row. */
.veille-controls { display: flex; flex-direction: column; gap: 0.6rem; margin-bottom: 1rem; }

/* Only the search+EPSS row is sticky — matches the spec's own layout
   diagram, which annotates just the search bar "← sticky", not the whole
   controls block. Making the whole 3-row block sticky covered a large
   chunk of PULSE as soon as the page scrolled even slightly (confirmed
   visually, not just reasoned about) — a search-only bar is thin enough
   that it never meaningfully overlaps PULSE content. Carries its own
   background/border since it's no longer nested inside a shared card with
   the (now non-sticky) chip rows. */
.veille-controls-sticky {
  position: sticky; top: 5rem; z-index: 20;
  background: var(--bg-glass); backdrop-filter: blur(8px);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: 0.75rem 1rem;
}
[data-theme="light"] .veille-controls-sticky { background: var(--bg-card); }
.veille-search-wrap { flex: 1; max-width: 360px; }
.veille-search { width: 100%; }
.veille-loading-indicator {
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid var(--border); border-top-color: var(--accent-cyan);
  opacity: 0;
}
.htmx-request .veille-loading-indicator,
.veille-loading-indicator.htmx-request { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .veille-loading-indicator.htmx-request { animation: veille-spin 700ms linear infinite; }
}
@keyframes veille-spin { to { transform: rotate(360deg); } }

/* Chip rows — each chip is its own <form>, so the row just needs to look
   like one continuous group; reuses .kg-status-btn for the button itself. */
.veille-chip-row { gap: 0; border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; width: fit-content; }
.veille-chip-form { display: contents; }
.veille-chip { border: none; border-right: 1px solid var(--border); }
.veille-chip-form:last-child .veille-chip { border-right: none; }
.veille-chip-link {
  display: inline-flex; align-items: center; padding: 0.3rem 0.65rem;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  color: var(--accent-cyan); font-size: 0.75rem; font-family: var(--font-mono);
  text-decoration: none; background: rgba(34,181,255,0.06);
}
.veille-chip-link:hover { background: rgba(34,181,255,0.12); }

/* ── PULSE ───────────────────────────────────────────────────────────────── */
.veille-pulse { margin: 1rem 0 1.25rem; }
.veille-pulse-kev-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0.6rem; margin-bottom: 0.75rem; }
.veille-pulse-card {
  display: flex; flex-direction: column; gap: 0.2rem;
  padding: 0.75rem 0.9rem; border-radius: var(--r-md);
  border: 1px solid var(--color-danger-border, var(--border));
  background: var(--color-danger-muted, var(--bg-card));
  text-decoration: none;
}
.veille-pulse-kev-badge { font-size: 0.62rem; font-weight: 700; letter-spacing: 0.06em; color: var(--color-danger-text, #ff3366); }
.veille-pulse-cve { font-family: var(--font-mono); font-size: 0.85rem; font-weight: 600; color: var(--text-primary); }
.veille-pulse-title { font-size: 0.78rem; color: var(--text-secondary, var(--text-muted)); }
.veille-pulse-date { font-size: 0.68rem; color: var(--text-muted); font-family: var(--font-mono); }
.veille-pulse-empty { font-size: 0.8rem; color: var(--text-muted); }

.veille-sparklines { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 0.75rem; }
.veille-sparkline-block { padding: 0.5rem 0.7rem; border: 1px solid var(--border); border-radius: var(--r-md); background: var(--bg-glass); }
.veille-sparkline-label { display: block; font-size: 0.68rem; font-family: var(--font-mono); color: var(--text-muted); margin-bottom: 0.25rem; }
.veille-sparkline-label strong { color: var(--text-primary); }
.veille-sparkline-svg { width: 100%; height: 28px; display: block; }
.veille-spark-path { stroke: var(--accent-cyan); stroke-dashoffset: 0; }
.spark-kev.veille-sparkline-svg .veille-spark-path { stroke: var(--color-danger-text, #ff3366); }
.spark-cve .veille-spark-path { stroke: var(--accent-cyan); }
.spark-news .veille-spark-path { stroke: var(--color-warning-text, #eab308); }
.spark-updates .veille-spark-path { stroke: var(--color-success-text, #22c55e); }

/* Draw-in on first paint only — pathLength="1" makes the dasharray trivial.
   Base rule above already sets the "settled" state (dashoffset 0) so a
   browser that somehow matches neither media query still renders correctly. */
@media (prefers-reduced-motion: no-preference) {
  .veille-spark-path {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    animation: veille-spark-draw 700ms var(--ease-standard, ease-out) forwards;
  }
  @keyframes veille-spark-draw { to { stroke-dashoffset: 0; } }
}

/* ── Grid ────────────────────────────────────────────────────────────────── */
.veille-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 0.75rem; list-style: none; padding: 0; margin: 0; }
.veille-card { list-style: none; }
.veille-card-inner {
  height: 100%; display: flex; flex-direction: column; gap: 0.4rem;
  padding: 0.85rem 1rem; border-radius: var(--r-lg);
  border: 1px solid var(--border); background: var(--bg-card, var(--bg-glass));
}
.veille-card-kev { border-color: var(--color-danger-border, var(--border)); }
.veille-card-top { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
.veille-cve-link { font-family: var(--font-mono); font-size: 0.85rem; font-weight: 600; color: var(--accent-cyan); text-decoration: none; }
.veille-cve-link:hover { text-decoration: underline; }
.veille-badge { font-size: 0.62rem; font-weight: 700; padding: 0.1rem 0.4rem; border-radius: 4px; letter-spacing: 0.05em; }
.veille-badge-kev { background: var(--color-danger-muted, rgba(255,51,102,0.12)); color: var(--color-danger-text, #ff3366); }
.veille-badge-social { background: var(--color-orange-muted, rgba(255,159,10,0.12)); color: var(--color-orange-text, #ff9f0a); }
.veille-meta { font-size: 0.72rem; font-family: var(--font-mono); color: var(--text-muted); }
.veille-card-title { font-size: 0.85rem; color: var(--text-primary); line-height: 1.4; margin: 0; }
.veille-card-excerpt { font-size: 0.76rem; color: var(--text-muted); line-height: 1.4; margin: 0; }

.veille-attribution-row { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: auto; padding-top: 0.3rem; }
.veille-attribution {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.2rem 0.5rem; border-radius: 999px; border: 1px solid var(--border);
  font-size: 0.68rem; text-decoration: none; color: var(--text-muted);
}
.veille-attribution cite { font-style: normal; color: var(--text-primary); }
.veille-attribution time { font-family: var(--font-mono); }
.veille-attribution:hover { border-color: var(--accent-cyan); color: var(--accent-cyan); }
/* Trust-tier accent — a border tint only; attribution text/link is always
   fully visible regardless of tier, never hidden or dimmed by tier. */
.veille-tier-1 { border-color: var(--color-success-border, var(--border)); }
.veille-tier-2 { border-color: var(--color-warning-border, var(--border)); }
.veille-tier-3 { border-color: var(--color-orange-border, var(--border)); }

.veille-social-original-link {
  font-size: 0.72rem; color: var(--accent-cyan); text-decoration: none; margin-top: -0.15rem;
}
.veille-social-original-link:hover { text-decoration: underline; }

/* ── Cluster expand — CSS grid-template-rows 0fr→1fr, no JS height math ──── */
.veille-cluster-toggle {
  display: inline-flex; align-items: center; gap: 0.3rem;
  background: transparent; border: none; padding: 0; margin-top: 0.15rem;
  color: var(--accent-cyan); font-size: 0.72rem; font-family: var(--font-mono);
  cursor: pointer;
}
.veille-chevron { transition: none; }
@media (prefers-reduced-motion: no-preference) {
  .veille-chevron { transition: transform var(--duration-fast, 120ms) var(--ease-standard, ease); }
}
.veille-cluster-toggle[aria-expanded="true"] .veille-chevron { transform: rotate(180deg); }

.veille-cluster-body { display: grid; grid-template-rows: 0fr; overflow: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .veille-cluster-body { transition: grid-template-rows 220ms var(--ease-standard, ease); }
}
.veille-cluster-body.is-open { grid-template-rows: 1fr; }
.veille-cluster-body-inner { min-height: 0; display: flex; flex-direction: column; gap: 0.3rem; padding-top: 0.4rem; }
.veille-cluster-member {
  display: flex; align-items: center; gap: 0.4rem; font-size: 0.72rem;
  text-decoration: none; color: var(--text-muted); border: 1px solid var(--border);
  border-radius: var(--r-sm); padding: 0.3rem 0.5rem;
}
.veille-cluster-member cite { font-style: normal; color: var(--text-primary); flex-shrink: 0; }
.veille-cluster-member:hover { border-color: var(--accent-cyan); }

/* ── Result count ────────────────────────────────────────────────────────── */
.veille-result-count { font-size: 0.78rem; color: var(--text-muted); margin: 0 0 0.6rem; }

/* ── Empty state ─────────────────────────────────────────────────────────── */
.veille-empty { text-align: center; padding: 3rem 1rem; }
.veille-empty-title { font-size: 1.1rem; font-weight: 700; color: var(--text-primary); margin-bottom: 0.35rem; }
.veille-empty-sub { font-size: 0.85rem; color: var(--text-muted); margin-bottom: 1rem; }
.veille-empty-suggestions { display: flex; justify-content: center; gap: 0.5rem; flex-wrap: wrap; }

/* ── Load more ───────────────────────────────────────────────────────────── */
.veille-load-more-wrap { display: flex; justify-content: center; margin-top: 1.25rem; }
.veille-load-more {
  padding: 0.5rem 1.25rem; border-radius: var(--r-md); border: 1px solid var(--border);
  background: rgba(255,255,255,0.03); color: var(--text-primary);
  font-size: 0.8rem; font-family: var(--font-mono); cursor: pointer;
}
[data-theme="light"] .veille-load-more { background: var(--bg-card); }
.veille-load-more:hover { border-color: var(--accent-cyan); color: var(--accent-cyan); }

/* ── Staggered card reveal on filter change — CSS-first, capped at 12 ────── */
@media (prefers-reduced-motion: no-preference) {
  .veille-card { opacity: 0; transform: translateY(8px); animation: veille-card-in 180ms var(--ease-standard, ease-out) forwards; }
  .veille-card:nth-child(1)  { animation-delay: 0ms; }
  .veille-card:nth-child(2)  { animation-delay: 30ms; }
  .veille-card:nth-child(3)  { animation-delay: 60ms; }
  .veille-card:nth-child(4)  { animation-delay: 90ms; }
  .veille-card:nth-child(5)  { animation-delay: 120ms; }
  .veille-card:nth-child(6)  { animation-delay: 150ms; }
  .veille-card:nth-child(7)  { animation-delay: 180ms; }
  .veille-card:nth-child(8)  { animation-delay: 210ms; }
  .veille-card:nth-child(9)  { animation-delay: 240ms; }
  .veille-card:nth-child(10) { animation-delay: 270ms; }
  .veille-card:nth-child(11) { animation-delay: 300ms; }
  .veille-card:nth-child(12) { animation-delay: 330ms; }
  .veille-card:nth-child(n+13) { animation-delay: 330ms; } /* capped, per spec */
  @keyframes veille-card-in { to { opacity: 1; transform: translateY(0); } }
}
/* Reserve the final layout box even before the animation starts, so the
   reveal never causes a layout shift (target CLS 0) — translateY(8px) is a
   transform, not a margin/position change, so it never affects flow. */

@media (max-width: 700px) {
  .veille-page { padding: 1.25rem 1rem 3rem; }
  .veille-controls-sticky { position: static; }
  .veille-search-wrap { max-width: 100%; }
}
