/* ─────────────────────────────────────────────────────────────
   Fonts — self-hosted, latin subset. Block copied verbatim from
   brand/BRAND.md. No runtime CDN request.
   ───────────────────────────────────────────────────────────── */
@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('/assets/fonts/space-grotesk-latin-var.woff2') format('woff2');
}

@font-face {
  font-family: 'Anton';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/fonts/anton-latin.woff2') format('woff2');
}

@font-face {
  font-family: 'Roboto';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/roboto-latin-var.woff2') format('woff2');
}

/* ── Tokens ─────────────────────────────────────────────────── */
:root {
  /* palette — brand/BRAND.md, sampled values only */
  --ink: #060404;
  --paper: #eeeadc;
  --blood: #c52d18;
  --sand: #7d7663;
  --midnight: #12122f;
  --rust: #883635;

  /* derived surfaces: base → elevated → floating */
  --surface-1: color-mix(in srgb, var(--ink) 94%, var(--paper));
  --surface-2: color-mix(in srgb, var(--ink) 89%, var(--paper));
  --surface-3: color-mix(in srgb, var(--midnight) 82%, var(--paper));
  --hairline: color-mix(in srgb, var(--sand) 34%, transparent);
  --hairline-strong: color-mix(in srgb, var(--sand) 62%, transparent);
  --muted: color-mix(in srgb, var(--paper) 62%, var(--ink));

  /* layered, colour-tinted shadows */
  --lift-1: 0 1px 0 color-mix(in srgb, var(--paper) 8%, transparent),
            0 8px 20px -10px color-mix(in srgb, var(--ink) 90%, transparent);
  --lift-2: 0 1px 0 color-mix(in srgb, var(--paper) 10%, transparent),
            0 12px 28px -14px rgba(6, 4, 4, .9),
            0 26px 60px -34px color-mix(in srgb, var(--midnight) 88%, transparent);
  --lift-blood: 0 10px 26px -12px color-mix(in srgb, var(--blood) 55%, transparent),
                0 2px 0 color-mix(in srgb, var(--ink) 70%, transparent);

  /* spacing scale */
  --s1: .375rem; --s2: .75rem; --s3: 1.25rem; --s4: 2rem;
  --s5: 3rem;    --s6: 4.5rem; --s7: 7rem;
  --pad-section: clamp(4.25rem, 8vw, 7.5rem);
  --gutter: clamp(1.25rem, 4.5vw, 3.5rem);
  --measure: 62ch;
  --shell: 1280px;

  --ease: cubic-bezier(.2, .8, .26, 1);
  --dur: .42s;

  /* Monochrome photo discipline — every photograph on the page runs
     through this. Red stays the only colour on screen. The two documented
     exceptions are the SVG logo lockup (never filtered) and the lightbox
     full view (colour returns when a photo is opened). */
  --bw: grayscale(1) contrast(1.07) brightness(.93);

  /* Training tiles run hotter than the site default: harder mid-contrast
     and a deeper foot so the four photographs carry real weight. Hover
     brings the colour back — the one place on the page a photograph does. */
  --tt-bw: grayscale(1) contrast(1.34) brightness(.84) saturate(0);
  --tt-color: grayscale(0) contrast(1.16) brightness(1.02) saturate(1.16);
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 5.5rem;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: 'Roboto', -apple-system, 'Segoe UI', sans-serif;
  font-size: clamp(1rem, .96rem + .2vw, 1.0625rem);
  line-height: 1.7;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* film grain — inline SVG noise, no external request */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  opacity: .05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

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

h1, h2, h3, .display {
  font-family: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1.03;
  letter-spacing: -.02em;
  margin: 0;
}

p { margin: 0 0 var(--s3); max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

a { color: inherit; }

::selection { background: var(--blood); color: var(--paper); }

:focus-visible {
  outline: 2px solid var(--blood);
  outline-offset: 3px;
  border-radius: 2px;
}

.shell {
  /* The old `width: min(100% - (var(--gutter) * 2), var(--shell))` was dropped
     inside .section (a column flex container), collapsing the gutter to zero
     and running body copy into the viewport edge. Padding-based gutters hold
     in every container type. Content width stays 1280px with 56px gutters. */
  width: 100%;
  max-width: calc(var(--shell) + var(--gutter) * 2);
  padding-inline: var(--gutter);
  margin-inline: auto;
  align-self: center;
}

.section {
  padding-block: var(--pad-section);
  position: relative;
  /* full-screen panel, Fenriz-style; content-heavy sections may spill */
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.section > * { width: 100%; }
.section--slim { min-height: 0; }
.section--tint { background: var(--surface-1); }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: absolute;
  left: var(--s3);
  top: -4rem;
  z-index: 100;
  background: var(--blood);
  color: var(--paper);
  padding: var(--s2) var(--s3);
  font-weight: 700;
  transition: transform var(--dur) var(--ease);
}
.skip:focus { transform: translateY(5rem); }

/* ── Utility type ───────────────────────────────────────────── */
.eyebrow {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--sand);
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin: 0 0 var(--s3);
}
.eyebrow::before {
  content: '';
  width: 1.75rem;
  height: 2px;
  background: var(--blood);
  flex: none;
}

.lead {
  font-size: clamp(1.0625rem, 1rem + .45vw, 1.3125rem);
  line-height: 1.62;
  color: color-mix(in srgb, var(--paper) 88%, var(--ink));
}

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

/* the ropes — three-line divider, taken from the ring itself */
.ropes {
  height: 15px;
  border-top: 1px solid var(--hairline);
  border-bottom: 1px solid var(--hairline);
  position: relative;
}
.ropes::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 6px;
  height: 2px;
  background: linear-gradient(90deg, var(--blood) 0 22%, var(--hairline-strong) 22% 100%);
}

/* ── Placeholders — must never ship unnoticed ───────────────── */
.confirm {
  display: inline-flex;
  align-items: center;
  gap: .4em;
  background: #ffe200;
  color: #0a0a0a;
  font-family: 'Roboto', sans-serif;
  font-weight: 700;
  font-size: .8125em;
  line-height: 1.25;
  letter-spacing: .04em;
  text-transform: uppercase;
  padding: .3em .6em;
  border: 2px solid #0a0a0a;
  box-shadow: 3px 3px 0 #0a0a0a;
  text-wrap: balance;
}
.confirm svg { width: 1.05em; height: 1.05em; flex: none; margin-top: .1em; }
/* the text needs its own box, or it sits at max-content and overflows */
.confirm i { font-style: normal; min-width: 0; }
.confirm--block { display: flex; width: fit-content; max-width: 100%; align-items: flex-start; }

/* ── Buttons ────────────────────────────────────────────────── */
.btn {
  --btn-bg: var(--blood);
  --btn-fg: var(--paper);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .6em;
  padding: .9rem 1.6rem;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-weight: 700;
  font-size: .9375rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  text-decoration: none;
  border: 2px solid var(--btn-bg);
  border-radius: 2px;
  cursor: pointer;
  box-shadow: var(--lift-blood);
  transition: transform var(--dur) var(--ease),
              background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
.btn svg { width: 1.15em; height: 1.15em; flex: none; }
.btn:hover { --btn-bg: var(--rust); transform: translateY(-2px); box-shadow: var(--lift-2); }
.btn:active { transform: translateY(1px); box-shadow: none; }

.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--paper);
  border-color: var(--hairline-strong);
  box-shadow: none;
}
.btn--ghost:hover {
  --btn-bg: transparent;
  --btn-fg: var(--paper);
  border-color: var(--paper);
  box-shadow: inset 0 0 0 100px color-mix(in srgb, var(--paper) 8%, transparent);
}

/* ── Nav ────────────────────────────────────────────────────── */
.nav {
  position: fixed;
  inset: 0 0 auto;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: var(--s4);
  /* Tighter block padding: the 56px mark sets the bar's height — with the
     old 20px padding the whole header grew. 10px keeps the bar at ~76px,
     slimmer than before the logo change, logos untouched. */
  padding: .625rem var(--gutter);
  background: linear-gradient(180deg, rgba(6, 4, 4, .82), rgba(6, 4, 4, 0));
  transition: background-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.nav.scrolled {
  background: color-mix(in srgb, var(--ink) 92%, transparent);
  backdrop-filter: blur(10px);
  box-shadow: 0 1px 0 var(--hairline), var(--lift-1);
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--s2);
  text-decoration: none;
  margin-right: auto;
  min-width: 0;
}
.brand img { height: 56px; width: auto; flex: none; }
.nav-word {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  line-height: 0;
}
.nav-word img { height: 44px; width: auto; }
.burger {
  margin-left: auto;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: transparent;
  color: var(--paper);
  cursor: pointer;
  transition: border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.burger svg { width: 22px; height: 22px; }
.burger:hover { border-color: var(--paper); }
.burger:focus-visible { outline: 2px solid var(--blood); outline-offset: 2px; }
.burger:active { transform: scale(.94); }
@media (max-width: 560px) {
  .brand img { height: 48px; }
  .nav-word img { height: 32px; }
}
/* ── Hero — built like a Thai fight poster ──────────────────── */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  /* stretch, not center: headline rides the top, .hero-bottom pins low */
  align-items: stretch;
  padding-block: 9rem var(--s5);
  overflow: hidden;
  isolation: isolate;
}
.hero-media { position: absolute; inset: 0; z-index: -2; }
/* camera: the motion layer settles and shakes this box; the photo inside
   keeps its own scroll drift */
.hero-cam { position: absolute; inset: 0; }
/* Scrim — PHONES/TABLETS ONLY. On small screens the crop puts bright pads
   and banners behind the lead text. Desktop is untouched by explicit
   instruction (Leo, 2026-08-26): photo as shot, no overlay. */
@media (max-width: 1023px) {
  .hero-media::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(6,4,4,.55) 0%, rgba(6,4,4,.28) 30%, rgba(6,4,4,.62) 62%, rgba(6,4,4,.9) 100%);
  }
}

/* Crop favours the right of the frame: Thewaritnoi on the pads — the champ
   the headline names. At 38% the window sat on the poster wall instead. */
.hero-media img { width: 100%; height: 100%; object-fit: cover; object-position: 90% 30%; }
/* gradient divider strip — the brand's signature bar, in reds */
.strip {
  height: 7px;
  border: 0;
  margin: 0;
  background: linear-gradient(90deg, var(--rust), var(--blood) 45%, #d96a2b 100%);
}

/* the global .shell align-self:center would re-centre the hero column —
   here it must fill the section so the bottom group can pin */
.hero .shell { align-self: stretch; }
.poster { display: flex; flex-direction: column; gap: var(--s4); }
.hero-bottom {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}
.hero-bottom p { margin: 0; }
.poster-type i, .poster-rule, .lead { text-shadow: 0 2px 18px rgba(6,4,4,.92), 0 1px 4px rgba(6,4,4,.95), 0 0 40px rgba(6,4,4,.6); }
.hero .btn--ghost { background: color-mix(in srgb, var(--ink) 72%, transparent); backdrop-filter: blur(4px); }

.poster-type {
  /* Hero headline only — Anton (Leo, 2026-08-26): tall, heavy, tight,
     matching the condensed poster reference. Single-weight face, keep 400.
     Rest of the display type stays Space Grotesk. */
  font-family: 'Anton', 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(4.5rem, 11.2vw, 10.5rem);
  line-height: 1.04;
  letter-spacing: .005em;
  word-spacing: .02em;
  margin: auto 0;
  max-width: 17ch;
  text-shadow: 0 12px 34px rgba(6, 4, 4, .55);
}
.poster-type i { font-style: normal; display: block; }
.poster-type .accent { color: var(--blood); }

.poster-rule {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin-top: var(--s2);
}
.poster-rule::before {
  content: '';
  height: 3px;
  width: clamp(2rem, 8vw, 6rem);
  background: var(--blood);
  flex: none;
}
.poster-rule b {
  font-size: clamp(.75rem, .68rem + .35vw, .9375rem);
  font-weight: 700;
  letter-spacing: .3em;
  text-transform: uppercase;
}

@media (max-width: 900px) {
  .poster-type { font-size: clamp(1.75rem, 6.4vw, 4.2rem); line-height: 1.06; letter-spacing: -.01em; }
}
.hero p { max-width: 46ch; }
.hero-cta { display: flex; flex-wrap: wrap; gap: var(--s2); }
@media (max-width: 560px) {
  .hero-cta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero-cta .btn { padding-inline: .6rem; font-size: .78rem; }
}

.scroll-hint {
  position: absolute;
  right: var(--gutter);
  bottom: var(--s5);
  writing-mode: vertical-rl;
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: .3em;
  text-transform: uppercase;
  color: var(--sand);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: var(--s2);
  transition: color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.scroll-hint::after { content: ''; width: 1px; height: 3.5rem; background: linear-gradient(var(--sand), transparent); }
.scroll-hint:hover { color: var(--paper); }
.scroll-hint:active { transform: translateY(2px); }
@media (max-width: 1100px) { .scroll-hint { display: none; } }

/* ── Section heads ──────────────────────────────────────────── */
.head { max-width: 68ch; margin-bottom: var(--s5); }
/* `.head` is used both as a wrapper and directly on the heading */
.head h2, h2.head { font-size: clamp(2.1rem, 1.5rem + 3vw, 4rem); margin-bottom: var(--s3); text-wrap: balance; }

/* ── About ──────────────────────────────────────────────────── */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
  gap: clamp(2rem, 5vw, 5rem);
  align-items: start;
}
@media (max-width: 880px) { .split { grid-template-columns: minmax(0, 1fr); } }

.frame {
  position: relative;
  border: 1px solid var(--hairline);
  padding: var(--s2);
  background: var(--surface-2);
  box-shadow: var(--lift-2);
}
.frame img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; filter: var(--bw); }
.frame figcaption {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
  padding: var(--s2) var(--s1) var(--s1);
}
@media (max-width: 880px) { .frame img { aspect-ratio: 3 / 2; } }

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
  gap: 1px;
  margin-top: var(--s5);
  background: var(--hairline);
  border: 1px solid var(--hairline);
}
.stats div { background: var(--ink); padding: var(--s3); }
.section--tint .stats div { background: var(--surface-1); }
.stats dt {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--sand);
  margin-bottom: .35rem;
}
.stats dd {
  margin: 0;
  font-family: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  font-weight: 700;
  font-size: 1.375rem;
  text-transform: uppercase;
  letter-spacing: -.012em;
  line-height: 1.1;
}

/* ── Quote ──────────────────────────────────────────────────── */
.quote {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  align-items: end;
  border-left: 3px solid var(--blood);
  padding-left: clamp(1.25rem, 3vw, 2.5rem);
}
.quote blockquote {
  margin: 0;
  font-family: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  text-transform: uppercase;
  font-weight: 700;
  font-size: clamp(1.35rem, .95rem + 2vw, 2.6rem);
  line-height: 1.1;
  letter-spacing: -.02em;
}
.quote footer { font-size: .8125rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--sand); margin-top: var(--s3); }
@media (max-width: 880px) {
  .quote { grid-template-columns: minmax(0, 1fr); align-items: start; }
}

/* ── Training tiles — photograph + stencil label ────────────── */
.tt-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s3) var(--s2);
}
@media (max-width: 700px) { .tt-grid { grid-template-columns: minmax(0, 1fr); } }

.tt-item { display: grid; gap: var(--s2); align-content: start; }

.tt {
  position: relative;
  display: block;
  margin: 0; /* figure's UA 40px inline margin would inset the tile */
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--surface-2);
  border: 1px solid var(--hairline);
  box-shadow: var(--lift-1);
  /* label scales to the tile, not the viewport — a 2-col and a 1-col
     tile are very different widths at the same breakpoint */
  container-type: inline-size;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
@media (max-width: 700px) { .tt { aspect-ratio: 16 / 10; } }

.tt img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: var(--tt-bw);
  transition: transform .7s var(--ease), filter .55s var(--ease);
}
.tt::after {
  content: '';
  position: absolute;
  inset: 0;
  /* flat scrim + foot gradient: keeps --paper above 4.5:1 even where the
     photograph blows out to white behind the label */
  background:
    linear-gradient(180deg, rgba(6, 4, 4, .38) 0%, rgba(6, 4, 4, .06) 38%, rgba(6, 4, 4, .9) 100%),
    /* vignette: pulls the corners down so the subject reads as lit */
    radial-gradient(115% 90% at 50% 42%, transparent 38%, rgba(6, 4, 4, .5) 100%),
    color-mix(in srgb, var(--ink) 24%, transparent);
  transition: opacity var(--dur) var(--ease);
}
.tt h3 {
  position: absolute;
  z-index: 1;
  left: clamp(.85rem, 4.4cqi, 1.75rem);
  right: clamp(.85rem, 4.4cqi, 1.75rem);
  bottom: clamp(.6rem, 3.4cqi, 1.4rem);
  margin: 0;
  font-size: 2rem; /* fallback where cqi is unsupported */
  font-size: clamp(1.5rem, 8.4cqi, 3.1rem);
  line-height: .94;
  letter-spacing: -.005em;
  color: var(--paper);
  text-shadow: 0 2px 20px rgba(6, 4, 4, .8);
  transition: color var(--dur) var(--ease);
}

/* Tiles are not links — there is nothing to activate — so this is pointer
   affordance only. :focus-within is carried for parity if a focusable
   child is ever added. */
.tt-item:hover .tt, .tt-item:focus-within .tt { border-color: var(--hairline-strong); box-shadow: var(--lift-2); }
.tt-item:hover .tt img, .tt-item:focus-within .tt img { transform: scale(1.055); filter: var(--tt-color); }
.tt-item:hover .tt h3, .tt-item:focus-within .tt h3 { color: var(--blood); }
.tt-item:hover .tt::after, .tt-item:focus-within .tt::after { opacity: .9; }

.tt-item p {
  margin: 0;
  font-size: .9375rem;
  line-height: 1.55;
  color: var(--muted);
  max-width: 48ch;
}

/* ── Full-bleed photo bands ─────────────────────────────────── */
.band {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: clamp(19rem, 54vh, 34rem);
  display: grid;
  align-items: end;
  border-block: 1px solid var(--hairline);
}
.band img {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: var(--bw);
}
.band::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, rgba(6, 4, 4, .62) 0%, rgba(6, 4, 4, .28) 30%, rgba(6, 4, 4, .56) 60%, rgba(6, 4, 4, .95) 100%);
}
/* per-band framing: the crop is doing real work, not decoration */
.band--fight img { object-position: 50% 8%; }
.band--beach img { object-position: 50% 70%; }
/* a band carrying no line needs far less scrim — the gradient exists to
   keep --paper legible, and there is nothing to keep legible here.
   Its height is set beside the .page-head rule that would collapse it. */
.band--quiet::before {
  background: linear-gradient(180deg, rgba(6, 4, 4, .42) 0%, rgba(6, 4, 4, .12) 40%, rgba(6, 4, 4, .5) 100%);
}
.band-line {
  font-family: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(1.5rem, .88rem + 2.95vw, 3.5rem);
  line-height: 1.02;
  letter-spacing: -.022em;
  margin: 0;
  max-width: 16ch;
  padding-block: var(--s5);
  text-wrap: balance;
  text-shadow: 0 10px 36px rgba(6, 4, 4, .75);
}
/* same red rule the hero and every eyebrow use — the bands are part of
   that system, not a new decoration */
.band-line::before {
  content: '';
  display: block;
  width: clamp(2rem, 7vw, 5rem);
  height: 3px;
  background: var(--blood);
  margin-bottom: var(--s3);
}

/* ── Live status (assets/hours.js) ─────────────────────────────
   One line of plain language, computed in Bangkok time. The dot pulses
   only while the gym (or a class) is actually on — a broadcast "live"
   light, not decoration. */
.live {
  display: flex;
  align-items: center;
  gap: .55em;
  margin: .6rem 0 0;
  font-family: 'Roboto', -apple-system, 'Segoe UI', sans-serif;
  font-size: .8125rem;
  font-weight: 700;
  line-height: 1.35;
  letter-spacing: .02em;
  text-transform: none;
  color: var(--paper);
}
.live:empty { display: none; }
.live-dot {
  position: relative;
  flex: none;
  width: .5rem;
  height: .5rem;
  border-radius: 50%;
  background: var(--sand);
}
.live[data-state="on"] .live-dot { background: var(--blood); }
.live[data-state="on"] .live-dot::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: var(--blood);
  animation: live-pulse 1.8s cubic-bezier(.2, .8, .26, 1) infinite;
}
@keyframes live-pulse {
  from { transform: scale(1); opacity: .75; }
  to { transform: scale(3); opacity: 0; }
}
/* the stats cell sets its dd in display type; the status line is text */
.stats dd.live { font-family: 'Roboto', -apple-system, 'Segoe UI', sans-serif; font-size: .8125rem; text-transform: none; letter-spacing: .02em; line-height: 1.35; }
@media (prefers-reduced-motion: reduce) { .live-dot::after { animation: none; } }

/* ── Week strip — real opening pattern, Friday is closed ────── */
.week {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 1px;
  background: var(--hairline);
  border: 1px solid var(--hairline);
  margin-bottom: var(--s3);
}
.week div {
  background: var(--surface-2);
  padding: var(--s3) var(--s1);
  text-align: center;
}
.week b {
  display: block;
  font-family: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  font-weight: 700;
  font-size: clamp(.8125rem, .68rem + .6vw, 1.15rem);
  text-transform: uppercase;
  letter-spacing: -.005em;
}
.week small {
  display: block;
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: .3rem;
}
.week div { position: relative; }
/* today, in Bangkok — a red bar across the top of the cell */
.week .is-today::before {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 3px;
  background: var(--blood);
}
.week .is-today small { color: var(--paper); }
.week .closed { background: color-mix(in srgb, var(--blood) 16%, var(--surface-2)); }
.week .closed b { color: var(--blood); text-decoration: line-through; text-decoration-thickness: 2px; }
.week .closed small { color: var(--muted); }
@media (max-width: 560px) {
  .week div { padding-inline: 0; }
  .week small { font-size: .5rem; letter-spacing: .03em; }
}

.panel {
  background: var(--surface-2);
  border: 1px solid var(--hairline);
  padding: clamp(1.5rem, 3vw, 2.5rem);
  box-shadow: var(--lift-2);
}
.panel h3, .panel .panel-title { font-size: 1.625rem; margin-bottom: var(--s3); }

.rows { border-top: 1px solid var(--hairline); }
.rows > div {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s2);
  justify-content: space-between;
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--hairline);
}
.rows strong { font-weight: 700; font-size: .9375rem; letter-spacing: .06em; text-transform: uppercase; }
.rows p { font-size: .875rem; color: var(--muted); margin: .2rem 0 0; flex-basis: 100%; }

/* ── Gallery ────────────────────────────────────────────────── */
/* Masonry, not a mosaic. The photographs arrive in three shapes —
   ringside landscape, square, backstage portrait — and the old square
   crop threw away the top and bottom of every tall one. Each keeps its
   own frame now.

   The columns are real elements built in site.js rather than CSS
   `columns`: the intrinsic heights are known up front, so site.js can
   deal each photo into the shortest column and finish level, where
   multicol fills greedily and leaves the last one short. */
.grid {
  display: flex;
  align-items: flex-start;
  gap: var(--s2);
}
.grid-col {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

/* Filters: the photos arrive in three kinds; a person looking for fight
   nights should not have to scroll past twenty pad rounds. */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-bottom: var(--s4);
}
.filters[hidden] { display: none; }
.filter {
  display: inline-flex;
  align-items: baseline;
  gap: .55em;
  padding: .55rem 1rem;
  border: 1px solid var(--hairline-strong);
  border-radius: 2px;
  background: transparent;
  color: var(--muted);
  font-family: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  font-weight: 700;
  font-size: .8125rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease), background-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.filter-n { font-family: 'Roboto', sans-serif; font-size: .6875rem; letter-spacing: .04em; color: var(--sand); }
.filter:hover { color: var(--paper); border-color: var(--paper); }
.filter:active { transform: scale(.97); }
.filter[aria-pressed="true"] { color: var(--paper); border-color: var(--blood); background: color-mix(in srgb, var(--blood) 18%, transparent); }
.filter[aria-pressed="true"] .filter-n { color: var(--paper); }

.tile {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  /* per-tile vanishing point: one shared perspective on .grid would
     skew the outer columns away from the pointer they're tracking */
  perspective: 900px;
}
.tile-in {
  position: relative;
  display: block;
  overflow: hidden;
  background: var(--surface-2);
  transition: transform .28s var(--ease), box-shadow var(--dur) var(--ease);
}
/* Declared under :hover on purpose. A transform sitting on all fourteen
   tiles at rest promotes every one to its own compositing layer, which
   costs scroll frames on a phone for an effect only a mouse can trigger. */
.tile:hover .tile-in {
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
}
.tile:hover .tile-in, .tile:focus-visible .tile-in { box-shadow: var(--lift-2); }

.tile img {
  display: block;
  width: 100%;
  height: auto;
  transition: transform .6s var(--ease), filter .45s var(--ease);
  filter: var(--bw);
}
.tile-in::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 40%, rgba(6, 4, 4, .72));
  opacity: .75;
  transition: opacity var(--dur) var(--ease);
}
.tile-cap {
  position: absolute;
  left: var(--s2);
  right: var(--s2);
  bottom: var(--s2);
  z-index: 1;
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--paper);
  opacity: 0;
  transform: translateY(6px);
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
}
/* the tilt already reads as lift, so the zoom pulls back from 1.06.
   Colour returns on hover — a preview of the lightbox, where it stays. */
.tile:hover img, .tile:focus-visible img { transform: scale(1.04); filter: none; }
.tile:hover .tile-in::after, .tile:focus-visible .tile-in::after { opacity: 1; }
.tile:hover .tile-cap, .tile:focus-visible .tile-cap { opacity: 1; transform: translateY(0); }
.tile:active img { transform: scale(1.02); }
.tile[hidden] { display: none; }

/* lightbox */
dialog.lb {
  border: 0;
  padding: 0;
  background: transparent;
  max-width: 100vw;
  max-height: 100vh;
  width: 100%;
  height: 100%;
  color: var(--paper);
  overflow: hidden;
}
/* The shade is an element, not ::backdrop, so the motion layer can fade
   it; the backdrop itself stays clear. */
dialog.lb::backdrop { background: transparent; }
dialog.lb { touch-action: pan-y pinch-zoom; }
.lb-shade { position: fixed; inset: 0; background: rgba(6, 4, 4, .94); }
.lb-inner, .lb-close { position: relative; }
.lb-inner {
  height: 100%;
  display: grid;
  grid-template-rows: 1fr auto;
  gap: var(--s3);
  padding: clamp(3.5rem, 6vw, 4.5rem) var(--gutter) var(--s4);
  place-items: center;
}
.lb-inner img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  object-fit: contain;
  box-shadow: var(--lift-2);
  /* the one place colour comes back */
  filter: none;
}
.lb-bar {
  display: flex;
  align-items: center;
  gap: var(--s3);
  flex-wrap: wrap;
  justify-content: center;
  text-align: center;
}
.lb-bar p {
  margin: 0;
  font-size: .8125rem;
  letter-spacing: .04em;
  color: var(--muted);
  max-width: 52ch;
}
.icon-btn {
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  background: var(--surface-2);
  color: var(--paper);
  border: 1px solid var(--hairline-strong);
  border-radius: 2px;
  cursor: pointer;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.icon-btn svg { width: 1.15rem; height: 1.15rem; }
.icon-btn:hover { background: var(--blood); border-color: var(--blood); }
.icon-btn:active { transform: scale(.94); }
.lb-close { position: absolute; top: var(--s3); right: var(--gutter); z-index: 2; }
.lb-inner { z-index: 1; }

/* ── Location ───────────────────────────────────────────────── */
.locate { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); gap: clamp(2rem, 4vw, 4rem); align-items: center; }
@media (max-width: 880px) { .locate { grid-template-columns: minmax(0, 1fr); } }

.pin-list { display: grid; gap: var(--s3); margin-bottom: var(--s4); }
/* dt/dd must be the row's own children, so the icon lives inside the dt
   and hangs in the row's left padding */
.pin-list > div { position: relative; padding-left: calc(1.35rem + var(--s3)); }
.pin-list svg { position: absolute; left: 0; top: .3rem; width: 1.35rem; height: 1.35rem; color: var(--blood); }
.pin-list dt {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: .2rem;
}
.pin-list dd { margin: 0; }

.map-card {
  position: relative;
  display: block;
  border: 1px solid var(--hairline);
  overflow: hidden;
  box-shadow: var(--lift-2);
  text-decoration: none;
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.map-card img { width: 100%; aspect-ratio: 16 / 11; object-fit: cover; filter: var(--bw) brightness(.74); }
.map-card::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(70% 60% at 50% 45%, color-mix(in srgb, var(--midnight) 30%, transparent), rgba(6, 4, 4, .84));
}
.map-card-body {
  position: absolute;
  inset: auto 0 0;
  z-index: 1;
  padding: clamp(1.25rem, 3vw, 2rem);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s3);
  flex-wrap: wrap;
}
.map-card b {
  font-family: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  font-weight: 700;
  font-size: clamp(1.125rem, .95rem + .95vw, 1.6rem);
  text-transform: uppercase;
  display: block;
  line-height: 1.05;
  letter-spacing: -.012em;
}
.map-card small { font-size: .75rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--sand); }
.map-card .coords {
  display: block;
  margin-top: .35rem;
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .08em;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
/* The pin: where the gym is, marked on its own training floor. The outer
   ring pulses like a location beacon; hover tightens it. */
.reticle {
  position: absolute;
  left: 50%;
  top: 40%;
  z-index: 1;
  width: 3.25rem;
  height: 3.25rem;
  margin: -1.625rem 0 0 -1.625rem;
  pointer-events: none;
}
.reticle i, .reticle b { position: absolute; inset: 0; border-radius: 50%; }
.reticle i:first-child { border: 2px solid var(--paper); transition: transform .5s var(--ease); }
.reticle i:nth-child(2) { border: 2px solid var(--blood); animation: beacon 2.2s cubic-bezier(.2, .8, .26, 1) infinite; }
.reticle b { inset: 38%; background: var(--blood); box-shadow: 0 0 0 3px color-mix(in srgb, var(--ink) 60%, transparent); }
.map-card:hover .reticle i:first-child, .map-card:focus-visible .reticle i:first-child { transform: scale(.72); }
.map-card:hover .reticle i:nth-child(2) { animation-duration: 1.1s; }
@keyframes beacon {
  from { transform: scale(.9); opacity: .9; }
  to { transform: scale(2.4); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) { .reticle i:nth-child(2) { animation: none; opacity: 0; } }
.map-card .go {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--paper);
  border-bottom: 2px solid var(--blood);
  padding-bottom: .2rem;
  transition: color var(--dur) var(--ease);
}
.map-card .go svg { width: 1rem; height: 1rem; }
.map-card:hover { transform: translateY(-3px); border-color: var(--hairline-strong); box-shadow: var(--lift-2), 0 0 0 1px color-mix(in srgb, var(--blood) 40%, transparent); }
.map-card:hover .go { color: var(--blood); }
.map-card:active { transform: translateY(0); }

/* ── Footer ─────────────────────────────────────────────────── */
.foot { background: var(--ink); padding-block: var(--s6) calc(var(--s6) + 3rem); }
.foot-top { display: flex; flex-wrap: wrap; gap: var(--s5); justify-content: space-between; align-items: flex-start; }
.foot img { width: 96px; height: auto; }
.foot .pairing {
  font-family: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  font-weight: 700;
  font-size: clamp(1.05rem, .95rem + .62vw, 1.4rem);
  text-transform: uppercase;
  letter-spacing: -.015em;
  line-height: 1.14;
  margin: var(--s3) 0 var(--s2);
  max-width: 16ch;
}
.foot .pairing em { font-style: normal; color: var(--blood); }

.socials { display: flex; gap: var(--s2); margin-top: var(--s3); }
.socials a {
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--hairline);
  color: var(--paper);
  border-radius: 2px;
  transition: background-color var(--dur) var(--ease), border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.socials svg { width: 1.15rem; height: 1.15rem; }
.socials a:hover { background: var(--blood); border-color: var(--blood); transform: translateY(-2px); }
.socials a:active { transform: translateY(0); background: var(--rust); }

.foot-links { display: grid; gap: var(--s2); }
.foot-links a {
  font-size: .8125rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--muted);
  width: fit-content;
  border-bottom: 1px solid transparent;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease), opacity var(--dur) var(--ease);
}
.foot-links a:hover { color: var(--paper); border-bottom-color: var(--blood); }
.foot-links a:active { opacity: .7; }

.colophon {
  margin-top: var(--s5);
  padding-top: var(--s3);
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3);
  justify-content: space-between;
  font-size: .75rem;
  letter-spacing: .06em;
  color: var(--sand);
}

/* ── Short screens (laptops): every panel fits the viewport ──── */
@media (min-width: 561px) and (max-height: 940px) {
  .hero { padding-block: 5.5rem var(--s3); }
  .poster { gap: var(--s3); }
  .poster-type { font-size: clamp(4rem, 11.5vh, 8.5rem); }
  .lead { font-size: 1.05rem; line-height: 1.5; }
  .hero p { max-width: 52ch; }
  :root { --pad-section: clamp(3.5rem, 9vh, 5.5rem); }
  .band { min-height: clamp(15rem, 44vh, 26rem); }
}
@media (min-width: 561px) and (max-height: 800px) {
  .hero { padding-block: 4.5rem var(--s3); }
  .poster-type { font-size: clamp(3.6rem, 10.5vh, 7rem); }
}

/* ── Motion ─────────────────────────────────────────────────── */
/* `.reveal` marks blocks the motion layer animates in. It hides nothing
   here: start states live in motion.css under html.motion, so the page
   is fully visible with JavaScript off or motion reduced. */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  /* the tile/gallery zoom is motion, not affordance — the label colour,
     scrim and border still carry the hover state */
  .tt-item:hover .tt img, .tt-item:focus-within .tt img { transform: none; }
  .tile:hover img, .tile:focus-visible img, .tile:active img { transform: none; }
  /* the pointer tilt is pure motion — the scrim, caption and shadow
     still mark the hover. Matches the :hover selector's specificity so it
     actually wins, rather than relying on site.js never setting --rx/--ry. */
  .tile-in, .tile:hover .tile-in { transform: none; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ── Kinetic band (home, under the hero strip) ─────────────────
   Facts already on the page, set large and run between fighter marks.
   Static without the motion layer: the first set simply sits in the
   band. motion.js clones the set and drives it with scroll velocity. */
.marquee {
  overflow: hidden;
  border-bottom: 1px solid var(--hairline);
  padding-block: clamp(1rem, 2.2vw, 1.75rem);
  background: var(--ink);
}
.marquee-track { display: flex; width: max-content; }
.marquee-set {
  display: flex;
  align-items: center;
  flex: none;
  gap: clamp(1.25rem, 2.6vw, 2.75rem);
  padding-right: clamp(1.25rem, 2.6vw, 2.75rem);
}
.marquee b {
  font-family: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(2.1rem, 1rem + 5.2vw, 6rem);
  line-height: 1;
  letter-spacing: -.035em;
  white-space: nowrap;
  color: var(--paper);
}
.marquee b.is-outline {
  color: transparent;
  -webkit-text-stroke: 1.5px color-mix(in srgb, var(--paper) 72%, transparent);
}
.marquee img { flex: none; width: auto; height: clamp(2.3rem, 1.2rem + 4.8vw, 5.4rem); }

/* ── Curtain: the home intro's cover. Shown only under html.intro. ── */
.curtain { display: none; }

/* ── Footer ropes: the ring's ropes run along the top of the footer ── */
.foot > .ropes { margin: calc(var(--s6) * -1) 0 var(--s6); }

/* ═══════════════════════════════════════════════════════════════
   Multi-page additions (2026-08-23)
   The one-pager navigated by anchor; five pages need real links.
   ═══════════════════════════════════════════════════════════════ */

/* ── Header nav: inline links on desktop, burger panel below ──── */
.nav-links {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: clamp(1rem, 1.8vw, 2rem);
  font-family: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  font-weight: 700;
  font-size: .8125rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.nav-links a {
  color: var(--muted);
  text-decoration: none;
  padding-block: .35rem;
  border-bottom: 2px solid transparent;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.nav-links a:hover { color: var(--paper); }
.nav-links a[aria-current="page"] { color: var(--paper); border-bottom-color: var(--blood); }
.nav-links a:focus-visible { outline: 2px solid var(--blood); outline-offset: 3px; }

/* Roll-up hover: site.js wraps each label in .roll (clip) > .roll-in
   (slides) with an aria-hidden duplicate parked one line below. */
.nav-links a .roll { display: inline-block; overflow: hidden; line-height: 1.4; }
.nav-links a .roll-in {
  display: inline-block;
  position: relative;
  transition: transform .3s var(--ease);
}
.nav-links a .roll-dup {
  position: absolute;
  left: 0;
  top: 100%;
  color: var(--paper);
}
.nav-links a.has-roll:hover .roll-in,
.nav-links a.has-roll:focus-visible .roll-in { transform: translateY(-100%); }
@media (prefers-reduced-motion: reduce) {
  .nav-links a .roll-in { transition: none; }
  .nav-links a.has-roll:hover .roll-in,
  .nav-links a.has-roll:focus-visible .roll-in { transform: none; }
}
.nav-book {
  background: var(--blood);
  color: var(--paper) !important;
  border: 0 !important;
  border-radius: 2px;
  padding: .5rem .9rem !important;
  box-shadow: var(--lift-blood);
}
.nav-book:hover { background: var(--rust); }

@media (max-width: 1023px) { .nav-links { display: none; } }
@media (min-width: 1024px) { .burger { display: none; } }

/* ── Burger panel (below 1024px) ──────────────────────────────── */
.navmenu {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  align-content: center;
  gap: var(--s3);
  padding: var(--gutter);
  background: color-mix(in srgb, var(--ink) 97%, transparent);
  backdrop-filter: blur(6px);
}
.navmenu[hidden] { display: none; }
.navmenu a {
  font-family: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  font-weight: 700;
  font-size: clamp(1.75rem, 7vw, 2.75rem);
  text-transform: uppercase;
  letter-spacing: -.02em;
  color: var(--paper);
  text-decoration: none;
  border-bottom: 1px solid var(--hairline);
  padding-block: var(--s2);
}
.navmenu a[aria-current="page"] { color: var(--blood); }
.navmenu a:focus-visible { outline: 2px solid var(--blood); outline-offset: 3px; }
.navmenu .navmenu-close {
  position: absolute;
  top: var(--s3);
  right: var(--gutter);
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: transparent;
  color: var(--paper);
  cursor: pointer;
  font-size: 1.5rem;
  line-height: 1;
  padding: 0;
}
.navmenu .navmenu-close:focus-visible { outline: 2px solid var(--blood); outline-offset: 2px; }
body.menu-open { overflow: hidden; }

/* ── Page header: the compact hero every page except Home uses ── */
.page-head {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: clamp(19rem, 42vh, 27rem);
  padding-block: 9rem var(--s5);
  overflow: hidden;
  isolation: isolate;
}
.page-head-media { position: absolute; inset: 0; z-index: -2; }
.page-head-media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(6,4,4,.8) 0%, rgba(6,4,4,.5) 45%, rgba(6,4,4,.92) 100%);
}
.page-head-media img { width: 100%; height: 100%; object-fit: cover; filter: var(--bw); }
.page-head h1 {
  font-size: clamp(2.6rem, 6vw, 4.75rem);
  letter-spacing: -.028em;
  line-height: .98;
  max-width: 16ch;
  text-shadow: 0 12px 34px rgba(6, 4, 4, .55);
}
.page-head p {
  margin: var(--s3) 0 0;
  max-width: 52ch;
  color: var(--muted);
  text-shadow: 0 2px 14px rgba(6,4,4,.9);
}

/* ── Breadcrumb back-link on sub-pages ────────────────────────── */
.backlink {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin-bottom: var(--s3);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--sand);
  text-decoration: none;
}
.backlink:hover { color: var(--paper); }
.backlink::before { content: '←'; }

/* ── Where to next: an index of the four pages (2026-09-27) ────
   Replaces the four small route cards. Big type, one row per page. A
   fine pointer gets the row's photo following the cursor (motion.js);
   touch screens get it inline as a thumbnail. No numbering: the pages are
   not a sequence. */
#routes { min-height: 0; }
.index { position: relative; border-bottom: 1px solid var(--hairline); }
.index-row {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 19rem) 8.5rem;
  align-items: center;
  gap: var(--s4);
  padding-block: clamp(1.1rem, 2.1vw, 1.8rem);
  border-top: 1px solid var(--hairline);
  color: var(--paper);
  text-decoration: none;
  transition: opacity var(--dur) var(--ease);
}
/* red rope along the top edge, drawn on hover */
.index-row::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: -1px;
  height: 2px;
  background: var(--blood);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .6s var(--ease);
}
.index-title {
  font-family: 'Space Grotesk', -apple-system, 'Segoe UI', sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(2.25rem, 1.1rem + 4.7vw, 5.75rem);
  line-height: .95;
  letter-spacing: -.035em;
  transition: transform .6s var(--ease);
}
.index-desc { font-size: .9375rem; line-height: 1.5; color: var(--muted); max-width: 34ch; }
.index-go {
  justify-self: end;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--blood);
  white-space: nowrap;
}
.index-thumb { display: none; }
.index-row:hover::after, .index-row:focus-visible::after { transform: scaleX(1); }
.index-row:hover .index-title, .index-row:focus-visible .index-title { transform: translateX(1.25rem); }
.index-row:active .index-title { transform: translateX(.6rem); }
.index-row:focus-visible { outline: 2px solid var(--blood); outline-offset: 4px; }
/* the rest of the list steps back while one row is chosen */
.index:hover .index-row:not(:hover) { opacity: .38; }
@media (max-width: 900px), (hover: none) {
  .index-row {
    grid-template-columns: minmax(0, 1fr) 5.5rem;
    grid-template-areas: 'title thumb' 'desc thumb' 'go thumb';
    gap: .3rem var(--s3);
  }
  .index-title { grid-area: title; font-size: clamp(2rem, 1.2rem + 5vw, 3.5rem); }
  .index-desc { grid-area: desc; font-size: .875rem; }
  .index-go { grid-area: go; justify-self: start; margin-top: .2rem; }
  .index-thumb {
    display: block;
    grid-area: thumb;
    width: 5.5rem;
    height: 5.5rem;
    object-fit: cover;
    filter: var(--bw);
    border: 1px solid var(--hairline);
  }
  .index:hover .index-row:not(:hover) { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .index-row:hover .index-title, .index-row:focus-visible .index-title, .index-row:active .index-title { transform: none; }
}

/* Sub-pages size their sections to content. The 100svh full-screen panel is
   a one-pager device; on a short page it manufactures empty screens, which is
   the exact problem the split was meant to remove. */
.page-head ~ .section,
.page-head ~ .band { min-height: 0; }
/* ...but a quiet band has no line inside it, so "size to content" means
   size to nothing. It carries its own height, at this specificity so the
   rule above does not flatten it. */
.page-head ~ .band--quiet { min-height: clamp(15rem, 40vh, 26rem); }

/* ── Package matrix: train + stay pricing (2026-08-26) ─────────
   The gym sells camp packages — training and accommodation bundled
   by duration — per its front-desk price card. Durations as columns
   so all twelve prices read in one glance. */
.matrix-scroll { overflow-x: auto; border-top: 1px solid var(--hairline); }
.matrix {
  width: 100%;
  min-width: 26rem;
  border-collapse: collapse;
  font-size: .9375rem;
}
.matrix th, .matrix td {
  padding: .7rem .5rem;
  border-bottom: 1px solid var(--hairline);
  text-align: right;
  white-space: nowrap;
}
.matrix thead th {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sand);
}
.matrix tbody th {
  text-align: left;
  font-weight: 700;
  font-size: .9375rem;
  letter-spacing: .06em;
  text-transform: uppercase;
}
.matrix td { color: var(--muted); font-variant-numeric: tabular-nums; }

/* Narrow panels — phones, and the two-column split between 881px and
   1180px — the package matrix must show all three durations at once: a
   sideways-scrolling table hides the month column with no hint it exists. */
@media (max-width: 560px), (min-width: 881px) and (max-width: 1180px) {
  .matrix { min-width: 0; font-size: .8125rem; }
  .matrix th, .matrix td { padding: .55rem .3rem; }
  .matrix tbody th { font-size: .75rem; white-space: normal; padding-right: .5rem; }
}

/* Anchored jumps land below the fixed nav */
#packages { scroll-margin-top: 6rem; }

/* Crosshair: the row and column under the pointer light up, so a price
   reads against both its package and its duration (site.js). Opacity
   on a tinted layer, not a background transition. */
.matrix th, .matrix td { position: relative; }
.matrix tbody :is(th, td)::before,
.matrix thead th::before {
  content: '';
  position: absolute;
  inset: 0;
  background: color-mix(in srgb, var(--paper) 5%, transparent);
  opacity: 0;
  transition: opacity .25s var(--ease);
  pointer-events: none;
}
.matrix .is-row::before, .matrix .is-col::before { opacity: 1; }
.matrix td.is-hit { color: var(--paper); font-weight: 700; }
.matrix td.is-hit::before { background: color-mix(in srgb, var(--blood) 22%, transparent); opacity: 1; }

/* ── Room photo strips on /stay/ (2026-08-26) ─────────────────
   Horizontally scrollable, snap per tile. Ships with honest
   placeholder tiles until room photography exists — swap each
   figure for an <img> tile when the photos arrive. */
.roomgal {
  display: flex;
  gap: var(--s2);
  margin-top: var(--s2);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  flex-basis: 100%;
}
.roomgal > * {
  flex: 0 0 min(15rem, 78%);
  aspect-ratio: 4 / 3;
  scroll-snap-align: start;
  margin: 0;
}
.roomgal figure.ph {
  display: grid;
  place-content: center;
  gap: .5rem;
  justify-items: center;
  border: 1px dashed var(--hairline-strong);
  background: var(--surface-2);
  color: var(--sand);
}
.roomgal figure.ph svg { width: 26px; height: 26px; opacity: .8; }
.roomgal figure.ph figcaption {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
}

/* Room strips: mouse users can drag them (site.js); a thin line shows
   the position and two buttons step a photo at a time. */
@media (hover: hover) and (pointer: fine) {
  .roomgal { cursor: grab; }
}
.roomgal.is-dragging { cursor: grabbing; scroll-snap-type: none; user-select: none; }
.roomgal.is-dragging .shot-open { pointer-events: none; }
.roomgal-bar {
  flex-basis: 100%;
  display: flex;
  align-items: center;
  gap: var(--s2);
  margin-top: var(--s2);
}
.roomgal-bar[hidden] { display: none; }
.roomgal-track { flex: 1; height: 2px; overflow: hidden; background: var(--hairline); }
.roomgal-track i { display: block; height: 100%; background: var(--blood); }
.roomgal-bar .icon-btn { width: 2.25rem; height: 2.25rem; }
.roomgal-bar .icon-btn[aria-disabled="true"] { opacity: .35; cursor: default; }
.roomgal-bar .icon-btn[aria-disabled="true"]:hover { background: var(--surface-2); border-color: var(--hairline-strong); }
.shot-open {
  display: block;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}
.shot-open:focus-visible { outline: 2px solid var(--blood); outline-offset: -2px; }
.roomgal figure.shot .shot-open img { transition: transform .6s var(--ease); }
.shot-open:hover img, .shot-open:focus-visible img { transform: scale(1.045); }
.shot-open:active img { transform: scale(1.015); }
@media (prefers-reduced-motion: reduce) {
  .shot-open:hover img, .shot-open:focus-visible img, .shot-open:active img { transform: none; }
}

/* ── Room strip: real photography (private house, 2026-08-27) ──
   Same box as the placeholder tile, filled. Rooms are exempt from the
   site's B&W grade entirely (Leo, 2026-08-30): guests are choosing a
   bed, not admiring a fight photo — they need to see the actual room. */
.roomgal figure.shot {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--hairline);
  background: var(--surface-2);
}
.roomgal figure.shot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.roomgal figure.shot::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 64%, rgba(6, 4, 4, .74));
  pointer-events: none; /* the photo underneath is a button */
}
.roomgal figure.shot figcaption {
  position: absolute;
  left: var(--s2);
  right: var(--s2);
  bottom: calc(var(--s2) - 2px);
  z-index: 1;
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--paper);
  pointer-events: none;
}

/* ── Mobile hero: poster stack (Leo picked variant A, 2026-08-26) ──
   Phones get a dedicated portrait crop (see the <picture> in index.html)
   and each headline line is sized to fill the column — poster breaks by
   design, not by wrap. Desktop hero is untouched. */
@media (max-width: 560px) {
  .hero { align-items: flex-end; padding-bottom: 3rem; }
  .hero-media img { object-position: 50% 30%; }
  .hero-media::after {
    /* flat darken + bottom ramp — legibility lives here now, not in
       text shadows, which read as smudges over the grey grade */
    background: linear-gradient(180deg, rgba(6,4,4,.5) 0%, rgba(6,4,4,.38) 40%, rgba(6,4,4,.6) 62%, rgba(6,4,4,.95) 100%);
  }
  .poster-type, .poster-type i, .poster-rule, .hero .lead { text-shadow: none; }
  .poster-type { max-width: none; font-size: 12.6vw; line-height: 1.04; letter-spacing: .005em; }
  .hero .lead { font-size: .9375rem; line-height: 1.55; }
}

/* ── The gym section fits one desktop screen (Leo, 2026-08-26) ──
   On laptop heights the square figure and full-size text overflow the
   viewport. Cap the photo and tighten the text column so the whole
   section lands inside one screen; phones scroll naturally and are
   exempt. */
@media (min-width: 881px) and (max-height: 940px) {
  #gym h2 { font-size: clamp(1.9rem, 4.6vh, 2.6rem); }
  #gym p { font-size: .9375rem; margin-bottom: var(--s2); }
  #gym .frame img { max-height: 48vh; width: 100%; object-fit: cover; }
  #gym .stats div { padding: var(--s2) var(--s2); }
  #gym .stats dd { font-size: 1.125rem; }
  #gym .confirm { font-size: .8125rem; }
}

/* ── Training: prices above the fold (Leo, 2026-08-27) ─────────
   Shorter page head and tighter top padding so the What-it-costs
   table is on screen at load, no scroll needed. */
.page-head--short { min-height: clamp(14rem, 30vh, 18rem); padding-block: 7rem var(--s4); }
#prices { padding-block: var(--s5) var(--pad-section); min-height: 0; justify-content: flex-start; }
