/* ==========================================================================
   Write Club Chicago — design system.
   Built from the approved "Dark and Red" concept.

   COLOUR IS CONSTRAINED. Only four foreground/background pairs are legal and
   all four are declared in the token block below. A pair that is not one of
   them is a bug, not a choice — check the spec before adding one.

   Oxblood is a SURFACE. It never carries text. Red text on the ground is
   --wc-red-ink and only at large display sizes. Rules and hairlines sitting
   on the ground are --wc-red-ink too, never oxblood, which reads as no edge
   at all against the ground.

   Self-contained. Shares no stylesheet or class name with the Midgame site.
   Every class is prefixed `wc-`.
   ========================================================================== */

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

:root {
  /* Ground and surfaces */
  --wc-ground:  #1E1C19;   /* near-black. Dark-first, not a dark mode.       */
  --wc-oxblood: #A81B21;   /* SURFACES ONLY — bands, buttons, footer.        */

  /* Foregrounds */
  --wc-cream:   #ECE7D4;   /* primary text. 13.72 on ground, 5.96 on oxblood */
  --wc-red-ink: #E03A42;   /* 3.93 on ground — LARGE DISPLAY TYPE ONLY,      */
                           /* plus hairlines, dividers and rules.            */
  --wc-muted:   #A9A49A;   /* 6.85 on ground — secondary body text.          */

  /* The logo cap lives here so the value is auditable in one place.
     Nothing scales the mark above this — not the hero, not the footer.
     The only logo file is 300x285; this is its maximum crisp width at 2x. */
  --wc-logo-cap: 150px;

  /* Type */
  --wc-display: 'Archivo', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --wc-mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  /* Display tracking is very tight and mono tracking is very wide. The
     tension between the two is most of what makes this feel like the
     concept. Neither value is decorative. */
  --wc-track-display: -0.045em;
  --wc-track-mono: 0.18em;
  --wc-track-mono-wide: 0.3em;

  /* The display tracking above is negative, which tightens the WORD gaps as
     well as the letter gaps, so multi-word headings run together. This opens
     the word gaps back up WITHOUT touching letter-spacing, which is
     load-bearing and unchanged.
     EM, NOT PX, on purpose: the display scale runs 112px down to 22px, and a
     fixed gap would be invisible at the top and heavy at the bottom - which is
     the same inversion this exists to remove, rebuilt at the other end.
     Display headings only. The mono faces already carry 0.18-0.3em positive
     letter-spacing tuned on its own; adding word gaps there would compound two
     independent decisions. */
  --wc-word-display: 0.1em;

  --wc-hair: 1px solid var(--wc-red-ink);
  --wc-measure: 68ch;
  --wc-gutter: clamp(20px, 5vw, 64px);
  --wc-maxw: 1280px;
}

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

body {
  margin: 0;
  background: var(--wc-ground);
  color: var(--wc-cream);
  font-family: var(--wc-display);
  font-size: 18px;
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; height: auto; display: block; }

a { color: var(--wc-cream); }

:focus-visible {
  outline: 2px solid var(--wc-red-ink);
  outline-offset: 3px;
}

.wc-skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--wc-oxblood);
  color: var(--wc-cream);
  padding: 12px 20px;
  font-family: var(--wc-mono);
  font-size: 12px;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  text-decoration: none;
}
.wc-skip:focus { left: 0; }

/* Visually hidden but still focusable and still read aloud. */
.wc-sr {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.wc-in {
  width: 100%;
  max-width: var(--wc-maxw);
  margin: 0 auto;
  padding-inline: var(--wc-gutter);
}

/* --------------------------------------------------------------------------
   TYPE SCALE
   Measured from the approved concept: 112 hero, then 92 / 52 / 48 / 44 / 40 /
   34 / 32 / 28 / 26 / 24 / 22 / 21. Body 17-18. Mono labels 10-14.

   Headline mobile sizes are chosen from that scale, not derived by shrinking
   the desktop value proportionally.
   -------------------------------------------------------------------------- */

.wc-eyebrow {
  font-family: var(--wc-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono-wide);
  text-transform: uppercase;
  color: var(--wc-muted);
  margin: 0 0 18px;
}

.wc-h1 {
  font-family: var(--wc-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: var(--wc-track-display);
  word-spacing: var(--wc-word-display);
  line-height: 0.92;
  overflow-wrap: break-word;
  font-size: clamp(34px, 8.6vw, 112px);
  margin: 0;
}

.wc-h2 {
  font-family: var(--wc-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: var(--wc-track-display);
  word-spacing: var(--wc-word-display);
  line-height: 0.98;
  font-size: clamp(28px, 5.2vw, 52px);
  margin: 0 0 28px;
}

.wc-h3 {
  font-family: var(--wc-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  word-spacing: var(--wc-word-display);
  line-height: 1.05;
  font-size: clamp(22px, 3.2vw, 32px);
  margin: 0 0 14px;
}

.wc-lede {
  font-size: clamp(21px, 2.4vw, 28px);
  line-height: 1.45;
  max-width: 24ch;
  margin: 0;
}

/* A lede that is a full factual sentence rather than a short punch needs a
   normal measure; 24ch turns it into a narrow ladder. */
.wc-lede-flow { max-width: 44ch; font-size: clamp(20px, 2.1vw, 26px); }

.wc-body { max-width: var(--wc-measure); }
.wc-body p { margin: 0 0 1.15em; }
.wc-body p:last-child { margin-bottom: 0; }
.wc-body a { color: var(--wc-cream); text-decoration: underline; text-underline-offset: 3px; }

.wc-muted { color: var(--wc-muted); }

.wc-mono {
  font-family: var(--wc-mono);
  font-size: 13px;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   SECTIONS
   -------------------------------------------------------------------------- */

.wc-sec { padding-block: clamp(56px, 8vw, 112px); }
/* Next Up sits directly under the headline and belongs to it. The gap that
   separates two ordinary sections would read as a break between them. */
.wc-sec-tight { padding-top: clamp(4px, 1vw, 16px); }
.wc-sec + .wc-sec { border-top: var(--wc-hair); }

.wc-sec-head { margin-bottom: clamp(32px, 4vw, 56px); }

/* --------------------------------------------------------------------------
   HEADER / NAV
   Seven flat links and no button. Every link is a real anchor in the
   served HTML — nothing is injected, and nothing is dropped on mobile.

   The persistent CTA was removed on 2026-08-27 (K6/J1). Its rules, its class
   and its markup are DELETED rather than disabled or hidden. A dead rule left
   behind is how the button comes back by accident in a later slice, so the
   class name does not appear anywhere in this build - not in a selector, not
   in an element, and not in a comment.

   The mobile panel is driven by a visually-hidden but FOCUSABLE checkbox, so
   the menu opens with no JavaScript at all: pointer users tap the label,
   keyboard users tab to the control and press Space. JS only adds Escape,
   the aria-expanded sync and focus return.
   -------------------------------------------------------------------------- */

.wc-head {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--wc-ground);
  border-bottom: var(--wc-hair);
}

.wc-head-in {
  width: 100%;
  max-width: var(--wc-maxw);
  margin: 0 auto;
  padding: 14px var(--wc-gutter);
  display: flex;
  align-items: center;
  gap: 24px;
}

.wc-brand { display: block; flex: 0 0 auto; line-height: 0; }
.wc-logo {
  width: 96px;
  max-width: var(--wc-logo-cap);
  height: auto;
}

.wc-nav {
  /* Logo hard left, the seven links immediately after it. Nothing is
     centred - centring fights the 900-1100px band, and Caveat, her own
     reference site, runs the same shape for the same reason. */
  margin-left: 0;
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: clamp(14px, 1.8vw, 30px);
}

.wc-navlist {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  gap: clamp(14px, 1.8vw, 30px);
}

.wc-navlist a {
  font-family: var(--wc-mono);
  font-size: clamp(11px, 0.95vw, 13px);
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--wc-cream);
  white-space: nowrap;
  padding-block: 6px;
  border-bottom: 2px solid transparent;
}

.wc-navlist a:hover { border-bottom-color: var(--wc-red-ink); }

/* Current page. A red-ink underline on the ground — 3.93, a legal non-text
   boundary — paired with aria-current for anything that is not looking. */
.wc-navlist a[aria-current="page"] {
  border-bottom-color: var(--wc-red-ink);
  color: var(--wc-cream);
}

.wc-navtoggle { position: absolute; opacity: 0; width: 44px; height: 44px; margin: 0; cursor: pointer; z-index: 2; }
.wc-burger { display: none; }

@media (max-width: 899px) {
  .wc-head-in { position: relative; gap: 12px; }

  .wc-navtoggle { display: block; right: var(--wc-gutter); top: 50%; transform: translateY(-50%); }

  .wc-burger {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: auto;
    min-height: 44px;
    padding: 0 2px;
    font-family: var(--wc-mono);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: var(--wc-track-mono);
    text-transform: uppercase;
    color: var(--wc-cream);
    cursor: pointer;
  }

  .wc-burger-bars, .wc-burger-bars::before, .wc-burger-bars::after {
    display: block;
    width: 22px;
    height: 2px;
    background: var(--wc-red-ink);
    content: '';
  }
  .wc-burger-bars { position: relative; }
  .wc-burger-bars::before { position: absolute; top: -7px; }
  .wc-burger-bars::after  { position: absolute; top: 7px; }

  .wc-close-txt { display: none; }
  .wc-navtoggle:checked ~ .wc-burger .wc-open-txt { display: none; }
  .wc-navtoggle:checked ~ .wc-burger .wc-close-txt { display: inline; }

  /* The open state is designed, not merely revealed: a full flat list of the
     same seven links, 44px rows, no accordions, nothing nested, no CTA.
     The socials below are additional and are not nav (J2). */
  .wc-nav {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--wc-ground);
    border-bottom: var(--wc-hair);
    padding: 8px var(--wc-gutter) 24px;
    max-height: calc(100vh - 100%);
    overflow-y: auto;
  }

  .wc-navtoggle:checked ~ .wc-nav { display: flex; }

  .wc-navlist { flex-direction: column; align-items: stretch; gap: 0; }

  .wc-navlist a {
    display: flex;
    align-items: center;
    min-height: 44px;
    font-size: 14px;
    border-bottom: 1px solid var(--wc-red-ink);
    padding-block: 0;
  }
  .wc-navlist a[aria-current="page"] { color: var(--wc-red-ink); }

  /* Socials repeat inside the open panel. */
  .wc-nav-social { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 20px; }
  .wc-nav-social a {
    font-family: var(--wc-mono);
    font-size: 11px;
    letter-spacing: var(--wc-track-mono);
    text-transform: uppercase;
    color: var(--wc-muted);
    text-decoration: none;
    min-height: 44px;
    display: flex;
    align-items: center;
  }
}

@media (min-width: 900px) {
  .wc-nav-social { display: none; }
}

/* THE 900-1100px BAND IS GONE. Removed 2026-08-28 on a measurement, not on
   reasoning (E3, M4).

   It existed to fit EIGHT nav items plus the CTA button in one row: it cut the
   logo to 44px, the links to 10px and every gap, and even then the button
   ended at x=1080 of 1100. The row is now seven items and no button, so the
   arithmetic it was solving no longer describes anything.

   Measured in Chrome on the built page, logo at 96px and all base
   declarations, at innerWidth 900 / 1000 / 1100 — last link right edge vs the
   content edge:

     900px   last link ends x=691, content edge 855   slack 164px   no wrap
     1000px  last link ends x=707, content edge 950   slack 243px   no wrap
     1100px  last link ends x=723, content edge 1045  slack 322px   no wrap

   1100 is continuous with 1101, which was already outside the band and
   measures 723 / 323. So the band was not merely unnecessary, it was creating
   a visible step: the logo jumped 44px -> 96px and the links 10px -> 11px
   across a single pixel of viewport. Deleting it makes the header identical
   from 900px to 1280px.

   The logo is 96px at every width at and above 900px. Nothing scales it above
   that, and --wc-logo-cap is untouched. */

/* --------------------------------------------------------------------------
   HERO
   -------------------------------------------------------------------------- */

.wc-hero { padding-block: clamp(36px, 5vw, 72px) clamp(24px, 2.6vw, 36px); }
.wc-hero .wc-h1 { max-width: 14ch; }

/* The Home hero, reset in Round 1 (2026-09-29) on her note that "Literature
   as Bloodsport" read as the heading. The name is now the H1 and takes .wc-h1
   whole (112 desktop, 34 mobile); the tagline is a <p class="wc-h2"> and takes
   the .wc-h2 step whole (52, 28). Neither size is new and neither is scaled
   by ratio: both are rungs on D2's ladder and the mobile values are the ones
   those two steps already use (M2). One H1 per page (G3).

   A short rule sits between the two lines. --wc-red-ink, NOT the brand
   oxblood: D3 measures oxblood #A81B21 at 2.30:1 on this ground, which reads
   as no edge at all; this token is the 3.93 one for rules on the ground.

   Decorative: a pseudo-element, no DOM node, nothing announced, nothing to
   anchor to. Scoped to the hero so .wc-home-name used elsewhere later does not
   inherit a divider it was never designed for. The H1's margin is 0 and the
   subheading's is zeroed here, so the rule's own margins are the whole gap.

   Below 600px the gaps close to 16px. 28px above and below a 34px H1 opened a
   hole taller than the line itself; width stays 120px. */
.wc-hero .wc-home-sub { margin: 0; }
.wc-hero .wc-home-name::after {
  content: "";
  display: block;
  width: 120px;
  height: 3px;
  margin: 28px 0;
  background: var(--wc-red-ink);
}
@media (max-width: 599px) {
  .wc-hero .wc-home-name::after { margin: 16px 0; }
}

/* --------------------------------------------------------------------------
   NEXT UP
   The single loudest thing after the headline. The failure of the current
   site is that this reads as body text.
   -------------------------------------------------------------------------- */

.wc-next {
  border: var(--wc-hair);
  padding: clamp(24px, 3.5vw, 44px);
}

.wc-next-label {
  font-family: var(--wc-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono-wide);
  text-transform: uppercase;
  color: var(--wc-red-ink);
  margin: 0 0 16px;
}

.wc-next-title {
  font-family: var(--wc-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: var(--wc-track-display);
  line-height: 1;
  font-size: clamp(28px, 5.2vw, 92px);
  overflow-wrap: break-word;
  margin: 0 0 20px;
}

.wc-next-meta {
  list-style: none;
  margin: 0 0 28px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 28px;
  font-family: var(--wc-mono);
  font-size: clamp(12px, 1.2vw, 14px);
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  color: var(--wc-cream);
}

.wc-next-actions { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

.wc-btn {
  display: inline-block;
  background: var(--wc-oxblood);
  color: var(--wc-cream);
  border: 1px solid var(--wc-oxblood);
  font-family: var(--wc-mono);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  text-decoration: none;
  padding: 15px 26px;
  min-height: 44px;
}
.wc-btn:hover { background: var(--wc-ground); border-color: var(--wc-red-ink); }

.wc-btn-ghost {
  background: transparent;
  border: 1px solid var(--wc-red-ink);
  color: var(--wc-cream);
}
.wc-btn-ghost:hover { background: var(--wc-oxblood); border-color: var(--wc-oxblood); }

/* --------------------------------------------------------------------------
   VS GRID
   Three columns, one per bout, each pairing two combatants with their
   opposing topics. On Home it carries the real upcoming lineup; where the
   format is explained it carries bare topic pairs with no names.

   The VS divider is what carries the pairing logic and it must survive the
   restack to a single column.
   -------------------------------------------------------------------------- */

.wc-vs {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0;
  border: var(--wc-hair);
}

.wc-bout {
  padding: clamp(20px, 2.4vw, 32px);
  display: flex;
  flex-direction: column;
}
.wc-bout + .wc-bout { border-left: var(--wc-hair); }

.wc-bout-no {
  font-family: var(--wc-display);
  font-weight: 900;
  font-size: clamp(52px, 8vw, 92px);
  line-height: 0.8;
  letter-spacing: var(--wc-track-display);
  color: var(--wc-red-ink);
  margin: 0 0 20px;
}

.wc-side { display: flex; flex-direction: column; gap: 4px; }

.wc-side-name {
  font-family: var(--wc-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.03em;
  line-height: 1.02;
  font-size: clamp(22px, 2.6vw, 34px);
}

.wc-side-topic {
  font-family: var(--wc-mono);
  font-size: clamp(12px, 1.1vw, 14px);
  font-weight: 500;
  letter-spacing: var(--wc-track-mono-wide);
  text-transform: uppercase;
  color: var(--wc-red-ink);
}

/* A named side keeps its writer and topic together: .wc-side's 4px gap is the
   space between them, which the browser's default <p> margins (1em - 34px at
   the name's size) were swamping the first time a real lineup rendered.
   Scoped to named sides, so a topic-only side (How It Works) is unchanged. */
.wc-side-name { margin: 0; }
.wc-side-name + .wc-side-topic { margin-top: 0; }

/* The divider is the pairing logic made visible. It stays on mobile. */
.wc-vs-div {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-block: 16px;
  font-family: var(--wc-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono-wide);
  text-transform: uppercase;
  color: var(--wc-muted);
}
.wc-vs-div::before, .wc-vs-div::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--wc-red-ink);
}

/* Interim: no announced lineup. Six waiting seats rather than the words "to
   be announced" set six times at display size, which reads as a broken page
   rather than a designed state. A SOLID red-ink edge, so it never reads as a
   [COPY NEEDED] marker, which is dashed. */
.wc-side-slot {
  border: 1px solid var(--wc-red-ink);
  min-height: 74px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 14px;
  text-align: center;
}
.wc-slot-label {
  font-family: var(--wc-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  color: var(--wc-muted);
  margin: 0;
}

@media (max-width: 899px) {
  .wc-vs { grid-template-columns: 1fr; }
  .wc-bout + .wc-bout { border-left: 0; border-top: var(--wc-hair); }
}

/* --------------------------------------------------------------------------
   PRESS
   -------------------------------------------------------------------------- */

/* The word gap belongs to display STATEMENTS the reader is meant to stop on -
   the three headings and this pull-quote - not to the Archivo face itself.
   .wc-next-title, .wc-side-name, .wc-cal-title and .wc-clip-performer are the
   same face but are labels and names, not statements, and stay flat. */
.wc-pull {
  font-family: var(--wc-display);
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: var(--wc-track-display);
  word-spacing: var(--wc-word-display);
  line-height: 1.02;
  font-size: clamp(26px, 4vw, 48px);
  margin: 0 0 18px;
  max-width: 20ch;
}

.wc-pull-src {
  font-family: var(--wc-mono);
  font-size: 12px;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  color: var(--wc-muted);
  margin: 0;
}

.wc-accolades { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.wc-accolades li {
  font-family: var(--wc-mono);
  font-size: clamp(12px, 1.15vw, 14px);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding-block: 14px;
  border-bottom: 1px solid var(--wc-red-ink);
}
.wc-accolades li:first-child { border-top: 1px solid var(--wc-red-ink); }

/* --------------------------------------------------------------------------
   FACT ROWS / CALENDAR
   -------------------------------------------------------------------------- */

.wc-facts { list-style: none; margin: 0; padding: 0; }
.wc-facts li {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 24px;
  padding-block: 16px;
  border-bottom: 1px solid var(--wc-red-ink);
}
.wc-facts li:first-child { border-top: 1px solid var(--wc-red-ink); }

.wc-fact-k {
  font-family: var(--wc-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  color: var(--wc-muted);
  flex: 0 0 190px;
}
.wc-fact-v { flex: 1 1 260px; font-size: 17px; }

.wc-cal { width: 100%; border-collapse: collapse; text-align: left; }
.wc-cal caption { text-align: left; margin-bottom: 20px; color: var(--wc-muted); font-size: 17px; }
.wc-cal th, .wc-cal td {
  padding: 15px 20px 15px 0;
  border-bottom: 1px solid var(--wc-red-ink);
  vertical-align: baseline;
}
.wc-cal th {
  font-family: var(--wc-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  color: var(--wc-muted);
  border-bottom: var(--wc-hair);
}
.wc-cal-date {
  font-family: var(--wc-mono);
  font-size: clamp(12px, 1.2vw, 14px);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}
.wc-cal-title {
  font-family: var(--wc-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  font-size: clamp(17px, 1.9vw, 24px);
  line-height: 1.1;
}
.wc-cal-where { font-family: var(--wc-mono); font-size: 12px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--wc-muted); white-space: nowrap; }

.wc-scroll { overflow-x: auto; }

/* --------------------------------------------------------------------------
   TEAM
   -------------------------------------------------------------------------- */

.wc-team { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0; }
.wc-member { padding: clamp(24px, 3vw, 40px) 0; border-top: 1px solid var(--wc-red-ink); }
.wc-member:nth-child(odd) { padding-right: clamp(24px, 3vw, 48px); }
.wc-member:nth-child(even) { padding-left: clamp(24px, 3vw, 48px); border-left: 1px solid var(--wc-red-ink); }
/* Team photos, carried from Corri's live About page on 2026-09-21 - one per
   person, her choices. The aspect is FORCED rather than natural: the sources
   run from 3:2 landscape to 3:4 portrait, and at natural height the two cards
   in a grid row start their names at different heights, which reads as broken
   rather than as varied. object-position sits above centre because six of the
   eight are performance shots framed with the face in the upper third. */
.wc-member-photo {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center 28%;
  display: block;
  margin: 0 0 clamp(14px, 1.6vw, 20px);
  border: 1px solid var(--wc-red-ink);
}
.wc-member-role {
  font-family: var(--wc-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono-wide);
  text-transform: uppercase;
  color: var(--wc-red-ink);
  margin: 0 0 8px;
}
.wc-member-bio { font-size: 17px; color: var(--wc-muted); margin: 0; }
/* Two people run to a second paragraph - Kyle Hamman always has, and Jill
   Hopkins does since the 2026-09-21 carry. With margin:0 above they ran
   together as one block of text with no break at all. */
.wc-member-bio + .wc-member-bio { margin-top: 0.9em; }

@media (max-width: 767px) {
  .wc-team { grid-template-columns: 1fr; }
  .wc-member:nth-child(odd) { padding-right: 0; }
  .wc-member:nth-child(even) { padding-left: 0; border-left: 0; }
}

/* --------------------------------------------------------------------------
   OXBLOOD BAND — a surface, carrying cream text only. 5.96.
   -------------------------------------------------------------------------- */

.wc-band { background: var(--wc-oxblood); color: var(--wc-cream); }
.wc-band .wc-eyebrow,
.wc-band .wc-muted,
.wc-band .wc-pull-src { color: var(--wc-cream); }
.wc-band a { color: var(--wc-cream); }

/* --------------------------------------------------------------------------
   PHOTO BAND
   No text sits over photography anywhere in this build: a text-on-image pair
   is not in the contrast table and cannot be measured.
   -------------------------------------------------------------------------- */

/* The banner is one flat image, full-bleed, and the two sources have DIFFERENT
   aspect ratios - 6:1 at desktop, 3:1 on the mobile source. So no height is
   forced here: height comes from each source's own ratio.

   The previous rule pinned height to clamp(140px, 22vw, 300px), which would
   crop whichever source was showing to a shape neither of them is. */
.wc-photo { border-block: var(--wc-hair); line-height: 0; }
.wc-photo picture { display: block; }
.wc-photo img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
}

/* --------------------------------------------------------------------------
   COPY NEEDED
   A visible, specific request to the client. Not a placeholder, and not
   filler of any kind — this is meant to be read.
   -------------------------------------------------------------------------- */

.wc-needed {
  display: block;
  border: 1px dashed var(--wc-red-ink);
  padding: 18px 20px;
  font-family: var(--wc-mono);
  font-size: clamp(12px, 1.2vw, 14px);
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--wc-red-ink);
  max-width: var(--wc-measure);
}
.wc-needed + .wc-needed { margin-top: 16px; }

/* --------------------------------------------------------------------------
   FOOTER
   Load-bearing, not decorative: it is the only place FAQ, Sponsors and
   Contact appear in global navigation. 18 anchors on every page: 11 linked
   pages, 6 socials, 1 address.
   -------------------------------------------------------------------------- */

/* Layout only. Oxblood surface, cream text — 5.96:1, the §D3-legal pair, and
   it does not change. Two anchors came out on 2026-08-27 — News (F5) and
   booking@ (J4) — and the columns were REBALANCED, not redesigned: the
   height win came from the one-band five-column shape, not from the
   distribution. The old shape stacked two three-column bands and split the
   socials into two columns of three, which cost roughly 250px on desktop
   and made the mobile footer taller than a phone screen. */

.wc-foot { background: var(--wc-oxblood); color: var(--wc-cream); margin-top: 0; }
.wc-foot-in { padding-block: clamp(36px, 3.4vw, 52px); }

/* One band: brand, then the four link groups. */
.wc-foot-grid {
  display: grid;
  /* Get In Touch gets a wider track: info@writeclubnation.com is 24
     unbreakable characters and a 1fr column cannot hold it. Paired with
     overflow-wrap: anywhere on the list links below. */
  grid-template-columns: minmax(0, 1.15fr) repeat(3, minmax(0, 0.85fr)) minmax(0, 1.35fr);
  gap: clamp(20px, 2.2vw, 36px);
}

.wc-foot-brand .wc-logo { width: 96px; margin-bottom: 14px; }
.wc-foot-tag {
  font-family: var(--wc-mono);
  font-size: 12px;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  margin: 0 0 6px;
}

.wc-foot-h {
  font-family: var(--wc-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono-wide);
  text-transform: uppercase;
  margin: 0 0 10px;
}

.wc-foot-list { list-style: none; margin: 0; padding: 0; }
.wc-foot-list li { margin: 0; }
.wc-foot-list li { min-width: 0; }
.wc-foot-list a {
  display: flex;
  align-items: center;
  min-height: 28px;
  overflow-wrap: anywhere;
  font-family: var(--wc-mono);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--wc-cream);
  text-decoration: none;
}
.wc-foot-list a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Bottom bar: socials left, the venue line right. */
.wc-foot-bot {
  margin-top: clamp(24px, 2.6vw, 40px);
  padding-top: 18px;
  border-top: 1px solid var(--wc-cream);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px 40px;
  font-family: var(--wc-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.wc-foot-bot a { color: var(--wc-cream); }

/* Six socials, one horizontal row. */
.wc-foot-social {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 0 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
}
.wc-foot-social a {
  display: flex;
  align-items: center;
  min-height: 30px;
  color: var(--wc-cream);
  text-decoration: none;
}
.wc-foot-social a:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Takes whatever the socials leave and wraps inside itself, so the venue line
   stays on the right rather than dropping to a row of its own. */
.wc-foot-legal {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 22px;
  margin: 0;
  justify-content: flex-end;
  text-align: right;
}

@media (max-width: 899px) {
  /* Fit as many link columns as the width allows rather than dropping straight
     to one. Four stacked lists is what made this 1469px at 390. */
  .wc-foot-grid { grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); }
  .wc-foot-brand { grid-column: 1 / -1; }
  /* 44px is the touch standard J2 already sets for the nav panel; a footer
     link is the same thumb. Desktop stays at 28px, a mouse target, which
     clears the WCAG 2.2 AA 24x24 minimum. */
  .wc-foot-list a { min-height: 44px; }
  .wc-foot-bot { justify-content: flex-start; }
  .wc-foot-social { flex: 1 1 100%; }
  .wc-foot-social a { min-height: 44px; }
  .wc-foot-legal { flex: 1 1 100%; justify-content: flex-start; text-align: left; }
}

/* --------------------------------------------------------------------------
   WATCH
   Facade embeds. A hotlinked thumbnail inside a real anchor to YouTube; JS
   swaps in a nocookie player on click. Nothing here loads a player bundle
   until someone asks for one, which matters for a mostly-mobile audience.

   The page carries the two most recent shows, clips only (K11).

   No view counts anywhere. They are never fetched, so they cannot appear.
   -------------------------------------------------------------------------- */

.wc-show-head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px 32px;
  margin-bottom: clamp(24px, 3vw, 40px);
}
.wc-show-head .wc-h2 { margin: 0; }

.wc-show-all {
  font-family: var(--wc-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  color: var(--wc-cream);
  text-decoration: none;
  border-bottom: 1px solid var(--wc-red-ink);
  padding-bottom: 3px;
  white-space: nowrap;
}
.wc-show-all:hover { color: var(--wc-cream); border-bottom-color: var(--wc-cream); }

.wc-clips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: clamp(20px, 2.4vw, 34px);
}

.wc-clip-a {
  display: flex;
  flex-direction: column;
  gap: 12px;
  text-decoration: none;
  color: var(--wc-cream);
}

.wc-clip-thumb {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: var(--wc-hair);
  background: var(--wc-ground);
}
/* The source is 480x360 (4:3) with letterboxing; cover crops the bars out. */
.wc-clip-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.wc-clip-play {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: var(--wc-oxblood);
  display: flex;
  align-items: center;
  justify-content: center;
}
.wc-clip-play::after {
  content: '';
  border-left: 16px solid var(--wc-cream);
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
  margin-left: 4px;
}
.wc-clip-a:hover .wc-clip-play { background: var(--wc-ground); }
.wc-clip-a:hover .wc-clip-thumb { border-color: var(--wc-cream); }

/* Solid ground behind the duration, so the pair stays cream-on-ground rather
   than cream-on-photograph, which is not a measurable pair. */
.wc-clip-dur {
  position: absolute;
  right: 8px;
  bottom: 8px;
  background: var(--wc-ground);
  color: var(--wc-cream);
  font-family: var(--wc-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  padding: 3px 7px;
}

.wc-clip-label { display: flex; flex-direction: column; gap: 4px; }

.wc-clip-performer {
  font-family: var(--wc-display);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  line-height: 1.1;
  font-size: clamp(17px, 1.6vw, 21px);
}

/* The topic is stored sentence case. The uppercase is presentation only.
   Muted rather than red-ink: red-ink is large display type only (D3). */
.wc-clip-topic {
  font-family: var(--wc-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  color: var(--wc-muted);
}

/* Player swapped in on click. */
.wc-clip-frame { position: relative; aspect-ratio: 16 / 9; border: var(--wc-hair); }
.wc-clip-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

/* A show with one or two clips. auto-fill leaves them hard left in a
   four-column track, which reads as broken; centred reads as deliberate.
   The newest show is the likeliest to be short — she uploads over weeks —
   and with two sections on the page this is half of it, not an edge case.
   The order is never changed to avoid it. */
.wc-clips-few {
  grid-template-columns: repeat(auto-fit, minmax(260px, 340px));
  justify-content: center;
}

@media (max-width: 480px) {
  .wc-clips { grid-template-columns: 1fr; }
  .wc-clips-few { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------------------
   PULLED QUOTE INSIDE BODY COPY
   Not .wc-pull, which is large display type on its own band. This is a long
   prose quotation that has to stay readable at body size: the Belknap
   passage on How It Works runs ~140 words and cannot be set in Archivo 900.

   Cream, not muted: at this length it is primary reading, and italic already
   carries the attribution signal. 13.72 on ground.
   -------------------------------------------------------------------------- */

.wc-quote {
  margin: clamp(28px, 3vw, 40px) 0 0;
  padding-left: clamp(18px, 2vw, 28px);
  border-left: 2px solid var(--wc-red-ink);
  max-width: var(--wc-measure);
}
.wc-quote p {
  margin: 0;
  font-size: clamp(16px, 1.6vw, 19px);
  line-height: 1.6;
  font-style: italic;
  color: var(--wc-cream);
}

/* --------------------------------------------------------------------------
   BODY BULLETS
   Donate's three ways to help. Marker is red-ink, which is legal here
   because it is a rule, not type (D3 header note).
   -------------------------------------------------------------------------- */

.wc-bullets { list-style: none; margin: 1.15em 0 0; padding: 0; }
.wc-bullets li {
  position: relative;
  padding-left: 26px;
  margin-bottom: 0.9em;
  font-size: 17px;
  line-height: 1.55;
}
.wc-bullets li:last-child { margin-bottom: 0; }
.wc-bullets li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 14px;
  height: 2px;
  background: var(--wc-red-ink);
}
.wc-bullets a { color: var(--wc-cream); text-decoration: underline; text-underline-offset: 3px; }
.wc-bullets strong { font-weight: 700; }

/* --------------------------------------------------------------------------
   FOOTNOTE
   The "*except for special shows" line under the WRITE CLUB IS table. Muted
   rather than red-ink: small type, so red-ink is not available (D3).
   -------------------------------------------------------------------------- */

.wc-footnote {
  font-family: var(--wc-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  color: var(--wc-muted);
  margin: 18px 0 0;
}

/* --------------------------------------------------------------------------
   ACCOLADE LINES, AS GIVEN
   Three award citations arrived run together on one line in the client's copy
   doc and are reproduced that way verbatim. The line wraps rather than
   scrolls; .wc-accolades already handles the row, this only relaxes the
   nowrap-ish tight tracking so a long run-on stays readable.
   -------------------------------------------------------------------------- */

.wc-accolades li.wc-accolade-run { letter-spacing: 0.06em; line-height: 1.65; }

/* --------------------------------------------------------------------------
   EMBED SLOTS — forms and map
   A slot is the container an external embed drops into later. Until its URL
   exists (data/forms.json, per form) the slot carries a dashed marker and
   occupies no fake height, so the page does not show a grey rectangle
   pretending to be a form.

   Set, a Google Form renders in .wc-form: an oxblood mat with a red-ink edge,
   so the form's own white page reads as a card set into the design rather
   than a hole cut in it. The mat is the design's surface red, and the cream
   the form sits on is never text on oxblood, so D3 is untouched. Markup and
   both states are in data/README.md.

   The iframe is width-100% with its height set on the element rather than an
   aspect box: a Google Form's height is content-driven and an aspect box
   crops it. min-width: 0 and the thin mobile mat keep it inside 390px with
   no horizontal scroll. The fallback link under it reuses .wc-map-link.
   These rules are dormant until the first URL lands - built now so the panel
   could be tested at 390px, not left for whoever pastes the URL.
   -------------------------------------------------------------------------- */

.wc-slot { max-width: var(--wc-measure); }
.wc-form {
  min-width: 0;
  background: var(--wc-oxblood);
  border: var(--wc-hair);
  padding: clamp(6px, 1.4vw, 16px);
}
.wc-form iframe {
  display: block;
  width: 100%;
  border: 0;
  background: var(--wc-cream);
}

/* The map is a fixed-ratio place, not a form, so it does take an aspect box. */
.wc-map { max-width: var(--wc-measure); }
.wc-map iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 10;
  border: var(--wc-hair);
  background: var(--wc-ground);
}
/* Sits immediately below the map and is the whole point of the pair: with the
   iframe blocked, this is still a working route to the venue. */
.wc-map-link {
  font-family: var(--wc-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  margin: 16px 0 0;
}
.wc-map-link a { color: var(--wc-cream); text-decoration: underline; text-underline-offset: 3px; }

/* --------------------------------------------------------------------------
   PAST SHOWS — THE OFF-VENUE NOTE
   past[] rows show a venue only when it is not GMan Tavern; the caption
   carries the default. A whole column would sit empty on fifteen of sixteen
   rows and read as missing data, so the exception is noted inline instead.

   Mono and muted against the Archivo display title beside it, so it reads as
   an annotation rather than part of her show name.
   -------------------------------------------------------------------------- */

.wc-cal-venue {
  display: inline-block;
  font-family: var(--wc-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  color: var(--wc-muted);
  border: 1px solid var(--wc-red-ink);
  padding: 2px 7px;
  margin-left: 8px;
  vertical-align: middle;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   SHOW INFO — THE NEXT SHOW (Round 1, 2026-09-29)
   The hero leads with shows[0]: its title as the H1, then its own show title,
   then date / time / venue on the Next Up meta row Home already uses, then
   the door line. Only spacing is new here; every face is an existing step.
   -------------------------------------------------------------------------- */

.wc-hero .wc-si-show { margin: 24px 0 20px; }
.wc-hero .wc-next-meta { margin-bottom: 20px; }

/* Her description beside her event poster, stacked below 900px. The poster
   is a 1080 square; 420px is enough to read its type without letting it
   out-mass her words. */
.wc-si-desc {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  gap: clamp(32px, 5vw, 72px);
  align-items: start;
}
.wc-si-poster { width: 100%; border: var(--wc-hair); }
@media (max-width: 899px) {
  .wc-si-desc { grid-template-columns: minmax(0, 1fr); }
  .wc-si-poster { max-width: 420px; }
}

/* A show's own title under its calendar name, as a quieter second line. */
.wc-cal-show {
  display: block;
  margin-top: 6px;
  font-family: var(--wc-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  color: var(--wc-muted);
}

/* --------------------------------------------------------------------------
   FAQ
   Her questions on the .wc-h3 step, answers as .wc-body paragraphs. The only
   thing added is the gap that separates one question from the answer above
   it; without it a question sits closer to the previous answer than to its
   own.
   -------------------------------------------------------------------------- */

.wc-faq .wc-h3 { margin-top: clamp(36px, 4vw, 56px); }
.wc-faq .wc-h3:first-child { margin-top: 0; }

/* --------------------------------------------------------------------------
   GALLERY
   55 photographs from data/gallery.json, in manifest order. Each thumb is a
   real anchor to its full-size WebP, opened in a new tab: no lightbox, no
   modal, no JS. The grid works with JavaScript off.

   Breakpoints reuse the ones already in this file — 900 and 480 — rather than
   introducing a third set: 4 columns, 2, then 1.
   -------------------------------------------------------------------------- */

/* The blanket credit, once, attached to the grid rather than to any photo.
   Driven by gallery.json's top-level credit/creditUrl. */
.wc-gal-by {
  font-family: var(--wc-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  color: var(--wc-muted);
  margin: 0 0 clamp(20px, 2.4vw, 32px);
}
.wc-gal-by a { color: var(--wc-cream); text-decoration: underline; text-underline-offset: 3px; }

.wc-gal {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(10px, 1.2vw, 18px);
}

@media (max-width: 899px) { .wc-gal { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 479px) { .wc-gal { grid-template-columns: 1fr; } }

/* Each cell carries an id so it can be linked to directly. The header is
   sticky and 120px tall at every breakpoint, so without this a link to a cell
   lands the photograph BEHIND the header. Measured, not estimated.

   The lightbox no longer closes to these ids - it closes to a non-matching
   fragment so the page does not move at all - but a shared or bookmarked
   #g-<id> link must still arrive somewhere legible. */
.wc-gal-item { margin: 0; min-width: 0; scroll-margin-top: 136px; }

/* Uniform cells. 3/2 is the majority shape in the archive — 53 of 55 are
   landscape at roughly that ratio — so it crops least. The two portraits crop
   to the same box rather than letterboxing, which is the instruction: the
   photograph covers the cell. */
.wc-gal-a {
  display: block;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border: var(--wc-hair);
  background: var(--wc-ground);
  line-height: 0;
}
/* ANCHOR THE CROP TO THE TOP OF THE PHOTOGRAPH.
   cover defaults to object-position: 50% 50%, which trims equally from top
   and bottom. 28 of the 55 are taller than the 3/2 cell and the two portraits
   lose 46.7% of their height — centred, roughly 23% of that comes off the
   top, which is where heads, faces and raised hands are. Top-anchored, the
   whole loss comes off the bottom (floor, tables, foreground) instead. */
.wc-gal-a img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 0;
  display: block;
}
.wc-gal-a:hover { border-color: var(--wc-cream); }

/* PER-PHOTO CREDIT — a deliberate exception to the no-orphaned-rules rule.
   Every photo in the manifest today has an empty `credit` and falls under the
   blanket line above, so this renders on nothing and the rule is unused.
   It stays anyway: the archive holds more than one photographer, and this is
   the mechanism that stops a photo being attributed to the wrong person. A
   value appearing in the manifest must render correctly and styled the moment
   it lands, not after someone remembers to add CSS. Attribution outranks
   stylesheet hygiene here. */
.wc-gal-credit {
  font-family: var(--wc-mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  color: var(--wc-muted);
  margin: 8px 0 0;
}

/* --------------------------------------------------------------------------
   LIGHTBOX — CSS ONLY, DRIVEN BY :target
   No JavaScript, no library. A thumb is an anchor to #lb-<id>; the close
   control and the backdrop are both anchors back to #g-<id>, that photo's own
   grid cell, so closing returns the reader to where they were. The browser's
   back button steps out for free because this is a fragment — nothing here
   interferes with history.

   No body scroll-locking. That needs either JS or an overflow trick that
   scrolls the page to the top on close, which is the bug this design avoids.
   -------------------------------------------------------------------------- */

/* display:none, NOT opacity or visibility. While closed the overlay is
   invisible, inert, unfocusable and absent from the accessibility tree, and
   its 1600px photograph is never fetched. Both matter: 55 full sizes are
   6.4 MB, and a lightbox that pulls that up front is worse than none. */
.wc-lb { display: none; }

/* TWO WAYS IN, AND THEY CANNOT FIGHT.
   Without script, :target opens the overlay - the mechanism the whole gallery
   is built on, and it keeps working with JavaScript disabled.
   With script, js/wc-gallery.js sets .wc-js on <html> and drives .is-open
   instead. That scoping is what stops both matching at once: mid-browse the
   fragment and the open overlay disagree, because arrows use replaceState and
   browsers do not reliably re-evaluate :target after one. If the :target rule
   were unscoped, two overlays would stack. */
html:not(.wc-js) .wc-lb:target,
.wc-lb.is-open {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 200;
  align-items: center;
  justify-content: center;
  padding: clamp(12px, 3vw, 40px);
}

/* The backdrop IS the close link, so clicking anywhere around the photograph
   dismisses it. tabindex="-1" + aria-hidden keep it out of the focus order and
   the accessibility tree: it is a pointer affordance only, and the real
   "Close" link below carries the accessible name. Without tabindex="-1" an
   aria-hidden focusable link would be a genuine a11y fault. */
.wc-lb-back {
  position: absolute;
  inset: 0;
  background: rgba(10, 9, 8, 0.94);
  cursor: pointer;
}

/* THE FRAME — exactly as wide as the rendered photograph.
   width:fit-content is what lets the close button be anchored to the IMAGE's
   corner instead of the window's. Above the backdrop in stacking order, so
   the photograph is not itself a close target.

   The full size is painted here as a background: an <img loading="lazy">
   inside a display:none subtree has no layout box, so Chrome cannot tell it
   is off-screen and fetches all of them on page load. Measured, not assumed.
   background-size contain shows the whole frame - the grid's cover-crop
   deliberately does not apply here. */
.wc-lb-frame {
  position: relative;
  z-index: 1;
  width: fit-content;
  max-width: 100%;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  background-color: var(--wc-ground);
  border: var(--wc-hair);
  line-height: 0;
}

/* The already-cached THUMB, carried only to give the frame the photograph's
   exact rendered size. It costs no extra request.

   opacity:0, NOT visibility:hidden: opacity keeps the element in the
   accessibility tree, so its alt - the real one, from the manifest - is still
   announced. visibility:hidden would silence it. The full-size background
   paints straight through. With CSS disabled it becomes a real, visible
   photograph, so a thumb link without CSS still resolves to actual content. */
/* SIZED FROM THE MANIFEST, NOT FROM THE DECODED FILE.
   The frame is width: fit-content and a background-image has no intrinsic
   size, so the only thing the frame can measure is this img. While it sized
   itself from its natural dimensions, a thumb whose request was aborted -
   complete: true, naturalWidth 0, never retried - collapsed the frame to its
   alt-text box, and the photograph then painted from the background at the
   wrong size with nothing reporting an error.
   --lb-w / --lb-h come from gallery.json's w/h, stamped on the frame. They
   are definite before any byte is fetched, so no load failure can move the
   layout. The three terms are the old constraints, unchanged: the photo's own
   width, the container, and the 74vh height cap that height-caps portraits. */
.wc-lb-frame img {
  opacity: 0;
  display: block;
  width: min(calc(var(--lb-w) * 1px), calc(74vh * var(--lb-w) / var(--lb-h)));
  aspect-ratio: var(--lb-w) / var(--lb-h);
  height: auto;
  /* Container clamp stays a separate max-width, NOT a term inside the min()
     above. The frame is width: fit-content, so a percentage inside the width
     min() resolves against an indefinite containing block and the whole
     function degrades to the natural-size path - which is the failure this
     rule exists to remove. As max-width it resolves in the later layout pass
     and behaves. */
  max-width: 100%;
}

/* CLOSE — anchored to the photograph's top-right corner, not the viewport's.
   It sits just inside the corner and overlaps the image edge, so it reads as
   that image's control however small the photograph is.

   Cream on oxblood, 5.96:1 - the D3-legal pair. The button carries its own
   solid surface, so no text ever sits on photography (the .wc-clip-dur
   precedent on Watch).

   44x44 minimum tap target. Held INSIDE the frame rather than offset outward,
   which is what guarantees it can never be clipped off the top or right edge
   at 390px, where the overlay's padding is only 12px.

   The visible word CLOSE is the accessible name; no aria-label is needed or
   present. The global :focus-visible ring applies unchanged. */
.wc-lb-close {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 16px;
  font-family: var(--wc-mono);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: var(--wc-track-mono);
  text-transform: uppercase;
  line-height: 1;
  color: var(--wc-cream);
  text-decoration: none;
  background: var(--wc-oxblood);
  border: 1px solid var(--wc-oxblood);
}
.wc-lb-close:hover { background: var(--wc-ground); border-color: var(--wc-red-ink); }

@media (prefers-reduced-motion: no-preference) {
  html:not(.wc-js) .wc-lb:target,
  .wc-lb.is-open { animation: wc-lb-in 120ms ease-out; }
  @keyframes wc-lb-in { from { opacity: 0; } to { opacity: 1; } }
}

/* The overlay set is a grouping wrapper only and must never contribute a box
   of its own to the section's flow. display:contents guarantees that: the 55
   overlays are display:none when closed and position:fixed when open, so the
   wrapper has no reason to exist in layout. */
.wc-lb-set { display: contents; }

/* PREV / NEXT — siblings of CLOSE visually, positioned against the OVERLAY.
   CLOSE is anchored to the frame because it belongs to that photograph. The
   arrows belong to the sequence, so they are pinned to the viewport instead:
   same place on screen for every photo, whatever its shape.

   Anchored to the frame they drifted with each image's aspect ratio - a
   portrait pulled them inward and down, a landscape pushed them outward and
   up - so they never sat still while a reader arrowed through.

   .wc-lb is position:fixed inset:0, so these offsets are viewport offsets.
   z-index 3 puts them above the backdrop (0) and the frame (1), which matters
   at narrow widths where the photograph reaches the screen edges and the
   arrows necessarily sit over it.

   Fill, border, family and colour are CLOSE's exactly. The glyph is 24px
   because a 12px chevron inside a 44px target is illegible, and tracking is
   normal because --wc-track-mono adds trailing space to a single character
   and pushes it off-centre.

   The glyphs are decorative; each link carries aria-label as its real name. */
.wc-lb-prev,
.wc-lb-next {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  font-family: var(--wc-mono);
  font-size: 24px;
  font-weight: 500;
  letter-spacing: normal;
  line-height: 1;
  color: var(--wc-cream);
  text-decoration: none;
  background: var(--wc-oxblood);
  border: 1px solid var(--wc-oxblood);
}

/* TUCKED BESIDE THE IMAGE, STILL STATIC.
   Measured from the CENTRE, not the viewport edge, so the arrows sit just
   outside the widest a photograph can render rather than out at the screen
   edge. Edge-anchored they left a ~170px gap beside an 800px photo at 1280.

   --wc-lb-reach is half the widest rendered photograph plus the gap. 800px is
   a hard cap, not a guess: the overlay <img> is the 800px thumb and it is
   sized width:auto, so nothing renders wider. Tall photos render NARROWER
   (max-height:74vh), and a static arrow cannot hug those too - that is the
   cost of not moving, which is what was asked for.

   max() clamps to a safe edge inset on small screens, where 50% - reach goes
   negative and would push the arrow off-screen. Both values depend only on
   the viewport, so the position is identical for all 56 photographs. */
.wc-lb-prev,
.wc-lb-next { --wc-lb-reach: calc(400px + 12px + 44px); }
.wc-lb-prev { left: max(6px, calc(50% - var(--wc-lb-reach))); }
.wc-lb-next { right: max(6px, calc(50% - var(--wc-lb-reach))); }
.wc-lb-prev:hover,
.wc-lb-next:hover { background: var(--wc-ground); border-color: var(--wc-red-ink); }

/* NEIGHBOUR WARM-UP. Carries the previous and next full sizes as background
   images so an arrow click is not a cold fetch.

   It must be RENDERED to fetch, so it cannot be display:none - but it is 1px,
   transparent, inert and aria-hidden. It sits inside .wc-lb, which IS
   display:none until :target, so opening one photo fetches exactly its two
   neighbours and nothing else. Measured: 3 full sizes per open, never 56. */
.wc-lb-pre {
  position: absolute;
  left: 0;
  top: 0;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
  background-repeat: no-repeat;
}
