/* ethang.dev — hand-written CSS.
 *
 * Palette and type scale are ported verbatim from the Astro site's
 * src/styles/global.css (@theme block). No Tailwind, no preprocessor, no
 * build step: this file is served as written.
 *
 * Fonts are self-hosted woff2 files in static/fonts/ (latin subset, downloaded
 * from the Fontsource CDN). No local() fallbacks: the file is self-contained and
 * renders identically everywhere.
 */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/inter-400.woff2") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/inter-600.woff2") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/inter-700.woff2") format("woff2");
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-400.woff2") format("woff2");
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/jetbrains-mono-700.woff2") format("woff2");
}

:root {
  color-scheme: dark;

  /* ── Night Owl palette ─────────────────────────────────────────────── */
  --night-owl-bg: #011627; /* base background                             */
  --night-owl-surface: #0b3553; /* elevated surface (cards, panels)       */
  --night-owl-border: rgba(127, 219, 202, 0.2);

  --night-owl-fg: #d6deeb; /* primary foreground / body text                */
  --night-owl-muted: #9aaebc; /* secondary text with readable contrast     */

  /* syntax-highlighting palette — also usable as semantic tokens */
  --night-owl-purple: #c792ea; /* keywords, emphasis                       */
  --night-owl-comment: #637777; /* comments                               */
  --night-owl-green: #c5e478; /* variables, constants, built-ins          */
  --night-owl-blue: #82aaff; /* types, functions, meta                    */
  --night-owl-cyan: #7fdbca; /* attributes, tags, params                  */
  --night-owl-red: #ff5874; /* literals                                  */
  --night-owl-orange: #f78c6c; /* numbers                                */
  --night-owl-yellow: #ecc48d; /* strings                                */
  --night-owl-peach: #ffcb8b; /* classes                                 */
  --night-owl-mint: #d9f5dd; /* punctuation, bullets                     */

  /* ── Semantic tokens (derived from Night Owl) ──────────────────────── */
  --primary: var(--night-owl-blue);
  --secondary: var(--night-owl-cyan);
  --accent: var(--night-owl-purple);
  --success: var(--night-owl-green);
  --warning: var(--night-owl-yellow);
  --danger: var(--night-owl-red);
  --on-primary: var(--night-owl-bg);

  /* ── Typography families ───────────────────────────────────────────── */
  --font-sans: "Inter", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, monospace;

  /* ── Type scale (size / line-height) ───────────────────────────────── */
  --text-xs: 0.75rem;
  --text-xs-line: 1rem;
  --text-sm: 0.875rem;
  --text-sm-line: 1.25rem;
  --text-base: 1rem;
  --text-base-line: 1.5rem;
  --text-lg: 1.125rem;
  --text-lg-line: 1.75rem;
  --text-xl: 1.25rem;
  --text-xl-line: 1.75rem;
  --text-2xl: 1.5rem;
  --text-2xl-line: 2rem;
  --text-3xl: 1.875rem;
  --text-3xl-line: 2.25rem;
  --text-4xl: 2.25rem;
  --text-4xl-line: 2.5rem;

  /* ── Measures ──────────────────────────────────────────────────────── */
  /* The Astro layout capped content at max-w-6xl (72rem) with a 4/6/8
   * step padding scale; these replace those fixed utility strings. */
  --page-max: 72rem;
  --page-pad: 1rem;
  /* A reading measure for the short blocks that want one - the learn ledes,
   * group blurbs, and the 404. Article prose does not use it: it fills
   * --page-max, the way the Astro layout's did. */
  --prose-measure: 68ch;

  /* ── Spacing ───────────────────────────────────────────────────────── */
  --space-2xs: 0.25rem;
  --space-xs: 0.5rem;
  --space-sm: 0.75rem;
  --space-md: 1rem;
  --space-lg: 1.5rem;
  --space-xl: 2rem;
  --space-2xl: 3rem;

  /* ── Radii and elevation ───────────────────────────────────────────── */
  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --radius-lg: 0.75rem;
  --shadow-card: 0 1.25rem 3rem rgba(0, 0, 0, 0.16);
}

@media (min-width: 40rem) {
  :root {
    --page-pad: 1.5rem;
  }
}

@media (min-width: 64rem) {
  :root {
    --page-pad: 2rem;
  }
}

/* ── Base ─────────────────────────────────────────────────────────────── */

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

html {
  background-color: var(--night-owl-bg);
  color: var(--night-owl-fg);
  overflow-block: scroll;
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  display: flex;
  flex-direction: column;
  min-block-size: 100vb;
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-base);
  line-height: var(--text-base-line);
  background-color: var(--night-owl-bg);
  background-image:
    linear-gradient(135deg, rgba(130, 170, 255, 0.05) 0 1px, transparent 1px 100%),
    radial-gradient(circle at 85% -10%, rgba(199, 146, 234, 0.12), transparent 32rem),
    radial-gradient(circle at 5% 20%, rgba(127, 219, 202, 0.06), transparent 28rem);
  background-size:
    4rem 4rem,
    auto,
    auto;
}

main {
  flex: 1 0 auto;
}

h1,
h2,
h3,
h4,
h5,
h6 {
  margin-block: 0;
  font-weight: 600;
  line-height: 1.25;
  color: var(--night-owl-fg);
  text-wrap: balance;
}

p {
  margin-block: 0;
}

a {
  color: var(--primary);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-thickness: 2px;
}

img,
svg,
video {
  display: block;
  max-inline-size: 100%;
  block-size: auto;
}

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

hr {
  border: 0;
  border-block-start: 1px solid var(--night-owl-border);
}

:focus-visible {
  outline: 2px solid var(--night-owl-cyan);
  outline-offset: 3px;
}

::selection {
  background-color: rgba(130, 170, 255, 0.3);
  color: var(--night-owl-fg);
}

/* ── Site chrome ──────────────────────────────────────────────────────── */

.site-header {
  max-inline-size: var(--page-max);
  margin-inline: auto;
  inline-size: 100%;
  padding-inline: var(--page-pad);
  padding-block-start: 1.25rem;
}

.site-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm) 1.25rem;
  padding-block-end: var(--space-md);
  border-block-end: 1px solid var(--night-owl-border);
}

.site-mark {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--night-owl-fg);
  text-decoration: none;
  transition: color 120ms ease;
}

.site-mark:hover {
  color: var(--secondary);
}

.site-mark__tilde {
  color: var(--night-owl-cyan);
}

.site-nav ul {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs) var(--space-md);
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-nav a {
  position: relative;
  color: var(--night-owl-fg);
  font-weight: 500;
  text-decoration: none;
  transition: color 120ms ease;
}

.site-nav a:hover {
  color: var(--primary);
}

.site-nav a[aria-current="page"] {
  color: var(--primary);
}

.site-nav a[aria-current="page"]::after {
  position: absolute;
  inset: auto 0 -0.5rem 0;
  block-size: 2px;
  background-color: var(--primary);
  content: "";
}

.page {
  max-inline-size: var(--page-max);
  margin-inline: auto;
  inline-size: 100%;
  padding-inline: var(--page-pad);
  padding-block: var(--space-xl);
}

.site-footer {
  max-inline-size: var(--page-max);
  margin-inline: auto;
  inline-size: 100%;
  padding-inline: var(--page-pad);
  padding-block: var(--space-lg) var(--space-2xl);
  color: var(--night-owl-muted);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

.site-footer .section-rule {
  margin-block-end: var(--space-md);
}

.site-footer p {
  margin: 0;
}

.site-footer ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm) var(--space-md);
  margin: var(--space-sm) 0 0;
  padding: 0;
  list-style: none;
}

.site-footer a {
  color: var(--night-owl-muted);
  text-decoration: none;
  transition: color 120ms ease;
}

.site-footer a:hover {
  color: var(--primary);
}

/* ── Shared surfaces and rules ────────────────────────────────────────── */

.surface-card {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-card);
  border: 1px solid var(--night-owl-border);
  background-color: var(--night-owl-surface);
}

.surface-card::before {
  position: absolute;
  inset: 0 auto auto 0;
  z-index: -1;
  inline-size: 5rem;
  block-size: 2px;
  background: linear-gradient(90deg, var(--night-owl-cyan), transparent);
  content: "";
}

.surface-card::after {
  position: absolute;
  inset: 0 0 auto auto;
  z-index: -1;
  inline-size: 2.5rem;
  block-size: 2.5rem;
  border-block-start: 1px solid rgba(127, 219, 202, 0.32);
  border-inline-end: 1px solid rgba(127, 219, 202, 0.32);
  clip-path: polygon(100% 0, 100% 100%, 0 0);
  content: "";
}

.surface-card-tint {
  background-image: linear-gradient(135deg, rgba(130, 170, 255, 0.08), transparent 42%);
}

.prose-muted {
  color: var(--night-owl-muted);
}

.section-kicker {
  color: var(--night-owl-cyan);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.section-rule {
  block-size: 1px;
  background: linear-gradient(90deg, var(--night-owl-border), transparent);
}

.visually-hidden {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Blog prose (article content) ─────────────────────────────────────── */

/* The prose column fills the page (72rem), as the Astro layout did: its
 * `.blog-prose` article sat directly inside `max-w-6xl` with no measure of
 * its own. Capping it at --prose-measure squeezed figures into ~600px and
 * made the browser pick the 640px srcset variant, so diagrams rendered soft
 * at half the width they were drawn for. Prose that wants a narrower measure
 * (the learn ledes, the 404) sets one on its own element. */
.blog-prose {
  line-height: 1.7;
}

.blog-prose h1 {
  font-size: var(--text-3xl);
  line-height: var(--text-3xl-line);
  margin-block: var(--space-lg) var(--space-sm);
}

.blog-prose h2 {
  font-size: var(--text-2xl);
  line-height: var(--text-2xl-line);
  margin-block: var(--space-lg) var(--space-sm);
}

.blog-prose h3 {
  font-size: var(--text-xl);
  line-height: var(--text-xl-line);
  margin-block: 1.25rem var(--space-xs);
}

.blog-prose h4 {
  font-size: var(--text-lg);
  line-height: var(--text-lg-line);
  margin-block: var(--space-md) var(--space-xs);
}

.blog-prose p {
  color: var(--night-owl-fg);
  margin-block: var(--space-sm);
  line-height: 1.7;
}

.blog-prose a {
  color: var(--primary);
  text-decoration: underline;
}

.blog-prose a:hover {
  text-decoration: none;
}

.blog-prose code {
  color: var(--night-owl-green);
  background: var(--night-owl-bg);
  padding: 0.1em 0.3em;
  border-radius: var(--radius-sm);
}

.blog-prose pre {
  background: var(--night-owl-bg);
  border: 1px solid var(--night-owl-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  overflow-inline: auto;
}

/* Highlighted blocks carry their own inline colours per span; the outer
 * `<code>` only supplies the base colour for runs a grammar left unstyled
 * (plain text, and diagram source), which must read as body text, not as
 * the green used for inline code. */
.blog-prose pre code {
  color: var(--night-owl-fg);
  background: transparent;
  padding: 0;
}

/* Quotations (scripture, cited passages) read as highlighted source
 * material: an accent bar on the reading-start edge plus a panel tint. */
.blog-prose blockquote {
  border-inline-start: 3px solid var(--primary);
  background: var(--night-owl-bg);
  border-radius: 0.375rem;
  margin-block: var(--space-md);
  margin-inline: 0;
  padding: 0.75rem var(--space-md);
}

.blog-prose blockquote p {
  margin-block: var(--space-2xs);
}

/* A bare reset strips list markers; restore them for article lists.
 * list-style-type longhand on purpose: the `disc` shorthand collapses to
 * `list-style: outside`, which loses the marker. */
.blog-prose ul {
  list-style-type: disc;
  margin-block: var(--space-sm);
  padding-inline-start: var(--space-lg);
}

.blog-prose ol {
  list-style-type: decimal;
  margin-block: var(--space-sm);
  padding-inline-start: var(--space-lg);
}

.blog-prose li {
  margin-block: 0.375rem;
}

.blog-prose img {
  border-radius: var(--radius-md);
  margin-block: 1.25rem;
}

/* Figures the post components produce: a video keeps a 16:9 box, and a wide
 * table scrolls inside its own frame instead of the page. */
.blog-prose figure {
  margin-block: var(--space-md);
}

.blog-prose .video-frame {
  position: relative;
  inline-size: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border-radius: var(--radius-lg);
  border: 1px solid var(--night-owl-border);
}

.blog-prose .video-frame iframe {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  border: 0;
}


/* Math arrives as MathML, which needs no stylesheet to be readable: the
 * browser has a default layout for it. These rules only place it. Display
 * math is a block, so it gets its own line and its own scroll container -
 * a wide equation on a narrow screen scrolls rather than forcing the page
 * to scroll sideways. */
.blog-prose .math {
  color: var(--night-owl-fg);
  font-size: 1.05em;
}

.blog-prose .math--display {
  display: block;
  margin-block: var(--space-md);
  padding-block: var(--space-sm);
  overflow-inline: auto;
  text-align: center;
  border-inline-start: 2px solid var(--night-owl-border);
  background: var(--night-owl-bg);
  border-radius: var(--radius-md);
}

/* A diagram is an image of a diagram: it scales with the column, keeps its
 * intrinsic ratio from the width/height pair the renderer emits, and never
 * grows past its own pixel size into a blurry mess. */
.blog-prose .diagram {
  margin-block: var(--space-md);
  margin-inline: 0;
}

.blog-prose .diagram img {
  display: block;
  inline-size: 100%;
  block-size: auto;
  max-inline-size: 100%;
  margin: 0;
  border: 1px solid var(--night-owl-border);
  border-radius: var(--radius-lg);
  background: var(--night-owl-surface);
}

/* The fallback for a mermaid fence with no committed diagram: visible, so it
 * cannot be mistaken for a rendered diagram, and readable, so the source can
 * be copied straight back out. */
.blog-prose pre.mermaid {
  border-inline-start: 3px solid var(--night-owl-red);
}

.blog-prose pre.mermaid code {
  color: var(--night-owl-muted);
}
.blog-prose .table-scroll {
  overflow-inline: auto;
  border: 1px solid var(--night-owl-border);
  border-radius: var(--radius-lg);
  background: var(--night-owl-surface);
}

.blog-prose table {
  inline-size: 100%;
  border-collapse: collapse;
  text-align: start;
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

.blog-prose th {
  padding: var(--space-sm) var(--space-md);
  border-block-end: 1px solid var(--night-owl-border);
  color: var(--night-owl-muted);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.blog-prose td {
  padding: var(--space-sm) var(--space-md);
  border-block-end: 1px solid var(--night-owl-border);
  vertical-align: top;
}

.blog-prose tr:last-child td {
  border-block-end: 0;
}

.blog-prose blockquote.quote {
  font-style: italic;
}

.blog-prose blockquote.quote footer {
  margin-block-start: var(--space-xs);
  color: var(--night-owl-muted);
  font-size: var(--text-xs);
  line-height: var(--text-xs-line);
  font-style: normal;
}
.blog-prose figcaption {
  color: var(--night-owl-muted);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
  margin-block-start: var(--space-xs);
}

/* ── Motion ───────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── Tips: the two CSS demos ──────────────────────────────────────────── */

/* scroll-containers: a grid with a scrolling middle row. The header and
 * footer stay put because the middle track is 1fr and scrolls on its own. */
.tip-demo {
  display: grid;
  grid-template-rows: auto 1fr auto;
  gap: var(--space-md);
  margin-block: var(--space-md);
  border: 1px solid var(--night-owl-border);
  border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-sm) var(--space-md);
}

.tip-demo__bar {
  margin: 0;
  border-block-end: 1px solid var(--night-owl-border);
  padding-block-end: var(--space-sm);
  color: var(--night-owl-fg);
  font-size: var(--text-lg);
  line-height: var(--text-lg-line);
  font-weight: 600;
}

.tip-demo__scroll {
  height: 16rem;
  overflow: auto;
}

.tip-demo__scroll p {
  margin: 0;
  color: var(--night-owl-fg);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

.tip-demo__foot {
  margin-block-start: var(--space-md);
  border-block-start: 1px solid var(--night-owl-border);
  padding-block-start: var(--space-md);
}

.tip-demo__foot p {
  margin: 0;
  color: var(--night-owl-fg);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

/* scrollbar-gutter: two panels, identical text, one reserving the gutter. */
.tip-demo-pair {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
  margin-block-start: var(--space-md);
}

@media (min-width: 48rem) {
  .tip-demo-pair {
    grid-template-columns: 1fr 1fr;
  }
}

.tip-demo-panel {
  border: 1px solid var(--night-owl-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
}

.tip-demo-panel__label {
  margin-block-end: var(--space-sm);
  color: var(--night-owl-fg);
  font-weight: 600;
}

.tip-demo-panel__scroll {
  height: 16rem;
  overflow: auto;
  border: 1px solid var(--night-owl-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
}

.tip-demo-panel__scroll p {
  margin: 0;
  color: var(--night-owl-fg);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

.tip-demo-panel__scroll p + p {
  margin-block-start: var(--space-sm);
}

/* The whole point of the tip: one reserves the gutter, one does not. */
.tip-demo-panel__scroll--stable {
  scrollbar-gutter: stable;
}

.tip-demo-panel__scroll--auto {
  scrollbar-gutter: auto;
}

/* ── Home ─────────────────────────────────────────────────────────────── */

.home {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

/* Profile card: photo and name on the left, the link row on the right. */
.home-profile {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  padding: var(--space-lg);
}

@media (min-width: 40rem) {
  .home-profile {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-xl);
  }
}

.home-profile__identity {
  display: flex;
  align-items: center;
  gap: var(--space-md);
}

.home-profile__photo {
  inline-size: 6rem;
  block-size: 6rem;
  flex: 0 0 auto;
  border-radius: 50%;
  border: 2px solid rgba(127, 219, 202, 0.6);
  object-fit: cover;
  background-color: var(--night-owl-bg);
}

@media (min-width: 40rem) {
  .home-profile__photo {
    inline-size: 7rem;
    block-size: 7rem;
  }
}

.home-profile__name {
  margin-block-start: var(--space-2xs);
  font-size: var(--text-3xl);
  line-height: var(--text-3xl-line);
  font-weight: 700;
}

@media (min-width: 40rem) {
  .home-profile__name {
    font-size: var(--text-4xl);
    line-height: var(--text-4xl-line);
  }
}

.home-profile__tagline {
  margin-block-start: var(--space-xs);
  max-inline-size: 28rem;
  color: var(--night-owl-muted);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

/* Link row: six targets, wrapping rather than overflowing on narrow screens. */
.home-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  margin: 0;
  padding: 0;
  list-style: none;
}

@media (min-width: 40rem) {
  .home-links {
    justify-content: flex-end;
  }
}

.home-links__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 2.25rem;
  min-block-size: 2.25rem;
  border-radius: var(--radius-md);
  color: var(--night-owl-fg);
  font-size: var(--text-sm);
  font-weight: 600;
  text-decoration: none;
  transition: color 120ms ease;
}

.home-links__link:hover {
  color: var(--primary);
}

.home-links__cta {
  border: 1px solid rgba(130, 170, 255, 0.6);
  border-radius: var(--radius-md);
  padding: var(--space-xs) var(--space-md);
  color: var(--primary);
  font-size: var(--text-sm);
  font-weight: 600;
  text-decoration: none;
  transition:
    background-color 120ms ease,
    color 120ms ease;
}

.home-links__cta:hover {
  background-color: var(--primary);
  color: var(--on-primary);
}

/* Two cards side by side once there is room, stacked before that. */
.home-columns {
  display: grid;
  gap: var(--space-lg);
}

@media (min-width: 64rem) {
  .home-columns {
    grid-template-columns: 1.15fr 0.85fr;
  }
}

.card {
  border: 1px solid var(--night-owl-border);
  border-radius: var(--radius-lg);
  background-color: var(--night-owl-surface);
  box-shadow: var(--shadow-card);
  padding: var(--space-lg);
}

@media (min-width: 40rem) {
  .card {
    padding: var(--space-xl);
  }
}

.card > h2 {
  margin-block: var(--space-2xs) var(--space-md);
  font-size: var(--text-2xl);
  line-height: var(--text-2xl-line);
}

/* A vertical run of labelled blocks: principles, toolkit groups. */
.stack-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.stack-list__value {
  margin-block-start: var(--space-xs);
  color: var(--night-owl-fg);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

.home-principle {
  border-inline-start: 2px solid var(--night-owl-border);
  padding-inline-start: var(--space-md);
}

.home-principle--night-owl-cyan {
  border-inline-start-color: var(--night-owl-cyan);
}

.home-principle--night-owl-purple {
  border-inline-start-color: var(--night-owl-purple);
}

.home-principle--night-owl-green {
  border-inline-start-color: var(--night-owl-green);
}

.home-principle__title {
  color: var(--night-owl-fg);
  font-weight: 700;
}

.home-principle__body {
  margin-block-start: var(--space-2xs);
  color: var(--night-owl-muted);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

/* Selected work. */
.home-work__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-md);
  margin-block-end: var(--space-md);
}

.home-work__head h2 {
  margin-block-start: var(--space-2xs);
  font-size: var(--text-2xl);
  line-height: var(--text-2xl-line);
}

.home-work__count {
  display: none;
  color: var(--night-owl-muted);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: var(--text-xs-line);
  white-space: nowrap;
}

@media (min-width: 40rem) {
  .home-work__count {
    display: inline;
  }
}

.home-work__grid {
  display: grid;
  gap: var(--space-md) var(--space-xl);
}

@media (min-width: 48rem) {
  .home-work__grid {
    grid-template-columns: 1fr 1fr;
  }
}

.home-project {
  border-block-start: 1px solid var(--night-owl-border);
  padding-block-start: var(--space-sm);
}

.home-project__name {
  color: var(--night-owl-fg);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
  font-weight: 700;
}

.home-project__detail {
  margin-block-start: var(--space-2xs);
  color: var(--night-owl-muted);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

.home-project__unstick {
  margin-block-start: var(--space-2xs);
  color: var(--night-owl-cyan);
  font-size: var(--text-xs);
  line-height: var(--text-xs-line);
}

/* ── Blog index and post pages ────────────────────────────────────────── */

/* The index header: kicker, title, rule - the shape every page head uses. */
.blog-head {
  margin-block-end: var(--space-xl);
}

.blog-head__title {
  margin-block: var(--space-2xs) var(--space-md);
  font-size: var(--text-4xl);
  line-height: var(--text-4xl-line);
}

/* The list: one card per post, stacked with a consistent gap. */
.blog-list {
  display: grid;
  gap: var(--space-md);
  margin-block-end: var(--space-xl);
}

.blog-card {
  padding: var(--space-lg);
  transition:
    border-color 120ms ease,
    background-color 120ms ease;
}

.blog-card:hover {
  border-color: rgba(130, 170, 255, 0.6);
}

.blog-card__kicker {
  margin-block-end: var(--space-sm);
}

.blog-card__title {
  font-size: var(--text-xl);
  line-height: var(--text-xl-line);
}

/* The title is the card's whole target, so its underline is drawn in the
 * border colour until hover: the card is the affordance, not the words. */
.blog-card__link {
  color: var(--night-owl-fg);
  text-decoration: underline;
  text-decoration-color: var(--night-owl-border);
  text-underline-offset: 0.2em;
  transition:
    color 120ms ease,
    text-decoration-color 120ms ease;
}

.blog-card__link:hover {
  color: var(--primary);
  text-decoration-color: var(--primary);
}

.blog-card__stamp {
  margin-block-start: var(--space-sm);
  color: var(--night-owl-muted);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: var(--text-xs-line);
}

.blog-card__stamp-label {
  color: var(--night-owl-cyan);
}

/* The empty state: one centred card, same shape the old page used. */
.blog-empty {
  display: flex;
  justify-content: center;
  padding: var(--space-xl);
  margin-block-end: var(--space-xl);
}

.blog-empty__text {
  color: var(--night-owl-muted);
}

/* Pagination: a centred row of page numbers with the two edges at the ends. */
.blog-pagination {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-xs);
}

.blog-pagination__number,
.blog-pagination__edge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-inline-size: 2.25rem;
  padding: 0.375rem 0.75rem;
  border: 1px solid var(--night-owl-border);
  border-radius: var(--radius-md);
  color: var(--night-owl-fg);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
  text-decoration: none;
  transition:
    color 120ms ease,
    border-color 120ms ease;
}

.blog-pagination__number:hover,
.blog-pagination__edge:hover {
  color: var(--primary);
  border-color: var(--primary);
}

.blog-pagination__number--current {
  border-color: var(--primary);
  background-color: rgba(130, 170, 255, 0.2);
  color: var(--primary);
  font-weight: 600;
}

/* A dead end is inert, not merely unlinked: dimmed, and not clickable. */
.blog-pagination__edge--disabled {
  color: var(--night-owl-muted);
  cursor: not-allowed;
  opacity: 0.5;
}

/* Post page: the title above the prose column. */
.blog-post__title {
  margin-block-end: var(--space-lg);
  font-size: var(--text-4xl);
  line-height: var(--text-4xl-line);
}

/* ── Learn page ───────────────────────────────────────────────────────── */

/* The page head: kicker, title, rule - the shape every page head uses. */
.learn-head {
  margin-block-end: var(--space-lg);
}

.learn-head__title {
  margin-block: var(--space-2xs) var(--space-md);
  font-size: var(--text-4xl);
  line-height: var(--text-4xl-line);
}

.learn-intro {
  max-inline-size: var(--prose-measure);
  color: var(--night-owl-fg);
}

/* Where to begin: quieter than the intro, since it repeats the map below. */
.learn-start {
  margin-block-start: var(--space-md);
  max-inline-size: var(--prose-measure);
  color: var(--night-owl-muted);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

/* The map: ten stages as one list, each row a whole-row link. */
.learn-map {
  margin-block-start: var(--space-xl);
}

.learn-map__list {
  margin: 0;
  padding: 0;
  list-style: none;
  border-block: 1px solid var(--night-owl-border);
}

.learn-map__item + .learn-map__item {
  border-block-start: 1px solid var(--night-owl-border);
}

.learn-map__link {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-md);
  padding: var(--space-sm) var(--space-2xs);
  color: var(--night-owl-fg);
  text-decoration: none;
  transition: background-color 120ms ease;
}

.learn-map__link:hover {
  background-color: var(--night-owl-surface);
}

.learn-map__number {
  color: var(--night-owl-cyan);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: var(--text-xs-line);
}

.learn-map__title {
  font-weight: 500;
  transition: color 120ms ease;
}

.learn-map__link:hover .learn-map__title {
  color: var(--primary);
}

.learn-map__count {
  margin-inline-start: auto;
  color: var(--night-owl-muted);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: var(--text-xs-line);
  white-space: nowrap;
}

/* The legend: each marker once, with the register it arrives in. */
.learn-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs) var(--space-lg);
  margin-block: var(--space-lg) 0;
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

.learn-legend__item {
  display: flex;
  align-items: baseline;
  gap: var(--space-xs);
}

.learn-legend__register {
  margin: 0;
  color: var(--night-owl-muted);
}

.learn-tally {
  margin-block-start: var(--space-md);
  color: var(--night-owl-muted);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: var(--text-xs-line);
}

/* Stages: one section each, separated by a wide gap. */
.learn-stages {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xl);
  margin-block-start: var(--space-2xl);
}

.learn-stage {
  scroll-margin-block-start: var(--space-xl);
}

.learn-stage__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-md);
  margin-block-end: var(--space-sm);
}

.learn-stage__number {
  color: var(--night-owl-cyan);
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
  font-weight: 700;
}

.learn-stage__title {
  font-size: var(--text-2xl);
  line-height: var(--text-2xl-line);
}

.learn-stage__markers {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  color: var(--night-owl-muted);
  font-size: var(--text-xs);
  line-height: var(--text-xs-line);
}

.learn-stage__lede {
  margin-block-start: var(--space-md);
  max-inline-size: var(--prose-measure);
  color: var(--night-owl-fg);
}

.learn-groups {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  margin-block-start: var(--space-md);
}

.learn-group {
  padding: var(--space-lg);
}

.learn-group__heading {
  font-size: var(--text-lg);
  line-height: var(--text-lg-line);
}

.learn-group__blurb {
  margin-block-start: var(--space-xs);
  max-inline-size: var(--prose-measure);
  color: var(--night-owl-muted);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

/* Entries: a bordered run, one row per source. */
.learn-entries {
  margin: var(--space-md) 0 0;
  padding: 0;
  list-style: none;
  border-block-start: 1px solid var(--night-owl-border);
}

.learn-entry {
  padding-block: var(--space-sm);
}

.learn-entry + .learn-entry {
  border-block-start: 1px solid var(--night-owl-border);
}

.learn-entry__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-sm);
}

.learn-entry__title {
  color: var(--night-owl-fg);
  font-weight: 500;
}

/* The title is the target, so its underline is drawn in the border colour
 * until hover: the row is the affordance, not the words. */
.learn-entry__link {
  color: var(--night-owl-fg);
  text-decoration: underline;
  text-decoration-color: var(--night-owl-border);
  text-underline-offset: 0.2em;
  transition:
    color 120ms ease,
    text-decoration-color 120ms ease;
}

.learn-entry__link:hover {
  color: var(--primary);
  text-decoration-color: var(--primary);
}

.learn-entry__by {
  color: var(--night-owl-muted);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

/* A cross-reference reads as a chip: small, bordered, cyan. */
.learn-entry__also {
  padding: 0.125rem 0.5rem;
  border: 1px solid rgba(127, 219, 202, 0.3);
  border-radius: var(--radius-md);
  color: var(--night-owl-cyan);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: var(--text-xs-line);
  text-decoration: none;
  white-space: nowrap;
  transition: border-color 120ms ease;
}

.learn-entry__also:hover {
  border-color: var(--night-owl-cyan);
}

.learn-entry__note {
  margin-block-start: var(--space-2xs);
  max-inline-size: var(--prose-measure);
  color: var(--night-owl-muted);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

/* The two closing blocks: the check, then what to pair the stage with. */
.learn-done {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2xs) var(--space-sm);
  margin-block-start: var(--space-md);
  padding-inline-start: var(--space-md);
  border-inline-start: 2px solid rgba(127, 219, 202, 0.5);
}

.learn-done__text {
  max-inline-size: var(--prose-measure);
  color: var(--night-owl-fg);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

.learn-pair {
  margin-block-start: var(--space-md);
  max-inline-size: var(--prose-measure);
  color: var(--night-owl-muted);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
}

.learn-pair__label {
  color: var(--night-owl-cyan);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: var(--text-xs-line);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* Marker badges: an inline glyph tinted per register. The icon carries the
 * meaning; the tint only groups entries of one format at a glance. */
.marker-badge {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  gap: var(--space-2xs);
  padding: 0.125rem 0.375rem;
  border: 1px solid var(--night-owl-border);
  border-radius: var(--radius-md);
}

.marker-badge__icon {
  flex-shrink: 0;
}

.marker-badge__count {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: var(--text-xs-line);
}

.marker-badge--video {
  border-color: rgba(127, 219, 202, 0.4);
  background-color: rgba(127, 219, 202, 0.1);
  color: var(--night-owl-cyan);
}

.marker-badge--course {
  border-color: rgba(130, 170, 255, 0.4);
  background-color: rgba(130, 170, 255, 0.1);
  color: var(--primary);
}

.marker-badge--book {
  border-color: rgba(199, 146, 234, 0.4);
  background-color: rgba(199, 146, 234, 0.1);
  color: var(--night-owl-purple);
}

.marker-badge--lab {
  border-color: rgba(197, 228, 120, 0.4);
  background-color: rgba(197, 228, 120, 0.1);
  color: var(--success);
}

.marker-badge--paper {
  border-color: rgba(236, 196, 141, 0.4);
  background-color: rgba(236, 196, 141, 0.1);
  color: var(--warning);
}

.marker-badge--corpus {
  border-color: rgba(247, 140, 108, 0.4);
  background-color: rgba(247, 140, 108, 0.1);
  color: var(--night-owl-orange);
}

/* ── Tips pages ───────────────────────────────────────────────────────── */

/* The page head: kicker, title, rule - the shape every page head uses. */
.tips-head {
  margin-block-end: var(--space-lg);
}

.tips-head__title {
  margin-block: var(--space-2xs) var(--space-md);
  font-size: var(--text-4xl);
  line-height: var(--text-4xl-line);
}

/* The list: one card per tip, stacked. The old page used a bare flex column;
 * a grid with an explicit gap does the same job without the wrapper. */
.tips-list {
  display: grid;
  gap: var(--space-md);
  margin: 0;
  padding: 0;
  list-style: none;
}

.tips-card {
  padding: var(--space-lg);
  transition: border-color 120ms ease;
}

.tips-card:hover {
  border-color: rgba(130, 170, 255, 0.6);
}

.tips-card__title {
  font-size: var(--text-xl);
  line-height: var(--text-xl-line);
}

/* The title is the card's whole target, so its underline is drawn in the
 * border colour until hover: the card is the affordance, not the words. */
.tips-card__link {
  color: var(--night-owl-fg);
  text-decoration: underline;
  text-decoration-color: var(--night-owl-border);
  text-underline-offset: 0.2em;
  transition:
    color 120ms ease,
    text-decoration-color 120ms ease;
}

.tips-card__link:hover {
  color: var(--primary);
  text-decoration-color: var(--primary);
}

/* A tip page: the title above the prose column, the same shape a post uses. */
.tip__title {
  margin-block-end: var(--space-lg);
  font-size: var(--text-4xl);
  line-height: var(--text-4xl-line);
}

/* ── Not found ────────────────────────────────────────────────────────── */

.not-found {
  max-inline-size: var(--prose-measure);
}

.not-found__title {
  margin-block: var(--space-2xs) var(--space-md);
  font-size: var(--text-4xl);
  line-height: var(--text-4xl-line);
}

.not-found__text {
  margin-block: var(--space-lg);
}

/* Two doors back in, side by side rather than as a run of sentences. */
.not-found__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm) var(--space-md);
  margin: 0;
  padding: 0;
  list-style: none;
}

.not-found__links a {
  display: inline-flex;
  align-items: center;
  padding: 0.375rem 0.75rem;
  border: 1px solid var(--night-owl-border);
  border-radius: var(--radius-md);
  color: var(--night-owl-fg);
  font-size: var(--text-sm);
  line-height: var(--text-sm-line);
  text-decoration: none;
  transition:
    color 120ms ease,
    border-color 120ms ease;
}

.not-found__links a:hover {
  color: var(--primary);
  border-color: var(--primary);
}
/* ── Print ────────────────────────────────────────────────────────────── */

@media print {
  body {
    background-image: none;
  }

  .site-nav,
  .site-footer {
    display: none;
  }
}
