/* ============================================================
   Shared v2 design tokens + reusable components. Bespoke palette (round
   15): a WHITE-dominant system -- background restored to near-white/near-
   black neutrals (violet pulled back to a sparing accent + specific
   background moments, e.g. the hero, rather than the base canvas colour
   round 13 made it) -- with violet, crimson, cyan, egg-yolk yellow and
   mint as the six-colour accent set (white itself being the 6th "colour",
   used for backgrounds rather than as an accent). See the full palette
   comment further down for the tier structure (primary text-safe hues vs.
   decorative-vivid hues) and why.

   Typography (rebuilt, round 5): Bricolage Grotesque for display (a
   distinctive, characterful variable grotesk -- not another Inter/
   Archivo/Space Grotesk default), Newsreader for body/reading text (a
   warm, literary serif distinct from the earlier Fraunces), Space Mono
   for data/UI labels (more character than the earlier IBM Plex Mono).
   Three typefaces with clearly separated jobs, not one face doing
   everything.

   Four theme variants (dark/dim/light/bright) share these same hues at
   different lightness levels -- toggled via [data-v2-theme] on <html>,
   cycling through the floating toolbar (v2-toolbar.js). Default (no
   attribute) = light.
   ============================================================ */
@import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,200..800&family=Newsreader:ital,opsz,wght@0,6..72,300..700;1,6..72,300..700&family=Space+Mono:ital,wght@0,400;0,700;1,400&display=swap');

/* ---------- White-dominant, 6-colour system (round 15) ----------
   Explicit brief: white as the dominant canvas, violet "designated for
   background elements... used sparingly and subtly" (not the base void
   colour itself, which round 13 had made it) -- so void/ink pulled back
   to near-neutral (chroma 0.002-0.012, down from round 13's 0.024-0.03)
   across all 4 themes, and violet's real "background element" moment
   lives instead in specific spots (the hero's own background gradient)
   rather than being the page-wide canvas tint.
   Six colours, one of which (white) is a background-only colour, not an
   accent -- mixing white into an already-near-white surface has no
   visible effect, so the accent-capable set is the other five: violet,
   crimson, cyan, egg-yolk yellow, mint.
   Role remap per the brief's own logical suggestions (crimson for
   actions, cyan for links, yellow/mint for accents): --v2-gold (the
   "used everywhere -- CTAs, emphasis text" alias) now points at crimson
   instead of violet; --v2-wine* (the link/secondary alias) now points at
   a NEW --v2-cyan instead of crimson. Violet keeps its own standalone
   token (no longer aliased to anything) for its background-element role
   and occasional bento-tint appearances.
   --v2-cyan hue (205) is converted from real references the same way
   crimson/yellow were (Tailwind cyan-600 #0891B2 -> hue 221.7, CSS
   darkcyan #008B8B -> hue 194.8, Bootstrap info #17A2B8 -> hue 212.2;
   205 sits in that cluster). Cyan turned out NOT to need the vivid/ink
   split yellow/mint/blue needed: at a lower chroma (0.09 vs 0.19-0.20)
   it clears 4.5:1 on light/bright while still reading as genuine teal/
   cyan (#0c7d87), not collapsing to near-black -- so cyan is a THIRD
   primary, text-safe-everywhere hue, not a decorative-only one.
   --v2-blue (sky blue, hue 237) is retired in favour of --v2-cyan;
   grepped and updated its 3 consumers (bento-tint 5th slot, the Skills
   network canvas's accent cycle, the Skills heatmap's "medium" tier).
   All values computed via a real OKLCH->linear-sRGB->WCAG-relative-
   luminance pipeline (scratchpad/oklch_final.py), not eyeballed. */
html {
  --v2-void: oklch(98.5% 0.004 300);          /* near-white -- violet only a whisper */
  --v2-void-raised: oklch(99.5% 0.002 300);
  --v2-glass: oklch(20% 0.012 300 / 0.04);
  --v2-glass-border: oklch(20% 0.012 300 / 0.14);
  --v2-ink: oklch(18% 0.02 300);               /* 18.05:1 vs light void */
  --v2-ink-soft: oklch(40% 0.025 300);

  --v2-violet: oklch(54% 0.19 302);           /* 5.09:1 vs light void -- background-element + occasional accent */
  --v2-violet-soft: oklch(54% 0.19 302 / 0.22);
  --v2-crimson: oklch(54% 0.20 20);           /* 5.16:1 vs light void -- matches true crimson's hue */
  --v2-crimson-bright: oklch(54% 0.20 20);
  --v2-crimson-dim: oklch(54% 0.20 20 / 0.18);
  --v2-cyan: oklch(54% 0.09 205);             /* 4.66:1 vs light void -- text-safe, unlike the old sky-blue */
  --v2-cyan-bright: oklch(54% 0.09 205);
  --v2-cyan-dim: oklch(54% 0.09 205 / 0.18);
  --v2-yellow: oklch(82% 0.17 90);            /* decorative pigment, all themes -- egg-yolk hue */
  --v2-yellow-ink: oklch(23% 0.19 90);        /* text-safe fallback, light/bright only */
  --v2-mint: oklch(88% 0.18 168);
  --v2-mint-ink: oklch(12% 0.19 168);

  --v2-gold: var(--v2-crimson); --v2-gold-soft: var(--v2-crimson-dim);
  --v2-wine: var(--v2-cyan); --v2-wine-bright: var(--v2-cyan-bright); --v2-wine-dim: var(--v2-cyan-dim);
  --v2-clay: var(--v2-mint);
  --v2-shadow: 0 16px 36px -18px oklch(20% 0.012 300 / 0.22);
}
html[data-v2-theme="dark"] {
  --v2-void: oklch(13% 0.012 300);            /* near-neutral dark, violet restrained here too */
  --v2-void-raised: oklch(18% 0.014 300);
  --v2-glass: oklch(94% 0.012 300 / 0.05);
  --v2-glass-border: oklch(94% 0.012 300 / 0.13);
  --v2-ink: oklch(95% 0.012 300);              /* 17.35:1 vs dark void */
  --v2-ink-soft: oklch(68% 0.02 300);

  --v2-violet: oklch(70% 0.19 302);           /* 6.92:1 vs dark void */
  --v2-violet-soft: oklch(70% 0.19 302 / 0.30);
  --v2-crimson: oklch(69% 0.20 20);           /* 6.55:1 vs dark void */
  --v2-crimson-bright: oklch(69% 0.20 20);
  --v2-crimson-dim: oklch(69% 0.20 20 / 0.26);
  --v2-cyan: oklch(75% 0.13 205);             /* 9.52:1 vs dark void -- vivid, clears AA as text here directly */
  --v2-cyan-bright: var(--v2-cyan);
  --v2-cyan-dim: oklch(75% 0.13 205 / 0.26);
  --v2-yellow: oklch(82% 0.17 90);            /* 11.37:1 vs dark void */
  --v2-yellow-ink: var(--v2-yellow);
  --v2-mint: oklch(88% 0.18 168);             /* 14.93:1 vs dark void */
  --v2-mint-ink: var(--v2-mint);

  --v2-gold: var(--v2-crimson); --v2-gold-soft: var(--v2-crimson-dim);
  --v2-wine: var(--v2-cyan); --v2-wine-bright: var(--v2-cyan-bright); --v2-wine-dim: var(--v2-cyan-dim);
  --v2-clay: var(--v2-mint);
  --v2-shadow: 0 20px 44px -18px oklch(0% 0 0 / 0.55);
}
html[data-v2-theme="dim"] {
  --v2-void: oklch(20% 0.012 300);
  --v2-void-raised: oklch(25% 0.014 300);
  --v2-glass: oklch(94% 0.011 300 / 0.045);
  --v2-glass-border: oklch(94% 0.011 300 / 0.12);
  --v2-ink: oklch(91% 0.011 300);              /* 13.85:1 vs dim void */
  --v2-ink-soft: oklch(69% 0.018 300);

  --v2-violet: oklch(70% 0.19 302);           /* 5.88:1 vs dim void */
  --v2-violet-soft: oklch(70% 0.19 302 / 0.30);
  --v2-crimson: oklch(69% 0.20 20);           /* 5.56:1 vs dim void */
  --v2-crimson-bright: oklch(69% 0.20 20);
  --v2-crimson-dim: oklch(69% 0.20 20 / 0.26);
  --v2-cyan: oklch(75% 0.13 205);             /* 8.58:1 vs dim void */
  --v2-cyan-bright: var(--v2-cyan);
  --v2-cyan-dim: oklch(75% 0.13 205 / 0.26);
  --v2-yellow: oklch(82% 0.17 90);            /* 9.66:1 vs dim void */
  --v2-yellow-ink: var(--v2-yellow);
  --v2-mint: oklch(88% 0.18 168);             /* 12.68:1 vs dim void */
  --v2-mint-ink: var(--v2-mint);

  --v2-gold: var(--v2-crimson); --v2-gold-soft: var(--v2-crimson-dim);
  --v2-wine: var(--v2-cyan); --v2-wine-bright: var(--v2-cyan-bright); --v2-wine-dim: var(--v2-cyan-dim);
  --v2-clay: var(--v2-mint);
}
html[data-v2-theme="bright"] {
  --v2-void: oklch(99.5% 0.002 300);          /* near-pure white */
  --v2-void-raised: oklch(100% 0 0);
  --v2-glass: oklch(20% 0.01 300 / 0.03);
  --v2-glass-border: oklch(20% 0.01 300 / 0.15);
  --v2-ink: oklch(12% 0.015 300);              /* 20.02:1 vs bright void */
  --v2-ink-soft: oklch(34% 0.025 300);

  --v2-violet: oklch(52% 0.19 302);           /* 5.88:1 vs bright void */
  --v2-violet-soft: oklch(52% 0.19 302 / 0.20);
  --v2-crimson: oklch(52% 0.20 20);           /* 5.96:1 vs bright void */
  --v2-crimson-bright: oklch(52% 0.20 20);
  --v2-crimson-dim: oklch(52% 0.20 20 / 0.16);
  --v2-cyan: oklch(55% 0.09 205);             /* 4.60:1 vs bright void */
  --v2-cyan-bright: oklch(55% 0.09 205);
  --v2-cyan-dim: oklch(55% 0.09 205 / 0.16);
  --v2-yellow: oklch(82% 0.17 90);            /* decorative pigment only -- see -ink */
  --v2-yellow-ink: oklch(23% 0.19 90);        /* 16.67:1 vs bright void */
  --v2-mint: oklch(88% 0.18 168);
  --v2-mint-ink: oklch(12% 0.19 168);         /* 18.72:1 vs bright void */

  --v2-gold: var(--v2-crimson); --v2-gold-soft: var(--v2-crimson-dim);
  --v2-wine: var(--v2-cyan); --v2-wine-bright: var(--v2-cyan-bright); --v2-wine-dim: var(--v2-cyan-dim);
  --v2-clay: var(--v2-mint);
  --v2-shadow: 0 12px 28px -16px oklch(20% 0.01 300 / 0.18);
}

.v2-scope {
  --v2-font-display: "Bricolage Grotesque", "Segoe UI", sans-serif;
  --v2-font-structure: "Newsreader", Georgia, serif;
  --v2-font-mono: "Space Mono", ui-monospace, monospace;

  background: var(--v2-void);
  color: var(--v2-ink);
  font-family: var(--v2-font-structure);
  font-optical-sizing: auto;
  transition: background-color 0.4s ease, color 0.4s ease;
}
.v2-scope, .v2-scope p, .v2-scope li { font-variation-settings: "opsz" 14; }
.v2-scope .breadcrumb { font-family: var(--v2-font-mono); font-size: 0.8rem; color: var(--v2-ink-soft); }
.v2-scope .breadcrumb a { color: var(--v2-ink-soft); }
.v2-scope .page-title { font-family: var(--v2-font-display); font-weight: 600; font-variation-settings: "opsz" 60; color: var(--v2-ink); font-size: clamp(2rem, 4.5vw, 3rem); margin: 8px 0 20px; }
.v2-scope .section__intro { color: var(--v2-ink-soft); font-size: 1rem; line-height: 1.65; }
.v2-scope .section__title, .v2-scope .v2-title {
  font-family: var(--v2-font-display); font-weight: 600; font-variation-settings: "opsz" 40; font-size: 1.4rem; color: var(--v2-ink);
  display: flex; align-items: baseline; gap: 12px; margin: 44px 0 24px;
}
.v2-scope .section__title:first-of-type, .v2-scope .v2-title:first-of-type { margin-top: 0; }
.v2-scope .section__title--sub, .v2-scope .v2-title--sub { font-size: 1.15rem; }
.v2-scope .section__index, .v2-scope .v2-index { font-family: var(--v2-font-display); font-weight: 600; color: var(--v2-gold); font-size: 1.3rem; }

/* ---------- Shared cross-page utilities (round 6+) -- proven once on
   Home/About, now reusable anywhere instead of re-writing per page. ---------- */
/* Corner-bracket editorial frame -- the mission-quote/specimen-card motif. */
.v2-corner-frame { position: relative; padding: 4px 0 4px 22px; }
.v2-corner-frame::before, .v2-corner-frame::after {
  content: ''; position: absolute; width: 14px; height: 14px; border: 2px solid var(--v2-gold);
}
.v2-corner-frame::before { top: -6px; left: 0; border-right: none; border-bottom: none; }
.v2-corner-frame::after { bottom: -6px; left: 0; border-right: none; border-top: none; }

/* Bento-tint -- a genuine 6-way wash across siblings (card grids, tag
   lists), one full palette hue per card in rotation.
   Round 19 had reverted this to one flat consistent accent, reasoning from
   the mood-board reference templates that repeated UI chrome stays in one
   brand colour there. Round 22 explicit, repeated direct instruction
   overrode that finding for this site specifically: "drop bento[-tint's
   single-accent rule] and use all given colours in equal proportions...
   no one colour must dominate." A direct, repeated instruction about the
   user's own site beats a general pattern inferred from OTHER people's
   templates -- reverted to real per-card colour variety, this time
   covering all 6 hues (round 12's version only had 5 and one of those
   referenced a token retired since). */
/* [data-tint-cycle] (assets/js/site.js assigns this by true page-wide
   position, see its own comment) rather than :nth-child -- several pages
   split their bento-tint cards across multiple separate .card-grid
   containers, and :nth-child only counts among same-parent siblings, so
   it silently restarted at 1 in every group and never reached colours
   4-6. Falls back to the :nth-child version for the rare no-JS case
   (same 3-colour limitation then, but still tinted rather than flat). */
.v2-scope .v2-bento-tint:nth-child(6n+1) { background: color-mix(in oklch, var(--v2-violet) 16%, var(--v2-glass)); }
.v2-scope .v2-bento-tint:nth-child(6n+2) { background: color-mix(in oklch, var(--v2-crimson) 16%, var(--v2-glass)); }
.v2-scope .v2-bento-tint:nth-child(6n+3) { background: color-mix(in oklch, var(--v2-cyan) 16%, var(--v2-glass)); }
.v2-scope .v2-bento-tint:nth-child(6n+4) { background: color-mix(in oklch, var(--v2-yellow) 18%, var(--v2-glass)); }
.v2-scope .v2-bento-tint:nth-child(6n+5) { background: color-mix(in oklch, var(--v2-mint) 18%, var(--v2-glass)); }
.v2-scope .v2-bento-tint:nth-child(6n+6) { background: color-mix(in oklch, var(--v2-ink) 10%, var(--v2-glass)); }
.v2-scope .v2-bento-tint[data-tint-cycle="0"] { background: color-mix(in oklch, var(--v2-violet) 16%, var(--v2-glass)); }
.v2-scope .v2-bento-tint[data-tint-cycle="1"] { background: color-mix(in oklch, var(--v2-crimson) 16%, var(--v2-glass)); }
.v2-scope .v2-bento-tint[data-tint-cycle="2"] { background: color-mix(in oklch, var(--v2-cyan) 16%, var(--v2-glass)); }
.v2-scope .v2-bento-tint[data-tint-cycle="3"] { background: color-mix(in oklch, var(--v2-yellow) 18%, var(--v2-glass)); }
.v2-scope .v2-bento-tint[data-tint-cycle="4"] { background: color-mix(in oklch, var(--v2-mint) 18%, var(--v2-glass)); }
.v2-scope .v2-bento-tint[data-tint-cycle="5"] { background: color-mix(in oklch, var(--v2-ink) 10%, var(--v2-glass)); }
.v2-scope a { color: var(--v2-wine-bright, var(--v2-wine)); text-decoration-thickness: 1px; text-underline-offset: 2px; }
.v2-scope a:hover { color: var(--v2-gold); }

/* Per-page accent rebalancing -- "gold" (this system's primary-accent
   alias) resolved to crimson on every single page before this, so despite
   round 19's fix being correct that each page/component needs ONE
   consistent accent rather than a rainbow cycle, the site AS A WHOLE still
   read as crimson-dominated -- the same one colour, page after page, isn't
   what "balance all 6 colours" meant.
   Limited to violet and crimson ONLY, not the full 6 -- checked every
   `var(--v2-gold)` usage site-wide first, and it drives literal `color:`
   (real text) in dozens of rules (nav links, section indices, active
   states), not just backgrounds. Yellow and mint are decorative-only
   pigments on light/bright themes per this file's own OKLCH verification
   (too light to clear 4.5:1 as text without collapsing to near-black) --
   assigning either to --v2-gold would silently fail contrast the moment
   any of those text-colour rules rendered on a yellow/mint-accented page.
   Cyan is excluded too: it's the fixed site-wide "links" alias (--v2-wine)
   already, so reusing it here would collapse two different semantic roles
   into one colour on that page. Split 10 pages 5/5 across the two hues
   that are actually safe everywhere. Yellow/mint keep their existing
   decorative/data-encoding roles (stat-band confetti, skills-network
   canvas nodes) rather than being forced into a text-bearing role they
   were never verified for. */
.about-v2, .community-v2, .skills-v2, .publications-v2, .gallery-v2 { --v2-gold: var(--v2-violet); --v2-gold-soft: var(--v2-violet-soft); }
/* home-v2, press-v2, portfolio-v2, map-v2, certificates-v2 keep the default crimson. */

/* ---------- Spotlight panel/card: mouse-following radial glow.
   Dialed subtler than the first pass -- smaller radius, lower peak
   opacity, so it reads as a soft sheen rather than a stage light. ---------- */
.v2-spotlight {
  --sx: 50%; --sy: 50%;
  position: relative; overflow: hidden;
  background: var(--v2-glass); border: 1px solid var(--v2-glass-border); backdrop-filter: blur(12px);
}
.v2-spotlight::before {
  content: ''; position: absolute; inset: 0; z-index: 0; opacity: 0; transition: opacity 0.4s ease; pointer-events: none;
  background: radial-gradient(200px circle at var(--sx) var(--sy), var(--v2-gold-soft), transparent 72%);
}
.v2-spotlight:hover::before, .v2-spotlight:focus-within::before { opacity: 0.4; }
.v2-spotlight--wine::before { background: radial-gradient(200px circle at var(--sx) var(--sy), var(--v2-wine-dim), transparent 72%); }
.v2-spotlight > * { position: relative; z-index: 1; }

/* ---------- Magnetic pill: staggered reveal + gentle cursor-drift. ---------- */
.v2-pill {
  --mx: 0px; --my: 0px;
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--v2-glass); border: 1px solid var(--v2-glass-border); color: var(--v2-ink-soft);
  font-family: var(--v2-font-mono); font-size: 0.8rem; padding: 8px 16px;
  transform: translate(var(--mx), var(--my)); transition: border-color 0.25s ease, color 0.25s ease;
}
.v2-pill:hover { border-color: var(--v2-gold); color: var(--v2-ink); }
.v2-reveal-stagger { opacity: 0; transform: translateY(10px); transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.22,1,0.36,1); }
.v2-reveal-stagger.is-visible { opacity: 1; transform: none; }

/* ---------- Scan-card: quiet corner ticks + one-time, slow sweep. ---------- */
.v2-scan-card { position: relative; border: 1px solid var(--v2-glass-border); background: var(--v2-void-raised); padding: 22px 24px; overflow: hidden; }
.v2-scan-card::before, .v2-scan-card::after { content: ''; position: absolute; width: 9px; height: 9px; border: 1px solid var(--v2-gold); opacity: 0.5; }
.v2-scan-card::before { top: 8px; left: 8px; border-right: none; border-bottom: none; }
.v2-scan-card::after { bottom: 8px; right: 8px; border-left: none; border-top: none; }
.v2-scan-card__title { font-family: var(--v2-font-mono); font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--v2-gold); margin: 0 0 14px; }
.v2-scan-sweep {
  position: absolute; left: 0; right: 0; top: 0; height: 34%; pointer-events: none;
  background: linear-gradient(180deg, var(--v2-wine-dim), transparent);
  transform: translateY(-100%); opacity: 0;
}
.v2-scan-card.is-scanned .v2-scan-sweep { animation: v2-scan 1.5s ease-out forwards; }
@keyframes v2-scan { 0% { transform: translateY(-100%); opacity: 0.7; } 100% { transform: translateY(300%); opacity: 0; } }

/* ---------- Timeline rail: scroll-scrubbed progress spine. ---------- */
.v2-timeline { position: relative; margin: 20px 0 0; padding-left: 28px; }
.v2-timeline-rail { position: absolute; left: 4px; top: 0; bottom: 0; width: 1.5px; background: var(--v2-glass-border); }
.v2-timeline-rail-fill { position: absolute; left: 0; top: 0; width: 100%; height: 0%; background: linear-gradient(180deg, var(--v2-gold), var(--v2-wine-bright, var(--v2-wine))); }
.v2-timeline-item { position: relative; padding: 0 0 36px; }
.v2-timeline-item:last-child { padding-bottom: 0; }
.v2-timeline-dot {
  position: absolute; left: -28px; top: 4px; width: 9px; height: 9px; border-radius: 50%;
  background: var(--v2-void); border: 2px solid var(--v2-glass-border); transition: background 0.4s ease, border-color 0.4s ease, box-shadow 0.4s ease;
}
.v2-timeline-item.is-visible .v2-timeline-dot { background: var(--v2-gold); border-color: var(--v2-gold); box-shadow: 0 0 8px 1px var(--v2-gold-soft); }

/* ---------- Terminal-style row: monospace, quiet cursor accent. ---------- */
.v2-terminal-row {
  display: flex; justify-content: space-between; gap: 14px; font-family: var(--v2-font-mono); font-size: 0.86rem;
  border-bottom: 1px dashed var(--v2-glass-border); padding: 10px 0;
}
.v2-terminal-cursor {
  display: inline-block; width: 6px; height: 1em; background: var(--v2-gold); margin-left: 2px; vertical-align: text-bottom;
  animation: v2-blink 1.1s step-end infinite;
}
@keyframes v2-blink { 50% { opacity: 0; } }

/* ---------- Generic card / pill-tag / feed-item base (v2 look for the
   already-existing .card / .tag / .feed-item / .filter-chip class names
   the site's live filter JS depends on -- visual only, no selector renames). ---------- */
.v2-scope .card, .v2-scope .tag, .v2-scope .feed-item, .v2-scope .event-card {
  background: var(--v2-glass); border: 1px solid var(--v2-glass-border); backdrop-filter: blur(10px);
  border-radius: 0; color: var(--v2-ink);
}
.v2-scope .card__title, .v2-scope .feed-item__title { font-family: var(--v2-font-display); font-weight: 600; font-variation-settings: "opsz" 20; color: var(--v2-ink); }
.v2-scope .card__body, .v2-scope .feed-item__summary { color: var(--v2-ink-soft); }
.v2-scope .feed-item__meta { font-family: var(--v2-font-mono); font-size: 0.78rem; color: var(--v2-ink-soft); }
.v2-scope .tag { border-left: 2px solid var(--v2-gold); }
.v2-scope .tag--pending { border-left-color: var(--v2-wine-bright, var(--v2-wine)); }
.v2-scope .tag__name { color: var(--v2-ink); font-weight: 600; }
.v2-scope .tag__meta { font-family: var(--v2-font-mono); font-size: 0.78rem; color: var(--v2-ink-soft); }
.v2-scope .pill { background: var(--v2-glass); border: 1px solid var(--v2-glass-border); color: var(--v2-ink-soft); }
.v2-scope .btn, .v2-scope .filter-chip, .v2-scope .copy-btn, .v2-scope .filter-toolbar__reset {
  font-family: var(--v2-font-mono); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.03em;
  border: 1px solid var(--v2-glass-border); color: var(--v2-ink); background: none; border-radius: 0;
  transition: border-color 0.25s ease, color 0.25s ease, background 0.25s ease;
}
.v2-scope .btn:hover, .v2-scope .filter-chip:hover, .v2-scope .copy-btn:hover, .v2-scope .filter-toolbar__reset:hover { border-color: var(--v2-gold); color: var(--v2-gold); }
.v2-scope .filter-chip.is-active { background: var(--v2-gold); color: var(--v2-void); border-color: var(--v2-gold); }
.v2-scope .filter-toolbar { background: var(--v2-glass); border: 1px solid var(--v2-glass-border); }
.v2-scope .filter-toolbar__field label { font-family: var(--v2-font-mono); color: var(--v2-ink-soft); }
.v2-scope .filter-toolbar__field select, .v2-scope .filter-toolbar__field input {
  background: var(--v2-void-raised); border: 1px solid var(--v2-glass-border); color: var(--v2-ink); border-radius: 0;
}
.v2-scope .filter-empty { color: var(--v2-ink-soft); }

@media (prefers-reduced-motion: reduce) {
  .v2-pill, .v2-reveal-stagger, .v2-timeline-item { opacity: 1 !important; transform: none !important; animation: none !important; }
  .v2-scan-sweep { display: none; }
}
