/* ============================================================
   STYLE.CSS
   Mobile-first. Dark forest green. Flat files.
   Big name header (Geerling style). Dynomight-style post titles.
   ============================================================ */

@font-face { font-family: century_supra_a; font-style: normal; font-weight: normal; font-display: swap; src: url('assets/fonts/century_supra_a_regular.woff2') format('woff2'); }
@font-face { font-family: century_supra_a; font-style: italic; font-weight: normal; font-display: swap; src: url('assets/fonts/century_supra_a_italic.woff2') format('woff2'); }
@font-face { font-family: century_supra_a; font-style: normal; font-weight: bold; font-display: swap; src: url('assets/fonts/century_supra_a_bold.woff2') format('woff2'); }
@font-face { font-family: century_supra_a; font-style: italic; font-weight: bold; font-display: swap; src: url('assets/fonts/century_supra_a_bold_italic.woff2') format('woff2'); }

/* Segoe UI (the body face). local()-first: any device that already has Segoe
   installed (every Windows machine, plus Macs with Microsoft Office) renders the
   genuine font and downloads NOTHING; everyone else (mobile, most Macs, Linux)
   gets the self-hosted woff. Deliberately NOT preloaded: a <link rel=preload>
   would force the download even where local() would have won, defeating the point.
   Three real weights are bundled: 400 / 600 / 700. The 600 is genuine Segoe UI
   Semibold, so the homepage date kickers and section labels (font-weight:600) get
   the true weight rather than rounding up to bold. A real Segoe UI Italic is
   bundled at weight 400; heavier italics (e.g. the 600 homepage tagline) keep the
   true italic letterforms with a synthesised weight bump, since no semibold/bold
   italic is bundled. Segoe UI is proprietary; self-hosting these files is the
   owner's call. */
@font-face { font-family: 'Segoe UI'; font-style: normal; font-weight: 400; font-display: swap; src: local('Segoe UI'), local('SegoeUI'), url('assets/fonts/segoe_ui_regular.woff') format('woff'); }
@font-face { font-family: 'Segoe UI'; font-style: italic; font-weight: 400; font-display: swap; src: local('Segoe UI Italic'), local('SegoeUI-Italic'), url('assets/fonts/segoe_ui_italic.woff') format('woff'); }
@font-face { font-family: 'Segoe UI'; font-style: normal; font-weight: 600; font-display: swap; src: local('Segoe UI Semibold'), local('SegoeUI-Semibold'), url('assets/fonts/segoe_ui_semibold.woff') format('woff'); }
@font-face { font-family: 'Segoe UI'; font-style: normal; font-weight: 700; font-display: swap; src: local('Segoe UI Bold'), local('SegoeUI-Bold'), url('assets/fonts/segoe_ui_bold.woff') format('woff'); }

/* Commit Mono, the monospace voice (data, code, gauges, the game HUD). Self-hosted
   and free. The whole site uses exactly THREE faces and no others: Century Supra
   (headings + editorial), Segoe UI (body + UI), and Commit Mono (everything
   monospaced). Regular / bold / italic are bundled. */
@font-face { font-family: 'Commit Mono'; font-style: normal; font-weight: 400; font-display: swap; src: url('assets/fonts/commit_mono_regular.woff2') format('woff2'); }
@font-face { font-family: 'Commit Mono'; font-style: normal; font-weight: 700; font-display: swap; src: url('assets/fonts/commit_mono_bold.woff2') format('woff2'); }
@font-face { font-family: 'Commit Mono'; font-style: italic; font-weight: 400; font-display: swap; src: url('assets/fonts/commit_mono_italic.woff2') format('woff2'); }

:root {
  --bg:              #303931;
  --bg-raised:       #1e2420;
  --text:            #E8E2D6;
  --text-bright:     #F5F1EA;
  --text-dim:        #B8B2A2;
  --accent:          #D4C4A0;
  --accent-hover:    #EDE0C0;
  --rule:            #4A544B;
  --row-hover:       rgba(245, 241, 234, 0.05);
  --selection-bg:    #5A6B5A;
  --selection-text:  #F5F1EA;
  --font-heading:    century_supra_a, 'Century Schoolbook', Palatino, Georgia, serif;
  --font-body:       'Segoe UI', system-ui, -apple-system, 'Helvetica Neue', Helvetica, sans-serif;
  --font-mono:       'Commit Mono', ui-monospace, Consolas, monospace;
  --content-width:   780px;
  --gutter:          1.25rem;
  --body-size:       1.2rem;
  --body-leading:    1.78;
}

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  background: var(--bg); color: var(--text);
  font-family: var(--font-body); font-size: var(--body-size);
  line-height: var(--body-leading); padding: 0 var(--gutter);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
::selection { background: var(--selection-bg); color: var(--selection-text); }

/* Reading progress */
.reading-progress { position: fixed; top: 0; left: 0; width: 0%; height: 2px; background: var(--accent); z-index: 1000; transition: width 60ms linear; pointer-events: none; }

/* Layout */
.site-wrapper { max-width: var(--content-width); margin: 0 auto; padding-top: 2.5rem; min-height: 100dvh; display: flex; flex-direction: column; }

/* -------------------------------------------------------
   HEADER: Big serif name + literary tagline
   ------------------------------------------------------- */
.site-header { margin-bottom: 3rem; animation: rise 1s cubic-bezier(0.23, 1, 0.32, 1) both; }
.site-name { font-weight: 700; margin-bottom: 0.5rem; line-height: 1; }
/* big serif name, lifted from the body-parts post cover h1 */
.site-name a {
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: clamp(2.6rem, 7.5vw, 3.9rem);
  line-height: 1.05;
  letter-spacing: -0.022em;
  color: var(--text-bright);
  text-decoration: none;
  text-wrap: balance;
  font-optical-sizing: auto;
  transition: color 0.2s ease-out;
}
.site-tagline { font-size: 1.2rem; font-style: italic; color: var(--text-dim); line-height: 1.5; margin-top: 0; max-width: 40ch; text-wrap: pretty; }
@keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .site-header { animation: none; }
  .article-list-item.fade-in { animation: none; opacity: 1; transform: none; }
}
.site-nav-links { display: flex; gap: 1.25rem; list-style: none; }
.site-nav-links a { font-size: 1rem; color: var(--text-dim); text-decoration: none; transition: color 0.25s; }
.site-nav-links a:hover { color: var(--text-bright); }

/* -------------------------------------------------------
   HOME: Article list
   Editorial column. Space (not rules) separates posts; each
   row is one link with a quiet hover wash. The serif titles
   lead; the landscape thumbnails stay quiet and keep their
   own natural height (varied, borderless).
   ------------------------------------------------------- */
.article-list { list-style: none; display: flex; flex-direction: column; gap: 0.5rem; }

/* The whole row is the link. Padding gives the hover wash a body; the matching
   negative side-margin lets the wash bleed into the gutter while the text stays
   on the same left spine as the name above. No layout shift on hover. */
.article-item {
  position: relative;
  display: block;
  text-decoration: none;
  padding: 1.35rem 1rem;
  margin: 0 -1rem;
  border-radius: 12px;
  /* Release: a plain decelerating ease-out, the row returns to its resting size
     and stops. No overshoot (the curve never goes past 1.0), so it does not
     bounce, that is the standard for a list-row/button tap. The quick press-in
     is overridden on .is-tapping; the image brightness shares this timing. */
  transition: transform 0.25s cubic-bezier(0.2, 0.8, 0.2, 1);
  -webkit-tap-highlight-color: transparent;
}
.article-item::after { content: ''; display: block; clear: both; }

/* Tap press (touch-only). The script adds .is-tapping while the finger is down
   and removes it on lift, so the row behaves like a physical button: the whole
   block presses in a touch, the image brightens a little, and the title warms
   to the same gold it takes on hover on desktop. Kept subtle. On lift the press
   springs back, the brightness settles on the same timing, and the title eases
   back like the desktop hover does.

   The 30ms transition-delay on every press-in property is the scroll guard: a
   quick scroll adds then removes .is-tapping inside this window, so nothing
   visually starts (no flash). It is short enough that even a fast tap registers
   the press. The release has no delay, so the settle is immediate. */
.article-item.is-tapping {
  transform: scale(0.982);
  transition: transform 0.09s cubic-bezier(0.4, 0, 0.6, 1) 0.03s;
}
.article-item.is-tapping .article-item-thumb img { filter: brightness(1.045); transition: filter 0.09s ease-out 0.03s; }
.article-item.is-tapping .article-item-title { color: var(--accent-hover); transition: color 0.09s ease-out 0.03s; }
.article-item:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px rgba(212, 196, 160, 0.5);
}
@media (hover: hover) {
  /* No row background on hover: the affordance is the content responding (the
     title eases to warm gold and the thumbnail leans), never a box. */
  .article-item:hover .article-item-title { color: var(--accent-hover); }
  .article-item:hover .article-item-thumb img { transform: scale(1.012); filter: brightness(1.03) saturate(1.02); }
}

.article-item-title {
  font-family: var(--font-heading);
  font-size: 1.5rem;
  font-weight: 400;
  color: var(--text-bright);
  line-height: 1.28;
  letter-spacing: -0.01em;
  margin-bottom: 0.32rem;
  text-wrap: balance;
  font-optical-sizing: auto;
  transition: color 0.18s ease-out;
}
.article-item-date { display: block; font-size: 0.82rem; color: var(--text-dim); letter-spacing: 0.04em; margin-bottom: 0.55rem; }
.article-item-description { font-size: 1.12rem; color: var(--text); font-style: italic; line-height: 1.58; text-wrap: pretty; }

/* thumbnail: borderless, landscape, keeping its own natural height (varied
   sizes, no frame, no mat). The wrapper clips a gentle hover scale.
   Phones stack the image above full-width text; from a comfortable reading
   width up it floats into a clean left column and the text wraps beside it,
   reclaiming the full width below. */
.article-item-thumb {
  display: block;
  width: 100%;
  margin: 0 0 0.9rem 0;
  border-radius: 4px;
  overflow: hidden;
}
.article-item-thumb img {
  display: block;
  width: 100%;
  height: auto;
  transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1), filter 0.25s ease-out;
}
@media (min-width: 560px) {
  .article-item-thumb {
    float: left;
    width: 150px;
    max-width: none;
    margin: 0.4rem 1.4rem 0.55rem 0;
    shape-outside: inset(0 round 4px);
  }
}

/* -------------------------------------------------------
   POST: Back link (top of article pages)
   ------------------------------------------------------- */
.post-back {
  display: inline-block;
  position: static;
  font-family: var(--font-body);
  font-size: 0.88rem;
  color: var(--text-dim);
  text-decoration: none;
  /* A plain link at the very top of the post: it sits in normal flow and
     scrolls away with the page rather than pinning to the viewport. */
  padding: 1rem 0 0.85rem;
  margin-bottom: 1.2rem;
  transition: color 0.25s;
}
.post-back .pb-label {
  display: inline;
}
.post-back .pb-label::before {
  content: '\2190';
  font-size: 0.82em;
  margin-right: 0.4em;
}
.post-back:hover { color: var(--text-bright); }
.post-back:focus-visible { outline: none; color: var(--text-bright); }
.post-back:focus-visible .pb-label {
  box-shadow: 0 0 0 2px rgba(212, 196, 160, 0.5);
  border-radius: 2px;
}

/* -------------------------------------------------------
   POST: Header (title + subtitle only)
   ------------------------------------------------------- */
.post-header { margin-bottom: 2rem; }
.post-title {
  font-family: var(--font-heading);
  font-size: min(2.8rem, 9vw);
  font-weight: 700;
  color: var(--text-bright);
  line-height: 1.12;
  margin-bottom: 0.6rem;
  letter-spacing: -0.015em;
}
.post-subtitle {
  font-family: var(--font-body);
  font-size: 1.1rem;
  font-style: italic;
  color: var(--text-dim);
  line-height: 1.5;
}

/* Post hero image (full-width before body) */
.post-hero { margin-bottom: 2.5rem; }
.post-hero img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 4px;
}
.post-hero figcaption {
  text-align: center;
  font-size: 0.88rem;
  color: var(--text-dim);
  margin-top: 0.5em;
  font-style: italic;
}

/* -------------------------------------------------------
   POST: Body
   ------------------------------------------------------- */
.post-body { flex: 1; }
.post-body p { margin-bottom: 1.4em; }
.post-body p:last-child { margin-bottom: 0; }
.post-body h2 { font-family: var(--font-heading); font-size: 1.65rem; font-weight: 700; color: var(--text-bright); margin-top: 2.8em; margin-bottom: 0.7em; line-height: 1.3; }
.post-body h3 { font-family: var(--font-heading); font-size: 1.3rem; font-weight: 700; color: var(--text-bright); margin-top: 2.2em; margin-bottom: 0.6em; line-height: 1.35; }
.post-body a { color: var(--accent); text-decoration: none; border-bottom: 1px solid transparent; transition: border-color 0.25s, color 0.25s; }
.post-body a:hover { color: var(--accent-hover); border-bottom-color: var(--accent-hover); }
.post-body em { font-style: italic; }
.post-body strong { font-weight: 600; color: var(--text-bright); }
.post-body blockquote { margin: 1.8em 0; padding: 0 0 0 1.4em; border-left: 2px solid var(--rule); color: var(--text); font-style: italic; opacity: 0.88; }
.post-body blockquote p { margin-bottom: 0.8em; }
.post-body blockquote p:last-child { margin-bottom: 0; }
.post-body .divider { text-align: center; margin: 2.5em 0; color: var(--text-dim); font-size: 1.1rem; letter-spacing: 0.6em; user-select: none; }
.post-body hr { border: none; border-top: 1px solid var(--rule); margin: 2.5em 0; }
.post-body code { font-family: var(--font-mono); font-size: 0.84em; background: rgba(255,255,255,0.06); padding: 0.15em 0.4em; border-radius: 3px; color: var(--text); }

/* Code blocks */
.post-body pre {
  position: relative;
  background: #141414;
  border: 2px solid #2a2a2a;
  border-radius: 18px;
  padding: 1.1em 1.3em;
  margin: 1.8em 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.post-body pre ::selection { background: rgba(82,139,255,0.25); color: inherit; }
.post-body pre ::-moz-selection { background: rgba(82,139,255,0.25); color: inherit; }
.post-body pre code { background: none; padding: 0; border-radius: 0; font-size: 0.88rem; line-height: 1.35; color: #dee2f7; font-family: var(--font-mono); border: none; }
/* Copy icon button */
.code-copy { position: absolute; top: 0.6em; right: 0.7em; background: transparent; border: none; cursor: pointer; padding: 0.3em; opacity: 0.25; transition: opacity 0.2s; display: flex; align-items: center; justify-content: center; }
.code-copy:hover { opacity: 0.6; }
.code-copy.copied { opacity: 0.8; }
.code-copy svg { width: 16px; height: 16px; stroke: #dee2f7; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.code-copy.copied svg { stroke: #54b4d0; }
/* Houston syntax colors (from screenshot) */
.post-body pre code .kw   { color: #c58bff; }
.post-body pre code .fn   { color: #54b4d0; }
.post-body pre code .str  { color: #7dd3a0; }
.post-body pre code .num  { color: #f0a76a; }
.post-body pre code .cm   { color: #4f5259; font-style: italic; }
.post-body pre code .var  { color: #dee2f7; }
.post-body pre code .prop { color: #add7ff; }
.post-body pre code .type { color: #54b4d0; }
.post-body pre code .tag  { color: #c58bff; }

.post-body ul, .post-body ol { margin: 1.2em 0; padding-left: 1.5em; }
.post-body li { margin-bottom: 0.4em; }
.post-body img { max-width: 100%; height: auto; display: block; margin: 2em auto; border-radius: 3px; }
.post-body figure { margin: 2.2em 0; }
.post-body figcaption { text-align: center; font-size: 0.88rem; color: var(--text-dim); margin-top: 0.6em; font-style: italic; }
.post-body .note { font-size: 0.95rem; color: var(--text-dim); line-height: 1.5; margin-top: 2em; }

/* ============================================================
   DEMO PANEL SYSTEM
   Warm, literary panels for interactive blocks. Same visual
   language as the rest of the site: forest green, parchment
   text, Century Supra serif, soft warm rules.

   Used by: .demo-wrapper, .pl-wrapper, .globe-wrapper, .game-wrapper.

   Design notes:
   - Serif (Century Supra) for labels, headings, button text.
   - System body font for descriptions.
   - Monospace ONLY for numerical readouts (FPS, slider values).
   - Soft 4px radius matching code blocks/hero.
   - Quiet corner accents (1px, dim).
   - Gentle accent (parchment) glow on focus/hover.
   ------------------------------------------------------------ */
:root {
  --d-mono: 'Commit Mono', ui-monospace, Consolas, monospace;
  /* Sit just slightly raised off the page bg (#303931) instead of crashing into black */
  --d-bg:           #2a322b;
  --d-bg-raised:    #232a25;
  --d-canvas-bg:    #1a201c;
  --d-rule:         #4A544B;          /* matches site --rule */
  --d-rule-strong:  #5a675c;
  --d-text:         #E8E2D6;          /* matches site --text */
  --d-text-dim:     #B8B2A2;          /* matches site --text-dim */
  --d-text-bright:  #F5F1EA;          /* matches site --text-bright */
  --d-accent:       #D4C4A0;          /* matches site --accent */
  --d-accent-strong:#EDE0C0;          /* matches site --accent-hover */
  --d-warn:         #d99090;
  --d-corner:       14px;
}

/* === Outer panel ===
   Shadow is a four-layer stack to feel like a real object on the page:
   1) a tight contact shadow that grounds the panel at its base,
   2) a soft mid-distance shadow for body weight,
   3) a wide low-opacity ambient shadow for atmosphere,
   4) an inset 1px highlight along the top to suggest light catching the
      edge of the panel.
   The shadow color is warm-dark (a deep version of the page's green)
   instead of pure black so it reads as belonging to this page rather
   than a generic UI card. */
.demo-wrapper, .pl-wrapper, .globe-wrapper, .game-wrapper {
  position: relative;
  margin: 3em 0;
  background: var(--d-bg);
  border: 1px solid var(--d-rule);
  border-radius: 4px;
  overflow: hidden;
  box-shadow:
    0 1px 2px rgba(12, 16, 13, 0.45),
    0 4px 10px -2px rgba(12, 16, 13, 0.35),
    0 18px 40px -16px rgba(8, 12, 9, 0.55),
    inset 0 1px 0 rgba(245, 241, 234, 0.04);
}


/* === Header bar === */
.demo-header, .pl-header, .game-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.7rem 0.9rem;
  flex-wrap: wrap;
  padding: 0.7em 1.2em;
  background: var(--d-bg-raised);
  border-bottom: 1px solid var(--d-rule);
  color: var(--d-text-dim),
}

.demo-header > span:not([class]),
.pl-header > span:not([class]),
.game-header > span:not([class]) {
  font-family: var(--font-heading);
  font-size: 0.92rem;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--d-text-dim);
  letter-spacing: 0;
}

.demo-label {
  font-family: var(--font-heading);
  font-size: 1.1rem;
  font-weight: 700;
  letter-spacing: 0.005em;
  text-transform: none;
  color: var(--d-text-bright);
  position: relative;
  padding-bottom: 0.3em;
  border-bottom: 1px solid var(--d-accent);
}

/* FPS / counters — use body font with old-style figures (oldstyle-nums)
   for an elegant, classical feel. Tabular for stable width. */
.demo-fps, .p-fps, .pl-fps, .pl-particle-count {
  font-family: var(--font-heading);
  font-size: 0.92rem;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--d-text-dim);
  letter-spacing: 0;
  text-transform: none;
}

/* === Hint text overlays === */
.demo-hint, .p-hint, .pl-canvas-hint {
  position: absolute;
  bottom: 14px; left: 50%;
  transform: translateX(-50%);
  font-family: var(--font-body);
  font-size: 0.85rem;
  font-style: italic;
  letter-spacing: 0.01em;
  text-transform: none;
  color: rgba(245, 241, 234, 0.45);
  pointer-events: none;
  transition: opacity 0.5s ease;
  white-space: nowrap;
  z-index: 3;
}
.demo-hint::before, .p-hint::before, .pl-canvas-hint::before {
  content: '';
  margin: 0;
}

/* Globe info: top-left, multi-line */
.globe-info {
  position: absolute;
  top: 14px; left: 16px;
  font-family: var(--font-heading);
  font-size: 0.85rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: rgba(245, 241, 234, 0.5);
  line-height: 1.7;
  pointer-events: none;
  z-index: 2;
  font-variant-numeric: tabular-nums;
}

/* === Control strip === */
.p-controls, .globe-controls {
  background: var(--d-bg-raised);
  border-top: 1px solid var(--d-rule);
  color: var(--d-text);
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
  padding: 1.1rem 1.25rem 1.2rem;
}
.p-controls-header {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 0.15rem;
  min-height: 1.4em;
}

/* === Sliders (unified for .p-, .pl-, .globe-) === */
.p-slider-row, .pl-slider-row, .globe-slider-row {
  display: flex;
  align-items: center;
  gap: 0.95rem;
}
.p-slider-row label,
.pl-slider-row label,
.globe-slider-row label {
  font-family: var(--font-heading);
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: 0.005em;
  text-transform: none;
  color: var(--d-text);
  min-width: 5.5em;
}
.p-slider-val, .pl-slider-val, .globe-date-display {
  font-family: var(--font-heading);
  font-size: 0.95rem;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--d-accent-strong);
  min-width: 4em;
  text-align: right;
}

/* Slider track + thumb. A slim warm track with a parchment thumb. */
.p-slider-row input[type="range"],
.pl-slider-row input[type="range"],
.globe-slider-row input[type="range"] {
  flex: 1;
  -webkit-appearance: none; appearance: none;
  height: 20px;
  background: transparent;
  cursor: pointer;
  outline: none;
  margin: 0;
  padding: 0;
}
.p-slider-row input[type="range"]::-webkit-slider-runnable-track,
.pl-slider-row input[type="range"]::-webkit-slider-runnable-track,
.globe-slider-row input[type="range"]::-webkit-slider-runnable-track {
  height: 2px;
  background: var(--d-rule);
  border-radius: 1px;
}
.p-slider-row input[type="range"]::-webkit-slider-thumb,
.pl-slider-row input[type="range"]::-webkit-slider-thumb,
.globe-slider-row input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 14px;
  margin-top: -6px;
  background: var(--d-accent);
  border-radius: 50%;
  border: none;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.25), 0 1px 2px rgba(0,0,0,0.3);
  transition: background 0.15s, box-shadow 0.15s, transform 0.1s;
}
.p-slider-row input[type="range"]:hover::-webkit-slider-thumb,
.pl-slider-row input[type="range"]:hover::-webkit-slider-thumb,
.globe-slider-row input[type="range"]:hover::-webkit-slider-thumb,
.p-slider-row input[type="range"]:focus::-webkit-slider-thumb,
.pl-slider-row input[type="range"]:focus::-webkit-slider-thumb,
.globe-slider-row input[type="range"]:focus::-webkit-slider-thumb {
  background: var(--d-accent-strong);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.25), 0 0 0 4px rgba(212,196,160,0.18);
  transform: scale(1.05);
}
.p-slider-row input[type="range"]::-moz-range-track,
.pl-slider-row input[type="range"]::-moz-range-track,
.globe-slider-row input[type="range"]::-moz-range-track {
  height: 2px;
  background: var(--d-rule);
  border: none;
  border-radius: 1px;
}
.p-slider-row input[type="range"]::-moz-range-thumb,
.pl-slider-row input[type="range"]::-moz-range-thumb,
.globe-slider-row input[type="range"]::-moz-range-thumb {
  width: 14px; height: 14px;
  background: var(--d-accent);
  border: none; border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(0,0,0,0.25), 0 1px 2px rgba(0,0,0,0.3);
}
.p-slider-row input[type="range"]:hover::-moz-range-thumb,
.pl-slider-row input[type="range"]:hover::-moz-range-thumb,
.globe-slider-row input[type="range"]:hover::-moz-range-thumb {
  background: var(--d-accent-strong);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.25), 0 0 0 4px rgba(212,196,160,0.18);
}

/* === Buttons (general) === */
.p-reset, .pl-btn, #globe-reset {
  font-family: var(--font-heading);
  font-size: 0.92rem;
  font-weight: 400;
  letter-spacing: 0.01em;
  text-transform: none;
  color: var(--d-text);
  background: transparent;
  border: 1px solid var(--d-rule-strong);
  border-radius: 3px;
  padding: 0.42em 1.05em;
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.p-reset:hover, .pl-btn:hover, #globe-reset:hover {
  color: var(--d-bg);
  border-color: var(--d-accent);
  background: var(--d-accent);
}
.p-reset:active, .pl-btn:active, #globe-reset:active { transform: translateY(1px); }

/* Reset button gets a small reload glyph */
.p-reset::before, #globe-reset::before {
  content: '↻';
  margin-right: 0.4em;
  font-size: 1em;
  opacity: 0.75;
  letter-spacing: 0;
}

/* === Segmented control groups (TZ, tilt) === */
.tz-group, .tilt-group {
  display: inline-flex;
  border: 1px solid var(--d-rule-strong);
  border-radius: 3px;
  overflow: hidden;
}
.tilt-group { flex: 1; }
.tz-btn, .tilt-btn {
  font-family: var(--font-heading);
  font-size: 0.9rem;
  font-weight: 400;
  letter-spacing: 0.005em;
  text-transform: none;
  color: var(--d-text-dim);
  background: transparent;
  border: none;
  border-right: 1px solid var(--d-rule-strong);
  padding: 0.42em 1em;
  cursor: pointer;
  transition: color 0.2s, background 0.2s;
}
.tz-btn:last-child, .tilt-btn:last-child { border-right: none; }
.tz-btn:hover, .tilt-btn:hover {
  color: var(--d-text-bright);
  background: rgba(212,196,160,0.08);
}
.tz-btn.active, .tilt-btn.active {
  color: var(--d-bg);
  background: var(--d-accent);
}
.tilt-btn { flex: 1; padding-left: 0.4em; padding-right: 0.4em; text-align: center; }

/* Tilt row & description */
.controls-top {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; margin-bottom: 0.3rem;
}
.tilt-row {
  display: flex; align-items: center;
  gap: 0.95rem;
  margin-top: 0.15rem;
}
.tilt-row-label {
  font-family: var(--font-heading);
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: 0.005em;
  text-transform: none;
  color: var(--d-text);
  min-width: 5.5em;
}
.tilt-desc-text {
  font-family: var(--font-body);
  font-size: 0.95rem;
  font-style: italic;
  color: var(--d-text-dim);
  padding: 0.5rem 0 0;
  line-height: 1.55;
  letter-spacing: 0;
}
.tilt-desc-text::before {
  content: '';
  margin: 0;
}

/* === Daylight panel === */
.daylight-panel {
  margin: 0;
  padding: 1.05rem 1.25rem 1.15rem;
  border-top: 1px solid var(--d-rule);
  background: var(--d-bg-raised);
}
.daylight-label {
  font-family: var(--font-heading);
  font-size: 1rem;
  font-weight: 400;
  color: var(--d-text-bright);
  letter-spacing: 0.005em;
  margin-bottom: 0.55rem;
  font-variant-numeric: tabular-nums;
}
.daylight-bar-wrap {
  position: relative;
  width: 100%; height: 10px;
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: 0.4rem;
  border: 1px solid var(--d-rule-strong);
}
.daylight-bar-wrap canvas { width: 100%; height: 100%; display: block; border-radius: 0; }
.daylight-bar-ticks {
  display: flex; justify-content: space-between;
  font-family: var(--font-heading);
  font-size: 0.78rem;
  font-weight: 400;
  letter-spacing: 0;
  color: var(--d-text-dim);
  padding: 0 1px;
  margin-bottom: 0.35rem;
  font-variant-numeric: tabular-nums;
}
.daylight-sub {
  font-family: var(--font-body);
  font-size: 0.92rem;
  font-style: italic;
  color: var(--d-text-dim);
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

/* === Globe canvas area === */
.globe-canvas-area {
  position: relative;
  width: 100%; aspect-ratio: 4/3;
  cursor: grab; touch-action: none; overflow: hidden;
  background: var(--d-canvas-bg);
}
.globe-canvas-area:active { cursor: grabbing; }
.globe-canvas-area canvas { display: block; width: 100%; height: 100%; }

/* === Particle demo canvas === */
.demo-canvas-wrapper {
  position: relative;
  width: 100%; height: 420px;
  background: var(--d-canvas-bg);
  cursor: pointer;
  touch-action: none;
  overflow: hidden;
}
.demo-canvas-wrapper .render-dot {
  position: absolute;
  width: 1px; height: 1px;
  border-radius: 50%;
  top: 0; left: 0;
  pointer-events: none;
}

/* ============================================================
   PAGE-SPECIFIC OVERRIDES
   These re-skin per-page <style> blocks (particle-life,
   Sluice) without touching the HTML. Higher specificity
   so they win over inline page styles.
   ============================================================ */

/* --- particle-life: section headings --- */
.pl-wrapper .pl-control-group h4,
.pl-wrapper .pl-slot-section h4 {
  font-family: var(--font-heading) !important;
  font-size: 1rem !important;
  font-weight: 700 !important;
  letter-spacing: 0.005em !important;
  text-transform: none !important;
  color: var(--d-text-bright) !important;
  margin: 0 0 0.85rem 0;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--d-rule);
}
.pl-wrapper .pl-control-group h4::before,
.pl-wrapper .pl-slot-section h4::before {
  content: '' !important;
  margin: 0 !important;
}

/* --- particle-life: explainer / hint paragraphs --- */
.pl-wrapper .pl-matrix-explainer,
.pl-wrapper .pl-slot-hint {
  font-family: var(--font-body) !important;
  font-size: 0.95rem !important;
  font-style: italic;
  line-height: 1.55 !important;
  color: var(--d-text-dim) !important;
  letter-spacing: 0 !important;
  margin: 0.85rem 0 0;
}
.pl-wrapper .pl-matrix-explainer strong,
.pl-wrapper .pl-slot-hint strong {
  color: var(--d-text-bright) !important;
  font-weight: 600 !important;
  font-style: normal;
}

/* --- particle-life: toggle checkboxes --- */
.pl-wrapper .pl-toggle {
  font-family: var(--font-heading) !important;
  font-size: 0.92rem !important;
  font-weight: 400 !important;
  letter-spacing: 0.005em !important;
  text-transform: none !important;
  color: var(--d-text) !important;
}
.pl-wrapper .pl-toggle:hover { color: var(--d-text-bright) !important; }
.pl-wrapper .pl-toggle input[type="checkbox"] {
  width: 15px !important; height: 15px !important;
  border-radius: 3px !important;
  border-color: var(--d-rule-strong) !important;
}
.pl-wrapper .pl-toggle input[type="checkbox"]:checked {
  background: var(--d-accent) !important;
  border-color: var(--d-accent) !important;
}

/* --- particle-life: prominent randomize button --- */
.pl-wrapper .pl-btn-prominent {
  font-family: var(--font-heading) !important;
  font-size: 1.05rem !important;
  font-weight: 700 !important;
  letter-spacing: 0.005em !important;
  text-transform: none !important;
  padding: 0.55em 1.8em !important;
  border-radius: 3px !important;
  color: var(--d-bg) !important;
  background: var(--d-accent) !important;
  border: 1px solid var(--d-accent) !important;
}
.pl-wrapper .pl-btn-prominent:hover {
  background: var(--d-accent-strong) !important;
  border-color: var(--d-accent-strong) !important;
  color: var(--d-bg) !important;
}

/* --- particle-life: unlock button (header) --- */
.pl-wrapper .pl-header .pl-unlock {
  font-family: var(--font-heading) !important;
  font-size: 0.85rem !important;
  font-weight: 400 !important;
  letter-spacing: 0.005em !important;
  text-transform: none !important;
  border-radius: 3px !important;
  padding: 0.32em 0.95em !important;
}
.pl-wrapper .pl-header .pl-unlock-msg {
  font-family: var(--font-body) !important;
  font-style: italic;
  font-size: 0.85rem !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
}

/* --- particle-life: save slots --- */
.pl-wrapper .pl-slot {
  width: 30px !important; height: 30px !important;
  border-radius: 3px !important;
  font-family: var(--d-mono) !important;
  font-size: 0.78rem !important;
  border-color: var(--d-rule-strong) !important;
  color: var(--d-text-dim) !important;
}
.pl-wrapper .pl-slot:hover {
  color: var(--d-text-bright) !important;
  border-color: var(--d-accent) !important;
}
.pl-wrapper .pl-slot.pl-slot-filled {
  background: rgba(212,196,160,0.15) !important;
  border-color: var(--d-accent) !important;
  color: var(--d-accent-strong) !important;
}
.pl-wrapper .pl-slot-share {
  font-family: var(--d-mono) !important;
  font-size: 0.82rem !important;
  border-radius: 3px !important;
  padding: 0.45em 0.75em !important;
  background: rgba(0,0,0,0.20) !important;
  border-color: var(--d-rule-strong) !important;
  color: var(--d-text) !important;
}
.pl-wrapper .pl-slot-share:focus { border-color: var(--d-accent) !important; }
.pl-wrapper .pl-slot-msg {
  font-family: var(--font-body) !important;
  font-style: italic;
  font-size: 0.88rem !important;
  letter-spacing: 0 !important;
  color: var(--d-text-dim) !important;
}

/* --- particle-life: status text on canvas --- */
.pl-wrapper .pl-status {
  font-family: var(--font-body) !important;
  font-style: italic;
  font-size: 0.95rem !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  color: var(--d-text-dim) !important;
}

/* --- Sluice: control info row at bottom of canvas --- */
.game-wrapper .game-controls-info {
  font-family: var(--font-heading) !important;
  font-size: 0.92rem !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  color: var(--d-text-dim) !important;
}
.game-wrapper .game-controls-info .key {
  font-family: var(--d-mono) !important;
  font-size: 0.78rem !important;
  border-radius: 3px !important;
  border-color: var(--d-rule-strong) !important;
  color: var(--d-text) !important;
  background: rgba(0,0,0,0.15) !important;
}
.game-wrapper .game-controls-info .action {
  font-family: var(--font-body) !important;
  font-style: italic !important;
  font-size: 0.92rem !important;
  text-transform: none !important;
  letter-spacing: 0 !important;
  color: var(--d-text-dim) !important;
  margin-left: 0.35em !important;
  margin-right: 0.5em !important;
}

/* --- daylight-globe: tilt-note inside tilt-btn --- */
.globe-wrapper .tilt-btn .tilt-note {
  font-family: var(--font-body) !important;
  font-style: italic !important;
  font-size: 0.78rem !important;
  letter-spacing: 0 !important;
  text-transform: none !important;
  opacity: 0.75;
}
.globe-wrapper .tilt-btn.active .tilt-note {
  color: rgba(42, 50, 43, 0.75) !important;
}

/* Site footer */
/* padding-bottom reserves a clear strip below the footer for the floating
   back-to-top button (js/backtotop.js), so its centered arrow never lands on
   the footer rule or the copyright line. This lives on the footer (not the
   wrapper) so the full-bleed cover posts, which have no .site-wrapper, get the
   same clearance. */
.site-footer { margin-top: auto; padding-top: 3.5rem; padding-bottom: 4rem; }
.site-footer-inner { border-top: 1px solid var(--rule); padding-top: 1.5rem; padding-bottom: 1rem; display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 0.4rem 1.5rem; font-size: 0.88rem; color: var(--text-dim); }
.site-footer a { color: var(--text-dim); text-decoration: none; transition: color 0.25s; }
.site-footer a:hover { color: var(--text-bright); }
.footer-links { display: flex; gap: 1rem; }

/* Fade-in */
.fade-in { opacity: 0; transform: translateY(10px); animation: fadeUp 0.5s ease forwards; }
@keyframes fadeUp { to { opacity: 1; transform: translateY(0); } }
.article-list-item:nth-child(1) { animation-delay: 0.05s; }
.article-list-item:nth-child(2) { animation-delay: 0.11s; }
.article-list-item:nth-child(3) { animation-delay: 0.17s; }
.article-list-item:nth-child(4) { animation-delay: 0.23s; }
.article-list-item:nth-child(5) { animation-delay: 0.29s; }
.article-list-item:nth-child(6) { animation-delay: 0.35s; }
.article-list-item:nth-child(7) { animation-delay: 0.41s; }

/* Desktop */
@media (min-width: 720px) {
  :root { --gutter: 2rem; --body-size: 1.25rem; }
  .site-wrapper { padding-top: 4rem; padding-bottom: 5rem; }
  .site-header { margin-bottom: 3.5rem; }
  .post-title { font-size: min(3.2rem, 7vw); }
  .post-body h2 { font-size: 1.75rem; }
  .demo-canvas-wrapper { height: 500px; }
  .article-item-thumb { width: 200px; margin-right: 1.7rem; }
  .article-item-title { font-size: 1.6rem; }
  .article-item-description { font-size: 1.15rem; }
}

@media (min-width: 1024px) {
  :root { --gutter: 2.5rem; --body-size: 1.28rem; }
  .site-wrapper { padding-top: 5rem; }
}

@media print {
  body { background: #fff; color: #222; }
  .reading-progress, .site-nav-links, .site-footer,
  .demo-wrapper, .globe-wrapper, .pl-wrapper, .game-wrapper { display: none; }
  .post-body a { color: #222; text-decoration: underline; border-bottom: none; }
}
