/*
 * releaseszn: site theme on top of Pico CSS.
 *
 * Look: modern single-column feed with a retro terminal nod to
 * freshmeat.net (phosphor green on near-black, monospace accents).
 * Dark first, light theme via the toggle or the OS setting.
 *
 * Smoothness rules (design/SITE.md §3.3): no box-shadow, filter or
 * backdrop-filter on cards or the sticky header; only transform/opacity
 * animate; every media box has its aspect ratio before load.
 */

/* ---------------------------------------------------------------- fonts */
/* font-display: optional → the browser uses the font only if it is ready
   for first paint (it is preloaded), so text never re-flows: CLS stays 0. */
@font-face {
  font-family: "Plex Sans";
  src: url("../fonts/plex-sans-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: optional;
}
@font-face {
  font-family: "Plex Sans";
  src: url("../fonts/plex-sans-600.woff2") format("woff2");
  font-weight: 600 700;
  font-style: normal;
  font-display: optional;
}
@font-face {
  font-family: "Plex Mono";
  src: url("../fonts/plex-mono-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: optional;
}
@font-face {
  font-family: "Plex Mono";
  src: url("../fonts/plex-mono-600.woff2") format("woff2");
  font-weight: 600 700;
  font-style: normal;
  font-display: optional;
}

/* --------------------------------------------------------------- tokens */
/* Every colour on the site comes from these nine tokens. A palette sets
   them for dark and light; `data-palette` on <html> picks the palette
   (none = Freshmeat blue, the rules on bare :root; pages are served with
   "sunset", the default) and `data-theme` forces dark or
   light (none = follow the OS). Both are set by the theme menu and
   restored by an inline script before first paint, so nothing flashes.

   Selector specificity does the work: palette rules (:root[data-palette])
   beat the bare :root ones, and light rules beat dark ones within a palette. */
:root {
  --rs-font-sans: "Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --rs-font-mono: "Plex Mono", ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --rs-radius: 3px;
}

/* Freshmeat blue (the default until 2026-10-17): navy and slate, blue
   links, orange versions. */
:root {
  --rs-bg: #0f141b;
  --rs-panel: #161d27;
  --rs-border: #263140;
  --rs-text: #e3e8ef;
  --rs-muted: #8b97a7;
  --rs-accent: #6ea8ff;
  --rs-accent-ink: #0f141b;
  --rs-amber: #fb923c;
  --rs-link: #8fbcff;
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --rs-bg: #f4f6f9;
    --rs-panel: #ffffff;
    --rs-border: #d9dee7;
    --rs-text: #1c2430;
    --rs-muted: #5f6b7a;
    --rs-accent: #1d4ed8;
    --rs-accent-ink: #ffffff;
    --rs-amber: #ea580c;
    --rs-link: #1d4ed8;
    color-scheme: light;
  }
}
:root[data-theme="light"] {
  --rs-bg: #f4f6f9;
  --rs-panel: #ffffff;
  --rs-border: #d9dee7;
  --rs-text: #1c2430;
  --rs-muted: #5f6b7a;
  --rs-accent: #1d4ed8;
  --rs-accent-ink: #ffffff;
  --rs-amber: #ea580c;
  --rs-link: #1d4ed8;
  color-scheme: light;
}

/* Slate & violet: blue-grey, violet links, gold versions. */
:root[data-palette="slate"] {
  --rs-bg: #0d1017;
  --rs-panel: #141823;
  --rs-border: #232a38;
  --rs-text: #e4e7ee;
  --rs-muted: #8a93a6;
  --rs-accent: #8b7cf6;
  --rs-accent-ink: #0d1017;
  --rs-amber: #f0b45a;
  --rs-link: #a99dff;
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  :root[data-palette="slate"]:not([data-theme="dark"]) {
    --rs-bg: #f7f8fb;
    --rs-panel: #ffffff;
    --rs-border: #e3e6ee;
    --rs-text: #171b24;
    --rs-muted: #5d6578;
    --rs-accent: #5b4bd6;
    --rs-accent-ink: #ffffff;
    --rs-amber: #b25e09;
    --rs-link: #5b4bd6;
    color-scheme: light;
  }
}
:root[data-palette="slate"][data-theme="light"] {
  --rs-bg: #f7f8fb;
  --rs-panel: #ffffff;
  --rs-border: #e3e6ee;
  --rs-text: #171b24;
  --rs-muted: #5d6578;
  --rs-accent: #5b4bd6;
  --rs-accent-ink: #ffffff;
  --rs-amber: #b25e09;
  --rs-link: #5b4bd6;
  color-scheme: light;
}

/* Ink & coral: neutral charcoal or off-white, coral accent. */
:root[data-palette="coral"] {
  --rs-bg: #121212;
  --rs-panel: #1a1a1a;
  --rs-border: #2a2a2a;
  --rs-text: #ececec;
  --rs-muted: #9a9a9a;
  --rs-accent: #ff6b5a;
  --rs-accent-ink: #121212;
  --rs-amber: #f5b14c;
  --rs-link: #ff8f80;
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  :root[data-palette="coral"]:not([data-theme="dark"]) {
    --rs-bg: #fbfaf8;
    --rs-panel: #ffffff;
    --rs-border: #e8e4de;
    --rs-text: #1d1d1d;
    --rs-muted: #6b6b6b;
    --rs-accent: #e5484d;
    --rs-accent-ink: #ffffff;
    --rs-amber: #b45309;
    --rs-link: #d13d42;
    color-scheme: light;
  }
}
:root[data-palette="coral"][data-theme="light"] {
  --rs-bg: #fbfaf8;
  --rs-panel: #ffffff;
  --rs-border: #e8e4de;
  --rs-text: #1d1d1d;
  --rs-muted: #6b6b6b;
  --rs-accent: #e5484d;
  --rs-accent-ink: #ffffff;
  --rs-amber: #b45309;
  --rs-link: #d13d42;
  color-scheme: light;
}

/* Amber CRT: warm brown-black, amber accents. */
:root[data-palette="amber"] {
  --rs-bg: #110e0a;
  --rs-panel: #19140e;
  --rs-border: #2e2519;
  --rs-text: #ece2d0;
  --rs-muted: #9c8b73;
  --rs-accent: #ffb000;
  --rs-accent-ink: #110e0a;
  --rs-amber: #ff7a45;
  --rs-link: #ffd27a;
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  :root[data-palette="amber"]:not([data-theme="dark"]) {
    --rs-bg: #faf6ee;
    --rs-panel: #ffffff;
    --rs-border: #e6dccb;
    --rs-text: #2a2118;
    --rs-muted: #7a6a55;
    --rs-accent: #b86e00;
    --rs-accent-ink: #ffffff;
    --rs-amber: #c2410c;
    --rs-link: #9a5800;
    color-scheme: light;
  }
}
:root[data-palette="amber"][data-theme="light"] {
  --rs-bg: #faf6ee;
  --rs-panel: #ffffff;
  --rs-border: #e6dccb;
  --rs-text: #2a2118;
  --rs-muted: #7a6a55;
  --rs-accent: #b86e00;
  --rs-accent-ink: #ffffff;
  --rs-amber: #c2410c;
  --rs-link: #9a5800;
  color-scheme: light;
}

/* Phosphor: green terminal on near-black. */
:root[data-palette="phosphor"] {
  --rs-bg: #0b0e0a;
  --rs-panel: #10150f;
  --rs-border: #1f2a1c;
  --rs-text: #d4e4cc;
  --rs-muted: #7d9374;
  --rs-accent: #39ff7a;
  --rs-accent-ink: #0b0e0a;
  --rs-amber: #ffb000;
  --rs-link: #8dffb5;
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  :root[data-palette="phosphor"]:not([data-theme="dark"]) {
    --rs-bg: #f3f0e6;
    --rs-panel: #fffdf7;
    --rs-border: #d8d2bf;
    --rs-text: #1b2118;
    --rs-muted: #5d6b55;
    --rs-accent: #0a7d38;
    --rs-accent-ink: #ffffff;
    --rs-amber: #9a5b00;
    --rs-link: #0a6b30;
    color-scheme: light;
  }
}
:root[data-palette="phosphor"][data-theme="light"] {
  --rs-bg: #f3f0e6;
  --rs-panel: #fffdf7;
  --rs-border: #d8d2bf;
  --rs-text: #1b2118;
  --rs-muted: #5d6b55;
  --rs-accent: #0a7d38;
  --rs-accent-ink: #ffffff;
  --rs-amber: #9a5b00;
  --rs-link: #0a6b30;
  color-scheme: light;
}

/* Neon sunset: dusk over a beach town, an indigo sky turning violet,
   pink, rose and peach at the horizon, plum silhouettes and lavender-white text. Pink accents, peach
   versions, lavender links; the sunset gradient goes under the header and
   in the logo, and the sky behind the page (below). Light is the same sky
   washed pale, with plum text. Every colour keeps 4.5:1 against every
   point of the sky (--rs-sky), not only against --rs-bg. */
:root[data-palette="sunset"] {
  --rs-bg: #1c1533;
  --rs-panel: #261c40;
  --rs-border: #3d2d5a;
  --rs-text: #ece4ee;
  --rs-muted: #bfafd0;
  --rs-accent: #f59cbb;
  --rs-accent-ink: #1c1533;
  --rs-amber: #f7ab8f;
  --rs-link: #c4b1f2;
  --rs-sunset: linear-gradient(90deg, #8f7ad0, #e07fae 50%, #f7ab8f);
  --rs-sky: linear-gradient(180deg, #1c1533 0%, #2a1a42 35%, #40204c 65%, #55284c 85%, #602e44 100%);
  color-scheme: dark;
}
@media (prefers-color-scheme: light) {
  :root[data-palette="sunset"]:not([data-theme="dark"]) {
    --rs-bg: #f6f0fa;
    --rs-panel: #ffffff;
    --rs-border: #e6d9ec;
    --rs-text: #351f3c;
    --rs-muted: #6a5372;
    --rs-accent: #a3317d;
    --rs-accent-ink: #ffffff;
    --rs-amber: #a8432a;
    --rs-link: #5a3c9c;
    --rs-sunset: linear-gradient(90deg, #69539f, #c4609a 50%, #e8866a);
    --rs-sky: linear-gradient(180deg, #f1ebf8 0%, #f6e6f2 40%, #fbe3ea 70%, #fde5dc 100%);
    color-scheme: light;
  }
}
:root[data-palette="sunset"][data-theme="light"] {
  --rs-bg: #f6f0fa;
  --rs-panel: #ffffff;
  --rs-border: #e6d9ec;
  --rs-text: #351f3c;
  --rs-muted: #6a5372;
  --rs-accent: #a3317d;
  --rs-accent-ink: #ffffff;
  --rs-amber: #a8432a;
  --rs-link: #5a3c9c;
  --rs-sunset: linear-gradient(90deg, #69539f, #c4609a 50%, #e8866a);
  --rs-sky: linear-gradient(180deg, #f1ebf8 0%, #f6e6f2 40%, #fbe3ea 70%, #fde5dc 100%);
  color-scheme: light;
}

/* Map our tokens onto Pico's variables. `:root:root` outranks Pico's own
   theme selectors, so these win in every theme. */
:root:root {
  --pico-font-family: var(--rs-font-sans);
  --pico-font-family-sans-serif: var(--rs-font-sans);
  --pico-font-family-monospace: var(--rs-font-mono);
  --pico-font-size: 100%;
  --pico-line-height: 1.55;
  --pico-border-radius: var(--rs-radius);
  --pico-background-color: var(--rs-bg);
  --pico-color: var(--rs-text);
  --pico-muted-color: var(--rs-muted);
  --pico-muted-border-color: var(--rs-border);
  --pico-primary: var(--rs-link);
  --pico-primary-hover: var(--rs-accent);
  --pico-primary-underline: transparent;
  --pico-primary-hover-underline: var(--rs-accent);
  --pico-primary-background: var(--rs-accent);
  --pico-primary-inverse: var(--rs-accent-ink);
  --pico-card-background-color: var(--rs-panel);
  --pico-card-sectioning-background-color: var(--rs-panel);
  --pico-card-box-shadow: none;
  --pico-code-background-color: var(--rs-panel);
  --pico-h1-color: var(--rs-text);
  --pico-h2-color: var(--rs-text);
  --pico-h3-color: var(--rs-text);
}

/* --------------------------------------------------------------- layout */
/* Always reserve the scrollbar's width, so short pages (no scrollbar) and
   long ones put the centred header in the same place. */
html {
  scrollbar-gutter: stable;
}

body {
  background: var(--rs-bg);
}

.wrap {
  max-width: 640px;
  margin-inline: auto;
  padding-inline: 1rem;
}

::selection {
  background: var(--rs-accent);
  color: var(--rs-accent-ink);
}

.muted {
  color: var(--rs-muted);
}

/* --------------------------------------------------------------- header */
.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--rs-bg);
  border-bottom: 1px solid var(--rs-border);
}

.site-header nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-block: 0.55rem;
}

/* Header navigation: logo | feed blog submit | [theme]. */
.site-nav {
  gap: 1rem;
}

.site-nav ul.nav-links {
  display: flex;
  gap: 1.1rem;
  margin: 0 auto 0 1.25rem;
  padding: 0;
}

.site-nav ul.nav-links li {
  padding: 0;
  list-style: none;
}

.site-nav ul.nav-links a {
  margin: 0;
  padding: 0;
  font-family: var(--rs-font-mono);
  font-size: 0.9rem;
  color: var(--rs-muted);
  text-decoration: none;
}

.site-nav ul.nav-links a:hover,
.site-nav ul.nav-links a:focus-visible {
  color: var(--rs-accent);
}

/* Current section: highlighted, with a terminal-style ">" marker. */
.site-nav ul.nav-links a[aria-current="page"] {
  color: var(--rs-text);
}

/* The marker hangs outside the link, so marking a section never moves the
   other links. */
.site-nav ul.nav-links a {
  position: relative;
}

.site-nav ul.nav-links a[aria-current="page"]::before {
  content: ">";
  position: absolute;
  right: 100%;
  margin-right: 0.2em;
  color: var(--rs-accent);
}

/* Phones: logo and [theme] on the first row, the links on their own row
   below, so nothing is pushed off-screen. */
@media (max-width: 520px) {
  .site-nav {
    flex-wrap: wrap;
    row-gap: 0.35rem;
  }

  .site-nav ul.nav-links {
    order: 3;
    width: 100%;
    gap: 1.1rem;
    margin: 0;
  }
}

/* Account link: "sign in", or "@handle" once signed in. */
.site-nav a.nav-account {
  font-family: var(--rs-font-mono);
  font-size: 0.9rem;
  color: var(--rs-muted);
  text-decoration: none;
  overflow: hidden;
  max-width: 14ch;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.site-nav a.nav-account:hover,
.site-nav a.nav-account:focus-visible,
.site-nav a.nav-account[aria-current="page"] {
  color: var(--rs-accent);
}

/* Phones: keep the account link next to [theme], after the logo. */
@media (max-width: 520px) {
  .site-nav a.nav-account {
    margin-left: auto;
  }
}

/* Neon sunset's sky: the window's background goes from night at the top
   to the last of the sunset at the bottom. A fixed layer behind the page,
   not `background-attachment: fixed` (which repaints the page on every
   scroll frame) nor the body's own background (which would stretch, and
   repaint, as the feed grows): the browser paints it once and composites
   it while scrolling (SITE §3.3). Its colours stay dark (or pale, by
   day) enough for text that sits on the page itself. The body's own
   background would cover it (it paints above a layer at z-index -1), so
   here it is left to <html>, which Pico paints with the same colour. */
:root[data-palette="sunset"] body {
  background: transparent;
}
:root[data-palette="sunset"] body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background: var(--rs-sky);
  pointer-events: none;
}

/* Neon sunset's gradient: a strip over the header's bottom border, drawn
   by a pseudo-element so the header keeps its height (CLS = 0, nothing
   moves when the palette changes), and the logo filled with it. Both are
   painted once: no animation, no filter (SITE §3.3). */
:root[data-palette="sunset"] .site-header::after {
  content: "";
  position: absolute;
  inset-inline: 0;
  bottom: -1px;
  height: 2px;
  background: var(--rs-sunset);
  pointer-events: none;
}
:root[data-palette="sunset"] .logo {
  background: var(--rs-sunset);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.logo {
  font-family: var(--rs-font-mono);
  font-weight: 600;
  font-size: 1.15rem;
  letter-spacing: -0.02em;
  color: var(--rs-accent);
  text-decoration: none;
}


/* Theme menu: a <details> dropdown in the header. It needs JavaScript, so
   it stays invisible until app.js sets it up, but keeps its space: showing
   it must not push the header around (CLS = 0, SITE §3.3). */
.theme-menu {
  position: relative;
  margin: 0;
}

.theme-menu[data-pending] {
  visibility: hidden;
}

.theme-menu > summary {
  padding: 0.15rem 0.5rem;
  font-family: var(--rs-font-mono);
  font-size: 0.8rem;
  color: var(--rs-muted);
  list-style: none;
  cursor: pointer;
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
}

.theme-menu > summary::-webkit-details-marker {
  display: none;
}

/* Pico draws a chevron after every summary; not here. */
.theme-menu > summary::after {
  display: none;
}

.theme-menu > summary:hover,
.theme-menu[open] > summary {
  color: var(--rs-accent);
  border-color: var(--rs-accent);
}

/* Pico spaces an open summary from its content; the panel floats here,
   so that margin would only grow the header and push the page down. */
.theme-menu[open] > summary {
  margin-bottom: 0;
}

.theme-panel {
  position: absolute;
  right: 0;
  top: calc(100% + 0.4rem);
  z-index: 20;
  width: 15rem;
  padding: 0.6rem 0.75rem;
  background: var(--rs-panel);
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
}

.theme-panel fieldset {
  margin: 0;
  padding: 0;
  border: 0;
}

.theme-panel fieldset + fieldset {
  margin-top: 0.6rem;
}

/* The feed's layouts only differ where the rails fit. */
.theme-layout {
  display: none;
}

@media (min-width: 1180px) {
  .theme-layout {
    display: block;
  }
}

.theme-panel legend {
  margin-bottom: 0.3rem;
  font-family: var(--rs-font-mono);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--rs-muted);
}

.theme-panel label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0.2rem 0;
  font-size: 0.88rem;
  color: var(--rs-text);
  cursor: pointer;
}

.theme-panel input[type="radio"] {
  margin: 0;
}

.swatch {
  display: inline-flex;
  margin-left: auto;
}

.swatch i {
  display: block;
  width: 0.7rem;
  height: 0.7rem;
  border: 1px solid var(--rs-border);
}

button.link-button {
  width: auto;
  margin: 0;
  padding: 0.15rem 0.5rem;
  font-family: var(--rs-font-mono);
  font-size: 0.8rem;
  color: var(--rs-muted);
  background: transparent;
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
  cursor: pointer;
}

button.link-button {
  padding: 0;
  border: 0;
}

button.link-button:hover,
button.link-button:focus-visible {
  color: var(--rs-accent);
  border-color: var(--rs-accent);
}

/* --------------------------------------------------------------- prompt */
/* Small section title above the feed. */
h1.feed-title {
  margin-block: 1.4rem 1rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--rs-muted);
}

/* Breathing room at the top of pages that lost the old prompt line. */
main > article.release,
main > header.page-head,
main > article.post,
main > section.error-page {
  margin-top: 1.5rem;
}

/* ----------------------------------------------------------------- feed */
.feed .empty,
.feed-end {
  font-family: var(--rs-font-mono);
  color: var(--rs-muted);
  text-align: center;
  padding-block: 2rem;
}

.feed-more {
  display: block;
  padding: 1.25rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
  text-align: center;
  color: var(--rs-muted);
}

/* A card emptied far off screen (app.js DOM trimming): its locked height
   holds its place, and it's refilled before it comes back into view. */
article.card.trimmed {
  border-color: transparent;
  background: none;
}

/* One card. content-visibility lets the browser skip layout and paint for
   off-screen cards; contain-intrinsic-size reserves their space. */
article.card {
  content-visibility: auto;
  contain-intrinsic-size: auto 720px;
  margin: 0 0 1.5rem;
  padding: 0;
  background: var(--rs-panel);
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
  box-shadow: none;
  overflow: hidden;
}

article.card > header.card-head,
article.card > footer.card-body {
  margin: 0;
  background: none;
  border: 0;
}

.card-head {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.6rem 0.75rem;
}

.avatar {
  flex: none;
  display: block;
}

.card-who {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  line-height: 1.3;
}

.card-project {
  font-weight: 600;
  color: var(--rs-text);
  text-decoration: none;
}

.card-meta,
.card-time {
  font-family: var(--rs-font-mono);
  font-size: 0.75rem;
  color: var(--rs-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.version {
  font-family: var(--rs-font-mono);
  color: var(--rs-amber);
}

.kind {
  padding: 0 0.3rem;
  font-family: var(--rs-font-mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--rs-muted);
  border: 1px solid currentColor;
  border-radius: 2px;
  vertical-align: 0.1em;
}

.kind-major,
.kind-initial {
  color: var(--rs-accent);
}

/* Hero: its box has the image's aspect ratio before anything loads; the
   tiny inline LQIP + dominant colour show until the image arrives. */
.hero {
  display: block;
  width: 100%;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.hero img,
.gallery-slide img,
.gallery-slide video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Double-tap to upvote (app.js): no double-tap zoom on screenshots, and a
   thumbs-up that pops over the frame. Transform and opacity only. */
.hero,
.gallery-slide {
  touch-action: manipulation;
}

.hero {
  position: relative;
}

.tap-burst {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  width: 5.5rem;
  height: 5.5rem;
  color: #fff;
  pointer-events: none;
  filter: drop-shadow(0 2px 10px rgb(0 0 0 / 0.45));
  transform: translate(-50%, -50%) scale(0.4);
  opacity: 0;
  animation: tap-burst 0.8s ease-out;
}

.tap-burst svg {
  width: 100%;
  height: 100%;
  margin: 0;
  fill: currentColor;
  stroke: currentColor;
  stroke-width: 1.5;
  stroke-linejoin: round;
}

@keyframes tap-burst {
  15% {
    transform: translate(-50%, -50%) scale(1.15);
    opacity: 1;
  }
  30% {
    transform: translate(-50%, -50%) scale(1);
  }
  70% {
    opacity: 1;
  }
  100% {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0;
  }
}

.vote.nudge {
  animation: vote-nudge 0.6s ease-in-out 2;
}

@keyframes vote-nudge {
  50% {
    transform: scale(1.18);
  }
}

/* A synced avatar: round, like the generated ones. */
img.avatar {
  flex: none;
  border-radius: 50%;
  object-fit: cover;
}

/* ------------------------------------------------------------- gallery */
/* More than one screenshot: one frame shaped like the hero, swiped to the
   next (SITE §3.1). Native scroll-snap does the work; nothing runs while
   scrolling. Slides other than the hero may have another shape: they fit
   inside the frame over their own blurred placeholder. */
.gallery {
  position: relative;
  width: 100%;
  overflow: hidden;
}

.gallery-track {
  display: flex;
  height: 100%;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.gallery-track::-webkit-scrollbar {
  display: none;
}

.gallery-track:focus-visible {
  outline: 2px solid var(--rs-accent);
  outline-offset: -2px;
}

.gallery-slide {
  flex: 0 0 100%;
  height: 100%;
  scroll-snap-align: start;
  scroll-snap-stop: always;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.gallery-slide:not(.hero) img,
.gallery-slide:not(.hero) video {
  object-fit: contain;
}

.gallery-count,
.gallery-dots {
  position: absolute;
  pointer-events: none;
  background: rgb(0 0 0 / 0.55);
  border-radius: 1rem;
}

.gallery-count {
  top: 0.6rem;
  right: 0.6rem;
  padding: 0.1rem 0.5rem;
  font-family: var(--rs-font-mono);
  font-size: 0.75rem;
  color: #fff;
}

.gallery-dots {
  bottom: 0.6rem;
  left: 50%;
  display: flex;
  gap: 0.3rem;
  padding: 0.3rem 0.45rem;
  transform: translateX(-50%);
}

.gallery-dots span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgb(255 255 255 / 0.45);
}

.gallery-dots span.on {
  background: #fff;
}

/* Arrows for mouse users (app.js shows them); touch screens swipe. */
.gallery-arrow {
  position: absolute;
  top: 50%;
  width: 2rem;
  height: 2rem;
  margin: 0;
  padding: 0;
  font-size: 1.4rem;
  line-height: 1;
  color: #111;
  background: rgb(255 255 255 / 0.85);
  border: 0;
  border-radius: 50%;
  opacity: 0;
  transform: translateY(-50%);
  transition: opacity 0.15s;
}

.gallery-prev {
  left: 0.5rem;
}

.gallery-next {
  right: 0.5rem;
}

.gallery:hover .gallery-arrow,
.gallery-arrow:focus-visible {
  opacity: 1;
}

.gallery-arrow:disabled {
  visibility: hidden;
}

@media (hover: none) {
  .gallery-arrow {
    display: none;
  }
}

.card-body {
  padding: 0.6rem 0.75rem 0.8rem;
}

.card-actions {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  margin-bottom: 0.4rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
}

/* The upvote button (templates/vote_button.html): a plain icon and count,
   not a Pico button. Filled icon once voted. */
.vote-form {
  display: inline;
  margin: 0;
}

.vote {
  display: inline-flex;
  align-items: center;
  width: auto;
  margin: 0;
  padding: 0.15rem 0.25rem;
  font-family: var(--rs-font-mono);
  font-size: inherit;
  line-height: 1.2;
  color: var(--rs-text);
  text-decoration: none;
  background: none;
  border: 0;
  border-radius: var(--rs-radius);
  box-shadow: none;
  cursor: pointer;
}

.vote:hover .vote-icon,
.vote:focus-visible .vote-icon {
  transform: translateY(-1px);
}

.vote[aria-pressed="true"] .vote-icon {
  fill: var(--rs-accent);
}

.vote[aria-pressed="true"] .vote-count {
  color: var(--rs-accent);
}

.vote:disabled {
  opacity: 1;
  cursor: progress;
}

.vote-own {
  cursor: default;
}

.release-vote {
  margin-top: 0.35rem;
}

@media (prefers-reduced-motion: reduce) {
  .vote-icon {
    transition: none;
  }

  .vote:hover .vote-icon,
  .vote:focus-visible .vote-icon {
    transform: none;
  }
}

/* Upvote: an outline thumbs-up drawn as inline SVG (templates/vote_icon.html),
   so it looks the same everywhere; filled once you've voted (milestone 8). */
.vote-icon {
  width: 1.05em;
  height: 1.05em;
  margin-right: 0.35em;
  fill: none;
  stroke: var(--rs-accent);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -0.15em;
  transition: transform 0.1s ease-out;
}

.caption {
  margin: 0 0 0.35rem;
}

.caption a {
  color: var(--rs-text);
  text-decoration: none;
}

.release-title {
  color: var(--rs-muted);
}

.tags {
  margin: 0;
  font-family: var(--rs-font-mono);
  font-size: 0.78rem;
}

.tag {
  margin-right: 0.45rem;
  color: var(--rs-link);
}

.tag-lang {
  color: var(--rs-amber);
}

.tag-ai {
  color: var(--rs-muted);
}

a.tag {
  text-decoration: none;
}

a.tag:hover,
a.tag:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* `/t/{kind}/{slug}`: the tag, large, above its feed. */
.tag-head {
  margin-block: 1.5rem 1rem;
}

.tag-kind {
  margin-bottom: 0.2rem;
  font-family: var(--rs-font-mono);
  font-size: 0.78rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--rs-muted);
}

h1.tag-title {
  margin: 0;
  font-family: var(--rs-font-mono);
  font-size: 1.7rem;
}

/* -------------------------------------------------------- release page */
/* Pico gives article headers negative margins and a band background;
   the release page wants a plain header. */
article.release {
  padding: 1.25rem;
  background: var(--rs-panel);
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
  box-shadow: none;
}

article.release > header.release-head {
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
}

.release-head h1 {
  margin-bottom: 0.25rem;
  font-family: var(--rs-font-mono);
  font-size: 1.6rem;
}

.release-head .release-title {
  margin-bottom: 0.4rem;
  font-size: 1.05rem;
}

.release-meta {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--rs-font-mono);
  font-size: 0.8rem;
  color: var(--rs-muted);
}

.release > .hero,
.release > .gallery,
.project-gallery > .hero,
.project-gallery > .gallery {
  margin-block: 1rem;
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
  overflow: hidden;
}

.release h2 {
  margin-block: 1.5rem 0.5rem;
  font-family: var(--rs-font-mono);
  font-size: 0.95rem;
  color: var(--rs-accent);
}


.changelog {
  padding: 0.9rem 1rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
  line-height: 1.6;
  /* User text: long unbroken words (hashes, URLs) wrap instead of
     widening the page. Not `anywhere`: that lets table columns shrink to
     one letter. */
  overflow-wrap: break-word;
  background: var(--rs-panel);
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
}

/* Wide tables scroll inside the changelog instead of the page. */
.changelog table {
  display: block;
  max-width: 100%;
  overflow-x: auto;
}

.changelog > :first-child {
  margin-top: 0;
}

.changelog > :last-child {
  margin-bottom: 0;
}

.changelog ul,
.changelog ol {
  margin-block: 0.5rem;
  padding-left: 1.25rem;
}

/* Pico pads quotes 1rem on both sides (~36px a level); a slim left
   inset keeps the deepest allowed nesting (markdown.rs) readable on phones. */
.changelog blockquote {
  margin-block: 0.5rem;
  padding: 0 0 0 0.75rem;
}

/* Task list items show their checkbox instead of a bullet. */
.changelog li:has(> input[type="checkbox"]) {
  list-style: none;
  margin-left: -1.25rem;
}

.changelog a {
  color: var(--rs-accent);
}

.changelog code {
  padding: 0.1em 0.3em;
  font-size: 0.88em;
  color: var(--rs-amber);
  background: var(--rs-bg);
  border-radius: 2px;
}

.changelog pre {
  padding: 0.6rem 0.75rem;
  overflow-x: auto;
}

.changelog pre code {
  padding: 0;
  color: var(--rs-text);
  background: none;
}

.links,
.others {
  padding-left: 0;
  font-family: var(--rs-font-mono);
  font-size: 0.9rem;
}

.links li,
.others li {
  list-style: none;
}


.back,
.error-page a {
  margin-top: 2rem;
  font-family: var(--rs-font-mono);
}

/* ---------------------------------------------- project and author pages */
.profile-head {
  margin-bottom: 1.5rem;
}

.profile-head h1 {
  margin-bottom: 0.35rem;
  font-family: var(--rs-font-mono);
  font-size: 1.6rem;
  line-height: 1.25;
  overflow-wrap: break-word;
}

.profile-summary {
  margin-bottom: 0.5rem;
  font-size: 1.05rem;
}

.profile-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin-bottom: 0.5rem;
  font-family: var(--rs-font-mono);
  font-size: 0.8rem;
  color: var(--rs-muted);
}

.profile-author {
  display: flex;
  align-items: center;
  gap: 1rem;
}

.profile-author > svg {
  flex: none;
  border-radius: 50%;
}

.profile-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 0;
}

.project-link {
  font-family: var(--rs-font-mono);
  font-size: 0.9rem;
}

/* ------------------------------------------------------------ search */
.search-form {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 0.75rem;
}

.search-form input[type="search"] {
  flex: 1;
  min-width: 0;
  margin-bottom: 0;
  font-family: var(--rs-font-mono);
}

/* Pico makes submit buttons full width; this one sits beside the box. */
.search-form button[type="submit"] {
  flex: none;
  width: auto;
  margin-bottom: 0;
  padding-inline: 1.25rem;
  font-family: var(--rs-font-mono);
}

/* newest · following · saved, above the feed when signed in. */
.feed-switch {
  display: flex;
  justify-content: flex-start;
  gap: 1.1rem;
  margin-top: 1.25rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
}

.feed-switch a {
  color: var(--rs-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
}

.feed-switch a[aria-current="page"] {
  color: var(--rs-text);
  border-bottom-color: var(--rs-accent);
}

/* Follow and save buttons, on or off. */
.toggle[aria-pressed="true"] {
  color: var(--rs-accent);
}

.toggle-form {
  display: inline;
  margin: 0;
}

.profile-actions {
  display: flex;
  gap: 1rem;
  margin-block: 0.5rem 0.75rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
}

/* "sort: newest · most loved" on search and author pages. */
.sort-links {
  margin-bottom: 0.75rem;
  font-family: var(--rs-font-mono);
  font-size: 0.8rem;
  color: var(--rs-muted);
}

.sort-links a {
  margin-left: 0.5rem;
  color: var(--rs-muted);
  text-decoration: none;
}

.sort-links a[aria-current="true"] {
  color: var(--rs-text);
  border-bottom: 2px solid var(--rs-accent);
}

.list-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0 1rem;
}

.list-head .sort-links {
  margin: 0;
}

.search-summary {
  margin-bottom: 1.25rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
  color: var(--rs-muted);
}

.search-summary strong {
  color: var(--rs-text);
}

/* ------------------------------------------------------------ boards */
/* Pico spreads a <nav>'s children apart; the tabs sit together. */
.board-tabs {
  display: flex;
  justify-content: flex-start;
  gap: 1.25rem;
  margin-bottom: 0.5rem;
  font-family: var(--rs-font-mono);
  font-size: 0.9rem;
}

.board-tabs a {
  color: var(--rs-muted);
  text-decoration: none;
  border-bottom: 2px solid transparent;
  padding-bottom: 0.15rem;
}

.board-tabs a:hover,
.board-tabs a[aria-current="page"] {
  color: var(--rs-text);
  border-bottom-color: var(--rs-accent);
}

.board-title {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-block: 1.5rem 0.35rem;
  font-family: var(--rs-font-mono);
  font-size: 1.05rem;
}

.board-title a {
  text-decoration: none;
}

.board-step {
  padding-inline: 0.35rem;
  color: var(--rs-muted);
}

.board-status,
.board-none {
  margin-bottom: 1rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
  color: var(--rs-muted);
}

.board-rank {
  margin: 0 0 0.4rem;
  font-family: var(--rs-font-mono);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--rs-muted);
}

.board-rank span {
  font-size: 0.8rem;
  font-weight: 400;
}

.board-rank-1 {
  color: var(--rs-amber);
}

.board-rank-2,
.board-rank-3 {
  color: var(--rs-text);
}

.board-past {
  margin-block: 1.25rem 0.6rem;
  font-family: var(--rs-font-mono);
  font-size: 0.9rem;
}

.board-runner-up {
  margin: -0.75rem 0 1rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
  color: var(--rs-muted);
}

.board-runner-up + .board-runner-up {
  margin-top: -0.75rem;
}

.release-placements {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  font-family: var(--rs-font-mono);
  font-size: 0.8rem;
}

.placement {
  padding: 0.1rem 0.5rem;
  border: 1px solid var(--rs-amber);
  border-radius: var(--rs-radius);
  color: var(--rs-amber);
  text-decoration: none;
}

/* First place stands out: filled. */
.placement-1 {
  color: var(--rs-accent-ink);
  background: var(--rs-amber);
}

/* The owner's README badge snippet on their project page. */
.badge-snippet {
  margin-block: 1rem 1.5rem;
  font-size: 0.9rem;
}

.badge-snippet summary {
  font-family: var(--rs-font-mono);
  color: var(--rs-muted);
}

.badge-snippet code {
  word-break: break-all;
}

/* A card's best placement, above its caption. */
.card-placement {
  margin: 0 0 0.45rem;
  font-family: var(--rs-font-mono);
  font-size: 0.75rem;
}

/* ---------------------------------------------------------------- blog */
/* A post: kicker, a large title, the lead sentence, a byline, the body at
   18 px, then the author, a call to action and what to read next. */
main > article.post {
  margin: 2rem 0 0;
  padding: 0;
  background: none;
  box-shadow: none;
}

article.post > header.post-head {
  margin: 0 0 2rem;
  padding: 0 0 1.5rem;
  background: none;
  border-bottom: 1px solid var(--rs-border);
}

.post-kicker {
  margin-bottom: 0.6rem;
  font-family: var(--rs-font-mono);
  font-size: 0.78rem;
}

.post-kicker a.category {
  text-decoration: none;
}

article.post .post-head h1 {
  margin-bottom: 0.75rem;
  font-size: clamp(1.9rem, 1.2rem + 3vw, 2.6rem);
  line-height: 1.15;
  letter-spacing: -0.015em;
  text-wrap: balance;
}

.post-lead {
  margin-bottom: 1.25rem;
  font-size: 1.25rem;
  line-height: 1.5;
  color: var(--rs-muted);
  text-wrap: pretty;
}

.byline {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.9rem;
  margin: 0;
  font-family: var(--rs-font-mono);
  font-size: 0.82rem;
  color: var(--rs-muted);
}

.byline-author {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--rs-text);
}

.byline svg {
  width: 28px;
  height: 28px;
  border-radius: 50%;
}

article.post .prose {
  font-size: 1.125rem;
  line-height: 1.65;
  hanging-punctuation: first last;
}

article.post .prose p,
article.post .prose ul,
article.post .prose ol {
  margin-bottom: 1.2em;
  text-wrap: pretty;
}

article.post .prose h2 {
  margin-block: 2.4rem 0.8rem;
  font-size: 1.45rem;
  line-height: 1.25;
  color: var(--rs-text);
}

article.post .prose h3 {
  margin-block: 1.8rem 0.6rem;
  font-size: 1.2rem;
}

article.post .prose li {
  margin-bottom: 0.45em;
}

article.post .prose li::marker {
  color: var(--rs-accent);
}

article.post .prose a {
  text-underline-offset: 0.18em;
  text-decoration-thickness: 1px;
}

article.post .prose blockquote {
  font-style: italic;
}

article.post .prose hr {
  margin-block: 2.5rem;
}

article.post .prose img {
  display: block;
  max-width: 100%;
  height: auto;
  margin-inline: auto;
  border-radius: var(--rs-radius);
}

@media (max-width: 600px) {
  article.post .prose {
    font-size: 1.0625rem;
  }
}

/* A post's hero, as wide as the text column; its size is in the markup,
   so the text never moves when it loads. */
.post-hero {
  margin: -0.5rem 0 2rem;
}

.post-hero img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--rs-radius);
  border: 1px solid var(--rs-border);
}

/* `#` links next to headings (posts and docs): shown on hover or focus. */
.prose :is(h2, h3) {
  scroll-margin-top: 1rem;
}

.heading-anchor {
  margin-left: 0.3em;
  font-weight: 400;
  color: var(--rs-muted);
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.15s;
}

.prose :is(h2, h3):hover .heading-anchor,
.heading-anchor:focus-visible {
  opacity: 1;
}

@media (hover: none) {
  .heading-anchor {
    display: none;
  }
}

/* Pico styles an article's <footer> as a card footer: undo it. */
article.post > footer.post-foot {
  margin: 3rem 0 0;
  padding: 0;
  background: none;
  border: 0;
}

.author-card {
  display: flex;
  gap: 1rem;
  align-items: center;
  padding-block: 1.5rem;
  border-block: 1px solid var(--rs-border);
}

.author-card svg {
  flex: none;
  width: 52px;
  height: 52px;
  border-radius: 50%;
}

.author-card p {
  margin: 0;
}

.author-label {
  font-family: var(--rs-font-mono);
  font-size: 0.75rem;
  color: var(--rs-muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.author-name {
  font-weight: 600;
}

.author-bio {
  color: var(--rs-muted);
}

.post-cta {
  margin-top: 1.5rem;
  padding: 1rem 1.25rem;
  background: var(--rs-panel);
  border: 1px solid var(--rs-border);
  border-left: 3px solid var(--rs-accent);
  border-radius: var(--rs-radius);
}

.post-cta p {
  margin: 0;
}

.post-cta p + p {
  margin-top: 0.4rem;
  font-family: var(--rs-font-mono);
  font-size: 0.9rem;
}

.related {
  margin-top: 2.5rem;
}

.related h2,
.blog-section {
  margin-bottom: 0.75rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--rs-muted);
}

.related ul {
  padding: 0;
}

.related li {
  list-style: none;
  border-bottom: 1px solid var(--rs-border);
}

.related a {
  display: block;
  padding-block: 0.8rem;
  text-decoration: none;
}

.related-title {
  display: block;
  font-weight: 600;
  color: var(--rs-text);
}

.related a:hover .related-title {
  color: var(--rs-accent);
}

.feed-link {
  margin: 0;
  font-family: var(--rs-font-mono);
  font-size: 0.8rem;
}

/* /mod: reports and the audit log. */
.mod-table td {
  vertical-align: top;
  font-size: 0.9rem;
}

.mod-actions form {
  display: inline;
  margin: 0 0.6rem 0 0;
}

.mod-actions .danger-link {
  color: var(--rs-amber);
}

.mod-log {
  padding: 0;
  font-family: var(--rs-font-mono);
  font-size: 0.82rem;
}

.mod-log li {
  list-style: none;
  padding-block: 0.35rem;
  border-bottom: 1px solid var(--rs-border);
}

.mod-when {
  display: inline-block;
  min-width: 6rem;
  color: var(--rs-muted);
}

.mod-text {
  max-width: 28rem;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.mod-role {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: center;
  max-width: 40rem;
}

.mod-role input,
.mod-role select,
.mod-role button {
  width: auto;
  margin: 0;
}

/* The "moderate" panel staff see on release and project pages. */
.mod-panel {
  margin-block: 1rem;
  padding: 0.6rem 0.9rem;
  border: 1px dashed var(--rs-amber);
  border-radius: 6px;
  font-size: 0.9rem;
}

.mod-panel summary {
  font-family: var(--rs-font-mono);
  color: var(--rs-amber);
}

.mod-panel form {
  margin-block: 0.6rem;
}

.mod-hide {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  align-items: center;
}

.mod-hide input,
.mod-hide button {
  width: auto;
  margin: 0;
}

.mod-panel .danger-link {
  color: var(--rs-amber);
}

/* /appeal: one block per moderation decision. */
.appeal {
  padding-block: 1rem;
  border-top: 1px solid var(--rs-border);
}

.appeal h2 {
  margin-bottom: 0.2rem;
  font-size: 1.15rem;
}

/* The changelog: dated entries in the blog's look. */
main > article.changelog-entry {
  margin-top: 0;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--rs-border);
}

.changelog-date {
  margin-block: 1.5rem 0.5rem;
  font-family: var(--rs-font-mono);
  font-size: 1.15rem;
}

.changelog-date a {
  color: var(--rs-text);
  text-decoration: none;
}

article.changelog-entry .prose h3 {
  margin-block: 1rem 0.4rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--rs-muted);
}

/* The roadmap: Now / Next / Later side by side, stacked on phones. */
.roadmap {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 1rem;
}

.roadmap-column {
  padding: 0.9rem 1rem;
  background: var(--rs-panel);
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
}

.roadmap-column h2 {
  margin: 0 0 0.6rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--rs-accent);
}

.roadmap-column ul {
  margin: 0;
  padding: 0;
}

.roadmap-column li {
  list-style: none;
  margin-bottom: 0.8rem;
}

.roadmap-column li p {
  margin: 0.15rem 0 0;
  font-size: 0.9rem;
  color: var(--rs-muted);
}

/* The blog index: the newest post large, the others as a dated list. */
.blog-head {
  margin-bottom: 2rem;
}

.post-featured {
  margin: 0 0 3rem;
  padding: 0 0 2rem;
  background: none;
  box-shadow: none;
  border-bottom: 1px solid var(--rs-border);
}

.post-featured h2 {
  margin-top: 0;
  margin-bottom: 0.6rem;
  font-family: var(--rs-font-mono);
  font-size: clamp(1.6rem, 1.1rem + 2.2vw, 2.1rem);
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

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

.post-featured h2 a:hover,
.post-item h3 a:hover {
  color: var(--rs-accent);
}

.read-more {
  margin: 1.25rem 0 0;
  font-family: var(--rs-font-mono);
  font-size: 0.9rem;
}

.post-list {
  padding: 0;
}

.post-list li.post-item {
  display: grid;
  grid-template-columns: 9.5rem 1fr;
  gap: 1rem;
  list-style: none;
  padding-block: 1.1rem;
  border-bottom: 1px solid var(--rs-border);
}

.post-date {
  padding-top: 0.2rem;
  font-family: var(--rs-font-mono);
  font-size: 0.8rem;
  color: var(--rs-muted);
}

.post-item h3 {
  margin-bottom: 0.3rem;
  font-size: 1.15rem;
}

.post-item p {
  margin-bottom: 0.3rem;
}

@media (max-width: 600px) {
  .post-list li.post-item {
    grid-template-columns: 1fr;
    gap: 0.2rem;
  }
}

/* ----------------------------------------------------- blog and docs */
.page-head h1,
.post-head h1 {
  margin-top: 0.25rem;
  margin-bottom: 0.35rem;
  font-family: var(--rs-font-mono);
  font-size: 1.7rem;
  line-height: 1.25;
}

.page-lead {
  font-size: 1.1rem;
  color: var(--rs-muted);
}

.post-meta {
  margin-bottom: 0.4rem;
  font-family: var(--rs-font-mono);
  font-size: 0.78rem;
  color: var(--rs-muted);
}

.category {
  color: var(--rs-amber);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.draft-badge {
  padding: 0 0.3rem;
  color: var(--rs-accent-ink);
  background: var(--rs-amber);
  border-radius: 2px;
}

/* Long-form text: a comfortable reading size and rhythm. */
.prose {
  font-size: 1.0625rem;
  line-height: 1.7;
}

.prose h2 {
  margin-block: 2rem 0.6rem;
  font-family: var(--rs-font-mono);
  font-size: 1.15rem;
  color: var(--rs-accent);
}


.prose h3 {
  margin-block: 1.5rem 0.5rem;
  font-size: 1.05rem;
}

.prose code {
  padding: 0.1em 0.3em;
  font-size: 0.88em;
  color: var(--rs-amber);
  background: var(--rs-panel);
  border-radius: 2px;
}

.prose pre,
.code-box pre {
  padding: 0.9rem 1rem;
  font-size: 0.85rem;
  background: var(--rs-panel);
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
}

.prose pre code {
  padding: 0;
  color: var(--rs-text);
  background: none;
}

.prose blockquote {
  margin-inline: 0;
  padding: 0.7rem 1rem;
  background: var(--rs-panel);
  border-left: 3px solid var(--rs-amber);
}

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

.code-box {
  margin-top: 1rem;
}

.code-box-bar {
  display: flex;
  justify-content: space-between;
  padding: 0.35rem 1rem;
  font-family: var(--rs-font-mono);
  font-size: 0.78rem;
  color: var(--rs-muted);
  background: var(--rs-border);
  border-radius: var(--rs-radius) var(--rs-radius) 0 0;
}

.code-box-bar a {
  margin-right: 0.8rem;
}

/* Keep the prompt's own line breaks; scroll sideways on narrow screens
   instead of re-wrapping already-wrapped lines. */
.code-box pre {
  margin-top: 0;
  font-size: 0.78rem;
  white-space: pre;
  overflow-x: auto;
  border-top: 0;
  border-radius: 0 0 var(--rs-radius) var(--rs-radius);
}

/* ---------------------------------------------------------- docs */
/* The wide column: the header on every page (so it never moves between
   pages), and the docs' three columns on wide screens: sidebar | article |
   "On this page". */
/* The blog's reading column: 700 px of text (BLOG.md §4). */
.wrap-read {
  max-width: calc(700px + 2rem);
  margin-inline: auto;
  padding-inline: 1rem;
}

.wrap-wide {
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: 1rem;
}

.docs {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 2.5rem;
  padding-top: 1.5rem;
}

@media (min-width: 900px) {
  .docs {
    grid-template-columns: 200px minmax(0, 1fr);
  }
}

@media (min-width: 1180px) {
  .docs {
    grid-template-columns: 200px minmax(0, 720px) 200px;
  }
}

.docs-nav,
.docs-toc {
  font-family: var(--rs-font-mono);
  font-size: 0.82rem;
}

@media (min-width: 900px) {
  .docs-nav,
  .docs-toc {
    position: sticky;
    top: 4.5rem;
    align-self: start;
    max-height: calc(100vh - 5.5rem);
    overflow-y: auto;
  }
}

/* Below 1180px there's no room for the outline column. */
.docs-toc {
  display: none;
}

@media (min-width: 1180px) {
  .docs-toc {
    display: block;
  }
}

.docs-nav-group {
  margin: 1.1rem 0 0.4rem;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--rs-muted);
}

.docs-nav-group:first-child {
  margin-top: 0;
}

.docs-nav ul,
.docs-toc ul {
  margin: 0;
  padding: 0;
}

.docs-nav li,
.docs-toc li {
  margin: 0;
  padding: 0;
  list-style: none;
}

.docs-nav a,
.docs-toc a {
  display: block;
  padding: 0.22rem 0 0.22rem 0.75rem;
  color: var(--rs-muted);
  text-decoration: none;
  border-left: 2px solid var(--rs-border);
}

.docs-nav a:hover,
.docs-toc a:hover {
  color: var(--rs-text);
}

.docs-nav a[aria-current="page"],
.docs-toc a.active {
  color: var(--rs-accent);
  border-left-color: var(--rs-accent);
}

.docs-toc li.toc-3 a {
  padding-left: 1.5rem;
}

/* Phones and tablets: the sidebar becomes a horizontal strip of links. */
@media (max-width: 899px) {
  .docs-nav {
    display: flex;
    gap: 0.25rem 1rem;
    flex-wrap: wrap;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--rs-border);
  }

  .docs-nav .docs-nav-group {
    display: none;
  }

  .docs-nav ul {
    display: contents;
  }

  .docs-nav a {
    padding: 0.15rem 0;
    border-left: 0;
  }
}

/* ------------------------------------------------------- feed rails */
/* Beside a feed on wide screens (SITE §3.1): boards on the left, tags on
   the right, the card column between them exactly where `.wrap` puts it
   (608px of content, centred), so nothing moves between pages. Below
   1180px the rails are hidden and the page is the plain column. The
   theme menu offers two more layouts there (`data-layout` on <html>):
   "plain", the column without rails, and "wide", a 900px column without
   rails, with larger text to match its larger screenshots. */
.rail {
  display: none;
}

@media (min-width: 1180px) {
  :root:not([data-layout]) .wrap.with-rails {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 608px minmax(0, 1fr);
    column-gap: 2.5rem;
    align-items: start;
    max-width: 1180px;
  }

  .feed-column {
    grid-area: 1 / 2;
    min-width: 0;
  }

  :root:not([data-layout]) .rail {
    display: block;
    grid-row: 1;
    position: sticky;
    top: 4.5rem;
    max-height: calc(100vh - 5.5rem);
    margin-top: 1.25rem;
    overflow-y: auto;
    font-family: var(--rs-font-mono);
    font-size: 0.82rem;
  }

  .rail-boards {
    grid-column: 1;
  }

  .rail-tags {
    grid-column: 3;
  }

  :root[data-layout="wide"] .wrap.with-rails {
    max-width: calc(900px + 2rem);
  }

  :root[data-layout="wide"] .feed-column .card-head,
  :root[data-layout="wide"] .feed-column .card-body {
    padding-inline: 1rem;
  }

  :root[data-layout="wide"] .feed-column .card-project,
  :root[data-layout="wide"] .feed-column .caption {
    font-size: 1.15rem;
  }

  :root[data-layout="wide"] .feed-column .card-meta,
  :root[data-layout="wide"] .feed-column .card-time,
  :root[data-layout="wide"] .feed-column .card-placement {
    font-size: 0.85rem;
  }

  :root[data-layout="wide"] .feed-column .card-actions {
    font-size: 0.95rem;
  }

  :root[data-layout="wide"] .feed-column .tags {
    font-size: 0.88rem;
  }
}

.rail-board + .rail-board {
  margin-top: 1.4rem;
}

h2.rail-title {
  margin: 0 0 0.5rem;
  font-family: var(--rs-font-mono);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--rs-muted);
}

.rail-title a {
  color: inherit;
  text-decoration: none;
}

.rail-title a:hover,
.rail-title a:focus-visible {
  color: var(--rs-text);
}

.rail-list {
  margin: 0;
  padding: 0;
}

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

.rail-none {
  margin: 0;
  color: var(--rs-muted);
}

/* The leader's screenshot, cropped to one shape so the rail's height
   doesn't depend on it. */
.rail-thumb {
  display: block;
  aspect-ratio: 16 / 9;
  margin-bottom: 0.35rem;
  overflow: hidden;
  background-size: cover;
  background-position: center;
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
}

.rail-thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* On short screens only the first board is pictured, so the rail fits
   without scrolling inside it. */
@media (max-height: 899px) {
  .rail-board + .rail-board .rail-thumb {
    display: none;
  }
}

.rail-row {
  display: flex;
  gap: 0.5rem;
  align-items: baseline;
  padding-block: 0.2rem;
  color: var(--rs-text);
  text-decoration: none;
}

.rail-row:hover .rail-name,
.rail-row:focus-visible .rail-name {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

.rail-rank {
  color: var(--rs-muted);
}

.rail-rank-1 {
  color: var(--rs-amber);
}

.rail-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rail-name.tag-cat,
.rail-name.tag-platform {
  color: var(--rs-link);
}

.rail-count {
  color: var(--rs-muted);
}

/* Docs read as plain text on the page, not as a card. */
article.docs-body {
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  box-shadow: none;
}

article.docs-body > header.docs-head {
  margin: 0 0 1.5rem;
  padding: 0 0 1rem;
  background: none;
  border-bottom: 1px solid var(--rs-border);
}

.docs-head h1 {
  margin: 0.2rem 0 0.4rem;
  font-family: var(--rs-font-mono);
  font-size: 1.9rem;
  line-height: 1.2;
}

.docs-markdown {
  margin: 0;
  font-family: var(--rs-font-mono);
  font-size: 0.78rem;
  color: var(--rs-muted);
}

.docs-breadcrumb {
  margin: 0;
  font-family: var(--rs-font-mono);
  font-size: 0.78rem;
  color: var(--rs-amber);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

/* Headings are link targets: leave room under the sticky header. */
.prose h2,
.prose h3 {
  scroll-margin-top: 5rem;
}

.prose table {
  font-size: 0.9rem;
}

.prose th {
  font-family: var(--rs-font-mono);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--rs-muted);
}

.prose td code {
  white-space: nowrap;
}

/* Callouts from "> [!NOTE]", "> [!TIP]", "> [!WARNING]". */
.prose blockquote[class^="markdown-alert"] {
  padding: 0.8rem 1rem;
  border-left-width: 3px;
}

.prose blockquote[class^="markdown-alert"]::before {
  display: block;
  margin-bottom: 0.3rem;
  font-family: var(--rs-font-mono);
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.prose blockquote.markdown-alert-note {
  border-left-color: var(--rs-link);
}

.prose blockquote.markdown-alert-note::before {
  content: "Note";
  color: var(--rs-link);
}

.prose blockquote.markdown-alert-tip {
  border-left-color: var(--rs-accent);
}

.prose blockquote.markdown-alert-tip::before {
  content: "Tip";
  color: var(--rs-accent);
}

.prose blockquote.markdown-alert-warning,
.prose blockquote.markdown-alert-caution,
.prose blockquote.markdown-alert-important {
  border-left-color: var(--rs-amber);
}

.prose blockquote.markdown-alert-warning::before,
.prose blockquote.markdown-alert-caution::before,
.prose blockquote.markdown-alert-important::before {
  content: "Warning";
  color: var(--rs-amber);
}

/* Code blocks get a copy button from app.js. */
.prose pre {
  position: relative;
}

.prose pre .copy-code {
  position: absolute;
  top: 0.4rem;
  right: 0.5rem;
  opacity: 0;
  transition: opacity 0.15s;
}

.prose pre:hover .copy-code,
.prose pre .copy-code:focus-visible {
  opacity: 1;
}

/* "Next steps" cards. */
.doc-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0.75rem;
  margin-block: 1rem;
}

a.doc-card {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding: 0.9rem 1rem;
  text-decoration: none;
  background: var(--rs-panel);
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
}

a.doc-card strong {
  font-family: var(--rs-font-mono);
  color: var(--rs-accent);
}

a.doc-card span {
  font-size: 0.9rem;
  color: var(--rs-muted);
}

a.doc-card:hover {
  border-color: var(--rs-accent);
}

/* Previous / next page. */
.docs-pager {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 3rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rs-border);
}

.docs-pager a {
  display: flex;
  flex-direction: column;
  font-family: var(--rs-font-mono);
  text-decoration: none;
}

.docs-pager a span {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--rs-muted);
}

.docs-next {
  margin-left: auto;
  text-align: right;
}

/* ------------------------------------------------------- feedback */
.feedback-form {
  margin-top: 1rem;
}

.feedback-form fieldset label {
  margin-bottom: 0.35rem;
}

.feedback-form textarea {
  font-family: var(--rs-font-sans);
}

.form-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 0 1rem;
}

.field-error {
  display: block;
  margin: -0.4rem 0 0.9rem;
  color: var(--rs-amber);
}

.form-notice {
  padding: 0.7rem 1rem;
  background: var(--rs-panel);
  border-left: 3px solid var(--rs-amber);
}

.form-note {
  margin-top: 0.75rem;
  font-size: 0.85rem;
}

/* Honeypot: off-screen for people and assistive tech, still in the form. */
.hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.feedback-sent {
  margin-top: 1rem;
  padding: 1.25rem;
  background: var(--rs-panel);
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
}

.feedback-sent h2 {
  margin-top: 0;
  font-family: var(--rs-font-mono);
  font-size: 1.1rem;
  color: var(--rs-accent);
}

/* ---------------------------------------------------- sign-in, tokens */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.login-box {
  max-width: 30rem;
  margin-top: 1rem;
}

.login-github {
  width: 100%;
}

/* `/device`: an agent's sign-in, read before approving. */
.login-box.device {
  max-width: 36rem;
}

.device-code {
  font-family: var(--rs-font-mono);
  font-size: 2rem;
  letter-spacing: 0.15em;
  color: var(--rs-accent);
}

.device-code-input {
  font-family: var(--rs-font-mono);
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.device-facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: 0.35rem 1rem;
}

.device-facts dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.device-decision {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.device-decision button {
  flex: 1 1 10rem;
}

.token-created {
  margin-block: 1rem 2rem;
  padding: 1.25rem;
  background: var(--rs-panel);
  border: 1px solid var(--rs-accent);
  border-radius: var(--rs-radius);
}

.token-created h2 {
  margin-top: 0;
  font-family: var(--rs-font-mono);
  font-size: 1.1rem;
  color: var(--rs-accent);
}

.token-secret {
  display: flex;
  gap: 0.75rem;
  align-items: center;
  margin-bottom: 1rem;
}

.token-secret code {
  overflow-wrap: anywhere;
  user-select: all;
}

/* `position` keeps visually hidden headers inside the scroll box. */
.table-scroll {
  position: relative;
  overflow-x: auto;
}

.token-table {
  font-size: 0.9rem;
}

.token-table td:not(:first-child),
.token-table th {
  white-space: nowrap;
}

.token-table form {
  margin: 0;
}

.token-table tr.expired td {
  color: var(--rs-muted);
}

.token-form fieldset label {
  margin-bottom: 0.35rem;
}

.account {
  margin-top: 2rem;
}

.account button {
  width: auto;
}

/* /hidden: one row per project, its "show again" button at the end. */
.hidden-list {
  padding: 0;
  list-style: none;
}

.hidden-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 0.6rem;
  border-bottom: 1px solid var(--rs-border);
}

.hidden-list form,
.hidden-list button {
  margin: 0;
}

/* Left in the feed where a hidden project's card was. */
.feed-note {
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
  color: var(--rs-muted);
  text-align: center;
  padding-block: 0.75rem;
}

/* The picture on /settings, with where it comes from. */
.avatar-current {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-block: 0.5rem 1rem;
}

.avatar-current p {
  margin: 0;
}

/* Account deletion: set apart, in the error colour. */
.danger-zone {
  margin-top: 3rem;
  padding: 1rem 1.25rem;
  border: 1px solid var(--rs-amber);
  border-radius: var(--rs-radius);
}

.danger-zone h2 {
  color: var(--rs-amber);
}

.delete-form input {
  max-width: 20rem;
}

.delete-form button.danger {
  display: block;
  width: auto;
  color: var(--rs-amber);
  background: transparent;
  border-color: var(--rs-amber);
}

.delete-form button.danger:hover,
.delete-form button.danger:focus-visible {
  color: var(--rs-bg);
  background: var(--rs-amber);
}

/* /settings/projects: one block per project, its releases as a list. */
.own-project {
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rs-border);
}

.own-head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  align-items: baseline;
  justify-content: space-between;
}

.own-head h2,
.own-head form {
  margin: 0;
}

.own-summary {
  margin-bottom: 0.75rem;
  font-size: 0.9rem;
}

.own-releases,
.own-media {
  padding: 0;
  list-style: none;
}

.own-releases > li,
.own-media > li {
  list-style: none;
}

.own-releases > li {
  padding-block: 0.75rem;
  border-top: 1px dashed var(--rs-border);
}

.own-release {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.6rem;
  align-items: baseline;
  margin: 0;
}

.own-todo {
  margin-top: 0.6rem;
  padding: 0.6rem 0.9rem;
  font-size: 0.9rem;
  background: var(--rs-panel);
  border-left: 3px solid var(--rs-amber);
}

.own-todo p,
.own-todo ul {
  margin-bottom: 0.3rem;
}

.own-media {
  margin: 0.75rem 0 0;
}

.own-media > li {
  display: flex;
  gap: 0.75rem;
  align-items: flex-start;
  margin-bottom: 0.6rem;
  font-size: 0.9rem;
}

.own-media > li > div {
  flex: 1;
  min-width: 0;
}

.own-media p {
  margin: 0;
}

/* The thumbnail's box is fixed, so nothing moves when it loads. */
.own-media img,
.own-thumb {
  flex: none;
  width: 96px;
  height: 60px;
  object-fit: cover;
  background: var(--rs-panel);
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
}

.own-problem {
  color: var(--rs-amber);
}

/* Actions that can't be undone open on a second click. */
.own-confirm {
  margin: 0.6rem 0 0;
  padding: 0;
  border: 0;
  font-size: 0.9rem;
}

.own-confirm summary {
  width: fit-content;
  font-family: var(--rs-font-mono);
  font-size: 0.8rem;
  color: var(--rs-muted);
  cursor: pointer;
}

.own-confirm form {
  margin: 0.5rem 0 0;
}

.own-confirm form > button:not(.link-button) {
  width: auto;
}

.own-media .own-confirm {
  margin-top: 0.25rem;
}

.own-danger summary,
button.link-button.own-delete {
  color: var(--rs-amber);
  text-align: left;
}

/* The guided flow (/settings/projects/new, /settings/projects/{slug}/release):
   numbered steps, forms in a readable column, checks as a plain list. */
.flow-back {
  margin-bottom: 0.25rem;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
}

.flow-form {
  max-width: 44rem;
  margin-top: 0.75rem;
}

.flow-form textarea {
  font-family: var(--rs-font-mono);
  font-size: 0.9rem;
}

.flow-form small.muted {
  display: block;
  margin: -0.4rem 0 0.9rem;
}

.tag-choices {
  margin-top: 0.5rem;
}

.tag-choices legend {
  margin-bottom: 0.4rem;
  font-weight: 600;
}

.tag-ai label {
  margin-bottom: 0.45rem;
}

.tag-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: 0 1rem;
}

.flow-step {
  margin-top: 2rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--rs-border);
}

.flow-step h2 {
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
  font-size: 1.25rem;
}

.flow-step h3 {
  margin: 1.25rem 0 0.5rem;
  font-size: 1rem;
}

.flow-number {
  font-family: var(--rs-font-mono);
  color: var(--rs-accent);
}

.flow-number::after {
  content: ".";
}

.flow-inline {
  margin: 0.5rem 0 0;
  font-size: 0.9rem;
}

/* The hero's preview has a fixed box, so nothing moves when it loads. */
.flow-hero {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  align-items: flex-start;
  margin: 0.75rem 0;
}

.flow-hero > div {
  flex: 1 1 16rem;
  min-width: 0;
}

.flow-hero p {
  margin: 0 0 0.3rem;
}

.flow-hero img,
.flow-hero .own-thumb {
  flex: none;
  width: 240px;
  max-width: 100%;
  height: 150px;
  object-fit: cover;
  background: var(--rs-panel);
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
}

.flow-checks {
  padding: 0;
  margin: 0.5rem 0 1rem;
  font-size: 0.9rem;
  list-style: none;
}

.flow-checks > li {
  margin-bottom: 0.35rem;
  list-style: none;
}

.gate-mark {
  display: inline-block;
  min-width: 3.4rem;
  font-family: var(--rs-font-mono);
  font-size: 0.8rem;
}

.gate-pass .gate-mark,
p.gate-pass {
  color: var(--rs-accent);
}

.gate-fail .gate-mark,
.gate-fix {
  color: var(--rs-amber);
}

.flow-alt {
  max-width: 44rem;
  margin-top: 1rem;
}

.flow-alt summary {
  font-size: 0.9rem;
  color: var(--rs-muted);
}

.flow-publish summary {
  font-size: 0.9rem;
  color: var(--rs-accent);
}

/* Report form on release pages: tucked away, small. */
.report {
  margin-top: 2rem;
  font-size: 0.9rem;
}

.report summary {
  color: var(--rs-muted);
}

.report fieldset label {
  margin-bottom: 0.3rem;
}

.report button {
  width: auto;
}

/* "Built with" on release pages. */
.models {
  padding-left: 0;
}

.models li {
  list-style: none;
  font-size: 0.9rem;
}

.model-provider {
  color: var(--rs-muted);
}

/* ------------------------------------------------------------ errors */
.error-code {
  margin: 0;
  font-family: var(--rs-font-mono);
  font-size: 4rem;
  font-weight: 600;
  line-height: 1;
  color: var(--rs-amber);
}

.error-page h1 {
  font-family: var(--rs-font-mono);
  font-size: 1.3rem;
}

/* --------------------------------------------------------------- footer */
.site-footer p {
  margin-bottom: 0.4rem;
}

.site-footer a {
  color: var(--rs-muted);
}

.site-footer {
  margin-top: 2rem;
  padding-block: 1.5rem;
  border-top: 1px solid var(--rs-border);
  font-family: var(--rs-font-mono);
  font-size: 0.75rem;
  color: var(--rs-muted);
}

/* ---------------------------------------------------- reduced motion */
@media (prefers-reduced-motion: reduce) {
  .theme-panel {
    transition: none;
  }
}

/* ---------------------------------------------------------------- stats */
/* /p/{slug}/stats: the owner's numbers (design/SITE.md §4.12).
   Charts are inline SVG bars; everything colours from the tokens, so every
   palette and both themes work. Good reads as the accent, weak as amber. */

/* The owner's way in, on the project page. */
.stats-link {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.6rem;
  margin-block: 1rem;
  padding: 0.8rem 1rem;
  border: 1px solid var(--rs-accent);
  border-radius: var(--rs-radius);
  background: var(--rs-panel);
  color: var(--rs-text);
  text-decoration: none;
}

.stats-link strong {
  font-family: var(--rs-font-mono);
  color: var(--rs-accent);
}

.stats-link span:not([aria-hidden]) {
  flex: 1 1 16rem;
  color: var(--rs-muted);
  font-size: 0.9rem;
}

.stats-link:hover strong {
  text-decoration: underline;
}

.stats-crumb {
  margin: 0;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
  color: var(--rs-muted);
}

.stats-head .page-lead {
  max-width: 46rem;
  font-size: 1rem;
}

.period-switch {
  display: inline-flex;
  margin-top: 0.5rem;
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
  overflow: hidden;
  font-family: var(--rs-font-mono);
  font-size: 0.85rem;
}

.period-switch a {
  padding: 0.35rem 0.8rem;
  color: var(--rs-muted);
  text-decoration: none;
}

.period-switch a + a {
  border-left: 1px solid var(--rs-border);
}

.period-switch a[aria-current="page"] {
  background: var(--rs-accent);
  color: var(--rs-accent-ink);
}

.stats-jump {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1rem;
  margin-top: 0.9rem;
  font-size: 0.85rem;
}

.stats-callout {
  margin-block: 1.25rem;
  padding: 0.9rem 1rem;
  border-left: 3px solid var(--rs-accent);
  background: var(--rs-panel);
}

.stats-callout h2 {
  margin-bottom: 0.4rem;
  font-size: 1.1rem;
}

.stats-callout p:last-child {
  margin-bottom: 0;
}

.stats-section {
  margin-top: 2.5rem;
  scroll-margin-top: 4.5rem;
}

.stats-section > h2 {
  font-family: var(--rs-font-mono);
  font-size: 1.25rem;
}

.stats-section h2 small {
  margin-left: 0.5rem;
  font-family: var(--rs-font-sans);
  font-size: 0.8rem;
  font-weight: 400;
}

.stats-section h3 {
  margin-top: 1.5rem;
  font-size: 1rem;
}

.stats-section h4 {
  margin: 1rem 0 0.5rem;
  font-size: 0.9rem;
  color: var(--rs-muted);
}

.stats-explain {
  max-width: 46rem;
  font-size: 0.9rem;
  color: var(--rs-muted);
}

/* Headline numbers. */
.metric-grid {
  display: grid;
  /* Two tiles a row on phones, as many as fit on wider screens. */
  grid-template-columns: repeat(auto-fill, minmax(min(10rem, calc(50% - 0.4rem)), 1fr));
  gap: 0.75rem;
}

.metric-grid-small {
  margin-top: 0.75rem;
}

.metric {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.75rem 0.85rem;
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
  background: var(--rs-panel);
}

.metric-label {
  font-size: 0.8rem;
  color: var(--rs-muted);
}

.metric-value {
  font-family: var(--rs-font-mono);
  font-size: 1.5rem;
  line-height: 1.2;
}

.metric-change {
  font-family: var(--rs-font-mono);
  font-size: 0.78rem;
  color: var(--rs-muted);
}

.metric-up .metric-change {
  color: var(--rs-accent);
}

.metric-up .metric-change::before {
  content: "▲ ";
}

.metric-down .metric-change {
  color: var(--rs-amber);
}

.metric-down .metric-change::before {
  content: "▼ ";
}

.metric-hint {
  margin-top: auto;
  padding-top: 0.3rem;
  font-size: 0.75rem;
  line-height: 1.35;
  color: var(--rs-muted);
}

/* Bar charts. */
.chart-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
  gap: 1rem;
}

.chart {
  margin: 0;
  padding: 0.75rem 0.85rem 0.5rem;
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
  background: var(--rs-panel);
}

.chart figcaption {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  font-size: 0.85rem;
  color: var(--rs-muted);
}

.chart figcaption strong {
  font-family: var(--rs-font-mono);
  color: var(--rs-text);
}

.chart svg {
  display: block;
  width: 100%;
  height: 6rem;
}

.chart rect {
  fill: var(--rs-accent);
}

.chart rect:hover {
  fill: var(--rs-link);
}

.chart-marker {
  stroke: var(--rs-amber);
  stroke-width: 1.5;
  stroke-dasharray: 3 2;
}

.chart-axis {
  display: flex;
  justify-content: space-between;
  gap: 0.5rem;
  margin-top: 0.3rem;
  font-family: var(--rs-font-mono);
  font-size: 0.7rem;
  color: var(--rs-muted);
}

.chart-empty {
  display: grid;
  place-items: center;
  height: 6rem;
  margin: 0;
  font-size: 0.85rem;
  color: var(--rs-muted);
}

.chart-launch {
  padding: 0.5rem 0.6rem 0.4rem;
}

.chart-launch svg {
  height: 4rem;
}

.stats-details {
  margin-block: 1rem;
}

.stats-details summary {
  font-size: 0.9rem;
  color: var(--rs-muted);
}

.stats-table {
  font-size: 0.85rem;
}

.stats-table td,
.stats-table th {
  white-space: nowrap;
}

.stats-table td {
  font-family: var(--rs-font-mono);
}

.stats-actions {
  font-size: 0.85rem;
  color: var(--rs-muted);
}

/* Boards. */
.board-spots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
  gap: 0.75rem;
}

.board-spot {
  padding: 0.85rem 1rem;
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
  background: var(--rs-panel);
}

.board-spot-podium {
  border-color: var(--rs-accent);
}

.board-spot h3 {
  margin: 0 0 0.2rem;
  font-size: 1rem;
}

.board-spot p {
  margin-bottom: 0.4rem;
  font-size: 0.85rem;
}

.spot-rank {
  font-family: var(--rs-font-mono);
  font-size: 1.6rem !important;
  line-height: 1.2;
}

.spot-rank small {
  font-family: var(--rs-font-sans);
  font-size: 0.75rem;
  color: var(--rs-muted);
}

.progress,
.bar {
  display: block;
  height: 0.45rem;
  border-radius: 999px;
  background: var(--rs-border);
  overflow: hidden;
}

.progress span,
.bar span {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--rs-accent);
}

.progress-label {
  margin-top: 0.3rem;
  font-family: var(--rs-font-mono);
  font-size: 0.75rem !important;
  color: var(--rs-muted);
}

.spot-status {
  margin-bottom: 0 !important;
}

.placements-won {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0;
}

/* Pico puts the marker on each item. */
.placements-won li {
  margin: 0;
  list-style: none;
}

.release-stats p {
  font-size: 0.9rem;
}

/* Release by release. */
.release-stats {
  margin-top: 1.5rem;
  padding: 1rem 1.1rem;
  border: 1px solid var(--rs-border);
  border-radius: var(--rs-radius);
  scroll-margin-top: 4.5rem;
}

.release-stats-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.75rem;
  margin-bottom: 0.5rem;
}

.release-stats-head h3 {
  margin: 0;
  font-family: var(--rs-font-mono);
  font-size: 1.1rem;
}

.release-stats-head span {
  font-size: 0.85rem;
}

.release-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: 0.5rem 2rem;
}

.feed-place {
  padding: 0.6rem 0.8rem;
  border-left: 3px solid var(--rs-accent);
  background: var(--rs-panel);
  font-size: 0.9rem;
}

.feed-place-rank {
  margin-bottom: 0.4rem;
}

.feed-place-rank strong {
  font-family: var(--rs-font-mono);
}

.score-parts {
  display: grid;
  gap: 0.2rem;
  margin: 0;
  font-size: 0.85rem;
}

.score-parts div {
  display: grid;
  grid-template-columns: 9.5rem 1fr;
  gap: 0.75rem;
}

.score-parts dt {
  color: var(--rs-muted);
  font-weight: 400;
}

.score-parts dd {
  margin: 0;
}

.rates {
  margin-bottom: 0.5rem;
  font-size: 0.85rem;
}

.rates th[scope="row"] {
  font-weight: 400;
}

.rates td {
  font-family: var(--rs-font-mono);
}

.rates td small {
  display: block;
  font-family: var(--rs-font-sans);
  font-size: 0.72rem;
  color: var(--rs-muted);
}

.rate-good td:first-of-type {
  color: var(--rs-accent);
}

.rate-low td:first-of-type {
  color: var(--rs-amber);
}

.plain-list {
  padding-left: 1.1rem;
  font-size: 0.9rem;
}

/* Shares: gallery reach, vote bands, referrers. */
.reach,
.share-list {
  display: grid;
  gap: 0.35rem;
  max-width: 40rem;
  padding: 0;
  list-style: none;
  font-size: 0.85rem;
}

.reach li,
.share-list li {
  display: grid;
  grid-template-columns: minmax(8rem, 16rem) 1fr 4rem;
  align-items: center;
  gap: 0.75rem;
  margin: 0;
}

.reach-value,
.share-value {
  font-family: var(--rs-font-mono);
  text-align: right;
}

.share-label {
  overflow-wrap: anywhere;
}

.bar-inline {
  display: inline-block;
  width: 5rem;
  vertical-align: middle;
}

.checks {
  display: grid;
  gap: 0.3rem;
  padding: 0;
  list-style: none;
  font-size: 0.85rem;
}

.checks li {
  margin: 0;
}

.checks small {
  display: block;
  margin-left: 1.4rem;
  color: var(--rs-muted);
}

.check-mark {
  display: inline-block;
  width: 1rem;
  font-weight: 700;
}

.check-ok .check-mark {
  color: var(--rs-accent);
}

.check-failed .check-mark {
  color: var(--rs-amber);
}

.stats-api code {
  word-break: break-all;
}

@media (max-width: 600px) {
  .reach li,
  .share-list li {
    grid-template-columns: 1fr 3.5rem;
  }

  .reach .bar,
  .share-list .bar {
    grid-column: 1 / -1;
    grid-row: 2;
  }

  .score-parts div {
    grid-template-columns: 1fr;
    gap: 0;
  }
}
