/* Generated by scripts/build-assets.mjs. Edit the files named below. */

/* base.css */
/* Base: element defaults, the page frame and small utilities (replica/design/components.md, Rules for
   every component). Tokens only: colours, type, radius, shadow and motion come from tokens.css; spacing
   is the fixed 4, 8, 12, 16, 24, 32, 48, 64 px scale. Breakpoints: sm 480px, md 768px, lg 1024px. */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--layout-bar) + 24px);
}
@media (max-width: 767.98px) {
  html { scroll-padding-bottom: calc(var(--layout-tabbar) + 16px + env(safe-area-inset-bottom)); }
}
@media (prefers-reduced-motion: no-preference) {
  html:focus-within { scroll-behavior: smooth; }
}

/* Every theme root, nested ones included (switcher swatches, demo frames), paints its own canvas. */
:root, [data-theme] { background: var(--bg); color: var(--text); }

body {
  margin: 0;
  min-block-size: 100dvh;
  display: flex;
  flex-direction: column;
  font: var(--type-base);
  font-variant-numeric: tabular-nums;
  overflow-wrap: break-word;
}

/* No scrolling behind an open dialog. */
html:has(dialog[open]) { overflow: hidden; }

h1, h2, h3, h4, h5, h6 { margin: 0; text-wrap: balance; }
h1 { font: var(--type-2xl); letter-spacing: var(--tracking-2xl); font-variation-settings: var(--display-variation); }
p { margin: 0; }
p, li { text-wrap: pretty; }
a { color: inherit; text-underline-offset: 3px; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }
img, svg { display: block; max-inline-size: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
code { font: inherit; font-weight: 600; }
:lang(ja) { line-break: strict; }

:focus-visible { outline: var(--focus-width) solid var(--focus); outline-offset: var(--focus-offset); }

/* Utilities. hidden always wins over a component's display. */
[hidden] { display: none !important; }
.visually-hidden {
  position: absolute !important;
  inline-size: 1px;
  block-size: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.muted { color: var(--text-muted); }
.num { font-variant-numeric: tabular-nums; font-weight: 600; }
.t-xs { font: var(--type-xs); }
.t-sm { font: var(--type-sm); }
.t-lg { font: var(--type-lg); }
.t-xl { font: var(--type-xl); letter-spacing: var(--tracking-xl); font-variation-settings: var(--display-variation); }
.t-2xl { font: var(--type-2xl); letter-spacing: var(--tracking-2xl); font-variation-settings: var(--display-variation); }
.section-title { font: var(--type-lg); }
.clamp { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3; overflow: hidden; }
.clamp-2 { -webkit-line-clamp: 2; line-clamp: 2; }
.card { background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-lg); }

/* Titles over 28 characters in headings condense only below a 480px content width, and only in themes
   whose --title-stretch is not normal. */
@container (max-width: 479.98px) { .condensed { font-stretch: var(--title-stretch); } }

/* Skip link: first in the tab order, visible on focus. */
.skip-link {
  position: absolute;
  inset-block-start: 8px;
  inset-inline-start: 8px;
  z-index: 30;
  padding: 8px 16px;
  border-radius: var(--radius-md);
  background: var(--inverse);
  color: var(--on-inverse);
  font: var(--type-sm);
  font-weight: 700;
  transform: translateY(-200%);
}
.skip-link:focus { transform: none; --focus: var(--on-inverse); }

/* The page column. Reading pages are 720px wide, grid pages 1200px. Components that sit in columns of
   different widths switch layout on this container's width. */
.page {
  flex: 1;
  inline-size: 100%;
  margin-inline: auto;
  padding: 24px var(--layout-gutter) 48px;
  container-type: inline-size;
}
.page-content { max-inline-size: calc(var(--layout-content) + 2 * var(--layout-gutter)); }
.page-wide { max-inline-size: calc(var(--layout-wide) + 2 * var(--layout-gutter)); }
.page-full { max-inline-size: none; }
.page:focus { outline: none; }
@media (max-width: 767.98px) {
  /* The floating tab bar never hides the last row. */
  body { padding-block-end: calc(var(--layout-tabbar) + 16px + env(safe-area-inset-bottom)); }
  /* Onboarding (S46) renders no tab bar. */
  body:not(:has(> .tabbar)) { padding-block-end: 0; }
}

.banner-wrap { inline-size: 100%; max-inline-size: calc(var(--layout-wide) + 2 * var(--layout-gutter)); margin: 8px auto 0; padding-inline: var(--layout-gutter); }

/* Cross-document view transitions between pages of this site. The bars keep their place; the rest
   crossfades. Reduced motion turns them off. */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--motion-base); animation-timing-function: var(--motion-ease); }
.topbar { view-transition-name: topbar; }
.tabbar { view-transition-name: tabbar; }
.is-demo { view-transition-name: none; }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* Without JavaScript, clamped text shows in full and its toggle is hidden. */
@media (scripting: none) {
  .clamp { display: block; -webkit-line-clamp: none; line-clamp: none; overflow: visible; }
  .text-toggle[data-clamp] { display: none; }
}

/* components.css */
/* Shared components (replica/design/components.md), one block per component, in the order of
   src/views/components/. Tokens only. Layers: the sticky top bar and the tab bar 20, the skip link 30,
   toasts 40; dialogs and popovers use the top layer and need none. */

/* ---------- glass: floating chrome, sheets and popovers only ---------- */
.glass, .topbar-inner, .tabbar, .dialog, .menu {
  background: var(--glass-tint);
  -webkit-backdrop-filter: blur(var(--surface-blur)) saturate(var(--glass-saturate));
  backdrop-filter: blur(var(--surface-blur)) saturate(var(--glass-saturate));
  border: var(--border-width) solid var(--border);
}

/* ---------- top bar ---------- */
.topbar {
  position: sticky;
  inset-block-start: 8px;
  z-index: 20;
  margin: 8px 8px 0;
}
.topbar-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 8px;
  min-block-size: var(--layout-bar);
  max-inline-size: calc(var(--layout-wide) + 2 * var(--layout-gutter));
  margin-inline: auto;
  padding: 0 8px 0 16px;
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-bar);
}
/* Plain canvas at the top of the page, glass once it scrolls 8px (a scroll-driven animation). Where that
   is unsupported the bar stays glass. */
@supports (animation-timeline: scroll()) {
  .topbar:not(.is-demo) .topbar-inner {
    animation: topbar-glass linear both;
    animation-timeline: scroll(root);
    animation-range: 0 8px;
  }
  @keyframes topbar-glass {
    from { background: var(--bg); border-color: transparent; box-shadow: none; -webkit-backdrop-filter: none; backdrop-filter: none; }
  }
}
.wordmark { display: inline-flex; align-items: center; min-block-size: 44px; color: var(--text); border-radius: var(--radius-sm); text-decoration: none; }
.wordmark svg { block-size: 24px; inline-size: auto; }
.topnav { display: none; gap: 4px; margin-inline-start: 16px; }
.topnav a { display: inline-flex; align-items: center; min-block-size: 36px; padding: 0 12px; border-radius: var(--radius-pill); font: var(--type-sm); font-weight: 600; text-decoration: none; color: var(--text-muted); }
.topnav a:hover { color: var(--text); background: color-mix(in srgb, var(--text) 8%, transparent); }
.topnav a[aria-current="page"] { color: var(--text); background: var(--accent-soft); color: var(--on-accent-soft); }
/* Three columns: the wordmark and nav, the main action in the true centre, and the account controls. */
.topbar-start, .topbar-end { display: flex; align-items: center; gap: 4px; min-inline-size: 0; }
.topbar-start { grid-column: 1; }
.topbar-end { grid-column: 3; justify-content: flex-end; }
.spacer { flex: 1; }
/* Scoped to .topbar: .btn, .icon-btn and .search-form come later with the same specificity and would
   win, showing these on phones (seen 2026-10-05 at 390px). */
.topbar .topbar-search { display: none; inline-size: min(320px, 28vw); }
.topbar-search .search { min-block-size: 40px; }
.topbar .topbar-box, .topbar .topbar-signup { display: none; }
/* Box it: the one main action, larger than any other control. The box icon's lid lifts on hover and drops
   on press (the press itself is .btn:active). Both are off with reduced motion. */
.topbar .topbar-box { grid-column: 2; padding-inline: 20px 24px; border-radius: var(--radius-pill); font: var(--type-sm); font-weight: 750; box-shadow: var(--shadow-button); }
.topbar-box .icon { --icon-size: 22px; transition: transform var(--motion-fast) var(--motion-spring); }
.topbar-box:hover .icon { transform: translateY(-2px) rotate(-8deg); }
.topbar-box:active .icon { transform: translateY(1px); }
.topbar-login { display: inline-flex; align-items: center; min-block-size: 44px; padding: 0 8px; font: var(--type-sm); font-weight: 600; text-decoration: none; }
.topbar-login:hover { text-decoration: underline; }
.dot { position: absolute; inset-block-start: 8px; inset-inline-end: 8px; inline-size: 8px; block-size: 8px; border-radius: 50%; background: var(--react); }
.avatar-btn { display: inline-grid; place-items: center; inline-size: 44px; block-size: 44px; padding: 0; border: 0; border-radius: 50%; background: transparent; }
@media (min-width: 480px) {
  .topbar .topbar-signup { display: inline-flex; }
}
@media (min-width: 768px) {
  .topnav { display: flex; }
  .topbar .topbar-search { display: block; }
  .topbar .topbar-search-link { display: none; }
  .topbar .topbar-box { display: inline-flex; }
}

/* ---------- bottom tab bar (below md) ---------- */
.tabbar {
  position: fixed;
  inset-inline: 8px;
  inset-block-end: calc(8px + env(safe-area-inset-bottom));
  z-index: 20;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  min-block-size: var(--layout-tabbar);
  padding: 4px;
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-bar);
}
.tabbar a {
  display: grid;
  grid-template-rows: 28px minmax(16px, auto);
  place-items: center;
  align-content: center;
  gap: 4px;
  min-block-size: 44px;
  border-radius: var(--radius-lg);
  color: var(--text-muted);
  font: var(--type-xs);
  text-decoration: none;
}
.tabbar a .icon { --icon-size: 24px; }
.tabbar a[aria-current="page"] { color: var(--text); }
.tabbar a:hover { color: var(--text); }
.tabbar .tab-log { color: var(--text); }
.log-pill {
  display: grid;
  place-items: center;
  inline-size: 48px;
  block-size: 28px;
  border-radius: var(--radius-pill);
  background: var(--accent);
  color: var(--on-accent);
  border: var(--control-border-width) solid var(--border);
  box-shadow: var(--shadow-button);
  transition: transform var(--motion-fast) var(--motion-ease), box-shadow var(--motion-fast) var(--motion-ease);
}
.tabbar .log-pill .icon { --icon-size: 22px; }
/* The tab bar's centre: a larger pill that rises above the bar, so it reads as the main action. */
.tabbar .log-pill { inline-size: 56px; block-size: 36px; margin-block-start: -12px; }
.tab-log:active .log-pill { transform: translate(var(--press-shift), var(--press-shift)) scale(var(--press-scale)); box-shadow: var(--shadow-press); }
@media (prefers-reduced-motion: reduce) {
  .topbar-box .icon, .topbar-box:hover .icon, .topbar-box:active .icon { transition: none; transform: none; }
}
@media (min-width: 768px) {
  .tabbar:not(.is-demo) { display: none; }
}

/* ---------- footer ---------- */
.site-footer { margin-block-start: 48px; background: var(--surface); border-block-start: var(--border-width) solid var(--divider); color: var(--text-muted); }
.footer-inner { max-inline-size: calc(var(--layout-wide) + 2 * var(--layout-gutter)); margin-inline: auto; padding: 24px var(--layout-gutter); display: grid; gap: 24px; }
.footer-cols { display: grid; gap: 24px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 160px), 1fr)); }
.footer-cols h2 { font: var(--type-sm); font-weight: 700; color: var(--text); margin-block-end: 8px; }
.footer-cols ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.site-footer a { color: var(--text); font: var(--type-sm); }
.footer-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; font: var(--type-sm); }
.footer-name { flex: 1 1 auto; }
.footer-legal { display: flex; flex-wrap: wrap; gap: 4px 16px; }
.footer-legal a { display: inline-flex; align-items: center; min-block-size: 24px; }

/* ---------- buttons ---------- */
.btn {
  --btn-bg: var(--surface-raised);
  --btn-fg: var(--text);
  --btn-border: var(--border-input);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-block-size: 40px;
  padding: 0 16px;
  border-radius: var(--radius-md);
  border: var(--control-border-width) solid var(--btn-border);
  background: var(--btn-bg);
  color: var(--btn-fg);
  box-shadow: var(--shadow-button);
  font: var(--type-sm);
  font-weight: 650;
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--motion-fast) var(--motion-ease), box-shadow var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}
.btn:hover { background: color-mix(in srgb, var(--btn-bg) 88%, var(--bg)); }
.btn:active { transform: translate(var(--press-shift), var(--press-shift)) scale(var(--press-scale)); box-shadow: var(--shadow-press); }
.btn-primary { --btn-bg: var(--accent); --btn-fg: var(--on-accent); --btn-border: var(--border); }
.btn-secondary { --btn-bg: var(--surface-raised); --btn-fg: var(--text); --btn-border: var(--border-input); }
.btn-ghost { --btn-bg: transparent; --btn-fg: var(--text); --btn-border: transparent; box-shadow: none; }
.btn-ghost:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.btn-danger { --btn-bg: var(--danger-fill); --btn-fg: var(--on-danger); --btn-border: var(--border); }
.btn-sm { min-block-size: 32px; padding: 0 12px; font: var(--type-xs); font-weight: 650; }
.btn-lg { min-block-size: 48px; padding: 0 24px; font: var(--type-base); font-weight: 650; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: none; }
.btn:disabled:hover, .btn[aria-disabled="true"]:hover { background: var(--btn-bg); }
.btn[aria-busy="true"] { opacity: 1; cursor: progress; }
.reason { font: var(--type-xs); color: var(--text-muted); }
.spinner { display: inline-block; flex: none; inline-size: 1em; block-size: 1em; border-radius: 50%; border: 2px solid currentColor; border-right-color: transparent; animation: spin 0.8s linear infinite; }
@keyframes spin { to { transform: rotate(1turn); } }
@media (prefers-reduced-motion: reduce) {
  .spinner { animation: none; border-color: color-mix(in srgb, currentColor 30%, transparent); border-top-color: currentColor; }
}

.icon-btn {
  position: relative;
  display: inline-grid;
  place-items: center;
  flex: none;
  inline-size: 40px;
  block-size: 40px;
  padding: 0;
  border: 0;
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text);
  text-decoration: none;
  cursor: pointer;
}
.icon-btn:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.icon-btn:active { transform: scale(var(--press-scale)); }
.icon-btn-outlined { border: var(--control-border-width) solid var(--border-input); }
.icon-btn-dense { inline-size: 32px; block-size: 32px; }
.icon-btn:disabled, .icon-btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; background: transparent; }

/* ---------- status buttons ---------- */
.statuses { display: flex; flex-wrap: wrap; gap: 8px; }
.statuses-equal > * { flex: 1 1 0; }
.statuses-equal .status { inline-size: 100%; justify-content: center; }
.status-form, .follow-form { display: contents; }
.status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-block-size: 48px;
  padding: 0 16px;
  border-radius: var(--radius-md);
  border: var(--control-border-width) solid var(--border-input);
  background: var(--surface-raised);
  color: var(--text);
  font: var(--type-sm);
  font-weight: 600;
  cursor: pointer;
  transition: transform var(--motion-fast) var(--motion-ease), box-shadow var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}
.status:hover { background: color-mix(in srgb, var(--surface-raised) 88%, var(--bg)); }
.status[aria-pressed="true"] { background: var(--accent-soft); color: var(--on-accent-soft); border-color: var(--border); box-shadow: var(--shadow-button); }
.status[aria-pressed="true"]:hover { background: color-mix(in srgb, var(--accent-soft) 88%, var(--bg)); }
.status:active { transform: translate(var(--press-shift), var(--press-shift)) scale(var(--press-scale)); box-shadow: var(--shadow-press); }
.status[aria-busy="true"] { cursor: progress; }

/* ---------- follow pill ---------- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-block-size: 36px;
  padding: 0 16px;
  border-radius: var(--radius-pill);
  border: var(--control-border-width) solid var(--border);
  background: var(--accent);
  color: var(--on-accent);
  font: var(--type-sm);
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: var(--shadow-button);
  transition: transform var(--motion-fast) var(--motion-ease), box-shadow var(--motion-fast) var(--motion-ease), background-color var(--motion-fast) var(--motion-ease);
}
.pill:hover { background: color-mix(in srgb, var(--accent) 88%, var(--bg)); }
.pill:active { transform: translate(var(--press-shift), var(--press-shift)) scale(var(--press-scale)); box-shadow: var(--shadow-press); }
.pill.is-following { background: var(--surface-raised); color: var(--text); border-color: var(--border-input); box-shadow: none; }
.pill.is-following:hover { background: color-mix(in srgb, var(--surface-raised) 88%, var(--bg)); }
.pill[aria-busy="true"] { cursor: progress; }

/* ---------- like button ---------- */
.like-group { display: inline-flex; align-items: center; }
.like {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-block-size: 36px;
  min-inline-size: 36px;
  padding: 0 8px;
  border-radius: var(--radius-pill);
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font: var(--type-sm);
  text-decoration: none;
  cursor: pointer;
}
.like:hover { background: color-mix(in srgb, var(--text) 8%, transparent); color: var(--text); }
.like[aria-pressed="true"] .icon { background-color: var(--react); }
.like-count { font: var(--type-sm); color: var(--text-muted); padding-inline-end: 8px; }
.like[aria-pressed="true"] + .like-count { color: var(--text); }
.likers { display: inline-flex; padding-inline-start: 4px; }
.likers > * + * { margin-inline-start: -8px; }
/* overlapping liker avatars: a ring in the page colour and a small overlap keep each one's initials readable */
.likers > .avatar { outline: 2px solid var(--bg); }
.likers > .avatar + .avatar { margin-inline-start: -4px; }

/* ---------- overflow menu and other popovers ---------- */
.menu-wrap { position: relative; display: inline-flex; }
.menu {
  min-inline-size: 200px;
  max-inline-size: min(320px, calc(100vw - 32px));
  margin: 0;
  padding: 4px;
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-pop);
  color: var(--text);
}
.menu:popover-open { margin: auto; }
/* Next to the button that opened it, where anchor positioning exists; centred otherwise. */
@supports (position-area: bottom) {
  .menu[popover] { margin: 4px 0; position-area: bottom span-left; position-try-fallbacks: flip-block, flip-inline; }
}
.menu ul { list-style: none; margin: 0; padding: 0; }
.menu form { margin: 0; }
.menu-item {
  display: flex;
  align-items: center;
  gap: 12px;
  inline-size: 100%;
  min-block-size: 40px;
  padding: 8px 12px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font: var(--type-sm);
  text-align: start;
  text-decoration: none;
  cursor: pointer;
}
.menu-item:hover, .menu-item:focus-visible { background: color-mix(in srgb, var(--text) 8%, transparent); }
.menu-item:disabled { opacity: 0.45; cursor: not-allowed; }
.menu-item.is-danger { color: var(--danger); }
.menu-end { margin-inline-start: auto; }
.menu-inline { position: static; display: block; }
@media (pointer: coarse) { .menu-item { min-block-size: var(--layout-tap); } }

/* ---------- action row ---------- */
.action-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.locked-action { display: inline-flex; align-items: center; gap: 8px; }
.lock-preview { font: var(--type-xs); font-weight: 600; white-space: nowrap; text-decoration: underline; }
.lock-note { display: inline-flex; align-items: center; gap: 4px; font: var(--type-xs); color: var(--text-muted); }
.lock-note .icon { --icon-size: 14px; }

/* ---------- inputs ---------- */
.field { display: grid; gap: 8px; margin-block-end: 16px; min-inline-size: 0; }
.field > label { font: var(--type-sm); font-weight: 600; }
.input {
  inline-size: 100%;
  min-block-size: var(--layout-tap);
  padding: 8px 12px;
  border-radius: var(--radius-md);
  border: var(--control-border-width) solid var(--border-input);
  background: var(--surface-raised);
  color: var(--text);
  font: var(--type-base);
}
.input::placeholder { color: var(--text-muted); opacity: 1; }
.input:hover:not(:disabled, [readonly]) { border-color: var(--text-muted); }
.input:focus-visible { outline: var(--focus-width) solid var(--focus); outline-offset: 1px; }
.input[aria-invalid="true"] { border-color: var(--danger); }
.input:disabled { opacity: 0.45; cursor: not-allowed; }
.input[readonly] { background: var(--surface); }
.input[type="date"] { color-scheme: inherit; }
.textarea { resize: vertical; field-sizing: content; min-block-size: calc(3lh + 18px); max-block-size: calc(16lh + 18px); }
.input-wrap { position: relative; display: block; }
.input-wrap.has-state .input { padding-inline-end: 40px; }
.input-state { position: absolute; inset-block: 0; inset-inline-end: 12px; display: grid; place-items: center; color: var(--text-muted); }
.is-available .input-state, .is-available .hint { color: var(--success); }
.hint { font: var(--type-xs); font-weight: 400; color: var(--text-muted); max-inline-size: 65ch; }
.error { display: flex; gap: 8px; align-items: flex-start; font: var(--type-sm); color: var(--danger); }
.error .icon { margin-block-start: 2px; }
.count { justify-self: end; font: var(--type-xs); color: var(--text-muted); }
.count.at-limit { color: var(--danger); }
.form-errors { display: grid; gap: 8px; margin-block-end: 16px; padding: 12px 16px; border-radius: var(--radius-md); border: var(--control-border-width) solid var(--danger); background: var(--surface); font: var(--type-sm); }
.form-errors p { display: flex; gap: 8px; align-items: center; color: var(--danger); font-weight: 600; }
.form-errors ul { margin: 0; padding-inline-start: 24px; }

/* search input */
.search-form { display: grid; gap: 8px; min-inline-size: 0; }
.search-label { font: var(--type-sm); font-weight: 600; }
.search {
  display: flex;
  align-items: center;
  gap: 8px;
  min-block-size: var(--layout-tap);
  padding: 0 12px;
  border-radius: var(--radius-md);
  border: var(--control-border-width) solid var(--border-input);
  background: var(--surface-raised);
  color: var(--text-muted);
}
.search input { flex: 1; min-inline-size: 0; border: 0; padding: 0; background: transparent; color: var(--text); font: var(--type-base); outline: none; }
.search input::placeholder { color: var(--text-muted); opacity: 1; }
.search:has(input:focus-visible) { outline: var(--focus-width) solid var(--focus); outline-offset: 1px; }

/* checkbox and switch: native controls */
.check { display: inline-flex; align-items: center; gap: 8px; min-block-size: 44px; font: var(--type-sm); cursor: pointer; }
.check input[type="checkbox"]:not(.switch) { accent-color: var(--accent); inline-size: 22px; block-size: 22px; margin: 0; }
.check input:disabled, .check input:disabled + span { opacity: 0.45; cursor: not-allowed; }
.check input.switch {
  appearance: none;
  flex: none;
  margin: 0;
  inline-size: 44px;
  block-size: 26px;
  padding: 2px;
  display: inline-grid;
  justify-items: start;
  align-items: center;
  border-radius: var(--radius-pill);
  border: var(--control-border-width) solid var(--border-input);
  background: var(--surface-raised);
  cursor: pointer;
}
.check input.switch::after { content: ""; inline-size: 18px; block-size: 18px; border-radius: var(--radius-pill); background: var(--border-input); transition: transform var(--motion-base) var(--motion-spring); }
.check input.switch:checked { background: var(--accent); border-color: var(--border); }
.check input.switch:checked::after { background: var(--on-accent); transform: translateX(16px); }
@media (forced-colors: active) {
  .check input.switch::after { forced-color-adjust: none; background: CanvasText; }
  .check input.switch:checked { border-color: Highlight; }
}

/* radio group and switcher rows */
.radios { display: grid; gap: 4px; margin: 0 0 16px; padding: 0; border: 0; min-inline-size: 0; }
.radios legend { padding: 0; margin-block-end: 8px; font: var(--type-sm); font-weight: 600; }
.opt { display: flex; align-items: center; gap: 12px; min-block-size: 44px; padding: 8px 12px; border-radius: var(--radius-md); font: var(--type-sm); font-weight: 600; cursor: pointer; }
.opt:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.opt:has(:checked) { background: var(--accent-soft); color: var(--on-accent-soft); }
.opt:has(:checked) .hint { color: var(--on-accent-soft); }
.opt input { flex: none; margin: 0; accent-color: var(--accent); inline-size: 18px; block-size: 18px; }
.opt-text { display: grid; gap: 2px; }
.opt.is-locked { color: var(--text-muted); cursor: not-allowed; }
.opt.is-locked:hover { background: transparent; }
.opt .lock-note { margin-inline-start: auto; }

/* segmented control: one row that never wraps */
.seg {
  display: inline-flex;
  flex-wrap: nowrap;
  max-inline-size: 100%;
  overflow-x: auto;
  gap: 4px;
  margin: 0 0 12px;
  padding: 4px;
  border: var(--control-border-width) solid var(--border-input);
  border-radius: var(--radius-pill);
  background: var(--surface);
}
.seg label, .seg-links a {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-block-size: 36px;
  padding: 0 16px;
  border-radius: var(--radius-pill);
  font: var(--type-sm);
  font-weight: 600;
  color: var(--text-muted);
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
}
.seg input { position: absolute; inset: 0; margin: 0; opacity: 0; cursor: pointer; }
.seg .icon-check { display: none; --icon-size: 16px; }
.seg label:has(:checked), .seg-links a[aria-current="page"] { background: var(--accent-soft); color: var(--on-accent-soft); font-weight: 700; }
.seg label:has(:checked) .icon-check, .seg-links a[aria-current="page"] .icon-check { display: inline-block; }
.seg label:has(:focus-visible) { outline: var(--focus-width) solid var(--focus); outline-offset: 1px; }
.seg label:not(:has(:checked)):hover, .seg-links a:not([aria-current]):hover { color: var(--text); }
.seg-count { font-weight: 400; color: var(--text-muted); }
.seg label:has(:checked) .seg-count { color: var(--on-accent-soft); }

/* filter dropdown and sort menu: native selects drawn like a secondary button */
.filter {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-block-size: 36px;
  padding: 0 4px 0 12px;
  border-radius: var(--radius-md);
  border: var(--control-border-width) solid var(--border-input);
  background: var(--surface-raised);
  font: var(--type-sm);
  cursor: pointer;
}
.filter:has(select:focus-visible) { outline: var(--focus-width) solid var(--focus); outline-offset: 1px; }
.filter-label { color: var(--text-muted); }
.filter select { min-block-size: 34px; padding: 0 8px 0 0; border: 0; background: transparent; color: var(--text); font: var(--type-sm); font-weight: 600; outline: none; cursor: pointer; }
.filter select option { background: var(--surface-raised); color: var(--text); }

/* file upload */
.upload { display: grid; gap: 8px; margin-block-end: 16px; }
.upload-label { font: var(--type-sm); font-weight: 600; }
.file-input { position: absolute; inline-size: 1px; block-size: 1px; opacity: 0; overflow: hidden; }
.drop {
  display: grid;
  justify-items: center;
  gap: 4px;
  padding: 24px 16px;
  border-radius: var(--radius-md);
  border: var(--control-border-width) solid var(--border-input);
  background: var(--skeleton);
  text-align: center;
  cursor: pointer;
}
.drop > .icon { --icon-size: 28px; color: var(--text-muted); }
.drop-title { font: var(--type-sm); font-weight: 600; }
.upload:has(.file-input:focus-visible) .drop { outline: var(--focus-width) solid var(--focus); outline-offset: var(--focus-offset); }
.upload.is-dragging .drop { border-color: var(--focus); outline: var(--focus-width) solid var(--focus); outline-offset: -4px; }
.upload.has-error .drop { border-color: var(--danger); }
.upload-cover .drop { border-radius: min(var(--radius-cover), 22%); }
.upload-progress { display: grid; gap: 4px; font: var(--type-xs); color: var(--text-muted); }
.upload-progress .bar { display: block; block-size: 6px; border-radius: var(--radius-pill); background: linear-gradient(to right, var(--rating) calc(var(--value) * 1%), var(--rating-track) 0); }
.upload-done { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.upload-preview { inline-size: 160px; block-size: 160px; object-fit: cover; border-radius: min(var(--radius-cover), 22%); border: var(--border-width) solid var(--border); }
.upload-preview.is-round { inline-size: 96px; block-size: 96px; border-radius: 50%; }
.upload-actions { display: inline-flex; gap: 8px; }
.upload-file { display: inline-flex; align-items: center; gap: 8px; font: var(--type-sm); font-weight: 600; }

/* ---------- rating ---------- */
.stars {
  --star: 1rem;
  position: relative;
  display: inline-block;
  flex: none;
  inline-size: calc(var(--star) * 5);
  block-size: var(--star);
  vertical-align: -0.15em;
  forced-color-adjust: none;
}
.stars::before, .stars::after { content: ""; position: absolute; inset: 0; mask: var(--m) 0 0 / var(--star) var(--star) repeat-x; }
.stars::before { --m: var(--icon-star); background: var(--text-muted); }
.stars::after { --m: var(--icon-star-on); background: var(--rating); inline-size: calc(var(--value) / 5 * 100%); }
.stars-sm { --star: 0.8125rem; }
.stars-lg { --star: 1.25rem; }
.stars-xl { --star: 2rem; }
@media (forced-colors: active) { .stars { --text-muted: GrayText; --rating: CanvasText; } }
.rating { display: inline-flex; align-items: center; gap: 8px; font: var(--type-sm); }
.rating .num { color: var(--text); }
.rating-count, .rating-none { color: var(--text-muted); }

/* rating input: a transparent range over the stars; the label sits above */
.rate-wrap { display: grid; grid-template-columns: auto auto; justify-content: start; align-items: center; gap: 4px 12px; margin-block-end: 12px; }
.rate-wrap > label { grid-column: 1 / -1; font: var(--type-xs); color: var(--text-muted); }
/* One alignment rule in every rate-wrap (design round 2): the stars start on the label's edge, and the
   44px target's 6px padding hangs outside it. */
.rate-wrap .rate { margin-inline-start: -6px; }
.rate-sheet > label { font: var(--type-sm); font-weight: 600; color: var(--text); padding-inline-start: 0; }
.rate-sheet .rate { margin-inline-start: -6px; }
.rate-fallback { display: inline-flex; flex-wrap: wrap; gap: 8px; align-items: center; grid-column: 1 / -1; }
.rate-fallback select { min-block-size: 36px; padding: 0 8px; border-radius: var(--radius-md); border: var(--control-border-width) solid var(--border-input); background: var(--surface-raised); color: var(--text); font: var(--type-sm); }
.rate { position: relative; display: inline-grid; padding: 6px; border-radius: var(--radius-md); touch-action: pan-y; }
.rate[hidden], .rate-num[hidden], .rate-clear[hidden] { display: none; }
.rate-clear { color: var(--text-muted); }
.rate-clear:hover { color: var(--text); }
.rate input { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; margin: 0; opacity: 0; cursor: pointer; touch-action: pan-y; }
.rate:has(:focus-visible) { outline: var(--focus-width) solid var(--focus); outline-offset: var(--focus-offset); }
.rate-num { font: var(--type-xl); font-variant-numeric: tabular-nums; min-inline-size: 2.5ch; }
.rate-error { grid-column: 1 / -1; }
.rate.is-confirmed { animation: var(--motion-confirm) var(--motion-slow) var(--motion-ease); }
@keyframes confirm-ring { 0% { box-shadow: 0 0 0 0 var(--cover-accent); } 100% { box-shadow: 0 0 0 14px transparent; } }
@keyframes confirm-stamp { 0% { transform: scale(1.22) rotate(-5deg); } 55% { transform: scale(0.95) rotate(1deg); } 100% { transform: none; } }
@keyframes confirm-pop { 0% { transform: none; } 40% { transform: scale(1.1); } 100% { transform: none; } }
@media (pointer: coarse) { .rate-fallback select { min-block-size: var(--layout-tap); font-size: 1rem; } }

/* histogram */
.histogram { margin: 0; display: grid; gap: 4px; }
.histogram-bars, .histogram.is-loading { display: grid; grid-template-columns: repeat(10, 1fr); align-items: end; gap: 2px; block-size: 64px; }
.histogram-bar { display: block; block-size: calc(var(--share) * 100%); min-block-size: 2px; border-radius: var(--radius-sm) var(--radius-sm) 0 0; background: var(--rating); }
.histogram-bar.is-empty { block-size: 2px; background: var(--text-muted); border-radius: 0; }
.histogram-axis { display: flex; justify-content: space-between; font: var(--type-xs); color: var(--text-muted); }
.bar-skeleton { block-size: 60%; border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.bar-skeleton:nth-child(odd) { block-size: 35%; }
.histogram-empty { font: var(--type-sm); }

/* ---------- covers and album grid ---------- */
/* A cover sits on its generated placeholder: two OKLCH stops from a hash of the release id, plus two
   soft circles. The image covers it once it loads. Covers stay squares: the radius is capped at 22%. */
.cover {
  position: relative;
  display: block;
  aspect-ratio: 1;
  inline-size: 100%;
  overflow: hidden;
  border-radius: min(var(--radius-cover), 22%);
  border: var(--border-width) solid var(--border);
  background:
    radial-gradient(circle at 30% 28%, oklch(0.92 0.06 var(--h1, 200) / 0.55) 0 14%, transparent 15%),
    radial-gradient(circle at 68% 70%, oklch(0.3 0.08 var(--h2, 160) / 0.7) 0 28%, transparent 29%),
    linear-gradient(135deg, oklch(0.72 0.14 var(--h1, 200)), oklch(0.42 0.12 var(--h2, 160)));
}
.cover-img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; }
.cover-img[hidden] { display: none; }
.cover.is-empty { background: var(--skeleton); }
.cover-thumb { inline-size: 48px; flex: none; }
.cover-row { inline-size: 40px; flex: none; }
.cover-sheet { inline-size: 56px; flex: none; }
.cover-card { inline-size: 72px; flex: none; }
.cover-large { inline-size: min(100%, 320px); }
/* --shadow-cover only on grid and carousel covers, the release cover and Top 5. Cards and thumbs stay flat. */
.album-cover .cover, .top5 .cover, .cover-large { box-shadow: var(--shadow-cover); }

.grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 16px 12px; }
@media (min-width: 768px) { .grid { grid-template-columns: repeat(auto-fill, minmax(152px, 1fr)); } }
.album { display: grid; align-content: start; gap: 4px; min-inline-size: 0; color: var(--text); text-decoration: none; border-radius: var(--radius-md); }
.album-cover { position: relative; display: block; margin-block-end: 4px; transition: transform var(--motion-base) var(--motion-spring); }
.album:hover .album-cover { transform: translateY(-4px); }
.album-title, .album-meta { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.album-title { font: var(--type-sm); font-weight: 700; }
.album-meta { font: var(--type-xs); font-weight: 400; color: var(--text-muted); }
.album-extra { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.album .rank { position: absolute; inset-inline-start: -4px; inset-block-start: -8px; }
.album.is-loading { pointer-events: none; }

/* rank badge */
.rank {
  min-inline-size: 24px;
  block-size: 24px;
  display: grid;
  place-items: center;
  padding: 0 4px;
  border-radius: var(--radius-pill);
  background: var(--inverse);
  color: var(--on-inverse);
  font: var(--type-xs);
  font-weight: 800;
  border: var(--border-width) solid var(--border);
  transform: rotate(var(--sticker-tilt));
}

/* carousel */
.carousel { display: grid; gap: 12px; margin-block: 24px; min-inline-size: 0; }
.carousel-head { display: flex; align-items: center; gap: 12px; }
.carousel-head .section-title { margin-inline-end: auto; }
.carousel-arrows { display: none; gap: 4px; }
@media (min-width: 768px) { .carousel-arrows { display: inline-flex; } }
.carousel-track { list-style: none; margin: 0; padding: 8px 0 8px 4px; display: grid; grid-auto-flow: column; grid-auto-columns: 140px; gap: 12px; overflow-x: auto; scroll-snap-type: inline mandatory; scrollbar-width: thin; }
.carousel-track > li { scroll-snap-align: start; }
@media (min-width: 768px) { .carousel-track { grid-auto-columns: 160px; } }

/* Top 5 and the Spinning strip */
.top5 { list-style: none; margin: 0; padding: 8px 0 0 4px; display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px; }
.top5-item { position: relative; display: block; border-radius: min(var(--radius-cover), 22%); }
.top5-item .rank { position: absolute; inset-inline-start: -4px; inset-block-start: -8px; }
/* Seven slots on one line (Spinning holds seven, src/lib/profile/slots.ts); covers shrink on a narrow screen. */
.strip { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(7, minmax(0, 56px)); gap: 8px; }
.strip .cover-row { inline-size: 100%; }
.strip a { display: block; border-radius: min(var(--radius-cover), 22%); }
.slot { display: grid; place-items: center; aspect-ratio: 1; border-radius: min(var(--radius-cover), 22%); background: var(--skeleton); color: var(--text-muted); border: var(--control-border-width) solid var(--border-input); }
.slot:hover { color: var(--text); }
.strip a.slot { display: grid; } /* .strip a would make it a block and lose the centred plus */

/* list card mosaic */
.mosaic { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; aspect-ratio: 1; overflow: hidden; border-radius: min(var(--radius-cover), 22%); }
.mosaic .cover { border: 0; border-radius: 0; }
.mosaic .skeleton-square { grid-column: 1 / -1; grid-row: 1 / span 2; border-radius: 0; }

/* ---------- review card ---------- */
.review { display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: 16px; padding: 16px; }
.review-release { grid-template-columns: minmax(0, 1fr); }
.review-body { display: grid; align-content: start; gap: 4px; min-inline-size: 0; }
.review-title { font: var(--type-lg); overflow-wrap: anywhere; }
.review-title a { text-decoration: none; }
.review-title a:hover { text-decoration: underline; }
.review-sub { font: var(--type-sm); color: var(--text-muted); }
.review-author { display: flex; align-items: center; gap: 8px; font: var(--type-sm); font-weight: 700; }
.review-author a { text-decoration: none; }
.review-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-block: 4px; font: var(--type-sm); }
.review-date { display: inline-flex; align-items: center; gap: 4px; color: var(--text-muted); }
.review-headline { font: var(--type-base); font-weight: 700; max-inline-size: 30em; overflow-wrap: anywhere; text-wrap: balance; }
.review-text p { max-inline-size: 65ch; overflow-wrap: anywhere; white-space: pre-line; }
.review-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 4px 0 0 -8px; }
.review-actions .menu-wrap { margin-inline-start: auto; }
/* Below a 480px content width the cover drops to 56px beside the title block; the rest spans the card. */
@container (max-width: 479.98px) {
  .review:not(.review-release) { grid-template-columns: 56px minmax(0, 1fr); column-gap: 12px; row-gap: 8px; }
  .review:not(.review-release) .cover-card { inline-size: 56px; }
  .review:not(.review-release) .review-body { display: contents; }
  .review:not(.review-release) > .cover { grid-row: 1 / span 3; }
  .review:not(.review-release) .review-body > * { grid-column: 2; }
  .review:not(.review-release) .review-body > .review-text, .review:not(.review-release) .review-body > .review-actions { grid-column: 1 / -1; }
}

/* text clamp */
.clamp-box { display: grid; justify-items: start; gap: 4px; }
.clamp-text { max-inline-size: 65ch; }
.text-toggle {
  display: inline-flex;
  align-items: center;
  padding: 2px 0;
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--accent-text);
  font: var(--type-sm);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.text-toggle[hidden], .text-toggle [hidden] { display: none; }
summary.text-toggle { list-style: none; }
summary.text-toggle::-webkit-details-marker { display: none; }

/* ---------- list card ---------- */
.list-grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 16px 12px; }
.list-card { display: grid; align-content: start; gap: 8px; padding: 8px; color: var(--text); text-decoration: none; min-inline-size: 0; }
.list-card:hover .list-card-title { text-decoration: underline; }
.list-card-text { display: grid; gap: 4px; min-inline-size: 0; }
.list-card-title { font: var(--type-sm); font-weight: 700; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.list-card-desc { font: var(--type-sm); color: var(--text-muted); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.list-card-meta { display: flex; flex-wrap: wrap; gap: 4px 12px; font: var(--type-xs); color: var(--text-muted); }
.list-card-meta > span { display: inline-flex; align-items: center; gap: 4px; }
.list-card-meta .icon { --icon-size: 14px; }
.list-card-row { grid-template-columns: 72px minmax(0, 1fr); align-items: center; gap: 12px; }
.list-card.is-loading { pointer-events: none; }

/* ---------- user row ---------- */
.user-row { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: center; gap: 12px; min-block-size: 56px; padding-block: 8px; }
.user-row + .user-row { border-block-start: 1px solid var(--divider); }
.user-text { display: grid; min-inline-size: 0; }
.user-name { font: var(--type-sm); font-weight: 700; text-decoration: none; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.user-name:hover { text-decoration: underline; }
.user-sub { display: flex; flex-wrap: wrap; gap: 0 8px; font: var(--type-xs); color: var(--text-muted); }
.user-sub > span { min-inline-size: 0; overflow-wrap: anywhere; }
.user-row.is-compact { min-block-size: 40px; padding-block: 4px; }

/* ---------- feed: one panel, rows split by a thin rule ---------- */
.feed { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-lg); }
.feed-item { position: relative; display: grid; grid-template-columns: 40px minmax(0, 1fr) 48px; gap: 12px; align-items: center; padding: 12px; }
.feed-item:has(> .menu-wrap) { grid-template-columns: 40px minmax(0, 1fr) 48px auto; }
.feed-item + .feed-item { border-block-start: 1px solid var(--divider); }
.feed-item:focus { outline: var(--focus-width) solid var(--focus); outline-offset: -4px; }
.feed-main { display: grid; gap: 4px; min-inline-size: 0; }
.feed-line { font: var(--type-sm); display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.feed-line a { text-decoration: none; }
/* the actor keeps to one line, so a long name never hides the verb and the object; the full name is in title */
.feed-line .actor { display: inline-block; max-inline-size: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
.feed-line a:hover { text-decoration: underline; }
.feed-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font: var(--type-xs); color: var(--text-muted); }
.feed-covers { list-style: none; margin: 4px 0 0; padding: 0; display: flex; gap: 4px; }
.feed-covers .cover-thumb { inline-size: 40px; }
.feed-thumb { display: block; }
.load-more { display: flex; justify-content: center; padding: 12px; list-style: none; }
li.load-more { border-block-start: 1px solid var(--divider); }

/* ---------- comments ---------- */
.comments { display: grid; gap: 16px; margin-block: 24px; }
.comment-list, .replies { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; }
.comment > article { display: grid; grid-template-columns: 32px minmax(0, 1fr); gap: 12px; }
.comment-main { display: grid; gap: 4px; min-inline-size: 0; }
.comment-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font: var(--type-sm); }
.comment-head a { text-decoration: none; }
.comment-head time { font: var(--type-xs); color: var(--text-muted); }
.comment-body { font: var(--type-sm); max-inline-size: 65ch; overflow-wrap: anywhere; white-space: pre-line; }
.replies { margin: 12px 0 0 16px; padding-inline-start: 24px; border-inline-start: 2px solid var(--divider); }
.more-replies { margin: 8px 0 0 56px; }
.reply summary { margin-block-start: 4px; }
.reply-form, .comment-form { display: grid; justify-items: start; gap: 8px; margin-block-start: 8px; }
.reply-form .field, .comment-form .field { inline-size: 100%; margin: 0; }

/* ---------- tabs ---------- */
.tabs { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; margin-block: 16px; }
.tabs a { display: inline-flex; align-items: center; gap: 4px; min-block-size: 44px; padding: 0 16px; border-radius: var(--radius-pill); color: var(--text); font: var(--type-sm); font-weight: 600; text-decoration: none; white-space: nowrap; }
.tabs a:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.tabs a[aria-current="page"] { background: var(--accent-soft); color: var(--on-accent-soft); font-weight: 700; }
.tabs .count { color: var(--text-muted); font-weight: 400; }
.tabs a[aria-current="page"] .count { color: var(--on-accent-soft); }

/* ---------- result count and pagination ---------- */
.result-count { font: var(--type-sm); color: var(--text-muted); margin-block: 8px; }
.pagination { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin-block: 16px; font: var(--type-sm); }
.pagination ol { list-style: none; display: flex; flex-wrap: wrap; gap: 4px; margin: 0; padding: 0; }
.pagination li { display: inline-grid; place-items: center; min-inline-size: 24px; }
.pagination a, .pagination .is-disabled { display: inline-flex; align-items: center; justify-content: center; gap: 4px; min-block-size: 40px; min-inline-size: 40px; padding: 0 8px; border-radius: var(--radius-md); text-decoration: none; }
.pagination a:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.pagination a[aria-current="page"] { font-weight: 700; text-decoration: underline 2px; text-underline-offset: 4px; }
.pagination .is-disabled { color: var(--text-muted); opacity: 0.45; cursor: not-allowed; }
@media (max-width: 479.98px) { .pagination a[rel] span, .pagination .is-disabled span { display: none; } }

/* ---------- accordion ---------- */
.accordion { display: grid; }
.accordion-all { justify-self: end; margin-block-end: 8px; }
.accordion details + details { border-block-start: 1px solid var(--divider); }
.accordion summary { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-block-size: 52px; font: var(--type-base); font-weight: 600; cursor: pointer; list-style: none; }
.accordion summary::-webkit-details-marker { display: none; }
.accordion summary .icon { transition: transform var(--motion-fast) var(--motion-ease); }
.accordion details[open] summary .icon { transform: rotate(90deg); }
.accordion-body { padding-block-end: 16px; max-inline-size: 65ch; color: var(--text-muted); }

/* ---------- stickers and chips ---------- */
.sticker {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  vertical-align: middle;
  max-inline-size: 24ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: calc(4px - var(--border-width)) 12px;
  border-radius: var(--radius-pill);
  border: var(--border-width) solid var(--border);
  font: var(--type-xs);
  letter-spacing: 0;
  text-decoration: none;
  transform: rotate(var(--sticker-tilt));
}
.sticker .icon { --icon-size: 14px; }
a.sticker:hover { text-decoration: underline; }
.sticker-1 { background: var(--tag-1); color: var(--on-tag-1); }
.sticker-2 { background: var(--tag-2); color: var(--on-tag-2); }
.sticker-3 { background: var(--tag-3); color: var(--on-tag-3); }
.sticker-4 { background: var(--tag-4); color: var(--on-tag-4); }
:is(.ds-row, .album-extra, .feed-meta) > .sticker:nth-child(even) { transform: rotate(calc(var(--sticker-tilt) * -1)); }
.chip { overflow: visible; padding-inline-end: 4px; }
.chip-text { overflow: hidden; text-overflow: ellipsis; }
.chip-x { display: inline-grid; place-items: center; flex: none; inline-size: 24px; block-size: 24px; margin: -4px 0; padding: 0; border: 0; border-radius: var(--radius-pill); background: transparent; color: inherit; cursor: pointer; }
.chip-x .icon { --icon-size: 14px; }
.chip:has(button:focus-visible) { outline: var(--focus-width) solid var(--focus); outline-offset: var(--focus-offset); }
.chip button:focus-visible { outline: none; }

/* ---------- avatar: people are round in every theme ---------- */
.avatar { display: inline-grid; place-items: center; flex: none; inline-size: 40px; block-size: 40px; border-radius: 50%; border: var(--border-width) solid var(--border); font: var(--type-xs); font-weight: 800; object-fit: cover; overflow: hidden; }
.avatar-24 { inline-size: 24px; block-size: 24px; letter-spacing: -0.04em; }
.avatar-32 { inline-size: 32px; block-size: 32px; }
.avatar-72 { inline-size: 72px; block-size: 72px; font: var(--type-lg); font-weight: 800; }
@container (min-width: 768px) { .avatar-72.is-header { inline-size: 96px; block-size: 96px; } }

/* ---------- data table ---------- */
.table-wrap { overflow-x: auto; margin-block: 8px 16px; border-radius: var(--radius-sm); }
.table { inline-size: 100%; border-collapse: collapse; font: var(--type-sm); }
.table th { font: var(--type-xs); color: var(--text-muted); text-align: start; padding: 8px 12px; border-block-end: 1px solid var(--divider); }
.table td { padding: 12px; min-block-size: 48px; border-block-end: 1px solid var(--divider); }
.table .is-num { text-align: end; }
.table-empty { color: var(--text-muted); text-align: center; }

/* ---------- pickers ---------- */
.picker { display: grid; gap: 8px; }
.picked { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.picker-count { font: var(--type-xs); color: var(--text-muted); }
.picker-list { list-style: none; margin: 0; padding: 4px; display: grid; gap: 2px; background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-md); max-block-size: min(60vh, 26rem); overflow-y: auto; overscroll-behavior: contain; }
.picker-list:empty { display: none; }
.picker-row { display: grid; grid-template-columns: 40px minmax(0, 1fr) auto; align-items: center; gap: 12px; min-block-size: 56px; padding: 8px; border-radius: var(--radius-sm); cursor: pointer; }
.picker-row:hover, .picker-row.is-active { background: color-mix(in srgb, var(--text) 8%, transparent); }
.picker-row.is-active { outline: var(--focus-width) solid var(--focus); outline-offset: -2px; }
.picker-row.is-picked { background: var(--accent-soft); }
.picker-row.is-picked .picker-title { color: var(--on-accent-soft); }
.picker-row.is-picked .picker-meta { color: var(--on-accent-soft); }
.picker-row[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.picker-text { display: grid; min-inline-size: 0; }
.picker-title { font: var(--type-sm); font-weight: 700; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.picker-meta { font: var(--type-xs); color: var(--text-muted); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

/* sortable list */
.sortable-wrap { display: grid; gap: 8px; }
.sortable { list-style: none; margin: 0; padding: 0; display: grid; background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-md); }
.sortable-row { display: grid; grid-template-columns: 24px auto 40px minmax(0, 1fr) auto; align-items: center; gap: 12px; min-block-size: 56px; padding: 8px; background: var(--surface); border-radius: var(--radius-md); }
.sortable:not(.is-ranked) .sortable-row { grid-template-columns: 24px 40px minmax(0, 1fr) auto; }
.sortable-row + .sortable-row { border-block-start: 1px solid var(--divider); }
.sortable-row .drag { display: grid; place-items: center; block-size: 40px; color: var(--text-muted); cursor: grab; touch-action: none; }
.sortable-rank { font: var(--type-sm); font-weight: 800; min-inline-size: 2ch; text-align: end; }
.sortable-row.is-dragging { position: relative; z-index: 1; background: var(--surface-raised); box-shadow: var(--shadow-pop); cursor: grabbing; }
.sortable-row.is-drop-before { box-shadow: inset 0 var(--focus-width) 0 var(--focus); }
.sortable-row.is-drop-after { box-shadow: inset 0 calc(-1 * var(--focus-width)) 0 var(--focus); }
/* src/client/reorder.ts turns the first Move up and the last Move down into aria-disabled, so focus stays */
.sortable .menu-item[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.icon-up { transform: rotate(90deg); }
.icon-down { transform: rotate(-90deg); }

/* ---------- dialog and bottom sheet ---------- */
.dialog {
  inline-size: min(var(--layout-sheet), calc(100vw - 32px));
  max-block-size: 90dvh;
  padding: 12px 16px 16px;
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-pop);
  color: var(--text);
  overflow: auto;
}
.dialog::before { content: ""; position: absolute; inset: 0 0 auto; block-size: 2px; background: var(--cover-accent); }
.dialog::backdrop { background: var(--overlay); }
.dialog-narrow { inline-size: min(400px, calc(100vw - 32px)); }
.dialog[open] { animation: dialog-in var(--motion-base) var(--motion-spring); }
@keyframes dialog-in { from { transform: translateY(16px); opacity: 0; } }
.grab { display: none; inline-size: 40px; block-size: 4px; margin: 0 auto 12px; border-radius: var(--radius-pill); background: var(--border-input); }
.dialog-head { display: flex; align-items: center; gap: 12px; margin-block-end: 16px; }
.dialog-title { flex: 1; font: var(--type-lg); overflow-wrap: anywhere; }
.dialog-body { display: grid; gap: 16px; }
.dialog-body p { max-inline-size: 65ch; }
.dialog-foot, .dialog-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; margin-block-start: 16px; }
.dialog-foot .dialog-actions { margin: 0; }
@media (max-width: 767.98px) {
  .dialog:modal {
    inline-size: 100%;
    max-inline-size: none;
    margin: auto 0 0;
    border-end-start-radius: 0;
    border-end-end-radius: 0;
    padding-block-end: calc(16px + env(safe-area-inset-bottom));
  }
  .dialog:modal .grab { display: block; }
}

/* ---------- toasts ---------- */
.toasts { position: fixed; z-index: 40; inset-inline: 16px; inset-block-end: calc(var(--layout-tabbar) + 16px + env(safe-area-inset-bottom)); display: grid; justify-items: center; gap: 8px; pointer-events: none; }
@media (min-width: 768px) { .toasts { inset-inline: auto 16px; inset-block-end: 16px; justify-items: end; } }
.toast-stack { display: flex; flex-direction: column-reverse; gap: 8px; }
.toast-stack:empty { display: none; }
.toast {
  --focus: var(--on-inverse);
  display: flex;
  align-items: center;
  gap: 12px;
  max-inline-size: min(480px, calc(100vw - 32px));
  padding: 8px 8px 8px 16px;
  border-radius: var(--radius-md);
  background: var(--inverse);
  color: var(--on-inverse);
  box-shadow: var(--shadow-pop);
  font: var(--type-sm);
  pointer-events: auto;
  animation: toast-in var(--motion-base) var(--motion-ease);
}
@keyframes toast-in { from { transform: translateY(8px); opacity: 0; } }
.toast-text { flex: 1; }
.toast form { display: contents; }
.toast-action, .toast-close { min-block-size: 32px; padding: 4px 8px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--on-inverse); font: var(--type-sm); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.toast-close { display: inline-grid; place-items: center; text-decoration: none; }
@media (pointer: coarse) { .toast-action, .toast-close { min-block-size: var(--layout-tap); } }

/* ---------- notice banner ---------- */
.notice { display: flex; gap: 12px; align-items: flex-start; padding: 12px 16px; border-radius: var(--radius-md); background: var(--notice); color: var(--on-notice); border: var(--border-width) solid var(--border); font: var(--type-sm); }
.notice > .icon { margin-block-start: 1px; }
.notice-text { flex: 1; display: grid; gap: 4px; }
.notice p { max-inline-size: 65ch; }
.notice a, .notice .text-toggle { color: inherit; text-decoration: underline; }
.notice .icon-btn { margin: -8px -8px -8px 0; color: inherit; }

/* ---------- theme switcher ---------- */
.switcher { display: grid; gap: 8px; padding: 8px; }
.switcher fieldset { display: grid; gap: 4px; margin: 0; padding: 0; border: 0; min-inline-size: 0; }
.switcher .btn { justify-self: end; }
.switcher-legend { padding: 0; margin-block-end: 8px; font: var(--type-sm); font-weight: 600; }
/* As wide as its longest row (Signal, its lock, Premium and Preview), never wider than the screen. */
.theme-pop { inline-size: max-content; min-inline-size: 280px; max-inline-size: calc(100vw - 32px); padding: 0; }
.sw { display: inline-flex; flex: none; gap: 2px; padding: 4px 8px; border-radius: var(--radius-pill); border: var(--border-width) solid var(--border); background: var(--bg); color: var(--text); }
.sw .icon:first-child { background-color: var(--rating); }
.sw .icon:last-child { background-color: var(--react); }
.sw-sys { display: inline-flex; flex: none; overflow: hidden; inline-size: 52px; block-size: 26px; border-radius: var(--radius-pill); border: 1px solid var(--border-input); }
.sw-sys > span { flex: 1; background: var(--bg); }

/* ---------- empty, loading, error and no-permission states ---------- */
.empty { display: grid; justify-items: center; gap: 8px; padding: 24px 16px; text-align: center; background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-lg); }
.empty > .icon { --icon-size: 36px; color: var(--text-muted); }
.empty-title { font: var(--type-lg); }
.empty-text { max-inline-size: 65ch; font: var(--type-sm); color: var(--text-muted); }
.empty .btn { margin-block-start: 4px; }

.skeleton { display: block; background: var(--skeleton); border-radius: var(--radius-sm); }
.skeleton-square { aspect-ratio: 1; inline-size: 100%; border-radius: min(var(--radius-cover), 22%); }
.skeleton-circle { inline-size: 40px; block-size: 40px; border-radius: 50%; }
.skeleton-line { block-size: 0.75rem; inline-size: 100%; margin-block: 4px; }
.skeleton-line.is-short { inline-size: 60%; }
.skeleton-thumb { inline-size: 48px; }
.skeleton-stack { display: grid; gap: 4px; }
@media (prefers-reduced-motion: no-preference) {
  .skeleton { animation: pulse 1.6s ease-in-out infinite; }
  @keyframes pulse { 50% { opacity: 0.55; } }
}

.error-state { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; padding: 12px 16px; border-radius: var(--radius-md); border: var(--control-border-width) solid var(--danger); background: var(--surface); font: var(--type-sm); }
.error-state > .icon { color: var(--danger); }
.error-state p { flex: 1; min-inline-size: 12ch; }

/* ---------- error pages (S47) ---------- */
.error-page { display: grid; justify-items: start; gap: 12px; max-inline-size: var(--layout-content); margin: 32px auto; }
.error-code { font: var(--type-display); letter-spacing: var(--tracking-display); font-variation-settings: var(--display-variation); color: var(--text-muted); }
.error-page h1 { font: var(--type-2xl); letter-spacing: var(--tracking-2xl); font-variation-settings: var(--display-variation); }
.error-text { max-inline-size: 65ch; color: var(--text-muted); }
.error-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-block-start: 8px; }

/* ---------- coarse pointers: 44px targets ---------- */
@media (pointer: coarse) {
  .btn, .status, .pill, .like, .seg label, .seg-links a, .pagination a, .text-toggle, .filter, .filter select { min-block-size: var(--layout-tap); }
  .icon-btn { inline-size: var(--layout-tap); block-size: var(--layout-tap); }
  select { font-size: 1rem; }
}

/* ---------- meta line (S15 title block, S24, S26, S28): three facts, no separator characters ---------- */
.meta { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 16px; font: var(--type-sm); color: var(--text-muted); }
.meta b { color: var(--text); font-weight: 700; font-variant-numeric: tabular-nums; }

/* auth.css */
/* auth area: styles for src/views/auth/. Tokens only (see base.css). */

.auth {
  max-inline-size: 28rem;
  margin: 32px auto;
  padding: 24px;
  display: grid;
  gap: 16px;
}
.auth > p { max-inline-size: 30em; }
.auth strong { overflow-wrap: anywhere; }
.auth-form { display: grid; gap: 16px; }
.auth-submit { inline-size: 100%; }
.auth-switch { color: var(--text-muted); }
.auth-fine { color: var(--text-muted); }
.auth-resend { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }

/* Turnstile shows itself only when it needs a click (interaction-only). It shares a box with the button,
   so until then it takes no room and no gap; once Cloudflare puts the widget in, it gets 16px below it. */
.auth-send { display: grid; }
.auth-send .cf-turnstile > :not(input) { margin-block-end: 16px; }

/* The live username check (S46): the spinner while a check runs, the check glyph once the name is free,
   and the hint in --success or --danger with the answer. */
.name-state .spinner, .name-state .icon { display: none; }
.name-state.htmx-request .spinner { display: inline-block; }
.username-field:has(.hint [data-state="available"]) .name-state:not(.htmx-request) .icon-check { display: inline-block; color: var(--success); }
.username-field .hint:has([data-state="available"]) { color: var(--success); }
.username-field .hint:has([data-state="taken"], [data-state="reserved"], [data-state="invalid"]) { color: var(--danger); }
.name-status { display: inline-flex; align-items: baseline; gap: 4px; overflow-wrap: anywhere; min-inline-size: 0; }
.name-status .icon { --icon-size: 1em; align-self: center; }

@media (max-width: 479.98px) {
  .auth { margin-block: 16px; padding: 16px; }
}

/* catalog.css */
/* catalog area: styles for src/views/catalog/ (S15 release page, S24 artist page, S25 discography).
   Tokens only (see base.css). Breakpoints: sm 480px, md 768px, lg 1024px. */

/* ---------- S15 release header (components.md, S15 release header) ---------- */
.release-page, .artist-page { display: grid; gap: 32px; padding-block: 8px 32px; }
.release { display: grid; gap: 16px; align-items: start; }
.release-cover-col { display: grid; gap: 8px; justify-items: start; }
.release-cover-note { display: flex; gap: 4px; align-items: flex-start; max-inline-size: 320px; }
.release-main { display: grid; gap: 16px; min-inline-size: 0; }
.release-title { display: grid; gap: 4px; min-inline-size: 0; }
.release-kind { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.release-name, .artist-name {
  font-family: var(--font-display);
  letter-spacing: var(--tracking-2xl);
  font-variation-settings: var(--display-variation);
  overflow-wrap: anywhere;
}
.release-artist { overflow-wrap: anywhere; }
.release-artist a { color: inherit; }
.release-live { display: grid; gap: 16px; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.release-rate .rate-wrap { margin: 0; gap: 0 8px; }
.release-rate form, .release-rate .rate-guest { margin: 0; }
.action-icons { display: inline-flex; align-items: center; gap: 4px; }
.rate-guest { display: inline-flex; align-items: center; gap: 8px; min-block-size: 48px; font: var(--type-sm); font-weight: 600; }
.release-notice { margin: 0; color: var(--text-muted); }

@media (min-width: 1024px) {
  .release { grid-template-columns: 320px minmax(0, 1fr); gap: 32px; }
}

/* The second Log it, in a bar 8px above the floating tab bar, below md only. */
.sticky-log {
  position: fixed;
  inset-inline: 16px;
  inset-block-end: calc(var(--layout-tabbar) + 16px + env(safe-area-inset-bottom));
  z-index: 20;
  display: flex;
}
.sticky-log .btn { flex: 1; }
@media (min-width: 768px) { .sticky-log { display: none; } }
@media (max-width: 767.98px) {
  html:has(.sticky-log) { scroll-padding-bottom: calc(var(--layout-tabbar) + 16px + 56px + env(safe-area-inset-bottom)); }
  body:has(.sticky-log) { padding-block-end: calc(var(--layout-tabbar) + 16px + 56px + env(safe-area-inset-bottom)); }
}

/* ---------- Overview: one column, then a 320px side column from lg ---------- */
.release-overview, .artist-overview { display: grid; gap: 32px; align-items: start; }
.release-primary, .release-side, .artist-side { display: grid; gap: 32px; align-content: start; min-inline-size: 0; }
@media (min-width: 1024px) {
  .release-overview, .artist-overview { grid-template-columns: minmax(0, 1fr) 320px; gap: 48px; }
}
.release-block { display: grid; gap: 12px; align-content: start; min-inline-size: 0; }
.release-primary .carousel { margin-block: 0; }
.block-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 16px; }
.block-head .seg { margin: 0; }
.review-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; transition: opacity var(--motion-fast) var(--motion-ease); }
/* Loading: the old list dims while Everyone or Following loads. */
#release-reviews.htmx-request .review-list { opacity: 0.55; }
.release-block > .text-toggle { justify-self: start; }

/* ---------- genres ---------- */
.genre-chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.genre-chips li:nth-child(even) .sticker { transform: rotate(calc(var(--sticker-tilt) * -1)); }
.genre-edit > summary { justify-self: start; }
.genre-edit-body { display: grid; gap: 12px; padding-block-start: 12px; }
.genre-form { display: flex; flex-wrap: wrap; gap: 8px; }
.genre-clear { display: none; }
@media (scripting: none) {
  .genre-edit .chip-x { display: none; }
  .genre-clear { display: inline-flex; }
}

/* ---------- tracklist (components.md, Tracklist table) ---------- */
.tracklist { inline-size: 100%; border-collapse: collapse; font: var(--type-sm); }
.tracklist th, .tracklist td { padding: 8px 0; min-block-size: 44px; text-align: start; vertical-align: baseline; }
.tracklist thead th { font: var(--type-xs); color: var(--text-muted); border-block-end: 1px solid var(--divider); }
.tracklist tbody tr { border-block-end: 1px solid var(--divider); }
.tracklist .track-n { inline-size: 3ch; padding-inline-end: 12px; color: var(--text-muted); text-align: end; font-variant-numeric: tabular-nums; }
.tracklist .track-title { overflow-wrap: anywhere; }
.tracklist .track-len { padding-inline-start: 12px; color: var(--text-muted); text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tracklist .track-disc th { padding-block-start: 16px; font: var(--type-xs); font-weight: 700; color: var(--text-muted); }
.tracklist tfoot th, .tracklist tfoot td { color: var(--text); font-weight: 600; }
@media (scripting: enabled) {
  .tracklist:not(.is-open) .is-more { display: none; }
}
@media (scripting: none) {
  [data-tracks], [data-share] { display: none; }
}

/* ---------- details lists (release details, artist about) ---------- */
.details { margin: 0; display: grid; gap: 12px; font: var(--type-sm); }
.details > div { display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: 12px; }
.details dt { color: var(--text-muted); }
.details dd { margin: 0; min-inline-size: 0; overflow-wrap: anywhere; }
.label-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.label-name { font-weight: 600; }
.label-more { display: grid; gap: 4px; margin-block-start: 4px; }
.label-more[open] > summary { margin-block-end: 4px; }

/* ---------- S24 and S25 artist header ---------- */
.artist-head { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 16px; align-items: center; }
.artist-avatar {
  display: inline-grid;
  place-items: center;
  inline-size: 72px;
  block-size: 72px;
  border-radius: 50%;
  border: var(--border-width) solid var(--border);
  font: var(--type-xl);
  font-weight: 800;
}
.artist-title { display: grid; gap: 4px; min-inline-size: 0; }
.artist-note { font: var(--type-sm); }
.artist-title .meta { margin-block-start: 4px; }
@media (min-width: 768px) {
  .artist-head { gap: 32px; }
  .artist-avatar { inline-size: 160px; block-size: 160px; font: var(--type-display); }
}
.artist-top { display: grid; gap: 16px; }
.artist-top .tabs { margin-block: 8px 0; }

/* ---------- S25 discography filters and grid ---------- */
.discography { display: grid; gap: 16px; }
.disc-filters { display: grid; gap: 12px; }
.disc-tabs { margin: 0; justify-self: start; }
.disc-switches { margin: 0; padding: 0; border: 0; min-inline-size: 0; display: grid; gap: 4px; }
.disc-legend { padding: 0; margin-block-end: 4px; font: var(--type-sm); font-weight: 600; }
.disc-switch-row { display: flex; flex-wrap: wrap; gap: 0 24px; }
.disc-more > summary { justify-self: start; }
.disc-more { display: grid; }
.disc-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
@media (scripting: enabled) { .disc-apply { display: none; } }
.discography .result-count { margin-block: 0; }
.disc-grid { transition: opacity var(--motion-fast) var(--motion-ease); }
.discography.htmx-request .disc-grid { opacity: 0.55; }

/* content.css */
/* content area: styles for src/views/content/. Owned by the content job. Tokens only (see base.css). */

/* design.css */
/* The /design page (src/views/design/page.tsx): layout for the component sheet only. The components keep
   their own styles. Tokens only. */

.ds { display: grid; gap: 48px; }
.ds-head { display: grid; gap: 12px; }
.ds-h1 { font: var(--type-display); letter-spacing: var(--tracking-display); font-variation-settings: var(--display-variation); }
.ds-lede { max-inline-size: 65ch; color: var(--text-muted); }
.ds-themes { margin: 4px 0 0; justify-self: start; }
.ds-toc { display: flex; flex-wrap: wrap; gap: 4px 16px; font: var(--type-sm); }
.ds-toc a { display: inline-flex; align-items: center; min-block-size: 24px; color: var(--text-muted); }
.ds-toc a:hover { color: var(--text); }

.ds-section { display: grid; gap: 12px; padding-block-start: 32px; border-block-start: 1px solid var(--divider); min-inline-size: 0; }
.ds-title { font: var(--type-2xl); letter-spacing: var(--tracking-2xl); font-variation-settings: var(--display-variation); }
.ds-note { max-inline-size: 65ch; font: var(--type-sm); color: var(--text-muted); }
.ds-label { margin-block-start: 16px; font: var(--type-xs); color: var(--text-muted); }
.ds-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.ds-row-top { align-items: flex-start; }
.ds-stack { display: grid; gap: 16px; }
.ds-cols { display: grid; gap: 24px; grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); align-items: start; }
.ds-pane { display: grid; gap: 8px; align-content: start; min-inline-size: 0; container-type: inline-size; }
.ds-pane-narrow { max-inline-size: 360px; }
.ds-stickers { row-gap: 12px; }

/* A frame of covers with the bars floating over it, as on a real page. */
.ds-frame { position: relative; block-size: 320px; overflow: hidden; border-radius: var(--radius-lg); border: var(--border-width) solid var(--border); }
.ds-frame-short { block-size: auto; overflow: visible; padding: 8px 0; }
.ds-frame-covers { position: absolute; inset: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); align-content: start; gap: 8px; padding: 8px; }
.ds-frame .topbar { position: absolute; inset: 0 0 auto; margin: 8px; }
.ds-frame-short .topbar { position: relative; margin: 0 8px; }
.ds-frame .tabbar { position: absolute; display: grid; }
.ds .site-footer.is-demo { margin: 0; border-radius: var(--radius-lg); }

.ds-toasts { display: grid; justify-items: start; gap: 8px; }
.ds-toasts .toast { animation: none; }
.ds-skel-square { inline-size: 72px; }
.ds-skel-lines { display: grid; inline-size: 160px; }
.ds-error .error-page { margin: 0; padding: 24px; }
.ds-sortable { margin: 0; }

.ds-icons { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 8px; }
.ds-icons li { display: flex; align-items: center; gap: 8px; min-block-size: 44px; padding: 8px 12px; border-radius: var(--radius-md); background: var(--surface); font: var(--type-xs); }
.ds-icons .icon { --icon-size: 24px; }

/* discovery.css */
/* discovery area: styles for src/views/discovery/. Owned by the discovery job. Tokens only (see base.css). */

/* imports.css */
/* imports area: styles for src/views/imports/. Owned by the imports job. Tokens only (see base.css). */

/* lists.css */
/* lists area: styles for src/views/lists/. Owned by the lists job. Tokens only (see base.css). */

/* ---------- S34 list page ---------- */
.list-page { display: grid; gap: 24px; padding-block: 16px 32px; }
.list-head { display: grid; gap: 12px; min-inline-size: 0; }
.list-owner { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 8px; font: var(--type-sm); }
.list-owner-text { display: flex; flex-wrap: wrap; gap: 0 8px; min-inline-size: 0; }
.list-owner-text > a { font-weight: 700; text-decoration: none; overflow-wrap: anywhere; }
.list-owner-text > a:hover { text-decoration: underline; }
.list-title {
  font-family: var(--font-display);
  letter-spacing: var(--tracking-2xl);
  font-variation-settings: var(--display-variation);
  overflow-wrap: anywhere;
  max-inline-size: 24em;
}
.list-desc p { max-inline-size: 30em; white-space: pre-line; overflow-wrap: anywhere; }
.list-private { display: inline-flex; align-items: center; gap: 4px; }
.list-private .icon { --icon-size: 16px; }
.list-head .action-row form { display: contents; }

/* search, sort and view in one row that wraps */
/* Below about 560px the search takes its own line, and the sort and the view share the next one. */
.list-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-inline-size: 0; }
.list-filter .search { flex: 1 1 280px; max-inline-size: 400px; }
.list-filter .seg { margin: 0 0 0 auto; }
.list-filter .filter { min-block-size: var(--layout-tap); }
@media (scripting: enabled) { .list-apply { display: none; } }

.list-body { display: grid; gap: 8px; min-inline-size: 0; transition: opacity var(--motion-fast) var(--motion-ease); }
.list-body.htmx-request { opacity: 0.55; }
.list-body .result-count { margin-block: 0 4px; }
.list-albums { margin-block-start: 8px; }

/* the list view: one panel, rows split by a thin rule */
.list-rows { list-style: none; margin: 0; padding: 0; background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-lg); }
.list-row { display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; align-items: center; gap: 12px; min-block-size: 64px; padding: 8px 12px; }
.list-row:has(.list-row-rank) { grid-template-columns: 3ch 48px minmax(0, 1fr) auto; }
.list-row + .list-row { border-block-start: 1px solid var(--divider); }
.list-row-rank { font: var(--type-sm); font-weight: 800; text-align: end; }
.list-row-text { display: grid; gap: 2px; min-inline-size: 0; }
.list-row-title { font: var(--type-sm); font-weight: 700; text-decoration: none; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.list-row-title:hover { text-decoration: underline; }
.list-row-meta { font: var(--type-xs); color: var(--text-muted); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
@container (max-width: 479.98px) { .list-row-added { display: none; } }

.list-more { display: grid; gap: 12px; margin-block-start: 16px; }

/* the delete question without JavaScript */
.list-delete-page { display: grid; justify-items: start; gap: 12px; padding-block: 32px; }
.list-delete-page p { max-inline-size: 30em; overflow-wrap: anywhere; }
.list-delete-page .dialog-actions { justify-content: flex-start; }

/* a back link on nested pages (the add page, the editor) */
.list-back { justify-self: start; display: inline-flex; align-items: center; gap: 4px; min-block-size: 44px; margin-block-end: -8px; font: var(--type-sm); font-weight: 600; text-decoration: none; }
.list-back:hover { text-decoration: underline; }

/* ---------- S21 add to lists: the dialog and the page ---------- */
.add-album { display: grid; grid-template-columns: 56px minmax(0, 1fr); align-items: center; gap: 12px; }
.add-album-text { display: grid; gap: 2px; min-inline-size: 0; font: var(--type-sm); }
.add-album-text b, .add-album-text span { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.add-alert:empty { display: none; }
.add-alert p { display: flex; gap: 8px; align-items: flex-start; padding: 12px 16px; border-radius: var(--radius-md); border: var(--control-border-width) solid var(--danger); background: var(--surface); color: var(--danger); font: var(--type-sm); font-weight: 600; }
.add-body { display: grid; gap: 16px; }
.add-lists { display: grid; margin: 0; padding: 0; border: 0; min-inline-size: 0; }
.add-lists legend { padding: 0; margin-block-end: 4px; font: var(--type-sm); font-weight: 600; }
.add-row + .add-row { border-block-start: 1px solid var(--divider); }
.add-check { display: flex; gap: 12px; inline-size: 100%; min-block-size: 56px; padding: 8px 4px; }
.add-check:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.add-row.htmx-request .add-check { opacity: 0.6; }
.add-text { display: grid; gap: 2px; min-inline-size: 0; flex: 1; }
.add-title { font: var(--type-sm); font-weight: 700; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.add-meta { display: flex; flex-wrap: wrap; gap: 0 12px; font: var(--type-xs); color: var(--text-muted); }
.add-meta .icon { --icon-size: 14px; }
.add-empty { padding: 16px; }
.add-new { display: grid; gap: 0; padding-block-start: 16px; border-block-start: var(--border-width) solid var(--divider); }
.add-new .field { margin-block-end: 8px; }
.add-new-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }

.add-page { display: grid; gap: 16px; padding-block: 16px 32px; }
.add-page > section { display: grid; gap: 8px; }
.add-page-lists { list-style: none; margin: 0; padding: 0; background: var(--surface); border: var(--border-width) solid var(--border); border-radius: var(--radius-lg); }
.add-page-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-block-size: 56px; padding: 8px 12px; }
.add-page-row + .add-page-row { border-block-start: 1px solid var(--divider); }
.add-page-row .add-text { flex: 1 1 12em; }
.add-page-act { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px 12px; margin-inline-start: auto; }
.add-state { display: inline-flex; align-items: center; gap: 4px; font: var(--type-xs); font-weight: 700; }

/* ---------- S35 list editor ---------- */
.editor { display: grid; gap: 24px; padding-block: 16px 32px; }
.editor-details { display: grid; min-inline-size: 0; }
.editor-first { display: flex; align-items: center; gap: 12px; margin-block-end: 16px; font: var(--type-sm); overflow-wrap: anywhere; }
.editor-ranked { gap: 0; }
.editor-ranked .hint { margin-inline-start: 30px; }
.editor-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.editor-items { display: grid; gap: 16px; padding-block-start: 24px; border-block-start: var(--border-width) solid var(--divider); }
.editor-sub { font: var(--type-base); font-weight: 700; margin-block-start: 8px; }
.editor-add { display: grid; gap: 8px; }
/* "0 of 20" says nothing before the first pick: hidden from sight, still read, so the first pick is heard. */
.editor-add .picker:not(:has([data-picked] li)) .picker-count { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.editor-add-form { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 16px; }
@media (scripting: none) { /* "0 of 20" says nothing before the first pick: hidden from sight, still read, so the first pick is heard. */
.editor-add .picker:not(:has([data-picked] li)) .picker-count { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.editor-add-form { display: none; } }
.editor-pick .notice-text { gap: 8px; }
.editor-list { display: grid; gap: 8px; }
.editor-count { font: var(--type-sm); color: var(--text-muted); }
.editor-count:empty { display: none; }
.editor-count:focus { outline: none; }
.editor-count:focus-visible { outline: var(--focus-width) solid var(--focus); outline-offset: var(--focus-offset); }
.editor-list .sortable-row { transition: box-shadow var(--motion-fast) var(--motion-ease); }
.editor-danger { display: grid; justify-items: start; gap: 8px; padding-block-start: 24px; border-block-start: var(--border-width) solid var(--divider); }
.editor-danger p { max-inline-size: 30em; }

/* Forced colours drop box shadows, so the drag's drop line becomes a border there. */
@media (forced-colors: active) {
  .sortable-row.is-drop-before { border-block-start: 2px solid Highlight; }
  .sortable-row.is-drop-after { border-block-end: 2px solid Highlight; }
  .sortable-row.is-dragging { outline: 2px solid Highlight; }
}

/* logging.css */
/* logging area: styles for src/views/logging/. Owned by the logging job. Tokens only (see base.css). */

/* ---------- S20 log sheet and editor (components.md, Log sheet) ---------- */
.log-head { display: grid; grid-template-columns: 56px minmax(0, 1fr) auto; align-items: center; gap: 12px; margin-block-end: 16px; }
.log-head-text { display: grid; gap: 4px; min-inline-size: 0; }
.log-head-title, .log-head-meta { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; overflow-wrap: anywhere; }
.log-head-title { font: var(--type-lg); font-weight: 700; letter-spacing: 0; font-variation-settings: normal; }
.log-head-meta { font: var(--type-sm); color: var(--text-muted); }
.log-body { display: grid; gap: 16px; }
.log-statuses .statuses { flex-wrap: nowrap; }
.log-statuses .status { padding-inline: 8px; }
.log-form { display: grid; gap: 0; }
.log-form .rate-wrap { margin-block-end: 16px; }
.log-form .check { margin-block-end: 8px; }
.log-actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 8px; margin-block-start: 8px; }
.log-actions .log-delete { margin-inline-end: auto; color: var(--danger); }

/* The sheet: the dialog's own glass panel and 2px --cover-accent edge (components.css, dialog). Save stays
   in view while the fields scroll on a phone. */
.log-sheet { padding-block-end: 0; }
.log-sheet .log-actions {
  position: sticky;
  inset-block-end: 0;
  margin-inline: -16px;
  padding: 12px 16px 16px;
  background: var(--glass);
  border-block-start: 1px solid var(--divider);
}
@media (max-width: 767.98px) {
  .log-sheet .log-actions { padding-block-end: calc(16px + env(safe-area-inset-bottom)); }
}
.log-discard { padding: 16px; }
.log-discard-text { margin-block: 8px 16px; max-inline-size: 30em; }

/* The same sheet as a page. */
.log-page { display: grid; gap: 16px; max-inline-size: var(--layout-sheet); margin-inline: auto; padding: 16px; }
.log-page .log-head { margin-block-end: 0; }
.log-page .log-head-title { font: var(--type-xl); letter-spacing: var(--tracking-xl); font-family: var(--font-display); font-variation-settings: var(--display-variation); }
.log-confirm { display: grid; gap: 8px; padding: 12px 16px; border-radius: var(--radius-md); border: var(--control-border-width) solid var(--danger); background: var(--surface-raised); }
.log-confirm p { max-inline-size: 30em; font: var(--type-sm); }
.log-confirm-title { font: var(--type-lg); }
.log-confirm .dialog-actions { justify-content: flex-start; margin-block-start: 4px; }

/* ---------- swap dialog (Spinning is full) ---------- */
.swap-form { display: grid; gap: 12px; }
.swap-text { max-inline-size: 30em; }
.swap-text b { overflow-wrap: anywhere; }
.swap-slots { margin: 0; }
.swap-opt { min-block-size: 56px; padding-block: 8px; }
.swap-opt .opt-text { min-inline-size: 0; }
.swap-title { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.swap-page { gap: 12px; }
.swap-page .dialog-actions { margin: 0; }

/* ---------- S27 review page ---------- */
.entry { display: grid; grid-template-columns: minmax(0, 1fr); gap: 24px; padding-block: 8px 32px; }
.back-link { display: inline-flex; align-items: center; gap: 8px; justify-self: start; max-inline-size: 100%; min-block-size: 44px; font: var(--type-sm); font-weight: 600; color: var(--text-muted); text-decoration: none; }
.back-link span { min-inline-size: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.back-link:hover { color: var(--text); text-decoration: underline; }
.entry-head { display: grid; grid-template-columns: 112px minmax(0, 1fr); gap: 16px; align-items: start; }
.entry-cover { box-shadow: var(--shadow-cover); }
.entry-head-text { display: grid; gap: 8px; min-inline-size: 0; }
.entry-author { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font: var(--type-sm); }
.entry-author a { font-weight: 700; text-decoration: none; min-inline-size: 0; overflow-wrap: anywhere; }
.entry-author a:hover { text-decoration: underline; }
.entry-album { font: var(--type-xl); font-family: var(--font-display); letter-spacing: var(--tracking-xl); font-variation-settings: var(--display-variation); overflow-wrap: anywhere; }
.entry-album a { text-decoration: none; }
.entry-album a:hover { text-decoration: underline; }
.entry-artist { font: var(--type-base); color: var(--text-muted); overflow-wrap: anywhere; }
.entry-main { display: grid; gap: 12px; justify-items: start; }
.entry-rating .rating { font: var(--type-lg); }
.entry-date { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; font: var(--type-sm); color: var(--text-muted); }
.entry-title { font: var(--type-lg); font-weight: 700; max-inline-size: 30em; overflow-wrap: anywhere; }
.entry-body { display: grid; gap: 12px; max-inline-size: 30em; }
.entry-body p { white-space: pre-line; overflow-wrap: anywhere; }
.entry-tags { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; }
.entry-tags li:nth-child(even) .sticker { transform: rotate(calc(var(--sticker-tilt) * -1)); }
.entry-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-inline-start: -8px; }
.entry .comments { margin-block: 0; padding-block-start: 24px; border-block-start: 1px solid var(--divider); }
@container (min-width: 480px) {
  .entry-head { grid-template-columns: 160px minmax(0, 1fr); gap: 24px; }
  .entry-album { font: var(--type-2xl); letter-spacing: var(--tracking-2xl); font-family: var(--font-display); font-variation-settings: var(--display-variation); }
}

/* ---------- profile frame of Diary and Later (S29 tabs) ---------- */
.owner-page { display: grid; gap: 8px; padding-block: 8px 32px; }
.owner-head { display: flex; align-items: center; gap: 12px; min-inline-size: 0; }
.owner-id { display: grid; min-inline-size: 0; }
.owner-name { font: var(--type-xl); letter-spacing: var(--tracking-xl); font-family: var(--font-display); font-variation-settings: var(--display-variation); overflow-wrap: anywhere; }
.owner-handle { font: var(--type-sm); color: var(--text-muted); overflow-wrap: anywhere; }
.owner-handle a { text-decoration: none; }
.owner-handle a:hover { text-decoration: underline; }
.owner-page .tabs { margin-block: 8px 16px; }

/* Filter bars: native selects drawn like secondary buttons (components.css, .filter), plus a tag field.
   Apply is for visitors without JavaScript; with it, a change submits the form. */
.filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-block-end: 16px; }
.filter-text input { inline-size: 10ch; min-block-size: 34px; padding: 0; border: 0; background: transparent; color: var(--text); font: var(--type-sm); font-weight: 600; outline: none; }
.filter-text:has(input:focus-visible) { outline: var(--focus-width) solid var(--focus); outline-offset: 1px; }
.filters-clear { margin-inline-start: 4px; }
@media (scripting: enabled) { .filters-apply { display: none; } }

/* ---------- S31 diary (components.md, Diary row) ---------- */
.diary { display: grid; max-inline-size: 50rem; }
.diary-results { display: grid; gap: 24px; }
.diary-results > .result-count { margin: 0; }
.diary-year { display: grid; gap: 16px; }
.diary-year-title { font: var(--type-2xl); font-family: var(--font-display); letter-spacing: var(--tracking-2xl); font-variation-settings: var(--display-variation); }
.diary-month { display: grid; gap: 8px; }
.diary-month-title { font: var(--type-xs); font-weight: 700; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0; }
.diary-days { list-style: none; margin: 0; padding: 0; display: grid; border-block-start: 1px solid var(--divider); }
.diary-day { display: grid; grid-template-columns: 48px minmax(0, 1fr); gap: 12px; padding-block: 8px; border-block-end: 1px solid var(--divider); }
.diary-date {
  display: grid;
  align-content: center;
  justify-items: center;
  align-self: start;
  block-size: 48px;
  border-radius: var(--radius-md);
  border: var(--control-border-width) solid var(--border-input);
  background: var(--surface);
}
.diary-date-month { font: var(--type-xs); color: var(--text-muted); }
.diary-date-day { font: var(--type-xl); font-variant-numeric: tabular-nums; }
.diary-rows { list-style: none; margin: 0; padding: 0; display: grid; }
.diary-row {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto auto;
  grid-template-areas: "cover text marks stars" ;
  align-items: center;
  gap: 4px 12px;
  min-block-size: 56px;
  padding-block: 4px;
}
.diary-row:has(.menu-wrap) { grid-template-columns: 48px minmax(0, 1fr) auto auto auto; grid-template-areas: "cover text marks stars menu"; }
.diary-row + .diary-row { border-block-start: 1px solid var(--divider); }
.diary-row > .cover { grid-area: cover; }
.diary-text { grid-area: text; display: grid; gap: 2px; min-inline-size: 0; }
.diary-title { font: var(--type-sm); font-weight: 700; text-decoration: none; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.diary-title:hover { text-decoration: underline; }
.diary-artist { font: var(--type-xs); color: var(--text-muted); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.diary-marks { grid-area: marks; display: inline-flex; align-items: center; gap: 8px; color: var(--text-muted); }
.diary-repeat { font: var(--type-xs); }
.diary-stars { grid-area: stars; display: inline-flex; }
.diary-row > .menu-wrap { grid-area: menu; }
@container (max-width: 479.98px) {
  .diary-row, .diary-row:has(.menu-wrap) {
    grid-template-columns: 48px minmax(0, 1fr) auto;
    grid-template-areas: "cover text menu" "cover stars marks";
  }
  .diary-stars { justify-self: start; }
  .diary-marks { justify-self: end; }
}

/* ---------- S30 Later ---------- */
.later { display: grid; gap: 16px; }
.later-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
.later-filter { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-inline-size: 0; max-inline-size: 100%; }
.later-shuffle { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.later-results { display: grid; gap: 16px; }
.later-item { position: relative; min-inline-size: 0; }
.later-remove { position: absolute; inset-block-start: 4px; inset-inline-end: 4px; }
.later-remove .icon-btn { background: var(--surface-raised); color: var(--text); }
.later-remove .icon-btn:hover { background: color-mix(in srgb, var(--surface-raised) 88%, var(--bg)); }
.later-tools { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 8px; }

/* moderation.css */
/* moderation area: styles for src/views/moderation/. Owned by the moderation job. Tokens only (see base.css). */

/* profile.css */
/* profile area: styles for src/views/profile/. Owned by the profile job. Tokens only (see base.css).
   Layout switches on the page column's width (container queries on .page), at 480px for the header and
   640px for the tile grid (components.md, Profile header and Profile tiles). */

/* ---------- S28 and S29: the page ---------- */
.profile-page { display: grid; gap: 24px; padding-block: 8px 32px; }
.profile-page > .tabs { margin-block: 0; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }

/* ---------- the header ---------- */
/* Avatar, name and handle, and the action in one row from 480px; below it the action moves under the
   handle, so the name gets the whole row. */
.profile {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px 16px;
}
.profile-id { min-inline-size: 0; }
.profile-name {
  margin: 0 0 4px;
  font-family: var(--font-display);
  overflow-wrap: anywhere;
}
.handle { margin: 0; display: flex; flex-wrap: wrap; gap: 0 8px; }
.handle > span { min-inline-size: 0; overflow-wrap: anywhere; }
.profile-action { justify-self: end; }
.profile-bio, .profile-meta, .profile .stats { grid-column: 1 / -1; }
.profile-bio .clamp-text { max-inline-size: 30em; font: var(--type-sm); overflow-wrap: anywhere; }
.profile-bio p { white-space: pre-line; }
.profile-meta { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 16px; min-inline-size: 0; }
.profile-meta li { min-inline-size: 0; max-inline-size: 100%; }
.profile-meta a { display: inline-flex; align-items: center; gap: 4px; max-inline-size: 100%; min-block-size: 24px; color: var(--accent-text); }
.profile-meta .icon { --icon-size: 14px; flex: none; }
.profile-link { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@container (max-width: 479.98px) {
  .profile { grid-template-columns: auto minmax(0, 1fr); }
  .profile-action { grid-column: 2; justify-self: start; }
}

/* Stats row: the number above its label, numbers tabular in the display axis. */
.stats { display: flex; flex-wrap: wrap; gap: 8px 32px; margin: 0; }
.stats div { display: grid; }
.stats dt { order: 2; font: var(--type-xs); color: var(--text-muted); }
.stats dd { margin: 0; font: var(--type-xl); font-variant-numeric: tabular-nums; font-variation-settings: var(--display-variation); }
.stats dd a { text-decoration: none; }
.stats dd a:hover { text-decoration: underline; }

/* ---------- S28 tiles ---------- */
.tiles { display: grid; gap: 16px; }
.tile {
  display: grid;
  align-content: start;
  gap: 12px;
  min-inline-size: 0;
  padding: 16px;
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
}
.tile-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.tile-title { font: var(--type-lg); }
.tile-head .text-toggle { display: inline-flex; align-items: center; gap: 4px; }
.tile-head .text-toggle .icon { --icon-size: 14px; }
.tile-empty { font: var(--type-sm); max-inline-size: 30em; }
.tile-empty a { color: var(--accent-text); font-weight: 600; }
.tile .top5 { padding-block-start: 8px; }
@container (min-width: 640px) {
  .tiles { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .tile-span-6 { grid-column: span 6; }
  .tile-span-4 { grid-column: span 4; }
  .tile-span-3 { grid-column: span 3; }
  .tile-span-2 { grid-column: span 2; }
}

/* This week: a short definition list, label left and value right. */
.week { display: grid; gap: 8px; margin: 0; }
.week div { display: flex; justify-content: space-between; align-items: center; gap: 8px; min-block-size: 24px; }
.week dt { font: var(--type-sm); color: var(--text-muted); }
.week dd { margin: 0; min-inline-size: 0; font: var(--type-sm); font-weight: 700; font-variant-numeric: tabular-nums; text-align: end; }
.week-avg { display: inline-flex; align-items: center; gap: 8px; }

/* Latest review: the whole tile body is one link to the review. */
.tile-review { display: grid; gap: 4px; color: var(--text); text-decoration: none; min-inline-size: 0; border-radius: var(--radius-sm); }
.tile-review:hover .tile-review-title b { text-decoration: underline; }
.tile-review-title { font: var(--type-sm); overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.tile-review .review-meta { margin: 0; }
.tile-review-text { font: var(--type-sm); max-inline-size: 30em; overflow-wrap: anywhere; }

/* Latest list: the 2 by 2 mosaic over the title; beside it when the tiles stack (List card row). */
.tile-list-link { display: grid; gap: 4px; color: var(--text); text-decoration: none; min-inline-size: 0; border-radius: var(--radius-sm); }
.tile-list-link:hover .tile-list-title b { text-decoration: underline; }
.tile-list-title { font: var(--type-sm); overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; overflow: hidden; }
.tile-list-meta { display: flex; flex-wrap: wrap; gap: 4px 12px; }
.tile-list-meta .private { display: inline-flex; align-items: center; gap: 4px; }
.tile-list-meta .icon { --icon-size: 14px; }
.tile-list-link .mosaic { margin-block-end: 4px; }
/* In the narrow tile beside the latest review, a capped mosaic keeps the pair's row short. */
.tile-span-2 .tile-list-link .mosaic { inline-size: 100%; max-inline-size: 136px; }
@container (max-width: 639.98px) {
  .tile-list-link { grid-template-columns: 72px minmax(0, 1fr); grid-template-rows: 1fr auto auto 1fr; column-gap: 12px; row-gap: 0; }
  .tile-list-link .mosaic { grid-row: 1 / -1; margin: 0; }
  .tile-list-title { grid-area: 2 / 2; }
  .tile-list-meta { grid-area: 3 / 2; margin-block-start: 4px; }
}
/* A single list tile on its own row stays a row too: a full-width mosaic would be a poster. */
@container (min-width: 640px) {
  .tile-span-6 .tile-list-link { grid-template-columns: 96px minmax(0, 1fr); grid-template-rows: 1fr auto auto 1fr; column-gap: 16px; row-gap: 0; }
  .tile-span-6 .tile-list-link .mosaic { grid-row: 1 / -1; margin: 0; }
  .tile-span-6 .tile-list-title { grid-area: 2 / 2; }
  .tile-span-6 .tile-list-meta { grid-area: 3 / 2; margin-block-start: 4px; }
}

.profile-section { display: grid; gap: 12px; }

/* ---------- S29 tabs ---------- */
.profile-tab { display: grid; gap: 16px; }
.tab-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.tab-filters .seg { margin: 0; }
.tab-results { display: grid; gap: 16px; }
.tab-results .result-count { margin: 0; }
.tab-results .tab-new { justify-self: start; }
.review-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
/* Loading: while htmx fetches a filter change, the old results dim (no spinner over a grid). */
.tab-results { transition: opacity var(--motion-fast) var(--motion-ease); }
.profile-tab:has(.tab-filters.htmx-request) .tab-results { opacity: 0.6; }
/* With JavaScript the filters apply on change, so Apply is only for visitors without it. */
@media (scripting: enabled) {
  .tab-filters .filter-apply { display: none; }
}

/* search.css */
/* search area: styles for src/views/search/ (S14, the top bar's live results and the pickers). Tokens
   only (see base.css). */

/* ---------- every search field: the icon turns into a spinner while htmx loads ---------- */
.search:has(> input.htmx-request) > .icon-search {
  inline-size: 1em;
  block-size: 1em;
  margin-inline: 0.125em;
  background: none;
  mask: none;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
  .search:has(> input.htmx-request) > .icon-search {
    animation: none;
    border-color: color-mix(in srgb, currentColor 30%, transparent);
    border-top-color: currentColor;
  }
}
.search-failed { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; color: var(--text); }
.search-failed::before {
  content: '';
  flex: none;
  inline-size: 1.25em;
  block-size: 1.25em;
  background-color: var(--danger);
  mask: var(--icon-warning) center / contain no-repeat;
}

/* ---------- result rows: a link that is also a listbox option ---------- */
a.option { color: var(--text); text-decoration: none; }
a.option:focus-visible, .option.is-active { outline: var(--focus-width) solid var(--focus); outline-offset: -2px; }
.option-note.picker-row { display: block; min-block-size: 0; padding: 12px; color: var(--text-muted); font: var(--type-sm); opacity: 1; cursor: default; }
.option-note.picker-row:hover { background: none; }
.picker-row.is-genre { grid-template-columns: minmax(0, 1fr) auto; min-block-size: 44px; }
.picker-row .avatar { inline-size: 40px; block-size: 40px; }
.picker-meta .sticker, .hit-sub .sticker { vertical-align: 1px; }
/* Picked on the client (combobox.ts sets aria-selected) shows the check glyph too, so the state is never
   colour alone. Rows the server rendered as picked already carry the icon. */
.picker-row[aria-selected="true"]:not(:has(> .icon-check))::after {
  content: '';
  inline-size: 1.25em;
  block-size: 1.25em;
  background-color: currentColor;
  mask: var(--icon-check) center / contain no-repeat;
}

/* ---------- S14 ---------- */
.search-page, .pick-page { display: grid; gap: 16px; padding-block: 8px 32px; }
.search-page .tabs { margin-block: 0; }
.search-page .result-count, .pick-page .result-count { margin-block: 0; }
/* An empty count line stays in the page (a live region must exist before it speaks) but takes no room. */
.search-page .result-count:empty, .pick-page .result-count:empty { margin-block-end: -16px; }
.search-results { display: grid; gap: 16px; }
.search-results[aria-busy="true"] .hits, .pick-region[aria-busy="true"] .pick-list { opacity: 0.6; transition: opacity var(--motion-fast) var(--motion-ease); }
.search-results .section-title { margin-block-end: -8px; }
.hits { list-style: none; margin: 0; padding: 0; border-block-start: 1px solid var(--divider); }
.hits > li { border-block-end: 1px solid var(--divider); }
.hit {
  display: flex;
  align-items: center;
  gap: 12px;
  min-block-size: 64px;
  padding: 8px;
  margin-inline: -8px;
  border-radius: var(--radius-md);
}
.hit:hover, .hit.is-active { background: color-mix(in srgb, var(--text) 8%, transparent); }
.hit .cover { inline-size: 48px; flex: none; }
.hit-text { display: grid; gap: 2px; flex: 1; min-inline-size: 0; }
.hit-title { font-weight: 700; overflow-wrap: anywhere; }
.hit:hover .hit-title { text-decoration: underline; text-underline-offset: 3px; }
.hit-sub { font: var(--type-sm); color: var(--text-muted); overflow-wrap: anywhere; }
.hit-count { flex: none; font: var(--type-sm); color: var(--text-muted); }
.hit-count b { color: var(--text); }
.search-none .empty-title { overflow-wrap: anywhere; }
.search-pager { justify-content: space-between; margin-block: 0; }
/* The current page is weight plus an underline, so the state is never weight alone (forced colours too). */
.pager-at { font-weight: 700; text-decoration: underline 2px; text-underline-offset: 4px; }

@media (max-width: 479.98px) {
  .hit-count { display: none; }
}

/* Phones: the field stays under the floating top bar while the results scroll (full-screen search). */
@media (max-width: 767.98px) {
  .search-page .search-main, .pick-page .search-main {
    position: sticky;
    inset-block-start: calc(var(--layout-bar) + 8px);
    z-index: 10;
    margin-block: -8px;
    padding-block: 8px;
    background: var(--bg);
  }
}

/* ---------- the top bar's live results (from md) ---------- */
.topbar-search { position: relative; }
.suggest {
  position: absolute;
  inset-block-start: calc(100% + 8px);
  inset-inline-end: 0;
  display: grid;
  gap: 4px;
  inline-size: min(400px, calc(100vw - 32px));
  max-block-size: min(70vh, 560px);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 4px;
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
  background: var(--glass);
  box-shadow: var(--shadow-pop);
  color: var(--text);
}
.suggest:empty,
.topbar-search:not(:focus-within) .suggest,
.topbar-search:has(input[aria-expanded="false"]) .suggest { display: none; }
.suggest ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.suggest-label { padding: 8px 8px 0; font: var(--type-xs); font-weight: 700; color: var(--text-muted); }
.suggest-group + .suggest-group, .suggest-all { padding-block-start: 4px; border-block-start: 1px solid var(--divider); }
.suggest-more.picker-row { grid-template-columns: minmax(0, 1fr); min-block-size: 44px; }
.suggest-more .picker-title { color: var(--accent-text); }
/* A failed request: the status under the field becomes a small panel with Try again. */
.topbar-search .search-failed.visually-hidden {
  position: absolute !important;
  inset-block-start: calc(100% + 8px);
  inset-inline-end: 0;
  inline-size: min(360px, calc(100vw - 32px));
  block-size: auto;
  overflow: visible;
  clip-path: none;
  white-space: normal;
  padding: 12px;
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-md);
  background: var(--glass);
  box-shadow: var(--shadow-pop);
  font: var(--type-sm);
}
.topbar-search:not(:focus-within) .search-failed { display: none; }

/* ---------- picker pages ---------- */
.pick-intro { max-inline-size: 30em; color: var(--text-muted); }
.pick-list { padding: 4px; }
.back-link {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-block-size: 44px;
  margin-block-end: -8px;
  font: var(--type-sm);
  font-weight: 600;
  text-decoration: none;
}
.back-link:hover { text-decoration: underline; }

/* settings.css */
/* settings area: styles for src/views/settings/ (S36 settings, S33 profile fields and slot editors). Owned
   by the settings job. Tokens only (see base.css). Reading pages: one column, 720px. */

/* ---------- S36 settings ---------- */
.settings { display: grid; gap: 24px; padding-block: 8px 32px; }
.settings-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 8px 16px; }
.settings-head h1 { font-family: var(--font-display); }

/* The section links: one row that scrolls sideways on phones, like the tabs. */
.settings-nav { display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none; margin-inline: -8px; }
.settings-nav a {
  display: inline-flex;
  align-items: center;
  flex: none;
  min-block-size: 36px;
  padding: 0 8px;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font: var(--type-sm);
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}
.settings-nav a:hover { color: var(--text); text-decoration: underline; }
@media (pointer: coarse) { .settings-nav a { min-block-size: var(--layout-tap); } }

/* Sections are split by a rule, not boxed: the forms are the content. */
.settings-section { display: grid; gap: 16px; padding-block-start: 24px; border-block-start: 1px solid var(--divider); }
.settings-section-head { display: grid; gap: 4px; }
.settings-section-head p { max-inline-size: 30em; }
.settings-form { display: grid; min-inline-size: 0; }
.settings-form .field { margin-block-end: 16px; }
.settings-pair { display: grid; gap: 0 16px; align-items: start; }
.settings-pair .field { align-content: start; }
@container (min-width: 560px) { .settings-pair { grid-template-columns: 1fr 1fr; } }
.settings-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.settings-actions .hint { max-inline-size: 30em; }
.settings-saved { font: var(--type-sm); font-weight: 600; color: var(--success); }
.avatar-form { padding-block-end: 8px; }
.avatar-form .upload { margin-block-end: 8px; }
.avatar-form .drop { max-inline-size: 360px; }
.select { appearance: auto; min-block-size: var(--layout-tap); }
.settings-switcher { padding: 0; max-inline-size: 360px; }
.settings-switcher .btn { justify-self: start; }

/* The Top 5 and Spinning rows: the name and count, a strip of the covers, and the edit link. */
.slot-links { display: grid; gap: 12px; }
.slot-link {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px 16px;
  padding: 12px 16px;
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
}
.slot-link-title { font: var(--type-base); font-weight: 700; }
.slot-link-covers { list-style: none; margin: 0; padding: 0; display: flex; gap: 4px; grid-column: 1 / -1; grid-row: 2; }
.slot-link-covers .cover { inline-size: 40px; }
@container (min-width: 560px) {
  .slot-link { grid-template-columns: minmax(0, 1fr) auto auto; }
  .slot-link-covers { grid-column: auto; grid-row: auto; }
}

/* ---------- S33 slot editors ---------- */
.slot-editor { display: grid; gap: 24px; padding-block: 8px 32px; }
.slot-form { display: grid; gap: 16px; min-inline-size: 0; }
.slot-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 16px; }
.slot-head-text { display: grid; gap: 8px; min-inline-size: 0; flex: 1 1 18rem; }
.slot-head-text h1 { font-family: var(--font-display); }
.slot-head-text p { max-inline-size: 30em; }
.slot-head-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.slot-form .form-errors { margin: 0; }
.slot-form .form-errors p { display: flex; gap: 8px; align-items: flex-start; color: var(--danger); }
.slot-status { font: var(--type-sm); font-weight: 600; }
.slot-status:focus { outline: none; }
.slot-status:focus-visible { outline: var(--focus-width) solid var(--focus); outline-offset: var(--focus-offset); }
.slot-count { margin: 0; }
.slot-pick .notice-text { display: grid; gap: 8px; }
.slot-pick-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; }
.slot-add { display: grid; gap: 12px; padding-block-start: 24px; border-block-start: 1px solid var(--divider); }
.slot-add > p { max-inline-size: 30em; }
.slot-add .picked:empty { display: none; }

/* Loading: while a save runs in the background the list dims and Save says it is busy. */
.slot-form .sortable { transition: opacity var(--motion-fast) var(--motion-ease); }
.slot-form.htmx-request .sortable { opacity: 0.6; }
.slot-form.htmx-request #slots-save, .settings-form.htmx-request .btn-primary { cursor: progress; opacity: 0.8; }

/* sharing.css */
/* sharing area: styles for src/views/sharing/. Owned by the sharing job. Tokens only (see base.css). */

/* social.css */
/* social area: styles for src/views/social/. Owned by the social job. Tokens only (see base.css). */

/* ---------- S01 landing: hero and cover wall, features, this week's chart, sign-up band ---------- */
.landing-page { display: grid; gap: 64px; padding-block: 32px 64px; }
.landing-hero { display: grid; gap: 32px; align-items: center; }
.landing-copy { display: grid; gap: 16px; justify-items: start; }
.landing-title {
  margin: 0;
  max-inline-size: 12em;
  font: var(--type-display);
  letter-spacing: var(--tracking-display);
  font-variation-settings: var(--display-variation);
  text-wrap: balance;
}
.landing-text { margin: 0; max-inline-size: 30em; font: var(--type-lg); color: var(--text-muted); }
.landing-actions { display: flex; flex-wrap: wrap; gap: 12px; }
@media (min-width: 1024px) {
  .landing-hero { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 48px; min-block-size: 480px; }
}

/* The wall: three rows of covers, each holding its covers twice, so moving the track by half loops it.
   Edges fade out; hovering pauses; reduced motion stands still. Decoration only (aria-hidden). */
.wall {
  display: grid;
  gap: 12px;
  overflow: hidden;
  border-radius: var(--radius-xl);
  /* a mask uses only alpha, so any opaque token works */
  -webkit-mask-image: linear-gradient(90deg, transparent, var(--text) 12%, var(--text) 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, var(--text) 12%, var(--text) 88%, transparent);
}
.wall-row { overflow: hidden; }
.wall-track { display: flex; gap: 12px; inline-size: max-content; }
@media (prefers-reduced-motion: no-preference) {
  .wall-track { animation: wall-scroll 90s linear infinite; }
  .wall-row-reverse .wall-track { animation-direction: reverse; animation-duration: 110s; }
}
.wall .cover { flex: none; inline-size: 112px; box-shadow: var(--shadow-cover); }
.wall:hover .wall-track { animation-play-state: paused; }
@keyframes wall-scroll { to { transform: translateX(-50%); } }
@media (min-width: 1024px) { .wall .cover { inline-size: 136px; } }

.feature-tiles { list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; }
@media (min-width: 768px) {
  .feature-tiles { grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); }
  .feature-lead { grid-row: span 2; }
}
.feature-lead .feature-title { font: var(--type-xl); }
.feature-covers { display: flex; gap: 8px; margin-block-start: 8px; }
.feature-covers .cover { flex: 1; min-inline-size: 0; box-shadow: var(--shadow-cover); }
.feature-tile {
  display: grid;
  align-content: start;
  gap: 8px;
  padding: 24px;
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
}
.feature-tile p { margin: 0; }
.feature-icon {
  display: inline-grid;
  place-items: center;
  inline-size: 44px;
  block-size: 44px;
  border-radius: var(--radius-pill);
  background: var(--accent-soft);
  color: var(--on-accent-soft);
}
.feature-icon .icon { --icon-size: 24px; }
.feature-title { margin: 0; font: var(--type-lg); }

.landing-chart { display: grid; gap: 16px; }
.landing-chart-more { margin: 0; font: var(--type-sm); font-weight: 600; }
.landing-band {
  display: grid;
  justify-items: center;
  gap: 16px;
  padding: 48px 24px;
  text-align: center;
  background: var(--accent-soft);
  color: var(--on-accent-soft);
  border-radius: var(--radius-xl);
}
.landing-band .landing-text { color: inherit; }
.landing-band-title { margin: 0; font: var(--type-2xl); letter-spacing: var(--tracking-2xl); }

/* Sections rise as they scroll into view (a scroll-driven animation; where unsupported they just show). */
@supports (animation-timeline: view()) {
  .landing-section { animation: rise-in linear both; animation-timeline: view(); animation-range: entry 0% entry 70%; }
}
/* Movement only, no fade: text keeps its full contrast at every point of the animation. */
@keyframes rise-in { from { transform: translateY(24px); } }

/* ---------- The Musicbox 50 (the member home and the landing) ---------- */
.chart-head { display: grid; gap: 4px; }
/* The chart's filters: This week or All time, then the release time and the genre, wrapping on phones. */
.chart-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.chart-filters .seg { margin: 0; }
.chart-head p { margin: 0; max-inline-size: 40em; }
.chart-name-title { margin: 0; font: var(--type-2xl); letter-spacing: var(--tracking-2xl); font-variation-settings: var(--display-variation); }
.chart { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; }
.chart-row {
  display: grid;
  grid-template-columns: 3ch 4.5ch 48px minmax(0, 1fr);
  align-items: center;
  gap: 12px;
  padding: 8px;
  border-radius: var(--radius-md);
}
.chart-row:hover { background: color-mix(in srgb, var(--text) 6%, transparent); }
.chart-rank { font: var(--type-xl); font-variant-numeric: tabular-nums; text-align: end; }
.chart-row .cover { inline-size: 48px; }
.chart-name { display: grid; min-inline-size: 0; }
.chart-title { font: var(--type-base); font-weight: 700; color: var(--text); text-decoration: none; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chart-title:hover { text-decoration: underline; }
.chart-artist { font: var(--type-sm); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chart-stat { display: none; font: var(--type-sm); font-variant-numeric: tabular-nums; text-align: end; }
.chart-stat-label { display: block; font: var(--type-xs); color: var(--text-muted); }
@media (min-width: 768px) {
  .chart:not(.chart-compact) .chart-row { grid-template-columns: 3ch 4.5ch 56px minmax(0, 1fr) 7ch 10ch; }
  .chart:not(.chart-compact) .chart-row .cover { inline-size: 56px; }
  .chart-stat { display: block; }
}
.move { font: var(--type-xs); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.move-up { color: var(--success); }
.move-down { color: var(--danger); }
.move-same { color: var(--text-muted); }
.move-new { padding: 2px 6px; border-radius: var(--radius-pill); background: var(--accent-soft); color: var(--on-accent-soft); }
/* Number one, larger, above the list. */
.chart-top {
  display: grid;
  grid-template-columns: minmax(96px, 160px) minmax(0, 1fr);
  align-items: center;
  gap: 16px 24px;
  padding: 16px;
  margin-block: 8px;
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
  color: var(--text);
  text-decoration: none;
}
.chart-top:hover .chart-top-title { text-decoration: underline; }
.chart-top-text { display: grid; gap: 4px; min-inline-size: 0; }
.chart-top-kicker { font: var(--type-xs); font-weight: 700; color: var(--accent-text); }
.chart-top-title { font: var(--type-xl); font-variation-settings: var(--display-variation); overflow-wrap: anywhere; }
.chart-top-artist { font: var(--type-base); color: var(--text-muted); }
.chart-top-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font: var(--type-sm); color: var(--text-muted); }
/* Rows rise in by rank as they scroll into view, and an up or down arrow nudges once. */
@supports (animation-timeline: view()) {
  .landing-chart .chart-row { animation: rise-in linear both; animation-timeline: view(); animation-range: entry 0% entry 50%; }
}
.move-up > span:first-child, .move-down > span:first-child { display: inline-block; }
@media (prefers-reduced-motion: no-preference) {
  .move-up > span:first-child, .move-down > span:first-child { animation: nudge var(--motion-slow) var(--motion-spring) calc(var(--motion-fast) + var(--row, 0) * 40ms) both; }
  .move-down > span:first-child { animation-name: nudge-down; }
}
@keyframes nudge { 50% { transform: translateY(-3px); } }
@keyframes nudge-down { 50% { transform: translateY(3px); } }

@media (prefers-reduced-motion: reduce) {
  .wall-track, .landing-section, .chart-row, .move-up > span:first-child, .move-down > span:first-child { animation: none; }
}

/* ---------- Home (the Spinning strip, the chart and friends) and Friends (the feed) ---------- */
.home { display: grid; gap: 24px; padding-block: 16px 32px; }
.home-grid { display: grid; gap: 32px; align-items: start; }
.home-chart { display: grid; gap: 12px; min-inline-size: 0; }
.home-friends { display: grid; gap: 12px; }
.home-friends-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.home-friends-head .section-title { margin: 0; }
@media (min-width: 1024px) {
  .home-grid { grid-template-columns: minmax(0, 1fr) 320px; }
  .home-friends { position: sticky; inset-block-start: calc(var(--layout-bar) + 24px); }
}
.home-strip {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px 24px;
  padding: 16px;
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
}
.home-strip-main { display: grid; gap: 8px; min-inline-size: 0; }
.home-strip-title { margin: 0; font: var(--type-sm); font-weight: 700; }
.home-strip-main p { margin: 0; max-inline-size: 30em; }
.home-later {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-block-size: 44px;
  padding: 8px 12px;
  border-radius: var(--radius-md);
  color: var(--text);
  text-decoration: none;
}
.home-later:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.home-later > .icon:first-child { color: var(--accent-text); }
.home-later-text { display: grid; }
.home-later-label { font: var(--type-sm); font-weight: 700; }
@container (max-width: 479.98px) {
  .home-strip { grid-template-columns: minmax(0, 1fr); }
  .home-later { justify-self: stretch; padding-inline: 0; border-block-start: 1px solid var(--divider); border-radius: 0; padding-block-start: 12px; }
  .home-later > .icon:last-child { margin-inline-start: auto; }
}

.home-feed { display: grid; gap: 12px; }
.home-feed-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 16px; }
.home-feed-head .section-title { margin: 0; }
.home-feed-head .seg { margin: 0; }
.home-feed .notice p, .home-feed .error-state p { margin: 0; }
/* a grouped row (a sentence over a row of covers) keeps its avatar beside the sentence */
.home .feed-item:has(.feed-covers) { align-items: start; }

/* Load more: while htmx fetches the next page, two placeholder rows show and the button rests. */
.load-more-skeleton { display: none; }
.load-more:has(> a.htmx-request) { display: grid; grid-template-columns: minmax(0, 1fr); justify-items: center; padding: 0 0 12px; }
.load-more:has(> a.htmx-request) .load-more-skeleton { display: grid; justify-self: stretch; }
.load-more-skeleton .feed-item + .feed-item { border-block-start: 1px solid var(--divider); }
.load-more > a.htmx-request { pointer-events: none; opacity: 0.45; }
.feed-error { list-style: none; padding: 12px; border-block-start: 1px solid var(--divider); }

/* ---------- S16 reviews of a release ---------- */
.reviews-page { display: grid; padding-block: 16px 32px; }
.reviews-head { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 16px; }
.reviews-cover { display: block; border-radius: min(var(--radius-cover), 22%); }
.reviews-id { display: grid; gap: 4px; min-inline-size: 0; }
.reviews-id p { margin: 0; }
.reviews-title { margin: 0; overflow-wrap: anywhere; text-wrap: balance; }
.reviews-title a { text-decoration: none; }
.reviews-title a:hover { text-decoration: underline; }
.reviews-by { color: var(--text); overflow-wrap: anywhere; }
.reviews-tools { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 16px; margin-block-end: 8px; }
.reviews-tools .seg { margin: 0; }
.review-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.reviews-page > .empty { margin-block-start: 8px; }

/* ---------- a premium theme previewed on the home (GET /?preview=<id>) ---------- */
.preview-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  margin-block-start: 16px;
  padding: 12px 16px;
  background: var(--accent-soft);
  color: var(--on-accent-soft);
  border-radius: var(--radius-lg);
}
.preview-bar p { margin: 0; flex: 1 1 20em; }
.preview-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.premium-soon { display: none; max-inline-size: 22em; padding: 16px; gap: 8px; }
.premium-soon:popover-open { display: grid; }
.premium-soon p, .premium-soon h2 { margin: 0; }
