/* ===========================================
   FONTS: Self-hosted (run `node scripts/download-fonts.js` to fetch)
   =========================================== */

/* Atkinson Hyperlegible — body text */
@font-face {
  font-family: 'Atkinson Hyperlegible';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/atkinson-regular.woff2') format('woff2');
}
@font-face {
  font-family: 'Atkinson Hyperlegible';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url('/fonts/atkinson-italic.woff2') format('woff2');
}
@font-face {
  font-family: 'Atkinson Hyperlegible';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/atkinson-bold.woff2') format('woff2');
}
@font-face {
  font-family: 'Atkinson Hyperlegible';
  font-style: italic;
  font-weight: 700;
  font-display: swap;
  src: url('/fonts/atkinson-bold-italic.woff2') format('woff2');
}

/* Recursive — monospace / code (variable: weight 300–700, slant -15–0deg) */
@font-face {
  font-family: 'Recursive';
  font-style: oblique -15deg 0deg;
  font-weight: 300 700;
  font-display: swap;
  src: url('/fonts/recursive-variable.woff2') format('woff2');
}

/* Additional font imports needed if showFontToggle is re-enabled:
   Download Inter, Outfit, Overpass via scripts/download-fonts.js
   (add their URLs to the FONTS array) */

/* ===========================================
   BASE: Variables & Reset
   =========================================== */

:root {
  /* Font families */
  --font-body: 'Atkinson Hyperlegible', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
  --font-mono: 'Recursive', ui-monospace, SFMono-Regular, monospace;
  
  /* Typography */
  --font-size: 15px;
  --measure: 70ch;
  --leading: 1.5;
  --leading-tight: 1.3;
  
  /* Spacing */
  --space-xs: 0.2rem;
  --space-sm: 0.4rem;
  --space-md: 0.8rem;
  --space-lg: 1.2rem;
  --space-xl: 2rem;
  
  /* Layout */
  --sidebar-width: 3rem;
  --content-max-width: 52rem;
  --container-width: 42rem;
  --container-wide: 56rem;
  --bg-image-width: 35vw;
  
  /* Border frame */
  --frame-outer: 5px;
  --frame-gap: 2px;
  --frame-inner: 3px;
  --frame: calc(var(--frame-outer) + var(--frame-gap) + var(--frame-inner));
  
  /* ---- Light palette (defined once, referenced by active vars) ---- */
  --palette-light-bg: #ffffff;
  --palette-light-bg-alt: #f5f5f5;
  --palette-light-bg-deep: #fff;
  --palette-light-bg-deep-t: rgba(255,255,255,0);
  --palette-light-text: #222;
  --palette-light-text-muted: #555;
  --palette-light-text-faint: #888;
  --palette-light-link: #2563eb;
  --palette-light-link-visited: #7c3aed;
  --palette-light-link-hover: #1d4ed8;
  --palette-light-border: #ddd;
  --palette-light-border-strong: #999;
  --palette-light-code-bg: #f5f5f5;
  --palette-light-selection: #dbeafe;
  --palette-light-accent-primary: #8b1a1a;
  --palette-light-accent-secondary: #a63d3d;
  --palette-light-accent-tertiary: #c76060;
  --palette-light-shadow: 0 2px 8px rgba(199, 96, 96, 0.12);
  --palette-light-shadow-strong: 0 2px 8px rgba(199, 96, 96, 0.25);
  --palette-light-frame-color: #000;
  --palette-light-nav-hover-bg: #f8f4f6;
  --palette-light-nav-active-bg: #000;
  --palette-light-nav-active-text: #ede4f2;
  --palette-light-bg-image-1200: url('/assets/greenland-bg-1200.webp');
  --palette-light-bg-image-1920: url('/assets/greenland-bg-1920.webp');
  --palette-light-name-fill: #fff;
  --palette-light-name-shadow: #1a1a1a;
  
  /* ---- Dark palette (defined once) ---- */
  --palette-dark-bg: #1a1a1a;
  --palette-dark-bg-alt: #242424;
  --palette-dark-bg-deep: #111;
  --palette-dark-bg-deep-t: rgba(17,17,17,0);
  --palette-dark-text: #fff;
  --palette-dark-text-muted: #bbb;
  --palette-dark-text-faint: #888;
  --palette-dark-link: #60a5fa;
  --palette-dark-link-visited: #a78bfa;
  --palette-dark-link-hover: #93c5fd;
  --palette-dark-border: #444;
  --palette-dark-border-strong: #666;
  --palette-dark-code-bg: #242424;
  --palette-dark-selection: #1e3a5f;
  --palette-dark-accent-primary: #c75050;
  --palette-dark-accent-secondary: #d47070;
  --palette-dark-accent-tertiary: #e09090;
  --palette-dark-shadow: 0 2px 8px rgba(224, 144, 144, 0.2);
  --palette-dark-shadow-strong: 0 2px 8px rgba(224, 144, 144, 0.35);
  --palette-dark-frame-color: #fff;
  --palette-dark-nav-hover-bg: #2d2a2c;
  --palette-dark-nav-active-bg: #fff;
  --palette-dark-nav-active-text: #1a1a1a;
  --palette-dark-bg-image-1200: url('/assets/snowflake-bg-1200.webp');
  --palette-dark-bg-image-1920: url('/assets/snowflake-bg-1920.webp');
  --palette-dark-name-fill: #1a1a1a;
  --palette-dark-name-shadow: #fff;
  
  /* ---- Active palette (default: light) ----
     CHECKLIST: When adding a new palette variable, update ALL FOUR blocks:
       1. :root (active vars → light defaults)         — here
       2. @media (prefers-color-scheme: dark) :root     — below
       3. body.force-dark                               — below
       4. body.force-light                              — below
     Each block remaps active vars (--bg, --text, etc.) to the
     corresponding --palette-light-* or --palette-dark-* value.
  */
  --bg: var(--palette-light-bg);
  --bg-alt: var(--palette-light-bg-alt);
  --bg-deep: var(--palette-light-bg-deep);
  --bg-deep-t: var(--palette-light-bg-deep-t);
  --text: var(--palette-light-text);
  --text-muted: var(--palette-light-text-muted);
  --text-faint: var(--palette-light-text-faint);
  --link: var(--palette-light-link);
  --link-visited: var(--palette-light-link-visited);
  --link-hover: var(--palette-light-link-hover);
  --border: var(--palette-light-border);
  --border-strong: var(--palette-light-border-strong);
  --code-bg: var(--palette-light-code-bg);
  --selection: var(--palette-light-selection);
  --accent-primary: var(--palette-light-accent-primary);
  --accent-secondary: var(--palette-light-accent-secondary);
  --accent-tertiary: var(--palette-light-accent-tertiary);
  --shadow: var(--palette-light-shadow);
  --shadow-strong: var(--palette-light-shadow-strong);
  --frame-color: var(--palette-light-frame-color);
  --nav-hover-bg: var(--palette-light-nav-hover-bg);
  --nav-active-bg: var(--palette-light-nav-active-bg);
  --nav-active-text: var(--palette-light-nav-active-text);
  --bg-image-1200: var(--palette-light-bg-image-1200);
  --bg-image-1920: var(--palette-light-bg-image-1920);
  --name-fill: var(--palette-light-name-fill);
  --name-shadow: var(--palette-light-name-shadow);
}

@media (max-width: 799px) {
  :root {
    --frame-outer: 3px;
    --frame-inner: 2px;
    --frame: calc(var(--frame-outer) + var(--frame-gap) + var(--frame-inner));
  }
}

/* Dark mode (system preference) */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: var(--palette-dark-bg);
    --bg-alt: var(--palette-dark-bg-alt);
    --bg-deep: var(--palette-dark-bg-deep);
    --bg-deep-t: var(--palette-dark-bg-deep-t);
    --text: var(--palette-dark-text);
    --text-muted: var(--palette-dark-text-muted);
    --text-faint: var(--palette-dark-text-faint);
    --link: var(--palette-dark-link);
    --link-visited: var(--palette-dark-link-visited);
    --link-hover: var(--palette-dark-link-hover);
    --border: var(--palette-dark-border);
    --border-strong: var(--palette-dark-border-strong);
    --code-bg: var(--palette-dark-code-bg);
    --selection: var(--palette-dark-selection);
    --accent-primary: var(--palette-dark-accent-primary);
    --accent-secondary: var(--palette-dark-accent-secondary);
    --accent-tertiary: var(--palette-dark-accent-tertiary);
    --shadow: var(--palette-dark-shadow);
    --shadow-strong: var(--palette-dark-shadow-strong);
    --frame-color: var(--palette-dark-frame-color);
    --nav-hover-bg: var(--palette-dark-nav-hover-bg);
    --nav-active-bg: var(--palette-dark-nav-active-bg);
    --nav-active-text: var(--palette-dark-nav-active-text);
    --bg-image-1200: var(--palette-dark-bg-image-1200);
    --bg-image-1920: var(--palette-dark-bg-image-1920);
    --name-fill: var(--palette-dark-name-fill);
    --name-shadow: var(--palette-dark-name-shadow);
  }
}

/* Force dark — just remap active vars, no value duplication */
body.force-dark {
  --bg: var(--palette-dark-bg);
  --bg-alt: var(--palette-dark-bg-alt);
  --bg-deep: var(--palette-dark-bg-deep);
  --bg-deep-t: var(--palette-dark-bg-deep-t);
  --text: var(--palette-dark-text);
  --text-muted: var(--palette-dark-text-muted);
  --text-faint: var(--palette-dark-text-faint);
  --link: var(--palette-dark-link);
  --link-visited: var(--palette-dark-link-visited);
  --link-hover: var(--palette-dark-link-hover);
  --border: var(--palette-dark-border);
  --border-strong: var(--palette-dark-border-strong);
  --code-bg: var(--palette-dark-code-bg);
  --selection: var(--palette-dark-selection);
  --accent-primary: var(--palette-dark-accent-primary);
  --accent-secondary: var(--palette-dark-accent-secondary);
  --accent-tertiary: var(--palette-dark-accent-tertiary);
  --shadow: var(--palette-dark-shadow);
  --shadow-strong: var(--palette-dark-shadow-strong);
  --frame-color: var(--palette-dark-frame-color);
  --nav-hover-bg: var(--palette-dark-nav-hover-bg);
  --nav-active-bg: var(--palette-dark-nav-active-bg);
  --nav-active-text: var(--palette-dark-nav-active-text);
  --bg-image-1200: var(--palette-dark-bg-image-1200);
  --bg-image-1920: var(--palette-dark-bg-image-1920);
  --name-fill: var(--palette-dark-name-fill);
  --name-shadow: var(--palette-dark-name-shadow);
}

/* Force light — override system dark back to light */
body.force-light {
  --bg: var(--palette-light-bg);
  --bg-alt: var(--palette-light-bg-alt);
  --bg-deep: var(--palette-light-bg-deep);
  --bg-deep-t: var(--palette-light-bg-deep-t);
  --text: var(--palette-light-text);
  --text-muted: var(--palette-light-text-muted);
  --text-faint: var(--palette-light-text-faint);
  --link: var(--palette-light-link);
  --link-visited: var(--palette-light-link-visited);
  --link-hover: var(--palette-light-link-hover);
  --border: var(--palette-light-border);
  --border-strong: var(--palette-light-border-strong);
  --code-bg: var(--palette-light-code-bg);
  --selection: var(--palette-light-selection);
  --accent-primary: var(--palette-light-accent-primary);
  --accent-secondary: var(--palette-light-accent-secondary);
  --accent-tertiary: var(--palette-light-accent-tertiary);
  --shadow: var(--palette-light-shadow);
  --shadow-strong: var(--palette-light-shadow-strong);
  --frame-color: var(--palette-light-frame-color);
  --nav-hover-bg: var(--palette-light-nav-hover-bg);
  --nav-active-bg: var(--palette-light-nav-active-bg);
  --nav-active-text: var(--palette-light-nav-active-text);
  --bg-image-1200: var(--palette-light-bg-image-1200);
  --bg-image-1920: var(--palette-light-bg-image-1920);
  --name-fill: var(--palette-light-name-fill);
  --name-shadow: var(--palette-light-name-shadow);
}

/* Body gradient — single rule, vars resolve per mode */
@media (min-width: 1200px) {
  body {
    background: linear-gradient(to right, var(--bg) 0%, var(--bg) min(56rem, 60vw), var(--bg-deep) 65vw, var(--bg-deep) 100%);
    background-attachment: fixed;
  }
}

/* Font variants via body class — only active when showFontToggle is true
   in site.json. Additional font files must be added to scripts/download-fonts.js
   and corresponding @font-face blocks added above before re-enabling the toggle. */
body.font-atkinson {
  --font-body: 'Atkinson Hyperlegible', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
}

body.font-inter {
  --font-body: 'Inter', -apple-system, system-ui, sans-serif;
}

body.font-recursive {
  --font-body: 'Recursive', -apple-system, system-ui, sans-serif;
}

body.font-overpass {
  --font-body: 'Overpass', -apple-system, system-ui, sans-serif;
}

body.font-outfit {
  --font-body: 'Outfit', -apple-system, system-ui, sans-serif;
}

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

/* ===========================================
   TYPOGRAPHY
   =========================================== */

html {
  font-size: var(--font-size);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body {
  font-family: var(--font-body);
  line-height: var(--leading);
  color: var(--text);
  background-color: var(--bg);
  margin: 0;
  padding: 0;
  font-weight: 200;
}

/* Wide screen: background image fading in from right.
   Image URLs and overlay color resolve via palette variables —
   no per-mode overrides needed. */
.bg-image {
  position: fixed;
  top: var(--frame);
  right: var(--frame);
  bottom: 0;
  width: calc(var(--bg-image-width) - var(--frame));
  pointer-events: none;
  z-index: 1;
  opacity: 0;
  animation: fadeInBg 0.2s ease-out 0.15s forwards;
  will-change: transform;
  overflow: hidden;
  transition: top 0.15s ease, bottom 0.15s ease;
}

.bg-image::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: var(--bg-image-1200);
  background-size: cover;
  background-position: right top;
  background-repeat: no-repeat;
}

.bg-image::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to right,
    var(--bg-deep) 0%,
    var(--bg-deep-t) 20%);
  z-index: 1;
}

@media (max-width: 1199px) {
  .bg-image { display: none; }
}

@media (min-width: 1600px) {
  .bg-image::before {
    background-image: var(--bg-image-1920);
  }
}

/* bg-ready: set by <head> script from sessionStorage, ensures bg-image
   is visible before inline body scripts run — critical for view transition
   snapshots which capture state at first render. */
html.bg-ready .bg-image {
  opacity: 1;
  animation: none;
}

@keyframes fadeInBg {
  to { opacity: 1; }
}

/* Site border - double frame using box-shadows (no miter bevels) */
.site-border {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 900;
  /* Outer frame: left + right + top bars */
  box-shadow:
    inset var(--frame-outer) 0 0 0 var(--frame-color),
    inset calc(-1 * var(--frame-outer)) 0 0 0 var(--frame-color),
    inset 0 var(--frame-outer) 0 0 var(--frame-color);
  transition: box-shadow 0.15s ease;
}

/* Inner frame uses explicit top/right/bottom/left instead of shorthand inset
   so top and bottom can independently adjust to match border state */
.site-border::after {
  content: "";
  position: absolute;
  left: calc(var(--frame-outer) + var(--frame-gap));
  right: calc(var(--frame-outer) + var(--frame-gap));
  top: calc(var(--frame-outer) + var(--frame-gap));
  bottom: 0; /* default: no bottom border, so extend to edge */
  pointer-events: none;
  box-shadow:
    inset var(--frame-inner) 0 0 0 var(--frame-color),
    inset calc(-1 * var(--frame-inner)) 0 0 0 var(--frame-color),
    inset 0 var(--frame-inner) 0 0 var(--frame-color);
  transition: box-shadow 0.15s ease, top 0.15s ease, bottom 0.15s ease;
}

/* Scrolled: remove top bars, inner top extends to edge */
body.scrolled .site-border {
  box-shadow:
    inset var(--frame-outer) 0 0 0 var(--frame-color),
    inset calc(-1 * var(--frame-outer)) 0 0 0 var(--frame-color);
}
body.scrolled .site-border::after {
  top: 0;
  box-shadow:
    inset var(--frame-inner) 0 0 0 var(--frame-color),
    inset calc(-1 * var(--frame-inner)) 0 0 0 var(--frame-color);
}

/* At bottom: add bottom bars, inner bottom pulls in */
.site-border.at-bottom {
  box-shadow:
    inset var(--frame-outer) 0 0 0 var(--frame-color),
    inset calc(-1 * var(--frame-outer)) 0 0 0 var(--frame-color),
    inset 0 var(--frame-outer) 0 0 var(--frame-color),
    inset 0 calc(-1 * var(--frame-outer)) 0 0 var(--frame-color);
}
.site-border.at-bottom::after {
  bottom: calc(var(--frame-outer) + var(--frame-gap));
  box-shadow:
    inset var(--frame-inner) 0 0 0 var(--frame-color),
    inset calc(-1 * var(--frame-inner)) 0 0 0 var(--frame-color),
    inset 0 var(--frame-inner) 0 0 var(--frame-color),
    inset 0 calc(-1 * var(--frame-inner)) 0 0 var(--frame-color);
}

/* Scrolled AND at bottom: sides + bottom only */
body.scrolled .site-border.at-bottom {
  box-shadow:
    inset var(--frame-outer) 0 0 0 var(--frame-color),
    inset calc(-1 * var(--frame-outer)) 0 0 0 var(--frame-color),
    inset 0 calc(-1 * var(--frame-outer)) 0 0 var(--frame-color);
}
body.scrolled .site-border.at-bottom::after {
  top: 0;
  bottom: calc(var(--frame-outer) + var(--frame-gap));
  box-shadow:
    inset var(--frame-inner) 0 0 0 var(--frame-color),
    inset calc(-1 * var(--frame-inner)) 0 0 0 var(--frame-color),
    inset 0 calc(-1 * var(--frame-inner)) 0 0 var(--frame-color);
}

/* Mobile frame widths set via --frame-outer/--frame-inner in :root override */

/* Frame color is set via --frame-color in dark/light mode variables */

/* ===========================================
   SCROLL STATE - top frame disappears, elements snap to top
   =========================================== */

/* Desktop & mobile: sidebar snaps to viewport top when scrolled */
body.scrolled .sidebar {
  top: 0;
}

/* Background image snaps to top */
body.scrolled .bg-image {
  top: 0;
}

/* At bottom: pull sidebar and bg-image up for bottom border */
@media (min-width: 800px) {
  body.at-bottom .sidebar {
    bottom: var(--frame);
  }
}
body.at-bottom .bg-image {
  bottom: var(--frame);
}

/* Back to top - appears on scroll, button style */
.back-to-top {
  position: fixed;
  top: calc(var(--frame) + 0.4rem);
  right: calc(var(--frame) + 0.4rem);
  font-family: var(--font-body);
  font-size: var(--font-size);
  color: var(--bg);
  background: var(--text);
  border: none;
  text-decoration: none;
  writing-mode: vertical-rl;
  letter-spacing: 0.02em;
  padding: 0.55rem 0.25rem;
  border-radius: 2px;
  z-index: 150;
  opacity: 0;
  transform: translateY(-0.5rem);
  transition: opacity 0.15s ease, transform 0.15s ease, top 0.15s ease;
  pointer-events: none;
  cursor: pointer;
}

.back-to-top:hover { opacity: 0.8; }

/* Arrow needs rotation correction in vertical-rl writing mode */
.btt-arrow {
  display: inline-block;
  transform: rotate(-90deg);
}

.back-to-top.visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

body.scrolled .back-to-top {
  top: 0.4rem;
}

.back-to-top-mobile { display: none; }

/* Mobile: position below sticky nav */
@media (max-width: 799px) {
  .back-to-top {
    top: calc(var(--frame) + 2.5rem);
    right: calc(var(--frame) + 0.4rem);
  }
  body.scrolled .back-to-top {
    top: 2.5rem;
  }
  .back-to-top-desktop { display: none; }
  .back-to-top-mobile { display: inline; }
}

/* Profile picture - floated right in about page, pulled up to heading level */
.about-pic {
  float: right;
  width: 20%;
  height: auto;
  border-radius: 50%;
  object-fit: cover;
  aspect-ratio: 1;
  border: 2px solid var(--accent-tertiary);
  margin: 0 0 var(--space-sm) var(--space-md);
  shape-outside: circle(50%);
}

@media (max-width: 799px) {
  .about-pic {
    width: 30%;
  }
}

/* Name SVG — outlined text with hard 80s drop shadow, themed via CSS */
.name-text {
  fill: var(--name-fill);
  stroke: var(--name-shadow);
  stroke-width: 2px;
  stroke-linejoin: round;
}
.name-shadow { fill: var(--name-shadow); }

::selection {
  background: var(--selection);
}

h1, h2, h3, h4, h5, h6 {
  line-height: var(--leading-tight);
  margin: 0 0 var(--space-sm);
  font-weight: 700;
  letter-spacing: 0.02em;
}

h1 { font-size: 1.5rem; }
h2 { font-size: 1.25rem; margin-top: var(--space-lg); }
h3 { font-size: 1.1rem; margin-top: var(--space-md); }
h4, h5, h6 { font-size: 1rem; font-weight: 700; }

p {
  margin: 0 0 var(--space-md);
  max-width: var(--measure);
}

.small, small { font-size: 0.85rem; }
.muted { color: var(--text-muted); }
.faint { color: var(--text-faint); }

/* ===========================================
   LINKS
   =========================================== */

a {
  color: var(--link);
  text-decoration: underline;
  text-underline-offset: 2px;
}

a:visited { color: var(--link-visited); }
a:hover { text-decoration-thickness: 2px; }

a.wikilink { text-decoration-style: dotted; }

/* ===========================================
   DIVIDERS - fade from solid to dashed
   =========================================== */

.divider,
.top-header,
.section-header,
footer.site-footer {
  border-bottom: none !important;
  border-top: none !important;
  position: relative;
}

.divider::after,
.top-header::after,
.section-header::after,
footer.site-footer::before {
  content: "────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ───── ───── ──── ──── ─── ─── ── ── ── ─ ─ ─ ─  ─  ─  ─   ─   ─    ─    ─     ─";
  position: absolute;
  left: 0;
  width: 100%;
  bottom: 0;
  height: 1px;
  font-size: 0.5rem;
  line-height: 1px;
  letter-spacing: -0.15em;
  overflow: hidden;
  white-space: nowrap;
  background: linear-gradient(
    to right,
    var(--text) 0%,
    var(--accent-primary) 60%,
    transparent 100%
  );
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  background-clip: text;
}

footer.site-footer::before {
  bottom: auto;
  top: 0;
}

/* ===========================================
   LAYOUT - Rotated sidebar nav on desktop
   =========================================== */

.site-wrapper {
  min-height: 100vh;
  min-height: 100dvh;
  position: relative;
  z-index: 2;
  padding-top: var(--frame);
  padding-bottom: var(--frame);
}

/* Desktop: rotated sidebar */
@media (min-width: 800px) {
  .sidebar {
    position: fixed;
    left: var(--frame);
    top: var(--frame);
    bottom: 0;
    width: var(--sidebar-width);
    background: var(--bg);
    z-index: 10;
    transition: top 0.15s ease, bottom 0.15s ease;
  }
  
  .sidebar-inner {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    display: flex;
  }
  
  .mobile-header {
    display: none;
  }
  
  .main-content {
    margin-left: calc(var(--sidebar-width) + var(--frame));
    padding: var(--space-lg) calc(var(--space-xl) * 1.4 + var(--frame)) var(--space-lg) var(--space-lg);
    max-width: var(--content-max-width);
    overflow-x: hidden;
  }
  
  /* Top header with name */
  .top-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: var(--space-sm) var(--space-md);
    padding-bottom: var(--space-md);
    margin-bottom: var(--space-lg);
  }
  
  .top-header .site-title {
    display: block;
  }
  
  .top-links {
    display: flex;
    align-items: baseline;
    gap: var(--space-md);
    font-size: 0.85rem;
  }
  
  .top-links .sep {
    color: var(--text-faint);
  }
  
  .top-links a {
    color: var(--text-muted);
    text-decoration: none;
  }
  
  .top-links a:hover {
    color: var(--text);
    text-decoration: underline;
    text-underline-offset: 3px;
  }
}

/* Mobile: stacked, no rotation */
@media (max-width: 799px) {
  .main-content {
    padding: var(--space-md) calc(var(--space-md) + var(--frame));
  }
  
  .top-header {
    display: none;
  }
}

/* Mobile dark mode sticky header background */
@media (max-width: 799px) and (prefers-color-scheme: dark) {
  .sidebar {
    background: var(--bg);
    box-shadow: var(--shadow-strong);
  }
}

@media (max-width: 799px) {
  body.force-dark .sidebar {
    background: var(--bg);
    box-shadow: var(--shadow-strong);
  }
  
  body.force-light .sidebar {
    background: var(--bg);
    box-shadow: var(--shadow);
  }
}

.container {
  max-width: var(--container-width);
}

.container--wide {
  max-width: var(--container-wide);
}

main {
  min-height: 50vh;
}

/* ===========================================
   SIDEBAR / HEADER
   =========================================== */

.site-title {
  display: block;
  max-width: 24rem;
  text-decoration: none;
  margin-bottom: -0.3rem;
}

.site-title .name-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: hidden;
}

/* Desktop: rotated vertical nav */
@media (min-width: 800px) {
  nav.site-nav {
    display: flex;
    flex-direction: row-reverse;  /* In rotated context, reverses so Writing=top, About=bottom */
    flex: 1;              /* Fill all available space */
    width: 100%;          /* Full width of sidebar-inner */
  }
  
  nav.site-nav a {
    flex: 1;              /* Each link takes equal space */
    display: flex;
    align-items: center;
    justify-content: center;
    
    font-size: 1rem;
    color: var(--text-muted);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    
    /* Padding to push text away from sidebar edges */
    /* In rotated context: padding-block = visual left/right */
    padding-block: 0.5rem;
    
    transition: background-color 0.15s ease, color 0.15s ease;
  }
  
  nav.site-nav a:hover {
    color: var(--text);
    background: var(--nav-hover-bg);
  }
  
  /* Current page highlight */
  nav.site-nav a[aria-current="page"] {
    background: var(--nav-active-bg);
    color: var(--nav-active-text);
    text-decoration: none;
  }
  
  nav.site-nav a[aria-current="page"]:hover {
    background: var(--nav-active-bg);
    color: var(--nav-active-text);
    text-decoration: none;
  }
}

/* Mobile: horizontal, matching desktop style */
@media (max-width: 799px) {
  .sidebar {
    position: sticky;
    top: var(--frame);
    z-index: 100;
    background: var(--bg);
    padding: 0;
    margin: 0 var(--frame);
    box-shadow: var(--shadow);
    transition: top 0.15s ease;
  }
  
  .sidebar-inner {
    display: block;
  }
  
  /* Mobile top row: name + utility links (in document flow) */
  .mobile-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    padding: var(--space-sm) var(--space-md);
    margin: 0 var(--frame);
    border-bottom: 1px solid var(--border);
    max-height: 3rem;
    overflow: hidden;
    transition: max-height 0.18s ease, padding 0.18s ease, opacity 0.18s ease, border-color 0.18s ease;
  }
  
  .mobile-header.scrolled {
    max-height: 0;
    padding-top: 0;
    padding-bottom: 0;
    opacity: 0;
    border-color: transparent;
  }
  
  .mobile-header .site-title {
    max-width: 16rem;
    margin: 0;
    margin-bottom: -0.2rem;
  }
  
  .mobile-links {
    display: flex;
    align-items: baseline;
    gap: var(--space-sm);
    font-size: 0.8rem;
  }
  
  .mobile-links .sep {
    color: var(--text-faint);
  }
  
  .mobile-links a {
    color: var(--text-muted);
    text-decoration: none;
  }
  
  .mobile-links a:hover {
    color: var(--text);
    text-decoration: underline;
    text-underline-offset: 3px;
  }
  
  /* Mobile nav row */
  nav.site-nav {
    display: flex;
    flex-wrap: wrap;
  }
  
  nav.site-nav a {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-sm) var(--space-md);
    font-size: 0.85rem;
    color: var(--text-muted);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 3px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    transition: background-color 0.15s ease, color 0.15s ease;
  }
  
  nav.site-nav a:hover {
    color: var(--text);
    background: var(--nav-hover-bg);
  }
  
  nav.site-nav a[aria-current="page"] {
    background: var(--nav-active-bg);
    color: var(--nav-active-text);
    text-decoration: none;
  }
  
  nav.site-nav a[aria-current="page"]:hover {
    background: var(--nav-active-bg);
    color: var(--nav-active-text);
    text-decoration: none;
  }
  
  .top-header {
    display: none;
  }
}

/* Nav colors are set via --nav-hover-bg, --nav-active-bg, --nav-active-text
   in light/dark mode variable blocks above */

/* ===========================================
   FOOTER
   =========================================== */

footer.site-footer {
  margin-top: var(--space-xl);
  padding-top: var(--space-md);
  font-size: 0.85rem;
  color: var(--text-muted);
}

.footer-inner {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.footer-links {
  display: flex;
  gap: var(--space-md);
}

.footer-links a { color: var(--text-muted); }

/* ===========================================
   SITE CONTROLS (theme + language toggle)
   =========================================== */

.site-controls {
  position: fixed;
  bottom: calc(var(--frame) + var(--space-sm));
  right: calc(var(--frame) + var(--space-sm));
  z-index: 100;
  font-size: 0.75rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 3px;
  display: flex;
  gap: 2px;
  opacity: 0.85;
  transition: opacity 0.15s ease;
}

.site-controls:hover { opacity: 1; }

.site-controls button {
  background: transparent;
  border: none;
  padding: 3px 6px;
  font-size: 0.7rem;
  color: var(--text-muted);
  cursor: pointer;
  border-radius: 2px;
  font-family: inherit;
}

.site-controls button:hover { color: var(--text); }
.site-controls button.active {
  color: var(--text);
  background: var(--bg-alt);
}

.site-controls .toggle-sep {
  color: var(--text-faint);
  padding: 0 2px;
}

#dark-toggle {
  font-size: 0.8rem;
}

#lang-toggle {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: -0.02em;
}

/* ===========================================
   HOMEPAGE
   =========================================== */

.home-intro {
  margin-bottom: var(--space-lg);
}

.home-intro p {
  margin-bottom: var(--space-sm);
}

.home-section {
  margin-bottom: var(--space-lg);
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: var(--space-sm);
  padding-bottom: var(--space-xs);
}

.section-title {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin: 0;
}

.section-link {
  font-size: 0.8rem;
  color: var(--text-faint);
}

/* ===========================================
   POST LISTS
   =========================================== */

.post-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.post-list-item {
  margin-bottom: var(--space-md);
}

.post-list-item h3 {
  font-size: 1rem;
  font-weight: 400;
  margin: 0;
}

.post-list-item h3 a {
  color: var(--text);
  text-decoration: none;
}

.post-list-item h3 a:hover { text-decoration: underline; }

.post-meta {
  font-size: 0.85rem;
  color: var(--text-muted);
}

.post-meta time {
  font-variant-numeric: tabular-nums;
}

.post-excerpt {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin-top: var(--space-xs);
}

/* Compact: date and title on same line */
.post-list--compact .post-list-item {
  margin-bottom: var(--space-xs);
  display: flex;
  gap: var(--space-md);
  align-items: baseline;
}

.post-list--compact .post-meta {
  min-width: 5rem;
  flex-shrink: 0;
}

/* ===========================================
   FEATURED LIST (with descriptions)
   =========================================== */

.featured-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.featured-item {
  margin-bottom: var(--space-md);
}

.featured-item h3 {
  font-size: 1rem;
  font-weight: 400;
  margin: 0;
  display: inline;
}

.featured-item h3 a {
  color: var(--text);
  text-decoration: none;
}

.featured-item h3 a:hover { text-decoration: underline; }

.featured-item .description {
  color: var(--text-muted);
  font-size: 0.9rem;
}

/* ===========================================
   ARTICLES
   =========================================== */

article {
  max-width: var(--measure);
}

.article-header {
  margin-bottom: var(--space-lg);
}

.article-header h1 {
  margin-bottom: var(--space-xs);
}

/* ===========================================
   PROSE
   =========================================== */

ul, ol {
  padding-left: 1.2rem;
  margin: 0 0 var(--space-md);
}

li {
  margin-bottom: var(--space-xs);
}

blockquote {
  border-left: 2px solid var(--border-strong);
  margin: var(--space-md) 0;
  padding-left: var(--space-md);
  color: var(--text-muted);
}

blockquote p:last-child { margin-bottom: 0; }

hr {
  border: none;
  border-top: 1px solid var(--border);
  margin: var(--space-lg) 0;
}

/* ===========================================
   CODE
   =========================================== */

code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--code-bg);
  padding: 0.1em 0.3em;
  border-radius: 2px;
}

pre {
  background: var(--code-bg);
  padding: var(--space-md);
  overflow-x: auto;
  border-radius: 3px;
  margin: var(--space-md) 0;
  font-size: 0.85rem;
  line-height: 1.4;
}

pre code {
  background: none;
  padding: 0;
}

/* ===========================================
   TABLES
   =========================================== */

table {
  border-collapse: collapse;
  width: 100%;
  margin: var(--space-md) 0;
  font-size: 0.9rem;
}

th, td {
  text-align: left;
  padding: var(--space-xs) var(--space-sm) var(--space-xs) 0;
  border-bottom: 1px solid var(--border);
}

th {
  font-weight: 600;
}

/* ===========================================
   IMAGES
   =========================================== */

img {
  max-width: 100%;
  height: auto;
}

figure {
  margin: var(--space-lg) 0;
}

figcaption {
  font-size: 0.85rem;
  color: var(--text-muted);
  margin-top: var(--space-xs);
}

/* ===========================================
   PHOTOS
   =========================================== */

.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--space-sm);
  margin: var(--space-md) 0;
}

.photo-grid img {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
}

.series-header {
  margin-bottom: var(--space-md);
}

.series-meta {
  color: var(--text-muted);
  font-size: 0.9rem;
}

/* ===========================================
   BACKLINKS
   =========================================== */

.backlinks {
  margin-top: var(--space-lg);
  padding-top: var(--space-md);
  border-top: 1px solid var(--border);
}

.backlinks-title {
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin-bottom: var(--space-sm);
}

.backlinks-list {
  list-style: none;
  padding: 0;
}

.backlinks-list li {
  margin-bottom: var(--space-xs);
}

/* ===========================================
   UTILITIES
   =========================================== */

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

/* ===========================================
   RESPONSIVE
   =========================================== */

@media (max-width: 799px) {
  .post-list--compact .post-list-item {
    flex-direction: column;
    gap: 0;
  }
  
  .post-list--compact .post-meta {
    min-width: auto;
  }
}


/* ===========================================
   VIEW TRANSITIONS (MPA cross-document)
   =========================================== */

@view-transition {
  navigation: auto;
}

/* ===========================================
   INTRO ANIMATION (first visit per session)
   =========================================== */

/* While waiting for fonts, hide name SVG and nav underlines to prevent FOUT */
html.waiting-intro .name-svg { visibility: hidden; }

/* Lock page during initial load — prevents scrollbar flash before layout settles.
   Not applied during html.intro because .name-svg has overflow: hidden
   and replay (theme toggle) shouldn't lock scroll position. */
html.waiting-intro {
  overflow: hidden;
}

/* --- Laser outline drawing: 0–0.3s --- */

/* The drawing layer: stroke only, sits on top */
.name-draw {
  stroke: var(--name-shadow);
  stroke-width: 2px;
  stroke-linejoin: round;
  opacity: 0; /* hidden when not animating */
}

/* During intro: draw layer traces outline then disappears */
html.intro .name-draw {
  stroke-dasharray: 4000;
  stroke-dashoffset: 4000;
  animation: laserDraw 0.3s ease-out forwards;
}

/* During intro: main text starts invisible, snaps in when outline finishes */
html.intro .name-text {
  opacity: 0;
  animation: snapIn 0.01s linear 0.29s forwards;
}

/* Draw in the outline, then snap hidden at the very end */
@keyframes laserDraw {
  0%   { stroke-dashoffset: 4000; opacity: 1; }
  95%  { stroke-dashoffset: 0;    opacity: 1; }
  100% { stroke-dashoffset: 0;    opacity: 0; }
}

@keyframes snapIn {
  to { opacity: 1; }
}

/* --- Shadow pop-in: 0.3–1.0s (5 layers × 0.14s) --- */

html.intro .name-shadow { opacity: 0; }
html.intro .name-shadow-1 { animation: snapIn 0.01s linear 0.30s forwards; }
html.intro .name-shadow-2 { animation: snapIn 0.01s linear 0.44s forwards; }
html.intro .name-shadow-3 { animation: snapIn 0.01s linear 0.58s forwards; }
html.intro .name-shadow-4 { animation: snapIn 0.01s linear 0.72s forwards; }
html.intro .name-shadow-5 { animation: snapIn 0.01s linear 0.86s forwards; }

/* --- Nav link underlines --- */
/* Desktop: fade in text-decoration-color (works with writing-mode rotation) */
@media (min-width: 800px) {
  html.waiting-intro nav.site-nav a:not([aria-current="page"]) {
    text-decoration-color: transparent;
  }

  html.intro nav.site-nav a:not([aria-current="page"]) {
    text-decoration-color: transparent;
    animation: decorReveal 0.3s ease 0.5s forwards;
  }
}

@keyframes decorReveal {
  to { text-decoration-color: currentColor; }
}

/* Mobile: grow underline from center via pseudo */
@media (max-width: 799px) {
  html.waiting-intro nav.site-nav a:not([aria-current="page"]) {
    text-decoration: none !important;
  }

  html.intro nav.site-nav a:not([aria-current="page"]) {
    text-decoration: none !important;
    position: relative;
  }
  
  html.intro nav.site-nav a:not([aria-current="page"])::after {
    content: "";
    position: absolute;
    left: 15%;
    right: 15%;
    bottom: calc(var(--space-sm) - 1px);
    height: 1px;
    background: currentColor;
    transform: scaleX(0);
    animation: underlineGrow 0.4s ease 0.4s forwards;
  }
}

@keyframes underlineGrow {
  to { transform: scaleX(1); }
}

/* Respect reduced motion preference */
@media (prefers-reduced-motion: reduce) {
  html.intro .name-draw { animation: none; opacity: 0; }
  html.intro .name-text { animation: none; opacity: 1; }
  html.intro .name-shadow { opacity: 1; }
  html.intro .name-shadow-1,
  html.intro .name-shadow-2,
  html.intro .name-shadow-3,
  html.intro .name-shadow-4,
  html.intro .name-shadow-5 { animation: none; opacity: 1; }
  html.intro nav.site-nav a:not([aria-current="page"]) {
    animation: none; text-decoration-color: currentColor;
  }
  html.intro nav.site-nav a:not([aria-current="page"])::after {
    animation: none; transform: scaleX(1);
  }
}

/* ===========================================
   VIEW TRANSITIONS
   =========================================== */

/* Only name elements that are visually identical between pages.
   Scroll-dependent elements (border, bg-image, sidebar, back-to-top,
   footer) stay in the root — the root snapshot is opaque, so its
   plus-lighter crossfade handles state differences cleanly.
   Transparent elements with VT names cause artifacts because old
   snapshots bleed through transparent areas of new snapshots. */
.site-controls { view-transition-name: site-controls; }
.top-header  { view-transition-name: top-header; }
main          { view-transition-name: main-content; }

/* Shorten the default crossfade for content and root */
::view-transition-group(main-content),
::view-transition-group(root) {
  animation-duration: 0.15s;
}

/* Persistent chrome: hold in place, no animation */
::view-transition-old(site-controls),
::view-transition-new(site-controls),
::view-transition-old(top-header),
::view-transition-new(top-header) {
  animation: none;
}

/* Suppress CSS transitions during view transitions and initial page load —
   prevents border/sidebar from visibly animating into correct positions. */
body.vt-settling .site-border,
body.vt-settling .site-border::after,
body.vt-settling .sidebar,
body.vt-settling .bg-image,
body.vt-settling .back-to-top,
body.vt-settling .mobile-header,
html.no-settle .site-border,
html.no-settle .site-border::after,
html.no-settle .sidebar,
html.no-settle .bg-image,
html.no-settle .back-to-top,
html.no-settle .mobile-header,
html.waiting-intro .site-border,
html.waiting-intro .site-border::after {
  transition: none !important;
}

/* ===========================================
   PRINT
   =========================================== */

@media print {
  .site-controls { display: none; }
  body { font-size: 11pt; color: black; background: white; }
  a { color: black; }
}
