/* site.css — The Serotonium. Hand-written, no framework (SPEC §12.4).
   Sections: fonts · tokens · base · utilities · header · search · intro · months · card · listen · history · load more · states. */

/* Fonts ------------------------------------------------------------------- */

@font-face { font-family: "FURIA I"; src: url("../fonts/furia-i.6ad9421c1a67.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Maison Neue"; src: url("../fonts/maison-neue-book.b2c5449a82e9.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Maison Neue"; src: url("../fonts/maison-neue-medium.1823abb6c9f6.woff2") format("woff2"); font-weight: 500; font-display: swap; }
/* Playfair (full Latin): release titles and month headings. */
@font-face { font-family: "Playfair Display"; src: url("../fonts/playfair-display-regular.27b2f94167bc.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Playfair Display"; src: url("../fonts/playfair-display-italic.1445697555f1.woff2") format("woff2"); font-style: italic; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url("../fonts/ibm-plex-mono-400.4cc7b4398540.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "IBM Plex Mono"; src: url("../fonts/ibm-plex-mono-600.ed616eb04c5f.woff2") format("woff2"); font-weight: 600; font-display: swap; }

/* Tokens ------------------------------------------------------------------ */

:root {
  --bg: #f4f2ee;
  --card: #fff;
  --fg: #151413;
  --muted: #625e58;
  --line: #e3dfd8;
  --control: #8a847c;
  --accent: #7a2457;
  --focus: #1f5fd6;
  --search-focus: #d06a99; /* softest pink with ≥ 3:1 on page and field */
  --hover: #f4f2ee;
  --shadow: 0 1px 2px rgb(21 20 19 / 4%), 0 6px 20px rgb(21 20 19 / 5%);
  --sans: "Maison Neue", system-ui, -apple-system, "Segoe UI", sans-serif;
  --serif: "Playfair Display", Georgia, serif;
  --mono: "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  /* Type scale (13/14/16/18/24px). Inputs stay ≥ 16px: iOS zooms on smaller ones. */
  --text-xs: .8125rem;
  --text-sm: .875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.5rem;
  --art: 104px;
  --target: 44px;
  --header: 4rem;
  color-scheme: light dark;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #0e0e0d;
    --card: #181716;
    --fg: #f2efe9;
    --muted: #a39d94;
    --line: #2b2927;
    --control: #6e6862;
    --accent: #e7a6cf;
    --focus: #8ab4ff;
    --search-focus: #e7a6cf;
    --hover: #22201e;
    --shadow: none;
  }
}

/* Base -------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
/* scroll-padding: focus and anchors land below the sticky header (WCAG 2.4.11). */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; font-synthesis: none; scroll-padding-top: calc(var(--header) + 1rem); }

body {
  margin: 0 auto;
  max-width: 46rem;
  padding: 0 max(1rem, env(safe-area-inset-right)) 4rem max(1rem, env(safe-area-inset-left));
  background: var(--bg);
  color: var(--fg);
  font: 400 var(--text-base)/1.5 var(--sans);
  -webkit-font-smoothing: antialiased;
  overflow-wrap: anywhere;
}
@media (min-width: 40rem) { body { padding-inline: max(1.5rem, env(safe-area-inset-left)) max(1.5rem, env(safe-area-inset-right)); } }

h1, h2, h3, p, ol, ul { margin: 0; }
ol, ul { padding: 0; list-style: none; }
a { color: var(--accent); text-underline-offset: .2em; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
main:focus, .release-title:focus:not(:focus-visible) { outline: none; }
svg { fill: currentColor; flex: none; }

/* Utilities --------------------------------------------------------------- */

.visually-hidden:not(:focus):not(:active) {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.icon-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.skip-link { position: absolute; z-index: 3; left: 1rem; top: -100%; padding: .75rem 1rem; background: var(--card); }
.skip-link:focus { top: 1rem; }

.rss, .crumbs, .intro-count, .results-summary, .release-meta, .release-history, .search-key, #more a {
  font-family: var(--mono); font-size: var(--text-xs); letter-spacing: .01em;
}

/* Header ------------------------------------------------------------------ */

/* Sticky bar: wordmark left, RSS right. The shadows paint its background and hairline full-bleed;
   clip-path trims them to the bar's height. */
.site-header {
  position: sticky; top: 0; z-index: 2; display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; min-height: var(--header); padding-top: env(safe-area-inset-top); margin-bottom: 1.5rem;
  background: var(--bg); box-shadow: 0 0 0 100vmax var(--bg), 0 1px 0 100vmax var(--line); clip-path: inset(0 -100vmax -1px);
}
.wordmark { font: 400 clamp(1.875rem, 1.5rem + 1.2vw, 2.25rem)/1 "FURIA I", Georgia, serif; overflow-wrap: normal; }
.wordmark a { display: inline-flex; align-items: center; gap: .3em; white-space: nowrap; color: var(--fg); text-decoration: none; }
/* Logomark: the FURIA keys, decorative, in the wordmark's colour. */
.wordmark a::before { content: ""; width: .8em; height: .8em; background: currentColor; mask: url("../img/keys.e7a18b431a56.png") center / contain no-repeat; }

/* Search ------------------------------------------------------------------ */

.rss { display: inline-flex; align-items: center; gap: .5rem; min-height: var(--target); color: var(--muted); white-space: nowrap; }
.rss svg { width: 14px; height: 14px; }

.search-row { display: flex; align-items: center; gap: .5rem; padding: .375rem; border: 1px solid var(--line); background: var(--card); }
.search-row:focus-within { outline: 3px solid var(--search-focus); outline-offset: 2px; }
.search input {
  flex: 1; min-width: 0; min-height: var(--target); padding: 0 .75rem;
  border: 0; background: none; color: var(--fg); font: inherit; font-size: var(--text-base);
}
.search input::placeholder { color: var(--muted); opacity: 1; font-size: var(--text-xs); } /* the field stays 16px */
.search input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.search input:focus { outline: none; }
.search button { min-height: var(--target); min-width: var(--target); border: 0; background: none; color: var(--fg); cursor: pointer; }
.search-clear:hover { background: var(--hover); }
.search-clear { display: none; font-size: 1.25rem; line-height: 1; }
.js .search-row:has(input:not(:placeholder-shown)) .search-clear { display: inline-flex; align-items: center; justify-content: center; }
.search-key { margin-right: .5rem; padding: .0625rem .375rem; border: 1px solid var(--line); color: var(--muted); }
.search-row:has(input:not(:placeholder-shown)) .search-key, .search-row:focus-within .search-key { display: none; }
@media (hover: none) { .search-key { display: none; } }

.results-summary { margin-top: 1.5rem; color: var(--muted); text-wrap: pretty; }

/* Intro (a person's page) ------------------------------------------------- */

/* Breadcrumb "All › Name": 44px-tall links, a muted chevron between, the current page in --fg. */
.crumbs ol { display: flex; flex-wrap: wrap; align-items: center; margin: -.75rem 0 0; padding: 0; list-style: none; }
.crumbs li { display: flex; align-items: center; min-width: 0; }
.crumbs li + li::before { content: "›"; padding-inline: .625rem; color: var(--muted); }
.crumbs a { display: inline-flex; align-items: center; min-height: var(--target); color: var(--muted); }
.crumbs [aria-current] { color: var(--fg); text-decoration: none; overflow-wrap: anywhere; }
.intro { margin-bottom: 1.5rem; }
.intro h2 { font: 400 var(--text-xl)/1.2 var(--serif); text-wrap: balance; overflow-wrap: anywhere; }
.intro-count { margin-top: .5rem; color: var(--muted); }

/* Months ------------------------------------------------------------------ */

.month h2 {
  display: flex; align-items: center; gap: 1rem; margin: 3rem 0 1rem;
  font: italic 400 var(--text-base)/1.2 var(--serif);
}
/* FURIA keys as a mask: takes any theme's colour. */
.month h2::before {
  content: ""; width: 1rem; height: 1rem; margin-right: -.5rem;
  background: var(--muted); mask: url("../img/keys.e7a18b431a56.png") center / contain no-repeat;
}
.month h2::after { content: ""; flex: 1; border-top: 1px solid var(--line); }
.month:not(:has(h2)) .releases { margin-top: .75rem; }

/* Card. A label strip (kind · sharer · date) runs across the top. Below it the art's edges are the
   alignment lines: title caps sit on its top edge; history and listen buttons sit on its bottom edge.
   The cover and title open "Listen elsewhere". Lays out by the list's own width (container query), not the viewport's. */

.releases { display: grid; gap: .75rem; container: releases / inline-size; }

.release {
  display: grid; align-items: start; gap: .5rem 1.5rem;
  /* The bottom row is exactly one target tall, so it ends on the art's edge; an opened history list
     grows into the last row instead of moving anything. */
  grid-template:
    "meta meta    meta" auto
    "art  text    text" 1fr
    "art  history listen" var(--target)
    ".    history ." auto / var(--art) 1fr auto;
  padding: 1.25rem 1.25rem .75rem; border: 1px solid var(--line); background: var(--card); box-shadow: var(--shadow);
}
.release:focus-within { border-color: var(--control); }

.release-art-link { grid-area: art; display: block; color: inherit; text-decoration: none; }
.release-art { display: block; width: var(--art); height: var(--art); object-fit: cover; background: var(--hover); }
.release-art--empty { display: grid; place-items: center; color: var(--muted); font: 400 2rem/1 var(--serif); }

.release-text { grid-area: text; min-width: 0; }
.release-title {
  font: 400 var(--text-lg)/1.25 var(--serif);
  text-wrap: balance; font-kerning: normal; text-box: trim-start cap alphabetic;
}
.release-title a { color: var(--fg); text-decoration: none; letter-spacing: .25px; }
.release-title a:hover { text-decoration: underline; text-decoration-thickness: 1px; }
.release-artist { margin-top: .375rem; color: var(--muted); font-size: var(--text-sm); letter-spacing: .3px; text-wrap: pretty; }
/* Label strip: kind left, "shared by N, on DATE" right. */
.release-meta {
  grid-area: meta; display: flex; flex-wrap: wrap; align-items: baseline; gap: .25rem .75rem; min-width: 0;
  margin-bottom: .5rem; padding-bottom: 1rem; border-bottom: 1px solid var(--line); color: var(--muted);
}
.shared { margin-left: auto; text-align: right; }
.release-meta time, .release-history time, .release-meta a { white-space: nowrap; }
.release-meta a, .release-history a { color: var(--fg); }
.kind { color: var(--fg); font-weight: 600; text-transform: uppercase; letter-spacing: .08em; }
/* A note for a track, a record for an album; decorative, the word stays. */
.kind svg { width: 12px; height: 12px; vertical-align: -1px; }
.tag { padding: 0 .5rem; border: 1px solid var(--control); }

/* Listen links: platform icons, a divider, then "Listen elsewhere" (song.link) */

.listen { grid-area: listen; align-self: start; display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; }
/* Icons: 36×44 targets (D33), 16px apart. */
.listen a {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 36px; min-height: var(--target); color: var(--fg); text-decoration: none;
}
.listen a:hover { background: var(--hover); }
.listen-elsewhere { display: flex; align-items: center; }
.listen-elsewhere::before { content: ""; width: 1px; height: 20px; margin-inline: .25rem; background: var(--line); }

@container releases (max-width: 34rem) {
  /* One hairline only (under the label strip). Beside the art, bottom row: the shares toggle left,
     icons right (last glyph on the card's text edge). Negative margins trim the 44px targets to
     their 20px glyph line, so that row sits on the art's bottom edge. */
  .release {
    --art: 72px; gap: .5rem 1rem; padding: 1rem;
    grid-template: "meta meta meta" auto "art text text" auto "art history listen" 20px ". history ." auto / var(--art) 1fr auto;
  }
  .release-meta { margin-bottom: .5rem; padding-bottom: .875rem; }
  .listen { align-self: end; margin: -12px -8px -12px 0; }
  .release-history summary { margin-top: -12px; }
  /* The open list may run under the icons (that cell is empty): the full width beside the art. */
  .release-history { min-width: 0; }
  .release-history ul { width: max-content; max-width: calc(100cqi - var(--art) - 3rem); }
}
/* Where the toggle and icons don't fit side by side, the toggle drops below the art (D36). Measured:
   side by side needs a list 256px + 36px per platform wide (fits "12 reccs" without wrapping). */
@container releases (max-width: 435px) {
  .release:has(.listen li:nth-child(6)) { grid-template: "meta meta" auto "art text" auto "art listen" 1fr "history history" auto / var(--art) 1fr; }
  .release:has(.listen li:nth-child(6)) .release-history summary { margin-top: 0; }
}
@container releases (max-width: 399px) {
  .release:has(.listen li:nth-child(5)) { grid-template: "meta meta" auto "art text" auto "art listen" 1fr "history history" auto / var(--art) 1fr; }
  .release:has(.listen li:nth-child(5)) .release-history summary { margin-top: 0; }
}
@container releases (max-width: 363px) {
  .release:has(.listen li:nth-child(4)) { grid-template: "meta meta" auto "art text" auto "art listen" 1fr "history history" auto / var(--art) 1fr; }
  .release:has(.listen li:nth-child(4)) .release-history summary { margin-top: 0; }
}
@container releases (max-width: 327px) {
  .release:has(.listen li:nth-child(3)) { grid-template: "meta meta" auto "art text" auto "art listen" 1fr "history history" auto / var(--art) 1fr; }
  .release:has(.listen li:nth-child(3)) .release-history summary { margin-top: 0; }
}
@container releases (max-width: 291px) {
  .release { grid-template: "meta meta" auto "art text" auto "art listen" 1fr "history history" auto / var(--art) 1fr; }
  .release .release-history summary { margin-top: 0; }
}

/* History ----------------------------------------------------------------- */

.release-history { grid-area: history; align-self: start; color: var(--muted); }
.release-history summary { display: inline-flex; white-space: nowrap; align-items: center; gap: .5rem; min-height: var(--target); cursor: pointer; list-style: none; }
.release-history summary::-webkit-details-marker { display: none; }
.release-history summary::before { content: "+"; width: 1ch; }
.release-history[open] summary::before { content: "−"; }
.release-history ul { padding: 0 0 .25rem 1.5ch; }
.release-history li { padding-block: .125rem; }

/* Load more --------------------------------------------------------------- */

#more { margin-top: 2rem; }
#more a {
  display: flex; align-items: center; justify-content: center; min-height: 52px;
  border: 1px solid var(--control); color: var(--fg); text-decoration: none;
}
#more a:hover { background: var(--card); }
#more a[aria-disabled] { color: var(--muted); cursor: progress; }

/* States ------------------------------------------------------------------ */

.empty { margin-top: 2rem; padding: 3rem 1rem; border: 1px dashed var(--control); color: var(--muted); text-align: center; }

#status.is-error {
  position: static; width: auto; height: auto; clip-path: none; white-space: normal;
  margin-top: 1rem; padding: 1rem; border: 1px solid var(--accent); background: var(--card);
}

@media (max-width: 40rem) {
  :root { --header: 3.5rem; }
  .month h2 { margin: 2rem 0 1.25rem; }
}

/* Short viewports (400% zoom, landscape phones): the header scrolls away instead of eating the screen. */
@media (max-height: 30rem) {
  .site-header { position: static; }
  html { scroll-padding-top: 0; }
}

@media (prefers-reduced-motion: no-preference) {
  .listen a, #more a, .search button, .release { transition: background-color .15s ease, border-color .15s ease; }
}

@media (forced-colors: active) {
  .release, .search-row, .empty, #more a, .tag, #status.is-error { border-color: CanvasText; }
  .listen-elsewhere::before { background: CanvasText; }
  .site-header { border-bottom: 1px solid CanvasText; }
  .search button { border: 1px solid ButtonText; }
  .listen svg { fill: LinkText; }
  .month h2::before, .wordmark a::before { background: CanvasText; }
}
