/* ====== DatJavaClass.com — theme tokens & base ====== */

:root {
  /* default palette: amber + cyan (dark mode) */
  --bg: oklch(0.155 0.008 60);
  --surface: oklch(0.205 0.010 60);
  --surface-2: oklch(0.255 0.012 60);
  --surface-3: oklch(0.30 0.013 60);
  --border: oklch(0.34 0.012 60 / 0.55);
  --border-strong: oklch(0.42 0.014 60 / 0.85);
  --text: oklch(0.96 0.005 80);
  --text-2: oklch(0.78 0.008 70);
  --muted: oklch(0.58 0.010 65);
  --accent: oklch(0.82 0.15 75);     /* amber */
  --accent-2: oklch(0.80 0.12 220);  /* cyan */
  --accent-ink: oklch(0.18 0.04 75);
  --danger: oklch(0.70 0.18 28);
  --ok: oklch(0.75 0.14 150);

  /* density */
  --pad: 24px;
  --pad-sm: 14px;
  --pad-lg: 36px;
  --gap: 20px;
  --radius: 14px;
  --radius-sm: 8px;
  --radius-lg: 22px;

  /* type */
  --font-display: "Space Grotesk", system-ui, sans-serif;
  --font-body: "IBM Plex Sans", system-ui, sans-serif;
  --font-mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --font-serif: "IBM Plex Serif", Georgia, serif;

  --shadow-sm: 0 1px 0 oklch(1 0 0 / 0.04) inset, 0 2px 8px oklch(0 0 0 / 0.20);
  --shadow: 0 1px 0 oklch(1 0 0 / 0.05) inset, 0 8px 24px oklch(0 0 0 / 0.32);
  --shadow-lg: 0 1px 0 oklch(1 0 0 / 0.06) inset, 0 24px 60px oklch(0 0 0 / 0.45);
}

/* ====== palettes ====== */
[data-palette="amber-cyan"][data-dark="true"] {
  --accent: oklch(0.82 0.15 75);
  --accent-2: oklch(0.80 0.12 220);
  --accent-ink: oklch(0.20 0.05 75);
}
[data-palette="amber-cyan"][data-dark="false"] {
  --accent: oklch(0.62 0.16 60);
  --accent-2: oklch(0.55 0.14 230);
  --accent-ink: #fff;
}
[data-palette="mint-plum"][data-dark="true"] {
  --accent: oklch(0.82 0.14 165);
  --accent-2: oklch(0.74 0.16 340);
  --accent-ink: oklch(0.18 0.04 165);
}
[data-palette="mint-plum"][data-dark="false"] {
  --accent: oklch(0.55 0.14 165);
  --accent-2: oklch(0.55 0.18 340);
  --accent-ink: #fff;
}
[data-palette="coral-indigo"][data-dark="true"] {
  --accent: oklch(0.78 0.17 28);
  --accent-2: oklch(0.72 0.16 270);
  --accent-ink: oklch(0.20 0.05 28);
}
[data-palette="coral-indigo"][data-dark="false"] {
  --accent: oklch(0.63 0.18 28);
  --accent-2: oklch(0.50 0.18 270);
  --accent-ink: #fff;
}
[data-palette="lime-magenta"][data-dark="true"] {
  --accent: oklch(0.88 0.18 125);
  --accent-2: oklch(0.74 0.20 330);
  --accent-ink: oklch(0.18 0.05 125);
}
[data-palette="lime-magenta"][data-dark="false"] {
  --accent: oklch(0.70 0.20 130);
  --accent-2: oklch(0.55 0.22 330);
  --accent-ink: oklch(0.16 0.04 125);
}

/* ====== dark / light surfaces ====== */
[data-dark="true"] {
  --bg: oklch(0.155 0.008 60);
  --surface: oklch(0.205 0.010 60);
  --surface-2: oklch(0.255 0.012 60);
  --surface-3: oklch(0.30 0.013 60);
  --border: oklch(0.34 0.012 60 / 0.55);
  --border-strong: oklch(0.42 0.014 60 / 0.85);
  --text: oklch(0.96 0.005 80);
  --text-2: oklch(0.78 0.008 70);
  --muted: oklch(0.58 0.010 65);
}
[data-dark="false"] {
  --bg: oklch(0.985 0.004 80);
  --surface: oklch(1 0 0);
  --surface-2: oklch(0.965 0.006 75);
  --surface-3: oklch(0.94 0.008 75);
  --border: oklch(0.86 0.008 75);
  --border-strong: oklch(0.74 0.010 75);
  --text: oklch(0.20 0.010 60);
  --text-2: oklch(0.38 0.010 60);
  --muted: oklch(0.52 0.008 60);
  --shadow-sm: 0 1px 0 oklch(1 0 0 / 0.6) inset, 0 1px 2px oklch(0 0 0 / 0.06), 0 2px 8px oklch(0 0 0 / 0.04);
  --shadow: 0 1px 0 oklch(1 0 0 / 0.7) inset, 0 4px 16px oklch(0 0 0 / 0.08);
  --shadow-lg: 0 1px 0 oklch(1 0 0 / 0.8) inset, 0 24px 60px oklch(0 0 0 / 0.12);
}

/* ====== font pairings ====== */
[data-font-pair="grotesk-plex"] {
  --font-display: "Space Grotesk", system-ui, sans-serif;
  --font-body: "IBM Plex Sans", system-ui, sans-serif;
}
[data-font-pair="plex-serif"] {
  --font-display: "IBM Plex Serif", Georgia, serif;
  --font-body: "IBM Plex Sans", system-ui, sans-serif;
}
[data-font-pair="mono-all"] {
  --font-display: "JetBrains Mono", ui-monospace, monospace;
  --font-body: "JetBrains Mono", ui-monospace, monospace;
}
[data-font-pair="grotesk-serif"] {
  --font-display: "Space Grotesk", system-ui, sans-serif;
  --font-body: "IBM Plex Serif", Georgia, serif;
}

/* ====== density ====== */
[data-density="compact"] {
  --pad: 16px; --pad-sm: 10px; --pad-lg: 24px;
  --gap: 14px; --radius: 10px; --radius-lg: 16px;
  --body-size: 14.5px;
}
[data-density="regular"] {
  --pad: 24px; --pad-sm: 14px; --pad-lg: 36px;
  --gap: 20px; --radius: 14px; --radius-lg: 22px;
  --body-size: 16px;
}
[data-density="comfy"] {
  --pad: 32px; --pad-sm: 18px; --pad-lg: 48px;
  --gap: 28px; --radius: 18px; --radius-lg: 28px;
  --body-size: 17px;
}

/* ====== base ====== */
* { box-sizing: border-box; }
html, body {
  margin: 0; padding: 0;
  background: var(--bg); color: var(--text);
  font-family: var(--font-body);
  font-size: var(--body-size, 16px);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
body {
  min-height: 100vh;
  background-image:
    radial-gradient(60% 50% at 10% 0%, oklch(from var(--accent) l c h / 0.06), transparent 60%),
    radial-gradient(50% 40% at 100% 0%, oklch(from var(--accent-2) l c h / 0.05), transparent 60%);
  background-attachment: fixed;
}
[data-dark="false"] body {
  background-image:
    radial-gradient(60% 50% at 10% 0%, oklch(from var(--accent) l c h / 0.10), transparent 60%),
    radial-gradient(50% 40% at 100% 0%, oklch(from var(--accent-2) l c h / 0.08), transparent 60%);
}

/* ====== Code-snapshot wallpaper ======================================
   A fixed, viewport-covering pattern of Java-style code fragments lifted
   from the site's own content (about-page class def, advice loop, blog
   filter, the footer stub, etc).

   Tokenized with syntax colors baked into the SVG so it reads like
   peering into a translucent IDE. The same colors are tuned to a middle
   brightness/saturation that works on both dark and light backgrounds —
   no per-mode SVG swap.

   The SVG tiles (no `cover`) so the pattern feels dense and small. Each
   tile is the full set of code clusters; tiling adds even more.

   Layering:
     - body keeps its accent radial gradients (the warm baseline).
     - body::before paints the wallpaper.
     - .app / main content gets position: relative + z-index 1 to sit on
       top of the pattern. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background-image: url("../images/code-pattern.svg");
  background-repeat: repeat;
  /* Smaller tile = smaller-looking text + more of it on screen. */
  /* Masonry layout in the SVG fills the canvas evenly — pattern density
     is now consistent, so opacity can come back down to a polite "you can
     tell what it is" level without competing with the foreground content. */
  background-size: 1100px auto;
  background-position: 0 0;
  opacity: 0.42;
}
[data-dark="false"] body::before {
  /* Light backgrounds swallow alpha faster than dark. */
  opacity: 0.55;
}
/* Make sure the app shell renders above the wallpaper. */
.app { position: relative; z-index: 1; }

a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; }

h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 600; letter-spacing: -0.015em; margin: 0; }
h1 { font-size: clamp(2rem, 3.4vw, 3.4rem); line-height: 1.05; }
h2 { font-size: clamp(1.5rem, 2.2vw, 2.1rem); line-height: 1.12; }
h3 { font-size: 1.2rem; line-height: 1.25; }

code, pre, .mono { font-family: var(--font-mono); font-feature-settings: "ss01", "ss02"; }

/* ====== app layout ====== */
.app {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  min-height: 100vh;
}
.app[data-rail="true"] {
  grid-template-columns: 56px minmax(0, 1fr);
}
.rail {
  position: sticky; top: 0; left: 0;
  height: 100vh;
  display: flex; flex-direction: column;
  align-items: center; justify-content: space-between;
  padding: 18px 0;
  border-right: 1px solid var(--border);
  background: oklch(from var(--bg) l c h / 0.85);
  backdrop-filter: blur(8px);
}
.rail-marks { display: flex; flex-direction: column; gap: 6px; align-items: center; }
.rail-tick {
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--muted); opacity: 0.4;
}
.rail-tick.major { background: var(--accent); opacity: 1; width: 6px; height: 6px; }
.rail-socials { display: flex; flex-direction: column; gap: 10px; }
.rail-icon {
  width: 36px; height: 36px; border-radius: 10px;
  display: grid; place-items: center;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-2);
  transition: background .15s, color .15s, border-color .15s;
}
.rail-icon:hover { background: var(--surface-2); color: var(--text); border-color: var(--border-strong); }
.rail-icon svg { width: 16px; height: 16px; }
.rail-brand {
  font-family: var(--font-mono); font-size: 10px; font-weight: 800;
  writing-mode: vertical-rl; transform: rotate(180deg);
  color: var(--text); letter-spacing: 0.22em;
  padding: 8px 0;
}

/* ====== Rail: mobile-only extras (search + divider + follow label) ======
   These three elements are emitted by template-parts/social-rail.php but
   hidden on desktop. On narrow viewports they swap in via flex `order:`
   to produce the layout:
       search → divider → socials → FOLLOW ME: → (spacer) → DESK
   Desktop keeps the original 3-element brand/marks/socials layout. */
.rail-search,
.rail-divider,
.rail-brand--follow {
  display: none;
}
.rail-search {
  width: 36px; height: 36px; border-radius: 10px;
  align-items: center; justify-content: center;
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text-2);
  cursor: pointer;
  padding: 0;
  transition: background .15s, color .15s, border-color .15s;
}
.rail-search:hover,
.rail-search:focus-visible {
  background: var(--surface-2);
  color: var(--text);
  border-color: var(--border-strong);
}
.rail-search svg { width: 18px; height: 18px; display: block; }
.rail-divider {
  width: 18px; height: 1px;
  background: var(--border);
  opacity: 0.7;
}
.rail-secret {
  color: inherit;
  text-decoration: none;
  transition: color 0.18s, text-shadow 0.18s;
  cursor: pointer;
}
.rail-secret:hover {
  color: var(--accent);
  text-shadow: 0 0 14px oklch(from var(--accent) l c h / 0.5);
}

.shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  width: 100%;
  max-width: 1320px;
  margin: 0 auto;
  padding: 0 var(--pad);
}

/* ====== top header ====== */
.topbar {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px var(--pad);
  background: oklch(from var(--bg) l c h / 0.78);
  backdrop-filter: blur(14px) saturate(140%);
  border-bottom: 1px solid var(--border);
}
.brand {
  display: flex; align-items: baseline; gap: 10px;
  font-family: var(--font-display);
  font-weight: 700; letter-spacing: -0.02em;
  font-size: 1.18rem;
}
.brand-glyph {
  display: inline-grid; place-items: center;
  width: 30px; height: 30px;
  border-radius: 8px;
  background: var(--accent); color: var(--accent-ink);
  font-family: var(--font-mono); font-weight: 700; font-size: 14px;
  transform: translateY(2px);
}
.brand-ext { color: var(--muted); font-family: var(--font-mono); font-weight: 500; font-size: 0.78em; }
.nav {
  display: flex; align-items: center; gap: 2px;
}
.nav a {
  padding: 8px 12px; border-radius: 8px;
  color: var(--text-2);
  font-weight: 500; font-size: 0.95em;
  transition: background .14s, color .14s;
}
.nav a:hover { background: var(--surface-2); color: var(--text); }
.nav a.active { color: var(--text); background: var(--surface-2); }
.nav a.active::after {
  content: ""; display: block; height: 2px; margin-top: 4px;
  background: var(--accent); border-radius: 2px;
}

.topbar-tools { display: flex; align-items: center; gap: 8px; }
.icon-btn {
  display: inline-grid; place-items: center;
  width: 34px; height: 34px; border-radius: 9px;
  background: transparent; border: 1px solid var(--border);
  color: var(--text-2);
  transition: background .14s, color .14s;
}
.icon-btn:hover { background: var(--surface-2); color: var(--text); }
.icon-btn svg { width: 15px; height: 15px; }

.search-trigger {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 10px 7px 11px; height: 34px;
  border-radius: 9px;
  background: var(--surface-2); border: 1px solid var(--border);
  color: var(--muted); font-size: 0.88em;
  min-width: 200px;
}
.search-trigger:hover { border-color: var(--border-strong); }
.search-trigger svg { width: 14px; height: 14px; flex-shrink: 0; }
.search-trigger span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.search-trigger kbd {
  margin-left: auto;
  font-family: var(--font-mono); font-size: 0.78em;
  padding: 2px 6px; border-radius: 4px;
  background: var(--surface-3); color: var(--text-2);
  border: 1px solid var(--border);
}

/* ====== page chrome ====== */
.page {
  padding: 32px var(--pad) 80px;
  max-width: 1320px; margin: 0 auto;
}
.page-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 40px;
  align-items: start;
}
@media (max-width: 980px) {
  .page-grid { grid-template-columns: 1fr; }
}

.package-line {
  font-family: var(--font-mono);
  font-size: 0.78em;
  color: var(--muted);
  margin: 0 0 20px;
}
.package-line .kw { color: var(--accent); }
.package-line .nm { color: var(--text-2); }

/* ====== profile card ====== */
.profile {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--pad);
  box-shadow: var(--shadow);
}
.profile[data-style="hero"] { overflow: hidden; }
.profile[data-style="compact"], .profile[data-style="inline"] { overflow: hidden; }
/* When the Add Content menu is mounted inside, let it overflow below */
.profile:has(.add-content) { overflow: visible; }
.profile[data-style="hero"]::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(120% 80% at 0% 0%, oklch(from var(--accent) l c h / 0.18), transparent 60%),
    radial-gradient(80% 60% at 100% 100%, oklch(from var(--accent-2) l c h / 0.12), transparent 60%);
}
.profile > * { position: relative; }
.profile-sig {
  font-family: var(--font-mono); font-size: 0.7rem;
  color: var(--muted); letter-spacing: 0.04em;
  margin-bottom: 14px;
}
.profile-sig .kw { color: var(--accent); }
.profile-sig .cls { color: var(--text); }
.profile-avatar {
  width: 84px; height: 84px; border-radius: 50%;
  background: linear-gradient(135deg, oklch(from var(--accent) l c h / 0.35), oklch(from var(--accent-2) l c h / 0.35));
  border: 2px solid var(--border-strong);
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 700; font-size: 32px;
  color: var(--text);
  margin-bottom: 14px;
  position: relative;
}
.profile-avatar-clip {
  position: absolute; inset: 0;
  border-radius: 50%;
  overflow: hidden;
}
.profile-avatar::after {
  content: "online"; position: absolute; bottom: -2px; right: -6px;
  font-family: var(--font-mono); font-size: 9px; color: var(--ok);
  background: var(--surface); padding: 2px 6px; border-radius: 999px;
  border: 1px solid var(--border);
}
.profile-name { font-family: var(--font-display); font-size: 1.35rem; font-weight: 600; margin-bottom: 4px; }
.profile-role { font-family: var(--font-mono); font-size: 0.78rem; color: var(--accent); margin-bottom: 14px; }
.profile-bio { color: var(--text-2); font-size: 0.95em; line-height: 1.6; }
.profile-meta {
  display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
  margin-top: 18px; padding-top: 14px;
  border-top: 1px dashed var(--border);
}
.profile-meta div { font-family: var(--font-mono); font-size: 0.74rem; color: var(--muted); }
.profile-meta div b { display: block; color: var(--text); font-size: 1.4em; font-weight: 600; font-family: var(--font-display); }

.profile[data-style="compact"] .profile-avatar { width: 56px; height: 56px; font-size: 22px; }
.profile[data-style="compact"] .profile-name { font-size: 1.1rem; }
.profile[data-style="compact"] .profile-bio { display: none; }
.profile[data-style="compact"] .profile-meta { display: none; }

.profile[data-style="inline"] {
  display: flex; align-items: center; gap: 14px; padding: var(--pad-sm) var(--pad);
}
.profile[data-style="inline"] .profile-sig,
.profile[data-style="inline"] .profile-bio,
.profile[data-style="inline"] .profile-meta { display: none; }
.profile[data-style="inline"] .profile-avatar { margin-bottom: 0; width: 48px; height: 48px; font-size: 18px; }
.profile[data-style="inline"] .profile-avatar::after { display: none; }
.profile[data-style="inline"] .profile-name { font-size: 1rem; margin-bottom: 0; }
.profile[data-style="inline"] .profile-role { margin-bottom: 0; }
.profile[data-style="compact"] .profile-ask,
.profile[data-style="inline"] .profile-ask { display: none; }

/* ===== Ask for Advice button ===== */
.profile-ask {
  width: 100%;
  margin: 20px 0 0;
  padding: 12px 16px;
  display: flex; align-items: center; gap: 10px;
  background: linear-gradient(135deg,
    oklch(from var(--accent) l c h / 0.16),
    oklch(from var(--accent-2) l c h / 0.16));
  border: 1px solid oklch(from var(--accent) l c h / 0.40);
  border-radius: var(--radius-sm);
  color: var(--accent);
  font-family: var(--font-mono);
  font-size: 0.82rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
  transition: background .14s, border-color .14s, transform .1s, box-shadow .14s;
  position: relative;
}
.profile-ask:hover {
  background: linear-gradient(135deg,
    oklch(from var(--accent) l c h / 0.26),
    oklch(from var(--accent-2) l c h / 0.26));
  border-color: oklch(from var(--accent) l c h / 0.72);
  box-shadow: 0 0 0 3px oklch(from var(--accent) l c h / 0.08);
}
.profile-ask:active { transform: translateY(1px); }
.profile-ask-glyph { color: var(--accent-2); }
.profile-ask-label { flex: 1; text-align: left; }
.profile-ask-arrow { color: var(--accent-2); opacity: 0.7; font-size: 0.9em; }

/* ===== Advice overlay ===== */
.advice-overlay {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(0, 0, 0, 0.94);
  /* Note: backdrop-filter: blur() was removed here. Every character of the
     typewriter caused the browser to re-rasterize the blurred region
     behind the moving text, which made the typing visibly stutter on
     pages with real content underneath. A solid (mostly opaque) backdrop
     gives nearly the same focus effect with zero per-frame cost. */
  display: grid; place-items: center;
  padding: 40px;
  cursor: pointer;
  animation: adviceFadeIn .22s ease;
}
@keyframes adviceFadeIn { from { opacity: 0; } to { opacity: 1; } }
.advice-content {
  max-width: 1100px;
  width: 100%;
  font-family: var(--font-mono);
  line-height: 1.5;
}
.advice-line1 {
  color: #ffd84a;
  font-size: clamp(0.95rem, 1.6vw, 1.55rem);
  font-weight: 500;
  letter-spacing: 0.01em;
  margin-bottom: 18px;
  white-space: nowrap;
  overflow: hidden;
  min-height: 1.5em;
}
.advice-line2 {
  color: #ffffff;
  font-size: clamp(1.05rem, 1.9vw, 1.75rem);
  font-weight: 500;
  /* Note: text-wrap: balance was removed here. Balance re-flows the entire
     line on every text-content change, so the typewriter (which appends
     one character at a time) re-balanced ~150 times in a row and stuttered.
     text-wrap: pretty is much cheaper and still avoids ugly orphans. */
  text-wrap: pretty;
  min-height: 1.5em;
}
.advice-caret {
  display: inline-block;
  color: inherit;
  margin-left: 2px;
  animation: adviceBlink .9s steps(2) infinite;
}
@keyframes adviceBlink { 50% { opacity: 0; } }
.advice-hint {
  position: absolute; bottom: 32px; left: 0; right: 0;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: rgba(255, 255, 255, 0.4);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  pointer-events: none;
}

@media (max-width: 720px) {
  .advice-line1 { white-space: normal; }
}

/* ====== post card ====== */
.card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--pad);
  box-shadow: var(--shadow-sm);
  transition: transform .18s ease, border-color .18s, box-shadow .18s;
  overflow: hidden;
}
.card:hover { border-color: var(--border-strong); transform: translateY(-1px); box-shadow: var(--shadow); }

[data-card="outlined"] .card { background: transparent; box-shadow: none; }
[data-card="outlined"] .card:hover { background: oklch(from var(--surface) l c h / 0.4); }
[data-card="minimal"] .card { background: transparent; border: 0; border-radius: 0; padding: 22px 4px; box-shadow: none; border-bottom: 1px solid var(--border); }
[data-card="minimal"] .card:hover { transform: none; background: transparent; }

.card-sig {
  font-family: var(--font-mono); font-size: 0.74rem;
  color: var(--muted); margin-bottom: 8px;
  display: flex; gap: 10px; align-items: center;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.card-sig .kw { color: var(--accent); }
.card-sig .ann { color: var(--accent-2); }
.card-sig .nm { color: var(--text); }
.card-title {
  font-family: var(--font-display);
  font-size: 1.35rem; font-weight: 600;
  letter-spacing: -0.015em;
  line-height: 1.22;
  margin: 0 0 8px;
  text-wrap: balance;
}
.card-excerpt {
  color: var(--text-2);
  font-size: 0.96em; line-height: 1.55;
  margin: 0 0 14px;
  text-wrap: pretty;
}
.card-meta {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--font-mono); font-size: 0.76rem; color: var(--muted);
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
}
.card-meta .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--muted); }
.card-tags { display: flex; gap: 6px; flex-wrap: wrap; margin: 8px 0 0; }

/* type badges */
.type-badge {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 8px; height: 22px;
  border-radius: 6px;
  font-family: var(--font-mono); font-size: 0.7rem; font-weight: 600;
  letter-spacing: 0.04em; text-transform: uppercase;
  background: var(--surface-2);
  color: var(--text-2);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.type-badge[data-t="blog"] { color: var(--accent); border-color: oklch(from var(--accent) l c h / 0.4); }
.type-badge[data-t="snippet"] { color: var(--accent-2); border-color: oklch(from var(--accent-2) l c h / 0.4); }
.type-badge[data-t="macro"] { color: oklch(0.80 0.13 130); border-color: oklch(0.80 0.13 130 / 0.4); }
.type-badge[data-t="program"] { color: oklch(0.78 0.14 290); border-color: oklch(0.78 0.14 290 / 0.4); }
.type-badge[data-t="writing"] { color: oklch(0.82 0.10 30); border-color: oklch(0.82 0.10 30 / 0.4); }
.type-badge[data-t="review"] { color: oklch(0.80 0.13 330); border-color: oklch(0.80 0.13 330 / 0.4); }
.type-badge[data-t="links"] { color: oklch(0.78 0.10 180); border-color: oklch(0.78 0.10 180 / 0.4); }
.type-badge[data-t="note"] { color: var(--muted); }
[data-dark="false"] .type-badge[data-t="blog"] { color: oklch(0.50 0.16 60); }
[data-dark="false"] .type-badge[data-t="snippet"] { color: oklch(0.45 0.15 230); }
[data-dark="false"] .type-badge[data-t="macro"] { color: oklch(0.45 0.14 145); }
[data-dark="false"] .type-badge[data-t="program"] { color: oklch(0.45 0.18 290); }
[data-dark="false"] .type-badge[data-t="writing"] { color: oklch(0.45 0.14 30); }
[data-dark="false"] .type-badge[data-t="review"] { color: oklch(0.48 0.15 330); }
[data-dark="false"] .type-badge[data-t="links"] { color: oklch(0.45 0.12 195); }

/* placeholder image */
.placeholder {
  position: relative;
  background:
    repeating-linear-gradient(
      45deg,
      oklch(from var(--surface-2) l c h) 0,
      oklch(from var(--surface-2) l c h) 8px,
      oklch(from var(--surface-3) l c h) 8px,
      oklch(from var(--surface-3) l c h) 16px
    );
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  display: grid; place-items: center;
  color: var(--muted); font-family: var(--font-mono); font-size: 0.72rem;
  letter-spacing: 0.06em; text-transform: uppercase;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
.placeholder span {
  background: var(--surface);
  padding: 4px 10px; border-radius: 4px;
  border: 1px solid var(--border);
}

/* ====== feed layouts ====== */
.feed {
  display: flex; flex-direction: column;
  gap: var(--gap);
}
.feed-header {
  display: flex; align-items: baseline; justify-content: space-between;
  margin-bottom: 18px;
}
.feed-header h2 .accent { color: var(--accent); }
.feed-tabs {
  display: inline-flex; gap: 2px;
  background: var(--surface); padding: 4px;
  border-radius: 10px; border: 1px solid var(--border);
}
.feed-tabs button {
  padding: 6px 12px; border-radius: 7px;
  background: transparent; border: 0;
  color: var(--text-2); font-size: 0.86em; font-weight: 500;
  font-family: var(--font-mono);
}
.feed-tabs button.active {
  background: var(--surface-2); color: var(--text);
}

/* bento variant */
.bento {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  grid-auto-rows: 120px;
  gap: var(--gap);
}
.bento .card { padding: var(--pad-sm); }
.bento .card-title { font-size: 1.05rem; margin-bottom: 6px; }
.bento .card-excerpt { font-size: 0.88em; -webkit-line-clamp: 2; display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
.bento .b-hero { grid-column: span 4; grid-row: span 3; padding: var(--pad); }
.bento .b-hero .card-title { font-size: 1.7rem; }
.bento .b-hero .card-excerpt { font-size: 1em; -webkit-line-clamp: 4; }
.bento .b-wide { grid-column: span 4; grid-row: span 2; }
.bento .b-tall { grid-column: span 2; grid-row: span 3; }
.bento .b-mid { grid-column: span 2; grid-row: span 2; }
.bento .b-sm { grid-column: span 2; grid-row: span 2; }
@media (max-width: 1100px) {
  .bento { grid-template-columns: repeat(4, 1fr); }
  .bento .b-hero { grid-column: span 4; }
  .bento .b-wide { grid-column: span 4; }
}
@media (max-width: 720px) {
  .bento {
    grid-template-columns: 1fr;
    /* Mobile: rows size to content, not the fixed 120px grid. Without
       this override, a long-title b-hero collapsed to span 1 still
       gets clipped to 120px. `auto` lets the card grow to fit. */
    grid-auto-rows: auto;
  }
  .bento .card { grid-column: span 1 !important; grid-row: span 1 !important; }
  /* Drop the bento line-clamps on mobile — cards have full vertical
     room now, so showing the whole excerpt is the better default. */
  .bento .card-title,
  .bento .b-hero .card-title {
    /* Tighter mobile sizing: hero title falls from 1.7rem to 1.25rem.
       Lets the title breathe without forcing a 4-line wrap. */
    font-size: 1.25rem;
    overflow-wrap: anywhere;
    text-wrap: pretty;
  }
  .bento .card-excerpt,
  .bento .b-hero .card-excerpt {
    -webkit-line-clamp: unset;
    display: block;
    overflow: visible;
    font-size: 0.92em;
  }
}

/* river: featured + grid */
.river-hero {
  display: grid; grid-template-columns: 1.4fr 1fr;
  gap: 0;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border);
  overflow: hidden;
  margin-bottom: var(--gap);
  min-height: 360px;
}
.river-hero .hero-art {
  background:
    radial-gradient(60% 80% at 80% 20%, oklch(from var(--accent) l c h / 0.35), transparent 60%),
    radial-gradient(60% 80% at 20% 80%, oklch(from var(--accent-2) l c h / 0.30), transparent 60%),
    var(--surface-2);
  position: relative; overflow: hidden;
  min-height: 240px;
  display: grid; place-items: end stretch;
  padding: 28px;
  font-family: var(--font-mono);
}
.hero-art .code-line {
  font-size: 0.86em; line-height: 2;
  color: var(--muted);
  position: relative; z-index: 1;
}
.hero-art .code-line .ln { color: var(--muted); opacity: 0.5; display: inline-block; width: 26px; }
.hero-art .code-line .kw { color: var(--accent); }
.hero-art .code-line .str { color: oklch(0.82 0.10 150); }
.hero-art .code-line .com { color: var(--muted); font-style: italic; }
.river-hero .hero-body { padding: 32px; display: flex; flex-direction: column; gap: 14px; justify-content: center; }
.river-hero .card-title { font-size: clamp(1.8rem, 2.6vw, 2.2rem); }
.river-hero .card-excerpt { font-size: 1.04em; }
@media (max-width: 880px) {
  .river-hero { grid-template-columns: 1fr; }
}

.river-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--gap);
}
@media (max-width: 720px) {
  .river-grid { grid-template-columns: 1fr; }
}

/* ====== sidebar ====== */
.side {
  display: flex; flex-direction: column; gap: var(--gap);
  position: sticky; top: 90px;
}
.side-block {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--pad);
}
.side-block h4 {
  font-family: var(--font-mono); font-size: 0.78rem;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
  margin-bottom: 14px;
}
.side-block ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.side-block li { font-size: 0.95em; line-height: 1.4; }
.side-block li a { color: var(--text); display: block; transition: color .14s; }
.side-block li a:hover { color: var(--accent); }
.side-block li small {
  font-family: var(--font-mono); font-size: 0.74rem; color: var(--muted);
  display: block; margin-top: 2px;
}

.nav-tree { font-family: var(--font-mono); font-size: 0.85em; }
.nav-tree .branch { padding: 4px 0; color: var(--text-2); display: flex; align-items: center; gap: 8px; cursor: default; }
.nav-tree .branch:hover { color: var(--text); }
.nav-tree .branch .glyph { color: var(--muted); width: 14px; display: inline-block; text-align: center; }
.nav-tree .sub { padding-left: 20px; display: flex; flex-direction: column; gap: 0; }
.nav-tree .count { margin-left: auto; color: var(--muted); font-size: 0.86em; }

/* ====== buttons ====== */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 14px;
  border-radius: 10px; border: 1px solid var(--border);
  background: var(--surface-2); color: var(--text);
  font-weight: 500; font-size: 0.92em;
  transition: background .14s, border-color .14s, transform .1s;
}
.btn:hover { border-color: var(--border-strong); background: var(--surface-3); }
.btn:active { transform: translateY(1px); }
.btn.primary { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.btn.primary:hover { filter: brightness(1.05); }
.btn.ghost { background: transparent; }

/* ====== post detail ====== */
.post-hero {
  margin-bottom: 28px;
}
.post-hero .post-sig {
  font-family: var(--font-mono); font-size: 0.82rem; color: var(--muted);
  margin-bottom: 12px;
}
.post-hero .post-sig .kw { color: var(--accent); }
.post-hero .post-sig .nm { color: var(--text); }
.post-hero .post-sig .ann { color: var(--accent-2); }
.post-hero h1 {
  font-size: clamp(2.2rem, 4vw, 3.4rem); line-height: 1.05;
  letter-spacing: -0.02em;
  text-wrap: balance;
  margin-bottom: 16px;
}
.post-hero .post-meta {
  display: flex; align-items: center; gap: 16px;
  font-family: var(--font-mono); font-size: 0.84rem; color: var(--muted);
  flex-wrap: wrap;
}
.post-cover {
  margin: 24px 0 36px;
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 21 / 9;
}
.post-body {
  font-size: 1.06em;
  line-height: 1.72;
  color: var(--text);
  max-width: 68ch;
}
.post-body h2 { margin: 40px 0 14px; font-size: 1.7rem; }
.post-body h3 { margin: 28px 0 10px; font-size: 1.25rem; }
.post-body p { margin: 0 0 16px; }
.post-body ul, .post-body ol { padding-left: 22px; margin: 0 0 16px; }
.post-body li { margin: 6px 0; }
.post-body blockquote {
  margin: 22px 0;
  padding: 8px 18px;
  border-left: 3px solid var(--accent);
  color: var(--text-2);
  font-family: var(--font-serif); font-style: italic;
  font-size: 1.08em;
}
.post-body a { color: var(--accent); border-bottom: 1px dashed oklch(from var(--accent) l c h / 0.5); }
.post-body a:hover { border-bottom-style: solid; }
.post-body code { font-size: 0.92em; background: var(--surface-2); padding: 2px 6px; border-radius: 4px; color: var(--accent); border: 1px solid var(--border); }
.post-body strong { color: var(--text); }

/* code block */
.codeblock {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin: 24px 0;
  overflow: hidden;
  font-family: var(--font-mono);
}
.codeblock-hd {
  display: flex; align-items: center; justify-content: space-between;
  padding: 8px 12px 8px 16px;
  background: var(--surface-2); border-bottom: 1px solid var(--border);
  font-size: 0.76rem; color: var(--muted);
  letter-spacing: 0.04em;
}
.codeblock-hd .lang { color: var(--accent); font-weight: 600; }
.codeblock-hd button {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 10px; border-radius: 6px;
  background: transparent; border: 1px solid var(--border);
  color: var(--text-2); font-size: 0.84em;
  font-family: var(--font-mono);
}
.codeblock-hd button:hover { background: var(--surface-3); color: var(--text); }
.codeblock-hd button.copied { color: var(--ok); border-color: oklch(from var(--ok) l c h / 0.4); }
.codeblock pre {
  margin: 0; padding: 18px 20px;
  font-size: 0.88em; line-height: 1.6;
  overflow-x: auto;
}
.codeblock .tok-kw { color: oklch(0.80 0.14 290); }
.codeblock .tok-str { color: oklch(0.82 0.12 150); }
.codeblock .tok-num { color: oklch(0.82 0.13 60); }
.codeblock .tok-com { color: var(--muted); font-style: italic; }
.codeblock .tok-fn { color: var(--accent-2); }
.codeblock .tok-cls { color: var(--accent); }

[data-dark="false"] .codeblock .tok-kw { color: oklch(0.42 0.16 290); }
[data-dark="false"] .codeblock .tok-str { color: oklch(0.42 0.16 150); }
[data-dark="false"] .codeblock .tok-num { color: oklch(0.50 0.16 60); }
[data-dark="false"] .codeblock .tok-fn { color: oklch(0.45 0.14 230); }
[data-dark="false"] .codeblock .tok-cls { color: oklch(0.50 0.16 60); }

/* ===== TOC ===== */
.toc {
  position: sticky; top: 90px;
  padding: 18px;
  border-left: 1px solid var(--border);
  font-family: var(--font-mono);
}
.toc h4 {
  font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--muted); font-weight: 600;
  margin: 0 0 12px;
}
.toc ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.toc li { font-size: 0.84rem; line-height: 1.4; }
.toc li a { color: var(--text-2); padding: 4px 0; display: block; transition: color .14s; }
.toc li a:hover, .toc li a.active { color: var(--accent); }
.toc li.h3 { padding-left: 14px; }
.toc-progress {
  height: 2px; background: var(--surface-2); margin-bottom: 14px; overflow: hidden;
  border-radius: 2px;
}
.toc-progress i { display: block; height: 100%; background: var(--accent); width: 25%; transition: width .15s; }

/* ===== reactions ===== */
.reactions {
  margin: 36px 0;
  padding: 18px 20px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: flex; flex-wrap: wrap; gap: 10px; align-items: center;
}
.reactions-label {
  font-family: var(--font-mono); font-size: 0.78rem; color: var(--muted);
  margin-right: 6px;
}
.react-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 12px; border-radius: 999px;
  background: var(--surface-2); border: 1px solid var(--border);
  color: var(--text-2); font-family: var(--font-mono); font-size: 0.82em;
  transition: background .14s, color .14s, border-color .14s, transform .1s;
}
.react-btn:hover { background: var(--surface-3); color: var(--text); }
.react-btn[data-on="1"] {
  background: oklch(from var(--accent) l c h / 0.18);
  color: var(--accent);
  border-color: oklch(from var(--accent) l c h / 0.4);
}
.react-btn .ann { color: var(--accent-2); }
.react-btn[data-on="1"] .ann { color: var(--accent); }
.react-btn .count { color: var(--muted); font-weight: 600; }
.react-btn[data-on="1"] .count { color: var(--accent); }
.react-btn:active { transform: scale(0.96); }

/* ===== program/tool ===== */
.tool-frame {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--pad);
  margin: 24px 0;
}
.tool-hd {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 16px; padding-bottom: 14px;
  border-bottom: 1px dashed var(--border);
}
.tool-hd h3 { font-size: 1.1rem; }
.tool-hd .tool-meta { font-family: var(--font-mono); font-size: 0.78rem; color: var(--muted); }

.tool-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 18px;
}
@media (max-width: 720px) { .tool-grid { grid-template-columns: 1fr; } }
.tool-grid label { font-family: var(--font-mono); font-size: 0.78rem; color: var(--muted); display: block; margin-bottom: 6px; }
.tool-grid textarea {
  width: 100%; min-height: 200px; resize: vertical;
  background: var(--bg);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  color: var(--text); font-family: var(--font-mono); font-size: 0.86em;
  padding: 12px 14px; line-height: 1.6;
}
.tool-grid textarea:focus { outline: none; border-color: var(--accent); }
.tool-out {
  background: var(--bg);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 16px 18px;
  display: flex; flex-direction: column; gap: 12px;
}
.tool-stat { display: flex; justify-content: space-between; align-items: baseline; padding: 6px 0; border-bottom: 1px dashed var(--border); }
.tool-stat:last-child { border-bottom: 0; }
.tool-stat label { margin: 0; }
.tool-stat b { font-family: var(--font-display); font-size: 1.4rem; font-weight: 600; color: var(--text); font-variant-numeric: tabular-nums; }
.tool-stat b.accent { color: var(--accent); }

.scatter {
  width: 100%; height: 220px;
  background: var(--bg);
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  position: relative;
  margin-top: 12px;
}

/* ===== rating widget ===== */
.rating {
  display: flex; align-items: center; gap: 14px;
  margin: 12px 0 24px;
}
.rating-stars { display: inline-flex; gap: 2px; }
.rating-stars i {
  width: 22px; height: 22px;
  background: var(--surface-2);
  border-radius: 4px;
}
.rating-stars i.on {
  background: var(--accent);
}
.rating-stars i.half {
  background: linear-gradient(90deg, var(--accent) 50%, var(--surface-2) 50%);
}
.rating-num { font-family: var(--font-display); font-size: 1.6rem; font-weight: 600; }
.rating-num small { color: var(--muted); font-size: 0.6em; font-family: var(--font-mono); font-weight: 400; }
.verdict {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 12px; border-radius: 999px;
  background: oklch(from var(--ok) l c h / 0.15);
  color: var(--ok);
  font-family: var(--font-mono); font-size: 0.82em; font-weight: 600;
}

.pros-cons {
  display: grid; grid-template-columns: 1fr 1fr; gap: 18px;
  margin: 28px 0;
}
@media (max-width: 720px) { .pros-cons { grid-template-columns: 1fr; } }
.pros, .cons {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--pad);
}
.pros h4 { color: var(--ok); }
.cons h4 { color: var(--danger); }
.pros h4, .cons h4 {
  font-family: var(--font-mono); font-size: 0.8rem; letter-spacing: 0.08em;
  text-transform: uppercase; margin: 0 0 12px; font-weight: 600;
}
.pros ul, .cons ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 8px; }
.pros li::before { content: "+ "; color: var(--ok); font-family: var(--font-mono); }
.cons li::before { content: "− "; color: var(--danger); font-family: var(--font-mono); }

/* ===== links roundup ===== */
.linklist { display: flex; flex-direction: column; gap: 14px; }
.linkrow {
  display: flex; gap: 16px; padding: 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  align-items: flex-start;
  transition: border-color .14s, background .14s;
}
.linkrow:hover { border-color: var(--border-strong); background: var(--surface-2); }
.linkrow .num {
  font-family: var(--font-mono); font-size: 1.6rem; font-weight: 700;
  color: var(--accent); width: 40px; flex-shrink: 0;
  line-height: 1;
}
.linkrow h4 { font-size: 1.05rem; margin-bottom: 4px; }
.linkrow .domain { font-family: var(--font-mono); font-size: 0.78rem; color: var(--muted); }
.linkrow p { color: var(--text-2); margin: 6px 0 0; font-size: 0.92em; }

/* ===== search palette ===== */
.search-overlay {
  position: fixed; inset: 0; z-index: 100;
  background: oklch(0 0 0 / 0.55);
  backdrop-filter: blur(6px);
  display: grid; place-items: start center;
  padding-top: 12vh;
  animation: fadeIn .14s ease;
}
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.search-box {
  width: min(640px, calc(100vw - 32px));
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  animation: pop .18s cubic-bezier(.3,1,.5,1);
}
@keyframes pop { from { opacity: 0; transform: translateY(-6px) scale(0.98); } to { opacity: 1; transform: none; } }
.search-input-wrap {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
.search-input-wrap input {
  flex: 1; background: transparent; border: 0; outline: none;
  font-family: var(--font-display); font-size: 1.15rem;
  color: var(--text);
}
.search-input-wrap input::placeholder { color: var(--muted); }
.search-results { max-height: 50vh; overflow-y: auto; padding: 8px; }
.search-result {
  display: flex; gap: 12px; padding: 12px 14px;
  border-radius: 8px;
  cursor: default;
  align-items: center;
}
.search-result.active { background: var(--surface-2); }
.search-result h5 { font-size: 0.98em; margin: 0 0 2px; font-weight: 500; }
.search-result p { font-size: 0.82em; margin: 0; color: var(--muted); font-family: var(--font-mono); }
.search-empty { padding: 28px; text-align: center; color: var(--muted); font-family: var(--font-mono); font-size: 0.86em; }
.search-foot {
  padding: 10px 18px;
  border-top: 1px solid var(--border);
  background: var(--surface-2);
  font-family: var(--font-mono); font-size: 0.78rem; color: var(--muted);
  display: flex; gap: 16px;
}
.search-foot kbd {
  padding: 2px 6px; border-radius: 4px;
  background: var(--bg); border: 1px solid var(--border);
}

/* ===== archive ===== */
.archive-filters {
  display: flex; gap: 8px; flex-wrap: wrap;
  margin-bottom: 24px;
}
.chip {
  padding: 7px 14px; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--border);
  font-family: var(--font-mono); font-size: 0.82em;
  color: var(--text-2);
  transition: border-color .14s, background .14s;
}
.chip:hover { border-color: var(--border-strong); }
.chip[data-on="1"] {
  background: oklch(from var(--accent) l c h / 0.15);
  color: var(--accent);
  border-color: oklch(from var(--accent) l c h / 0.5);
}
.archive-list {
  border-top: 1px solid var(--border);
}
.archive-row {
  display: grid;
  grid-template-columns: 110px 90px 1fr auto;
  gap: 18px;
  padding: 16px 8px;
  border-bottom: 1px solid var(--border);
  align-items: center;
  transition: background .14s;
}
.archive-row:hover { background: var(--surface-2); }
.archive-row .date { font-family: var(--font-mono); font-size: 0.84em; color: var(--muted); }
.archive-row .title { font-weight: 500; }
.archive-row .read { font-family: var(--font-mono); font-size: 0.78em; color: var(--muted); }
@media (max-width: 720px) {
  .archive-row { grid-template-columns: 80px 1fr; }
  .archive-row .read, .archive-row .type-badge { display: none; }
}

/* ===== about ===== */
.about-hero {
  display: grid; grid-template-columns: 1fr 1fr; gap: 40px;
  align-items: center;
  margin-bottom: 60px;
}
@media (max-width: 880px) {
  .about-hero { grid-template-columns: 1fr; }
}
.about-avatar {
  width: 100%; aspect-ratio: 1; border-radius: 24px;
  background:
    radial-gradient(60% 60% at 30% 30%, oklch(from var(--accent) l c h / 0.6), transparent 70%),
    radial-gradient(70% 70% at 80% 70%, oklch(from var(--accent-2) l c h / 0.5), transparent 70%),
    var(--surface-2);
  display: grid; place-items: center;
  font-family: var(--font-display); font-size: 7rem; font-weight: 700;
  color: var(--text);
  border: 1px solid var(--border);
  overflow: hidden;
}
.about-blob h1 .accent { color: var(--accent); }
.about-blob p { font-size: 1.1em; line-height: 1.7; color: var(--text-2); margin: 18px 0; }
.about-methods {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--pad);
  font-family: var(--font-mono); font-size: 0.92em;
  margin: 24px 0;
  white-space: pre;
  overflow-x: auto;
  line-height: 1.8;
  color: var(--text-2);
}
.about-methods .kw { color: var(--accent); }
.about-methods .cls { color: var(--accent-2); }
.about-methods .com { color: var(--muted); font-style: italic; }

.timeline {
  position: relative; padding-left: 24px;
  margin: 30px 0;
}
.timeline::before {
  content: ""; position: absolute; left: 4px; top: 6px; bottom: 6px;
  width: 1px; background: var(--border);
}
.timeline-item { position: relative; padding: 8px 0 20px; }
.timeline-item::before {
  content: ""; position: absolute; left: -23px; top: 14px;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 0 4px var(--bg);
}
.timeline-year { font-family: var(--font-mono); font-size: 0.78rem; color: var(--accent); letter-spacing: 0.05em; }
.timeline-item h4 { font-size: 1.05rem; margin: 2px 0 4px; }
.timeline-item p { color: var(--text-2); font-size: 0.94em; margin: 0; }

/* ===== 404 ===== */
.notfound {
  display: grid; place-items: center;
  min-height: 70vh; text-align: center;
  padding: var(--pad);
  font-family: var(--font-mono);
}
.notfound-code {
  font-family: var(--font-mono);
  font-size: clamp(7rem, 16vw, 13rem);
  font-weight: 700;
  line-height: 1; letter-spacing: -0.04em;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  -webkit-background-clip: text; background-clip: text; color: transparent;
  margin-bottom: 8px;
}
.notfound h1 { font-family: var(--font-display); font-size: 2.2rem; margin-bottom: 12px; }
.notfound .stack {
  margin-top: 28px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 24px;
  text-align: left;
  font-family: var(--font-mono); font-size: 0.86em;
  color: var(--muted); line-height: 1.7;
  max-width: 580px;
}
.notfound .stack .err { color: var(--danger); }
.notfound .stack .at { color: var(--text-2); }
.notfound .stack .file { color: var(--accent); }

/* ===== post media (rendered cover, gallery, video) ===== */
.post-video { margin: 0 0 28px; }
.post-gallery { margin: 32px 0; }
.post-gallery-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}
.post-gallery figure { margin: 0; }
.post-gallery img {
  width: 100%; aspect-ratio: 4/3; object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  display: block;
}
.post-gallery figcaption {
  margin-top: 6px;
  font-family: var(--font-mono); font-size: 0.78rem; color: var(--muted);
}

/* ===== post media (rendered cover, gallery, video) ===== */
.post-video { margin: 0 0 28px; }
.post-gallery { margin: 32px 0; }
.post-gallery-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 12px;
}
.post-gallery figure { margin: 0; }
.post-gallery img {
  width: 100%; aspect-ratio: 4/3; object-fit: cover;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  display: block;
}
.post-gallery figcaption {
  margin-top: 6px;
  font-family: var(--font-mono); font-size: 0.78rem; color: var(--muted);
}

/* ===== creative writing ===== */
.writing-body {
  font-family: var(--font-serif);
  font-size: 1.16em; line-height: 1.85;
  color: var(--text);
  max-width: 64ch;
}
.writing-body h2 { font-family: var(--font-serif); font-style: italic; font-weight: 500; }
.writing-body p:first-of-type::first-letter {
  font-size: 4em; line-height: 0.9; float: left;
  padding-right: 12px; padding-top: 6px;
  color: var(--accent); font-weight: 700;
  font-family: var(--font-display);
}
.writing-body .ornament {
  display: flex; align-items: center; justify-content: center; gap: 18px;
  margin: 32px 0;
  font-family: var(--font-mono); color: var(--muted);
}
.writing-body .ornament i { height: 1px; flex: 1; background: var(--border); display: block; }

/* utility */
.divider {
  height: 1px; background: var(--border); margin: 32px 0;
}
.muted { color: var(--muted); }
.mono-small { font-family: var(--font-mono); font-size: 0.78rem; color: var(--muted); }
.kbd {
  font-family: var(--font-mono); font-size: 0.78em;
  padding: 2px 6px; border-radius: 4px;
  background: var(--surface-2); color: var(--text-2);
  border: 1px solid var(--border);
}

/* ====== Mobile-only "permanent" advice card ==========================
   Sits between the feed and the footer on mobile. Visually matches
   post-card styling so it reads as the natural last entry. Hidden on
   desktop — the slim footer advice line already handles desktop.

   Activation rule (mobile EVERYWHERE): also include
   `(hover: none) and (pointer: coarse)` so the layout fires for any
   touch-only device (iPad-in-Safari, Android tablet) regardless of
   viewport width — that's the "trigger on iOS/Android" behaviour
   without needing JS-level OS sniffing. */
.mobile-advice-card { display: none; }
@media (max-width: 720px) {
  .mobile-advice-card {
    display: block;
    /* Tightened from the original 24/16/32 — the user's screenshot
       showed too much air above and below this card relative to the
       feed cards. Now it sits 12px from neighbours. */
    margin: 12px 16px;
    padding: 18px 18px 20px;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    border-left: 3px solid var(--accent);
  }
  .mobile-advice-card-label {
    font-family: var(--font-mono);
    font-size: 0.74rem;
    font-weight: 600;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-bottom: 8px;
  }
  .mobile-advice-card-label .sigil {
    color: var(--muted);
    margin-right: 4px;
    font-weight: 500;
  }
  .mobile-advice-card-text {
    margin: 0;
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 1rem;
    line-height: 1.5;
    color: var(--text);
    text-wrap: pretty;
  }
  .djc-footer-advice { display: none; }
}

/* "No cards in this category" placeholder — injected by the chip filter
   JS into the feed container when a filter matches zero cards. */
.mobile-filter-empty {
  margin: 24px 16px;
  padding: 18px;
  border: 1px dashed var(--border);
  border-radius: var(--radius);
  color: var(--muted);
  font-family: var(--font-mono);
  font-size: 0.86rem;
  text-align: center;
}
.mobile-filter-empty p { margin: 0; }

/* ====== Footer: mobile overflow fix =================================
   The desktop footer is a 3-column grid with a min-width:260px brand
   column and a <pre> EOF block with overflow-x:auto. On mobile both
   conspire to produce a horizontal scrollbar. Force wrapping. */
@media (max-width: 720px) {
  .djc-footer {
    padding: 32px 16px 40px;
    margin-top: 24px;
  }
  .djc-footer-inner {
    gap: 24px;
  }
  .djc-footer-brand {
    min-width: 0;
    width: 100%;
  }
  .djc-footer-cols {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px 12px;
    width: 100%;
  }
  .djc-footer-cols > div {
    min-width: 0;
  }
  .djc-footer-cols > div > a {
    overflow-wrap: anywhere;
  }
  /* The <pre class="djc-footer-eof"> is the actual scrollbar source.
     Allow it to wrap on word/character boundaries on narrow screens. */
  .djc-footer-eof {
    overflow-x: visible;
    white-space: pre-wrap;
    word-break: break-word;
  }
}
   Top-to-bottom: brand row (with dark toggle), role line, then a
   "rolled-up" identity row with the avatar + name + snarky feeling.
   Hidden above 720px. */
.mobile-profile-card { display: none; }
@media (max-width: 720px) {
  .mobile-profile-card {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 14px 16px 14px;
    background: var(--surface);
    border-bottom: 1px solid var(--border);
    /* Scrolls away with the page so the chip nav alone stays pinned at
       the top as the user reads down. The brand stays visible at the
       top of the first viewport; access to categories never leaves. */
    position: relative;
    z-index: 40;
  }
  .mobile-profile-card-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
  }
  .mobile-profile-brand {
    font-size: 1.18rem;
    min-width: 0;
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .mobile-profile-brand .brand-glyph { width: 30px; height: 30px; }
  .mobile-profile-brand .brand-ext { display: inline; }
  .mobile-profile-role {
    font-family: var(--font-mono);
    font-size: 0.78rem;
    color: var(--accent);
    line-height: 1.4;
  }
  /* "Rolled-up" identity row. Mini avatar on the left, name + feeling
     stack on the right. Avatar is smaller than the desktop sidebar
     version since we're inside a tight header band. */
  .mobile-profile-identity {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    margin-top: 4px;
    padding-top: 10px;
    border-top: 1px dashed var(--border);
  }
  .mobile-profile-avatar {
    /* Override .profile-avatar's default 84px box. The status badge
       (::after) is hidden on mobile to keep the card light. */
    width: 52px;
    height: 52px;
    flex-shrink: 0;
    margin-bottom: 0;
    font-size: 18px;
  }
  .mobile-profile-avatar::after { display: none; }
  .mobile-profile-identity-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
  }
  .mobile-profile-name {
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--text);
    line-height: 1.2;
  }
  .mobile-profile-feeling {
    margin: 0;
    font-family: var(--font-serif);
    font-style: italic;
    font-size: 0.86rem;
    color: var(--text-2);
    line-height: 1.4;
  }
  /* Hide the desktop topbar entirely on mobile. */
  .topbar { display: none; }
  /* Hide the desktop sidebar profile + content-tree block on mobile.
     The sidebar uses <aside class="side">, not .sidebar. Profile +
     content tree are surfaced elsewhere on mobile (profile card / chip
     nav), so they'd just take up scroll space here. The "recently
     committed" block stays visible — that's still useful. */
  aside.side > .profile,
  aside.side > .side-block--tree { display: none; }
  /* iOS safe-area padding — pushes the topmost content below the
     Dynamic Island / status bar on real devices. The mobile-profile-card
     gets the inset for first-paint; the chip nav gets it too since it
     becomes the topmost pinned element once the profile card scrolls
     out of view. Falls back to 0 in browsers that don't expose env();
     the preview simulator gets an extra hardcoded boost via the
     mobile-preview wrapper script. */
  .mobile-profile-card {
    padding-top: max(14px, calc(env(safe-area-inset-top, 0) + 14px));
  }
  .mobile-cat-nav {
    padding-top: max(8px, calc(env(safe-area-inset-top, 0) + 8px));
  }
  .rail {
    padding-top: max(14px, env(safe-area-inset-top, 0));
  }
}

/* ====== Mobile category nav — horizontal scrolling chips ============
   A second nav strip that lives directly under the topbar on phones.
   Each chip routes to a content type's archive. Hidden on desktop —
   the topbar <nav> already handles cross-section navigation there.

   Scroll behavior: native overflow-x: auto with scroll-snap + iOS
   momentum scroll. Scrollbar hidden cross-browser. The active chip
   gets the accent fill; everything else is a subtle outline. */
.mobile-cat-nav { display: none; }
@media (max-width: 720px) {
  .mobile-cat-nav {
    display: flex;
    gap: 8px;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
    padding: 8px 14px;
    border-bottom: 1px solid var(--border);
    /* Solid background so content scrolling underneath doesn't bleed
       through. Slightly more opaque than `var(--surface)` to make sure
       the code-pattern wallpaper doesn't show through when the chip
       strip is stuck over content. */
    background: var(--surface);
    /* Persistent navigation: stays pinned at the top of the viewport as
       the user scrolls down. With the profile card above set to
       `position: relative`, the chip strip slides up under it and then
       sticks at top:0. */
    position: sticky;
    top: 0;
    z-index: 50;
    margin-bottom: 0;
    scrollbar-width: none;
  }
  /* Kill the page-anim top padding on mobile so the chip strip sits flush
     against the first content block — the wasted space we saw under the
     chips was the .page's default top breathing room. */
  .page-anim,
  main#site-content > .page,
  main#site-content > .page-anim { padding-top: 14px; }
  .mobile-cat-nav::-webkit-scrollbar { display: none; }
  .mobile-cat-chip {
    flex: 0 0 auto;
    padding: 7px 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    font-family: var(--font-mono);
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--text-2);
    text-decoration: none;
    white-space: nowrap;
    background: transparent;
    scroll-snap-align: start;
    transition: background .14s, color .14s, border-color .14s;
  }
  .mobile-cat-chip:hover,
  .mobile-cat-chip:focus-visible {
    color: var(--text);
    border-color: var(--border-strong);
  }
  .mobile-cat-chip.is-active {
    color: var(--accent-ink);
    background: var(--accent);
    border-color: var(--accent);
  }
}

/* ====== Rail: mobile reflow ==========================================
   Switches the rail from "spread three items top/middle/bottom" to
   "stack top, push DESK label to the bottom" — and reveals the new
   search button, divider, and FOLLOW ME label. */
@media (max-width: 720px) {
  .app[data-rail="true"] {
    /* Narrow the rail slightly so chip padding feels right next to it. */
    grid-template-columns: 52px minmax(0, 1fr);
  }
  .rail {
    justify-content: flex-start;
    gap: 12px;
    padding: 14px 0 18px;
  }
  /* Reveal mobile-only elements. */
  .rail-search       { display: inline-flex; }
  .rail-divider      { display: block; }
  .rail-brand--follow { display: block; }
  /* Hide the decorative tick marks on mobile — visual clutter in a tight
     column. Keep the markup for screen readers / desktop. */
  .rail-marks { display: none; }
  /* Reorder via flex order. Source markup order remains the desktop
     order so a11y / no-CSS fallback still reads sensibly. */
  .rail-search        { order: 1; }
  .rail-divider       { order: 2; }
  .rail-socials       { order: 3; }
  .rail-brand--follow { order: 4; }
  .rail-brand:not(.rail-brand--follow) {
    order: 5;
    margin-top: auto; /* push the DESK label to the bottom of the column */
  }
  /* Subtler "FOLLOW ME:" sigil — muted, smaller letter-spacing than the
     main DESK label so it reads as a section header, not a brand.
     Bumped up on mobile so the vertical text is actually readable. */
  .rail-brand:not(.rail-brand--follow) {
    font-size: 12px;
    letter-spacing: 0.22em;
    padding: 12px 0;
  }
  .rail-brand--follow {
    font-size: 11px;
    letter-spacing: 0.18em;
    color: var(--muted);
    padding: 6px 0;
  }
}

/* slide-in transitions for page changes */
.page-anim { animation: pageIn .26s cubic-bezier(.2,.7,.3,1); }
@keyframes pageIn {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}


/* ====== WordPress-specific additions (footer columns, comments, pagination) ====== */

.djc-footer {
  border-top: 1px solid var(--border);
  margin-top: 80px;
  padding: 40px var(--pad);
  background: var(--surface);
}
.djc-footer-inner {
  max-width: 1320px; margin: 0 auto;
  display: flex; align-items: flex-start; gap: 40px; flex-wrap: wrap;
}
.djc-footer-brand { min-width: 260px; }
.djc-footer-name {
  font-family: var(--font-display); font-weight: 700; font-size: 1.1rem;
  margin-bottom: 8px;
}
.djc-footer-ext { color: var(--muted); font-family: var(--font-mono); font-size: 0.78em; }
.djc-footer-stub { margin-bottom: 14px; }
.djc-footer-meta { color: var(--muted); margin-bottom: 14px; }
.djc-footer-eof { margin: 0; color: var(--muted); font-size: 0.72rem; overflow-x: auto; }
.djc-footer-cols {
  flex: 1;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 24px;
}
.djc-footer-cols > div > a {
  display: block; padding: 4px 0;
}
.djc-footer-h {
  margin-bottom: 10px; color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.08em; font-weight: 600;
}
.djc-footer-advice {
  max-width: 1320px; margin: 40px auto 0;
  padding-top: 24px;
  border-top: 1px dashed var(--border);
  text-align: center;
  font-family: var(--font-serif); font-style: italic;
  font-size: 1.02em; color: var(--text-2);
  text-wrap: balance;
}
.djc-footer-advice-label {
  display: inline-block;
  font-family: var(--font-mono); font-style: normal;
  font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--accent); margin-right: 10px;
}

/* Pagination */
.pagination, .nav-links {
  display: flex; gap: 8px; flex-wrap: wrap; justify-content: center;
  font-family: var(--font-mono); font-size: 0.86rem;
}
.pagination .page-numbers, .nav-links .page-numbers, .nav-links a, .nav-links .current {
  padding: 8px 14px; border-radius: var(--radius-sm);
  background: var(--surface); border: 1px solid var(--border);
  color: var(--text-2); text-decoration: none;
}
.pagination .page-numbers.current, .nav-links .current {
  background: var(--accent); color: var(--accent-ink); border-color: transparent;
}
.pagination .page-numbers:hover, .nav-links a:hover {
  border-color: var(--border-strong); color: var(--text);
}

/* Block-editor content compat for the .post-body */
.post-body img, .writing-body img {
  max-width: 100%; height: auto;
  border-radius: var(--radius-sm); border: 1px solid var(--border);
  margin: 18px 0;
}
.post-body figure { margin: 24px 0; }
.post-body figcaption {
  margin-top: 6px;
  font-family: var(--font-mono); font-size: 0.78rem; color: var(--muted);
}
.post-body pre {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 18px 20px; overflow-x: auto;
  font-family: var(--font-mono); font-size: 0.88em; line-height: 1.6;
}
.post-body table {
  width: 100%; border-collapse: collapse; margin: 22px 0;
  font-family: var(--font-mono); font-size: 0.92em;
}
.post-body th, .post-body td {
  padding: 10px 12px; border-bottom: 1px solid var(--border); text-align: left;
}
.post-body th { color: var(--muted); font-weight: 600; }

/* TOC wrapper sticky position */
.toc-wrap { position: sticky; top: 90px; align-self: start; }

/* Dark/sun icon toggling */
[data-djc-toggle-dark] .icon-sun { display: none; }
[data-djc-toggle-dark] .icon-moon { display: block; }
[data-dark="true"] [data-djc-toggle-dark] .icon-sun { display: block; }
[data-dark="true"] [data-djc-toggle-dark] .icon-moon { display: none; }

/* Body shell: when a rail is present, .app handles the grid. */
.djc-main-col { min-width: 0; }
.djc-body { margin: 0; }


/* ====== Online-status badge variants (data-online on .profile-avatar) ====== */
.profile-avatar[data-online]::after { content: attr(data-online); }
.profile-avatar[data-online="online"]::after  { color: var(--ok); }
.profile-avatar[data-online="offline"]::after { color: var(--muted); }
.profile-avatar[data-online="away"]::after    { color: var(--accent); }
.profile-avatar[data-online="hidden"]::after  { display: none; }

/* ====== Featured-image: GIF preservation ====== */
.post-cover[data-gif="1"] img { object-fit: cover; image-rendering: auto; }


/* ====== HTML hidden attribute compat ======
   .search-overlay sets display:grid, which would beat the UA's default
   [hidden] { display: none }. Make the attribute authoritative. */
[hidden] { display: none !important; }


/* ====== Custom-uploaded rail icons (PNG/SVG) ======
   When a user uploads their own icon via Customizer, render it square inside
   the rail badge with the same visual weight as the built-in stroke icons. */
.rail-custom-icon {
  width: 18px; height: 18px;
  object-fit: contain;
  display: block;
}

/* ====== Amazon Wish List icon — baked-in dark/light swap ======
   Two pre-painted PNGs, one per theme mode. Hide BOTH by default and
   explicitly reveal the active one via the [data-dark] cascade — that way
   if the cascade fails to apply (e.g. stale cached CSS), the failure mode
   is "icon missing" rather than "two icons stacked on top of each other",
   which is easier to notice and less visually broken.
   Sized to 18px to sit comfortably inside the 36px rail badge alongside
   the stroke-based SVG icons of its siblings. */
.rail-icon img.djc-wishlist {
  width: 18px;
  height: 18px;
  display: none;
}
[data-dark="true"]  .rail-icon img.djc-wishlist-dark  { display: block; }
[data-dark="false"] .rail-icon img.djc-wishlist-light { display: block; }
/* Belt-and-braces: if <html> somehow has no data-dark attr at all (i.e.
   djc_html_data_attrs didn't run), still show the dark variant — matches
   the theme's default mode. */
html:not([data-dark]) .rail-icon img.djc-wishlist-dark { display: block; }


/* ====== Rail hover labels — unfurl pill ======
   Each rail icon has a sibling .rail-label span. When the parent .rail-icon
   is hovered (or keyboard-focused), the label expands from 0 width to its
   natural width, sliding into view from the right edge of the icon. Pure CSS,
   no JS. The label is decorative — the <a> has aria-label, the label has
   aria-hidden, so screen readers hear the platform name once. */
.rail-icon { position: relative; }
.rail-icon .rail-label {
  position: absolute;
  left: calc(100% + 10px);
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex; align-items: center;
  height: 28px;
  padding: 0;
  white-space: nowrap;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--text);
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow-sm);
  max-width: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  transition:
    max-width 0.36s cubic-bezier(0.22, 0.61, 0.36, 1),
    padding 0.36s cubic-bezier(0.22, 0.61, 0.36, 1),
    opacity 0.20s ease-out;
  /* Sits above other rail content. */
  z-index: 60;
}
/* Tiny tick on the left edge so the pill feels anchored to the icon. */
.rail-icon .rail-label::before {
  content: "";
  position: absolute;
  left: -5px;
  top: 50%;
  width: 8px; height: 8px;
  transform: translateY(-50%) rotate(45deg);
  background: var(--surface-2);
  border-left: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.rail-icon:hover .rail-label,
.rail-icon:focus-visible .rail-label {
  max-width: 320px;
  padding: 0 14px;
  opacity: 1;
}

/* Don't show the unfurl on touch devices (no real hover). */
@media (hover: none) {
  .rail-icon .rail-label { display: none; }
}



/* ====== Multi-line wishlist label (no horizontal overflow into page) ======
   The wishlist label renders each word on its own line via hard <br> tags.
   Center-align, give it auto height, narrow the pill so it stays mostly
   inside the rail's footprint at any breakpoint. */
.rail-label--wishlist {
  height: auto;
  min-height: 28px;
  line-height: 1.2;
  text-align: center;
  white-space: normal;
  padding-top: 6px;
  padding-bottom: 6px;
}
.rail-icon:hover .rail-label--wishlist,
.rail-icon:focus-visible .rail-label--wishlist {
  max-width: 130px;
  padding-left: 12px;
  padding-right: 12px;
}


/* ====== Profile: feeling status (side-car next to avatar) ======
   When the admin sets a "Current feeling" in Customizer, the avatar pairs
   with a code-style status block to its right. // Feeling label + the
   typed text in italic serif, quote-wrapped — like a String value in a
   class definition. Hidden in compact/inline profile modes (no room). */
.profile-top {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 14px;
}
.profile-top .profile-avatar { margin-bottom: 0; flex-shrink: 0; }
.profile-feeling {
  flex: 1;
  min-width: 0;
  padding-top: 2px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.profile-feeling-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  font-weight: 600;
}
.profile-feeling-label .sigil {
  color: var(--muted);
  font-weight: 500;
  margin-right: 2px;
}
.profile-feeling-text {
  margin: 0;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 0.92em;
  line-height: 1.4;
  color: var(--text);
  text-wrap: pretty;
  /* Soft accent on the opening/closing quotes via the unicode chars we wrap with */
  position: relative;
}


/* ====== TL;DR sidebar — replaces the auto-TOC ====== */
.toc--hidden { display: none; }
.toc-body {
  color: var(--text-2);
  font-family: var(--font-body);
  font-size: 0.88rem;
  line-height: 1.5;
}
.toc-body p { margin: 0 0 8px; }
.toc-body p:last-child { margin-bottom: 0; }
.toc-body a {
  color: var(--accent);
  border-bottom: 1px dashed oklch(from var(--accent) l c h / 0.5);
}
.toc-body strong { color: var(--text); }
.toc-empty {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--muted);
  line-height: 1.5;
  margin: 0;
  padding: 8px 10px;
  background: oklch(from var(--accent) l c h / 0.08);
  border-left: 2px solid oklch(from var(--accent) l c h / 0.4);
  border-radius: 0 6px 6px 0;
}


/* ====== Single Snippet / Macro — compact layout ====== */
.snippet-page {
  max-width: 880px;
  margin: 0 auto;
}
.snippet-frame {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.snippet-head {
  padding: 22px 24px 18px;
  border-bottom: 1px dashed var(--border);
}
.snippet-head-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}
.snippet-head-text { min-width: 0; flex: 1; }
.snippet-title {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 2.2vw, 1.85rem);
  line-height: 1.15;
  font-weight: 600;
  letter-spacing: -0.015em;
  margin: 4px 0 8px;
  text-wrap: balance;
}
.snippet-byline {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--muted);
}
.snippet-byline strong { color: var(--text-2); font-weight: 600; }
.snippet-byline .dot {
  width: 3px; height: 3px; border-radius: 50%; background: var(--muted);
}

.snippet-lang {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--accent);
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.snippet-lang-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 2px oklch(from var(--accent) l c h / 0.18);
}

.snippet-section {
  padding: 20px 24px;
  border-bottom: 1px dashed var(--border);
}
.snippet-section:last-of-type { border-bottom: 0; }
.snippet-section-label {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 12px;
  display: flex; align-items: center; gap: 6px;
}
.snippet-section-label .sigil { color: var(--muted); font-weight: 500; }

.snippet-purpose-body {
  font-family: var(--font-body);
  font-size: 1.02rem;
  line-height: 1.55;
  color: var(--text);
  text-wrap: pretty;
}
.snippet-purpose-body p { margin: 0 0 10px; }
.snippet-purpose-body p:last-child { margin-bottom: 0; }
.snippet-purpose-body strong { color: var(--text); }
.snippet-purpose-body em { color: var(--text-2); }

/* The .codeblock inside a snippet section gets a tighter top margin */
.snippet-section .codeblock { margin: 0; }

.snippet-explain-body {
  font-size: 0.98em;
  line-height: 1.65;
  max-width: 68ch;
}

.snippet-figure {
  padding: 20px 24px 24px;
}
.snippet-figure-cover {
  margin: 0;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--border);
  aspect-ratio: 16 / 9;
}
.snippet-figure-cover img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}

.snippet-frame .reactions {
  margin: 0;
  border-radius: 0;
  border-left: 0;
  border-right: 0;
  border-bottom: 0;
  border-top: 1px dashed var(--border);
  background: transparent;
}


/* ====== Single Macro — modular block-driven layout ====== */
.macro-page { max-width: 980px; margin: 0 auto; }
.macro-frame {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.macro-head {
  padding: 22px 24px 18px;
  border-bottom: 1px dashed var(--border);
}
.macro-head-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}
.macro-head-text { min-width: 0; flex: 1; }
.macro-title {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  line-height: 1.15;
  font-weight: 600;
  letter-spacing: -0.015em;
  margin: 4px 0 8px;
  text-wrap: balance;
}
.macro-byline {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--muted);
}
.macro-byline strong { color: var(--text-2); font-weight: 600; }
.macro-byline .dot {
  width: 3px; height: 3px; border-radius: 50%; background: var(--muted);
}
.macro-lang {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 600;
  color: oklch(0.80 0.13 130);
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.macro-lang-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: oklch(0.80 0.13 130);
  box-shadow: 0 0 0 2px oklch(0.80 0.13 130 / 0.18);
}

.macro-hero-image { padding: 20px 24px 0; }
.macro-hero-cover {
  margin: 0;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--border);
  aspect-ratio: 21 / 9;
}
.macro-hero-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }

.macro-section { padding: 20px 24px; }
.macro-section.macro-purpose { border-bottom: 1px dashed var(--border); }
.macro-section-label {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 12px;
}
.macro-section-label .sigil { color: var(--muted); font-weight: 500; }
.macro-purpose-body {
  font-family: var(--font-body);
  font-size: 1.02rem;
  line-height: 1.55;
  color: var(--text);
  text-wrap: pretty;
}
.macro-purpose-body p { margin: 0 0 10px; }
.macro-purpose-body p:last-child { margin-bottom: 0; }

/* The block-editor's modular content lives here. We style core blocks so
   they feel native inside the macro frame: columns sit flush, code blocks
   inherit our .codeblock-style chrome, images get a subtle border. */
.macro-content { max-width: none; }
.macro-content > * + * { margin-top: 18px; }
.macro-content h2 { font-size: 1.5rem; margin-top: 32px; }
.macro-content h3 { font-size: 1.18rem; margin-top: 28px; }

/* WP core columns — used for Script | Text rows */
.macro-content .wp-block-columns {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  margin: 0;
}
.macro-content .wp-block-column {
  flex: 1 1 0;
  min-width: 0;
}
@media (max-width: 720px) {
  .macro-content .wp-block-columns { flex-direction: column; gap: 14px; }
}

/* WP core code block — pick up our codeblock chrome */
.macro-content .wp-block-code {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 14px 16px;
  font-family: var(--font-mono);
  font-size: 0.88em;
  line-height: 1.55;
  overflow-x: auto;
  color: var(--text);
  margin: 0;
}
.macro-content .wp-block-code code { background: transparent; padding: 0; border: 0; color: inherit; }

/* WP core image block */
.macro-content .wp-block-image,
.macro-content figure.wp-block-image {
  margin: 0;
}
.macro-content .wp-block-image img {
  width: 100%;
  height: auto;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  display: block;
}
.macro-content .wp-block-image figcaption {
  margin-top: 6px;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--muted);
  text-align: center;
}

.macro-frame .reactions {
  margin: 0;
  border-radius: 0;
  border-left: 0; border-right: 0; border-bottom: 0;
  border-top: 1px dashed var(--border);
  background: transparent;
}


/* ====== Single Program — compact layout w/ live embed ====== */
.program-page { max-width: 980px; margin: 0 auto; }
.program-frame {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.program-head {
  padding: 22px 24px 18px;
  border-bottom: 1px dashed var(--border);
}
.program-head-top {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 16px;
}
.program-head-text { min-width: 0; flex: 1; }
.program-title {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  line-height: 1.15;
  font-weight: 600;
  letter-spacing: -0.015em;
  margin: 4px 0 8px;
  text-wrap: balance;
}
.program-byline {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--muted);
}
.program-byline strong { color: var(--text-2); font-weight: 600; }
.program-byline .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--muted); }
.program-service {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text);
  letter-spacing: 0.02em;
  flex-shrink: 0;
}
.program-service-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 2px oklch(from var(--accent) l c h / 0.18);
}

.program-section { padding: 20px 24px; border-bottom: 1px dashed var(--border); }
.program-section:last-of-type { border-bottom: 0; }
.program-section-label {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 12px;
}
.program-section-label .sigil { color: var(--muted); font-weight: 500; }

.program-purpose-body {
  font-family: var(--font-body);
  font-size: 1.02rem;
  line-height: 1.55;
  color: var(--text);
}
.program-purpose-body p { margin: 0 0 10px; }
.program-purpose-body p:last-child { margin-bottom: 0; }

.program-embed {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--bg);
}
.program-embed iframe {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0; display: block;
}
.program-embed--placeholder { display: grid; place-items: center; }
.program-embed--placeholder .placeholder { width: calc(100% - 24px); }

.program-explain-body {
  font-size: 0.98em;
  line-height: 1.65;
  max-width: 68ch;
}

.program-download-btn {
  display: inline-flex; align-items: center; gap: 12px;
  padding: 12px 16px;
  background: linear-gradient(135deg,
    oklch(from var(--accent) l c h / 0.16),
    oklch(from var(--accent-2) l c h / 0.16));
  border: 1px solid oklch(from var(--accent) l c h / 0.40);
  border-radius: var(--radius-sm);
  color: var(--text);
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: 0.86rem;
  font-weight: 600;
  transition: background .14s, border-color .14s, transform .1s;
}
.program-download-btn:hover {
  background: linear-gradient(135deg,
    oklch(from var(--accent) l c h / 0.26),
    oklch(from var(--accent-2) l c h / 0.26));
  border-color: oklch(from var(--accent) l c h / 0.72);
}
.program-download-btn:active { transform: translateY(1px); }
.program-download-btn svg { width: 18px; height: 18px; color: var(--accent); flex-shrink: 0; }
.program-download-label { color: var(--text); }
.program-download-host {
  color: var(--muted); font-weight: 400; font-size: 0.84em;
  margin-left: 4px;
}

.program-frame .reactions {
  margin: 0;
  border-radius: 0;
  border-left: 0; border-right: 0; border-bottom: 0;
  border-top: 1px dashed var(--border);
  background: transparent;
}


/* ====== Single Review — modular extension of blog ====== */
.review-page { max-width: 980px; margin: 0 auto; }
.review-frame {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.review-head {
  padding: 22px 24px 18px;
  border-bottom: 1px dashed var(--border);
}
.review-head-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.review-head-text { min-width: 0; flex: 1; }
.review-title {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 2.6vw, 2.1rem);
  line-height: 1.15;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 4px 0 8px;
  text-wrap: balance;
}
.review-byline {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--muted);
}
.review-byline strong { color: var(--text-2); font-weight: 600; }
.review-byline .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--muted); }

.review-score {
  display: inline-flex; align-items: baseline; gap: 4px;
  padding: 6px 14px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 999px;
  flex-shrink: 0;
}
.review-score-num {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--accent);
  line-height: 1;
}
.review-score-sep {
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--muted);
}

.review-hero-image { padding: 20px 24px 0; }
.review-hero-cover {
  margin: 0;
  border-radius: var(--radius-sm);
  overflow: hidden;
  border: 1px solid var(--border);
  aspect-ratio: 21 / 9;
}
.review-hero-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }

.review-section { padding: 20px 24px; }
.review-section:not(:last-of-type) { border-bottom: 1px dashed var(--border); }
.review-section-label {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 12px;
}
.review-section-label .sigil { color: var(--muted); font-weight: 500; }

.review-purpose-body {
  font-family: var(--font-body);
  font-size: 1.02rem;
  line-height: 1.55;
  color: var(--text);
  max-width: 70ch;
  margin: 0 auto;
}
.review-purpose-body p { margin: 0 0 10px; }
.review-purpose-body p:last-child { margin-bottom: 0; }

.review-section .rating { margin: 0; }
.review-section .pros-cons { margin: 0; }

.post-body.review-take-body,
.review-take-body {
  font-size: 0.98em;
  line-height: 1.65;
  max-width: none !important;
  width: 100%;
}
.review-take-body > p,
.review-take-body > h2,
.review-take-body > h3,
.review-take-body > h4,
.review-take-body > ul,
.review-take-body > ol,
.review-take-body > blockquote {
  max-width: 68ch;
  margin-left: auto;
  margin-right: auto;
}
.review-take-body > * + * { margin-top: 18px; }

/* WP core columns inside reviews — same treatment as macros. */
.review-take-body .wp-block-columns {
  display: flex;
  gap: 18px;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0 auto;
  max-width: none;
}
.review-take-body .wp-block-column { flex: 1 1 0; min-width: 0; }
@media (max-width: 720px) {
  .review-take-body .wp-block-columns { flex-direction: column; gap: 14px; }
}
.review-take-body .wp-block-image,
.review-take-body figure.wp-block-image { margin: 0; }
.review-take-body .wp-block-image img {
  width: 100%; height: auto;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  display: block;
}
.review-take-body .wp-block-image figcaption {
  margin-top: 6px;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--muted);
  text-align: center;
}

.review-link-btn {
  display: inline-flex; align-items: center; gap: 12px;
  padding: 12px 16px;
  background: linear-gradient(135deg,
    oklch(from var(--accent) l c h / 0.16),
    oklch(from var(--accent-2) l c h / 0.16));
  border: 1px solid oklch(from var(--accent) l c h / 0.40);
  border-radius: var(--radius-sm);
  color: var(--text);
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: 0.86rem;
  font-weight: 600;
  transition: background .14s, border-color .14s, transform .1s;
}
.review-link-btn:hover {
  background: linear-gradient(135deg,
    oklch(from var(--accent) l c h / 0.26),
    oklch(from var(--accent-2) l c h / 0.26));
  border-color: oklch(from var(--accent) l c h / 0.72);
}
.review-link-btn:active { transform: translateY(1px); }
.review-link-btn svg { width: 18px; height: 18px; color: var(--accent); flex-shrink: 0; }
.review-link-label { color: var(--text); }
.review-link-host {
  color: var(--muted); font-weight: 400; font-size: 0.84em;
  margin-left: 4px;
}

.review-frame .reactions {
  margin: 0;
  border-radius: 0;
  border-left: 0; border-right: 0; border-bottom: 0;
  border-top: 1px dashed var(--border);
  background: transparent;
}


/* ====== Single Fiction — VIM / CLI editor styling ====== */
.fiction-page { max-width: 880px; margin: 0 auto; }
.fiction-frame {
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  font-family: var(--font-mono);  /* chrome only — body overrides */
}

/* Status bars (top + bottom) — the terminal feel */
.fiction-statusbar {
  background: var(--surface-3);
  padding: 8px 16px;
  font-family: var(--font-mono);
  font-size: 0.78rem;
  display: flex;
  align-items: center;
  gap: 14px;
  color: var(--text-2);
  border-bottom: 1px solid var(--border);
}
[data-dark="true"] .fiction-statusbar { background: oklch(0.18 0.012 60); }
.fiction-statusbar--top .fiction-path {
  flex: 1; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  color: var(--accent);
}
.fiction-statusbar--top .fiction-tilde { color: var(--muted); }
.fiction-statusbar--top .fiction-mode {
  color: var(--accent-2);
  background: oklch(from var(--accent-2) l c h / 0.14);
  padding: 2px 8px;
  border-radius: 4px;
  letter-spacing: 0.06em;
  font-weight: 600;
}
.fiction-statusbar--top .fiction-stats { color: var(--muted); font-variant-numeric: tabular-nums; }

/* Title block */
.fiction-head {
  padding: 28px 28px 8px;
  background: var(--surface);
}
.fiction-title {
  font-family: var(--font-serif);
  font-size: clamp(1.6rem, 2.6vw, 2.1rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.01em;
  margin: 8px 0 8px;
  text-wrap: balance;
}
.fiction-byline {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--muted);
}
.fiction-byline strong { color: var(--text-2); font-weight: 600; }
.fiction-byline .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--muted); }

/* Optional blurb between title and body */
.fiction-blurb {
  margin: 4px 28px 0;
  padding: 14px 16px;
  background: var(--surface-2);
  border-left: 2px solid var(--accent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-family: var(--font-mono);
  font-size: 0.84rem;
  color: var(--text-2);
  line-height: 1.5;
}
.fiction-blurb-tag {
  display: block;
  color: var(--accent);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  font-size: 0.72rem;
  margin-bottom: 6px;
}
.fiction-blurb-body p { margin: 0; }

/* Body — serif for readability, NOT mono */
.fiction-body.writing-body {
  padding: 36px 28px 40px;
  max-width: 65ch;
  margin: 0 auto;
  font-family: var(--font-serif);
  font-size: 1.14em;
  line-height: 1.85;
}
.fiction-body p { margin: 0 0 18px; }
.fiction-body .wp-block-image,
.fiction-body figure.wp-block-image { margin: 24px 0; }
.fiction-body .wp-block-image img {
  max-width: 100%; height: auto;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
}
.fiction-body .wp-block-image figcaption {
  margin-top: 6px;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  color: var(--muted);
  text-align: center;
}

/* Bottom status bar — :prev / :next file links */
.fiction-statusbar--bottom {
  background: var(--surface-3);
  border-top: 1px solid var(--border);
  border-bottom: 0;
  padding: 14px 16px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
[data-dark="true"] .fiction-statusbar--bottom { background: oklch(0.18 0.012 60); }
.fiction-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-family: var(--font-mono);
  font-size: 0.92rem;
  color: var(--text);
  transition: background .14s, border-color .14s, transform .1s;
}
.fiction-link:hover {
  background: var(--surface-2);
  border-color: oklch(from var(--accent) l c h / 0.5);
  transform: translateY(-1px);
}
.fiction-link:active { transform: translateY(0); }
.fiction-link--empty {
  cursor: default;
  color: var(--muted);
  font-style: italic;
}
.fiction-link--empty:hover { background: var(--surface); border-color: var(--border); transform: none; }

.fiction-link-cmd {
  color: var(--accent);
  font-weight: 600;
  flex-shrink: 0;
}
.fiction-link-cmd .sigil { color: var(--muted); font-weight: 500; }
.fiction-link-arrow {
  color: var(--accent-2);
  font-size: 1.05em;
  flex-shrink: 0;
}
.fiction-link-title {
  color: var(--text);
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 0.96em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex: 1;
}
.fiction-link--prev { justify-content: flex-start; }
.fiction-link--next { justify-content: flex-end; }
.fiction-link--next .fiction-link-title { text-align: right; }

@media (max-width: 600px) {
  .fiction-statusbar--bottom { grid-template-columns: 1fr; }
  .fiction-link--next { justify-content: flex-start; }
  .fiction-link--next .fiction-link-title { text-align: left; }
}

.fiction-frame .reactions {
  margin: 0;
  border-radius: 0;
  border-left: 0; border-right: 0; border-bottom: 0;
  border-top: 1px dashed var(--border);
  background: var(--surface);
}


/* ====== About page — 7-section layout ====== */
.about-page { max-width: 1100px; margin: 0 auto; }

.about-section {
  margin: 56px 0;
  scroll-margin-top: 96px;
}
.about-section-label {
  font-family: var(--font-mono);
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--accent);
  margin: 0 0 18px;
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}
.about-section-label .sigil { color: var(--muted); font-weight: 500; }
.about-section-label .muted { color: var(--muted); font-size: 0.78rem; font-weight: 400; font-style: italic; }
.about-section-aside {
  color: var(--muted);
  font-size: 0.74rem;
  font-weight: 400;
  font-family: var(--font-mono);
  font-style: italic;
}

/* ── // now block ─────────────────────────────────── */
.about-now {
  background: oklch(from var(--accent) l c h / 0.05);
  border-left: 3px solid var(--accent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  padding: 20px 24px;
  margin: 56px 0;
}
.about-now-body p { margin: 0 0 12px; color: var(--text); line-height: 1.6; }
.about-now-body p:last-child { margin-bottom: 0; }

/* ── // commit log ────────────────────────────────── */
.about-commits-body {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 18px 22px;
  font-family: var(--font-mono);
  font-size: 0.86rem;
  line-height: 1.7;
}
.about-commit {
  display: flex;
  align-items: baseline;
  gap: 18px;
  padding: 4px 0;
  flex-wrap: nowrap;
}
.about-commit-sha { color: var(--accent); font-weight: 600; }
.about-commit-date { color: var(--accent-2); }
.about-commit-msg {
  color: var(--text);
  white-space: normal;
  overflow: hidden;
  text-overflow: ellipsis;
}
.about-commit-head { color: var(--accent); font-weight: 700; }
@media (max-width: 720px) {
  .about-commit { flex-wrap: wrap; row-gap: 4px; }
  .about-commit-msg { flex-basis: 100%; padding-left: 80px; }
}

/* ── // what you'll find here ─────────────────────── */
.about-types-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 14px;
}
.about-type {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  text-decoration: none;
  color: inherit;
  transition: border-color .14s, background .14s, transform .1s;
}
.about-type:hover {
  border-color: oklch(from var(--accent) l c h / 0.5);
  background: var(--surface-2);
  transform: translateY(-1px);
}
.about-type-glyph {
  font-family: var(--font-mono);
  font-size: 1.1rem;
  font-weight: 700;
  color: var(--accent);
  width: 32px;
  height: 32px;
  flex-shrink: 0;
  background: oklch(from var(--accent) l c h / 0.10);
  border-radius: 8px;
  display: grid;
  place-items: center;
}
.about-type-text { min-width: 0; flex: 1; }
.about-type-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  font-size: 1.02rem;
}
.about-type-head strong { color: var(--text); font-weight: 600; }
.about-type-count {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--muted);
}
.about-type-text p {
  margin: 4px 0 0;
  font-size: 0.88rem;
  line-height: 1.45;
  color: var(--text-2);
}

/* ── // philosophy ───────────────────────────────── */
.about-philosophy-body {
  font-size: 1.04rem;
  line-height: 1.7;
  color: var(--text);
  max-width: 70ch;
  text-wrap: pretty;
}
.about-philosophy-body p { margin: 0 0 14px; }

/* ── // find me elsewhere ────────────────────────── */
.about-elsewhere-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 10px;
}
.about-elsewhere-item {
  display: flex; align-items: baseline; gap: 12px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 0.86rem;
  text-decoration: none;
  color: inherit;
  transition: border-color .14s, background .14s;
}
.about-elsewhere-item:hover { border-color: oklch(from var(--accent) l c h / 0.5); background: var(--surface-2); }
.about-elsewhere-key { color: var(--accent); font-weight: 600; flex-shrink: 0; }
.about-elsewhere-val { color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }


/* ====== About hero quote — under the avatar ====== */
.about-hero { align-items: start; }
.about-hero > .about-avatar { grid-row: 1; }
.about-hero-quote {
  grid-row: 2;
  grid-column: 1;
  margin: 18px 0 0;
  padding: 0 8px;
  position: relative;
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.02rem;
  line-height: 1.5;
  color: var(--text-2);
  text-wrap: pretty;
}
.about-hero-quote-mark {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 2.4rem;
  line-height: 0.6;
  color: var(--accent);
  vertical-align: text-top;
  margin-right: 4px;
}
.about-hero-quote-text { color: var(--text); }
@media (max-width: 880px) {
  .about-hero-quote { margin-top: 12px; padding: 0; }
}


.about-hero-quote-cite {
  display: block;
  margin-top: 6px;
  font-family: var(--font-mono);
  font-style: normal;
  font-size: 0.78rem;
  color: var(--accent);
  letter-spacing: 0.04em;
}


.about-hero-quote-mark--close {
  font-size: 1.4rem;
  line-height: 0.6;
  margin-left: 3px;
  vertical-align: -0.15em;
}


/* ====== Release history — phase coloring ====== */
.about-commit[data-phase="alpha"]  .about-commit-sha { color: var(--accent); }
.about-commit[data-phase="beta"]   .about-commit-sha { color: var(--accent-2); }
.about-commit[data-phase="launch"] .about-commit-sha { color: oklch(0.78 0.15 145); }
.about-commit-sha { text-transform: uppercase; letter-spacing: 0.05em; font-size: 0.78rem; }


/* Per-column flex sizing inside .about-commit (replaces the broken grid). */
.about-commit-sha {
  flex-shrink: 0;
  min-width: 72px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 0.78rem;
  font-weight: 700;
}
.about-commit-date {
  flex-shrink: 0;
  font-weight: 500;
  white-space: nowrap;
  margin-left: auto;       /* push event+role away from the phase tag */
}
.about-commit-msg {
  flex-shrink: 0;          /* no longer expands — stays beside the event */
  color: var(--text-2);
  white-space: normal;
}


/* Release-history fourth column — time period, right-aligned */
.about-commit-time {
  flex-shrink: 0;
  margin-left: auto;       /* push time to the right edge — symmetrical with .date */
  font-family: var(--font-mono);
  font-size: 0.78rem;
  color: var(--accent-2);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}
@media (max-width: 720px) {
  .about-commit-time { margin-left: 0; padding-left: 80px; flex-basis: 100%; text-align: left; }
}


/* Label tags inside the // now block ("Currently:", "Reading:", "Learning:") */
.about-now-label {
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--accent);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-right: 8px;
  padding: 2px 8px;
  background: oklch(from var(--accent) l c h / 0.10);
  border-radius: 4px;
  display: inline-block;
  vertical-align: baseline;
}


/* ====== Hero bio expand toggle ======
   Short bio always visible. The extended bio lives inside a <details>
   element whose <summary> is styled as a // mono pill — same vocabulary
   as the section labels. Open/close uses native details semantics
   (no JS, accessible by default); the content fades in on expand. */
.about-bio-expand {
  margin-top: 14px;
}
.about-bio-expand summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  font-family: var(--font-mono);
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--accent);
  background: oklch(from var(--accent) l c h / 0.08);
  border: 1px solid oklch(from var(--accent) l c h / 0.30);
  border-radius: 6px;
  letter-spacing: 0.02em;
  user-select: none;
  transition: background 0.14s, border-color 0.14s, transform 0.1s;
}
.about-bio-expand summary::-webkit-details-marker { display: none; }
.about-bio-expand summary::marker { content: ''; display: none; }
.about-bio-expand summary:hover {
  background: oklch(from var(--accent) l c h / 0.16);
  border-color: oklch(from var(--accent) l c h / 0.55);
}
.about-bio-expand summary:active { transform: translateY(1px); }
.about-bio-expand summary .sigil { color: var(--muted); font-weight: 500; }
.about-bio-expand summary .about-bio-pill-icon {
  display: inline-block;
  width: 1ch;
  text-align: center;
  font-weight: 700;
  transition: transform 0.22s ease;
}
.about-bio-expand[open] summary .about-bio-pill-icon {
  /* rotate the + into a × on open — pure CSS, no swap */
  transform: rotate(45deg);
  color: var(--accent-2);
}
.about-bio-expand summary .when-open    { display: none; }
.about-bio-expand[open] summary .when-closed { display: none; }
.about-bio-expand[open] summary .when-open   { display: inline; }

.about-bio-extended {
  margin-top: 18px;
  padding-top: 18px;
  border-top: 1px dashed var(--border);
  animation: aboutBioReveal 0.34s ease-out;
}
.about-bio-extended p {
  margin: 0 0 14px;
  line-height: 1.7;
  font-size: 1rem;
  color: var(--text);
  text-wrap: pretty;
}
.about-bio-extended p:last-child { margin-bottom: 0; }
@keyframes aboutBioReveal {
  from { opacity: 0; transform: translateY(-6px); }
  to { opacity: 1; transform: none; }
}


/* ====== Fiction — optional establishing illustration ======
   Renders only when the post has a Featured Image. Sits between the
   title block and the blurb so it acts as a chapter-heading visual.
   Max-height capped so a tall portrait doesn't dominate the page. */
.fiction-figure {
  margin: 16px 28px 0;
}
.fiction-figure-img {
  display: block;
  width: 100%;
  max-height: 480px;
  object-fit: cover;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.fiction-figure[data-gif="1"] .fiction-figure-img { image-rendering: auto; }
.fiction-figure-cap {
  margin-top: 8px;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  color: var(--muted);
  letter-spacing: 0.04em;
}
.fiction-figure-cap .sigil {
  color: var(--muted);
  font-weight: 500;
  margin-right: 4px;
}
@media (max-width: 600px) {
  .fiction-figure { margin: 12px 16px 0; }
}

/* ====== Brute-force overrides ====================================
   Two non-negotiable rules, applied at the very end of the cascade so
   nothing can override them.

   1. Mobile-only elements (.mobile-profile-card, .mobile-cat-nav,
      .mobile-advice-card) are hidden AND opacity:0 when viewport > 720
      — belt-and-braces so even a stray rule that flips display can't
      make them visible.
   2. Every page container is force-centered. `margin: 0 auto` plus
      `text-align: center` for inline content on container, with
      `text-align: left` re-applied to readable text blocks so
      paragraphs aren't centered. This neutralises any earlier rule
      that left-justifies a page.

   Ship-or-die overrides — the user asked for hard-coded force. */

/* (1) Mobile-only elements: hidden when not mobile -------------------- */
.mobile-profile-card,
.mobile-cat-nav,
.mobile-advice-card,
.mobile-filter-empty {
  display: none !important;
  opacity: 0 !important;
}
@media (max-width: 720px) {
  .mobile-profile-card { display: flex !important; opacity: 1 !important; }
  .mobile-cat-nav      { display: flex !important; opacity: 1 !important; }
  .mobile-advice-card  { display: block !important; opacity: 1 !important; }
  .mobile-filter-empty:not([hidden]) { display: block !important; opacity: 1 !important; }
}

/* (2) Force center the page container on every template -------------- */
.page,
.snippet-page,
.macro-page,
.program-page,
.review-page,
.fiction-page,
.about-page {
  margin-left: auto !important;
  margin-right: auto !important;
}
/* Restore left-aligned text inside content bodies (otherwise body
   paragraphs would inherit center-text from the container). */
.page,
.page-grid > *,
.snippet-page,
.macro-page,
.program-page,
.review-page,
.fiction-page,
.about-page,
/* Right-rail sidebar — explicitly left-aligned. The sidebar (.side)
   contains profile card + content tree + recently-committed list; all
   of these read naturally as left-aligned blocks. Added here so the
   above .page-grid > * cascade can never lose to a more specific
   center-text rule elsewhere. */
aside.side,
aside.side * {
  text-align: left;
}


/* ====== Easter egg: "Till All Are One" access sequence ======
   Reconstructed styling for the elements theme.js builds when the rail brand
   words are clicked: a slide-in status banner, a 4-digit code modal (red flash
   on a wrong code), and the full-screen success / abort reveals. */
.djc-egg-banner {
  position: fixed; top: 0; left: 50%; transform: translate(-50%, -130%);
  z-index: 9000; white-space: nowrap;
  font-family: var(--font-mono); font-size: 13px; font-weight: 700; letter-spacing: 0.04em;
  color: #fff; background: var(--accent);
  padding: 10px 22px; border-radius: 0 0 12px 12px;
  box-shadow: 0 10px 34px oklch(from var(--accent) l c h / 0.45);
  transition: transform .35s cubic-bezier(.2,.8,.2,1);
}
.djc-egg-banner.is-open { transform: translate(-50%, 0); }

.djc-egg-modal {
  position: fixed; inset: 0; z-index: 9100; display: grid; place-items: center;
  background: oklch(from var(--bg) l c h / 0.82); backdrop-filter: blur(6px);
  opacity: 0; pointer-events: none; transition: opacity .22s ease;
}
.djc-egg-modal.is-open { opacity: 1; pointer-events: auto; }
.djc-egg-modal-inner {
  background: var(--surface-2, #1b1b1b); border: 1px solid var(--border, #333);
  border-radius: 16px; padding: 30px 34px; text-align: center; max-width: 90vw;
  box-shadow: 0 24px 70px rgba(0,0,0,0.5);
  transform: scale(.93); transition: transform .22s ease;
}
.djc-egg-modal.is-open .djc-egg-modal-inner { transform: scale(1); }
.djc-egg-caption { font-family: var(--font-mono); font-size: 20px; font-weight: 800; color: var(--text); margin: 0 0 4px; }
.djc-egg-subcaption { font-family: var(--font-mono); font-size: 11px; color: var(--muted); margin: 0 0 18px; }
.djc-egg-inputs { display: flex; gap: 12px; justify-content: center; }
.djc-egg-digit {
  width: 48px; height: 60px; text-align: center; outline: none;
  font-family: var(--font-mono); font-size: 28px; font-weight: 700; color: var(--text);
  background: var(--bg); border: 2px solid var(--border, #444); border-radius: 10px;
  transition: border-color .15s, box-shadow .15s, color .15s;
}
.djc-egg-digit:focus { border-color: var(--accent); box-shadow: 0 0 0 3px oklch(from var(--accent) l c h / 0.3); }
.djc-egg-modal.is-error .djc-egg-modal-inner { animation: djc-egg-shake .4s; }
.djc-egg-modal.is-error .djc-egg-digit { border-color: #e0245e; color: #e0245e; }
@keyframes djc-egg-shake { 0%,100%{transform:translateX(0)} 20%{transform:translateX(-8px)} 40%{transform:translateX(8px)} 60%{transform:translateX(-5px)} 80%{transform:translateX(5px)} }

.djc-egg-success, .djc-egg-fail {
  position: fixed; inset: 0; z-index: 9200; display: grid; place-items: center; text-align: center;
  font-family: var(--font-mono); padding: 24px;
  opacity: 0; pointer-events: none; transition: opacity .4s ease;
}
.djc-egg-success.is-open, .djc-egg-fail.is-open { opacity: 1; pointer-events: auto; }
.djc-egg-success { background: #04110f; color: #2ee6c5; }
.djc-egg-fail { background: #1a0306; color: #ff3b5c; }
.djc-egg-success-title { font-size: 26px; font-weight: 800; letter-spacing: 0.08em; margin: 0 0 10px; }
.djc-egg-success-meta { font-size: 13px; opacity: 0.85; margin: 0 0 8px; }
.djc-egg-success-count { font-size: 13px; opacity: 0.7; }
.djc-egg-fail-title { font-size: 26px; font-weight: 800; line-height: 1.3; text-transform: uppercase; margin: 0 0 12px; }
.djc-egg-fail-count { font-size: 13px; opacity: 0.8; }
.djc-egg-fail.is-open { animation: djc-egg-redpulse 1s ease-in-out infinite alternate; }
@keyframes djc-egg-redpulse { from { background: #1a0306; } to { background: #3a0710; } }


/* Red-alert flash while the access-code prompt is open (Star Trek style):
   the full-screen modal backdrop pulses red as it asks for the code. */
.djc-egg-modal.is-open { animation: djc-egg-redalert 1.1s ease-in-out infinite; }
@keyframes djc-egg-redalert {
  0%, 100% { background: oklch(from var(--bg) l c h / 0.82); }
  50%      { background: rgba(122, 0, 14, 0.62); }
}


/* The rail brand words trigger the hidden egg, so make them read as interactive:
   pointer cursor, not selectable like plain text, theme-accent glow on hover. */
.rail-brand-word {
  cursor: pointer;
  -webkit-user-select: none;
  user-select: none;
  transition: color 0.18s, text-shadow 0.18s;
}
.rail-brand-word:hover {
  color: var(--accent);
  text-shadow: 0 0 14px oklch(from var(--accent) l c h / 0.5);
}
