/* =====================================================================
   Genres — index + detail.

   The INDEX is a ranked ledger, the same grammar as the homepage lineage band
   and the writers index: rows on paper, separated by rules, not cards. It is
   deliberately NOT the writers index component (see page_styles/writers.css on
   why those two are not unified) — this side ranks by weight in the graph and
   names a genre's debts to other genres, which the literature side has no
   equivalent of.

   Rows are ordered by connections, not followers, and that ordering is
   load-bearing: the rank number is printed, so an unordered list would be
   claiming a ranking it doesn't have.

   The DETAIL page follows the same grammar: a roster of rows on paper instead
   of the old rounded photo cards, ranked by the same degree figure, with the
   chip bar flattened to plain links so it reads as wayfinding rather than
   another row of buttons.

   Tokens only — no hardcoded colors/spacing/fonts.
   ===================================================================== */

/* ---------- Index: header ---------- */

.genre-index {
  max-width: 72rem;
  margin: 0 auto;
  /* Was --space-3xl (4rem) to clear a two-row ~8.5rem header that stacked a
     centered title over the nav. That header is GONE: .header-top is one slim
     fixed 4rem row (see base_styles/header.css), which fits inside the locked
     4.5rem .main-content clearance, so the compensator was buying nothing but
     empty paper above the <h1>. --space-xl matches every other page container.
     Still do NOT touch the locked .main-content padding. */
  padding: var(--space-xl) var(--space-lg) var(--space-xl);
}

.genre-index-header {
  margin-bottom: var(--space-lg);
}

.genre-index-kicker {
  font-family: var(--font-ui);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps-wide);
  color: var(--color-accent);
  margin: 0 0 var(--space-xs);
}

.genre-index-title {
  font-family: var(--font-heading);
  font-size: var(--font-size-page-title);
  color: var(--color-heading-text);
  margin: 0 0 var(--space-xs);
  line-height: var(--line-height-tight);
  letter-spacing: var(--tracking-display);
}

.genre-index-intro {
  font-size: var(--font-size-base);
  color: var(--color-subtle-text);
  margin: 0;
  max-width: 42rem;
}

/* The shared .section-bar carries a 3.5rem top margin tuned for stacking
   sections down the homepage. Here it follows the page header, so it needs
   less air above it. Same adjustment the writers index makes. */
.genre-index .section-bar {
  margin-top: var(--space-xl);
}

/* ---------- Index: the ledger ---------- */

.genre-ledger {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--color-divider);
}

/* Three tracks, so the figures and the two lists line up down the whole ledger
   rather than re-flowing per row. The identity column is fixed-width because a
   ragged left edge would break the rank numbers' vertical read.

   The middle track is `auto`, not `1fr`: six names wrap to two lines well
   before they fill a proportional third of a 72rem row, and a `1fr` track
   holds that full width open, leaving a visible gutter of dead paper on the
   right of every row. `auto` lets the names take what they need and hands the
   slack to the draws-from column, which right-aligns its counts and so reads
   better wide than narrow. */
.gl-row {
  display: grid;
  grid-template-columns: minmax(0, 14rem) minmax(0, auto) minmax(9rem, 15rem);
  gap: var(--space-md) var(--space-xl);
  align-items: start;
  padding: var(--space-lg) 0;
  border-bottom: 1px solid var(--color-divider);
}

.gl-id {
  grid-column: 1;
}

.gl-rank {
  font-family: var(--font-ui);
  font-size: var(--font-size-xs);
  letter-spacing: var(--tracking-caps);
  color: var(--color-light-gray);
  margin: 0 0 var(--space-xxs);
}

.gl-name {
  font-family: var(--font-heading);
  font-size: var(--font-size-2xl);
  font-weight: var(--font-weight-bold-heading);
  line-height: 1.1;
  letter-spacing: var(--tracking-display);
  margin: 0;
}

.gl-name a {
  color: var(--color-heading-text);
  text-decoration: none;
  transition: color var(--transition-fast);
}

.gl-name a:hover,
.gl-row:hover .gl-name a {
  color: var(--color-accent);
}

.gl-figures {
  display: flex;
  gap: var(--space-lg);
  margin: var(--space-sm) 0 0;
}

.gl-figure {
  font-family: var(--font-ui);
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-subtle-text);
  line-height: 1.4;
}

.gl-figure b {
  display: block;
  font-family: var(--font-heading);
  font-size: var(--font-size-xl);
  font-weight: var(--font-weight-bold);
  color: var(--color-accent);
  letter-spacing: 0;
}

/* Overlapping thumbnails. Decorative only — every one of these artists is
   already named as a real link in the column beside it, so the row loses
   nothing when an image 404s (hence the inline onerror in the template). */
.gl-faces {
  display: flex;
  margin: var(--space-sm) 0 0;
}

.gl-face {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-round);
  object-fit: cover;
  background: var(--color-bg-subtle);
  border: 2px solid var(--color-bg);
  margin-right: -0.55rem;
}

.gl-side--cited {
  grid-column: 2;
}

.gl-side--draws {
  grid-column: 3;
}

.gl-side-label {
  font-family: var(--font-ui);
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-subtle-text);
  margin: 0 0 var(--space-xs);
}

/* The most-cited names run as a wrapped sentence rather than a column: six
   short names stacked would out-tall the identity column and open a hole in
   every row. */
.gl-names {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xxs) var(--space-sm);
}

.gl-name-item {
  display: flex;
  align-items: baseline;
  gap: var(--space-xxs);
}

.gl-name-item + .gl-name-item::before {
  content: "·";
  color: var(--color-light-gray);
  margin-right: var(--space-xxs);
}

.gl-name-link {
  font-size: var(--font-size-base);
  color: var(--color-body-text);
  text-decoration: none;
}

.gl-name-link:hover {
  color: var(--color-accent);
  text-decoration: underline;
}

/* The artist's degree in the whole graph, not just this genre — the same
   figure their own page prints. Set quiet: it annotates the name, it isn't a
   second thing to read. */
.gl-degree {
  font-family: var(--font-ui);
  font-size: var(--font-size-xs);
  color: var(--color-light-gray);
}

.gl-draws {
  list-style: none;
  margin: 0;
  padding: 0;
}

.gl-draw {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-xxs) 0;
}

.gl-draw-link {
  font-size: var(--font-size-base);
  color: var(--color-body-text);
  text-decoration: none;
  text-transform: capitalize;
}

.gl-draw-link:hover {
  color: var(--color-accent);
  text-decoration: underline;
}

.gl-draw-count {
  font-family: var(--font-ui);
  font-size: var(--font-size-xs);
  color: var(--color-subtle-text);
  flex: none;
}

/* An empty column is an unfinished corner of the graph, not an error. Same
   treatment as the writers index: a quiet note in the body colour, never
   greyed-out italics, which read as "disabled". */
.gl-none {
  font-size: var(--font-size-sm);
  color: var(--color-subtle-text);
  margin: 0;
}

.genre-index-empty {
  list-style: none;
  color: var(--color-subtle-text);
}

/* ---------- Index: narrow widths ----------
   The three tracks collapse to one. The draws-from column keeps its rule above
   it so the row still reads as two distinct claims once stacked. */

@media (max-width: 60rem) {
  .gl-row {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-md);
  }

  .gl-id,
  .gl-side--cited,
  .gl-side--draws {
    grid-column: 1;
  }

  .gl-side--draws {
    border-top: 1px solid var(--color-divider);
    padding-top: var(--space-md);
  }

  .gl-draws {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs) var(--space-lg);
  }

  .gl-draw {
    gap: var(--space-xxs);
    padding: 0;
  }
}

@media (max-width: 36rem) {
  .gl-name {
    font-size: var(--font-size-xl);
  }
}

/* =====================================================================
   Detail page
   ===================================================================== */

.genre-detail {
  max-width: 72rem;
  margin: 0 auto;
  /* See .genre-index: the 4rem two-row-header compensator is gone, --space-xl
     is the site-wide opening inset. */
  padding: var(--space-xl) var(--space-lg) var(--space-xl);
}

.genre-detail-header {
  margin-bottom: var(--space-lg);
}

/* Breadcrumb back to the index. Lives inside the already-cleared header — does
   not affect the page's top spacing. */
.genre-breadcrumb {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  margin-bottom: var(--space-sm);
  font-size: var(--font-size-sm);
}

.genre-breadcrumb-link {
  color: var(--color-accent);
  font-weight: var(--font-weight-medium);
  text-decoration: none;
}

.genre-breadcrumb-link:hover {
  text-decoration: underline;
}

.genre-breadcrumb-sep {
  color: var(--color-subtle-text);
}

.genre-breadcrumb-current {
  color: var(--color-subtle-text);
  text-transform: capitalize;
}

.genre-detail-title {
  font-family: var(--font-heading);
  font-size: var(--font-size-page-title);
  color: var(--color-heading-text);
  margin: 0 0 var(--space-sm);
  text-transform: capitalize;
  line-height: var(--line-height-tight);
  letter-spacing: var(--tracking-display);
}

/* The same two figures the ledger index prints for this genre, in the same
   treatment — the index row and the page it opens should agree at a glance.
   Reuses .gl-figure rather than restyling: one definition, two pages. */
.genre-detail-figures {
  display: flex;
  gap: var(--space-lg);
  margin: 0;
}

/* ---------- Sticky filter-chip bar ---------- */

.genre-chip-bar {
  position: sticky;
  top: 4.5rem; /* header clearance (locked, see layout.css) */
  z-index: 5;
  display: flex;
  gap: var(--space-sm);
  overflow-x: auto;
  padding: var(--space-sm) 0;
  margin-top: var(--space-xl);
  background: var(--color-bg);
  border-top: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
  scrollbar-width: none; /* Firefox */
}

.genre-chip-bar::-webkit-scrollbar {
  display: none;
}

/* Chips are wayfinding, not content: flat text with a hairline, so they don't
   compete with the roster names underneath. The pill shape and card background
   went with the old card-based page. */
.genre-chip {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-xs);
  padding: var(--space-xxs) 0;
  color: var(--color-body-text);
  font-family: var(--font-ui);
  font-size: var(--font-size-sm);
  text-decoration: none;
  white-space: nowrap;
  border-bottom: 1px solid transparent;
  transition: color var(--transition-fast), border-color var(--transition-fast);
}

.genre-chip + .genre-chip {
  margin-left: var(--space-md);
}

.genre-chip:hover {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
}

.genre-chip-count {
  font-size: var(--font-size-xs);
  color: var(--color-subtle-text);
}

/* ---------- Sections ---------- */

.genre-section {
  scroll-margin-top: 9rem; /* clear fixed header + sticky chip bar on anchor jump */
}

/* The shared .section-bar's 3.5rem top margin is tuned for stacking sections
   down the homepage; here the first one follows the sticky chip bar. */
.genre-section:first-of-type .section-bar {
  margin-top: var(--space-xl);
}

/* ---------- The roster ----------
   Rows on paper, not cards: same grammar as the index ledger. Auto-fill rather
   than a fixed column count so a 2-artist section doesn't leave four empty
   cells, and the row height is set by the face so names of any length align. */

.genre-roster {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 0 var(--space-xl);
}

.gr-item {
  border-bottom: 1px solid var(--color-divider);
}

.gr-link {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-sm) 0;
  text-decoration: none;
  min-width: 0;
}

.gr-face {
  width: 3rem;
  height: 3rem;
  flex: none;
  object-fit: cover;
  border-radius: var(--radius-round);
  background: var(--color-bg-subtle);
}

.gr-face--empty {
  display: block;
  border: 1px solid var(--color-divider);
}

.gr-body {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.gr-name {
  font-family: var(--font-heading);
  font-size: var(--font-size-base-plus);
  font-weight: var(--font-weight-bold-heading);
  line-height: var(--line-height-tight);
  color: var(--color-heading-text);
  transition: color var(--transition-fast);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

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

.gr-degree {
  font-family: var(--font-ui);
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-subtle-text);
}

/* ---------- CSS-only "show all" ----------
   Every artist stays in the DOM in both states — this list is the page's
   crawlable content. A max-height clamp, not an nth-child cutoff: the grid
   re-flows by width, so a row count would clamp to a different height at every
   breakpoint. Same mechanism as .ledger-rows--clamped on the artist page.

   The label is restyled here rather than reused from artist_detail.css: that
   file is only loaded on the artist page, so borrowing its rules would leave
   this label unstyled. The checkbox itself is `.sr-only`, which IS global
   (global_styles.css). */

.genre-roster--clamped {
  max-height: 21rem;
  overflow: hidden;
  mask-image: linear-gradient(to bottom, #000 74%, transparent 100%);
  -webkit-mask-image: linear-gradient(to bottom, #000 74%, transparent 100%);
}

.genre-more-toggle:checked ~ .genre-roster--clamped {
  max-height: none;
  overflow: visible;
  mask-image: none;
  -webkit-mask-image: none;
}

.genre-more-label {
  display: inline-flex;
  align-items: center;
  min-height: 44px; /* comfortable thumb target */
  margin-top: var(--space-xs);
  font-family: var(--font-ui);
  font-size: var(--font-size-xs);
  font-weight: var(--font-weight-semibold);
  text-transform: uppercase;
  letter-spacing: var(--tracking-caps);
  color: var(--color-accent);
  cursor: pointer;
}

.genre-more-label:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.genre-more-label .genre-more-hide,
.genre-more-toggle:checked ~ .genre-more-label .genre-more-show {
  display: none;
}

.genre-more-toggle:checked ~ .genre-more-label .genre-more-hide {
  display: inline;
}

/* The checkbox is sr-only, so its keyboard-focus ring moves to the label. */
.genre-more-toggle:focus-visible ~ .genre-more-label {
  outline: var(--focus-ring-width) solid var(--color-accent);
  outline-offset: var(--focus-ring-offset);
  border-radius: var(--radius-sm);
}

.genre-detail-empty {
  color: var(--color-subtle-text);
}

@media (max-width: 36rem) { /* --bp-phone-sm */
  .genre-roster {
    grid-template-columns: minmax(0, 1fr);
  }

  .genre-detail-title {
    font-size: var(--font-size-heading);
  }

  .genre-roster--clamped {
    max-height: 24rem;
  }
}
