/* ── Unholy Land — band page ──────────────────────────────────
   Grid: 10 columns, 20px gutter, 20px page margin.
   Major sections are inset by 60px from their column line.
   ------------------------------------------------------------ */
@font-face { font-family:'Cloister Black';      src:url('../vendor/cloisterblack.woff2') format('woff2'); font-display:swap; }
@font-face { font-family:'UnifrakturMaguntia';  src:url('../vendor/unifraktur.woff2')    format('woff2'); font-display:swap; }
@font-face { font-family:'Metal Mania';         src:url('../vendor/metalmania.woff2')    format('woff2'); font-display:swap; }
@font-face { font-family:'Inter';               src:url('../vendor/inter_3.woff2')       format('woff2'); font-weight:400 700; font-display:swap; }

:root {
  /* the two spacings the layout is built from */
  --gap:      20px;   /* gutter, and everything inside a section */
  --gap-lg:   60px;   /* separation between the major sections */
  --pad:      20px;   /* page margin */
  --cols:     10;
  --nav-h:    62px;
  /* the hero's two end boxes take their height from their column width — see
     .hero-logo/.hero-photo — so there is no fixed height to name here */

  --display-font: 'Cloister Black', 'UnifrakturMaguntia', 'Metal Mania', cursive;
  --nav-font: 'Inter', system-ui, sans-serif;

  --bg:      #030507;
  --bg-90:   #0b0d10e6;   /* the page background at 90% — scrim behind overlays */
  --surface: #090b0e;
  --border:  #262b33;
  --text:    #d8dde5;
  --white:   #f2f4f8;
  --muted:   #8b93a1;
  /* the quietest text on the site, and it still has to be readable: at
     #5f6773 it sat at 3.4:1 on --bg, under the 4.5:1 floor, and it is used at
     10-12.5px — the flyer year spine, the result count, the Legends and
     Flyers rules. 5.0:1 here, still a clear step below --muted's 6.3. */
  --dim:     #7a828f;
  --accent:  #e0453e;
  /* see the note in style.css — interface accent, red until archive-system.css
     repoints it to brass. Keep the two definitions in sync. */
  --ui-accent: var(--accent);
  --ok:      #59b85e;
  /* honors only, never UI chrome — and now the name is honest again. It was
     bone, #cfd9e3, on the argument that a prize is the wrong idea for an
     archive; the call came back the other way, that an honor nobody can pick
     out of the chrome is not an honor. 10.5:1 on this ground against the
     steel's 8.09, so it still outranks the interface around it, and by more
     than the bone did. The sigils carry the same ramp — see badges/*.svg. */
  --gold:     #e3b44a;
  --gold-dim: #a37e2c;

  /* 315 of the 385 Metallum logos are white-on-black JPGs with no alpha —
     mix-blend-mode:screen drops the black box out against the page.
     one shared recipe so every logo reads the same: color and gray logos go
     monochrome, contrast crushes jpeg near-black noise, brightness lifts dim
     grays toward the white the majority already have */
  --logo-filter: grayscale(1) contrast(1.45) brightness(1.15);
  --ease: cubic-bezier(.2, .7, .3, 1);
}

* { box-sizing: border-box; }
body {
  margin: 0;
  padding-top: var(--nav-h);
  background: var(--bg);
  color: var(--text);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }

/* ── nav ─────────────────────────────────────────────────── */
/* Centred, like the map's topbar — the name, the search and the four sigils
   are one group and sit on the page's centre line. The X is the exception and
   is taken out of the flow below: it is a way back rather than a member of the
   group, and left in the row its auto margin ate the free space and pushed the
   group off centre by half the X. */
#nav {
  position: fixed; top: 0; left: 0; right: 0; height: var(--nav-h);
  display: flex; align-items: center; justify-content: center; gap: 28px;
  padding: 0 var(--pad);
  background: var(--bg);
  z-index: 2000;
}
#brand {
  font-family: var(--display-font);
  font-size: 30px; line-height: 1;
  color: var(--white);
  letter-spacing: .5px;
  white-space: nowrap;
}
#brand span { color: var(--accent); }
#navlinks { display: flex; align-items: center; gap: 24px; }
#navlinks a, #navlinks button {
  font-family: var(--nav-font);
  font-size: 16px; font-weight: 600;
  color: var(--white);
  background: none; border: 0; padding: 0; cursor: pointer;
  white-space: nowrap;
}
#navlinks a:hover, #navlinks button:hover { color: var(--ui-accent); }
.nav-honors { display: inline-flex; align-items: center; gap: 6px; color: var(--gold) !important; }
.nav-honors:hover { color: var(--ui-accent) !important; }
.nav-honors img { height: 17px; width: auto; }

/* the search sits first in the nav, where the "Search" link used to be */
#searchbox { position: relative; width: 250px; }
#search {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  padding: 8px 10px;
  outline: none;
  transition: border-color .2s;
}
#search::placeholder { color: var(--dim); }
#search:focus { border-color: #3a424e; }

#search-results {
  position: absolute; top: calc(100% + 6px); left: 0;
  width: 320px;
  max-height: 60vh; overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding-bottom: 4px;
  box-shadow: 0 12px 28px #000000a6;
}
.sr-head {
  padding: 8px 10px 4px;
  color: var(--dim); font-size: 10px;
  letter-spacing: .12em; text-transform: uppercase;
}
.sr-row {
  padding: 6px 10px; cursor: pointer;
  display: flex; align-items: baseline; gap: 8px;
}
.sr-row:hover { background: #1a1f26; }
.sr-name { color: var(--white); font-size: 13px; }
.sr-sub {
  color: var(--dim); font-size: 11px;
  margin-left: auto; padding-left: 10px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  max-width: 45%;
}
.sr-row .rb-dot { align-self: center; }
/* musicians get a hollow neutral dot — a filled one always means a genre */
.person-dot { background: transparent; box-shadow: inset 0 0 0 1px var(--muted) !important; }
.sr-none { padding: 10px; color: var(--dim); font-size: 12px; }

#nav-close {
  position: absolute;
  right: var(--pad);
  font-family: var(--nav-font);
  font-size: 19px; font-weight: 700;
  color: var(--accent);
  padding: 0 2px;
}
#nav-close:hover { color: var(--white); }

/* ── grid ────────────────────────────────────────────────── */
.grid {
  display: grid;
  grid-template-columns: repeat(var(--cols), 1fr);
  gap: var(--gap);
  padding: 0 var(--pad);
}

h2 {
  margin: 0 0 var(--gap);
  font-family: var(--display-font);
  font-size: 30px; font-weight: 400; line-height: 1;
  color: var(--ui-accent);
  letter-spacing: .5px;
}

/* ── hero ────────────────────────────────────────────────── */
/* Logo and photograph are the two ends of the hero, the same size, one at each
   page edge; the name, the facts and the player stack up the middle.
   The Bandcamp embed used to hold three of these ten columns on its own, and
   sat empty on the 174 bands (44%) with no Bandcamp — while 85% have a
   photograph. It rides under the facts now, and both end boxes are three
   columns instead of two. */
.hero { padding-top: var(--gap); align-items: start; }
.hero-logo   { grid-column: 1 / 4; }
.hero-mid    { grid-column: 4 / 7; align-self: center;
               padding-left: calc(var(--gap-lg) - var(--gap)); }
/* column 7 is left empty on purpose — the middle stack needs air before the
   photograph, and the facts are short enough that filling it would only
   stretch them */
.hero-photo  { grid-column: 8 / -1; }

/* Both boxes are 1.4 — sweeping all 337 band photographs against every
   candidate shape, that is where the wasted area bottoms out (a median 13% of
   the box, against 21% and worse either side of it). The height follows the
   column width, so the pair holds that shape at every breakpoint and the two
   ends of the hero always match each other exactly. */
.hero-logo, .hero-photo { aspect-ratio: 1.4; height: auto; }
.hero-logo img {
  display: block; width: 100%; height: 100%;
  object-fit: contain; object-position: center center;
  mix-blend-mode: screen;
  filter: var(--logo-filter);
}
/* no logo in the archive: the name in blackletter takes the box */
.hero-logo { display: flex; align-items: center; justify-content: center; }
.name-logo {
  font-family: var(--display-font);
  font-size: 58px; font-weight: 400; line-height: 1.05;
  color: var(--white);
  letter-spacing: 1px;
  text-align: center;
  overflow-wrap: break-word;
  max-width: 100%;
}
.name-logo.small { font-size: 40px; }

.band-name {
  margin: 0;
  font-family: var(--display-font);
  /* still the largest type on the page, but only a step above the 30px section
     headings rather than towering over them. the honours wreath and its count
     are sized in em, so they follow this down on their own */
  font-size: 34px; font-weight: 400; line-height: 1;
  color: var(--ui-accent);
  letter-spacing: .5px;
}
/* the wreath spans exactly from the heading's baseline to the top of the
   blackletter capital (Cloister Black cap height = .684em), the number sits
   on the same baseline beside it */
.band-honors{
  margin-left: .3em;
  font-family: var(--nav-font);
  font-size: .706em;        /* Inter digit cap (.705em) = the lowercase x-height */
  font-weight: 700;
  color: var(--gold); letter-spacing: 0;
  white-space: nowrap;
}
.band-honors img {
  height: 1.174em; width: auto; /* the capital's full ink height, feet included */
  vertical-align: -0.202em;     /* bottom sinks to the blackletter feet line */
  margin-right: .16em;
}
.band-genre { margin-top: 6px; font-size: 13px; font-weight: 600; }
.band-genre .status { color: var(--ok); font-weight: 400; }
.band-genre .status.dead { color: var(--muted); }

.band-facts {
  /* half the section gutter, not the whole one — the genre line and the facts
     are the same block of information about the band, and a 20px trench under
     the genre broke them into two things that then read as unrelated */
  margin: 10px 0 0;
  display: grid; grid-template-columns: 62px 1fr;
  row-gap: 3px; column-gap: var(--gap);
  font-size: 12px;
}
.band-facts dt { color: var(--muted); }
.band-facts dd { margin: 0; color: var(--text); }

/* height is set from the info block's own height at render time (see band.js);
   160px is only the pre-measurement default */
/* the player sits under the facts in the middle stack. :empty is doing real
   work — 44% of bands have no Bandcamp, and without it they would carry its
   top margin as a hole under the facts */
.hero-player { margin-top: var(--gap); }
.hero-player:empty { display: none; }
/* Bandcamp's own small size: one line, 42px. The large one carried a second
   copy of the cover that the discography already shows, plus a by-line
   repeating the band name at the top of its own page. The cost is that a long
   release title truncates. */
.bc-player { width: 100%; height: 42px; border: 0; display: block; }

/* The box is fixed on every band so the hero row never shifts, but it is not a
   fixed *shape*: two columns over 250px runs 1.18 wide at 1600px and 0.78 at
   1100px, while 65% of the 337 band photos are landscape (median 1.35, p90
   1.78). object-fit:cover had to eat the difference — a median 21% of each
   shot at 1600px and 42% at 1100px, and on a wide group shot it would land on
   empty background and render the box as a black rectangle.
   So nothing is cropped: the photo is contained, and its own blurred, dimmed
   copy fills whatever the shape leaves over. Same box, whole photograph. */
.hero-photo { position: relative; overflow: hidden; }
.hero-photo.has-photo::before {
  content: ''; position: absolute; inset: -30px;  /* overscan — a blur must not reveal its own edge */
  background: var(--photo-src) center / cover no-repeat;
  filter: grayscale(1) blur(22px) brightness(.55);
}
.hero-photo img {
  position: relative;      /* above the blurred fill */
  display: block; width: 100%; height: 100%;
  object-fit: contain;
  filter: grayscale(1);
}

/* ── body ────────────────────────────────────────────────── */
.body { padding-top: var(--gap-lg); padding-bottom: var(--gap-lg); }
.col-members  { grid-column: 1 / 4; }
.col-disco    { grid-column: 4 / 7; padding-left: var(--gap-lg); }

/* ── content-aware columns ────────────────────────────────────
   Half the scene is small bands: 194 have 1–2 releases, 52 have a single
   member, 16 list no members at all. Each column takes only the width its
   content earns; the map absorbs whatever is left, so no layout has a hole.
   solo = one member · no-members = none · slim-disco = 1–2 releases ·
   no-disco = none */

/* one member: members column narrows, lone card keeps its size */
.body.solo .col-members  { grid-column: 1 / 3; }
.body.solo .col-disco    { grid-column: 3 / 7; }
.body.solo .members-grid { grid-template-columns: repeat(2, 1fr); }
.body.solo .disco-grid   { grid-template-columns: repeat(3, 1fr); }

/* 1–2 releases: discography folds to one large cover per row, map grows */
.body.slim-disco .col-disco    { grid-column: 4 / 6; }
.body.slim-disco .disco-grid   { grid-template-columns: 1fr; }
.body.slim-disco .col-related  { grid-column: 6 / -1; }
.body.slim-disco .col-comments,
.body.slim-disco .col-shows    { grid-column: 1 / 6; }

.body.solo.slim-disco .col-disco    { grid-column: 3 / 5; }
.body.solo.slim-disco .disco-grid   { grid-template-columns: 1fr; }
.body.solo.slim-disco .col-related  { grid-column: 5 / -1; }
.body.solo.slim-disco .col-comments,
.body.solo.slim-disco .col-shows    { grid-column: 1 / 5; }

/* no releases: the map starts where the members end */
.body.no-disco .col-related  { grid-column: 4 / -1; }
.body.no-disco .col-comments,
.body.no-disco .col-shows    { grid-column: 1 / 4; }
.body.solo.no-disco .col-related  { grid-column: 3 / -1; }
.body.solo.no-disco .col-comments,
.body.solo.no-disco .col-shows    { grid-column: 1 / 3; }

/* no members listed: discography moves to the left edge */
.body.no-members .col-disco    { grid-column: 1 / 7; padding-left: 0; }
.body.no-members .disco-grid   { grid-template-columns: repeat(4, 1fr); }
.body.no-members.slim-disco .col-disco    { grid-column: 1 / 4; }
.body.no-members.slim-disco .disco-grid   { grid-template-columns: repeat(2, 1fr); }
.body.no-members.slim-disco .col-related  { grid-column: 4 / -1; }
.body.no-members.slim-disco .col-comments,
.body.no-members.slim-disco .col-shows    { grid-column: 1 / 4; }
/* nothing but the pin: the map takes the whole row */
.body.no-members.no-disco .col-related  { grid-column: 1 / -1; padding-left: 0; }
.body.no-members.no-disco .col-comments,
.body.no-members.no-disco .col-shows    { grid-column: 1 / 6; }
.col-related  {
  grid-column: 7 / -1;
  grid-row: 1 / span 3;          /* let shows and comments sit beside the map, not below it */
  padding-left: var(--gap-lg);
  margin-right: calc(-1 * var(--pad));
  position: sticky; top: var(--nav-h); align-self: start;
  height: calc(100vh - var(--nav-h) - var(--gap-lg));
  display: flex; flex-direction: column;
}
/* the show log and the comments stack down the left of the sticky map */
.col-shows    { grid-column: 1 / 7; grid-row: 2; padding-top: var(--gap-lg); }
.col-comments { grid-column: 1 / 7; grid-row: 3; padding-top: var(--gap-lg); }
/* 189 of 398 bands have no documented show — comments move up, no empty row */
.body.no-shows .col-comments { grid-row: 2; }

/* ── members ─────────────────────────────────────────────── */
.members-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: var(--gap);
}
#past-wrap { margin-top: var(--gap-lg); }

.member-card { min-width: 0; }
.mc-photo {
  position: relative;
  width: 100%; aspect-ratio: 1 / 1;
  background: #16191e;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.mc-photo img {
  width: 100%; height: 100%; object-fit: cover;
  filter: grayscale(1);
}
.mc-ph {
  font-family: var(--display-font);
  font-size: 46px; color: #333a44;
}

.member-card.linked { cursor: pointer; }
.mc-photo img, .mc-ph, .m-name { transition: transform .5s var(--ease), filter .35s, color .2s; }
.member-card:hover .mc-photo img { transform: scale(1.07); filter: grayscale(1) brightness(1.18); }
.member-card:hover .mc-ph { transform: scale(1.1); color: #454e5b; }
.member-card.linked:hover .m-name { color: var(--ui-accent); }
.mc-photo::after {
  content: ''; position: absolute; inset: 0;
  box-shadow: inset 0 0 0 1px #ffffff00;
  transition: box-shadow .35s;
  pointer-events: none;
}
.member-card:hover .mc-photo::after { box-shadow: inset 0 0 0 1px #ffffff2e; }
.m-name {
  display: block; margin-top: 10px;
  color: var(--white); font-size: 13px; font-weight: 700;
}
.m-role { color: var(--muted); font-size: 12px; margin-top: 1px; }
.m-bands { margin-top: 6px; font-size: 11px; line-height: 1.45; }
.m-bands .lbl { color: var(--dim); }
.m-bands .now a, .m-bands .now span { color: var(--ok); }
.m-bands .ex  a, .m-bands .ex  span { color: var(--ui-accent); }
.m-bands a { cursor: pointer; }
.m-bands a:hover { text-decoration: underline; }

/* ── honors (badges under a musician's photo) ────────────── */
.honors { margin-top: 7px; display: flex; flex-direction: column; gap: 4px; }
.honor {
  display: flex; align-items: center; gap: 7px;
  font-size: 10.5px; letter-spacing: .05em; text-transform: uppercase;
  color: var(--gold);
  min-width: 0;
}
/* contain, because the three decade marks are wider than they are tall — one
   X per decade — and every other sigil is square, so the box is the same and
   only the ink inside it differs */
.honor img { width: 16px; height: 16px; object-fit: contain; flex: none; }
.honor .hl { white-space: nowrap; }
.honor .n {
  margin-left: auto; padding-left: 8px;
  color: var(--gold-dim);
  letter-spacing: 0; text-transform: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* On a member card the honors are a row of medals, not a list. The card is
   121px wide — a labelled row can only ever hold one honor — so a six-honor
   veteran wore six lines of gold under a small photograph, and the pile read
   as noise rather than as distinction. Here they sit as icons in a row; the
   words survive in the hover title and, in full with their detail, on the
   musician's own page, where the list stays vertical and has the room for it.
   The label stays in the accessibility tree rather than being removed. */
.member-card .honors { flex-direction: row; flex-wrap: wrap; gap: 5px 6px; }
.member-card .honor  { gap: 0; }
.member-card .honor .hl {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.member-card .honor .n { display: none; }

/* ── discography ─────────────────────────────────────────── */
.disco-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: var(--gap);
}
.disco-item { min-width: 0; cursor: pointer; }
.disco-thumb {
  position: relative; overflow: hidden;
  width: 100%; aspect-ratio: 1 / 1;
  background: #16191e;
}
.disco-thumb.empty { background: #14171c; border: 1px solid #1c2027; }
.disco-cover { width: 100%; height: 100%; object-fit: cover; display: block; }
.physical-strip {
  position: absolute; left: 7px; right: 7px; bottom: 7px; z-index: 2;
  padding: 4px 6px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--white); background: #0b0d10d9; font-size: 9px; letter-spacing: .06em;
  text-transform: uppercase; backdrop-filter: blur(4px);
}
.disco-title { display: block; margin-top: 10px; color: var(--white); font-size: 13px; }
.disco-sub   { display: block; margin-top: 1px; color: var(--muted); font-size: 12px; }

/* the cover pushes in behind its frame and an accent line wipes across the
   bottom — enough motion to read as clickable without shifting the grid */
.disco-cover, .disco-title { transition: transform .45s var(--ease), color .2s; }
.disco-thumb::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 2px;
  background: var(--ui-accent);
  transform: scaleX(0); transform-origin: left center;
  transition: transform .38s var(--ease);
}
.disco-item:hover .disco-cover { transform: scale(1.07); }
.disco-item:hover .disco-thumb::after { transform: scaleX(1); }
.disco-item:hover .disco-title { color: var(--ui-accent); }

/* ── related bands + map ─────────────────────────────────── */
.mapwrap { position: relative; flex: 1; min-height: 380px; overflow: hidden; }
#map { position: absolute; inset: 0; background: #0e1114; }
.leaflet-container { background: #0e1114; font: inherit; }
.mapwrap::before {
  content: ''; position: absolute; inset: 0; z-index: 500;
  pointer-events: none;
  background: linear-gradient(90deg, #0b0d10cc 0%, #0b0d1080 34%, transparent 62%);
}

.related-list {
  position: absolute; top: var(--gap); left: var(--gap); z-index: 600;
  margin: 0; padding: 0; list-style: none;
  max-height: calc(100% - var(--gap) * 2);
  overflow-y: auto;
  max-width: 62%;
}
.related-list li {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 12px 4px 10px;
  border-radius: 12px;
  cursor: pointer;
  white-space: nowrap;
}
.related-list li:hover, .related-list li.on {
  background: #1c2129e6;
}
.rb-dot {
  width: 9px; height: 9px; border-radius: 50%;
  flex: none;
  box-shadow: 0 0 0 1px #0006;
}
.rb-dot.dark { box-shadow: 0 0 0 1px #9aa5b1; }
.rb-name { color: var(--white); font-size: 13px; text-shadow: 0 1px 3px #000; }
.rb-via  { color: var(--muted); font-size: 12px; text-shadow: 0 1px 3px #000;
           overflow: hidden; text-overflow: ellipsis; }

/* band logos floating over the map, screen-blended into the tiles */
/* the pane itself is screen-blended into the tiles (see band.js) */
.map-logo-icon img {
  width: 100%; height: 100%; object-fit: contain;
  filter: var(--logo-filter);
}

.band-tip {
  background: #14171cf2 !important;
  border: 1px solid var(--border) !important;
  color: var(--text) !important;
  box-shadow: none !important;
  font-size: 12px;
}
.band-tip::before { display: none !important; }

/* ── documented live shows ───────────────────────────────────
   A ledger, not a gallery: one line per night, the flyer thumbnail on the
   left where one survives. Only rows with a flyer are clickable. */
.col-shows[hidden] { display: none; }
.shows-note {
  margin: -8px 0 8px;
  color: var(--muted); font-size: 12px; line-height: 1.5;
  max-width: 62ch;
}
.shows-count {
  color: var(--dim); font-size: 11px;
  letter-spacing: .06em; text-transform: uppercase;
  margin-bottom: var(--gap);
}

.shows-list { margin: 0; padding: 0; list-style: none; }
.show-year {
  font-family: var(--display-font);
  font-size: 20px; color: var(--ui-accent);
  margin: 18px 0 6px;
  letter-spacing: .5px;
}
.show-year:first-child { margin-top: 0; }

.show-row {
  display: flex; align-items: flex-start; gap: 12px;
  padding: 8px 0;
  border-top: 1px solid #ffffff0f;
}
.show-thumb {
  flex: none; width: 44px; height: 44px;
  background: #16191e;
  overflow: hidden;
  position: relative;
}
.show-thumb img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  filter: grayscale(1) contrast(1.1);
  transition: transform .45s var(--ease), filter .3s;
}
/* no flyer survived this night — the slot stays as an empty spacer so the rows
   align, but draws nothing: on most bands the flyers are a handful among
   dozens, and a column of grey boxes would drown them.
   a band whose log kept no flyer at all drops the column entirely */
.show-thumb.empty { background: none; }
.shows-list:not(.has-flyers) .show-thumb { display: none; }

.show-main { min-width: 0; flex: 1; }
.show-head { display: block; }
.show-date { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.show-where { color: var(--white); font-size: 13px; margin-left: 8px; }
/* the same red the room's abroad night carries and the museum's wall marks —
   one meaning, one hue, in all four places it is stated */
.show-abroad {
  display: inline-block; margin-left: 6px;
  padding: 0 4px;
  border: 1px solid rgb(224 69 62 / .38);
  color: var(--accent); font-size: 10px;
  letter-spacing: .08em; vertical-align: 1px;
}
.show-note { display: block; margin-top: 1px; color: #97a0ad; font-size: 12px; }
.show-src {
  display: block; margin-top: 1px;
  color: var(--dim); font-size: 10.5px; letter-spacing: .05em;
}
.show-link {
  flex: none; align-self: center;
  color: var(--dim); font-size: 13px; padding: 0 2px;
}
.show-link:hover { color: var(--ui-accent); }

.show-row.has-flyer { cursor: pointer; }
.show-row.has-flyer:hover .show-thumb img,
.show-row.has-flyer:focus-visible .show-thumb img { transform: scale(1.1); filter: none; }
.show-row.has-flyer:hover .show-where,
.show-row.has-flyer:focus-visible .show-where { color: var(--ui-accent); }
.show-row.has-flyer:focus-visible { outline: 1px solid var(--ui-accent); outline-offset: 2px; }

#shows-more {
  margin-top: var(--gap);
  background: none; border: 1px solid var(--border);
  padding: 7px 14px;
  color: var(--text); font-family: var(--nav-font);
  font-size: 12px; letter-spacing: .04em;
  cursor: pointer;
}
#shows-more:hover { border-color: var(--ui-accent); color: var(--ui-accent); }
#shows-more[hidden] { display: none; }

/* ── flyer card ──────────────────────────────────────────────
   The scan, blown up on the same 90% scrim the album card uses. */
#flyer-overlay[hidden] { display: none; }
#flyer-overlay {
  position: fixed; inset: 0; z-index: 3000;
  background: var(--bg-90);
  display: flex; align-items: center; justify-content: center;
  padding: var(--gap-lg) var(--gap);
  overflow-y: auto;
  animation: fc-fade .22s ease both;
}
#flyer-card {
  position: relative;
  width: min(720px, 100%);
  max-height: calc(100vh - var(--gap-lg) * 2);
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  padding: var(--gap);
  animation: fc-in .34s var(--ease) both;
}
.fc-img { background: #0e1114; }
.fc-img img {
  display: block; margin: 0 auto;
  max-width: 100%; max-height: 66vh;
  object-fit: contain;
}
.fc-meta { margin-top: var(--gap); }
.fc-date  { color: var(--muted); font-size: 12px; font-variant-numeric: tabular-nums; }
.fc-where { color: var(--white); font-size: 17px; margin-top: 2px; }
.fc-note  { color: #97a0ad; font-size: 13px; margin-top: 4px; }
/* the rest of the night — every co-billed band is a door to its own page */
.fc-bill { margin-top: 8px; font-size: 12.5px; line-height: 1.6; color: var(--muted); }
.fc-bill .lbl { color: var(--dim); }
.fc-bill a { color: var(--white); }
.fc-bill a:hover { color: var(--ui-accent); }
.fc-src   { color: var(--dim); font-size: 10.5px; letter-spacing: .05em; margin-top: 6px; }
.fc-src a { color: var(--ui-accent); }
.fc-src a:hover { text-decoration: underline; }
#flyer-close {
  position: absolute; top: 8px; right: 12px;
  background: none; border: 0; padding: 0 4px;
  color: var(--ui-accent); cursor: pointer;
  font-family: var(--nav-font);
  font-size: 22px; font-weight: 700; line-height: 1;
}
#flyer-close:hover { color: var(--white); }

@keyframes fc-fade { from { opacity: 0 } to { opacity: 1 } }
@keyframes fc-in {
  from { opacity: 0; transform: translateY(20px) scale(.96); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  #flyer-overlay, #flyer-card { animation: none; }
}

/* ── comments ────────────────────────────────────────────── */
.remark-holder { min-height: 60px; }

/* ── narrower screens ────────────────────────────────────── */
@media (max-width: 1400px) {
  :root { --gap-lg: 40px; }
  /* the spare column between the stack and the photograph is the first thing
     to go — the two end boxes keep their size, the middle just gets tighter */
  .hero-logo   { grid-column: 1 / 4; }
  .hero-mid    { grid-column: 4 / 8; }
  .hero-photo  { grid-column: 8 / -1; }
}
@media (max-width: 1100px) {
  :root { --gap-lg: 20px; }
  /* no room for three abreast: logo and photograph share the top row at half
     width each, the stack runs full width underneath. the rows are pinned
     because the stack sits between them in source order and auto-placement
     would otherwise push the photograph down into a third row */
  .hero-logo   { grid-column: 1 / 6;  grid-row: 1; }
  .hero-photo  { grid-column: 6 / -1; grid-row: 1; }
  .hero-mid    { grid-column: 1 / -1; grid-row: 2;
                 padding-left: 0; margin-top: var(--gap-lg); align-self: start; }
  .col-members { grid-column: 1 / 6; }
  .col-disco   { grid-column: 6 / -1; }
  .col-related {
    grid-column: 1 / -1; padding-left: 0; margin-right: 0;
    position: static; height: 70vh; margin-top: var(--gap-lg);
    grid-row: auto;
  }
  .col-shows    { grid-column: 1 / -1; grid-row: auto; }
  .col-comments { grid-column: 1 / -1; grid-row: auto; }
}

/* ═══ mobile ═══════════════════════════════════════════════════
   One breakpoint: below 860px the header wraps into rows and every
   page becomes a single column — display:block retires the whole
   column system, including the content-aware variants. */
@media (max-width: 860px) {
  body { padding-top: 0; font-size: 14px; }

  /* nav: brand + X on top, search full row, links wrap below */
  #nav {
    position: static; height: auto;
    flex-wrap: wrap; gap: 12px 20px;
    padding: 12px 16px;
  }
  #navlinks { display: contents; }
  #brand { order: 1; }
  /* back in the flow here: this nav is static and wraps, so an absolute X
     would resolve against the viewport instead of the bar. It shares the
     first line with the brand and holds the right end of it. */
  #nav-close { position: static; order: 2; margin-left: auto; }
  #searchbox { order: 3; flex: 1 1 100%; width: auto; }
  #search-results { width: 100%; }
  #navlinks a, #navlinks button { order: 4; font-size: 15px; }

  .grid { display: block; padding: 0 16px; }
  .hero { padding-top: 16px; }
  /* one column: logo, then the stack, then the photograph. both end boxes keep
     the 1.43 shape and simply run the full width — a fixed height here would
     put the wasted band straight back */
  .hero-logo  { max-height: 200px; }
  .hero-mid   { padding: 24px 0 0 0; margin-top: 0; }
  .hero-photo { max-height: 300px; margin: 24px auto 0; padding-left: 0; }
  .bc-player  { height: 42px; }

  .body { padding-top: 40px; padding-bottom: 40px; }
  .col-members, .col-disco, .col-related, .col-shows, .col-comments {
    padding-left: 0 !important;
    margin: 0 0 40px;
  }
  .col-related {
    position: static; height: auto;
    margin-right: 0;
    display: block;
  }
  /* 62vh here meant the related-bands map ate two thirds of the phone before
     the reader had scrolled past it. The list floats over the map and scrolls
     inside itself, so a shorter map loses no band — only the empty sea. */
  .mapwrap { height: 42vh; min-height: 280px; }
  .members-grid { grid-template-columns: repeat(2, 1fr) !important; }
  .disco-grid { grid-template-columns: repeat(2, 1fr) !important; gap: 24px 16px; }
  .related-list { max-width: 78%; }
  h2 { font-size: 26px; }
}

/* ── asked for someone who is not here ─────────────────────────
   Both the band page and the artist page render this instead of drawing an
   arbitrary record under the requested id. It is deliberately plain: nothing
   to click but the way out, and no chrome that could be mistaken for a
   record. Steel, never gold — a page that failed is not an honor. */
#not-here {
  max-width: 620px;
  margin: 18vh auto 0;
  padding: 0 24px 120px;
  text-align: center;
}
#not-here h2 {
  font-family: var(--display-font);
  font-size: 34px; font-weight: 400; line-height: 1.1;
  color: var(--ui-accent);
  margin: 0 0 18px;
}
#not-here p { color: var(--muted); font-size: 14px; line-height: 1.7; margin: 0 0 10px; }
/* the id is the one thing here worth reading twice — it is what the visitor
   typed or followed, and seeing it is how they recognise a stale link */
#not-here b {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px; font-weight: 400; color: var(--white);
}
#not-here a { color: var(--ui-accent); text-decoration: none; border-bottom: 1px solid currentColor; }
#not-here a:hover { color: var(--white); }
