/* ariatone.com: the landing page (docs/adr/0002), the apps' pages (docs/adr/0006), the dev blog (docs/adr/0004) and the
   404 page, one stylesheet for all. Plain CSS, no build step and nothing of ours that runs: the CSP (public/_headers)
   allows this file, the fonts, the images and Cloudflare's visitor-count beacon, and nothing else (no inline styles,
   no scripts of ours). */

/* The fonts the apps use, served from here rather than Google's servers, so a visit tells nobody else (OFL, licenses
   beside them in fonts/). */
@font-face { font-family: 'Chakra Petch'; font-weight: 300; font-display: swap; src: url('/fonts/chakra-petch-latin-300-normal.woff2') format('woff2'); }
@font-face { font-family: 'Chakra Petch'; font-weight: 500; font-display: swap; src: url('/fonts/chakra-petch-latin-500-normal.woff2') format('woff2'); }
@font-face { font-family: 'Chakra Petch'; font-weight: 600; font-display: swap; src: url('/fonts/chakra-petch-latin-600-normal.woff2') format('woff2'); }
@font-face { font-family: 'IBM Plex Sans'; font-weight: 400; font-display: swap; src: url('/fonts/ibm-plex-sans-latin-400-normal.woff2') format('woff2'); }
@font-face { font-family: 'IBM Plex Sans'; font-weight: 500; font-display: swap; src: url('/fonts/ibm-plex-sans-latin-500-normal.woff2') format('woff2'); }
@font-face { font-family: 'IBM Plex Mono'; font-weight: 400; font-display: swap; src: url('/fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2'); }

/* The apps' neon tokens: a copy of the few this page needs from @ariatone/ui's base.css (ariatone-audio). Keep the
   values in step when the apps' change. */
:root {
  --ink: #04060c;
  --panel-rgb: 7 9 18;
  --line-rgb: 176 200 255;
  --line: rgb(var(--line-rgb) / 0.11);
  --text: #e8edf8;
  --muted: #8f9bbb;
  --dim: #56617f;
  --accent: #5eeaff;
  --accent-rgb: 94 234 255;
  --accent-2: #ff52cf;
  --accent-2-rgb: 255 82 207;
  --amber: #ffb35c;
  --on-accent: #0b0a14;
  --brand-gradient: linear-gradient(90deg, var(--accent), var(--accent-2));
  --font-display: 'Chakra Petch', 'Avenir Next Condensed', 'Arial Narrow', sans-serif;
  --font-brand: 'Chakra Petch', 'Avenir Next Condensed', 'Arial Narrow', sans-serif;
  --font-body: 'IBM Plex Sans', -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;
  --r: 14px;
  --gutter: max(16px, env(safe-area-inset-left), env(safe-area-inset-right));
  color-scheme: dark;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body {
  margin: 0;
  background: var(--ink);
  color: var(--text);
  font: 16px/1.6 var(--font-body);
  -webkit-font-smoothing: antialiased;
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
h1, h2, h3 { margin: 0; font-weight: 500; }
p { margin: 0; }

.wrap { width: 100%; max-width: 1200px; margin: 0 auto; padding-inline: var(--gutter); }

/* ---------- the hero: a still of Sanctuary, its waveform across the middle; the words sit in the dark above it ---------- */
/* How far the apps section rises into the hero's foot (2026-10-14: its kicker 10 to 20% up from the bottom of
   the first screen) */
:root { --rise: 15svh; }
.hero { position: relative; min-height: 100vh; min-height: 100svh; display: grid; }
.hero-art, .hero-art img { position: absolute; inset: 0; width: 100%; height: 100%; }
/* the picture fades into the page toward its foot, under the rising apps section: at full strength down past the
   waveform, then eased out to nothing at the bottom */
.hero-art {
  -webkit-mask-image: linear-gradient(180deg, #000 58%, rgb(0 0 0 / 0.82) 70%, rgb(0 0 0 / 0.45) 82%, rgb(0 0 0 / 0.15) 92%, transparent);
  mask-image: linear-gradient(180deg, #000 58%, rgb(0 0 0 / 0.82) 70%, rgb(0 0 0 / 0.45) 82%, rgb(0 0 0 / 0.15) 92%, transparent);
}
/* centered both ways, so whatever the screen's shape, the waveform stays across its middle */
.hero-art img { object-fit: cover; object-position: 50% 50%; }
/* Sanctuary at 37.5% of its still's brightness (2026-10-16: half, then a quarter darker than that), so the Jam
   Room over it stands out a little */
.hero-art img { filter: brightness(0.375); }
/* The Jam Room (scripts/room.mjs: ariatone-mix's own scene; 2026-10-16, in place of the studio gear: the first
   screen says "a musician's tool" as well as "visuals"). Its band stands below the words, on Sanctuary's floor behind
   the waveform; screened, so its dark leaves Sanctuary as it is and only its lines and light lie over it. Its ceiling
   and string lights fade behind the words, and it fades with Sanctuary toward the foot. */
.hero-room, .hero-room img { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero-room img { object-fit: cover; object-position: 50% 50%; }
.hero-room {
  pointer-events: none; mix-blend-mode: screen;
  -webkit-mask-image: linear-gradient(180deg, rgb(0 0 0 / 0.45), #000 36%, #000 58%, rgb(0 0 0 / 0.82) 70%, rgb(0 0 0 / 0.45) 82%, rgb(0 0 0 / 0.15) 92%, transparent);
  mask-image: linear-gradient(180deg, rgb(0 0 0 / 0.45), #000 36%, #000 58%, rgb(0 0 0 / 0.82) 70%, rgb(0 0 0 / 0.45) 82%, rgb(0 0 0 / 0.15) 92%, transparent);
}
/* held upright, the room is seen from higher and its ceiling's back edge falls just under the buttons: it comes up
   out of the dark instead */
@media (max-aspect-ratio: 23/20) {
  .hero-room {
    -webkit-mask-image: linear-gradient(180deg, rgb(0 0 0 / 0.15) 38%, #000 54%, #000 58%, rgb(0 0 0 / 0.82) 70%, rgb(0 0 0 / 0.45) 82%, rgb(0 0 0 / 0.15) 92%, transparent);
    mask-image: linear-gradient(180deg, rgb(0 0 0 / 0.15) 38%, #000 54%, #000 58%, rgb(0 0 0 / 0.82) 70%, rgb(0 0 0 / 0.45) 82%, rgb(0 0 0 / 0.15) 92%, transparent);
  }
}
/* Two equal halves: the words in the top one, down to just above the waveform, and the picture's floor below it, where
   the apps section rises in. Where the words take more than half the screen (a phone held sideways, a short window),
   both halves grow with them, so the waveform, in the middle of the picture, still runs below the words, and the
   section still covers only the empty floor (2026-10-14: it ran through the lede) */
.hero-inner { position: relative; display: grid; grid-template-rows: 1fr 1fr; }
.hero-top { display: flex; flex-direction: column; justify-content: space-between; gap: 14px; padding-top: max(18px, env(safe-area-inset-top)); padding-bottom: clamp(28px, 6vh, 64px); }

.topbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.brand { display: flex; align-items: center; text-decoration: none; }
.brand .wordmark { font-size: 19px; }
/* the AriaTone logo (docs/adr/0003), as @ariatone/ui's Wordmark draws it in the apps (its base.css): ARIA light, the
   wave, TONE semibold, every measure in em */
.wordmark { display: inline-block; font: 600 17px/1 var(--font-brand); letter-spacing: 0.14em; white-space: nowrap; color: var(--text); }
.wordmark-aria { font-weight: 300; }
.wordmark-wave { display: inline-block; width: 1.13em; height: 0.78em; margin: 0 0.42em 0 0.28em; vertical-align: -0.06em; overflow: visible; }
.wordmark-from { stop-color: var(--accent); }
.wordmark-to { stop-color: var(--accent-2); }
/* the trademark claim after TONE (™, never ®, until the mark is registered), on a page's first logo only */
.wordmark-tm { position: relative; top: -1.05em; margin-left: -0.06em; font-size: 0.4em; font-weight: 300; letter-spacing: 0; color: var(--muted); }
/* beside the logo, the way back to each app (2026-10-18): its name set as the app's own top bar sets it beside
   the same logo (@ariatone/ui's .brand-app), so a listener who tapped the logo in an app and landed here finds their
   app at a glance, on a phone too */
.brand-row { display: flex; align-items: baseline; gap: 12px; min-width: 0; }
.brand-apps { display: flex; align-items: baseline; margin: 0; padding: 0; list-style: none; }
/* a hairline between the two, so they read as two apps, never one "Mix Radio" */
.brand-apps li + li { display: flex; align-items: baseline; }
.brand-apps li + li::before { content: ''; align-self: center; width: 1px; height: 11px; margin-inline: 12px; background: rgb(var(--line-rgb) / 0.3); }
.brand-apps a { font: 500 12px/1 var(--font-display); letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); text-decoration: none; }
.brand-apps a:hover { color: var(--text); }
/* a finger needs about 44 px: the hit area reaches past the words, unseen, as the apps' controls do */
@media (pointer: coarse) {
  .brand-apps a { position: relative; }
  .brand-apps a::after { content: ''; position: absolute; inset: -16px -6px; }
}
.nav { display: flex; gap: 28px; margin: 0; padding: 0; list-style: none; }
.nav a { font: 500 12px/1 var(--font-display); letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); text-decoration: none; }
.nav a:hover { color: var(--text); }
@media (max-width: 720px) { .nav { display: none; } }

.hero-copy { max-width: 640px; }
h1 { font-size: clamp(30px, 5.2vw, 54px); line-height: 1.12; letter-spacing: -0.012em; }
.lede { margin-top: 16px; max-width: 34em; color: var(--muted); font-size: clamp(16px, 1.6vw, 19px); }
.lede-bright { color: var(--text); } /* a phrase lifted to the headings' color */
.hero-links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 24px; }

/* a chip: a quiet button with a hairline edge, as in the apps */
.chip {
  display: inline-flex; align-items: center; gap: 0.45em; min-height: 40px; padding: 0 18px;
  border: 1px solid rgb(var(--line-rgb) / 0.22); border-radius: 999px; background: rgb(var(--panel-rgb) / 0.55);
  font: 500 12px/1 var(--font-display); letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); text-decoration: none;
}
.chip-brand { color: var(--text); }
.chip:hover { border-color: rgb(var(--accent-rgb) / 0.55); }

/* ---------- sections ---------- */
.section { padding-top: clamp(72px, 11vw, 128px); }
/* the apps section rises --rise into the hero's faded foot (positioned, so it paints over the hero's picture); a jump
   to it from the nav still leaves room above its kicker */
.section.rises { position: relative; margin-top: calc(-1 * var(--rise)); padding-top: 0; scroll-margin-top: clamp(24px, 5vw, 56px); }
.rises > .kicker, .rises > h2 { text-shadow: 0 0 2px rgb(4 6 12 / 0.7), 0 1px 12px rgb(4 6 12 / 0.9); }
/* its heading is a long sentence: lines of even length, not one long and one short */
.rises > h2 { text-wrap: balance; }
.kicker { font: 500 12px/1 var(--font-display); letter-spacing: 0.2em; text-transform: uppercase; color: var(--amber); }
h2 { margin-top: 14px; font-size: clamp(26px, 3.4vw, 38px); line-height: 1.2; letter-spacing: -0.008em; }
.section-lede { margin-top: 16px; max-width: 40em; color: var(--muted); font-size: 17px; }

/* ---------- the apps ---------- */
/* the two cards stand apart, so they read as two apps rather than one panel (2026-10-15; 24px until then) */
.apps { display: grid; grid-template-columns: minmax(0, 1fr); gap: 44px; margin-top: 40px; }
@media (min-width: 900px) { .apps { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(48px, 5vw, 72px); } }
/* Each card is a small screen of its app: the look behind it, the name above the waveform as the hero's headline is,
   and the details on a glass panel below it, as the apps' panels sit over their visuals. The still is as wide as the
   card (so its waveform is always the same share of the way down) and fades into the card's ink at its foot. */
.app { container-type: inline-size; position: relative; isolation: isolate; display: flex; flex-direction: column; border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; background: var(--ink); }
.app-art {
  position: absolute; top: 0; left: 0; z-index: -1; width: 100%; height: auto;
  -webkit-mask-image: linear-gradient(180deg, #000 70%, transparent); mask-image: linear-gradient(180deg, #000 70%, transparent);
}
/* down to just past the waveform: the stills are 600 x 800 with it 26% of the way down (--center 0.74), so 35% of the
   card's width; the panel's margin leaves it in view */
.app-head { display: flex; flex-direction: column; gap: 10px; gap: clamp(10px, 2.2cqi, 16px); aspect-ratio: 600 / 214; padding: 22px clamp(20px, 3vw, 32px) 0; padding-top: clamp(22px, 4.6cqi, 34px); }
/* the name and its line sit on the look itself: a soft shadow keeps them clear of its brightest lines */
.app-head > * { text-shadow: 0 0 2px rgb(4 6 12 / 0.7), 0 1px 12px rgb(4 6 12 / 0.9); }
.app-body {
  display: flex; flex-direction: column; gap: 14px; flex: 1; margin: 18px 12px 12px; padding: 22px clamp(16px, 2.4vw, 24px) 22px;
  border: 1px solid var(--line); border-radius: 10px; color: var(--muted);
  background: rgb(var(--panel-rgb) / 0.66); -webkit-backdrop-filter: blur(14px) saturate(1.1); backdrop-filter: blur(14px) saturate(1.1);
}
.lockup { display: flex; align-items: baseline; gap: 9px; gap: clamp(9px, 2cqi, 14px); font: 600 20px/1 var(--font-display); letter-spacing: 0.14em; text-transform: uppercase; }
/* The name and its line grow with the card (cqi: a hundredth of its width), to fill the look above the waveform
   (2026-10-14): on a phone's card they're as they were, where they already reach the waveform */
.lockup .wordmark { font-size: 20px; font-size: clamp(20px, 5.6cqi, 34px); }
.lockup-app { font-size: 14px; font-size: clamp(14px, 3.6cqi, 22px); letter-spacing: 0.16em; color: var(--accent); }
.app-line { font-size: 19px; font-size: clamp(19px, 4.9cqi, 30px); line-height: 1.4; color: var(--text); text-wrap: balance; }
/* A word and what it means, a row each, as Mix's tiers and Radio's features: the words share a column as wide as the
   longest of them (76 px at least, so Mix's tiers line up as they always have; 96 px in a browser without subgrid) */
.terms { margin: 0; display: grid; grid-template-columns: minmax(76px, max-content) minmax(0, 1fr); column-gap: 12px; border-top: 1px solid var(--line); }
.terms div { display: grid; grid-column: 1 / -1; grid-template-columns: 96px minmax(0, 1fr); grid-template-columns: subgrid; column-gap: 12px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.terms dt { font: 500 12px/1.9 var(--font-display); letter-spacing: 0.16em; text-transform: uppercase; color: var(--text); }
.terms dd { margin: 0; font-size: 15px; }
/* the Open button and, beside it, the way to the app's own page (the landing page's cards), at the foot of the card */
.app-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 22px; margin-top: auto; padding-top: 10px; }
/* the gradient button: the one main action, as in the apps */
.button {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 22px; border-radius: 999px;
  font: 600 13px/1 var(--font-display); letter-spacing: 0.14em; text-transform: uppercase; color: var(--on-accent); text-decoration: none;
  background: var(--brand-gradient);
  box-shadow: 0 0 22px rgb(var(--accent-2-rgb) / 0.28), 0 0 4px rgb(var(--accent-rgb) / 0.5);
}
.fine { font-size: 13px; color: var(--dim); }
.fine a { color: var(--muted); }

/* ---------- underneath: the shared parts ---------- */
.parts { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 48px; margin: 40px 0 0; padding: 0; list-style: none; }
@media (min-width: 760px) { .parts { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.part { padding: 24px 0 28px; border-top: 1px solid var(--line); }
.part-label { font: 400 12px/1 var(--font-mono); letter-spacing: 0.04em; color: var(--accent); }
.part h3 { margin-top: 12px; font-size: 20px; line-height: 1.3; }
.part p:last-child { margin-top: 10px; color: var(--muted); }
/* Columns side by side end together (2026-10-18: "I want to see uniform height columns of text whenever
   possible"). Each column's label, heading and words take the row's own three tracks (a subgrid), so where one
   heading wraps and its neighbor's doesn't, the words beside it still start on the same line; the words are written to
   take as many lines as their neighbors' (test/layout.test.mjs counts them). The same for the priorities and the dev
   blog's newest entries, whose "Read more" links then line up. */
@supports (grid-template-rows: subgrid) {
  .parts > .part, .priorities > li, .post-list-home > .post-card { display: grid; grid-row: span 3; grid-template-rows: subgrid; }
}

/* An app page's three-part rows side by side on a wide screen, then a closing line */
@media (min-width: 900px) { .parts-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.section-close { margin-top: 28px; max-width: 40em; font-size: 19px; line-height: 1.5; color: var(--text); text-wrap: balance; }

/* ---------- the looks: stills side by side, their waveforms one line across them ---------- */
/* Every look at once on a desktop, sharing the row; narrower, a row to swipe through. Every column is at least as wide
   as the longest name (Chronograph, 109 px) and a clear space after it, --name-room, so a name never runs into the
   next (test/layout.test.mjs, "the looks' row"): eleven looks all fit from a 1366 px laptop up, and a look that
   doesn't fit there fails that test. */
.looks {
  --name-room: 118px;
  display: grid; grid-auto-flow: column; grid-auto-columns: minmax(var(--name-room), 1fr);
  max-width: 1680px; margin: 40px auto 0; padding: 0 var(--gutter); list-style: none;
  overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter); scrollbar-width: none;
}
.looks::-webkit-scrollbar { display: none; }
.looks li { scroll-snap-align: start; }
.looks figure { margin: 0; }
.looks img { width: 100%; aspect-ratio: 480 / 1040; object-fit: cover; }
/* each look's name, and only its name (2026-10-14); what it shows is the picture's alt text */
.looks figcaption { padding: 14px 14px 0 0; font: 500 12px/1.4 var(--font-display); letter-spacing: 0.16em; text-transform: uppercase; color: var(--text); }
/* narrower screens: a part of the next still always showing, so the row reads as one to swipe through: seven and a bit
   at a time in a window too narrow for every look, four and a bit on a tablet, two and a bit on a phone */
@media (max-width: 1365px) { .looks { grid-auto-columns: max(var(--name-room), 13.5%); } }
@media (max-width: 1099px) { .looks { grid-auto-columns: max(var(--name-room), 42%); } }
@media (min-width: 600px) and (max-width: 1099px) { .looks { grid-auto-columns: max(var(--name-room), 23%); } }

/* ---------- the priorities ---------- */
.priorities { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 48px; margin: 40px 0 0; padding: 0; list-style: none; counter-reset: priority; }
@media (min-width: 760px) { .priorities { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.priorities li { counter-increment: priority; padding: 24px 0 28px; border-top: 1px solid var(--line); }
.priorities li::before { content: counter(priority, decimal-leading-zero); font: 400 12px/1 var(--font-mono); color: var(--amber); }
.priorities h3 { margin-top: 12px; font-size: 20px; line-height: 1.3; }
.priorities p { margin-top: 10px; color: var(--muted); }

/* ---------- footer ---------- */
.footer { margin-top: clamp(72px, 11vw, 128px); border-top: 1px solid var(--line); }
.footer-inner { display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px 32px; padding-top: 28px; padding-bottom: max(32px, env(safe-area-inset-bottom)); font-size: 14px; color: var(--muted); }
.maker { flex: 1 1 320px; }
.footer-links { display: flex; gap: 24px; margin: 0; padding: 0; list-style: none; }
.footer-links a { text-decoration: none; color: var(--text); }
.footer-links a:hover { color: var(--accent); }
.copyright a { color: inherit; text-decoration: none; }
.copyright a:hover { color: var(--accent); }
.copyright { color: var(--dim); }
/* the trademark notice: the fine print, a line of its own under the rest */
.trademark { flex-basis: 100%; margin: 0; font-size: 13px; color: var(--dim); }

/* ---------- the page for an address that isn't here (404.html) ---------- */
.missing { min-height: 100vh; min-height: 100svh; display: flex; flex-direction: column; justify-content: center; padding-block: 48px; }
.missing .brand { margin-bottom: 56px; }
.missing h1 { margin-top: 14px; font-size: clamp(28px, 4vw, 44px); }

/* ---------- the dev blog, Session Notes (docs/adr/0004; its pages are made by scripts/blog.mjs) ---------- */
/* No hero: the topbar (.page-top, as on the apps' pages), then words in one comfortable column, the apps' type and
   hairlines */
.page-top { padding-top: max(18px, env(safe-area-inset-top)); padding-bottom: 8px; }
/* the blog's two links are short enough for a phone, where the landing page's four hide */
@media (max-width: 720px) { .nav.nav-always { display: flex; gap: 20px; } }
/* on a phone the logo is the way home, which leaves room for the apps beside it */
@media (max-width: 480px) { .nav-home { display: none; } }
/* and on the narrowest phones the logo steps down a little, as the apps' does, so the row keeps its air (with the
   logo's ™, the apps sit 8 px after it) */
@media (max-width: 360px) {
  .brand .wordmark { font-size: 17px; }
  .brand-row { gap: 8px; }
  .brand-apps li + li::before { margin-inline: 10px; }
}
.blog-head, .post { max-width: 720px; padding-top: clamp(48px, 8vw, 88px); }
.blog-head h1, .post h1 { margin-top: 14px; font-size: clamp(30px, 4.6vw, 48px); line-height: 1.14; letter-spacing: -0.012em; text-wrap: balance; }
.post-meta { margin-top: 14px; font: 400 13px/1.5 var(--font-mono); color: var(--dim); }

.post-list { max-width: 720px; margin: 40px 0 0; padding: 0; list-style: none; }
.post-card { padding: 26px 0 30px; border-top: 1px solid var(--line); }
.post-card .post-meta { margin-top: 0; }
.post-card h2 { margin-top: 10px; font-size: clamp(22px, 2.6vw, 28px); }
.post-card h2 a { text-decoration: none; }
.post-card h2 a:hover { color: var(--accent); }
.post-summary { margin-top: 10px; color: var(--muted); }

/* an entry's body: the reading column */
.post-body { margin-top: 36px; font-size: 17px; line-height: 1.7; color: #c9d1e4; }
.post-body > * + * { margin-top: 1.1em; }
.post-body h2 { margin-top: 2.2em; font-size: clamp(21px, 2.4vw, 25px); line-height: 1.3; color: var(--text); }
.post-body h2 + * { margin-top: 0.7em; }
.post-body strong { font-weight: 500; color: var(--text); }
.post-body em { color: var(--text); }
.post-body a { color: var(--accent); text-underline-offset: 3px; }
.post-body ul, .post-body ol { padding-left: 1.2em; }
.post-body li + li { margin-top: 0.7em; }
.post-body li::marker { color: var(--amber); }
.post-body blockquote { margin-inline: 0; padding: 4px 0 4px 22px; border-left: 2px solid rgb(var(--accent-2-rgb) / 0.6); }
.post-body blockquote p:first-child { font: 500 clamp(21px, 2.6vw, 26px)/1.35 var(--font-display); color: var(--text); }
.post-body blockquote .cite { margin-top: 10px; font: 400 13px/1.5 var(--font-mono); color: var(--dim); }

/* the numbers: a small panel of a word and its figure a row, like the apps' terms */
.post-numbers { padding: 20px 22px 8px; border: 1px solid var(--line); border-radius: 10px; background: rgb(var(--panel-rgb) / 0.66); }
.post-numbers-title { font: 500 12px/1 var(--font-display); letter-spacing: 0.2em; text-transform: uppercase; color: var(--amber); }
.post-numbers dl { margin: 14px 0 0; }
.post-numbers dl div { display: flex; justify-content: space-between; gap: 16px; padding: 10px 0; border-top: 1px solid var(--line); font-size: 15px; }
.post-numbers dt { color: var(--muted); }
.post-numbers dd { margin: 0; text-align: right; font-family: var(--font-mono); color: var(--text); }

/* before, after, every entry */
.post-steps { display: flex; flex-wrap: wrap; gap: 12px; max-width: 720px; margin-top: 56px; padding-top: 24px; border-top: 1px solid var(--line); }
.post-step { display: inline-flex; align-items: baseline; gap: 0.6em; min-height: 44px; padding: 12px 18px; border: 1px solid rgb(var(--line-rgb) / 0.22); border-radius: 999px; background: rgb(var(--panel-rgb) / 0.55); text-decoration: none; font-size: 14px; line-height: 1.4; }
.post-step:hover { border-color: rgb(var(--accent-rgb) / 0.55); }
.post-step-label { font: 500 11px/1 var(--font-display); letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); }
/* an entry's art: a still of a look (public/images/blog/), dim behind the title at the top right, fading into the ink
   toward the words and the foot, so it never competes with them */
.blog { position: relative; isolation: isolate; }
.post-art {
  position: absolute; top: 0; right: 0; z-index: -1; width: min(100%, 760px); height: min(92svh, 860px); object-fit: cover; object-position: 50% 18%;
  opacity: 0.5;
  -webkit-mask-image: linear-gradient(180deg, #000 30%, transparent 92%), linear-gradient(90deg, transparent, #000 55%);
  -webkit-mask-composite: source-in; mask-image: linear-gradient(180deg, #000 30%, transparent 92%), linear-gradient(90deg, transparent, #000 55%); mask-composite: intersect;
}
@media (max-width: 720px) { .post-art { width: 100%; height: 70svh; opacity: 0.38; } }
.blog-head h1, .post h1, .post-meta { text-shadow: 0 0 2px rgb(4 6 12 / 0.7), 0 1px 12px rgb(4 6 12 / 0.9); }
/* "Read more" at the end of each entry's card, here and on the landing page */
.post-more { margin-top: 14px; }
.post-more a { display: inline-flex; align-items: center; gap: 0.5em; min-height: 44px; font: 500 12px/1 var(--font-display); letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); text-decoration: none; }
.post-more a:hover { color: var(--text); }
.post-card .post-more { margin-top: 6px; margin-bottom: -10px; }
/* the landing page's dev blog section: the newest entries side by side (one under another on a phone) */
.post-list-home { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 48px; max-width: none; }
@media (min-width: 760px) { .post-list-home { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.post-list-home h3 { margin-top: 10px; font-size: 20px; line-height: 1.3; }
.post-list-home h3 a { text-decoration: none; }
.post-list-home h3 a:hover { color: var(--accent); }

/* ---------- a page per app, /mix and /radio (docs/adr/0006) ---------- */
/* The app's card from the landing page, grown into a page: its name, its line and what it is beside a picture of the
   app (the card's still, framed as a screen of it; after the words on a narrow screen), then its parts in the landing
   page's sections, and at the foot the other app's page and the way home (Radio's its user guide first), the blog's
   .post-step chips */
/* the opening: the app's name, line and words over the card's still, dimmed far enough that the words read first
   (2026-10-18: "put the image ... as a background on that section but make it pretty dim so the text reads
   clearly"). The still covers the panel, its waveform a little above the middle, and the ink deepens behind the words:
   from the left on a wide screen, where the words sit, and from the top and foot on a narrow one. */
.app-intro { padding-top: clamp(24px, 5vw, 56px); }
.app-intro-panel {
  position: relative; isolation: isolate; overflow: hidden; display: flex; align-items: center;
  min-height: min(560px, 78svh); padding: clamp(28px, 6vw, 72px) clamp(20px, 5vw, 64px);
  border: 1px solid var(--line); border-radius: var(--r); background: var(--ink);
}
.app-intro-panel > picture { display: contents; }
.app-intro-art {
  position: absolute; inset: 0; z-index: -2; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 45%;
}
/* each look's own dimming, set so its still shows about 15% brighter on average than the card's still did at 0.42
   (2026-10-18: "make them about 15% brighter"): Columns drawn wide is darker than on its card, Skyline lighter */
.app-intro-art-mix { opacity: 0.62; }
.app-intro-art-radio { opacity: 0.34; }
.app-intro-panel::before {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgb(4 6 12 / 0.55), rgb(4 6 12 / 0.2) 40%, rgb(4 6 12 / 0.75));
}
@media (min-width: 900px) {
  .app-intro-panel::before { background: linear-gradient(90deg, rgb(4 6 12 / 0.82), rgb(4 6 12 / 0.55) 45%, rgb(4 6 12 / 0.05)); }
}
.app-intro-copy { display: flex; flex-direction: column; gap: 18px; max-width: 40em; }
@media (min-width: 900px) { .app-intro-copy { max-width: 36em; } }
.app-intro .lockup .wordmark { font-size: clamp(26px, 4vw, 40px); }
.app-intro .lockup-app { font-size: clamp(17px, 2.6vw, 26px); }
.app-intro .app-line { font-size: clamp(22px, 3vw, 32px); }
.app-intro .lede { margin-top: 0; color: var(--text); }
.app-intro .app-actions { margin-top: 8px; padding-top: 0; }
.app-intro .fine { color: var(--muted); }
/* the Jam Room on the Mix page, framed the same: a still per range of widths, each composed for its range (scripts/room.mjs) */
.app-figure { margin: 40px 0 0; border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; background: var(--ink); }
.app-figure img { width: 100%; }
/* a paragraph after a section's parts or picture */
.section-more { margin-top: 18px; max-width: 40em; color: var(--muted); }
/* a station's name, linked to its site */
.part h3 a { text-decoration: none; }
.part h3 a:hover { color: var(--accent); }
/* "More about Mix" and "More about Radio", the way from a card to its app's page */
.more { display: inline-flex; align-items: center; gap: 0.5em; min-height: 44px; font: 500 12px/1 var(--font-display); letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); text-decoration: none; }
.more:hover { color: var(--text); }
