/* dashboard.css — page layer (owner: S2).
   Loaded after studio.css by base.html.  Tokens only: no colour or length
   literals outside design-tokens.css.

   S2 owns the Home surface and the ranked-list language: the bento totals, the
   one-row period control, the compact now-playing strip, and the ranked rows
   every list on Library / Discover shares.  studio.css supplies the component
   (`.bento`, `.stat-tile`, `.ranked-*`, `.period-selector`); this file only
   arranges them for this page, so nothing here restates a component. */

/* ── The bento: hero + four tiles ────────────────────────────────────── */

/* `.stats-bar.bento` is one grid.  On a phone the hero owns the first row and
   the four tiles are a 2x2 grid under it; from 768px the tiles join the parent
   grid (display: contents) so studio.css's `span 2` hero sits beside the first
   tile and the other three fill the second row — a bento, never five rows. */
.stats-bar.bento {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-xs);
}

.bento .bento-grid {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-xs);
}

.bento .bento-hero {
  min-inline-size: 0;
}

.bento .stat-tile-icon {
  align-self: flex-start;
}

.bento .stat-tile-icon-hero {
  inline-size: var(--space-2xl);
  block-size: var(--space-2xl);
  border-radius: var(--radius-lg);
}

.bento .stat-tile-value {
  font-variant-numeric: tabular-nums;
}

.bento .stat-tile-foot {
  margin-block-start: var(--space-3xs);
}

/* The hero is the one number the eye lands on: display scale, tabular digits. */
.bento .bento-hero .stat-tile-value {
  line-height: 1;
}

@media (min-width: 768px) {
  /* Desktop: the hero owns the full width and the four tiles fill one row —
     four columns, so the grid ends flush with the card edge instead of leaving
     an orphan cell. */
  .bento .bento-hero {
    grid-column: 1 / -1;
  }

  .bento .bento-grid {
    display: contents;
    grid-template-columns: none;
  }

  .bento .bento-grid > .stat-tile {
    grid-column: auto;
  }

  .stats-bar.bento {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* ── Period control: label and pills on one row ──────────────────────── */

.period-bar {
  margin-block-end: var(--space-md);
}

.period-bar .period-btn {
  min-inline-size: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Ranked rows ─────────────────────────────────────────────────────── */

/* The row is: rank · avatar · (name, subtitle, bar) · metrics.  The bar lives
   *inside* the name column, so it can never run past the card's right edge, and
   the metrics keep their own column so a long number is never clipped. */
.ranked-item {
  align-items: center;
}

.ranked-item .ranked-avatar {
  inline-size: var(--space-xl);
  block-size: var(--space-xl);
  font-size: var(--font-size-2xs);
}

/* Track avatars borrow the square-ish shape of a record sleeve. */
.ranked-avatar-track {
  border-radius: var(--radius-md);
}

.ranked-item .ranked-info {
  gap: var(--space-3xs);
}

.ranked-item .ranked-name {
  color: var(--color-text);
  text-decoration: none;
}

.ranked-item .ranked-name:hover {
  color: var(--color-accent);
}

.ranked-item .ranked-bar-track {
  margin-block-start: var(--space-3xs);
}

/* Artists carry full-width embedded background progress bars across the entire row
   (C-6: the number on the bar equals the number in the label). */
[data-ranked-list="artists"] .ranked-item {
  position: relative;
  overflow: hidden;
  z-index: 0;
}

[data-ranked-list="artists"] .ranked-bar-track {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  margin: 0;
  background: transparent;
  pointer-events: none;
  z-index: 0;
  border-radius: var(--radius-lg);
  overflow: hidden;
}

[data-ranked-list="artists"] .ranked-bar {
  position: absolute;
  inset-block: 0;
  inset-inline-start: 0;
  block-size: 100%;
  background: color-mix(in srgb, var(--color-accent) 15%, transparent);
  border-inline-end: 2px solid var(--color-accent);
  transition: width var(--transition);
  z-index: 0;
}

[data-ranked-list="artists"] .ranked-bar-count {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
}

[data-ranked-list="artists"] .rank-number,
[data-ranked-list="artists"] .ranked-avatar,
[data-ranked-list="artists"] .ranked-info,
[data-ranked-list="artists"] .ranked-metrics {
  position: relative;
  z-index: 1;
}

.ranked-item .ranked-metrics {
  flex-direction: column;
  align-items: flex-end;
  gap: 0;
  line-height: var(--line-height-tight);
}

.ranked-item .ranked-hours::before {
  content: none;
  margin: 0;
}

.ranked-item .ranked-hours {
  color: var(--color-text-muted);
}

/* The shared dual-action row stays on the track row it acts on, as one
   horizontally scrollable strip: it never pushes the name/metrics column and it
   can never be clipped at the card's edge. */
.ranked-item .ui-track-actions {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--space-3xs);
  margin-block-start: var(--space-2xs);
  max-inline-size: 100%;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.ranked-item .ui-track-actions::-webkit-scrollbar {
  display: none;
}

.ranked-item .ui-track-actions .ui-btn {
  flex: 0 0 auto;
  padding-inline: var(--space-xs);
  font-size: var(--font-size-2xs);
  white-space: nowrap;
}

/* ── Now playing: a compact hero strip ───────────────────────────────── */

.dashboard-now-playing {
  margin-block-end: var(--space-md);
}

.now-playing-strip {
  gap: var(--space-sm);
  padding: var(--space-md);
}

.now-playing-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
}

.now-playing-head .now-playing-heading {
  letter-spacing: 0.12em;
}

/* The equaliser: four bars, a two-second loop, off under reduced motion. */
.now-playing-eq {
  display: inline-flex;
  align-items: flex-end;
  gap: var(--space-3xs);
  block-size: var(--space-sm);
}

.now-playing-eq span {
  inline-size: var(--space-3xs);
  block-size: 40%;
  border-radius: var(--radius-full);
  background: var(--color-accent);
  animation: now-playing-eq 1.4s ease-in-out infinite alternate;
}

.now-playing-eq span:nth-child(2) {
  animation-delay: 0.2s;
}
.now-playing-eq span:nth-child(3) {
  animation-delay: 0.45s;
}
.now-playing-eq span:nth-child(4) {
  animation-delay: 0.1s;
}

@keyframes now-playing-eq {
  from {
    block-size: 25%;
  }
  to {
    block-size: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .now-playing-eq span {
    animation: none;
    block-size: 60%;
  }
}

.now-playing-hero {
  align-items: center;
  min-inline-size: 0;
}

.now-playing-strip .now-playing-art {
  inline-size: 72px;
  block-size: 72px;
  border-radius: var(--radius-lg);
}

.now-playing-art--none {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-muted);
}

.now-playing-meta {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  min-inline-size: 0;
}

.now-playing-name,
.now-playing-title {
  font-size: var(--font-size-md);
  font-weight: var(--font-weight-semibold);
  letter-spacing: -0.02em;
  line-height: var(--line-height-tight);
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
}

.now-playing-device {
  font-size: var(--font-size-2xs);
}

.now-playing-progress {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-xs);
}

.now-playing-clock {
  font-size: var(--font-size-2xs);
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
}

.now-playing-bar {
  inline-size: 100%;
  block-size: var(--space-2xs);
  border: 0;
  border-radius: var(--radius-full);
  overflow: hidden;
  appearance: none;
  background: var(--meter-track);
}

.now-playing-bar::-webkit-progress-bar {
  background: var(--meter-track);
  border-radius: var(--radius-full);
}

.now-playing-bar::-webkit-progress-value {
  background: var(--accent-gradient);
  border-radius: var(--radius-full);
}

.now-playing-bar::-moz-progress-bar {
  background: var(--accent-gradient);
  border-radius: var(--radius-full);
}

.now-playing-transport {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2xs);
}

.now-playing-control {
  margin: 0;
}

.now-playing-more {
  margin: 0;
}

.now-playing-more > summary {
  inline-size: auto;
  padding-inline: var(--space-sm);
  font-size: var(--font-size-2xs);
  color: var(--color-text-secondary);
  cursor: pointer;
  list-style: none;
}

.now-playing-more > summary::-webkit-details-marker {
  display: none;
}

.now-playing-more-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin-block-start: var(--space-xs);
}

.now-playing-more-body form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2xs);
  margin: 0;
}

.now-playing-verdict {
  font-size: var(--font-size-2xs);
  color: var(--color-text-secondary);
}

/* The strip's own states are one compact block, not a page section: a title, a
   line of human text, and the engine's explanation behind a disclosure. */
.now-playing-strip .ui-surface-state {
  padding: 0;
  gap: var(--space-3xs);
}

.now-playing-strip .ui-surface-state-title {
  font-size: var(--font-size-sm);
}

.now-playing-strip .ui-surface-state-message {
  font-size: var(--font-size-2xs);
  line-height: var(--line-height-normal);
}

.now-playing-why {
  font-size: var(--font-size-2xs);
  color: var(--color-text-muted);
}

.now-playing-why > summary {
  cursor: pointer;
  min-block-size: var(--space-lg);
  display: flex;
  align-items: center;
}

.now-playing-why > p {
  margin: var(--space-3xs) 0 0;
  line-height: var(--line-height-normal);
}

.now-playing-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2xs);
}

.now-playing-card-link {
  display: flex;
  flex-direction: column;
  gap: var(--space-3xs);
  min-block-size: var(--tap-min);
  padding: var(--space-xs);
  border: var(--hairline) solid var(--glass-border);
  border-radius: var(--radius-md);
  background: var(--glass-bg);
  text-decoration: none;
  transition: border-color var(--transition), background var(--transition);
}

.now-playing-card-link:hover {
  border-color: color-mix(in srgb, var(--color-accent) 30%, var(--glass-border));
  background: var(--surface-tint);
}

.now-playing-card-title {
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  color: var(--color-text);
}

.now-playing-card-sub {
  font-size: var(--font-size-2xs);
  line-height: var(--line-height-tight);
}

/* ── Streak + enrichment ─────────────────────────────────────────────── */

/* A slot, not a card: partials/_streak.html renders its own .card. */
.dashboard-streak {
  display: block;
}

.enrich-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-block-end: var(--space-sm);
}

.enrich-status {
  display: none;
  padding: var(--space-xs) var(--space-sm);
}

.enrich-status-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
}

.enrich-result-detail {
  margin-block-start: var(--space-2xs);
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}

