/* ─────────────────────────────────────────────────────────────
   Songs: site-specific blocks (BEM, CUBE composition)
   Sits on top of default.css (theme tokens + base + layout primitives).
   ───────────────────────────────────────────────────────────── */

/* ── Masthead: full-bleed editorial header ───────────────── */
.masthead {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  align-items: baseline;
  justify-content: space-between;
  padding-block: var(--space-s);
  padding-inline: var(--space-l);
  border-block-end: var(--rule-thick);
}

.masthead__wordmark {
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
}

.masthead__nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  align-items: center;
  font-family: var(--font-sans);
  font-size: var(--step--1);
}

/* Thin vertical rule fencing the page links (About/Prompts) off from the
   account area (notifications + identity). */
.masthead__divider {
  align-self: center;
  inline-size: 0;
  block-size: var(--step-1);
  border-inline-start: var(--rule-soft);
}

/* Account menu: the name is a dropdown trigger holding Profile / Settings /
   Log out. Same details-popover pattern as .manage-menu below; only the
   summary's weight differs (the name reads as identity, not a nav item). */
.account-menu {
  position: relative;
}

.account-menu__summary {
  display: inline-flex;
  gap: var(--space-3xs);
  align-items: baseline;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: 600;
  color: var(--color-ink);
  cursor: pointer;
  list-style: none;
}
.account-menu__summary::-webkit-details-marker {
  display: none;
}

.account-menu[open]::before {
  position: fixed;
  inset: 0;
  z-index: 9;
  content: "";
  background: color-mix(in srgb, var(--color-ink) 8%, transparent);
}

.account-menu[open] > .account-menu__summary {
  position: relative;
  z-index: 10;
}

.account-menu__chevron::before {
  display: inline-block;
  font-size: var(--step--2);
  content: "\25BE"; /* ▾ */
  transition: transform 0.12s ease;
}
.account-menu[open] .account-menu__chevron::before {
  transform: rotate(180deg);
}

.account-menu__panel {
  position: absolute;
  inset-block-start: calc(100% + var(--space-2xs));
  inset-inline-end: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  min-inline-size: 10rem;
  padding: var(--space-2xs);
  background: var(--color-bg);
  border: var(--rule-thin);
}

.account-menu__link {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink);
  text-decoration: none;
}
.account-menu__link:hover {
  color: var(--color-accent);
}

/* The log-out button sits in the same list as the links; strip the button
   chrome so it reads as a menu item, left-aligned like the anchors. */
.account-menu__logout {
  margin: 0;
}
.account-menu__logout-button {
  padding: 0;
  text-align: start;
  cursor: pointer;
  background: none;
  border: none;
}

/* ── Prompt strip: three-column ruled strip ──────────────── */
.prompt-strip {
  display: grid;
  grid-template-columns: minmax(8rem, 12rem) 1fr minmax(14rem, 20rem);
  gap: var(--space-l);
  align-items: start;
  padding-block: var(--space-l);
  padding-inline: var(--space-l);
  border-block-end: var(--rule-thin);
}

.prompt-strip__week {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  padding-inline-end: var(--space-l);
  border-inline-end: var(--rule-soft);
}

.prompt-strip__week-marker {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink);
}

.prompt-strip__week-date {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.prompt-strip__lede {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

.prompt-strip__heading {
  max-inline-size: 30ch;
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 400;
  line-height: 1.05;
}

.prompt-strip__heading-accent {
  font-style: italic;
  color: var(--color-accent);
}

.prompt-strip__brief {
  max-inline-size: 50ch;
  margin: 0;
  font-size: var(--step-0);
  color: var(--color-ink-soft);
}

/* Requirements: a quieter footnote under the brief — small label + smaller,
   more muted text so it reads as fine print, not part of the prompt itself. */
.prompt-strip__requirements {
  margin-block-start: var(--space-2xs);
}

.prompt-strip__requirements-heading {
  margin-block: 0 var(--space-3xs);
  font-family: var(--font-sans);
  font-size: var(--step--2);
  font-weight: 600;
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
}

.prompt-strip__requirements-text {
  max-inline-size: 50ch;
  margin: 0;
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.prompt-strip__cta {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  padding-inline-start: var(--space-l);
  border-inline-start: var(--rule-soft);
}

.prompt-strip__submit {
  display: inline-block;
  align-self: start;
  padding: var(--space-xs) var(--space-m);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--color-accent-ink);
  text-decoration: none;
  background: var(--color-accent);
}

.prompt-strip__submit:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

.prompt-strip__meta {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

/* Single-column collapse for narrow viewports */
@media (max-width: 50rem) {
  .prompt-strip {
    grid-template-columns: 1fr;
    gap: var(--space-m);
  }
  .prompt-strip__week,
  .prompt-strip__cta {
    padding-inline: 0;
    border: 0;
  }
  .prompt-strip__cta {
    padding-block-start: var(--space-m);
    border-block-start: var(--rule-soft);
  }
}

/* ── Feed: documentary two-column layout below the strip ─── */
.feed {
  padding-block: var(--space-l);
  padding-inline: var(--space-l);
}

/* Per-week archive page (week.html): a back link above the reused prompt-strip
   + entry cards. The heavy lifting is borrowed from .prompt-strip / .feed. */
.week__back {
  padding-block-start: var(--space-m);
  padding-inline: var(--space-l);
}
.week__back-link {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  text-decoration: none;
}
.week__back-link:hover {
  color: var(--color-accent);
}

.feed__rail {
  /* z-index + an explicit composited layer (translateZ) so native <audio>
     controls, which Chrome promotes to their own layer, scroll *behind* the
     sticky rail instead of painting over the filters. */
  position: sticky;
  inset-block-start: 0;
  z-index: 30;
  align-self: start;
  padding-block: var(--space-s);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  background: rgb(from var(--color-bg) r g b / 0.72);
  isolation: isolate;
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
  transform: translateZ(0);
}

/* On narrow viewports the rail spans the full feed width. Bleed the
   blurred backdrop to the section's edges so the frosted effect reads
   as a band, not a floating pill. */
@media (max-width: 40rem) {
  .feed__rail {
    padding-inline: var(--space-l);
    margin-inline: calc(var(--space-l) * -1);
  }
}

.feed__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
}

/* ── Filter strip: lives in the feed rail, anchors navigate ─── */
.filter-strip {
  font-family: var(--font-sans);
  font-size: var(--step--1);
}

.filter-strip__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  padding: 0;
  margin: 0;
  list-style: none;
}

.filter-strip__item {
  margin: 0;
}

.filter-strip__option {
  display: inline-block;
  padding-block: var(--space-3xs);
  padding-inline: var(--space-2xs);
  color: var(--color-ink-soft);
  text-decoration: none;
  border-inline-start: 2px solid transparent;
}

.filter-strip__option:hover {
  color: var(--color-ink);
}

.filter-strip__option--active {
  font-weight: 500;
  color: var(--color-ink);
  border-inline-start-color: var(--color-accent);
}

/* Per-filter count. */
.filter-strip__count {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  font-variant-numeric: tabular-nums;
  color: var(--color-ink-muted);
}

/* A filter with nothing to show: dimmed and not interactive. */
.filter-strip__option--disabled {
  color: var(--color-ink-muted);
  pointer-events: none;
  cursor: default;
  opacity: 0.5;
}
.filter-strip__option--disabled .filter-strip__count {
  color: inherit;
}

/* On narrow viewports the rail stacks above the list, so flow the
   filters horizontally to keep the layout compact. */
@media (max-width: 40rem) {
  .filter-strip__list {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-2xs);
  }
  .filter-strip__option {
    border-block-end: 2px solid transparent;
    border-inline-start: 0;
  }
  .filter-strip__option--active {
    border-block-end-color: var(--color-accent);
  }
}

.feed__empty {
  padding-block: var(--space-2xl);
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  font-style: italic;
  color: var(--color-ink-muted);
  text-align: center;
}

/* Shown in place of the prompt strip + feed when no week is live. */
.feed-no-week {
  padding-block: var(--space-3xl);
  padding-inline: var(--space-l);
  text-align: center;
}

.feed-no-week__heading {
  margin-block: 0 var(--space-2xs);
  font-family: var(--font-serif);
  font-size: var(--step-2);
  font-weight: 400;
}

.feed-no-week__copy {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  font-style: italic;
  color: var(--color-ink-muted);
}

/* ── Group chooser: / for members of more than one group ── */
.group-chooser {
  max-inline-size: var(--measure);
  padding-block: var(--space-2xl);
  padding-inline: var(--space-l);
  margin-inline: auto;
}

.group-chooser__heading {
  margin-block: 0 var(--space-m);
  font-family: var(--font-serif);
  font-size: var(--step-2);
  font-weight: 400;
}

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

.group-chooser__item {
  border-block-start: var(--rule-thin);
}

.group-chooser__item:last-child {
  border-block-end: var(--rule-thin);
}

.group-chooser__link {
  display: block;
  padding-block: var(--space-s);
  font-family: var(--font-serif);
  font-size: var(--step-1);
  text-decoration: none;
}

.group-chooser__link:hover {
  color: var(--color-accent);
}

.group-chooser__empty {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  font-style: italic;
  color: var(--color-ink-muted);
}

/* ── Song detail page: full lyrics + audio + comments shell ── */
.song {
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
  max-inline-size: 70ch;
  padding-block: var(--space-l);
  padding-inline: var(--space-l);
  margin-inline: auto;
}

.song__back {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  text-decoration: none;
}

.song__back:hover {
  color: var(--color-accent);
}

.song__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding-block-end: var(--space-m);
  border-block-end: var(--rule-thin);
}

.song__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 500;
  line-height: 1.05;
}

.song__byline {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  align-items: baseline;
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.song__contributor {
  color: var(--color-ink-soft);
}

.song__role-badge {
  padding-inline: var(--space-3xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  line-height: 1.4;
  color: var(--color-ink);
  letter-spacing: 0.04em;
  border: var(--rule-thin);
}

.song__player {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

/* Server-rendered peaks. fill is inherited by the bare <rect> bars. Stretches
   to the player width via the svg's preserveAspectRatio="none". */
.song__waveform {
  display: block;
  inline-size: 100%;
  block-size: var(--space-2xl);
  fill: var(--color-ink);
}

/* player.js wraps the waveform in this track and overlays the played-so-far
   clone + playhead. With no JS the track never appears: the bare waveform and
   the native controls remain the whole player. */
.song__waveform-track {
  position: relative;
  inline-size: 100%;
  cursor: pointer;
}

/* The played layer is a tinted clone of the same bars, revealed left-to-right
   by --played (0..1, set per frame from the audio's timeupdate). clip-path
   keeps the reveal to the bar shapes; the gaps stay clear. */
.song__waveform--played {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  inline-size: 100%;
  block-size: 100%;
  pointer-events: none;
  clip-path: inset(0 calc((1 - var(--played, 0)) * 100%) 0 0);
  fill: var(--color-accent);
}

.song__playhead {
  position: absolute;
  inset-block: 0;
  inset-inline-start: calc(var(--played, 0) * 100%);
  inline-size: 2px;
  pointer-events: none;
  background: var(--color-ink);
}

.song__audio {
  inline-size: 100%;
}

.song__section-heading {
  padding-block-end: var(--space-2xs);
  margin-block: 0 var(--space-s);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
  border-block-end: var(--rule-soft);
}

/* "About this song" prose: goldmark output, read as a short essay. */
.song__description {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--color-ink-soft);
}
.song__description p {
  margin-block: var(--space-s);
}
.song__description p:first-child {
  margin-block-start: 0;
}

/* Lyrics block is goldmark output. Hard-wraps mean every newline becomes a
   <br>, so paragraphs read like a printed lyric sheet, and ## headings turn
   into per-section labels. */
.song__lyrics {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--color-ink);
}
.song__lyrics p {
  margin-block: var(--space-s);
}
.song__lyrics h2 {
  margin-block: var(--space-l) var(--space-xs);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
}
.song__lyrics h2:first-child {
  margin-block-start: 0;
}

.song__edit-link {
  margin-inline-start: var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.04em;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}
.song__delete-link {
  margin-inline-start: var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-accent);
  letter-spacing: 0.04em;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

/* ── Feedback / comments ─────────────────────────────────── */
.song__comment-count {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-soft);
}

.comments {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  padding: 0;
  margin-block: 0 var(--space-l);
  list-style: none;
}

.comments__thread {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.comments__replies {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding-inline-start: var(--space-m);
  margin-block: var(--space-2xs) 0;
  list-style: none;
  border-inline-start: var(--rule-soft);
}

.comment {
  font-family: var(--font-serif);
  color: var(--color-ink);
}

.comment__byline {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  align-items: baseline;
  margin-block: 0 var(--space-3xs);
  font-family: var(--font-sans);
  font-size: var(--step--1);
}

.comment__author {
  font-weight: 600;
  color: var(--color-ink);
}

.comment__role-badge {
  padding-inline: var(--space-3xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  line-height: 1.4;
  color: var(--color-ink);
  letter-spacing: 0.04em;
  border: var(--rule-thin);
}

.comment__posted,
.comment__edited {
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.comment__body {
  margin: 0;
  line-height: 1.5;
}
.comment__body p {
  margin-block: var(--space-3xs);
}

.comment__tombstone {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.comments__empty,
.comments__locked {
  margin-block: 0 var(--space-l);
  font-family: var(--font-serif);
  font-style: italic;
  color: var(--color-ink-muted);
}

.comments__reply > summary {
  inline-size: max-content;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-accent);
  letter-spacing: 0.04em;
  cursor: pointer;
}

/* Post / reply form */
.comment-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  margin-block-start: var(--space-s);
}
.comment-form--reply {
  margin-block-start: var(--space-2xs);
}

.comment-form__label {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.comment-form__input {
  inline-size: 100%;
  padding: var(--space-2xs);
  font-family: var(--font-serif);
  font-size: var(--step-0);
  color: var(--color-ink);
  resize: vertical;
  background: var(--color-bg);
  border: var(--rule-thin);
}

.comment-form__submit {
  align-self: start;
  padding: var(--space-2xs) var(--space-m);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-bg);
  letter-spacing: 0.04em;
  cursor: pointer;
  background: var(--color-ink);
  border: var(--rule-thin);
}

.comment-form__error {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-accent);
}

/* Per-comment edit / delete controls */
.comment__actions {
  display: flex;
  gap: var(--space-m);
  margin-block-start: var(--space-3xs);
}

.comment__action > summary {
  inline-size: max-content;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
  cursor: pointer;
}

.comment__delete-prompt {
  margin-block: var(--space-2xs);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

/* ── Notifications bell (masthead) ───────────────────────── */
.notif {
  position: relative;
}

/* Inherits the masthead nav's sans so it sits flush with the page links;
   only the count badge keeps mono (numerals). */
.notif__summary {
  display: inline-flex;
  gap: var(--space-3xs);
  align-items: baseline;
  font-size: var(--step--1);
  color: var(--color-ink);
  cursor: pointer;
  list-style: none;
}
.notif__summary::-webkit-details-marker {
  display: none;
}

/* Dismiss film: while the popover is open, a faint wash over the rest of
   the page signals that clicking anywhere outside closes it. As a pseudo-
   element of the <details>, clicks on it hit-test to the details itself,
   which notifications.js reads as "outside" and closes. The summary is
   lifted above the film so the bell stays crisp and its native toggle
   keeps receiving clicks; the panel already sits at z-index 10. */
.notif[open]::before {
  position: fixed;
  inset: 0;
  z-index: 9;
  content: "";
  background: color-mix(in srgb, var(--color-ink) 8%, transparent);
}

.notif[open] > .notif__summary {
  position: relative;
  z-index: 10;
}

/* Caret signalling the summary opens a dropdown; flips when the panel is open. */
.notif__chevron::before {
  display: inline-block;
  font-size: var(--step--2);
  content: "\25BE"; /* ▾ */
  transition: transform 0.12s ease;
}
.notif[open] .notif__chevron::before {
  transform: rotate(180deg);
}

.notif__count {
  padding-inline: var(--space-3xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  line-height: 1.3;
  color: var(--color-accent-ink);
  background: var(--color-accent);
  border: var(--rule-thin);
}

.notif__panel {
  position: absolute;
  inset-block-start: calc(100% + var(--space-2xs));
  inset-inline-end: 0;
  z-index: 10;
  inline-size: 22rem;
  max-inline-size: 90vw;
  max-block-size: 24rem;
  padding: var(--space-2xs);
  overflow-y: auto;
  background: var(--color-bg);
  border: var(--rule-thin);
}

.notif__list {
  display: flex;
  flex-direction: column;
  padding: 0;
  margin: 0;
  list-style: none;
}

.notif__item {
  border-block-end: var(--rule-soft);
}
.notif__item:last-child {
  border-block-end: none;
}
.notif__item--unread {
  background: var(--color-accent-wash, transparent);
}

.notif__link {
  display: block;
  padding: var(--space-2xs);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  line-height: 1.4;
  color: var(--color-ink);
  text-decoration: none;
}
.notif__link:hover {
  text-decoration: underline;
}

.notif__actor,
.notif__song {
  font-weight: 600;
}

.notif__empty {
  margin: var(--space-2xs);
  font-family: var(--font-serif);
  font-size: var(--step--1);
  font-style: italic;
  color: var(--color-ink-muted);
}

/* ── Manage dropdown (masthead) ──────────────────────────── */
/* Same details-popover pattern as the notifications bell above; menu.js
   handles click-away via the [open]::before film. */
.manage-menu {
  position: relative;
}

.manage-menu__summary {
  display: inline-flex;
  gap: var(--space-3xs);
  align-items: baseline;
  font-size: var(--step--1);
  color: var(--color-ink);
  cursor: pointer;
  list-style: none;
}
.manage-menu__summary::-webkit-details-marker {
  display: none;
}

.manage-menu[open]::before {
  position: fixed;
  inset: 0;
  z-index: 9;
  content: "";
  background: color-mix(in srgb, var(--color-ink) 8%, transparent);
}

.manage-menu[open] > .manage-menu__summary {
  position: relative;
  z-index: 10;
}

.manage-menu__chevron::before {
  display: inline-block;
  font-size: var(--step--2);
  content: "\25BE"; /* ▾ */
  transition: transform 0.12s ease;
}
.manage-menu[open] .manage-menu__chevron::before {
  transform: rotate(180deg);
}

.manage-menu__panel {
  position: absolute;
  inset-block-start: calc(100% + var(--space-2xs));
  inset-inline-end: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  min-inline-size: 12rem;
  padding: var(--space-2xs);
  background: var(--color-bg);
  border: var(--rule-thin);
}

.manage-menu__link {
  font-size: var(--step--1);
  color: var(--color-ink);
  text-decoration: none;
}
.manage-menu__link:hover {
  color: var(--color-accent);
}

/* On phones the masthead nav wraps, so the bell sits mid-row and a panel
   anchored to the bell's right edge runs off the left of the screen. Anchor
   it to the masthead instead and span the viewport (with gutters) so it
   always stays on-screen. The manage menu gets the same treatment. */
@media (max-width: 40rem) {
  .masthead {
    position: relative;
  }
  /* The nav wraps on phones (flex-wrap), so the decorative vertical rules
     would dangle at row breaks and their gaps eat width the admin nav can't
     spare. Drop them here; they still fence page links from the account area
     on wider screens where the nav stays on one row. */
  .masthead__divider {
    display: none;
  }
  .notif,
  .manage-menu,
  .account-menu {
    position: static;
  }
  .notif__panel,
  .manage-menu__panel,
  .account-menu__panel {
    inset-block-start: calc(100% + var(--space-3xs));
    inset-inline: var(--space-s);
    inline-size: auto;
    max-inline-size: none;
  }
}

/* ── Auth pages: signup and login forms ──────────────────── */
.auth {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  max-inline-size: 30rem;
  padding-block: var(--space-xl);
  padding-inline: var(--space-l);
  margin-inline: auto;
}

.auth__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-3);
  font-weight: 500;
}

.auth__lede {
  margin: 0;
  font-family: var(--font-serif);
  color: var(--color-ink-soft);
}

.auth__error {
  padding: var(--space-s);
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-accent);
  background: rgb(from var(--color-accent) r g b / 0.05);
  border: var(--rule-thin);
  border-color: var(--color-accent);
}

.auth__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

.auth__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.auth__label {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-soft);
}

.auth__input {
  padding: var(--space-2xs) var(--space-xs);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  color: var(--color-ink);
  background: var(--color-surface);
  border: var(--rule-thin);
}

.auth__input:focus {
  outline: var(--focus-ring);
  outline-offset: -2px;
}

.auth__hint {
  font-family: var(--font-sans);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.auth__submit {
  align-self: start;
  padding: var(--space-xs) var(--space-m);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--color-accent-ink);
  background: var(--color-accent);
}

.auth__submit:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

/* Passkey sign-in: a secondary (outline) button so the password "Sign in"
   stays the primary accent-filled action. The "or" sets it apart. */
.auth__passkey {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  align-items: start;
}

.auth__or {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.auth__passkey-button {
  padding: var(--space-xs) var(--space-m);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--color-ink);
  cursor: pointer;
  background: var(--color-bg);
  border: var(--rule-thin);
}

.auth__passkey-button:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

.auth__alt {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.auth__note {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-0);
  line-height: 1.5;
  color: var(--color-ink-soft);
}

/* ── Landing: anonymous home page ─────────────────────────── */
.landing {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  max-inline-size: 36rem;
  padding-block: var(--space-2xl);
  padding-inline: var(--space-l);
  margin-inline: auto;
}

.landing__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-5);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
}

.landing__lede {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--color-ink-soft);
}

.landing__cta {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step-0);
}

.landing__cta-divider {
  padding-inline: var(--space-2xs);
  color: var(--color-ink-muted);
}

/* ── About page ────────────────────────────────────────────── */
.about {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  max-inline-size: 36rem;
  padding-block: var(--space-2xl);
  padding-inline: var(--space-l);
  margin-inline: auto;
}

.invite {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  max-inline-size: 36rem;
  padding-block: var(--space-2xl);
  padding-inline: var(--space-l);
  margin-inline: auto;
}
.invite__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-3);
}
.invite__copy {
  margin: 0;
}
.invite__cancel {
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

.about__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
}

.about__copy {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--color-ink-soft);
}

.about__aside {
  font-size: var(--step-0);
  color: var(--color-ink-muted);
}

/* ── Formatting guide (/formatting) ───────────────────────── */
.formatting {
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
  max-inline-size: 44rem;
  padding-block: var(--space-2xl);
  padding-inline: var(--space-l);
  margin-inline: auto;
}

.formatting__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
}

.formatting__copy {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--color-ink-soft);
}

.formatting__aside {
  font-size: var(--step-0);
  color: var(--color-ink-muted);
}

.formatting__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  margin: 0;
}

/* Each example is a hairline-topped row; the label sits above a two-up
   "type this / get this" pair. */
.formatting__example {
  padding-block-start: var(--space-m);
  border-block-start: var(--rule-thin);
}

.formatting__label {
  margin-block-end: var(--space-xs);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
}

.formatting__pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-m);
  align-items: start;
  margin: 0;
}

.formatting__source {
  padding: var(--space-s);
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  line-height: 1.6;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
  background: var(--color-surface);
  border: var(--rule-thin);
}

/* song__lyrics supplies the type + spacing for headings/paragraphs/etc; the
   frame here just matches the source box beside it. */
.formatting__rendered {
  padding: var(--space-s);
  border: var(--rule-thin);
}

@media (max-width: 40rem) {
  .formatting__pair {
    grid-template-columns: 1fr;
  }
}

.about__toc {
  margin-block: var(--space-m) var(--space-l);
}

.about__toc-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-l);
  padding: 0;
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  list-style: none;
}

/* The three about-page sections (why / ownership / upcoming) share a top rule
   so they read as distinct, anchor-linked blocks. scroll-margin keeps the
   heading clear of the viewport top when reached from the contents links. */
.about__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  padding-block-start: var(--space-m);
  scroll-margin-block-start: var(--space-m);
  border-block-start: var(--rule-soft);
}

.about__subheading {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-2);
  font-weight: 400;
}

.about__upcoming-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding-inline-start: var(--space-l);
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-0);
  line-height: 1.5;
  color: var(--color-ink-soft);
}

/* ── Privacy page (/privacy) ──────────────────────────────────
   Its own block, parallel to .about: a prose page with a table of
   contents and hairline-ruled, anchor-linked sections. */
.privacy {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  max-inline-size: 44rem;
  padding-block: var(--space-2xl);
  padding-inline: var(--space-l);
  margin-inline: auto;
}

.privacy__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
}

.privacy__copy {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.6;
  color: var(--color-ink-soft);
}

.privacy__aside {
  font-size: var(--step-0);
  color: var(--color-ink-muted);
}

.privacy__toc {
  margin-block: var(--space-2xs) var(--space-s);
}

.privacy__toc-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-l);
  padding: 0;
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  list-style: none;
}

/* Each section shares a soft top rule so it reads as a distinct, anchor-linked
   block; scroll-margin keeps the heading clear of the viewport top when
   reached from the contents links. */
.privacy__section {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  padding-block-start: var(--space-m);
  scroll-margin-block-start: var(--space-m);
  border-block-start: var(--rule-soft);
}

.privacy__subheading {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-2);
  font-weight: 400;
}

.privacy__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding-inline-start: var(--space-l);
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-0);
  line-height: 1.5;
  color: var(--color-ink-soft);
}

/* ── Group section switcher (Feed | Chat) ──────────────────────
   Two flush, equal square segments. The active one carries an oxide-red
   underline. On the feed it pins to the bottom on mobile (thumb zone); on the
   chat page it stays at the top (the composer owns the bottom there). */
.group-nav {
  display: flex;
  max-inline-size: 78rem;
  margin-inline: auto;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  border-block-end: var(--rule-thin);
}
.group-nav__seg {
  display: inline-flex;
  flex: 1 1 0;
  gap: var(--space-2xs);
  align-items: center;
  justify-content: center;
  padding: var(--space-xs) var(--space-m);
  color: var(--color-ink-muted);
  text-decoration: none;
  border-block-end: 2px solid transparent;
}
.group-nav__seg:hover {
  color: var(--color-accent);
}
.group-nav__seg--active {
  font-weight: 600;
  color: var(--color-ink);
  border-block-end-color: var(--color-accent);
}
/* Unread badge on the Chat segment: small square, oxide accent. */
.group-nav__count {
  display: inline-block;
  padding-inline: var(--space-3xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-accent-ink);
  background: var(--color-accent);
}

@media (max-width: 40rem) {
  /* On the feed, pin the switcher to the bottom so Chat is in the thumb zone. */
  .group-nav[data-nav-active="feed"] {
    position: fixed;
    inset-block-end: 0;
    inset-inline: 0;
    /* High z-index + its own composited layer (translateZ) so native <audio>
       controls, which Chrome promotes to a compositing layer, don't paint over
       the pinned switcher. */
    z-index: 100;
    max-inline-size: none;
    padding-block-end: env(safe-area-inset-bottom);
    background: var(--color-bg);
    border-block-start: var(--rule-thin);
    border-block-end: 0;
    isolation: isolate;
    transform: translateZ(0);
  }
  /* Reserve room so the fixed switcher doesn't cover the foot of the feed. */
  #main:has(> .group-nav[data-nav-active="feed"]) {
    padding-block-end: var(--space-2xl);
  }
}

/* ── Group chat (/g/{slug}/chat) ───────────────────────────────
   Ledger layout from sketch 007 variant A: one column, square monogram
   avatars, your own messages carry a highlight panel + oxide spine. Hard
   radius 0, identity by rule and tint, never rounded bubbles. */
.chat {
  display: flex;
  flex-direction: column;
  max-inline-size: 52rem;
  padding-block: var(--space-s) 0;
  padding-inline: var(--space-m);
  margin-inline: auto;
}

/* The composer + typing line, pinned to the bottom of the viewport while the
   message log scrolls above. Last child of .chat, so sticky bottom keeps it in
   view through the whole history. */
.chat__foot {
  position: sticky;
  inset-block-end: 0;
  padding-block: var(--space-2xs) var(--space-s);
  padding-block-end: max(var(--space-s), env(safe-area-inset-bottom));
  background: var(--color-bg);
}

.chat__header {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-m);
  align-items: baseline;
  padding-block-end: var(--space-s);
  border-block-end: var(--rule-thin);
}
.chat__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-3);
  font-weight: 600;
  letter-spacing: -0.01em;
}
.chat__context {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  letter-spacing: 0.04em;
}

.chat__log {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  padding: 0;
  margin-block: var(--space-s);
  list-style: none;
}

.chat__empty {
  font-family: var(--font-serif);
  font-size: var(--step-0);
  color: var(--color-ink-muted);
}

.chat__error {
  padding: var(--space-2xs) var(--space-s);
  margin-block: 0 var(--space-2xs);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-accent);
  border: 1px solid var(--color-accent);
}

/* A single message: square monogram + content. */
.msg {
  display: flex;
  gap: var(--space-s);
  align-items: flex-start;
}
.msg__avatar {
  display: grid;
  flex: 0 0 auto;
  place-items: center;
  inline-size: 2.25rem;
  block-size: 2.25rem;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink);
  background: var(--color-bg);
  border: var(--rule-thin);
}
.msg__content {
  flex: 1 1 auto;
  min-inline-size: 0;
}
.msg__byline {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
  align-items: baseline;
  margin-block: 0 var(--space-3xs);
  font-family: var(--font-sans);
  font-size: var(--step--1);
}
.msg__author {
  font-weight: 600;
  color: var(--color-ink);
  text-decoration: none;
}
.msg__author:hover {
  color: var(--color-accent);
}
.msg__you {
  padding-inline: var(--space-3xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-accent-ink);
  letter-spacing: 0.04em;
  background: var(--color-accent);
}
.msg__role-badge {
  padding-inline: var(--space-3xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink);
  letter-spacing: 0.04em;
  border: var(--rule-thin);
}
.msg__time {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}
.msg__body {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-0);
  line-height: 1.5;
  color: var(--color-ink);
  overflow-wrap: anywhere;
}
.msg__tombstone {
  font-style: italic;
  color: var(--color-ink-muted);
}
.msg__edited {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

/* Inline edit/delete controls under a message: collapsed <details> that open to
   a small form, mirroring the comment actions. */
.msg__actions {
  display: flex;
  gap: var(--space-s);
  margin-block-start: var(--space-2xs);
  font-family: var(--font-sans);
  font-size: var(--step--1);
}
.msg__action summary {
  color: var(--color-ink-muted);
  cursor: pointer;
}
.msg__action summary:hover {
  color: var(--color-accent);
}
.msg__action-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  margin-block-start: var(--space-2xs);
}

/* Your own messages: pale highlight panel + an oxide-red spine, square. */
.msg--me .msg__body {
  padding: var(--space-2xs) var(--space-s);
  background: var(--color-highlight);
  border-inline-start: 2px solid var(--color-accent);
}
.msg--me .msg__avatar {
  color: var(--color-surface);
  background: var(--color-ink);
  border-color: var(--color-ink);
}

/* Variant-C grouping: a continuation of the same author's run drops the avatar
   and byline and tucks up closer to the message above it. */
.msg--cont {
  margin-block-start: calc(-1 * var(--space-2xs));
}
.msg--cont .msg__avatar {
  visibility: hidden;
}
.msg--cont .msg__byline {
  display: none;
}

/* An @mention autolink: bold + pale highlight, no underline, so it reads as a
   person rather than a generic link. */
.mention {
  padding-inline: 2px;
  font-weight: 600;
  color: var(--color-ink);
  text-decoration: none;
  background: var(--color-highlight);
}
.mention:hover {
  color: var(--color-accent);
}

/* A #week-N prompt reference, autolinked by renderChatBody to that week's
   archive page. Monospace + accent underline, with a ▸ lead-in, so it reads as
   a pointer to a past prompt rather than a generic link (ported from sketch 007). */
.prompt-ref {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-accent);
  white-space: nowrap;
  text-decoration: none;
  border-block-end: 1px solid var(--color-accent);
}
.prompt-ref::before {
  content: "▸ ";
}

/* Typing indicator: "X is typing" + animated square dots. */
.chat__typing {
  display: flex;
  gap: var(--space-2xs);
  align-items: center;
  min-block-size: 1.5rem;
  margin-block: 0 var(--space-2xs);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}
/* The class sets display:flex, which would override the UA [hidden] rule, so
   restore hiding explicitly. */
.chat__typing[hidden] {
  display: none;
}
.typing-dots {
  display: inline-flex;
  gap: 3px;
}
.typing-dots span {
  display: inline-block;
  inline-size: 5px;
  block-size: 5px;
  background: var(--color-ink-muted);
  animation: blink 1.2s infinite both;
}
.typing-dots span:nth-child(2) {
  animation-delay: 0.2s;
}
.typing-dots span:nth-child(3) {
  animation-delay: 0.4s;
}
@keyframes blink {
  0%,
  80%,
  100% {
    opacity: 0.2;
  }
  40% {
    opacity: 1;
  }
}

/* Composer: square text field + send button. */
.composer {
  position: relative;
  display: flex;
  gap: var(--space-2xs);
  align-items: stretch;
  padding-block-start: var(--space-s);
  border-block-start: var(--rule-thin);
}
.composer__field {
  flex: 1 1 auto;
  min-block-size: 3rem;
  padding: var(--space-2xs) var(--space-s);
  font-family: var(--font-serif);
  font-size: var(--step-0);
  resize: vertical;
  background: var(--color-surface);
  border: var(--rule-thin);
}
.composer__btn {
  flex: 0 0 auto;
  padding-inline: var(--space-m);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink);
  background: var(--color-bg);
  border: var(--rule-thin);
}
.composer__btn--send {
  font-weight: 600;
  color: var(--color-surface);
  background: var(--color-ink);
  border-color: var(--color-ink);
}
.composer__btn--send:hover {
  background: var(--color-accent);
  border-color: var(--color-accent);
}

/* @-mention typeahead: a member-pick dropdown anchored above the composer.
   Built by chat.js; hidden until "@" opens it. Hard radius 0 like everything. */
.mention-menu {
  position: absolute;
  inset-block-end: calc(100% + var(--space-2xs));
  inset-inline: 0;
  z-index: 5;
  max-block-size: 14rem;
  padding: 0;
  margin: 0;
  overflow-y: auto;
  list-style: none;
  background: var(--color-surface);
  border: var(--rule-thin);
}
.mention-menu__item {
  display: flex;
  gap: var(--space-xs);
  align-items: baseline;
  padding: var(--space-2xs) var(--space-s);
  cursor: pointer;
}
.mention-menu__item--active {
  color: var(--color-surface);
  background: var(--color-ink);
}
.mention-menu__handle {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: 600;
}
.mention-menu__name {
  font-family: var(--font-sans);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}
.mention-menu__item--active .mention-menu__name {
  color: var(--color-surface);
}

/* ── Card: a single submission in the feed ─────────────────── */
.card {
  position: relative;
  display: grid;
  grid-template-areas:
    "head    meta"
    "audio   audio"
    "markers .";
  grid-template-columns: 1fr auto;
  gap: var(--space-2xs) var(--space-l);
  align-items: start;
  padding-block: var(--space-m);
  border-block-end: var(--rule-soft);
}

.card:last-child {
  border-block-end: 0;
}

.card__head {
  display: flex;
  flex-direction: column;
  grid-area: head;
  gap: var(--space-3xs);
}

.card__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-2);
  font-weight: 500;
  line-height: 1.15;
}

.card__title-link {
  color: var(--color-ink);
  text-decoration: none;
}

.card__title-link:hover {
  color: var(--color-accent);
}

/* Stretch the title link over the whole card so clicking anywhere — markers,
   byline, footer — opens the song (people kept trying to). The only
   interactive child, the audio player, is raised above this overlay below. */
.card__title-link::after {
  position: absolute;
  inset: 0;
  content: "";
}

.card__byline {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: baseline;
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.card__contributor {
  color: var(--color-ink-soft);
}

.card__role-badge {
  padding-block: 0;
  padding-inline: var(--space-3xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  line-height: 1.4;
  color: var(--color-ink);
  letter-spacing: 0.04em;
  border: var(--rule-thin);
}

.card__posted {
  color: var(--color-ink-muted);
}

.card__audio {
  position: relative;
  z-index: 1;
  grid-area: audio;
  inline-size: 100%;
  /* Native player keeps its own visual chrome; nothing to override here
     beyond layout. Browsers will respect color-scheme: light so this
     reads coherently on the warm paper background. z-index lifts it above the
     stretched title-link overlay so play/seek still work. */
}

.card__markers {
  display: flex;
  flex-wrap: wrap;
  grid-area: markers;
  gap: var(--space-xs);
  padding: 0;
  margin: 0;
  list-style: none;
}

.card__marker {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
}

.card__marker--needs-feedback,
.card__marker--needs-listening {
  color: var(--color-accent);
}

.card__meta {
  grid-area: meta;
  align-self: center;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.card__comments {
  font-variant-numeric: tabular-nums;
}

@media (max-width: 40rem) {
  .card {
    grid-template-areas:
      "head"
      "audio"
      "markers"
      "meta";
    grid-template-columns: 1fr;
    gap: var(--space-2xs);
  }
  .card__meta {
    align-self: start;
  }
}

/* ── Verify-email banner ───────────────────────────────────────
   Sits between the masthead and the prompt strip when the signed-in
   user hasn't confirmed their email yet. Resend button posts to
   /verify/resend; the page reloads with ?verification_sent=1 which
   swaps the banner to the confirmation copy. */

.verify-banner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  align-items: center;
  justify-content: space-between;
  padding: var(--space-s) var(--space-m);
  background: var(--color-highlight);
  border-block-end: var(--rule-thin);
}

.verify-banner__copy,
.verify-banner__sent {
  max-inline-size: 60ch;
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink);
}

.verify-banner__sent {
  font-weight: 500;
}

.verify-banner__form {
  margin: 0;
}

.verify-banner__resend {
  padding: var(--space-2xs) var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-bg);
  letter-spacing: 0.04em;
  cursor: pointer;
  background: var(--color-ink);
  border: 0;
}

.verify-banner__resend:hover {
  background: var(--color-accent);
}

/* ── Submit page (sketch 004 variant B) ────────────────────────
   Two columns: rail with the week context + title + audio
   placeholder + submit, main column with the markdown editor.
   Collapses to single column under 64rem. */

.submit-page {
  display: grid;
  grid-template-columns: 24rem 1fr;
  gap: 0;
  min-block-size: calc(100vh - 5rem);
}

/* Shown instead of the form when the viewer already submitted this week. */
.submit-done {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  max-inline-size: 36rem;
  padding-block: var(--space-2xl);
  padding-inline: var(--space-l);
  margin-inline: auto;
}

.submit-done__heading {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-3);
  font-weight: 400;
}

.submit-done__copy {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--color-ink-soft);
}

.submit-done__actions {
  display: flex;
  gap: var(--space-m);
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step-0);
}

.submit-page__rail {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  padding: var(--space-l) var(--space-m);
  background: var(--color-bg);
  border-inline-end: var(--rule-thin);
}

.submit-page__week {
  padding-block-end: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  border-block-end: var(--rule-thin);
}

.submit-page__week strong {
  display: block;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  font-weight: 600;
  color: var(--color-ink);
}

.submit-page__prompt {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.3;
}

.submit-page__brief {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.submit-page__divider {
  margin: 0;
  border: 0;
  border-block-start: var(--rule-thin);
}

.submit-page__error {
  padding: var(--space-xs) var(--space-s);
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-accent-ink);
  background: var(--color-accent);
}

/* The window-closed notice on late submissions: informative, not alarming. */
.submit-page__late-notice {
  padding-block: var(--space-2xs);
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step--1);
  font-style: italic;
  color: var(--color-ink-muted);
  border-block-start: var(--rule-soft);
}

.submit-page__field {
  display: block;
}

.submit-page__label {
  display: block;
  margin-block-end: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.04em;
}

.submit-page__input {
  inline-size: 100%;
  padding: var(--space-xs) var(--space-s);
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.4;
  background: var(--color-surface);
  border: var(--rule-thin);
}

.submit-page__input:focus {
  outline: var(--focus-ring);
  outline-offset: -1px;
}

/* Audio dropzone is a <label> wrapping the file input so clicking anywhere
   in the dashed box opens the system picker. The input is visually hidden
   but still focusable for keyboard users. */
.submit-page__dropzone {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding: var(--space-s);
  cursor: pointer;
  background: var(--color-surface);
  border: 2px dashed var(--color-ink);
  transition: background 0.15s;
}

.submit-page__dropzone:hover {
  background: var(--color-highlight);
}

.submit-page__file-input {
  font-family: var(--font-sans);
  font-size: var(--step--1);
}

.submit-page__dropzone-cue {
  font-family: var(--font-serif);
  font-size: var(--step-0);
}

.submit-page__dropzone-hint {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.submit-page__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  margin-block-start: auto;
}

/* On /edit the actions sit high in the rail (right after Title) so the primary
   action is above the fold; cancel the auto top-margin that pins them to the
   rail foot on /submit. */
.submit-page__actions--top {
  margin-block-start: 0;
}

.submit-page__submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-xs) var(--space-m);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--color-accent-ink);
  cursor: pointer;
  background: var(--color-accent);
  border: 0;
}

.submit-page__submit:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

.submit-page__cancel {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  text-align: center;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

.submit-page__cancel:hover {
  color: var(--color-accent);
}

.submit-page__meta {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.submit-page__main {
  display: flex;
  flex-direction: column;
  padding: var(--space-l) var(--space-m);
}

/* ── Edit page: the heading IS the title field ─────────────────────── */
/* No separate Title box: the title shown at the top of the rail is an
   in-place editable serif input, underlined like a heading; the rule turns
   accent while it's focused. */
.edit-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  padding-block-end: var(--space-2xs);
  border-block-end: var(--rule-thin);
}

.edit-head:focus-within {
  border-block-end-color: var(--color-accent);
}

.edit-head__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
}

.edit-head__title {
  inline-size: 100%;
  padding: 0;
  font-family: var(--font-serif);
  font-size: var(--step-2);
  font-weight: 500;
  line-height: 1.15;
  color: var(--color-ink);
  background: transparent;
  border: 0;
}

.edit-head__title:focus {
  outline: 0;
}
/* Keyboard focus needs more than the hairline-colour shift on .edit-head; give
   the borderless title input the shared ring. :focus-visible keeps pointer
   clicks clean (the accent underline from :focus-within still cues those). */
.edit-head__title:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 2px;
}

/* ── Edit page: audio lives in the rail, like /submit ──────────────── */
/* A field group in the rail: current track + dropzone + a Replace button.
   It posts to its own form (form="edit-audio-form") so it can stay distinct
   from the Save-changes (title/lyrics) form it sits inside. */
.edit-audio {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.edit-audio__current {
  margin: 0;
  font-size: var(--step--1);
  color: var(--color-ink-soft);
}

/* Secondary to Save changes (the accent button at the foot of the rail): an
   outline button so the two don't compete. */
.edit-audio__submit {
  display: inline-flex;
  align-items: center;
  align-self: start;
  justify-content: center;
  padding: var(--space-2xs) var(--space-s);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--color-ink);
  cursor: pointer;
  background: transparent;
  border: var(--rule-thin);
}

.edit-audio__submit:hover {
  color: var(--color-accent-ink);
  background: var(--color-ink);
}

/* Extras: links out to the advanced per-song pages (recording snapshot). */
.edit-extras {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.edit-extras__link {
  align-self: start;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--color-ink);
}

.edit-extras__hint {
  margin: 0;
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

/* Delete control on the edit page: set apart with a divider so the
   destructive link reads as a deliberate, separate action from the edits
   above it. */
.edit-danger {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  margin-block-start: var(--space-l);
}

.edit-danger__link {
  align-self: start;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--color-accent);
}

.edit-danger__hint {
  margin: 0;
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

/* Recording snapshot page: a narrow single-column page like /formatting.
   The drop zone + parsed preview grow into this shell. */
.snapshot-page {
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
  max-inline-size: 44rem;
  padding-block: var(--space-2xl);
  padding-inline: var(--space-l);
  margin-inline: auto;
}

.snapshot-page__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
}

.snapshot-page__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.02em;
}

.snapshot-page__privacy {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-0);
  line-height: 1.6;
  color: var(--color-ink-soft);
}

.snapshot-page__back {
  align-self: start;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink);
}

/* The drop target: same dashed-border language as the submit dropzone. */
.snapshot-drop__label {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding: var(--space-l) var(--space-s);
  cursor: pointer;
  background: var(--color-surface);
  border: 2px dashed var(--color-ink);
  transition: background 0.15s;
}

.snapshot-drop__label:hover,
.snapshot-drop--over .snapshot-drop__label {
  background: var(--color-highlight);
}

.snapshot-drop__input {
  font-family: var(--font-sans);
  font-size: var(--step--1);
}

.snapshot-drop__cue {
  font-family: var(--font-serif);
  font-size: var(--step-0);
}

.snapshot-drop__hint {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.snapshot-page__error {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-s);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-accent-ink);
  background: var(--color-accent);
}

/* display:flex above beats the UA [hidden] rule; restate it (same as the
   preview block). Covers the error container and its toggled children. */
.snapshot-page__error[hidden],
.snapshot-report[hidden] {
  display: none;
}

.snapshot-page__error-text {
  margin: 0;
}

.snapshot-report {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
}

.snapshot-report__copy,
.snapshot-report__done {
  margin: 0;
  font-size: var(--step--2);
}

.snapshot-report__send {
  align-self: start;
  padding: var(--space-3xs) var(--space-xs);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--color-accent-ink);
  cursor: pointer;
  background: transparent;
  border: 1px solid currentcolor;
}

.snapshot-report__send[disabled] {
  cursor: default;
  opacity: 0.6;
}

/* The parsed-project review: what would upload, and nothing else. */
.snapshot-preview {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

/* An author display beats the UA's [hidden] rule, so restate it: the
   preview stays gone until the script has something to show. */
.snapshot-preview[hidden] {
  display: none;
}

.snapshot-preview__heading {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-2);
  font-weight: 700;
}

.snapshot-preview__subheading {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
}

.snapshot-preview__source {
  margin: 0;
  font-size: var(--step--1);
  color: var(--color-ink-soft);
}

.snapshot-preview__facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-3xs) var(--space-s);
  margin: 0;
}

.snapshot-preview__fact-label {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.snapshot-preview__fact-value {
  margin: 0;
  font-size: var(--step--1);
}

.snapshot-preview__tracks,
.snapshot-preview__channels {
  margin: 0;
  font-size: var(--step--1);
  line-height: 1.6;
}

.snapshot-preview__kind {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.snapshot-preview__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding-block-start: var(--space-s);
  border-block-start: var(--rule-thin);
}

.snapshot-preview__approve {
  align-self: start;
  padding: var(--space-2xs) var(--space-s);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--color-accent-ink);
  cursor: pointer;
  background: var(--color-accent);
  border: 1px solid var(--color-accent);
}

.snapshot-preview__approve[disabled] {
  cursor: default;
  opacity: 0.6;
}

.snapshot-preview__approve-note {
  margin: 0;
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

/* Track sheet on the song-detail page: an attached snapshot, rendered from
   stored JSON. The heading reuses .song__section-heading. */
.track-sheet__facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-3xs) var(--space-s);
  margin-block: 0 var(--space-s);
}

.track-sheet__fact-label {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.track-sheet__fact-value {
  margin: 0;
  font-size: var(--step--1);
}

.track-sheet__subheading {
  margin-block: var(--space-s) var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
}

.track-sheet__tracks,
.track-sheet__channels {
  margin: 0;
  font-size: var(--step--1);
  line-height: 1.6;
}

.track-sheet__kind {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

/* Signal-flow block diagram (sketch 006, variant D): a server-rendered SVG
   styled entirely with theme tokens (the markup carries no inline colour).
   The scroller keeps a wide graph from blowing out the column. */
.flow-scroller {
  padding: var(--space-s);
  overflow-x: auto;
  background: var(--color-surface);
  border: var(--rule-soft);
}

.flow {
  display: block;
  min-inline-size: 48rem;
  font-family: var(--font-mono);
  /* Raw 12px, not a --step token, on purpose: the server lays out box
     widths against a hard-coded 12px monospace metric (internal/flow
     fontW), so the rendered text size must match that constant or labels
     stop fitting their boxes. */
  font-size: 12px;
}

.flow__edge {
  fill: none;
  stroke: var(--color-ink-soft);
  stroke-width: 1;
}

.flow__edge--send {
  stroke: var(--color-accent);
}

.flow__node rect {
  fill: var(--color-bg);
  stroke: var(--color-rule);
}

.flow__node text {
  fill: var(--color-ink);
}

/* Returns (reverb/delay sends) read as dashed; the submix and output read
   as filled, inverting their label. */
.flow__node--ret rect {
  stroke-dasharray: 3 2;
}

.flow__node--mix rect,
.flow__node--out rect {
  fill: var(--color-ink);
}

.flow__node--mix text,
.flow__node--out text {
  fill: var(--color-bg);
}

/* Click-to-isolate (flow.js): a clicked channel lights its wiring and the
   rest recedes. .is-lit overrides the dim, so the focused subgraph stays at
   full strength. */
.flow__node {
  cursor: pointer;
}

.flow__node,
.flow__edge {
  transition: opacity 0.15s ease;
}

.flow--focus .flow__node,
.flow--focus .flow__edge {
  opacity: 0.15;
}

.flow--focus .is-lit {
  opacity: 1;
}

.submit-page__lyrics-label {
  margin-block-end: var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
}

/* Textarea sits inside .lyric-editor__panel--write which owns the visible
   border + background; the textarea itself is borderless so the panel reads
   as a single field. */
.submit-page__lyrics {
  flex: 1;
  min-block-size: 22rem;
  padding: var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step-0);
  line-height: 1.6;
  resize: vertical;
  outline: 0;
  background: transparent;
  border: 0;
}

.submit-page__lyrics:focus {
  outline: var(--focus-ring);
  outline-offset: -1px;
}

/* "About this song" textarea in the rail: a modest multiline field, smaller
   than the main lyric editor. */
.submit-page__description {
  inline-size: 100%;
  min-block-size: 6rem;
  padding: var(--space-xs);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  line-height: 1.5;
  resize: vertical;
  background: transparent;
  border: var(--rule-thin);
}
.submit-page__description:focus {
  outline: var(--focus-ring);
  outline-offset: -1px;
}

.submit-page__lyrics-hint {
  margin-block-start: var(--space-2xs);
  font-family: var(--font-sans);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.submit-page__lyrics-hint code {
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

/* The panel has no padding (the textarea owns its own), so without this the
   hint would sit flush against the panel's left border. Match the textarea's
   inset and give it room below. */
.lyric-editor__panel--write .submit-page__lyrics-hint {
  padding-block-end: var(--space-xs);
  padding-inline: var(--space-s);
}

/* ── Write/Preview tabs ─────────────────────────────────────
   CSS-only tab switching driven by two hidden radios. Preview
   panel is HTMX-populated with goldmark output. The `:has()`
   selector lets the parent react to the checked state without
   any JS. */

.lyric-editor {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-block-size: 0;
}

.lyric-editor__state {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  pointer-events: none;
  opacity: 0;
}

.lyric-editor__tabs {
  display: flex;
  gap: 0;
  border-block-end: var(--rule-thin);
}

.lyric-editor__tab {
  padding: var(--space-2xs) var(--space-s);
  margin-block-end: -1px;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
  cursor: pointer;
  background: var(--color-bg);
  border-block-start: var(--rule-thin);
  border-inline-start: var(--rule-thin);
  border-inline-end: var(--rule-thin);
}

.lyric-editor__tab:hover {
  color: var(--color-accent);
}

/* Active-tab styling derived from the corresponding radio's checked state. */
.lyric-editor:has(#editor-write:checked) .lyric-editor__tab--write,
.lyric-editor:has(#editor-preview:checked) .lyric-editor__tab--preview {
  color: var(--color-ink);
  background: var(--color-surface);
  border-block-end: 1px solid var(--color-surface);
}

/* Keyboard focus indicator. The focusable control is the visually-hidden
   radio, so the ring has to be drawn on its corresponding tab label. */
.lyric-editor:has(#editor-write:focus-visible) .lyric-editor__tab--write,
.lyric-editor:has(#editor-preview:focus-visible) .lyric-editor__tab--preview {
  outline: var(--focus-ring);
  outline-offset: -2px;
}

.lyric-editor__panel {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-block-size: 24rem;
  background: var(--color-surface);
  border-block-end: var(--rule-thin);
  border-inline: var(--rule-thin);
}

.lyric-editor__panel--write {
  display: flex;
}
.lyric-editor__panel--preview {
  display: none;
  padding: var(--space-s);
}

.lyric-editor:has(#editor-preview:checked) .lyric-editor__panel--write {
  display: none;
}
.lyric-editor:has(#editor-preview:checked) .lyric-editor__panel--preview {
  display: block;
}

.submit-page__preview-hint {
  margin: 0;
  font-family: var(--font-serif);
  font-style: italic;
  color: var(--color-ink-muted);
}

/* Visually hide an element but keep it accessible to screen readers. */
.u-visually-hidden {
  position: absolute;
  inline-size: 1px;
  block-size: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  white-space: nowrap;
  border: 0;
  clip: rect(0, 0, 0, 0);
}

@media (max-width: 64rem) {
  .submit-page {
    grid-template-columns: 1fr;
  }
  .submit-page__rail {
    border-block-end: var(--rule-thin);
    border-inline-end: 0;
  }
  /* Stacked layout: the editor would otherwise collapse to its content
     height. Let it fill the viewport so there's real room to write, and pin
     the Write/Preview tabs to the top so they stay reachable while scrolling
     the textarea. Background + z-index stop the textarea bleeding through the
     gap beside the tabs while sticky. */
  .submit-page__main {
    padding-block: 0;
  }
  .lyric-editor {
    min-block-size: 100dvh;
  }
  .lyric-editor__tabs {
    position: sticky;
    inset-block-start: 0;
    z-index: 2;
    background: var(--color-bg);
  }
}

/* ── Organiser: author a prompt ───────────────────────────── */
.admin-prompt {
  max-inline-size: 48rem;
  padding: var(--space-l) var(--space-m) var(--space-2xl);
  margin-inline: auto;
}

.admin-prompt__title {
  margin-block: 0 var(--space-2xs);
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1.1;
}

.admin-prompt__intro {
  max-inline-size: var(--measure);
  padding-block-end: var(--space-m);
  margin-block: 0 var(--space-l);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  border-block-end: var(--rule-thin);
}

.admin-prompt__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

.admin-prompt__error {
  padding: var(--space-xs) var(--space-s);
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-accent-ink);
  background: var(--color-accent);
}

.admin-prompt__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.admin-prompt__label {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.04em;
}

.admin-prompt__hint {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.admin-prompt__input,
.admin-prompt__textarea {
  inline-size: 100%;
  padding: var(--space-xs) var(--space-s);
  margin-block-start: var(--space-3xs);
  background: var(--color-surface);
  border: var(--rule-thin);
}

.admin-prompt__input {
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.4;
}

.admin-prompt__textarea {
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.5;
  resize: vertical;
}

.admin-prompt__input:focus,
.admin-prompt__textarea:focus {
  outline: var(--focus-ring);
  outline-offset: -1px;
}

.admin-prompt__submit {
  display: inline-flex;
  align-items: center;
  align-self: start;
  padding: var(--space-xs) var(--space-l);
  margin-block-start: var(--space-2xs);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--color-accent-ink);
  background: var(--color-accent);
  border: 0;
}

.admin-prompt__submit:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

/* ── Manager: prompt schedule ─────────────────────────────── */
.admin-schedule {
  max-inline-size: 56rem;
  padding: var(--space-l) var(--space-m) var(--space-2xl);
  margin-inline: auto;
}

.admin-schedule__back {
  display: inline-block;
  margin-block-end: var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  text-decoration: none;
}

.admin-schedule__back:hover {
  color: var(--color-accent);
}

/* Groups the manage/admin section-switcher links in a named nav landmark
   without changing layout: display:contents leaves the links as direct flex
   children of the page header, so the existing spacing is untouched. */
.manage-nav {
  display: contents;
}

.admin-schedule__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  align-items: baseline;
  justify-content: space-between;
  padding-block-end: var(--space-s);
  border-block-end: var(--rule-thick);
}

.admin-schedule__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1.1;
}

.admin-schedule__new {
  padding: var(--space-2xs) var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-decoration: none;
  background: var(--color-surface);
  border: var(--rule-thin);
}

.admin-schedule__new:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

/* Flash confirmation, shared across create/edit flows (see _flash.html).
   Symmetric block margins: flex+gap parents (.song, .admin-detail) space it
   anyway; block-flow parents (.profile, .settings) rely on the end margin. */
.flash {
  padding: var(--space-xs) var(--space-s);
  margin-block: var(--space-m);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  background: var(--color-highlight);
  border-inline-start: var(--rule-thick);
}

.admin-schedule__list {
  padding: 0;
  margin-block: var(--space-m) 0;
  list-style: none;
}

.admin-schedule__row {
  display: grid;
  grid-template-columns: 5rem 13rem 1fr 7rem;
  gap: var(--space-s);
  align-items: baseline;
  padding-block: var(--space-s);
  border-block-start: var(--rule-soft);
}

.admin-schedule__row:last-child {
  border-block-end: var(--rule-soft);
}

.admin-schedule__week {
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

.admin-schedule__dates {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.admin-schedule__prompt {
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.3;
}

.admin-schedule__status {
  justify-self: start;
  padding: var(--space-3xs) var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  white-space: nowrap;
  border: var(--rule-thin);
}

.admin-schedule__row[data-status="current"] .admin-schedule__status {
  color: var(--color-accent-ink);
  background: var(--color-accent);
  border-color: var(--color-accent);
}

.admin-schedule__row[data-status="past"] {
  color: var(--color-ink-muted);
}

.admin-schedule__row[data-status="past"] .admin-schedule__status {
  color: var(--color-ink-muted);
  border-color: var(--color-rule-soft);
}

.admin-schedule__empty {
  margin-block: var(--space-l) 0;
  color: var(--color-ink-muted);
}

@media (max-width: 48rem) {
  .admin-schedule__row {
    grid-template-columns: 1fr;
    gap: var(--space-3xs);
  }
}

/* Schedule prompt is a link to the detail; keep it reading as the headline. */
a.admin-schedule__prompt {
  text-decoration: none;
}
a.admin-schedule__prompt:hover {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

/* ── Manage members: roster + invites ─────────────────────── */
.manage-members {
  max-inline-size: 56rem;
  padding: var(--space-l) var(--space-m) var(--space-2xl);
  margin-inline: auto;
}

.manage-members__back {
  display: inline-block;
  margin-block-end: var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  text-decoration: none;
}

.manage-members__back:hover {
  color: var(--color-accent);
}

.manage-members__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  align-items: baseline;
  justify-content: space-between;
  padding-block-end: var(--space-s);
  border-block-end: var(--rule-thick);
}

.manage-members__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1.1;
}

.manage-members__prompts-link {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  text-decoration: none;
}

.manage-members__prompts-link:hover {
  color: var(--color-accent);
}

.manage-members__section {
  margin-block-start: var(--space-l);
}

.manage-members__subtitle {
  margin: 0 0 var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 400;
  color: var(--color-ink-muted);
}

.manage-members__list,
.manage-members__invites {
  padding: 0;
  margin: 0;
  list-style: none;
}

.manage-members__row,
.manage-members__invite {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  align-items: baseline;
  padding-block: var(--space-s);
  border-block-start: var(--rule-soft);
}

.manage-members__row:last-child,
.manage-members__invite:last-child {
  border-block-end: var(--rule-soft);
}

.manage-members__name {
  font-family: var(--font-serif);
  font-size: var(--step-1);
}

.manage-members__handle {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
  text-decoration: none;
}

.manage-members__role,
.manage-members__invite-role {
  padding: var(--space-3xs) var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  border: var(--rule-thin);
}

.manage-members__row[data-role="manager"] .manage-members__role,
.manage-members__invite[data-role="manager"] .manage-members__invite-role {
  color: var(--color-accent-ink);
  background: var(--color-accent);
  border-color: var(--color-accent);
}

.manage-members__invite-to {
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

.manage-members__invite-kind {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.manage-members__invite-url {
  flex: 1 1 18rem;
  min-inline-size: 0;
  padding: var(--space-3xs) var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  background: var(--color-surface);
  border: var(--rule-thin);
}

/* The remove/revoke forms sit at the row's end. */
.manage-members__remove,
.manage-members__revoke {
  margin-inline-start: auto;
}

.manage-members__remove-btn,
.manage-members__revoke-btn {
  padding: var(--space-3xs) var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  cursor: pointer;
  background: var(--color-surface);
  border: var(--rule-thin);
}

.manage-members__remove-btn:hover,
.manage-members__revoke-btn:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

/* Invite forms: label stacks over its control, laid out inline via l-cluster. */
.manage-members__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.manage-members__label {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.manage-members__input,
.manage-members__select {
  padding: var(--space-2xs) var(--space-xs);
  font: inherit;
  font-size: var(--step--1);
  background: var(--color-bg);
  border: var(--rule-thin);
}

.manage-members__submit {
  align-self: end;
  padding: var(--space-2xs) var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  cursor: pointer;
  background: var(--color-surface);
  border: var(--rule-thin);
}

.manage-members__submit:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

.manage-members__empty {
  margin-block: var(--space-s) 0;
  color: var(--color-ink-muted);
}

/* ── Organiser: prompt detail ─────────────────────────────── */
.admin-detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  max-inline-size: 48rem;
  padding: var(--space-l) var(--space-m) var(--space-2xl);
  margin-inline: auto;
}

.admin-detail__back {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  text-decoration: none;
}

.admin-detail__back:hover {
  color: var(--color-accent);
}

.admin-detail__head {
  padding-block-end: var(--space-s);
  border-block-end: var(--rule-thick);
}

.admin-detail__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  align-items: baseline;
  margin-block: 0 var(--space-xs);
}

.admin-detail__week {
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

.admin-detail__dates {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.admin-detail__status {
  padding: var(--space-3xs) var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  border: var(--rule-thin);
}

.admin-detail__status[data-status="current"] {
  color: var(--color-accent-ink);
  background: var(--color-accent);
  border-color: var(--color-accent);
}

.admin-detail__status[data-status="past"] {
  color: var(--color-ink-muted);
  border-color: var(--color-rule-soft);
}

.admin-detail__prompt {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1.1;
}

.admin-detail__section {
  margin: 0;
}

.admin-detail__label {
  margin-block: 0 var(--space-3xs);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  letter-spacing: 0.04em;
}

.admin-detail__text {
  max-inline-size: var(--measure);
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.6;
  white-space: pre-wrap;
}

.admin-detail__edit {
  align-self: start;
  padding: var(--space-xs) var(--space-l);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--color-accent-ink);
  text-decoration: none;
  background: var(--color-accent);
}

.admin-detail__edit:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

/* Detail actions: edit + remove-from-queue (upcoming only). */
.admin-detail__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  align-items: start;
}

/* Expand-to-confirm remove: pure <details>, no JS, no one-click delete. */
.admin-detail__remove {
  font-family: var(--font-mono);
  font-size: var(--step--1);
}

.admin-detail__remove-toggle {
  padding-block: var(--space-xs);
  color: var(--color-ink-muted);
  cursor: pointer;
  list-style: none;
}

.admin-detail__remove-toggle::-webkit-details-marker {
  display: none;
}

.admin-detail__remove-toggle:hover,
.admin-detail__remove[open] .admin-detail__remove-toggle {
  color: var(--color-accent);
}

.admin-detail__remove-confirm {
  max-inline-size: 28rem;
  padding: var(--space-s);
  margin-block-start: var(--space-2xs);
  border: 1px solid var(--color-accent);
}

.admin-detail__remove-warning {
  margin-block: 0 var(--space-s);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-soft);
}

.admin-detail__remove-button {
  padding: var(--space-2xs) var(--space-s);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--color-accent-ink);
  cursor: pointer;
  background: var(--color-accent);
  border: 0;
}

.admin-detail__remove-button:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

/* ── Loading / pending states ────────────────────────────── */
/* A small hard-edged (radius 0) square spinner, in keeping with the
   no-rounded-corners rule. Inherits currentColor so it tints to its context. */
.spinner {
  display: inline-block;
  inline-size: 0.7em;
  block-size: 0.7em;
  margin-inline-end: 0.45em;
  vertical-align: -0.06em;
  border: 2px solid currentColor;
  border-block-start-color: transparent; /* the gap makes the rotation legible */
  animation: spin 0.7s linear infinite;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
/* Honour a reduced-motion preference. The canonical universal !important reset
   trips the project's no-!important lint, so instead still each motion source
   by name. This block sits after all of them in source order, so the matching
   selectors win on order alone. Add new animated selectors here when they land. */
@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation: none;
  }
  .account-menu__chevron::before,
  .notif__chevron::before,
  .manage-menu__chevron::before,
  .submit-page__dropzone,
  .snapshot-drop__label,
  .flow__node,
  .flow__edge {
    transition: none;
  }
}

/* A submit button mid-request (forms.js sets aria-busy + disabled): keep it
   legible but clearly inert. */
button[aria-busy="true"] {
  cursor: progress;
  opacity: 0.7;
}

/* HTMX swap indicator (feed filters, lyric preview). Hidden until htmx marks
   the request in flight, then shown — display toggling (not just opacity) so it
   reserves no space when idle and can't shift the layout. */
.htmx-indicator {
  display: none;
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}
.htmx-indicator.htmx-request {
  display: inline-flex;
}

/* ── Error pages (404 / 500 / 403) ───────────────────────── */
.error-page {
  max-inline-size: 32rem;
  padding-block: var(--space-2xl) var(--space-xl);
  padding-inline: var(--space-l);
  margin-inline: auto;
  text-align: center;
}
.error-page__status {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step-3);
  font-variant-numeric: tabular-nums;
  color: var(--color-ink-muted);
}
.error-page__heading {
  margin-block: var(--space-2xs) var(--space-s);
  font-family: var(--font-serif);
  font-size: var(--step-2);
  color: var(--color-ink);
}
.error-page__message {
  margin-block: 0 var(--space-l);
  font-family: var(--font-sans);
  color: var(--color-ink-soft);
}
.error-page__back {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-accent);
}

/* ── Member profile (/u/{handle}) — sketch 005, variant A ───── */
.profile {
  padding-block: var(--space-l) var(--space-2xl);
}
.profile__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-l);
  align-items: flex-start;
  padding-block-end: var(--space-l);
  border-block-end: var(--rule-thin);
}
.profile__identity {
  flex: 1 1 20rem;
}
.profile__name {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.01em;
}
.profile__handle {
  margin-block: var(--space-3xs) 0;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}
.profile__bio {
  margin-block: var(--space-l) 0;
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.4;
}

/* Avatar: auto initials on a handle-derived colour. Square (hard radius). */
.avatar {
  display: grid;
  flex-shrink: 0;
  place-items: center;
  inline-size: 120px;
  block-size: 120px;
  font-family: var(--font-serif);
  font-size: var(--step-3);
  font-weight: 600;
  line-height: 1;
  color: #fff;
  user-select: none;
  background: var(--avatar-bg, var(--color-ink-soft));
}
.avatar--0 {
  --avatar-bg: #4a6c6f;
}
.avatar--1 {
  --avatar-bg: #8a4b2f;
}
.avatar--2 {
  --avatar-bg: #5b6b73;
}
.avatar--3 {
  --avatar-bg: #6b6234;
}
.avatar--4 {
  --avatar-bg: #7a4a5a;
}
.avatar--5 {
  --avatar-bg: #3f5a4a;
}
.avatar--6 {
  --avatar-bg: #b8330a;
}
.avatar--7 {
  --avatar-bg: #4f5a6e;
}

/* Music links: labelled monochrome marks, oxide on hover. */
.links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs) var(--space-m);
  margin-block-start: var(--space-m);
}
.link {
  display: inline-flex;
  gap: var(--space-3xs);
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  text-decoration: none;
}
.link:hover .link__platform {
  color: var(--color-accent);
}
.icon {
  display: inline-block;
  flex-shrink: 0;
  inline-size: 1.15em;
  block-size: 1.15em;
  vertical-align: -0.15em;
  fill: currentColor;
}
.svg-sprite {
  display: none;
}

/* Catalogue: one row per song, reusing the feed/archive register. */
.catalogue {
  margin-block-start: var(--space-xl);
}
.catalogue__heading {
  margin: 0 0 var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 400;
  color: var(--color-ink-muted);
  letter-spacing: 0.06em;
}
.catalogue__list {
  padding: 0;
  margin: 0;
  list-style: none;
}
.song-row {
  display: grid;
  grid-template-columns: 6rem 1fr auto;
  gap: var(--space-m);
  align-items: baseline;
  padding-block: var(--space-s);
  text-decoration: none;
  border-block-start: var(--rule-soft);
}
.song-row__week {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}
.song-row__title {
  font-family: var(--font-serif);
  font-size: var(--step-1);
}
.song-row:hover .song-row__title {
  color: var(--color-accent);
}
.song-row__meta {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  white-space: nowrap;
}
.catalogue__empty {
  padding-block: var(--space-s);
  font-family: var(--font-serif);
  color: var(--color-ink-muted);
  border-block-start: var(--rule-soft);
}

@media (max-width: 40rem) {
  .song-row {
    grid-template-columns: 1fr;
    gap: var(--space-3xs);
  }
}

/* Edit-profile affordance on own profile head. */
.profile__edit {
  align-self: start;
  padding: var(--space-3xs) var(--space-xs);
  margin-inline-start: auto;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  white-space: nowrap;
  text-decoration: none;
  border: var(--rule-thin);
}
.profile__edit:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

/* ── Profile edit / account settings (/settings) ────────────── */
.settings {
  max-inline-size: 48rem;
  padding-block: var(--space-l) var(--space-2xl);
}
.settings__title {
  margin: 0 0 var(--space-m);
  font-family: var(--font-serif);
  font-size: var(--step-3);
  font-weight: 700;
}
.settings__error {
  padding: var(--space-2xs) var(--space-s);
  margin-block: 0 var(--space-m);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-accent-ink);
  background: var(--color-accent);
}
.settings__section {
  padding-block: var(--space-m);
  margin: 0;
  border: 0;
  border-block-start: var(--rule-thin);
}
.settings__section:first-of-type {
  border-block-start: 0;
}
.settings__legend {
  padding: 0;
  margin-block-end: var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  letter-spacing: 0.06em;
}
.settings__hint {
  max-inline-size: var(--measure);
  margin-block: 0 var(--space-s);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}
.settings__danger-link {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  font-weight: 500;
  color: var(--color-accent);
}
.settings__avatar {
  display: flex;
  gap: var(--space-s);
  align-items: center;
  margin-block-end: var(--space-m);
}
.settings__avatar .avatar {
  inline-size: 64px;
  block-size: 64px;
  font-size: var(--step-1);
}
.settings__actions {
  display: flex;
  gap: var(--space-m);
  align-items: center;
  padding-block-start: var(--space-m);
  border-block-start: var(--rule-thin);
}
.settings__cancel {
  font-family: var(--font-mono);
  font-size: var(--step--1);
}
.settings__passkeys-intro,
.settings__passkeys-empty {
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}
.settings__passkey-list {
  padding: 0;
  margin: 0;
  list-style: none;
}
.settings__passkey-row {
  display: flex;
  gap: var(--space-s);
  align-items: baseline;
  justify-content: space-between;
  padding-block: var(--space-2xs);
  border-block-end: var(--rule-soft);
}
.settings__passkey-row:last-child {
  border-block-end: none;
}
.settings__passkey-label {
  font-family: var(--font-serif);
  font-size: var(--step-0);
}
.settings__passkey-meta {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}
.settings__passkey-rename {
  display: flex;
  gap: var(--space-2xs);
  align-items: baseline;
}
.settings__passkey-name {
  inline-size: 12rem;
  max-inline-size: 100%;
  padding: var(--space-3xs) var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  background: var(--color-surface);
  border: var(--rule-thin);
}
.settings__passkey-remove-btn,
.settings__passkey-save-btn {
  padding: var(--space-3xs) var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  cursor: pointer;
  background: var(--color-surface);
  border: var(--rule-thin);
}
.settings__passkey-remove-btn:hover,
.settings__passkey-save-btn:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}
.field {
  display: block;
}
.field + .field {
  margin-block-start: var(--space-m);
}
.field__label {
  display: block;
  margin-block-end: var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.04em;
}
.field__hint {
  display: block;
  margin-block-start: var(--space-2xs);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}
.input-text,
.textarea {
  inline-size: 100%;
  padding: var(--space-xs) var(--space-s);
  font-family: var(--font-serif);
  font-size: var(--step-0);
  line-height: 1.4;
  background: var(--color-surface);
  border: var(--rule-thin);
}
.textarea {
  min-block-size: 6rem;
  resize: vertical;
}
.input-text:focus,
.textarea:focus {
  outline: var(--focus-ring);
  outline-offset: -1px;
}
.link-field {
  display: grid;
  grid-template-columns: 9rem 1fr;
  gap: var(--space-s);
  align-items: center;
}
.link-field + .link-field {
  margin-block-start: var(--space-2xs);
}
.link-field__label {
  display: flex;
  gap: var(--space-3xs);
  align-items: center;
  font-family: var(--font-mono);
  font-size: var(--step--1);
}
.button-primary {
  padding: var(--space-xs) var(--space-l);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  color: var(--color-bg);
  background: var(--color-ink);
  border: var(--rule-thin);
}
.button-primary:hover {
  background: var(--color-accent);
  border-color: var(--color-accent);
}

@media (max-width: 40rem) {
  .link-field {
    grid-template-columns: 1fr;
    gap: var(--space-3xs);
  }
}

/* Separate the change-password form from the profile form. */
.settings + .settings {
  border-block-start: var(--rule-thin);
}

/* ── Manager: shared prompt library ───────────────────────── */
.manage-library {
  max-inline-size: 56rem;
  padding: var(--space-l) var(--space-m) var(--space-2xl);
  margin-inline: auto;
}

.manage-library__back {
  display: inline-block;
  margin-block-end: var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  text-decoration: none;
}

.manage-library__back:hover {
  color: var(--color-accent);
}

.manage-library__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  align-items: baseline;
  justify-content: space-between;
  padding-block-end: var(--space-s);
  border-block-end: var(--rule-thick);
}

.manage-library__title {
  margin: 0;
  margin-inline-end: auto;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1.1;
}

.manage-library__nav-link {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  text-decoration: none;
}

.manage-library__nav-link:hover {
  color: var(--color-accent);
}

.manage-library__intro {
  max-inline-size: var(--measure);
  margin-block: var(--space-m) 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.manage-library__section {
  margin-block-start: var(--space-l);
}

.manage-library__subtitle {
  margin: 0 0 var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 400;
  color: var(--color-ink-muted);
}

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

.manage-library__entry {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs);
  padding-block: var(--space-m);
  border-block-start: var(--rule-soft);
}

.manage-library__entry:last-child {
  border-block-end: var(--rule-soft);
}

.manage-library__entry-prompt {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-2);
  font-weight: 700;
  line-height: 1.3;
}

.manage-library__entry-brief {
  max-inline-size: var(--measure);
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.5;
}

.manage-library__entry-reqs {
  max-inline-size: var(--measure);
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

.manage-library__entry-meta {
  margin: 0;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.manage-library__entry-author {
  color: var(--color-ink-muted);
  text-decoration: none;
}

.manage-library__entry-author:hover {
  color: var(--color-accent);
}

/* Per-entry actions, laid out inline via l-cluster. */
.manage-library__entry-controls {
  margin-block-start: var(--space-2xs);
}

.manage-library__use,
.manage-library__edit {
  padding: var(--space-3xs) var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  text-decoration: none;
  background: var(--color-surface);
  border: var(--rule-thin);
}

.manage-library__use:hover,
.manage-library__edit:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

.manage-library__delete-btn {
  padding: var(--space-3xs) var(--space-2xs);
  font-family: var(--font-mono);
  font-size: var(--step--2);
  cursor: pointer;
  background: var(--color-surface);
  border: var(--rule-thin);
}

.manage-library__delete-btn:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

.manage-library__empty {
  margin-block: var(--space-l) 0;
  color: var(--color-ink-muted);
}

/* Contribute form: mirrors the new-prompt form (.admin-prompt__*). */
.manage-library__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

.manage-library__error {
  padding: var(--space-xs) var(--space-s);
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-accent-ink);
  background: var(--color-accent);
}

.manage-library__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.manage-library__label {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.04em;
}

.manage-library__hint {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.manage-library__input,
.manage-library__textarea {
  inline-size: 100%;
  padding: var(--space-xs) var(--space-s);
  margin-block-start: var(--space-3xs);
  background: var(--color-surface);
  border: var(--rule-thin);
}

.manage-library__input {
  font-family: var(--font-serif);
  font-size: var(--step-1);
  line-height: 1.4;
}

.manage-library__textarea {
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.5;
  resize: vertical;
}

.manage-library__input:focus,
.manage-library__textarea:focus {
  outline: var(--focus-ring);
  outline-offset: -1px;
}

.manage-library__submit {
  display: inline-flex;
  align-items: center;
  align-self: start;
  padding: var(--space-xs) var(--space-l);
  margin-block-start: var(--space-2xs);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--color-accent-ink);
  background: var(--color-accent);
  border: 0;
}

.manage-library__submit:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

/* ── Site admin: groups overview + create ─────────────────── */
.admin-groups {
  max-inline-size: 56rem;
  padding: var(--space-l) var(--space-m) var(--space-2xl);
  margin-inline: auto;
}

.admin-groups__head {
  padding-block-end: var(--space-s);
  border-block-end: var(--rule-thick);
}

.admin-groups__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1.1;
}

.admin-groups__section {
  margin-block-start: var(--space-l);
}

.admin-groups__subtitle {
  margin: 0 0 var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  font-weight: 400;
  color: var(--color-ink-muted);
}

.admin-groups__intro {
  max-inline-size: var(--measure);
  margin-block: 0 var(--space-m);
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
}

/* Create form: mirrors the new-prompt form (.admin-prompt__*). */
.admin-groups__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

.admin-groups__error {
  padding: var(--space-xs) var(--space-s);
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-accent-ink);
  background: var(--color-accent);
}

.admin-groups__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.admin-groups__label {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.04em;
}

.admin-groups__hint {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.admin-groups__input,
.admin-groups__select {
  inline-size: 100%;
  padding: var(--space-xs) var(--space-s);
  margin-block-start: var(--space-3xs);
  font: inherit;
  font-size: var(--step-0);
  background: var(--color-surface);
  border: var(--rule-thin);
}

.admin-groups__input:focus,
.admin-groups__select:focus {
  outline: var(--focus-ring);
  outline-offset: -1px;
}

.admin-groups__submit {
  display: inline-flex;
  align-items: center;
  align-self: start;
  padding: var(--space-xs) var(--space-l);
  margin-block-start: var(--space-2xs);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--color-accent-ink);
  background: var(--color-accent);
  border: 0;
}

.admin-groups__submit:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}

/* Group list: rows mirror the prompt schedule. */
.admin-groups__list {
  padding: 0;
  margin: 0;
  list-style: none;
}

.admin-groups__row {
  display: grid;
  grid-template-columns: 1fr 1fr 10rem 7rem;
  gap: var(--space-s);
  align-items: baseline;
  padding-block: var(--space-s);
  border-block-start: var(--rule-soft);
}

.admin-groups__row:last-child {
  border-block-end: var(--rule-soft);
}

.admin-groups__name {
  font-family: var(--font-serif);
  font-size: var(--step-1);
  text-decoration: none;
}

.admin-groups__name:hover {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

.admin-groups__slug,
.admin-groups__tz {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.admin-groups__count {
  justify-self: start;
  font-family: var(--font-mono);
  font-size: var(--step--2);
  white-space: nowrap;
}

.admin-groups__empty {
  margin-block: var(--space-l) 0;
  color: var(--color-ink-muted);
}

@media (max-width: 48rem) {
  .admin-groups__row {
    grid-template-columns: 1fr;
    gap: var(--space-3xs);
  }
}

/* ── Manager: group settings (rename + timezone) ──────────── */
.manage-settings {
  max-inline-size: 56rem;
  padding: var(--space-l) var(--space-m) var(--space-2xl);
  margin-inline: auto;
}

.manage-settings__back {
  display: inline-block;
  margin-block-end: var(--space-s);
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  text-decoration: none;
}

.manage-settings__back:hover {
  color: var(--color-accent);
}

.manage-settings__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-s);
  align-items: baseline;
  padding-block-end: var(--space-s);
  border-block-end: var(--rule-thick);
}

.manage-settings__title {
  margin: 0;
  margin-inline-end: auto;
  font-family: var(--font-serif);
  font-size: var(--step-4);
  font-weight: 700;
  line-height: 1.1;
}

.manage-settings__nav-link {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  color: var(--color-ink-muted);
  text-decoration: none;
}

.manage-settings__nav-link:hover {
  color: var(--color-accent);
}

/* Form mirrors the new-prompt / create-group form idiom. */
.manage-settings__form {
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
  margin-block-start: var(--space-l);
}

.manage-settings__error {
  padding: var(--space-xs) var(--space-s);
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--step--1);
  color: var(--color-accent-ink);
  background: var(--color-accent);
}

.manage-settings__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
}

.manage-settings__label {
  font-family: var(--font-mono);
  font-size: var(--step--1);
  letter-spacing: 0.04em;
}

.manage-settings__hint {
  font-family: var(--font-mono);
  font-size: var(--step--2);
  color: var(--color-ink-muted);
}

.manage-settings__input,
.manage-settings__select {
  inline-size: 100%;
  padding: var(--space-xs) var(--space-s);
  margin-block-start: var(--space-3xs);
  font: inherit;
  font-size: var(--step-0);
  background: var(--color-surface);
  border: var(--rule-thin);
}

.manage-settings__input:focus,
.manage-settings__select:focus {
  outline: var(--focus-ring);
  outline-offset: -1px;
}

.manage-settings__submit {
  display: inline-flex;
  align-items: center;
  align-self: start;
  padding: var(--space-xs) var(--space-l);
  margin-block-start: var(--space-2xs);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  font-weight: 500;
  color: var(--color-accent-ink);
  background: var(--color-accent);
  border: 0;
}

.manage-settings__submit:hover {
  color: var(--color-bg);
  background: var(--color-ink);
}
