:root {
  /* dark theme (default) */
  --bg: #0f1115;
  --panel: #161a21;
  --text: #e7eaf0;
  --muted: #9aa3b2;
  --accent: #6ea8fe;
  --accent-soft: rgba(110, 168, 254, 0.12);
  --border: #232a35;
  --btn-text: #0b0e13;
  --shadow: rgba(0, 0, 0, 0.35);
  --radius: 14px;
  --maxw: 880px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

html[data-theme="light"] {
  --bg: #fbfcfe;
  --panel: #ffffff;
  --text: #1a1f29;
  --muted: #5b6472;
  --accent: #2563eb;
  --accent-soft: rgba(37, 99, 235, 0.10);
  --border: #e4e8ee;
  --btn-text: #ffffff;
  --shadow: rgba(20, 30, 60, 0.12);
}

/* smooth the swap */
body, .card, .btn, .hero { transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease; }

* { box-sizing: border-box; }

/* Theme toggle */
.theme-toggle {
  position: fixed;
  top: 18px;
  right: 18px;
  z-index: 20;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.15s ease, transform 0.12s ease;
}

.theme-toggle:hover { border-color: var(--accent); transform: translateY(-1px); }

html[data-theme="dark"] .theme-icon-light { display: none; }
html[data-theme="light"] .theme-icon-dark { display: none; }

/* Scroll progress bar (Lesson 5) — fills as you scroll the page.
   Driven by scroll position, not time: animation-timeline: scroll(). */
.scroll-progress {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 30;
  height: 3px;
  width: 100%;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 0 50%; /* grow from the left edge */
}

/* Only animate where scroll timelines are supported; elsewhere the bar stays
   at scaleX(0) (invisible) — no broken UI. */
@supports (animation-timeline: scroll()) {
  .scroll-progress {
    animation-name: progress-grow;
    animation-timing-function: linear;
    animation-fill-mode: both;
    /* tie progress to the root scroller's vertical (block) axis */
    animation-timeline: scroll(root block);
  }
}

@keyframes progress-grow {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-progress { animation: none; }
}

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 24px;
}

/* Hero */
.hero {
  position: relative;
  overflow: hidden;
  /* fluid padding: scales with viewport between the min and max — no breakpoint. */
  padding: clamp(56px, 10vw, 96px) 0 clamp(40px, 7vw, 72px);
  border-bottom: 1px solid var(--border);
}

/* Ambient animated gradient — three soft accent blobs that slowly drift.
   Lives on a ::before layer behind the content so text stays crisp. */
.hero::before {
  content: "";
  position: absolute;
  inset: -25%;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(40% 40% at 18% 28%, var(--accent-soft), transparent 70%),
    radial-gradient(38% 38% at 82% 22%, var(--accent-soft), transparent 70%),
    radial-gradient(34% 34% at 60% 82%, var(--accent-soft), transparent 70%);
  animation: hero-drift 20s ease-in-out infinite alternate;
}

/* Content must sit above the gradient layer. */
.hero .wrap { position: relative; z-index: 1; }

@keyframes hero-drift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(0, -4%, 0) scale(1.08); }
}

@media (prefers-reduced-motion: reduce) {
  .hero::before { animation: none; }
}

.eyebrow {
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--accent);
  margin: 0 0 18px;
}

.hero h1 {
  font-size: clamp(2rem, 5vw, 3.1rem);
  line-height: 1.1;
  margin: 0 0 24px;
  letter-spacing: -0.02em;
}

.tagline {
  font-size: clamp(1.15rem, 3.5vw, 1.4rem);
  color: var(--text);
  font-weight: 500;
  margin: 0 0 18px;
  letter-spacing: -0.01em;
}

.lede {
  font-size: 1.05rem;
  color: var(--muted);
  max-width: 620px;
  margin: 0 0 36px;
}

.cta { display: flex; gap: 14px; flex-wrap: wrap; }

.btn {
  display: inline-block;
  padding: 12px 22px;
  border-radius: 10px;
  font-weight: 600;
  text-decoration: none;
  background: var(--accent);
  color: var(--btn-text);
  border: 1px solid var(--accent);
  transition: transform 0.12s ease, opacity 0.12s ease;
}

.btn:hover { transform: translateY(-1px); opacity: 0.92; }

.btn.ghost {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
}

/* Sections */
.section-title {
  font-size: clamp(1.35rem, 4vw, 1.6rem);
  margin: 72px 0 6px;
  letter-spacing: -0.01em;
}

.section-sub {
  color: var(--muted);
  margin: 0 0 36px;
}

/* Cards */
.cards {
  display: grid;
  /* auto-fit + minmax = responsive with NO media query: each column is at least
     280px and grows to share leftover space (1fr). When the row can't fit two
     280px columns, it wraps to one automatically. */
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 22px;
  padding-bottom: 80px;
}

.card {
  /* flex COLUMN: stack children vertically, one dimension. Combined with the
     grid stretching all cards to equal height, this lets us pin the link to
     the bottom no matter how long the description is. */
  display: flex;
  flex-direction: column;
  /* make the card a query container so its children can react to the CARD's
     width (not the viewport's). The card is wider in 2-col, narrow in 1-col. */
  container-type: inline-size;
  container-name: card;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 26px;
  transition: border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}

.card:hover {
  border-color: var(--accent);
  transform: translateY(-4px);
  box-shadow: 0 14px 34px var(--shadow);
}

.kicker {
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--accent);
  margin: 0 0 12px;
}

.card h3 { font-size: 1.35rem; margin: 0 0 12px; }

.card p { color: var(--muted); margin: 0 0 16px; }

/* Tag pills: a flex ROW that wraps. Demonstrates the other axis of flexbox
   plus flex-wrap + gap. */
.tags {
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.tags li {
  font-size: 0.76rem;
  color: var(--muted);
  background: var(--accent-soft);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 11px;
}

/* When the CARD itself is under 330px wide, tighten its type. Note this keys off
   the card's width, not the screen — the same component adapts wherever it lives. */
@container card (max-width: 330px) {
  .card h3 { font-size: 1.15rem; }
  .tags li { font-size: 0.72rem; }
}

/* Focus rings for keyboard users. :focus-visible (not :focus) means the ring
   shows on keyboard navigation but NOT on mouse clicks — no ugly outline when
   you click a button, but full visibility when you Tab. Accessibility, done right. */
.btn:focus-visible,
.card-link:focus-visible,
.theme-toggle:focus-visible,
.footer a:focus-visible,
.back:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 6px;
}

.card-link {
  /* margin-top:auto in a flex column eats all the leftover vertical space above
     this element — pushing it to the bottom. align-self stops it stretching
     full width (flex columns stretch children on the cross axis by default). */
  margin-top: auto;
  align-self: flex-start;
  color: var(--accent);
  text-decoration: none;
  font-weight: 600;
}

.card-link:hover { text-decoration: underline; }

/* Arrow nudge: when the card is hovered, the arrow slides right.
   inline-block is required — you can't transform a plain inline element. */
.card-link .arrow {
  display: inline-block;
  transition: transform 0.18s ease;
}

.card:hover .card-link .arrow { transform: translateX(5px); }

/* Footer */
.footer {
  border-top: 1px solid var(--border);
  padding: 32px 0;
  color: var(--muted);
}

.footer .wrap {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.footer a { color: var(--muted); text-decoration: none; margin-left: 18px; }
.footer a:hover { color: var(--text); }

/* Scroll-reveal (Lesson 1) */
/* Resting state: invisible + nudged down. JS adds .is-visible to animate in. */
.reveal {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.reveal.is-visible {
  opacity: 1;
  transform: none;
}

/* Stagger: the 2nd card lands a beat after the 1st. */
.reveal[data-delay="1"] { transition-delay: 0.12s; }
.reveal[data-delay="2"] { transition-delay: 0.24s; }
.reveal[data-delay="3"] { transition-delay: 0.36s; }

/* Accessibility: users who ask for less motion get the content, not the animation. */
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* Project pages */
.article-body {
  padding: 72px 0 96px;
  max-width: 720px;
}

.article-body .back {
  color: var(--accent);
  text-decoration: none;
  font-size: 0.9rem;
}

/* Small inline status pill (e.g. WIP). */
.badge {
  display: inline-block;
  vertical-align: middle;
  margin-left: 12px;
  font-size: 0.55em;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--accent);
  background: var(--accent-soft);
  border: 1px solid var(--accent);
  border-radius: 999px;
  padding: 3px 10px;
}

/* About paragraph on the front page */
.about-text { max-width: 620px; color: var(--muted); padding-bottom: 40px; }

/* ---- Project writeup components ---- */
.article-body .lead { font-size: 1.15rem; color: var(--text); margin: 0 0 24px; }

/* Repo cards (the pieces of the system) */
.repo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px;
  margin: 18px 0;
  padding: 0;
  list-style: none;
}
.repo-grid li {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  background: var(--panel);
}
.repo-grid strong { display: block; margin-bottom: 4px; }
.repo-grid span { color: var(--muted); font-size: 0.92rem; }

/* Numbered data-flow */
.flow { list-style: none; counter-reset: step; padding: 0; margin: 18px 0; }
.flow li {
  position: relative;
  padding: 6px 0 16px 42px;
  border-left: 2px solid var(--border);
  margin-left: 14px;
}
.flow li:last-child { border-left-color: transparent; }
.flow li::before {
  counter-increment: step;
  content: counter(step);
  position: absolute;
  left: -15px;
  top: 0;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: var(--btn-text);
  border-radius: 50%;
  font-size: 0.85rem;
  font-weight: 700;
}

/* Decision blocks */
.decision {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
  padding: 16px 18px;
  margin: 16px 0;
  background: var(--panel);
}
.decision h3 { margin: 0 0 8px; font-size: 1.08rem; }
.decision p { margin: 6px 0; }
.decision .tag {
  font-size: 0.7rem;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-weight: 700;
}
.decision .tradeoff { color: var(--muted); font-size: 0.95rem; }

/* Results table */
.article-body table {
  border-collapse: collapse;
  width: 100%;
  margin: 18px 0;
  font-size: 0.95rem;
}
.article-body th,
.article-body td {
  text-align: left;
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
}
.article-body th { color: var(--muted); font-weight: 600; }
.article-body table.metrics td:not(:first-child),
.article-body table.metrics th:not(:first-child) { text-align: right; font-variant-numeric: tabular-nums; }

/* Now / Next / Later roadmap */
.roadmap {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 14px;
  margin: 18px 0;
}
.roadmap > div {
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 14px 16px;
  background: var(--panel);
}
.roadmap h3 { margin: 0 0 8px; font-size: 1rem; }
.roadmap ul { margin: 0; padding-left: 1.1rem; }
.roadmap li { font-size: 0.92rem; color: var(--muted); margin-bottom: 6px; }

/* Interactive system diagram (SVG, Tier 3) */
.diagram-wrap { margin: 18px 0; }
.diagram {
  width: 100%;
  height: auto;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--panel);
}
#system-diagram marker path { fill: var(--muted); }
.edge { stroke: var(--muted); stroke-width: 2; opacity: 0.7; }
.edge-label { fill: var(--muted); font-size: 12px; }
.edge-label-bg { fill: var(--panel); }
.node rect {
  fill: var(--bg);
  stroke: var(--border);
  stroke-width: 1.5;
  cursor: pointer;
  transition: stroke 0.15s ease, fill 0.15s ease;
}
.node text {
  fill: var(--text);
  font-size: 15px;
  font-weight: 600;
  pointer-events: none;
}
.node:hover rect { stroke: var(--accent); }
.node.active rect { stroke: var(--accent); fill: var(--accent-soft); }
.diagram-detail {
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: 10px;
  padding: 14px 16px;
  background: var(--panel);
  margin-top: 12px;
  color: var(--muted);
}

.article-body h1 { font-size: 2.2rem; margin: 18px 0 8px; letter-spacing: -0.02em; }
.article-body .subtitle { color: var(--muted); font-size: 1.05rem; margin: 0 0 36px; }
.article-body h2 { margin: 40px 0 12px; font-size: 1.3rem; }
.article-body p, .article-body li { color: var(--text); }
.article-body code {
  background: var(--accent-soft);
  padding: 2px 6px;
  border-radius: 6px;
  font-size: 0.9em;
}

/* Responsive */
/* No viewport/breakpoint media queries left: the grid auto-fits and the
   spacing/type clamp, so the layout is intrinsically responsive. (The only
   @media rules remaining are prefers-reduced-motion — a user *preference*
   query, not a screen-width breakpoint.) */
