/* ==========================================================================
   DevOps Diary — plotter-print design system
   Palette: cool paper, ink navy, blueprint cobalt, signal magenta
   ========================================================================== */

:root {
  /* --- color: light ("plotter print") --- */
  --paper:        #e7eaee;
  --panel:        #f6f8fa;
  --panel-2:      #ffffff;
  --ink:          #131a24;
  --ink-soft:     #55606e;
  --ink-faint:    #8a94a1;
  --rule:         #c8cfd8;
  --cobalt:       #1b3be0;
  --cobalt-soft:  #e4e8fd;
  --magenta:      #d6215f;
  --magenta-soft: #fce4ec;
  --ok:           #0f8a5f;
  --ok-soft:      #dff2e9;
  --warn:         #b26a00;
  --terminal-bg:  #101722;
  --terminal-ink: #dbe3ee;

  /* --- sky: daytime, high overcast --- */
  /* The zenith is capped at this lightness deliberately: the sky is fixed, so
     scrolling body text passes over every stop, and #bcdef7 is the darkest
     blue that still clears 4.5:1 against --ink-soft. */
  --sky-1:    #bcdef7;   /* zenith */
  --sky-2:    #d0e8fa;
  --sky-3:    #e6f2fd;
  --sky-4:    #f5fafe;   /* horizon */
  --cloud:    rgba(255, 255, 255, 0.92);
  --cloud-dim: rgba(255, 255, 255, 0.5);
  --cloud-0:  rgba(255, 255, 255, 0);
  --frost:    72%;       /* how opaque section bands are over the sky */
  --frost-card: 93%;     /* cards stay near-solid so text keeps its contrast */

  /* --- type --- */
  --font-display: "Bricolage Grotesque", "Archivo", system-ui, -apple-system, sans-serif;
  --font-body:    "Newsreader", Georgia, "Times New Roman", serif;
  --font-mono:    "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  --step--1: clamp(0.78rem, 0.76rem + 0.1vw, 0.84rem);
  --step-0:  clamp(1rem, 0.97rem + 0.15vw, 1.09rem);
  --step-1:  clamp(1.2rem, 1.12rem + 0.4vw, 1.4rem);
  --step-2:  clamp(1.45rem, 1.3rem + 0.75vw, 1.9rem);
  --step-3:  clamp(1.8rem, 1.5rem + 1.4vw, 2.7rem);
  --step-4:  clamp(2.2rem, 1.6rem + 2.9vw, 4.3rem);

  /* --- space / shape --- */
  --gutter: clamp(1.15rem, 4vw, 2.5rem);
  --band-y: clamp(3.5rem, 7vw, 6.5rem);
  --r-sm: 3px;
  --r-md: 6px;
  --r-lg: 10px;
  --shadow: 0 1px 0 var(--rule), 0 10px 30px -22px rgba(19, 26, 36, 0.55);
  --max: 1180px;

  /* Topbar height is shared: the sticky bar sets it, the mobile nav drawer
     hangs off it, and anchor targets scroll clear of it. */
  --topbar-h: 60px;
  /* Comfortable touch target. Pointer-precision queries scale this up. */
  --touch: 34px;

  color-scheme: light;
}

:root[data-theme="dark"] {
  color-scheme: dark;

  --paper:        #0e1218;
  --panel:        #161c25;
  --panel-2:      #1c2430;
  --ink:          #e9eef4;
  --ink-soft:     #a3b0bf;
  --ink-faint:    #6d7a8a;
  --rule:         #2b3644;
  --cobalt:       #7d92ff;
  --cobalt-soft:  #1b2440;
  --magenta:      #ff628f;
  --magenta-soft: #35172a;
  --ok:           #3fce97;
  --ok-soft:      #122e26;
  --warn:         #e8a33d;
  --terminal-bg:  #080c12;
  --terminal-ink: #dbe3ee;
  --shadow: 0 1px 0 var(--rule), 0 14px 34px -24px #000;

  /* --- sky: night. clouds go dark, or they punch holes in the page --- */
  --sky-1:    #060a12;
  --sky-2:    #0b1220;
  --sky-3:    #111b2c;
  --sky-4:    #16202f;
  --cloud:    rgba(126, 152, 196, 0.17);
  --cloud-dim: rgba(112, 138, 182, 0.1);
  --cloud-0:  rgba(126, 152, 196, 0);
  --frost:    78%;
  --frost-card: 95%;
}

/* ==========================================================================
   base
   ========================================================================== */

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* The sky lives on <html> so it always fills the viewport, even on short pages.
   <body> stays transparent so the cloud layers below can show through. */
html {
  background:
    linear-gradient(to bottom,
      var(--sky-1) 0%,
      var(--sky-2) 30%,
      var(--sky-3) 62%,
      var(--sky-4) 100%) fixed;
}

body {
  margin: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.68;
  font-synthesis-weight: none;
}

/* Safety net for the wide bits (code blocks, tables, the pipeline board). Every
   one of them already scrolls inside its own wrapper, but a stray unbreakable
   token should never make the whole page pan sideways. `clip` contains the
   overflow without creating a scroll container, so the sticky topbar and the
   sticky chapter TOC both keep working; scoping it to <main> keeps it away from
   the fixed cloud layers on <body>, which deliberately overhang the viewport. */
main { overflow-x: clip; }

/* Android/iOS paint a translucent grey box over any tapped element. It reads
   as a rendering glitch on the custom buttons, tiles and cards here, all of
   which already have their own :active and state styling. */
* { -webkit-tap-highlight-color: transparent; }

/* ---------------------------------------------------------------- the clouds
   Three fixed layers drifting at different speeds for parallax. Each cloud is
   a cluster of soft radial gradients — no images, so it costs nothing to load
   and recolours itself for dark mode. x positions are px (tile-relative),
   y positions are % (viewport-relative) so clouds spread over any screen.
   Each layer is one tile wider than the viewport and translates by exactly
   one tile width, which makes the loop seamless. */

html::before,
body::before,
body::after {
  content: "";
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  pointer-events: none;
  background-repeat: repeat;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

/* high cirrus — small, faint, barely moving */
html::before {
  z-index: -3;
  right: -760px;
  background-size: 760px 100%;
  background-image:
    radial-gradient(46px 15px at 90px 9%,   var(--cloud-dim), var(--cloud-0)),
    radial-gradient(34px 12px at 132px 11%, var(--cloud-dim), var(--cloud-0)),
    radial-gradient(40px 13px at 418px 21%, var(--cloud-dim), var(--cloud-0)),
    radial-gradient(28px 10px at 456px 23%, var(--cloud-dim), var(--cloud-0)),
    radial-gradient(52px 16px at 615px 14%, var(--cloud-dim), var(--cloud-0));
  animation-name: drift-far;
  animation-duration: 260s;
}

/* mid deck */
body::before {
  z-index: -2;
  right: -1080px;
  background-size: 1080px 100%;
  background-image:
    radial-gradient(80px 27px at 160px 31%, var(--cloud), var(--cloud-0)),
    radial-gradient(58px 21px at 216px 34%, var(--cloud), var(--cloud-0)),
    radial-gradient(44px 17px at 118px 35%, var(--cloud-dim), var(--cloud-0)),
    radial-gradient(70px 24px at 620px 17%, var(--cloud), var(--cloud-0)),
    radial-gradient(50px 19px at 674px 20%, var(--cloud-dim), var(--cloud-0)),
    radial-gradient(64px 23px at 900px 53%, var(--cloud), var(--cloud-0)),
    radial-gradient(46px 17px at 948px 56%, var(--cloud-dim), var(--cloud-0));
  animation-name: drift-mid;
  animation-duration: 170s;
}

/* low deck — biggest and nearest, so it passes fastest */
body::after {
  z-index: -1;
  right: -880px;
  background-size: 880px 100%;
  background-image:
    radial-gradient(110px 33px at 200px 69%, var(--cloud), var(--cloud-0)),
    radial-gradient(78px 27px at 270px 72%, var(--cloud), var(--cloud-0)),
    radial-gradient(60px 23px at 146px 73%, var(--cloud-dim), var(--cloud-0)),
    radial-gradient(96px 31px at 640px 41%, var(--cloud), var(--cloud-0)),
    radial-gradient(68px 24px at 702px 44%, var(--cloud-dim), var(--cloud-0));
  animation-name: drift-near;
  animation-duration: 110s;
}

@keyframes drift-far  { to { transform: translate3d(-760px, 0, 0); } }
@keyframes drift-mid  { to { transform: translate3d(-1080px, 0, 0); } }
@keyframes drift-near { to { transform: translate3d(-880px, 0, 0); } }

h1, h2, h3, h4, .display {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -0.022em;
  margin: 0;
  text-wrap: balance;
}

p { margin: 0 0 1em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a { color: var(--cobalt); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { text-decoration-style: dotted; }

img, svg { max-width: 100%; height: auto; display: block; }
hr { border: 0; border-top: 1px solid var(--rule); margin: 2rem 0; }

:focus-visible {
  outline: 2px solid var(--magenta);
  outline-offset: 3px;
  border-radius: 2px;
}

code, kbd, samp, pre { font-family: var(--font-mono); font-size: 0.88em; }

code:not(pre code) {
  background: var(--cobalt-soft);
  color: color-mix(in oklab, var(--cobalt) 82%, var(--ink));
  padding: 0.12em 0.36em;
  border-radius: var(--r-sm);
  word-break: break-word;
}

kbd {
  border: 1px solid var(--rule);
  border-bottom-width: 2px;
  border-radius: var(--r-sm);
  padding: 0.05em 0.4em;
  background: var(--panel-2);
  font-size: 0.8em;
}

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
.band { padding-block: var(--band-y); }
.band--panel { background: var(--panel); border-block: 1px solid var(--rule); }
.band--tight { padding-block: clamp(2.2rem, 4vw, 3.4rem); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 99;
  background: var(--ink); color: var(--paper); padding: 0.6rem 1rem;
  font-family: var(--font-mono); font-size: var(--step--1);
}
.skip:focus { left: 0.5rem; top: 0.5rem; }

.sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
}

/* ==========================================================================
   shared bits: eyebrow, meta, buttons, tags
   ========================================================================== */

.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 1.1rem;
}
.eyebrow b { color: var(--magenta); font-weight: 500; }

.mono { font-family: var(--font-mono); font-size: var(--step--1); letter-spacing: 0.02em; }

.lede {
  font-size: var(--step-1);
  color: var(--ink-soft);
  line-height: 1.5;
  max-width: 60ch;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--step-0);
  letter-spacing: -0.01em;
  padding: 0.7rem 1.25rem;
  border: 1px solid var(--ink);
  border-radius: var(--r-md);
  background: var(--panel-2);
  color: var(--ink);
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;
}
.btn:hover { transform: translateY(-2px); box-shadow: 0 6px 0 -2px var(--rule); }
.btn:active { transform: translateY(0); }

.btn--primary {
  background: var(--cobalt);
  border-color: var(--cobalt);
  color: #fff;
}
.btn--primary:hover { box-shadow: 0 6px 0 -2px color-mix(in oklab, var(--cobalt) 55%, var(--ink)); }
:root[data-theme="dark"] .btn--primary { color: #0b0f15; }

.btn--ghost { background: transparent; }
.btn--sm { font-size: var(--step--1); padding: 0.45rem 0.8rem; }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.7rem; align-items: center; }

.tag {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 0.2rem 0.5rem;
  border-radius: 999px;
  background: var(--cobalt-soft);
  color: color-mix(in oklab, var(--cobalt) 78%, var(--ink));
  white-space: nowrap;
}
.tag--pink { background: var(--magenta-soft); color: color-mix(in oklab, var(--magenta) 80%, var(--ink)); }
.tag--ok { background: var(--ok-soft); color: color-mix(in oklab, var(--ok) 78%, var(--ink)); }
.tag--plain { background: transparent; border: 1px solid var(--rule); color: var(--ink-soft); }

.section-head { margin-bottom: clamp(1.8rem, 3vw, 2.8rem); }
.section-head h2 { font-size: var(--step-3); max-width: 26ch; }
.section-head p { margin-top: 0.9rem; }

/* ==========================================================================
   topbar
   ========================================================================== */

.topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in oklab, var(--paper) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--rule);
}
.topbar__in {
  display: flex;
  align-items: center;
  gap: 1.2rem;
  min-height: var(--topbar-h);
}

.brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--ink);
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.03em;
  font-size: 1.08rem;
  margin-right: auto;
}
.brand__mark {
  width: 26px; height: 26px;
  flex: none;
  border: 1.5px solid var(--ink);
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  letter-spacing: -0.05em;
  background: var(--magenta);
  color: #fff;
}
.brand__mark::after { content: "∞"; font-size: 0.9rem; line-height: 1; }
.brand span em { font-style: normal; color: var(--ink-faint); font-weight: 400; }

.nav { display: flex; align-items: center; gap: 1.35rem; }
.nav a {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.94rem;
  color: var(--ink-soft);
  text-decoration: none;
}
.nav a:hover, .nav a[aria-current="page"] { color: var(--ink); text-decoration: underline; }

.topbar__actions { display: flex; align-items: center; gap: 0.6rem; }

.theme-toggle {
  width: var(--touch); height: var(--touch);
  display: grid; place-items: center;
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--panel-2);
  color: var(--ink-soft);
  cursor: pointer;
  font-size: 0.95rem;
  line-height: 1;
}
.theme-toggle:hover { color: var(--ink); border-color: var(--ink-faint); }

.nav-toggle { display: none; }

@media (max-width: 880px) {
  .nav {
    position: absolute;
    inset: var(--topbar-h) 0 auto;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
    background: var(--panel);
    border-bottom: 1px solid var(--rule);
    padding: 0.4rem var(--gutter) 1rem;
    display: none;
    /* A phone in landscape has ~330px of height to spare; six 44px rows plus
       padding does not fit, so the drawer scrolls rather than running off the
       bottom of the screen with no way to reach the last link. */
    max-height: calc(100vh - var(--topbar-h));
    max-height: calc(100dvh - var(--topbar-h));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .nav[data-open="true"] { display: flex; }
  .nav a {
    padding: 0.7rem 0;
    width: 100%;
    border-bottom: 1px solid var(--rule);
    font-size: 1rem;
    min-height: 44px;
    display: flex;
    align-items: center;
  }
  .nav-toggle {
    display: grid; place-items: center;
    width: var(--touch); height: var(--touch);
    border: 1px solid var(--rule); border-radius: var(--r-md);
    background: var(--panel-2); color: var(--ink); cursor: pointer;
    font-family: var(--font-mono); font-size: 0.9rem;
  }
}

/* ==========================================================================
   hero + signature pipeline board
   ========================================================================== */

.hero { padding-block: clamp(2.5rem, 6vw, 5rem) clamp(3rem, 6vw, 5.5rem); }
.hero__in {
  display: grid;
  grid-template-columns: minmax(0, 1.02fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
@media (max-width: 940px) { .hero__in { grid-template-columns: 1fr; } }

.hero h1 { font-size: var(--step-4); }
.hero h1 mark {
  background: linear-gradient(to top, var(--magenta-soft) 42%, transparent 42%);
  color: inherit;
  padding-inline: 0.05em;
}
.hero .lede { margin-top: 1.3rem; }
.hero .btn-row { margin-top: 1.9rem; }
.hero__fine {
  margin-top: 1.15rem;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--ink-faint);
}

/* the board */
.board {
  background: var(--terminal-bg);
  border: 1px solid #26313f;
  border-radius: var(--r-lg);
  box-shadow: 0 30px 60px -40px rgba(19, 26, 36, 0.9);
  overflow: hidden;
  color: var(--terminal-ink);
  font-family: var(--font-mono);
  font-size: 0.79rem;
}
.board__bar {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.85rem;
  border-bottom: 1px solid #26313f;
  background: #0b1119;
  color: #7f8ea1;
  font-size: 0.72rem;
}
.board__bar b { color: #cfd9e6; font-weight: 500; }
.board__live { margin-left: auto; display: inline-flex; align-items: center; gap: 0.4rem; color: #3fce97; }
.dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: currentColor;
  box-shadow: 0 0 0 0 currentColor;
  animation: pulse 2.4s infinite;
}
@keyframes pulse {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, currentColor 60%, transparent); }
  70% { box-shadow: 0 0 0 7px transparent; }
  100% { box-shadow: 0 0 0 0 transparent; }
}

.stages { list-style: none; margin: 0; padding: 0.5rem 0; }
.stages li { border-left: 2px solid transparent; }
.stages a {
  display: grid;
  grid-template-columns: 1.4rem 2.3rem 1fr auto;
  gap: 0.6rem;
  align-items: center;
  padding: 0.34rem 0.9rem;
  color: #8b9aad;
  text-decoration: none;
}
.stages a:hover { background: #17202c; color: #eaf1f8; }
.stages .st-num { color: #4f5f72; }
.stages .st-name { color: #cbd6e3; letter-spacing: 0.02em; }
.stages .st-time { color: #4f5f72; font-size: 0.72rem; }
.stages .st-icon { text-align: center; }

.stages li[data-state="done"] { border-left-color: #3fce97; }
.stages li[data-state="done"] .st-icon { color: #3fce97; }
.stages li[data-state="run"] { border-left-color: #ffc857; background: #141d29; }
.stages li[data-state="run"] .st-icon { color: #ffc857; }
.stages li[data-state="run"] .st-name { color: #fff; }
.stages li[data-state="idle"] .st-icon { color: #3b4757; }

.board__log {
  border-top: 1px solid #26313f;
  background: #080d14;
  padding: 0.6rem 0.9rem 0.75rem;
  height: 6.6rem;
  overflow: hidden;
  font-size: 0.72rem;
  line-height: 1.7;
  color: #6f7f93;
}
.board__log span { display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.board__log span b { color: #9fb0c4; font-weight: 400; }
.board__log span.ok b { color: #3fce97; }
.board__log span.warn b { color: #ffc857; }

/* ==========================================================================
   stack strip
   ========================================================================== */

.strip { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem 0.65rem; }
.strip__label {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--ink-faint);
  margin-right: 0.4rem;
}
.chip {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  padding: 0.28rem 0.6rem;
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--panel-2);
  color: var(--ink-soft);
}

/* ==========================================================================
   chapter log entries
   ========================================================================== */

.chapters { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); border-radius: var(--r-lg); overflow: hidden; }

.entry {
  display: grid;
  grid-template-columns: 4.6rem minmax(0, 1fr) minmax(0, 15rem);
  gap: clamp(0.9rem, 2.5vw, 2rem);
  background: var(--panel-2);
  padding: clamp(1.1rem, 2.4vw, 1.7rem) clamp(1rem, 2.4vw, 1.6rem);
  text-decoration: none;
  color: inherit;
  position: relative;
  transition: background 0.14s ease;
}
.entry:hover { background: var(--cobalt-soft); }
.entry:hover .entry__title { text-decoration: underline; text-decoration-thickness: 2px; }

.entry__num {
  font-family: var(--font-mono);
  font-size: 1.5rem;
  color: var(--ink-faint);
  letter-spacing: -0.04em;
  line-height: 1;
}
.entry__num small { display: block; font-size: 0.62rem; letter-spacing: 0.1em; margin-top: 0.4rem; color: var(--ink-faint); }

.entry__title { font-family: var(--font-display); font-size: var(--step-1); font-weight: 700; letter-spacing: -0.02em; }
.entry__blurb { color: var(--ink-soft); font-size: 0.97rem; margin-top: 0.4rem; line-height: 1.55; }
.entry__topics {
  margin-top: 0.7rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.45rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-faint);
}
.entry__topics span::after { content: " ·"; color: var(--rule); }
.entry__topics span:last-child::after { content: ""; }

.entry__side {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  align-items: flex-start;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--ink-soft);
}
.entry__side .done-flag { color: var(--ok); }

@media (max-width: 760px) {
  .entry { grid-template-columns: 3rem minmax(0, 1fr); }
  .entry__num { font-size: 1.15rem; }
  .entry__side { grid-column: 2; flex-direction: row; flex-wrap: wrap; }
}

/* progress meter */
.meter {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--ink-soft);
  margin-bottom: 1.2rem;
  flex-wrap: wrap;
}
.meter__track {
  flex: 1 1 180px;
  height: 8px;
  background: var(--panel-2);
  border: 1px solid var(--rule);
  border-radius: 999px;
  overflow: hidden;
  min-width: 140px;
}
.meter__fill {
  display: block; height: 100%;
  width: 0%;
  background: repeating-linear-gradient(135deg, var(--ok) 0 6px, color-mix(in oklab, var(--ok) 70%, #fff) 6px 12px);
  transition: width 0.5s ease;
}

/* ==========================================================================
   approach: three ways per topic
   ========================================================================== */

.ways { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1px; background: var(--rule); border: 1px solid var(--rule); border-radius: var(--r-lg); overflow: hidden; }
.way { background: var(--panel-2); padding: clamp(1.2rem, 2.5vw, 1.8rem); }
.way__k {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--magenta);
  margin-bottom: 0.8rem;
}
.way h3 { font-size: var(--step-1); margin-bottom: 0.55rem; }
.way p { color: var(--ink-soft); font-size: 0.97rem; }

.demo {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
  margin-top: clamp(2rem, 4vw, 3rem);
}
@media (max-width: 860px) { .demo { grid-template-columns: 1fr; } }

/* ==========================================================================
   lesson content primitives (used on chapter pages + landing demo)
   ========================================================================== */

.analogy {
  border-left: 3px solid var(--magenta);
  background: var(--magenta-soft);
  padding: 0.95rem 1.1rem;
  border-radius: 0 var(--r-md) var(--r-md) 0;
  margin: 1.3rem 0;
}
.analogy__k {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--magenta) 80%, var(--ink));
  display: block;
  margin-bottom: 0.35rem;
}
.analogy p { font-size: 0.99rem; }

.note {
  border-left: 3px solid var(--cobalt);
  background: var(--cobalt-soft);
  padding: 0.9rem 1.1rem;
  border-radius: 0 var(--r-md) var(--r-md) 0;
  margin: 1.3rem 0;
  font-size: 0.97rem;
}
.note__k {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--cobalt) 80%, var(--ink));
  display: block;
  margin-bottom: 0.35rem;
}

.term {
  background: var(--terminal-bg);
  border: 1px solid #26313f;
  border-radius: var(--r-md);
  margin: 1.3rem 0;
  overflow: hidden;
}
.term__bar {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  padding: 0.4rem 0.75rem;
  background: #0b1119;
  border-bottom: 1px solid #26313f;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #6f7f93;
}
.term__bar::before {
  content: "";
  width: 8px; height: 8px; border-radius: 50%;
  background: #ff628f;
  box-shadow: 12px 0 0 #ffc857, 24px 0 0 #3fce97;
  margin-right: 1.4rem;
  flex: none;
}
.term pre {
  margin: 0;
  padding: 0.85rem 0.95rem;
  overflow-x: auto;
  color: var(--terminal-ink);
  font-size: 0.8rem;
  line-height: 1.75;
  tab-size: 2;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.term pre b { color: #7dd3a8; font-weight: 400; }        /* command */
.term pre i { color: #6f7f93; font-style: normal; }      /* comment / output */
.term pre u { color: #ffc857; text-decoration: none; }   /* emphasis */

.lab {
  border: 1px solid var(--rule);
  border-top: 3px solid var(--ok);
  border-radius: var(--r-md);
  background: var(--panel);
  padding: clamp(1rem, 2.2vw, 1.4rem);
  margin: 1.6rem 0;
}
.lab__k {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--ok) 75%, var(--ink));
  display: block;
  margin-bottom: 0.5rem;
}
.lab h4 { font-size: 1.06rem; margin-bottom: 0.5rem; }
.lab ol, .lab ul { margin: 0.6rem 0 0; padding-left: 1.25rem; }
.lab li { margin-bottom: 0.4rem; font-size: 0.97rem; }
.lab li:last-child { margin-bottom: 0; }

.takeaway {
  display: grid;
  gap: 0.5rem;
  border: 1px dashed var(--rule);
  border-radius: var(--r-md);
  padding: 1rem 1.15rem;
  margin: 1.5rem 0;
  background: var(--panel-2);
}
.takeaway__k {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.takeaway ul { margin: 0; padding-left: 1.2rem; }
.takeaway li { font-size: 0.97rem; margin-bottom: 0.3rem; }

.table-scroll {
  overflow-x: auto;
  margin: 1.4rem 0;
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  -webkit-overflow-scrolling: touch;
  /* Keep a sideways swipe inside the table: without this it bubbles up and
     Android reads it as the back gesture, so panning a wide table can walk
     the user out of the chapter. */
  overscroll-behavior-x: contain;
}
table { border-collapse: collapse; width: 100%; font-size: 0.93rem; background: var(--panel-2); }
th, td { text-align: left; padding: 0.65rem 0.85rem; border-bottom: 1px solid var(--rule); vertical-align: top; }
th { font-family: var(--font-display); font-size: 0.85rem; letter-spacing: 0.02em; background: var(--panel); white-space: nowrap; }
tr:last-child td { border-bottom: 0; }
td code { white-space: nowrap; }

/* ==========================================================================
   arcade cards
   ========================================================================== */

.arcade-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(255px, 1fr)); gap: 1.1rem; }

.game-card {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  background: var(--panel-2);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  padding: 1.2rem;
  text-decoration: none;
  color: inherit;
  position: relative;
  overflow: hidden;
  transition: transform 0.14s ease, border-color 0.14s ease;
}
.game-card::after {
  content: "";
  position: absolute; inset: auto -30% -60% auto;
  width: 150px; height: 150px;
  background: radial-gradient(circle, var(--magenta-soft) 0%, transparent 70%);
  opacity: 0; transition: opacity 0.2s ease;
}
.game-card:hover { transform: translateY(-3px); border-color: var(--magenta); }
.game-card:hover::after { opacity: 1; }
.game-card__icon { font-size: 1.5rem; line-height: 1; }
.game-card h3 { font-size: 1.1rem; }
.game-card p { color: var(--ink-soft); font-size: 0.93rem; }
.game-card__meta {
  margin-top: auto;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-faint);
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

/* ==========================================================================
   plan timeline
   ========================================================================== */

.weeks { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 1.1rem; counter-reset: w; }
.week {
  border-top: 2px solid var(--ink);
  padding-top: 0.9rem;
}
.week__k { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--magenta); }
.week h3 { font-size: 1.05rem; margin: 0.35rem 0 0.5rem; }
.week p { font-size: 0.93rem; color: var(--ink-soft); }

/* ==========================================================================
   footer
   ========================================================================== */

.site-footer { border-top: 1px solid var(--rule); background: var(--panel); padding-block: clamp(2.5rem, 5vw, 4rem) 2rem; }
.footer-grid { display: grid; grid-template-columns: minmax(0, 1.4fr) repeat(auto-fit, minmax(140px, 1fr)); gap: 2rem; }
.footer-grid h4 { font-family: var(--font-mono); font-size: 0.72rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-faint); font-weight: 400; margin-bottom: 0.8rem; }
.footer-grid ul { list-style: none; margin: 0; padding: 0; }
.footer-grid li { margin-bottom: 0.4rem; }
.footer-grid a { color: var(--ink-soft); text-decoration: none; font-size: 0.93rem; }
.footer-grid a:hover { color: var(--ink); text-decoration: underline; }
.colophon {
  margin-top: 2.5rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 1.2rem;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-faint);
}

/* ==========================================================================
   chapter (lesson) page layout
   ========================================================================== */

.lesson-hero { padding-block: clamp(2.2rem, 5vw, 3.6rem) clamp(1.5rem, 3vw, 2.4rem); }
.lesson-hero h1 { font-size: var(--step-3); max-width: 30ch; }
.lesson-hero .lede { margin-top: 1rem; }
.crumbs { font-family: var(--font-mono); font-size: var(--step--1); color: var(--ink-faint); margin-bottom: 1.1rem; }
.crumbs a { color: var(--ink-soft); text-decoration: none; }
.crumbs a:hover { color: var(--cobalt); text-decoration: underline; }

.lesson-layout {
  display: grid;
  grid-template-columns: 15.5rem minmax(0, 1fr);
  gap: clamp(1.6rem, 4vw, 3.2rem);
  align-items: start;
  padding-bottom: var(--band-y);
}
@media (max-width: 900px) { .lesson-layout { grid-template-columns: 1fr; } }

.toc {
  position: sticky;
  top: 76px;
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--panel-2);
  padding: 1rem 1.1rem;
  font-size: 0.9rem;
}
.toc h2 { font-family: var(--font-mono); font-size: 0.7rem; letter-spacing: 0.13em; text-transform: uppercase; color: var(--ink-faint); font-weight: 400; margin-bottom: 0.7rem; }
.toc ol { list-style: none; margin: 0; padding: 0; counter-reset: toc; }
.toc li { counter-increment: toc; margin-bottom: 0.15rem; }
.toc a {
  display: flex;
  gap: 0.5rem;
  padding: 0.24rem 0;
  color: var(--ink-soft);
  text-decoration: none;
  line-height: 1.4;
}
.toc a::before {
  content: counter(toc, decimal-leading-zero);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  color: var(--ink-faint);
  padding-top: 0.2rem;
  flex: none;
}
.toc a:hover, .toc a.is-active { color: var(--cobalt); }
.toc a.is-active { font-weight: 600; }
@media (max-width: 900px) { .toc { position: static; } }

.prose { max-width: 72ch; }
.prose > h2 {
  font-size: var(--step-2);
  margin-top: clamp(2.6rem, 5vw, 3.6rem);
  padding-top: 1.4rem;
  border-top: 1px solid var(--rule);
  scroll-margin-top: 80px;
}
.prose > h2:first-child { margin-top: 0; border-top: 0; padding-top: 0; }
.prose > h2 .h2num {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  color: var(--magenta);
  margin-bottom: 0.5rem;
  font-weight: 400;
}
.prose h3 { font-size: var(--step-1); margin-top: 2rem; margin-bottom: 0.6rem; }
.prose h4 { font-size: 1.05rem; margin-top: 1.4rem; margin-bottom: 0.4rem; }
.prose ul, .prose ol { padding-left: 1.3rem; margin: 0 0 1.1em; }
.prose li { margin-bottom: 0.45rem; }
.prose li > ul, .prose li > ol { margin-top: 0.45rem; }
.prose dl { margin: 1.2rem 0; }
.prose dt { font-family: var(--font-display); font-weight: 600; margin-top: 0.9rem; }
.prose dd { margin: 0.2rem 0 0; color: var(--ink-soft); }
.prose blockquote {
  margin: 1.4rem 0;
  padding-left: 1.1rem;
  border-left: 3px solid var(--rule);
  color: var(--ink-soft);
  font-style: italic;
}

.chapter-nav {
  display: flex;
  gap: 1rem;
  justify-content: space-between;
  flex-wrap: wrap;
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: 1.4rem;
  border-top: 1px solid var(--rule);
}
.chapter-nav a { font-family: var(--font-display); text-decoration: none; font-weight: 600; }
.chapter-nav a small { display: block; font-family: var(--font-mono); font-size: 0.68rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); font-weight: 400; margin-bottom: 0.2rem; }
.chapter-nav a:last-child { text-align: right; }

.complete-bar {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  flex-wrap: wrap;
  background: var(--panel);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  padding: 0.9rem 1.1rem;
  margin-top: 2rem;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--ink-soft);
}

/* ==========================================================================
   quiz (inline check, used on every chapter)
   ========================================================================== */

.quiz {
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  background: var(--panel-2);
  padding: clamp(1.1rem, 2.5vw, 1.6rem);
  margin: 1.6rem 0;
}
.quiz__q { font-family: var(--font-display); font-weight: 600; font-size: 1.05rem; margin-bottom: 0.85rem; }
.quiz__opts { display: grid; gap: 0.5rem; }
.opt {
  display: flex;
  gap: 0.6rem;
  align-items: flex-start;
  text-align: left;
  width: 100%;
  font: inherit;
  font-size: 0.96rem;
  padding: 0.6rem 0.8rem;
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--panel);
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.opt:hover:not(:disabled) { border-color: var(--cobalt); }
.opt__key { font-family: var(--font-mono); font-size: 0.75rem; color: var(--ink-faint); padding-top: 0.15rem; flex: none; }
.opt[data-verdict="right"] { border-color: var(--ok); background: var(--ok-soft); }
.opt[data-verdict="wrong"] { border-color: var(--magenta); background: var(--magenta-soft); }
.opt:disabled { cursor: default; }
.quiz__why {
  margin-top: 0.9rem;
  font-size: 0.95rem;
  color: var(--ink-soft);
  border-top: 1px dashed var(--rule);
  padding-top: 0.8rem;
}
.quiz__why[hidden] { display: none; }
.quiz__foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  margin-top: 1rem;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--ink-faint);
}

/* ==========================================================================
   games page
   ========================================================================== */

.game {
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  background: var(--panel-2);
  padding: clamp(1.2rem, 3vw, 2rem);
  margin-bottom: clamp(1.6rem, 3vw, 2.4rem);
  scroll-margin-top: 76px;
}
.game__head { display: flex; gap: 1rem; align-items: flex-start; flex-wrap: wrap; margin-bottom: 1.1rem; }
.game__head h2 { font-size: var(--step-2); }
.game__head p { color: var(--ink-soft); font-size: 0.97rem; margin-top: 0.5rem; max-width: 62ch; }
.game__score {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--ink-soft);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  padding: 0.4rem 0.7rem;
  white-space: nowrap;
  background: var(--panel);
}
.game__score b { color: var(--ok); font-weight: 500; }

.play-area { display: grid; gap: 1rem; }
.play-cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1rem; }

/* pipeline builder */
.slots { display: grid; gap: 0.5rem; }
.slot {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-height: 48px;
  border: 1px dashed var(--rule);
  border-radius: var(--r-md);
  padding: 0.4rem 0.7rem;
  background: var(--panel);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--ink-faint);
}
.slot__n { color: var(--ink-faint); font-size: 0.72rem; width: 1.5rem; flex: none; }
.slot.is-over { border-color: var(--cobalt); background: var(--cobalt-soft); }
.slot[data-verdict="right"] { border-style: solid; border-color: var(--ok); background: var(--ok-soft); }
.slot[data-verdict="wrong"] { border-style: solid; border-color: var(--magenta); background: var(--magenta-soft); }

.pieces { display: flex; flex-wrap: wrap; gap: 0.5rem; align-content: flex-start; }
.piece {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  padding: 0.45rem 0.75rem;
  border: 1px solid var(--ink);
  border-radius: var(--r-md);
  background: var(--panel-2);
  color: var(--ink);
  cursor: grab;
  user-select: none;
}
.piece:hover { background: var(--cobalt-soft); }
.piece.is-dragging { opacity: 0.4; }
.piece.is-placed { cursor: pointer; border-style: solid; }

/* sorter bins */
.bin {
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--panel);
  padding: 0.85rem;
  min-height: 130px;
}
.bin h4 { font-family: var(--font-mono); font-size: 0.74rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-faint); font-weight: 400; margin-bottom: 0.7rem; }
.bin.is-over { border-color: var(--cobalt); background: var(--cobalt-soft); }
.bin__items { display: flex; flex-wrap: wrap; gap: 0.4rem; }

/* terminal trainer */
.trainer { display: grid; gap: 0.8rem; }
.trainer__task {
  border-left: 3px solid var(--magenta);
  background: var(--magenta-soft);
  padding: 0.8rem 1rem;
  border-radius: 0 var(--r-md) var(--r-md) 0;
  font-size: 0.99rem;
}
.trainer__task span {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: color-mix(in oklab, var(--magenta) 80%, var(--ink));
  margin-bottom: 0.3rem;
}
.prompt-line {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  background: var(--terminal-bg);
  border: 1px solid #26313f;
  border-radius: var(--r-md);
  padding: 0.6rem 0.8rem;
  font-family: var(--font-mono);
}
.prompt-line::before { content: "$"; color: #3fce97; flex: none; }
.prompt-line input {
  flex: 1;
  min-width: 0;
  background: transparent;
  border: 0;
  color: var(--terminal-ink);
  font: inherit;
  font-size: 0.85rem;
  padding: 0.15rem 0;
}
.prompt-line input:focus { outline: none; }
.verdict { font-family: var(--font-mono); font-size: var(--step--1); min-height: 1.4em; }
.verdict[data-kind="right"] { color: var(--ok); }
.verdict[data-kind="wrong"] { color: var(--magenta); }
.verdict[data-kind="hint"] { color: var(--warn); }

/* incident room */
.scenario {
  background: var(--panel);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  padding: 1rem 1.15rem;
}
.scenario__clock { font-family: var(--font-mono); font-size: 0.74rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--magenta); margin-bottom: 0.5rem; }
.scenario p { font-size: 0.99rem; }
.choices { display: grid; gap: 0.5rem; margin-top: 1rem; }
.log-feed {
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--ink-soft);
  border-left: 2px solid var(--rule);
  padding-left: 0.8rem;
  display: grid;
  gap: 0.3rem;
  max-height: 12rem;
  overflow-y: auto;
}
.log-feed b { font-weight: 400; color: var(--ink); }

/* matcher */
.match-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 0.55rem; }
.card-tile {
  aspect-ratio: 4 / 3;
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--panel);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 0.74rem;
  line-height: 1.35;
  padding: 0.5rem;
  cursor: pointer;
  display: grid;
  place-items: center;
  text-align: center;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.card-tile[data-face="down"] { background: var(--ink); color: transparent; border-color: var(--ink); }
.card-tile[data-face="down"]::after { content: "?"; color: var(--paper); font-size: 1rem; }
.card-tile[data-state="matched"] { border-color: var(--ok); background: var(--ok-soft); cursor: default; }
.card-tile[data-state="wrong"] { border-color: var(--magenta); background: var(--magenta-soft); }

/* yaml doctor */
.code-lines {
  background: var(--terminal-bg);
  border: 1px solid #26313f;
  border-radius: var(--r-md);
  padding: 0.7rem 0;
  font-family: var(--font-mono);
  font-size: 0.79rem;
  line-height: 1.8;
  overflow-x: auto;
  color: var(--terminal-ink);
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}
.code-lines button {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  border-left: 3px solid transparent;
  color: inherit;
  font: inherit;
  padding: 0 0.9rem;
  cursor: pointer;
  white-space: pre;
}
.code-lines button:hover:not(:disabled) { background: #17202c; border-left-color: #ffc857; }
.code-lines button .ln { color: #4f5f72; display: inline-block; width: 2.1rem; }
.code-lines button[data-verdict="right"] { background: #12331f; border-left-color: #3fce97; }
.code-lines button[data-verdict="wrong"] { background: #331420; border-left-color: #ff628f; }
.code-lines button:disabled { cursor: default; }

/* generic game footer */
.game__foot { display: flex; flex-wrap: wrap; gap: 0.6rem; align-items: center; margin-top: 1.1rem; }
.game__msg { font-family: var(--font-mono); font-size: var(--step--1); color: var(--ink-soft); }
.game__msg[data-kind="right"] { color: var(--ok); }
.game__msg[data-kind="wrong"] { color: var(--magenta); }

/* ==========================================================================
   cheatsheet page
   ========================================================================== */

.sheet-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 1.1rem; }
.sheet {
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  background: var(--panel-2);
  padding: 1.1rem 1.2rem;
}
.sheet h3 { font-size: 1.05rem; margin-bottom: 0.7rem; padding-bottom: 0.5rem; border-bottom: 1px solid var(--rule); }
.sheet dl { margin: 0; display: grid; gap: 0.55rem; }
.sheet dt { font-family: var(--font-mono); font-size: 0.78rem; color: var(--cobalt); word-break: break-word; }
.sheet dd { margin: 0.1rem 0 0; font-size: 0.9rem; color: var(--ink-soft); }

/* ==========================================================================
   surfaces over the sky
   These override the solid backgrounds set earlier so the clouds stay visible
   between and behind content. Large bands frost heavily; cards holding body
   text stay near-solid, because readability wins over the view.
   ========================================================================== */

.band--panel,
.site-footer {
  background: color-mix(in oklab, var(--panel) var(--frost), transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
}

/* Cards that sat on --panel-2 (white) */
.entry,
.way,
.game,
.sheet,
.game-card,
.quiz,
.toc,
.takeaway,
table {
  background-color: color-mix(in oklab, var(--panel-2) var(--frost-card), transparent);
}

/* Cards that sat on --panel (the tinted grey) */
.lab,
.scenario,
.bin,
.complete-bar,
th {
  background-color: color-mix(in oklab, var(--panel) var(--frost-card), transparent);
}

/* The chapter list and the "three passes" grid draw their hairline dividers
   with a background colour. Softening it lets the sky through the 1px gaps
   instead of showing a flat slab of grey. */
.chapters,
.ways {
  background-color: color-mix(in oklab, var(--rule) 62%, transparent);
}

/* Deliberately left solid: buttons, quiz options, slots, bins and memory
   tiles all signal state through colour, and small controls gain nothing
   from transparency. Terminals and the pipeline board are screens — they
   stay opaque so the code on them keeps full contrast. */

/* ==========================================================================
   mobile + touch
   The layout is fluid throughout, so what follows is corrections rather than a
   second design: the places where a fixed column, a hardcoded offset or a
   hover-only affordance does not survive a 360px phone.
   ========================================================================== */

/* ------------------------------------------------------------ input device
   Keyed off the pointer rather than the viewport, so a touchscreen laptop is
   treated like a phone and a 360px desktop window is not. */

@media (pointer: coarse) {
  :root { --touch: 42px; }

  /* Rows that were sized for a mouse. The pipeline board and the chapter TOC
     are the tightest: both are lists of tap targets at ~26px. */
  .stages a { padding-block: 0.5rem; }
  .toc a { padding-block: 0.5rem; }
  .footer-grid a { display: inline-block; padding-block: 0.3rem; }
  .footer-grid li { margin-bottom: 0.15rem; }
  .piece { padding: 0.6rem 0.85rem; }
  .chapter-nav a { padding-block: 0.3rem; }

  /* The one text input on the site. iOS zooms the viewport on focus whenever
     an input's text measures under 16px, and it does not zoom back out —
     leaving the arcade page panned sideways for the rest of the session. */
  .prompt-line input { font-size: 16px; }
}

@media (hover: none) {
  /* `cursor: grab` is invisible to a finger, and HTML5 drag events do not
     fire on touch — the games' tap-to-place path is the real interaction
     here, so the pieces should read as tappable. */
  .piece { cursor: pointer; }

  /* Lift-on-hover cannot trigger, but on touch it fires on tap and leaves the
     element stuck in its hover state until the next tap elsewhere. */
  .btn:hover { transform: none; box-shadow: none; }
  .game-card:hover { transform: none; border-color: var(--rule); }
  .game-card:hover::after { opacity: 0; }
  .entry:hover { background-color: color-mix(in oklab, var(--panel-2) var(--frost-card), transparent); }
}

/* Tap-to-place marks the held piece with aria-pressed. Without a visible
   state, the phone path gives no feedback that anything was picked up. */
.piece[aria-pressed="true"] {
  border-color: var(--magenta);
  background: var(--magenta-soft);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--magenta) 22%, transparent);
}

/* Long-press on a draggable turns into a text selection instead of a drag. */
.piece, .card-tile, .slot__n, .opt__key { -webkit-user-select: none; user-select: none; }

/* Contain the scroll on the boxes that scroll internally. */
.log-feed { overscroll-behavior: contain; }

/* ------------------------------------------------------------ small screens */

@media (max-width: 700px) {
  /* Footer: four link columns at minmax(140px, 1fr) collapse to a single
     very long column. Two columns keep it to a thumb-flick. */
  .footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1.6rem 1.2rem;
  }
  .footer-grid > :first-child { grid-column: 1 / -1; }

  /* `text-align: right` on the second link is meant for a two-across row.
     Once the pair stacks it reads as a stray indent. */
  .chapter-nav { display: grid; grid-template-columns: 1fr; gap: 0.9rem; }
  .chapter-nav a:last-child { text-align: left; }

  /* Three stacked backdrop-filters (topbar, bands, footer) over three
     animated cloud layers is the most expensive thing on the page. Halving
     the blur radius is roughly a quarter of the work per composite and is
     not perceptible at this size. */
  .topbar, .band--panel, .site-footer {
    backdrop-filter: blur(5px);
    -webkit-backdrop-filter: blur(5px);
  }

  .quiz__foot { flex-wrap: wrap; }
  .game__head { gap: 0.7rem; }
  .game__score { margin-left: 0; }

  /* The memory grid at minmax(112px) gives two columns on a phone, so a
     16-tile board becomes an eight-row scroll. */
  .match-grid { grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); }

  /* Static on mobile already; drop the desktop card padding it kept. */
  .toc { padding: 0.85rem 0.95rem; }
}

@media (max-width: 460px) {
  /* The topbar is the one hard overflow on the site: brand (~141px) plus two
     42px controls plus the CTA (~102px) plus gaps needs ~400px of a 360px
     viewport. Flex resolves it by wrapping the button text and doubling the
     bar's height. The CTA is the item that goes, because every page already
     reaches the same place another way: the hero repeats it verbatim on the
     landing page, chapters end with prev/next, and the drawer's "Chapters"
     link opens the full list from anywhere. */
  .topbar__actions .btn { display: none; }
  .topbar__in { gap: 0.7rem; }

  /* Neither of these should ever wrap mid-word to buy space. */
  .brand { white-space: nowrap; }
  .btn { white-space: nowrap; }

  /* Buy back room in the pipeline board's four-column rows. */
  .stages a { grid-template-columns: 1.1rem 1.9rem 1fr auto; gap: 0.45rem; padding-inline: 0.7rem; }
  .board__bar { padding-inline: 0.7rem; }
  .board__log { padding-inline: 0.7rem; }
}

/* ---------------------------------------------------------------- the sky, cheaper
   Three fixed full-viewport layers drifting on an infinite loop means the
   compositor never idles: on a phone that shows up as scroll jank on the long
   chapter pages and as steady battery draw on a page with no video on it.

   The clouds stay — they are the identity of the page — but below 700px they
   stop moving, and the high cirrus (the faintest of the three, and a whole
   extra composited layer) drops out. Delete this block to get the drift back
   on phones. */

@media (max-width: 700px) {
  html::before { display: none; }
  body::before, body::after { animation: none; }
}

/* ==========================================================================
   motion
   ========================================================================== */

.reveal { opacity: 0; transform: translateY(14px); }
.reveal.is-in { opacity: 1; transform: none; transition: opacity 0.55s ease, transform 0.55s cubic-bezier(0.2, 0.7, 0.3, 1); }

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal.is-in { opacity: 1; transform: none; transition: none; }
  .dot { animation: none; }
  .btn:hover { transform: none; }
  .game-card:hover { transform: none; }
  /* the sky stays, the drift stops */
  html::before, body::before, body::after { animation: none; }
  * { scroll-behavior: auto !important; }
}

@media print {
  html { background: #fff; }
  body { background: #fff; }
  html::before, body::before, body::after { display: none; }
  .band--panel, .site-footer, .entry, .way, .game, .sheet, .game-card,
  .quiz, .toc, .takeaway, .lab, .scenario, .bin, .complete-bar, table, th {
    background-color: #fff;
    backdrop-filter: none;
  }
  .topbar, .site-footer, .toc, .chapter-nav, .complete-bar { display: none; }
  .lesson-layout { grid-template-columns: 1fr; }
}
