/*!
 * AWS Security Governance at Scale — shared "AI Glass" design system.
 *
 * Load order in every page (order matters):
 *   1. base.css     ← this file: variables, layout, cards, tabs, hero, SVG classes
 *   2. icons.css    ← Cloudscape icon sizing
 *   3. mobile.css   ← responsive rules + ALL html[data-theme="light"] overrides
 *   4. inline <style> ← page-specific only, scoped to page-unique class names
 *
 * Because mobile.css owns the light-theme layer, page-specific inline CSS must
 * NOT redeclare themed properties (background / border-color / color) on the
 * shared classes below, or it will win over the light overrides.
 *
 * Class names here are deliberately the same ones mobile.css targets:
 *   .card .cc .mod-card .lab-card .svc-card .callout .sh .ss .tab-nav .hero
 */

/* ─────────────────────────────────────────────────────────────
   Tokens
   ───────────────────────────────────────────────────────────── */
:root {
  --bg: #0C0C0F;
  --bg-hero: #080810;

  --glass: rgba(255,255,255,.04);
  --glass-hover: rgba(255,255,255,.07);
  --glass-border: rgba(255,255,255,.08);
  --glass-border-hover: rgba(255,255,255,.15);
  --shine: rgba(255,255,255,.11);

  --p: #7B2FBE;
  --pl: #9D50E0;
  --pb: #C084FC;
  --cyan: #22D3EE;
  --pink: #F472B6;
  --grn: #34D399;
  --amb: #FBBF24;
  --red: #F87171;

  --txt: #F1F5F9;
  --tb: #CBD5E1;
  --tm: #94A3B8;
  --td: #475569;

  --radius: 22px;
  --radius-sm: 14px;
  --radius-xs: 9px;
  --ease: cubic-bezier(.4,0,.2,1);

  /* ── Layout column ──────────────────────────────────────────
     ONE left edge shared by .hero, .tab-nav and .tab-content, at
     every viewport width. Change --gut per breakpoint (mobile.css)
     and all three move together.

     .tab-content is a centred max-width wrapper, so its text edge
     sits at (W - col)/2 + gut. .hero-inner is centred too, but
     .tab-nav is NOT a wrapper — its pills sit on flat padding. So
     --pad-x reproduces that same edge as plain padding, which is
     what lets the tab bar line up with the title above it.

     100% is the body content box. 100vw would include the
     scrollbar and drift the tab bar ~15px right of the content. */
  --col: 1100px;
  --gut: 24px;
  --pad-x: max(var(--gut), calc((100% - var(--col)) / 2 + var(--gut)));
}

/* ─────────────────────────────────────────────────────────────
   Keyframes — the always-on "alive" layer
   ───────────────────────────────────────────────────────────── */
@keyframes borderGlow {
  0%,100% { border-color: rgba(123,47,190,.18); box-shadow: 0 0 15px rgba(123,47,190,.04), 0 4px 12px rgba(0,0,0,.25) }
  33%     { border-color: rgba(34,211,238,.15); box-shadow: 0 0 15px rgba(34,211,238,.04), 0 4px 12px rgba(0,0,0,.25) }
  66%     { border-color: rgba(244,114,182,.12); box-shadow: 0 0 15px rgba(244,114,182,.03), 0 4px 12px rgba(0,0,0,.25) }
}
@keyframes shimmer       { 0% { background-position: 200% 50% } 100% { background-position: -200% 50% } }
@keyframes breathe       { 0%,100% { opacity:.4 } 50% { opacity:.8 } }
@keyframes iconFloat     { 0%,100% { transform: translateY(0) scale(1) } 50% { transform: translateY(-3px) scale(1.05) } }
@keyframes gradientShift { 0% { background-position:0% 50% } 50% { background-position:100% 50% } 100% { background-position:0% 50% } }
@keyframes tfi           { from { opacity:0; transform:translateY(10px) } to { opacity:1; transform:translateY(0) } }
@keyframes fadeLayer     { from { opacity:0; transform:translateY(4px) } to { opacity:1; transform:translateY(0) } }
@keyframes dash          { to { stroke-dashoffset:-16 } }
@keyframes dashFlow      { to { stroke-dashoffset:-24 } }
@keyframes particlePulse { 0% { opacity:.5; r:2.5 } 100% { opacity:1; r:3.5 } }
@keyframes pulseRing     { 0%,100% { stroke-opacity:.35 } 50% { stroke-opacity:.85 } }

/* ─────────────────────────────────────────────────────────────
   Reset + page shell
   ───────────────────────────────────────────────────────────── */
* { margin:0; padding:0; box-sizing:border-box }

body {
  font-family: 'Plus Jakarta Sans', -apple-system, BlinkMacSystemFont, sans-serif;
  background: var(--bg);
  color: var(--tb);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Whisper-level aurora wash in the corners */
body::before {
  content:''; position:fixed; inset:0; z-index:0; pointer-events:none;
  background:
    radial-gradient(ellipse 55% 35% at 15% 0%,  rgba(123,47,190,.07), transparent),
    radial-gradient(ellipse 40% 25% at 85% 5%,  rgba(34,211,238,.04), transparent),
    radial-gradient(ellipse 30% 40% at 50% 100%, rgba(123,47,190,.05), transparent);
}
/* Content paints above the ambient layer. Elements with their own
   class-based position/z-index (sticky tab bar, nav FAB) keep theirs. */
body > * { position: relative; z-index: 1 }

code, pre, .mono { font-family: 'JetBrains Mono', ui-monospace, monospace }

/* ─────────────────────────────────────────────────────────────
   Hero
   ───────────────────────────────────────────────────────────── */
.hero {
  background: var(--bg-hero);
  padding: 56px var(--pad-x) 48px;
  position: relative; overflow: hidden;
  border-bottom: 1px solid rgba(255,255,255,.05);
}
.hero::before {
  content:''; position:absolute; inset:0;
  background: radial-gradient(ellipse 60% 60% at 50% -20%, rgba(123,47,190,.1), transparent);
}
.hero::after {
  content:''; position:absolute; bottom:0; left:0; right:0; height:2px;
  background: linear-gradient(90deg, transparent, var(--p), var(--cyan), var(--p), transparent);
  background-size: 200% 100%;
  animation: gradientShift 4s ease-in-out infinite;
}
.hero > * { position: relative; z-index: 1 }

.hero-inner { max-width: var(--col); margin: 0 auto }

.hero .eyebrow {
  font-size: 11px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase;
  color: var(--pb); margin-bottom: 12px;
}
.hero h1 {
  font-size: 40px; font-weight: 800; letter-spacing: -.8px; line-height: 1.15;
  color: var(--txt); margin-bottom: 14px;
}
.hero h1 .accent {
  background: linear-gradient(90deg, var(--pb) 0%, var(--cyan) 35%, var(--pink) 65%, var(--pb) 100%);
  background-size: 200% 100%;
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
  animation: gradientShift 6s ease-in-out infinite;
}
.hero .subtitle {
  font-size: 16px; color: var(--tb); max-width: 780px;
}
.hero .badge-row { display:flex; gap:8px; margin-top:18px; flex-wrap:wrap }

.badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 13px; border-radius: 20px;
  font-size: 11px; font-weight: 700; letter-spacing: .3px;
  background: rgba(123,47,190,.12);
  border: 1px solid rgba(192,132,252,.28);
  color: var(--pb);
}
.badge.cy { background: rgba(34,211,238,.1);  border-color: rgba(34,211,238,.28);  color: var(--cyan) }
.badge.pk { background: rgba(244,114,182,.1); border-color: rgba(244,114,182,.28); color: var(--pink) }
.badge.gn { background: rgba(52,211,153,.1);  border-color: rgba(52,211,153,.28);  color: var(--grn) }
.badge.ab { background: rgba(251,191,36,.1);  border-color: rgba(251,191,36,.28);  color: var(--amb) }
.badge.rd { background: rgba(248,113,113,.1); border-color: rgba(248,113,113,.28); color: var(--red) }

/* ─────────────────────────────────────────────────────────────
   Tab navigation — THE standard nav pattern
   ───────────────────────────────────────────────────────────── */
.tab-nav {
  position: sticky; top: 0; z-index: 100;
  background: rgba(13,7,20,.88);
  backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
  border-bottom: 1px solid rgba(255,255,255,.06);
  padding: 10px var(--pad-x);
  display: flex; gap: 6px; overflow-x: auto;
  scrollbar-width: none;
}
.tab-nav::-webkit-scrollbar { display: none }
.tab-nav button {
  padding: 8px 18px; border-radius: 30px;
  border: 1px solid transparent; background: transparent;
  font-family: inherit; font-size: 12px; font-weight: 600;
  color: var(--tm); cursor: pointer;
  transition: all .25s ease; white-space: nowrap;
}
.tab-nav button:hover {
  background: rgba(255,255,255,.06); color: var(--tb);
  border-color: rgba(255,255,255,.08);
}
.tab-nav button.active {
  background: linear-gradient(135deg, var(--p), var(--pl));
  color: #fff; border-color: transparent;
  box-shadow: 0 4px 20px rgba(123,47,190,.4), inset 0 0 0 1px rgba(255,255,255,.1);
}

.tab-content {
  display: none;
  max-width: var(--col); margin: 0 auto;
  padding: 32px var(--gut) 72px;
  animation: tfi .35s var(--ease);
}
.tab-content.active { display: block }

/* ─────────────────────────────────────────────────────────────
   Section headings
   ───────────────────────────────────────────────────────────── */
.sh {
  font-size: 24px; font-weight: 800; letter-spacing: -.4px;
  color: var(--txt); margin-bottom: 8px;
  display: flex; align-items: center; gap: 10px;
}
.ss {
  font-size: 14.5px; color: var(--tm); margin-bottom: 24px; max-width: 820px;
}
.sh-sm {
  font-size: 16px; font-weight: 700; color: var(--txt);
  margin: 26px 0 10px; display: flex; align-items: center; gap: 8px;
}

/* ─────────────────────────────────────────────────────────────
   Card — the primary AI Glass panel
   ───────────────────────────────────────────────────────────── */
.card {
  background: rgba(255,255,255,.025);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(123,47,190,.15);
  border-radius: var(--radius);
  padding: 26px;
  margin-bottom: 20px;
  position: relative; overflow: hidden;
  animation: borderGlow 6s ease-in-out infinite;
  transition: all .35s var(--ease);
}
.card::before {
  content:''; position:absolute; top:0; left:0; right:0; height:1px;
  background: linear-gradient(90deg, transparent 0%, rgba(192,132,252,0) 20%, rgba(192,132,252,.4) 50%,
              rgba(34,211,238,.3) 60%, rgba(192,132,252,0) 80%, transparent 100%);
  background-size: 200% 100%;
  animation: shimmer 4s linear infinite;
}
.card::after {
  content:''; position:absolute; inset:0; border-radius:inherit;
  background: linear-gradient(135deg, rgba(123,47,190,.03) 0%, rgba(34,211,238,.04) 30%,
              rgba(244,114,182,.03) 60%, rgba(52,211,153,.02) 100%);
  opacity:.5; transition: opacity .4s ease; pointer-events:none;
}
.card:hover {
  background: rgba(255,255,255,.06);
  border-color: rgba(192,132,252,.4);
  box-shadow: 0 0 60px rgba(123,47,190,.12), 0 0 30px rgba(34,211,238,.06),
              0 12px 40px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.08);
  transform: translateY(-4px);
}
.card:hover::after { opacity: 1 }
/* Content must paint above the ::after overlay */
.card > * { position: relative; z-index: 1 }

.card h3 { font-size: 17px; font-weight: 700; color: var(--txt); margin-bottom: 8px }
.card p  { font-size: 14.5px; color: var(--tb); margin-bottom: 12px }
.card p:last-child { margin-bottom: 0 }

/* Static variant — for cards wrapping SVG playgrounds where the moving
   border would compete with the diagram's own animation. */
.card.static { animation: none; border-color: rgba(255,255,255,.09) }
.card.static::before { animation: none; opacity: .5 }
.card.static:hover { transform: none }

/* ─────────────────────────────────────────────────────────────
   Concept card grid (.cc) — subtler shimmer so grids stay calm
   ───────────────────────────────────────────────────────────── */
.cc-grid {
  display: grid; gap: 16px;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  margin: 20px 0;
}
.cc-grid.two   { grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)) }
.cc-grid.three { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)) }

.cc {
  background: rgba(255,255,255,.025);
  border: 1px solid rgba(255,255,255,.08);
  border-radius: var(--radius-sm);
  padding: 20px;
  position: relative; overflow: hidden;
  box-shadow: 0 0 10px rgba(123,47,190,.03), 0 2px 8px rgba(0,0,0,.2);
  transition: all .3s var(--ease);
}
.cc::before {
  content:''; position:absolute; top:0; left:0; right:0; height:1px;
  background: linear-gradient(90deg, transparent 0%, rgba(192,132,252,.25) 50%, transparent 100%);
  background-size: 200% 100%;
  animation: shimmer 6s linear infinite;
}
.cc > * { position: relative; z-index: 1 }
.cc:hover { transform: translateY(-4px) }

.cc h4 {
  font-size: 14px; font-weight: 700; color: var(--txt);
  margin-bottom: 6px; display: flex; align-items: center; gap: 8px;
}
.cc p { font-size: 13px; color: var(--tm); line-height: 1.65; margin: 0 }

.cc .cc-ico {
  width: 40px; height: 40px; border-radius: 11px;
  display: inline-flex; align-items: center; justify-content: center;
  margin-bottom: 11px;
  /* Icons in decorative wells need bright text colour + heavier stroke for
     contrast — NOT the accent colour, which goes muddy against the tint. */
  color: var(--txt);
}
.cc .cc-ico svg { stroke-width: 2 }

/* Colour variants — border tint at rest hints at the category */
.cc.pu { border-color: rgba(123,47,190,.14) }
.cc.cy { border-color: rgba(34,211,238,.12) }
.cc.pk { border-color: rgba(244,114,182,.12) }
.cc.gn { border-color: rgba(52,211,153,.12) }
.cc.ab { border-color: rgba(251,191,36,.12) }
.cc.rd { border-color: rgba(248,113,113,.12) }

.cc.pu .cc-ico { background: rgba(123,47,190,.14) }
.cc.cy .cc-ico { background: rgba(34,211,238,.12) }
.cc.pk .cc-ico { background: rgba(244,114,182,.12) }
.cc.gn .cc-ico { background: rgba(52,211,153,.12) }
.cc.ab .cc-ico { background: rgba(251,191,36,.12) }
.cc.rd .cc-ico { background: rgba(248,113,113,.12) }

.cc.pu:hover { border-color: rgba(192,132,252,.3); box-shadow: 0 0 28px rgba(123,47,190,.12) }
.cc.cy:hover { border-color: rgba(34,211,238,.3);  box-shadow: 0 0 28px rgba(34,211,238,.1) }
.cc.pk:hover { border-color: rgba(244,114,182,.3); box-shadow: 0 0 28px rgba(244,114,182,.1) }
.cc.gn:hover { border-color: rgba(52,211,153,.3);  box-shadow: 0 0 28px rgba(52,211,153,.1) }
.cc.ab:hover { border-color: rgba(251,191,36,.3);  box-shadow: 0 0 28px rgba(251,191,36,.08) }
.cc.rd:hover { border-color: rgba(248,113,113,.3); box-shadow: 0 0 28px rgba(248,113,113,.1) }

/* ─────────────────────────────────────────────────────────────
   Callout
   ───────────────────────────────────────────────────────────── */
.callout {
  border-radius: var(--radius-sm);
  padding: 16px 20px; margin: 18px 0;
  display: flex; gap: 13px; align-items: flex-start;
  background: rgba(255,255,255,.03);
  border: 1px solid rgba(255,255,255,.09);
  font-size: 14px; color: var(--tb);
}
.callout .co-ico { flex-shrink: 0; margin-top: 2px }
.callout strong { color: var(--txt) }
.callout.info { background: rgba(34,211,238,.07);  border-color: rgba(34,211,238,.22) }
.callout.info .co-ico { color: var(--cyan) }
.callout.warn { background: rgba(251,191,36,.07);  border-color: rgba(251,191,36,.22) }
.callout.warn .co-ico { color: var(--amb) }
.callout.good { background: rgba(52,211,153,.07);  border-color: rgba(52,211,153,.22) }
.callout.good .co-ico { color: var(--grn) }
.callout.bad  { background: rgba(248,113,113,.07); border-color: rgba(248,113,113,.22) }
.callout.bad .co-ico { color: var(--red) }
.callout.tip  { background: rgba(123,47,190,.08);  border-color: rgba(192,132,252,.22) }
.callout.tip .co-ico { color: var(--pb) }

/* ─────────────────────────────────────────────────────────────
   Hub cards — module / lab / service tiles
   ───────────────────────────────────────────────────────────── */
.mod-grid {
  display: grid; gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
  margin: 22px 0;
}

.mod-card, .lab-card, .svc-card {
  display: block; text-decoration: none;
  background: rgba(255,255,255,.025);
  backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
  border: 1px solid rgba(123,47,190,.15);
  border-radius: var(--radius);
  padding: 24px;
  position: relative; overflow: hidden;
  animation: borderGlow 6s ease-in-out infinite;
  transition: all .35s var(--ease);
}
.mod-card::before, .lab-card::before, .svc-card::before {
  content:''; position:absolute; top:0; left:0; right:0; height:1px;
  background: linear-gradient(90deg, transparent 0%, rgba(192,132,252,0) 20%, rgba(192,132,252,.4) 50%,
              rgba(34,211,238,.3) 60%, rgba(192,132,252,0) 80%, transparent 100%);
  background-size: 200% 100%;
  animation: shimmer 4s linear infinite;
}
.mod-card::after, .lab-card::after, .svc-card::after {
  content:''; position:absolute; inset:0; border-radius:inherit;
  background: linear-gradient(135deg, rgba(123,47,190,.03) 0%, rgba(34,211,238,.04) 30%,
              rgba(244,114,182,.03) 60%, rgba(52,211,153,.02) 100%);
  opacity:.5; transition: opacity .4s ease; pointer-events:none;
}
.mod-card > *, .lab-card > *, .svc-card > * { position: relative; z-index: 1 }
.mod-card:hover, .lab-card:hover, .svc-card:hover {
  background: rgba(255,255,255,.06);
  border-color: rgba(192,132,252,.4);
  box-shadow: 0 0 60px rgba(123,47,190,.12), 0 0 30px rgba(34,211,238,.06),
              0 12px 40px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.08);
  transform: translateY(-5px);
}
.mod-card:hover::after, .lab-card:hover::after, .svc-card:hover::after { opacity: 1 }

.mod-card .mc-top { display:flex; align-items:center; justify-content:space-between; margin-bottom:14px }
.mod-card .mc-ico {
  width: 46px; height: 46px; border-radius: 13px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(123,47,190,.14); color: var(--txt);
  animation: iconFloat 4s ease-in-out infinite;
}
.mod-card .mc-ico svg { stroke-width: 2 }
.mod-card .mc-id {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; font-weight: 600; color: var(--tm);
  letter-spacing: .5px;
}
.mod-card h3 { font-size: 18px; font-weight: 700; color: var(--txt); margin-bottom: 7px }
.mod-card p  { font-size: 13.5px; color: var(--tm); line-height: 1.6; margin-bottom: 14px }
.mod-card .mc-meta { display: flex; gap: 7px; flex-wrap: wrap }

/* Coming-soon tiles must read as clearly inactive */
.mod-card.soon, .lab-card.soon {
  animation: none; opacity: .4; pointer-events: none;
}
.mod-card.soon::before, .lab-card.soon::before { animation: none }

/* ─────────────────────────────────────────────────────────────
   Tables
   ───────────────────────────────────────────────────────────── */
.tbl-wrap { overflow-x: auto; margin: 18px 0; border-radius: var(--radius-sm) }
table.dt { width: 100%; border-collapse: collapse; font-size: 13.5px; min-width: 520px }
table.dt th {
  text-align: left; padding: 11px 14px;
  background: rgba(123,47,190,.1);
  color: var(--pb);
  font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .7px;
  border-bottom: 1px solid rgba(192,132,252,.2);
  white-space: nowrap;
}
table.dt td {
  padding: 11px 14px; color: var(--tb);
  border-bottom: 1px solid rgba(255,255,255,.05);
  vertical-align: top;
}
table.dt tbody tr { transition: background .2s ease }
table.dt tbody tr:hover { background: rgba(123,47,190,.07) }
table.dt td strong { color: var(--txt) }

/* ─────────────────────────────────────────────────────────────
   Code blocks
   ───────────────────────────────────────────────────────────── */
.code {
  background: rgba(8,8,14,.75);
  border: 1px solid rgba(255,255,255,.08);
  border-radius: var(--radius-xs);
  padding: 15px 17px; margin: 14px 0;
  overflow-x: auto;
  font-family: 'JetBrains Mono', monospace;
  font-size: 12.5px; line-height: 1.75;
  color: #D8E2F0;
  white-space: pre;
}
.code-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; margin: 16px 0 0;
  padding: 8px 14px;
  background: rgba(123,47,190,.1);
  border: 1px solid rgba(192,132,252,.18);
  border-bottom: none;
  border-radius: var(--radius-xs) var(--radius-xs) 0 0;
  font-size: 11px; font-weight: 700; letter-spacing: .5px;
  color: var(--pb); text-transform: uppercase;
}
.code-head + .code { margin-top: 0; border-radius: 0 0 var(--radius-xs) var(--radius-xs) }
.tok-k { color: #C084FC }   /* keyword  */
.tok-s { color: #34D399 }   /* string   */
.tok-c { color: #64748B }   /* comment  */
.tok-n { color: #22D3EE }   /* number   */

.copy-btn {
  background: rgba(123,47,190,.16); border: 1px solid rgba(192,132,252,.3);
  color: var(--pb); padding: 3px 10px; border-radius: 6px;
  font-family: inherit; font-size: 10px; font-weight: 700;
  cursor: pointer; transition: all .2s ease;
  display: inline-flex; align-items: center; gap: 5px;
  text-transform: uppercase; letter-spacing: .5px;
}
.copy-btn:hover { background: rgba(123,47,190,.28); border-color: rgba(192,132,252,.5) }
.copy-btn.done { background: rgba(52,211,153,.2); border-color: rgba(52,211,153,.45); color: var(--grn) }

/* ─────────────────────────────────────────────────────────────
   Pills / chips / key-value lists
   ───────────────────────────────────────────────────────────── */
.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 11px; border-radius: 14px;
  font-size: 10.5px; font-weight: 700; letter-spacing: .4px;
  background: rgba(255,255,255,.05);
  border: 1px solid rgba(255,255,255,.1);
  color: var(--tm);
}
.pill.pu { background: rgba(123,47,190,.14); border-color: rgba(192,132,252,.3); color: var(--pb) }
.pill.cy { background: rgba(34,211,238,.12); border-color: rgba(34,211,238,.3);  color: var(--cyan) }
.pill.pk { background: rgba(244,114,182,.12);border-color: rgba(244,114,182,.3); color: var(--pink) }
.pill.gn { background: rgba(52,211,153,.12); border-color: rgba(52,211,153,.3);  color: var(--grn) }
.pill.ab { background: rgba(251,191,36,.12); border-color: rgba(251,191,36,.3);  color: var(--amb) }
.pill.rd { background: rgba(248,113,113,.12);border-color: rgba(248,113,113,.3); color: var(--red) }

.kv { display: grid; gap: 10px; margin: 16px 0 }
.kv-row {
  display: grid; grid-template-columns: 160px 1fr; gap: 14px;
  padding-bottom: 10px; border-bottom: 1px solid rgba(255,255,255,.05);
  font-size: 13.5px;
}
.kv-row:last-child { border-bottom: none; padding-bottom: 0 }
.kv-row .k { color: var(--pb); font-weight: 700; font-size: 12px; text-transform: uppercase; letter-spacing: .5px }
.kv-row .v { color: var(--tb) }

/* Bullet lists inside cards */
.blist { list-style: none; margin: 10px 0 }
.blist li {
  position: relative; padding-left: 20px; margin-bottom: 9px;
  font-size: 14px; color: var(--tb);
}
.blist li::before {
  content: ''; position: absolute; left: 4px; top: 10px;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--pb); opacity: .7;
}
.blist li strong { color: var(--txt) }

/* ─────────────────────────────────────────────────────────────
   SVG playground shell + shared SVG classes
   ───────────────────────────────────────────────────────────── */
.svg-wrap {
  background: rgba(255,255,255,.02);
  border: 1px solid rgba(255,255,255,.07);
  border-radius: var(--radius-sm);
  padding: 20px 16px; margin: 18px 0;
  overflow-x: auto;
}
.svg-wrap svg { width: 100%; display: block; max-width: 960px; margin: 0 auto }

.narrator {
  display: flex; align-items: center; gap: 12px;
  background: rgba(123,47,190,.08);
  border: 1px solid rgba(192,132,252,.22);
  border-radius: var(--radius-sm);
  padding: 14px 18px; margin-bottom: 16px; min-height: 56px;
}
.narrator .nr-ico { flex-shrink: 0; color: var(--pb) }
.narrator .nr-txt { font-size: 13.5px; color: var(--tb); line-height: 1.6 }
.narrator .nr-txt strong { color: var(--pb) }

.autoplay-btn {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 11px 24px; border-radius: 26px;
  border: 1.5px solid rgba(192,132,252,.32);
  background: rgba(123,47,190,.1);
  font-family: inherit; font-size: 13px; font-weight: 700;
  color: var(--pb); cursor: pointer;
  transition: all .3s var(--ease);
  margin-bottom: 14px;
}
.autoplay-btn:hover {
  background: rgba(123,47,190,.2); border-color: rgba(192,132,252,.55);
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(123,47,190,.2);
}
.autoplay-btn.playing {
  background: linear-gradient(135deg, var(--p), var(--pl));
  color: #fff; border-color: transparent;
  box-shadow: 0 6px 24px rgba(123,47,190,.4);
}

/* Pre-themed connector edge classes. Put the class on the path and let the
   stylesheet own width + colour so arrows stay bold in BOTH themes.
   mobile.css supplies the light-mode counterparts. */
.edge-p { stroke: rgba(192,132,252,.6); stroke-width: 2.4; fill: none }
.edge-c { stroke: rgba(34,211,238,.6);  stroke-width: 2.4; fill: none }
.edge-k { stroke: rgba(244,114,182,.6); stroke-width: 2.4; fill: none }
.edge-g { stroke: rgba(52,211,153,.6);  stroke-width: 2.4; fill: none }
.edge-r { stroke: rgba(248,113,113,.6); stroke-width: 2.4; fill: none }
.edge-dash { stroke-dasharray: 7 5; animation: dashFlow 1s linear infinite }

/* Decorative strokes use DIFFERENT alphas so the light-theme boldening
   rules for .edge-* never catch them. */
.edge-faint { stroke: rgba(255,255,255,.28); stroke-width: 1.4; fill: none }

.node-label { font-size: 12px; font-weight: 700; text-anchor: middle; fill: var(--txt) }
.node-sub   { font-size: 10px; text-anchor: middle; fill: var(--tm) }
.flow-label { font-size: 10px; font-weight: 800; text-anchor: middle; fill: var(--tm);
              letter-spacing: .6px; text-transform: uppercase }

.svg-node { cursor: pointer; transition: opacity .25s ease }
.svg-node:hover { opacity: .85 }

.particle { filter: drop-shadow(0 0 4px rgba(192,132,252,.6)) }

/* ─────────────────────────────────────────────────────────────
   Vertical timeline — for prose-per-step sequences.
   Deliberately does NOT set background/border on the card: the row's
   body reuses .card so it inherits the themed surface for free.
   ───────────────────────────────────────────────────────────── */
.tl { margin: 20px 0 }
.tl-row {
  display: grid; grid-template-columns: 78px 26px 1fr;
  gap: 0; align-items: start;
}
.tl-time {
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; font-weight: 600; color: var(--tm);
  padding-top: 22px; text-align: right; padding-right: 12px;
}
.tl-rail { position: relative; justify-self: center; width: 26px; align-self: stretch }
.tl-rail::before {
  content: ''; position: absolute; left: 50%; top: 0; bottom: 0;
  width: 2px; transform: translateX(-50%);
  background: var(--rail, rgba(192,132,252,.4));
}
.tl-row:last-child .tl-rail::before { bottom: calc(100% - 30px) }
.tl-dot {
  position: absolute; left: 50%; top: 22px;
  width: 12px; height: 12px; border-radius: 50%;
  transform: translateX(-50%);
  background: var(--dot, var(--pb));
  box-shadow: 0 0 0 4px var(--dotring, rgba(123,47,190,.18));
}
.tl-row.active .tl-dot { animation: breathe 2s ease-in-out infinite }
.tl-body { padding: 0 0 16px 8px }
.tl-body h4 { font-size: 15px; font-weight: 700; color: var(--txt); margin-bottom: 6px }
.tl-body p  { font-size: 13.5px; color: var(--tb); margin: 0 }

/* State modifiers set ONLY colour vars */
.tl-row.st-p { --dot:#C084FC; --rail:rgba(192,132,252,.42); --dotring:rgba(123,47,190,.18) }
.tl-row.st-c { --dot:#22D3EE; --rail:rgba(34,211,238,.42);  --dotring:rgba(34,211,238,.16) }
.tl-row.st-k { --dot:#F472B6; --rail:rgba(244,114,182,.42); --dotring:rgba(244,114,182,.16) }
.tl-row.st-g { --dot:#34D399; --rail:rgba(52,211,153,.42);  --dotring:rgba(52,211,153,.16) }
.tl-row.st-a { --dot:#FBBF24; --rail:rgba(251,191,36,.42);  --dotring:rgba(251,191,36,.16) }
.tl-row.st-r { --dot:#F87171; --rail:rgba(248,113,113,.42); --dotring:rgba(248,113,113,.16) }

/* ─────────────────────────────────────────────────────────────
   "What's new" announcement rows (.wn)

   One shared component, four accents. The accent is carried on the
   CONTAINER as two custom properties, so the light-theme layer only has
   to flip the vars rather than re-declare every rule:

     --wa    the accent colour  (text / chip foreground)
     --wa-r  the same colour as bare "r,g,b" for rgba() alpha work

   Default is purple; add .acc-cy / .acc-pk / .acc-gn on .wn-list to
   match the host module's accent.
   ───────────────────────────────────────────────────────────── */
.wn-list {
  --wa: var(--pb);  --wa-r: 192,132,252;
  display: grid; gap: 14px; margin: 20px 0;
}
.wn-list.acc-cy { --wa: var(--cyan); --wa-r: 34,211,238 }
.wn-list.acc-pk { --wa: var(--pink); --wa-r: 244,114,182 }
.wn-list.acc-gn { --wa: var(--grn);  --wa-r: 52,211,153 }

.wn {
  position: relative; overflow: hidden;
  padding: 18px 20px 16px;
  border-radius: var(--radius-sm);
  background: rgba(255,255,255,.025);
  border: 1px solid rgba(255,255,255,.08);
  box-shadow: 0 0 10px rgba(var(--wa-r),.03), 0 2px 8px rgba(0,0,0,.2);
  transition: all .3s var(--ease);
}
/* Slower, quieter shimmer than .card — these appear 6–10 to a screen */
.wn::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: linear-gradient(90deg, transparent 0%, rgba(var(--wa-r),.28) 50%, transparent 100%);
  background-size: 200% 100%;
  animation: shimmer 7s linear infinite;
}
.wn > * { position: relative; z-index: 1 }
.wn:hover {
  transform: translateY(-3px);
  background: rgba(255,255,255,.05);
  border-color: rgba(var(--wa-r),.32);
  box-shadow: 0 0 28px rgba(var(--wa-r),.1), 0 8px 24px rgba(0,0,0,.35);
}

/* Meta strip — date chip, then service pills */
.wn-top { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; margin-bottom: 10px }
.wn-when {
  font-family: 'JetBrains Mono', monospace;
  font-size: 10px; font-weight: 600; letter-spacing: .6px; text-transform: uppercase;
  color: var(--tm); padding: 3px 9px; border-radius: 7px;
  background: rgba(255,255,255,.04);
  border: 1px solid rgba(255,255,255,.1);
  white-space: nowrap;
}
/* Flags an item that changes what the course deck says */
.wn-shift {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 10px; font-weight: 800; letter-spacing: .6px; text-transform: uppercase;
  padding: 3px 10px; border-radius: 12px;
  background: rgba(251,191,36,.14);
  border: 1px solid rgba(251,191,36,.34);
  color: var(--amb);
}

.wn h4 { font-size: 14.5px; font-weight: 700; color: var(--txt); line-height: 1.45; margin-bottom: 8px }
.wn p  { font-size: 13.5px; color: var(--tb); line-height: 1.7; margin: 0 0 9px }
.wn p:last-child { margin-bottom: 0 }

/* "Why it matters here" line — inline label, no border-left accent */
.wn-why { font-size: 13px; color: var(--tm); line-height: 1.65 }
.wn-why b {
  color: var(--wa); font-weight: 800;
  font-size: 10px; letter-spacing: .8px; text-transform: uppercase;
  margin-right: 7px;
}

/* Source-link chips. Every What's New claim carries one. */
.wn-src { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 12px }
.wn-src a {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 11px; border-radius: 13px;
  font-size: 11px; font-weight: 600; letter-spacing: .2px;
  text-decoration: none; border-bottom: none;
  background: rgba(var(--wa-r),.09);
  border: 1px solid rgba(var(--wa-r),.28);
  color: var(--wa);
  transition: all .22s ease;
}
.wn-src a:hover {
  background: rgba(var(--wa-r),.2);
  border-color: rgba(var(--wa-r),.55);
  transform: translateY(-1px);
}

/* Freshness stamp shown under the tab standfirst */
.wn-asof {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: 'JetBrains Mono', monospace;
  font-size: 11px; color: var(--tm);
  padding: 7px 14px; border-radius: 10px;
  background: rgba(255,255,255,.03);
  border: 1px solid rgba(255,255,255,.09);
  margin-bottom: 20px;
}
.wn-asof strong { color: var(--txt); font-weight: 600 }

/* ─────────────────────────────────────────────────────────────
   Footer
   ───────────────────────────────────────────────────────────── */
.site-footer {
  text-align: center; padding: 34px 24px 46px;
  border-top: 1px solid rgba(255,255,255,.05);
  font-size: 12px; color: var(--td);
}
.site-footer strong { color: var(--tm) }

/* ─────────────────────────────────────────────────────────────
   Scroll reveal (one-shot, applied by page JS)
   ───────────────────────────────────────────────────────────── */
.reveal { opacity: 0; transform: translateY(14px);
          transition: opacity .5s var(--ease), transform .5s var(--ease) }
.reveal.visible { opacity: 1; transform: none }

/* ─────────────────────────────────────────────────────────────
   Reduced motion — keep the theme, kill the movement
   ───────────────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .reveal { opacity: 1; transform: none }
}
