/* ==========================================================================
   Bleu Grave — single stylesheet
   Look: New Order meets The Cure, gone goth (Smith, 2026-09-15: "make the
   site more goth looking, remove this color from everything" — the ice
   blue). The structure is unchanged: flat fields, a modernist grid, clean
   grotesque type, a code strip spelling the band's name, near-black ground,
   duotone photos with a soft vignette, a scrawled handwriting face. What
   changed is the palette, three times on 2026-09-15: Smith asked for the ice
   blue gone, then for the whole site to be black and white, then for the
   blue out of the band's own logo to run through it. **The site is black
   and blue.** One blue — `--hi`, sampled straight out of the logo artwork —
   on a blue-black ground, with bone type. Photos stay hard black and white;
   he asked for that and it has not changed.
   Change colours and fonts in :root, not through the file.
   ========================================================================== */

:root {
  /* Colour — black and blue. --hi is the one colour on the site: the blue
     from the band's logo, used for the scrawled labels, show dates, ticket
     links, link underlines and hovers, and the buttons. The blacks and greys
     are all tinted toward it so the whole thing reads cold. */
  --bg: #000000;            /* Smith asked for a darker black twice, then
                               said the desktop still read grey — it is now
                               true black (2026-09-15) */
  --bg-raised: #030405;
  --bg-line: #0e141a;
  --ink: #e4e9ee;
  --ink-dim: #8b97a3;
  /* The flat field the page titles sit on. It was a visibly lighter block
     beside the black on a wide screen, which is what Smith was seeing; it is
     now barely off the ground and only reads as a field at all because the
     code bars sit next to it. */
  --accent: #040608;
  --accent-ink: #f1f5f8;    /* type that sits on the field */
  --accent-deep: #10202c;   /* the store's hover fills */
  --hi: #04a2ec;            /* the blue, straight out of the logo */

  /* Type — one grotesque for everything set. The handwriting face is no
     longer loaded: Smith had every blue cursive label taken off the site on
     2026-09-16, so nothing uses --font-hand any more and the pages don't
     fetch "Nothing You Could Do". The rules below that still name it are
     kept only for the restore notes in the HTML; bringing any of them back
     means re-adding the face to the font link in all six pages first. */
  --font-display: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-body: "Archivo", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-hand: "Nothing You Could Do", "Segoe Script", "Bradley Hand", cursive;

  /* Photos — every photo gets the same hard black and white so anything the
     band sends fits. Hover on the gallery lifts it slightly. Once the ground
     went true black the photos were the brightest thing left on a phone, so
     they came down a notch too (Smith, 2026-09-15, "could be darker"). */
  --duotone: grayscale(1) contrast(1.3) brightness(0.66);

  /* Rhythm */
  --space: 1rem;
  --space-lg: 3rem;
  --space-xl: 6rem;
  --measure: 40rem;
  --page-pad: clamp(1.25rem, 5vw, 3.5rem);
}

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

* { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: var(--font-display);
  line-height: 1;
  letter-spacing: -0.03em;
}

h2 {
  font-weight: 700;
  font-size: clamp(2rem, 5vw, 3.4rem);
  margin-bottom: var(--space-lg);
}

h3 {
  font-weight: 700;
  font-size: clamp(1.3rem, 3vw, 1.8rem);
  letter-spacing: -0.02em;
}

p { max-width: var(--measure); }
p + p { margin-top: var(--space); }

/* Links are bone, underlined in the blue, and go blue on hover. */
a { color: var(--ink); text-decoration-color: var(--hi); text-decoration-thickness: 1px; text-underline-offset: 3px; }
/* Spelled out so a browser's own visited-link purple can never show through
   (Smith, 2026-09-15: "no purple"). */
a:link, a:visited { color: var(--ink); }
a:hover, a:focus { color: var(--hi); }

img, svg { max-width: 100%; display: block; }

::selection { background: var(--hi); color: var(--bg); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

/* Small tracked caps — catalogue-number style lines */
.caps {
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
}

/* Handwriting — the scrawl. Used for taglines and section labels. */
.hand {
  font-family: var(--font-hand);
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
}

/* --------------------------------------------------------------------------
   Code strip — the band's name spelled one block per letter (A=0 … Z=25).
   The markup gives each block its letter number in --i. It used to be a
   rainbow of hues; now the letter sets the block's lightness on one fixed
   blue hue (Smith, 2026-09-15), so it reads as a run of blue-grey bars. Used
   small under the band name, thin across the top of the footer, and as big
   bars on the inner page banners.
   -------------------------------------------------------------------------- */

.code {
  display: flex;
  height: 0.6rem;
  width: 100%;
}

.code span {
  flex: 1;
  background: hsl(199deg 45% calc(16% + var(--i) * 2.4%));
}

.code .gap { flex: 0 0 0.6rem; background: transparent; }

.code-thin { height: 0.35rem; }

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

.site-header {
  position: relative;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space);
  padding: 1.4rem var(--page-pad);
  background: var(--bg);
}

.site-header .wordmark {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1.05rem;
  letter-spacing: -0.03em;
  text-decoration: none;
  color: var(--ink);
  white-space: nowrap;
}

/* The band's logo (winged figure, with their name set into it) is the
   wordmark — Smith asked on 2026-09-15 for the typed "Bleu Grave" next to it
   to come off, so the link is the image alone and its alt carries the name.
   It is a JPG with a black ground, which matches --bg, so no cutout is
   needed. The logo is the one exception to the black-and-white rule: it
   keeps its blue, because Smith asked for it that way (2026-09-15) right
   after asking for the rest of the site to go black and white. Don't
   desaturate it. */
.site-header .wordmark {
  /* Never let the nav squeeze the logo: as a flex item it was being shrunk
     sideways on phones (55px wide at 67px tall for artwork that is wider
     than tall), which Smith saw as "squished" (2026-09-15). */
  flex: 0 0 auto;
}

.site-header .wordmark img {
  display: block;
  max-width: none;
  /* Sized so the band's name inside the artwork is actually legible — Smith
     asked for it bigger on 2026-09-15. The name is only about a tenth of the
     image's height, so this has to be generous to read at all. */
  height: 4.2rem;
  width: auto;
}

/* A little bigger on a desktop, where there is room for it beside the nav —
   Smith asked for that on 2026-09-15. The phone size is unchanged. */
@media (min-width: 800px) {
  .site-header .wordmark img { height: 5.2rem; }
}

.site-nav { display: flex; flex-wrap: wrap; gap: 0.25rem 1.4rem; }

.site-nav a {
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-dim);
  padding-bottom: 0.2rem;
  border-bottom: 2px solid transparent;
}

.site-nav a:hover { color: var(--ink); }
.site-nav a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--hi); }

/* --------------------------------------------------------------------------
   Hero — home page. A flat violet-black field with the name on it, next to a
   full-height duotone photo with the tagline scrawled across the bottom.
   -------------------------------------------------------------------------- */

.hero {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  min-height: calc(100svh - 4.6rem);   /* the header sits above it */
  overflow: hidden;
}

@media (min-width: 800px) {
  .hero { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  /* When there is a panel beside the photo, it takes the narrow left column
     even though the photo comes first in the markup. */
  .hero-panel { order: -1; }
}

/* The home page hero is the photo on its own (Smith, 2026-09-15) — one full
   column at every width. Two classes so this beats the .hero rule above.
   It does not hold the screen open to full height any more: Smith said the
   photo sat too low (2026-09-15), and the height was leaving a band of black
   above it, made worse by the taller logo in the header. The box is now the
   shape of the photo, so the photo starts right under the header. */
.hero.hero-photo-only {
  grid-template-columns: minmax(0, 1fr);
  min-height: 0;
  overflow: visible;
}

.hero-panel {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 1.5rem;
  background: var(--accent);
  color: var(--accent-ink);
  padding: var(--space-xl) var(--page-pad) var(--space-lg);
}

.hero-title {
  font-weight: 900;
  font-size: clamp(3.4rem, 17vw, 8.5rem);
  line-height: 0.86;
  letter-spacing: -0.045em;
  text-transform: uppercase;
  color: var(--accent-ink);
}

.hero-title span { display: block; }

@media (min-width: 800px) {
  /* the field is 5/12 of the viewport: keep GRAVE inside it */
  .hero-title { font-size: clamp(3.4rem, 8.2vw, 8.5rem); }
}

.hero-panel .code { max-width: 18rem; }

.hero-city { color: var(--accent-ink); opacity: 0.8; }

/* Without the script the slides are a plain list one under another, so this
   box has to grow to fit them — no fixed height, nothing clipped. */
.hero-photo {
  position: relative;
  background: var(--bg);
}

.hero-photo .hero-art { position: static; }

/* With the script running the slides are stacked, so the box takes the shape
   of the photos (5:4) and is capped so it always fits on one screen.

   The stacked slides are taken out of the flow, so this box has no content
   of its own to give it a height — it has to get one from the aspect ratio.
   `align-self: start` is what lets that happen: as a grid item it would
   otherwise stretch to the row, the row would size to its (empty) contents,
   and the whole slideshow would collapse to nothing and vanish off the page.
   That happened on 2026-09-15. The min-height is a hard floor so it can
   never disappear again. Don't remove either of them. */
html.js-motion .hero-photo {
  overflow: hidden;
  align-self: start;
  /* 3:2, the shape most of the band's live shots come in. It was 5:4, which
     letterboxed them and wasted height — Smith said the slideshow looked too
     small on a desktop (2026-09-15). The height cap is what actually decides
     how big the photo renders on a wide screen, so raise that, not the
     width, if he asks for bigger again. */
  aspect-ratio: 3 / 2;
  min-height: 16rem;
  max-height: calc(100svh - 7.5rem);
}

/* On a wide screen the photo box is capped and centred on the page instead
   of running the full width — Smith asked for the slideshow photos to be
   centred on desktop, then for them to be bigger (2026-09-15). On a phone it
   is still edge to edge. */
.hero.hero-photo-only .hero-photo {
  /* `width` + `justify-self`, NOT `max-width` + `margin-inline: auto`. Auto
     side margins stop a grid item stretching to its column, so its width goes
     shrink-to-fit; the slides are positioned out of the flow, so there is
     nothing to shrink to and the whole box collapsed to a few hundred pixels.
     That is why the slideshow looked tiny on a desktop (Smith, 2026-09-15).
     An explicit width keeps the inline size definite so the aspect ratio can
     do its job. */
  width: min(100%, 92rem);
  justify-self: center;
}

html.js-motion .hero-photo .hero-art {
  position: absolute;
  inset: 0;                 /* no bleed: the photo is shown whole, and what
                               the parallax slides into view is black */
  z-index: 0;
  pointer-events: none;
}

/* The whole photo shows — Smith asked for it uncropped (2026-09-15), so this
   is `contain`, not `cover`. Whatever is left over top and bottom is the
   page's own black, so it reads as a frame rather than a letterbox. Don't
   put `cover` back without asking him. */
.hero-photo img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center;
  filter: var(--duotone);
}

/* Slideshow at the top of the home page (Smith asked for one, 2026-09-15).
   With JavaScript off or reduced motion on it is simply the photos one under
   another — nothing is ever hidden from a visitor. When motion is allowed,
   js/main.js stacks them and cross-fades one every five seconds. To add a
   photo to it, copy a whole <li> in index.html; the order in the markup is
   the order they show in. */
.slideshow { list-style: none; }

.slideshow img {
  width: 100%;
  height: auto;
  filter: var(--duotone);
}

html.js-motion .hero-photo .slideshow { position: absolute; inset: 0; }

html.js-motion .hero-photo .slideshow li {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1200ms ease;
}

html.js-motion .hero-photo .slideshow li.is-current { opacity: 1; }

html.js-motion .hero-photo .slideshow img {
  height: 100%;
  object-fit: contain;
}

/* The Cure vignette: soft dark edges, darker toward the bottom so the
   handwriting reads. Kept shallow since the photo is shown whole — the
   gradient should sit in the black below it, not over the band. */
.hero-photo::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    radial-gradient(ellipse 85% 80% at 50% 45%, transparent 60%, rgba(0, 0, 0, 0.6) 100%),
    linear-gradient(to top, rgba(0, 0, 0, 0.92) 0%, rgba(0, 0, 0, 0) 26%);
}

.hero-tagline {
  position: absolute;
  z-index: 2;
  left: var(--page-pad);
  right: var(--page-pad);
  bottom: var(--space-lg);
  max-width: none;
  font-family: var(--font-hand);
  font-size: clamp(1.9rem, 4.2vw, 3.4rem);
  line-height: 1.15;
  color: var(--ink);
  text-shadow: 0 2px 30px rgba(0, 0, 0, 0.7);
  transform: rotate(-2deg);
  transform-origin: left bottom;
}

/* --------------------------------------------------------------------------
   Inner page banners — page title on the flat field.

   The big code bars that sat beside (and, on a phone, under) every page
   title are gone as of 2026-09-15: Smith asked twice for "the blue line
   across the bottom of each page" off, and on a phone those bars are what
   that is. Every banner now carries "page-hero-bare". The .code-bars rules
   are kept below in case he ever wants them back — nothing uses them.
   -------------------------------------------------------------------------- */

.page-hero {
  position: relative;
  display: grid;
  grid-template-columns: 1fr;
  min-height: 46svh;
}

@media (min-width: 800px) {
  .page-hero { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
}

.page-hero .hero-panel { padding-top: var(--space-xl); }

.page-hero .hero-title { font-size: clamp(3rem, 15vw, 7rem); }

@media (min-width: 800px) {
  .page-hero .hero-title { font-size: clamp(3rem, 9vw, 7rem); }
}

.page-hero .code-bars {
  display: flex;
  min-height: 7rem;
}

.page-hero .code-bars span {
  flex: 1;
  background: hsl(199deg 45% calc(16% + var(--i) * 2.4%));
}

/* A banner with no code bars beside it: one column at every width, so the
   title has the whole page. Used on the Tour page (Smith, 2026-09-15). */
.page-hero-bare { grid-template-columns: minmax(0, 1fr); }

@media (min-width: 800px) {
  .page-hero-bare { grid-template-columns: minmax(0, 1fr); }
}

/* The Cure treatment for a page title: the scrawled hand instead of the
   grotesque, set big and tipped off the horizontal, with the soft halo those
   record sleeves have. Smith asked for the Tour title to look "cooler, like
   the cure" (2026-09-15). Lower case — the hand has no real capitals to
   speak of and shouting it in caps kills the scrawl. */
.hero-title-hand {
  font-family: var(--font-hand);
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  line-height: 1;
  color: var(--ink);
  transform: rotate(-3deg);
  transform-origin: left bottom;
  text-shadow:
    0 0 28px rgba(4, 162, 236, 0.45),
    0 0 70px rgba(4, 162, 236, 0.25);
}

/* The hand is a much smaller face at the same size, so it needs its own
   scale — these beat the .page-hero .hero-title sizes above. */
.page-hero .hero-title-hand { font-size: clamp(4.5rem, 24vw, 11rem); }

@media (min-width: 800px) {
  .page-hero .hero-title-hand { font-size: clamp(4.5rem, 14vw, 11rem); }
}

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

/* No rule across the top of a section any more. It was a 1px blue-grey
   hairline the full width of the page; invisible on a phone, clearly a blue
   line on a desktop screen, which is what Smith was still seeing after the
   footer strip and the code bars came off (2026-09-15). The padding keeps
   the sections apart on its own. The hairlines inside content — the show
   rows and the release list — are untouched. */
.section {
  padding: var(--space-xl) var(--page-pad);
}

.section-inner { max-width: 68rem; margin: 0 auto; }

/* Section label — scrawled, in the blue */
.section .kicker {
  font-family: var(--font-hand);
  font-size: 1.7rem;
  line-height: 1;
  color: var(--hi);
  margin-bottom: 0.9rem;
  transform: rotate(-1.5deg);
  transform-origin: left bottom;
}

/* The bio's heading is the band's wordmark image rather than set type
   (Smith, 2026-09-15). Sized to sit where the old heading did. */
.wordmark-heading img {
  width: 100%;
  max-width: 26rem;
  height: auto;
}

/* On a phone the wordmark ran the full width of the column and read too big
   next to the bio — Smith asked for it smaller there (2026-09-15). Desktop
   is unchanged. */
@media (max-width: 600px) {
  .wordmark-heading img { width: 62%; }
}

.lede { font-size: 1.2rem; line-height: 1.5; }

.muted { color: var(--ink-dim); }

/* Flat blocks — the blue with black type, going bone on hover */
.button {
  display: inline-block;
  margin-top: var(--space-lg);
  padding: 0.95rem 1.7rem;
  border: 0;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.74rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--bg);
  background: var(--hi);
  transition: background-color 150ms ease, color 150ms ease;
}

.button:hover { background: var(--ink); color: var(--bg); }

/* --------------------------------------------------------------------------
   Photos — the About photo on the home page and the Photos page grid.
   Every photo is forced into the same hard black and white (--duotone) so
   the site stays one look no matter what gets uploaded.
   -------------------------------------------------------------------------- */

.about-grid {
  display: grid;
  gap: var(--space-lg);
  align-items: start;
}

@media (min-width: 720px) {
  .about-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--space-xl); }
}

/* Photo with a flat blue block set behind it, offset down and right.
   Nothing uses .band-photo right now — Smith took the About photo off on
   2026-09-15 — but it is here for the next photo beside a bio. */
.band-photo {
  position: relative;
  margin: 0 1.25rem 1.25rem 0;
}

.band-photo::before {
  content: "";
  position: absolute;
  inset: 1.25rem -1.25rem -1.25rem 1.25rem;
  background: var(--hi);
}

.band-photo img {
  position: relative;
  width: 100%;
  height: auto;
  filter: var(--duotone);
}

.button-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: var(--space-lg);
}

.button-row .button { margin-top: 0; }

.button-row .button + .button {
  background: transparent;
  color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--bg-line);
}

.button-row .button + .button:hover { background: var(--hi); color: var(--bg); box-shadow: none; }

.photo-grid {
  list-style: none;
  display: grid;
  grid-template-columns: 1fr;
  gap: 4px;
}

@media (min-width: 600px) { .photo-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 900px) { .photo-grid { grid-template-columns: 1fr 1fr 1fr; } }

.photo-grid a {
  display: block;
  background: var(--bg-raised);
}

.photo-grid img {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  filter: var(--duotone);
  transition: filter 250ms ease;
}

.photo-grid a:hover img { filter: grayscale(1) contrast(1.08); }

/* A single poster/flyer image dropped into a section, e.g. Past Shows.
   Black and white like every other photo on the site, and dimmed below its
   own paper tone so it sits back on the black instead of glaring off it.
   Smith walked this down over 2026-09-16 — 2.4 (pure white), then 1.6,
   then 1, all still too bright on a phone — and then asked for the same
   setting on a computer, so there is deliberately no desktop override. */
.section-photo {
  width: 100%;
  height: auto;
  max-width: 24rem;
  margin: 0 auto;
  filter: grayscale(1) contrast(1) brightness(0.95);
}

/* Smith asked to keep this one poster in its own color, 2026-09-16 — an
   exception to the black-and-white rule above, not a change to it. */
.section-photo-color {
  filter: none;
}

/* --------------------------------------------------------------------------
   Music page
   -------------------------------------------------------------------------- */

.release {
  padding: var(--space-lg) 0;
  border-top: 1px solid var(--bg-line);
}

.release:first-child { border-top: 0; padding-top: 0; }

.release .embed-slot {
  display: grid;
  place-items: center;
  min-height: 10rem;
  border: 1px dashed var(--bg-line);
  color: var(--ink-dim);
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-align: center;
  padding: var(--space);
  margin-top: var(--space);
}

/* The Bandcamp player is Bandcamp's own page in a frame, so its release
   artwork arrives in full colour. The site is black and white, so the frame
   is desaturated from out here (Smith, 2026-09-15: "no purple"). */
.release iframe {
  margin-top: var(--space-lg);
  filter: grayscale(1);
}

/* --------------------------------------------------------------------------
   Video page
   -------------------------------------------------------------------------- */

/* Smith asked for the videos to play on the site (2026-09-15), so unlike the
   Bandcamp frames these keep their own colour — the hard black and white rule
   is about photographs. Each frame is 16:9 and fills its width. */
.video-item {
  padding: var(--space-lg) 0;
  border-top: 1px solid var(--bg-line);
}

.video-item:first-of-type { border-top: 0; padding-top: 0; }

.video-frame {
  position: relative;
  margin-top: var(--space);
  aspect-ratio: 16 / 9;
  background: var(--accent);
}

.video-frame iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

/* The way out if a frame is blocked, and the way a no-JS visitor still gets
   the video. */
.video-link {
  margin-top: 0.25rem;
  font-weight: 500;
  font-size: 0.74rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

/* Big enough to hit with a thumb. */
.video-link a {
  display: inline-block;
  padding: 0.6rem 0;
}

.listen-links {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 2rem;
  margin-top: var(--space);
}

.listen-links a {
  font-weight: 500;
  font-size: 0.74rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   Merch page
   -------------------------------------------------------------------------- */

.merch-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-lg);
}

@media (min-width: 600px) { .merch-grid { grid-template-columns: 1fr 1fr; } }

.product { background: var(--bg-raised); }

.product-art {
  aspect-ratio: 1;
  border-bottom: 1px solid var(--bg-line);
  overflow: hidden;
}

.product-art svg { width: 100%; height: 100%; }
.product-art img { width: 100%; height: 100%; object-fit: cover; }
/* Some product photos are a wider shot that cropping cuts into (e.g. the
   stickers/pins photo, which is a wide flat-lay) — this class shows the
   whole photo instead, letterboxed on the square card. */
.product-art img.uncropped { object-fit: contain; }

.product-info { padding: var(--space) 1.25rem 1.5rem; }

.product-info .price { color: var(--ink-dim); margin-top: 0.25rem; }

/* Store: the buy slot is empty (and takes no space) until js/shop.js
   mounts a Shopify buy button in it, or until a .buy-link is added. */
.product-info .buy-slot { margin-top: var(--space); }
.product-info .buy-slot:empty { display: none; }
.product-info .buy-link { margin-top: var(--space); }

/* --------------------------------------------------------------------------
   Events page — a clean ruled list:
     DATE     CITY
              venue · note · Tickets
   -------------------------------------------------------------------------- */

.event-list { list-style: none; }

.event {
  display: grid;
  grid-template-columns: 9rem minmax(0, 1fr);
  column-gap: var(--space);
  align-items: baseline;
  padding: 1.25rem 0;
  border-top: 1px solid var(--bg-line);
}

.event:last-child { border-bottom: 1px solid var(--bg-line); }

.event-date {
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--hi);
}

.event-leader { display: none; }

.event-city {
  font-weight: 700;
  font-size: clamp(1.2rem, 2.4vw, 1.5rem);
  letter-spacing: -0.02em;
}

.event-detail {
  grid-column: 2;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 1.5rem;
  color: var(--ink-dim);
  font-size: 0.9rem;
  margin-top: 0.15rem;
}

.event-detail a {
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--hi);
}

.event-detail a:hover { color: var(--ink); }

.event.past { opacity: 0.5; }
.event.past .event-date { color: var(--ink-dim); }

@media (max-width: 540px) {
  .event { grid-template-columns: 1fr; row-gap: 0.15rem; }
  .event-detail { grid-column: 1; }
}

/* --------------------------------------------------------------------------
   Footer — the code strip runs thin across the top, then the links.
   -------------------------------------------------------------------------- */

/* The thin code strip that used to run across the top of the footer came off
   on 2026-09-15 at Smith's request ("the blue line at the bottom"), so the
   footer carries its own top space now. The .code rules stay in the file for
   the big bars on the inner page banners. */
.site-footer {
  padding: var(--space-xl) 0;
  text-align: center;
}

.footer-links {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem 2rem;
  margin-bottom: var(--space-lg);
  padding: 0 var(--page-pad);
}

.footer-links a {
  font-weight: 500;
  font-size: 0.74rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
}

.footer-links a:hover { color: var(--hi); }

.signup {
  max-width: 26rem;
  margin: 0 auto var(--space-lg);
  padding: 0 var(--page-pad);
}

.signup label {
  display: block;
  margin-bottom: 0.75rem;
  font-weight: 500;
  font-size: 0.74rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink);
}

.signup-row { display: flex; gap: 0.5rem; }

.signup-row input {
  flex: 1;
  min-width: 0;
  padding: 0.85rem 0.9rem;
  border: 1px solid var(--ink-dim);
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 0.95rem;
}

.signup-row input:focus { outline: 2px solid var(--hi); outline-offset: 2px; border-color: var(--hi); }

.signup-row button {
  padding: 0.85rem 1.2rem;
  border: 0;
  font-family: var(--font-body);
  font-weight: 500;
  font-size: 0.74rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--bg);
  background: var(--hi);
  cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease;
}

.signup-row button:hover { background: var(--ink); }

.signup-thanks, .signup-sorry { margin: 0; color: var(--ink); }

.mailing-list {
  max-width: var(--measure);
  margin: 0 auto var(--space-lg);
  padding: 0 var(--page-pad);
  color: var(--ink-dim);
}

/* The handle in this line was the last blue thing at the bottom of a page —
   links are underlined in the blue everywhere else, but down here it read as
   a stray blue line and Smith asked for it gone (2026-09-15). Underlined in
   the dim grey instead, so it is still obviously a link. */
.mailing-list a { text-decoration-color: var(--ink-dim); }
.mailing-list a:hover, .mailing-list a:focus { color: var(--ink); text-decoration-color: var(--ink); }

.copyright {
  max-width: none;
  color: var(--ink-dim);
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   Motion — everything below only applies when js/main.js has confirmed
   that JS is running AND the visitor allows motion (html.js-motion).
   With JS off or reduced motion on, all content is fully visible and still.
   -------------------------------------------------------------------------- */

html.js-motion .reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 700ms ease, transform 700ms ease;
}

html.js-motion .reveal.is-visible {
  opacity: 1;
  transform: none;
}

html.js-motion .hero-art { will-change: transform; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  html.js-motion .reveal { opacity: 1; transform: none; transition: none; }
  .photo-grid img, .button { transition: none; }
}
