/* Hallmark · genre: atmospheric · macrostructure: Console (bespoke) · theme: Midnight
 * verb: redesign (was Index-First) · enrichment: none (typography only)
 * chrome: fixed top bar + fixed status bar · footer: status line
 * mode: dark · anchor hue: 255 · tone: technical / instrument
 * audience: someone who wants the right row fast · use case: open one song, or send a set onward
 * motion primitives: row-tint (1)
 * outlier face: JetBrains Mono in exactly 2 slots — .kbd · .col-rank cells
 * pre-emit critique: P5 H5 E5 S5 R5 V5
 * slop test: 58/58 · contrast: pass (40–41) · mobile: pass (34, 49, 50–57)
 * honest: pass (46) · chrome: pass (47) · tokens: pass (48) · icons: pass (30)
 *
 * Mobile-first. Every colour and font comes through a token in tokens.css.
 * The table collapses to stacked cards below 52rem — a 7-column grid is not a
 * mobile layout, and horizontal scroll is a gate-34 failure.
 */

@import url("tokens.css");

/* ============================================================
   Base
   ============================================================ */

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

html {
  overflow-x: clip;
  scroll-padding-block: var(--space-3xl) var(--space-3xl);
  -webkit-text-size-adjust: 100%;
}

body {
  overflow-x: clip;
  margin: 0;
  min-height: 100dvh;
  background-color: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 350;              /* dark-mode optical compensation */
  line-height: 1.55;
  padding-block: var(--bar-height) calc(var(--bar-height) + env(safe-area-inset-bottom, 0px));
  padding-inline: max(0px, env(safe-area-inset-left));
}

/* One bloom only. The console is an instrument, not a canvas — the atmosphere
   sits behind the chrome rather than competing with the data. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: var(--z-base);
  pointer-events: none;
  background-image: radial-gradient(46rem 34rem at 8% -8%, var(--color-bloom), transparent 72%);
  opacity: 0.13;
}

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 800;
  font-style: normal;            /* headers are roman — never italic */
  letter-spacing: -0.03em;
  line-height: 1.08;
  overflow-wrap: anywhere;
  min-width: 0;
  margin: 0;
}

p { margin: 0; }
a { color: inherit; text-decoration: none; }

:focus-visible {
  outline: var(--rule-thick) solid var(--color-focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
  /* never transitioned — the ring must be there on the first frame */
}

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

.u-visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: absolute;
  inset-block-start: var(--space-xs);
  inset-inline-start: var(--space-xs);
  z-index: var(--z-top);
  padding: var(--space-xs) var(--space-sm);
  background-color: var(--color-paper-3);
  border: var(--rule-hair) solid var(--color-accent);
  border-radius: var(--radius-sm);
  transform: translateY(-200%);
}
.skip:focus { transform: none; }

/* Outlier slot 1 of 2 — key caps. */
.kbd {
  font-family: var(--font-data);
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1;
  color: var(--color-ink);
  background-color: var(--color-paper-3);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-sm);
  padding: var(--space-2xs);
  min-width: 20px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 150ms !important;
    transition-duration: 150ms !important;
  }
}

/* ============================================================
   Fixed chrome — top bar and status bar
   ============================================================ */

.bar {
  position: fixed;
  inset-inline: 0;
  z-index: var(--z-nav);
  block-size: var(--bar-height);
  background-color: color-mix(in oklch, var(--color-paper) 86%, transparent);
  backdrop-filter: blur(14px) saturate(120%);
}

.bar--top    { inset-block-start: 0; border-block-end: var(--rule-hair) solid var(--color-rule); }
.bar--status {
  inset-block-end: 0;
  border-block-start: var(--rule-hair) solid var(--color-rule);
  block-size: calc(var(--bar-height) + env(safe-area-inset-bottom, 0px));
  padding-block-end: env(safe-area-inset-bottom, 0px);
}

.bar__inner {
  block-size: var(--bar-height);
  max-width: 96rem;
  margin-inline: auto;
  padding-inline: var(--page-gutter);
  display: flex;
  align-items: center;
  gap: var(--space-md);
}

.wordmark {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--text-md);
  letter-spacing: -0.02em;
  white-space: nowrap;
}

.bar__end {
  margin-inline-start: auto;
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.bar__link {
  display: none;                 /* restored at ≥60rem */
  font-size: var(--text-sm);
  color: var(--color-muted);
  white-space: nowrap;
  transition: color var(--dur-micro) var(--ease-out);
}
.bar__link:active { color: var(--color-ink); }

.kbd-btn {
  display: none;                 /* keys are irrelevant without a keyboard */
  align-items: center;
  gap: var(--space-2xs);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-muted);
  background: none;
  border: 0;
  padding: var(--space-2xs);
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--dur-micro) var(--ease-out);
}
.kbd-btn:active { color: var(--color-ink); }
.kbd-btn:disabled { opacity: 0.55; cursor: not-allowed; }

@media (hover: hover) and (pointer: fine) {
  .bar__link:hover { color: var(--color-ink); }
  .kbd-btn:hover:not(:disabled) { color: var(--color-ink); }
  .kbd-btn { display: inline-flex; }
}

@media (min-width: 60rem) {
  .bar__link { display: inline; }
}

/* ---- playlist tabs ---- */

.tabs {
  display: flex;
  align-items: center;
  gap: var(--space-2xs);
  overflow-x: auto;
  scrollbar-width: none;
  min-width: 0;
}
.tabs::-webkit-scrollbar { display: none; }

.tab {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 350;
  white-space: nowrap;
  color: var(--color-muted);
  background: none;
  border: 0;
  border-block-end: var(--rule-thick) solid transparent;
  padding: var(--space-2xs) var(--space-xs);
  min-height: 34px;
  cursor: pointer;
  transition: color var(--dur-micro) var(--ease-out),
              border-color var(--dur-micro) var(--ease-out);
}

.tab__count {
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral);
  margin-inline-start: var(--space-2xs);
}

.tab[aria-selected="true"] {
  color: var(--color-ink);
  font-weight: 500;
  border-block-end-color: var(--color-accent);
}
.tab[aria-selected="true"] .tab__count { color: var(--color-accent); }
.tab:active { color: var(--color-ink); }
.tab:disabled { opacity: 0.55; cursor: not-allowed; }

@media (hover: hover) and (pointer: fine) {
  .tab:hover:not(:disabled) { color: var(--color-ink); }
}
@media (pointer: coarse) { .tab { min-height: 44px; } }

/* ---- status bar ---- */

.status__main {
  font-size: var(--text-sm);
  color: var(--color-muted);
  font-variant-numeric: tabular-nums;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.status__hint {
  display: none;                 /* pointer-only devices get no key hints */
  margin-inline-start: auto;
  align-items: center;
  gap: var(--space-2xs);
  font-size: var(--text-sm);
  color: var(--color-neutral);
  white-space: nowrap;
}

@media (hover: hover) and (pointer: fine) and (min-width: 52rem) {
  .status__hint { display: flex; }
}

/* ============================================================
   Command row
   ============================================================ */

.cmd {
  max-width: 96rem;
  margin-inline: auto;
  padding: var(--space-md) var(--page-gutter) var(--space-sm);
  display: grid;
  gap: var(--space-sm);
}

.cmd__inner { display: grid; gap: var(--space-sm); }

.cmd__search {
  position: relative;
  display: flex;
  align-items: center;
}

/* Body face, not mono: the outlier is capped at two slots (.kbd and .col-rank),
   and a solidus does not need a monospace face to read as one. */
.cmd__slash {
  position: absolute;
  inset-inline-start: var(--space-sm);
  font-size: var(--text-base);
  color: var(--color-neutral);
  pointer-events: none;
}

.input {
  width: 100%;
  min-height: 44px;
  font-family: var(--font-body);
  font-size: var(--text-base);
  font-weight: 350;
  color: var(--color-ink);
  background-color: var(--color-paper-2);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-md);
  padding: var(--space-xs) var(--space-xl) var(--space-xs) var(--space-xl);
  outline: var(--rule-thick) solid transparent;  /* reserved: focus never shifts geometry */
  transition: border-color var(--dur-micro) var(--ease-out);
}

.input::placeholder { color: var(--color-muted); }
.input:disabled { opacity: 0.55; cursor: not-allowed; }
.input:active { border-color: var(--color-neutral); }

@media (hover: hover) and (pointer: fine) {
  .input:hover:not(:disabled) { border-color: var(--color-neutral); }
}

.cmd__clear {
  position: absolute;
  inset-inline-end: var(--space-xs);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  color: var(--color-accent);
  background: none;
  border: 0;
  padding: var(--space-2xs) var(--space-xs);
  min-height: 34px;
  cursor: pointer;
  white-space: nowrap;
}
.cmd__clear[hidden] { display: none; }
.cmd__clear:active { color: var(--color-ink); }
.cmd__clear:disabled { opacity: 0.55; cursor: not-allowed; }

@media (hover: hover) and (pointer: fine) {
  .cmd__clear:hover:not(:disabled) { text-decoration: underline; text-underline-offset: 3px; }
}

.cmd__filters {
  display: grid;
  gap: var(--space-xs);
}

.seg {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
}

.chip {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 350;
  white-space: nowrap;
  color: var(--color-muted);
  background-color: transparent;
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-pill);
  padding: var(--space-2xs) var(--space-sm);
  min-height: 34px;
  cursor: pointer;
  transition: color var(--dur-micro) var(--ease-out),
              border-color var(--dur-micro) var(--ease-out),
              background-color var(--dur-micro) var(--ease-out);
}

.chip__count {
  font-variant-numeric: tabular-nums;
  color: var(--color-muted);
  margin-inline-start: var(--space-2xs);
}

.chip[aria-pressed="true"] {
  color: var(--color-ink);
  border-color: var(--color-accent);
  background-color: var(--color-paper-3);
}
.chip:active { background-color: var(--color-paper-3); }
.chip:disabled { opacity: 0.55; cursor: not-allowed; }

@media (hover: hover) and (pointer: fine) {
  .chip:hover:not(:disabled) { color: var(--color-ink); border-color: var(--color-neutral); }
}
@media (pointer: coarse) { .chip { min-height: 44px; } }

.cmd__about {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-xs);
  font-size: var(--text-sm);
  color: var(--color-muted);
  max-width: 74ch;
}

.cmd__rule-label {
  color: var(--color-accent);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

@media (min-width: 60rem) {
  .cmd__inner { grid-template-columns: minmax(0, 26rem) minmax(0, 1fr); align-items: start; }
  .cmd__filters { grid-template-columns: minmax(0, 1fr); }
}

/* ============================================================
   The grid — a real table, collapsing to cards below 52rem
   ============================================================ */

.console {
  max-width: 96rem;
  margin-inline: auto;
  padding-inline: var(--page-gutter);
  padding-block-end: var(--space-2xl);
}

.grid {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.grid thead { display: none; }     /* card mode by default; restored at ≥52rem */

.grid th {
  text-align: start;
  font-weight: 400;
  color: var(--color-muted);
  padding: var(--space-xs) var(--space-sm);
  border-block-end: var(--rule-hair) solid var(--color-rule);
  white-space: nowrap;
}

.grid th button {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 400;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  white-space: nowrap;
  transition: color var(--dur-micro) var(--ease-out);
}

.grid th button::after {
  content: "";
  margin-inline-start: var(--space-2xs);
  color: var(--color-accent);
}
.grid th[aria-sort="ascending"]  button::after { content: "↑"; }
.grid th[aria-sort="descending"] button::after { content: "↓"; }
.grid th[aria-sort="ascending"]  button,
.grid th[aria-sort="descending"] button { color: var(--color-ink); }
.grid th button:active { color: var(--color-ink); }

@media (hover: hover) and (pointer: fine) {
  .grid th button:hover { color: var(--color-ink); }
}

/* ---- rows ---- */

.row {
  border-block-end: var(--rule-hair) solid var(--color-rule-soft);
  /* the one motion primitive — a colour shift, not a transform */
  transition: background-color var(--dur-micro) var(--ease-out);
}

.row.is-active { background-color: var(--color-paper-2); }
.row:focus-visible { outline-offset: -2px; }

@media (hover: hover) and (pointer: fine) {
  .row:hover { background-color: var(--color-paper-2); }
}

.grid td {
  padding: var(--space-xs) var(--space-sm);
  vertical-align: baseline;
  min-width: 0;
}

/* Outlier slot 2 of 2 — the ordinal spine. */
.col-rank {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  color: var(--color-neutral);
  width: 4rem;
}

/* The note is disclosed by a real button, not a click handler on the row —
   that is what makes aria-expanded meaningful and keeps it usable by touch. */
.disclose {
  font-family: var(--font-data);
  font-variant-numeric: tabular-nums;
  font-size: var(--text-sm);
  color: var(--color-neutral);
  background: none;
  border: 0;
  padding: var(--space-2xs);
  margin-inline-start: calc(var(--space-2xs) * -1);
  min-height: 34px;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs);
  cursor: pointer;
  transition: color var(--dur-micro) var(--ease-out);
}

.disclose__mark { color: var(--color-accent); line-height: 1; }
.disclose:active { color: var(--color-ink); }
.disclose:disabled { opacity: 0.55; cursor: not-allowed; }
.disclose[aria-expanded="true"] { color: var(--color-ink); }

@media (hover: hover) and (pointer: fine) {
  .disclose:hover:not(:disabled) { color: var(--color-ink); }
}
@media (pointer: coarse) { .disclose { min-height: 44px; } }

.col-title  { color: var(--color-ink); font-size: var(--text-base); font-weight: 500; }
.col-artist { color: var(--color-ink); }
.col-album  { color: var(--color-muted); }
.col-year   { color: var(--color-muted); font-variant-numeric: tabular-nums; width: 5rem; }
.col-genre  { color: var(--color-muted); white-space: nowrap; }
.col-open   { width: 1%; white-space: nowrap; }

.col-title, .col-artist, .col-album { overflow-wrap: anywhere; }

/* Never wraps in table mode — three stacked buttons turn a 44px row into a
   125px row and destroy the density this layout exists for. */
.links { display: flex; flex-wrap: nowrap; align-items: center; gap: var(--space-2xs); }

.link__short { display: inline; }
.link__long  { display: none; }

.link {
  font-size: var(--text-sm);
  white-space: nowrap;                 /* clickable text never wraps */
  color: var(--color-muted);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-sm);
  padding: var(--space-2xs) var(--space-xs);
  min-height: 34px;
  display: inline-flex;
  align-items: center;
  line-height: 1;
  transition: color var(--dur-micro) var(--ease-out),
              border-color var(--dur-micro) var(--ease-out);
}
.link:active { border-color: var(--color-accent); }

@media (hover: hover) and (pointer: fine) {
  .link:hover { color: var(--color-ink); border-color: var(--color-accent); }
}
@media (pointer: coarse) { .link { min-height: 44px; } }

/* ---- the note row ---- */

.note-row > td {
  padding-block: 0 var(--space-md);
  padding-inline: var(--space-sm);
  color: var(--color-muted);
}

.note-row[hidden] { display: none; }

.note {
  max-width: 74ch;
  border-inline-start: var(--rule-thick) solid var(--color-accent-dim);
  padding-inline-start: var(--space-sm);
  line-height: 1.55;
}

/* ---- desktop table mode ---- */

@media (min-width: 52rem) {
  .grid thead { display: table-header-group; }
  .grid { font-size: var(--text-sm); }
  .col-album  { max-width: 16rem; }
}

@media (max-width: 51.999rem) {
  /* Card mode. A seven-column grid is not a mobile layout.
     Block flow rather than grid, so album/year/genre sit on ONE line as inline
     text instead of becoming three separate grid rows. */
  .grid, .grid tbody, .grid tr, .grid td { display: block; width: 100%; }

  .row {
    position: relative;
    padding: var(--space-sm) 0 var(--space-sm) 3.25rem;
  }

  .grid td { padding: 0; }

  /* Selectors are qualified with .grid because the blanket `.grid td` rule
     above out-specifies a bare class — without this the meta cells stay
     display:block and each takes its own line. */
  .grid td.col-rank {
    position: absolute;
    inset-block-start: var(--space-sm);
    inset-inline-start: 0;
    width: auto;
  }

  .grid td.col-album,
  .grid td.col-year,
  .grid td.col-genre {
    display: inline;
    width: auto;
    font-size: var(--text-sm);
    color: var(--color-neutral);
  }
  .grid td.col-album::after,
  .grid td.col-year::after { content: " · "; white-space: pre; }

  .grid td.col-open { padding-block-start: var(--space-xs); }

  .note-row { padding-inline-start: 3.25rem; }
  .note-row > td { padding-inline: 0; }

  /* Card mode has the room, so use the real platform names. */
  .links { flex-wrap: wrap; }
  .link__short { display: none; }
  .link__long  { display: inline; }

  /* Filter strips scroll sideways instead of wrapping into ten rows — on a
     375px screen the wrapped version consumed ~40 % of the viewport before a
     single song was visible. The strip scrolls; the page never does. */
  .seg {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding-block-end: var(--space-2xs);
    -webkit-overflow-scrolling: touch;
  }
  .seg::-webkit-scrollbar { display: none; }
  .chip { flex: 0 0 auto; }
}

/* ---- empty state — never a blank data area ---- */

.empty {
  padding-block: var(--space-2xl);
  display: grid;
  gap: var(--space-sm);
  justify-items: start;
}
.empty[hidden] { display: none; }

.empty__head {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: var(--text-lg);
  overflow-wrap: anywhere;
  min-width: 0;
}

.empty__body {
  max-width: 60ch;
  color: var(--color-muted);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
}

/* ============================================================
   Prose below the tool
   ============================================================ */

.prose {
  max-width: 96rem;
  margin-inline: auto;
  padding: var(--space-2xl) var(--page-gutter);
  border-block-start: var(--rule-hair) solid var(--color-rule);
  display: grid;
  gap: var(--space-sm);
}

.prose__head { font-size: var(--text-lg); }
.prose p { max-width: 68ch; color: var(--color-muted); }
.prose strong { color: var(--color-ink); font-weight: 500; }

.prose__links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
  padding-block-start: var(--space-xs);
}

.btn {
  font-family: var(--font-body);
  font-size: var(--text-sm);
  white-space: nowrap;
  color: var(--color-ink);
  background-color: transparent;
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-sm);
  padding: var(--space-2xs) var(--space-sm);
  min-height: 34px;
  display: inline-flex;
  align-items: center;
  line-height: 1;
  cursor: pointer;
  transition: border-color var(--dur-micro) var(--ease-out),
              background-color var(--dur-micro) var(--ease-out);
}
.btn:active { background-color: var(--color-paper-3); }
.btn:disabled { opacity: 0.55; cursor: not-allowed; }

@media (hover: hover) and (pointer: fine) {
  .btn:hover:not(:disabled) { border-color: var(--color-accent); }
}
@media (pointer: coarse) { .btn { min-height: 44px; } }

/* ============================================================
   Keyboard help dialog
   ============================================================ */

.help {
  margin: auto;
  max-width: 34rem;
  width: calc(100% - var(--space-lg));
  color: var(--color-ink);
  background-color: var(--color-paper-2);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-md);
  padding: 0;
}

.help::backdrop { background-color: color-mix(in oklch, var(--color-paper) 72%, transparent); }

.help__inner { padding: var(--space-lg); display: grid; gap: var(--space-md); }
.help__title { font-size: var(--text-lg); }

.help__list { display: grid; gap: var(--space-xs); margin: 0; }
.help__list > div {
  display: grid;
  grid-template-columns: 6rem minmax(0, 1fr);
  gap: var(--space-sm);
  align-items: center;
}
.help__list dt { display: flex; gap: var(--space-2xs); }
.help__list dd { margin: 0; color: var(--color-muted); font-size: var(--text-sm); }

.help__note {
  color: var(--color-muted);
  font-size: var(--text-sm);
  max-width: 56ch;
  border-block-start: var(--rule-hair) solid var(--color-rule);
  padding-block-start: var(--space-sm);
}
