/* =========================================================
   Plus Fitness Belrose
   Light, editorial, Swiss-grotesque.
   ========================================================= */

/* ---------- Tokens ---------- */
:root {
  --paper:    #FFFFFF;
  --paper-2:  #F5F4F2;
  --paper-3:  #EBEAEA;
  /* The Apex menu board's own background. The shake photographs are cut
     from the board and carry this colour, so the plate behind them is
     painted to match. Sampled from the artwork — don't nudge it. */
  --cream:    #FAF1E3;
  --ink:      #181818;
  --ink-2:    #5B5B5B;
  --ink-3:    #A0A0A0;
  --ink-4:    #C6C6C6;
  --black:    #0C0C0C;
  --line:     rgba(24, 24, 24, 0.13);
  --line-2:   rgba(24, 24, 24, 0.07);
  --line-inv: rgba(255, 255, 255, 0.20);

  --sans:  "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --serif: "Instrument Serif", Georgia, "Times New Roman", serif;

  --gutter: clamp(1.5rem, 5vw, 5rem);
  --maxw:   1400px;
  --section: clamp(4.5rem, 9vw, 9.5rem);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }

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

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 0.9375rem;
  font-weight: 300;
  line-height: 1.78;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

img, picture, video, svg, iframe { display: block; max-width: 100%; }
input, button, textarea, select { font: inherit; color: inherit; }
button { background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }
::selection { background: var(--ink); color: var(--paper); }
:focus-visible { outline: 1px solid var(--ink); outline-offset: 4px; }

/* ---------- Type ---------- */
.display, .h2, .h3, .h4 {
  font-weight: 200;
  text-transform: uppercase;
  line-height: 1.16;
  text-wrap: balance;
}

.display {
  font-size: clamp(1.75rem, 4.6vw, 3.6rem);
  letter-spacing: 0.095em;
  font-weight: 200;
  line-height: 1.12;
}
.display--lg { font-size: clamp(2rem, 6vw, 4.6rem); letter-spacing: 0.085em; }

.h2 { font-size: clamp(1.3rem, 2.5vw, 2rem); letter-spacing: 0.11em; font-weight: 200; }
.h3 { font-size: clamp(1.02rem, 1.5vw, 1.2rem); letter-spacing: 0.13em; font-weight: 300; }
.h4 { font-size: 0.82rem; letter-spacing: 0.16em; font-weight: 400; }

.label {
  display: block;
  font-size: 0.655rem;
  font-weight: 400;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-2);
}
.label--ink { color: var(--ink); }

.lede {
  font-size: clamp(0.98rem, 1.15vw, 1.08rem);
  font-weight: 300;
  line-height: 1.72;
  color: var(--ink-2);
  max-width: 46ch;
  text-wrap: pretty;
}

.serif {
  font-family: var(--serif);
  font-style: italic;
  text-transform: none;
  letter-spacing: 0.005em;
  font-weight: 400;
}

p { max-width: 60ch; text-wrap: pretty; color: var(--ink-2); }
.muted { color: var(--ink-3); }
strong { font-weight: 500; color: var(--ink); }

/* ---------- Layout ---------- */
.wrap { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--gutter); }
.wrap--mid { max-width: 1000px; }
.wrap--narrow { max-width: 720px; }

.section { padding-block: var(--section); }
.section--sm { padding-block: clamp(3rem, 6vw, 6rem); }
.section--flush { padding-top: 0; }

.center { text-align: center; }
.center p, .center .lede { margin-inline: auto; }

.rule { height: 1px; background: var(--line); border: 0; }

.grid { display: grid; gap: clamp(1.75rem, 3.5vw, 3.5rem); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 940px) { .grid-3, .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: minmax(0, 1fr); } }

.stack   { display: grid; gap: 1.5rem; align-content: start; justify-items: start; }
.stack-sm { display: grid; gap: 0.85rem; align-content: start; justify-items: start; }
.center .stack, .center .stack-sm { justify-items: center; }

/* Tonal sections */
.tone     { background: var(--paper-2); }
.tone-3   { background: var(--paper-3); }
.inverse  { background: var(--black); color: var(--paper); }
.inverse p, .inverse .lede { color: rgba(255,255,255,0.62); }
.inverse .label { color: rgba(255,255,255,0.55); }
.inverse .label--ink { color: var(--paper); }
.inverse strong { color: var(--paper); }
.inverse .rule, .inverse .flist li, .inverse .specs > div, .inverse .specs { border-color: var(--line-inv); }
.inverse .btn { border-color: var(--line-inv); color: var(--paper); }
.inverse .btn:hover { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.inverse .tlink { color: var(--paper); }
.inverse .tlink::after { background: var(--paper); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.9em;
  padding: 1.05em 2.15em;
  border: 1px solid var(--ink);
  border-radius: 100px;
  background: transparent;
  color: var(--ink);
  font-size: 0.655rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  line-height: 1;
  transition: background 0.45s var(--ease), color 0.45s var(--ease), border-color 0.45s var(--ease);
}
.btn:hover { background: var(--ink); color: var(--paper); }
.btn--solid { background: var(--ink); color: var(--paper); }
.btn--solid:hover { background: transparent; color: var(--ink); }

.btn-row { display: flex; flex-wrap: wrap; gap: 0.75rem; }
.center .btn-row { justify-content: center; }

.tlink {
  position: relative;
  display: inline-block;
  font-size: 0.655rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding-bottom: 0.5em;
  color: var(--ink);
}
.tlink::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--ink);
  transform-origin: right;
  transition: transform 0.55s var(--ease-out);
}
.tlink:hover::after { transform: scaleX(0); transform-origin: left; }

/* ---------- Media ---------- */
.media {
  position: relative;
  overflow: hidden;
  background: var(--paper-3);
  isolation: isolate;
}
.media img {
  width: 100%; height: 100%;
  object-fit: cover;
  /* Where the crop sits. Defaults to the middle, which is right for a photo
     shot for its box — and wrong for the clubs whose photos are stills off a
     360 virtual tour: those are 2.5-3.5:1 panoramas, so a portrait box keeps
     barely a quarter of the width, and the middle of a panorama is usually
     the empty floor between two banks of equipment. Set --focal on the .media
     to move the window onto the equipment. */
  object-position: var(--focal, 50% 50%);
  /* --zoom crops further in without cutting a second file. --focal steers the
     window, --zoom magnifies about the centre of the box, so set the focal
     first and then zoom. Needed where a photo is composed too wide for the
     box it lands in — a dumbbell rack shot from the end of the room, say. */
  transform: scale(var(--zoom, 1));
  transition: transform 1.4s var(--ease-out);
}
/* Hover multiplies whatever base zoom is set, rather than replacing it. */
.media--zoom:hover img { transform: scale(calc(var(--zoom, 1) * 1.04)); }

.r-1x1  { aspect-ratio: 1 / 1; }
.r-4x5  { aspect-ratio: 4 / 5; }
.r-3x4  { aspect-ratio: 3 / 4; }
.r-3x2  { aspect-ratio: 3 / 2; }
.r-16x9 { aspect-ratio: 16 / 9; }
.r-21x9 { aspect-ratio: 21 / 9; }
@media (max-width: 640px) { .r-21x9 { aspect-ratio: 16 / 10; } }

/* Empty photo slot — reads as an editorial placeholder, not a broken image */
.media.is-missing,
.hero__bg.is-missing { background: var(--paper-3); }

.media.is-missing::before,
.hero__bg.is-missing::before {
  content: attr(data-n);
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: clamp(2.5rem, 6vw, 5rem);
  font-weight: 100;
  letter-spacing: 0.08em;
  color: rgba(24, 24, 24, 0.14);
  z-index: 1;
}
.media.is-missing::after,
.hero__bg.is-missing::after {
  content: attr(data-file);
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: 1rem 1.2rem;
  font-size: 0.575rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
  text-align: center;
  z-index: 1;
}

/* On dark grounds the placeholder inverts so hero and full-bleed text stays legible */
.inverse .media.is-missing,
.bleed .media.is-missing,
.hero__bg.is-missing { background: #1A1A1A; }

.inverse .media.is-missing::before,
.bleed .media.is-missing::before,
.hero__bg.is-missing::before { color: rgba(255, 255, 255, 0.15); }

.inverse .media.is-missing::after,
.bleed .media.is-missing::after,
.hero__bg.is-missing::after { color: rgba(255, 255, 255, 0.30); }

/* The hero's own gradient sits above the placeholder */
.hero__bg.is-missing::after { bottom: auto; top: 0; }

figcaption {
  margin-top: 1rem;
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ---------- Header ---------- */
.hdr {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  background: rgba(255,255,255,0);
  transition: background 0.5s var(--ease), border-color 0.5s var(--ease);
  border-bottom: 1px solid transparent;
}
.hdr.is-stuck {
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--line-2);
}
/* Over a dark hero, invert until scrolled */
.hdr--over { color: var(--paper); }
.hdr--over.is-stuck { color: var(--ink); }

.hdr__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  height: 84px;
  transition: height 0.5s var(--ease);
}
.hdr.is-stuck .hdr__inner { height: 68px; }

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  flex: none;
}
.brand span {
  font-weight: 300;
  color: currentColor;
  opacity: 0.55;
  padding-left: 0.7rem;
  border-left: 1px solid currentColor;
}

.nav { display: flex; align-items: center; gap: clamp(1.4rem, 2.6vw, 2.6rem); }
.nav a {
  position: relative;
  font-size: 0.635rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding-block: 0.5rem;
  opacity: 0.62;
  transition: opacity 0.35s var(--ease);
}
.nav a::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0.15rem;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.5s var(--ease-out);
}
.nav a:hover { opacity: 1; }
.nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
.nav a[aria-current="page"] { opacity: 1; }

.hdr__end { display: flex; align-items: center; gap: 1rem; flex: none; }
.hdr__end .btn {
  padding: 0.85em 1.6em;
  border-color: currentColor;
  color: currentColor;
}
.hdr__end .btn:hover { background: currentColor; }
.hdr--over:not(.is-stuck) .hdr__end .btn:hover { color: var(--ink); }
.hdr.is-stuck .hdr__end .btn:hover, .hdr:not(.hdr--over) .hdr__end .btn:hover { color: var(--paper); }

.burger { display: none; width: 40px; height: 40px; position: relative; flex: none; }
.burger span {
  position: absolute; left: 50%; top: 50%;
  width: 20px; height: 1px; background: currentColor;
  transition: transform 0.45s var(--ease-out);
}
.burger span:nth-child(1) { transform: translate(-50%, -4px); }
.burger span:nth-child(2) { transform: translate(-50%, 4px); }
body.nav-open .burger span:nth-child(1) { transform: translate(-50%, 0) rotate(45deg); }
body.nav-open .burger span:nth-child(2) { transform: translate(-50%, 0) rotate(-45deg); }

/* Nine nav items plus the Enquire button need about 1185px to fit on one
   line, so the nav collapses to the burger below this width. Measured in the
   browser, with headroom left for a wider fallback font — re-measure if a nav
   item is ever added or renamed. */
@media (max-width: 1220px) {
  .nav { display: none; }
  .burger { display: block; }
}
/* Keep the enquiry button visible down to phone width — it's the primary
   call to action. It only hides once there isn't room beside the burger. */
@media (max-width: 460px) {
  .hdr__end .btn { display: none; }
}

/* Drawer */
.drawer {
  position: fixed;
  inset: 0;
  z-index: 99;
  background: var(--paper);
  color: var(--ink);
  padding: 120px var(--gutter) 3rem;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 2rem;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.5s var(--ease), visibility 0.5s;
  overflow-y: auto;
}
body.nav-open .drawer { opacity: 1; visibility: visible; }
body.nav-open { overflow: hidden; }

.drawer__nav { display: grid; }
.drawer__nav a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-block: 1.15rem;
  border-bottom: 1px solid var(--line-2);
  font-size: clamp(1.1rem, 4.5vw, 1.5rem);
  font-weight: 200;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  transition: padding-left 0.5s var(--ease-out);
}
.drawer__nav a:hover { padding-left: 0.5rem; }
.drawer__nav a em { font-style: normal; font-size: 0.6rem; letter-spacing: 0.2em; color: var(--ink-3); }
.drawer__foot { display: grid; gap: 1rem; justify-items: start; font-size: 0.8rem; color: var(--ink-2); }

/* ---------- Hero ---------- */
.hero {
  position: relative;
  min-height: min(100svh, 900px);
  display: flex;
  align-items: flex-end;
  padding-top: 150px;
  padding-bottom: clamp(3rem, 6vw, 5.5rem);
  overflow: hidden;
  background: var(--black);
  color: var(--paper);
}
.hero__bg { position: absolute; inset: 0; overflow: hidden; }
.hero__bg img,
.hero__bg video { width: 100%; height: 100%; object-fit: cover; }
/* The video sits above its poster image and fades in once it can play */
.hero__bg video {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 1.2s var(--ease);
}
.hero__bg video.is-ready { opacity: 1; }
.hero__bg::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(8,8,8,0.88) 0%, rgba(8,8,8,0.46) 44%, rgba(8,8,8,0.26) 72%, rgba(8,8,8,0.52) 100%);
}
.hero__inner { position: relative; width: 100%; }
.hero .label { color: rgba(255,255,255,0.72); }
.hero .lede { color: rgba(255,255,255,0.72); }
.hero__title { margin-block: 1.6rem 1.8rem; }

.hero__meta {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: 1.4rem;
  border-top: 1px solid var(--line-inv);
  display: flex;
  flex-wrap: wrap;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.62);
}
.hero__meta strong { color: var(--paper); font-weight: 400; }

/* Buttons sit on a dark photograph, so they invert */
.hero .btn {
  border-color: rgba(255, 255, 255, 0.55);
  color: var(--paper);
}
.hero .btn:hover {
  background: var(--paper);
  border-color: var(--paper);
  color: var(--ink);
}

/* Interior page head */
.phead {
  padding-top: clamp(9rem, 15vw, 13rem);
  padding-bottom: clamp(2.5rem, 5vw, 4.5rem);
}
.phead .display { max-width: 18ch; }
.center.phead .display { margin-inline: auto; }

/* ---------- Marquee counters ---------- */
.figures {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: 1px solid var(--line);
}
.figure {
  padding: clamp(2rem, 4vw, 3.25rem) clamp(0.75rem, 2vw, 2rem);
  border-right: 1px solid var(--line);
  display: grid;
  gap: 0.75rem;
  justify-items: center;
  text-align: center;
}
.figure:last-child { border-right: 0; }
.figure__n {
  font-size: clamp(1.7rem, 3.4vw, 2.75rem);
  font-weight: 100;
  letter-spacing: 0.06em;
  line-height: 1;
}
.figure__n sup { font-size: 0.4em; top: -0.9em; position: relative; }
@media (max-width: 780px) {
  .figures { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .figure:nth-child(2) { border-right: 0; }
  .figure:nth-child(-n+2) { border-bottom: 1px solid var(--line); }
}

/* Three-up variant. The row above is built for four; with three items a
   plain four-column grid leaves a dead cell and a hairline running into
   nothing. On a phone the third drops to its own row and spans it, rather
   than sitting in a half-width column with a gap beside it. */
.figures--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 780px) {
  /* .figures--3 sits after the base breakpoint rule and would otherwise
     keep three columns on a phone, leaving an empty cell beside the pair. */
  .figures--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .figures--3 .figure:nth-child(3) { grid-column: 1 / -1; border-right: 0; }
}

/* ---------- Split ---------- */
.split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(2rem, 5vw, 5.5rem);
  align-items: center;
}
.split--rev .split__media { order: 2; }
.split__body { display: grid; gap: 1.6rem; justify-items: start; align-content: center; }
/* Set when an optional image slot is empty — the text takes the full width */
.split--solo { grid-template-columns: minmax(0, 1fr); max-width: 760px; }
@media (max-width: 900px) {
  .split { grid-template-columns: minmax(0, 1fr); }
  .split--rev .split__media { order: 0; }
}

/* ---------- Tile (zone card) ---------- */
.tile { display: block; }
.tile .media { margin-bottom: 1.4rem; }
.tile__body { display: grid; gap: 0.6rem; }
.tile__n { font-size: 0.6rem; letter-spacing: 0.24em; color: var(--ink-3); }
.tile p { font-size: 0.875rem; max-width: 36ch; }
.tile:hover .h3 { opacity: 0.55; }
.tile .h3 { transition: opacity 0.4s var(--ease); }

/* ---------- Lists ---------- */
.flist { display: grid; list-style: none; padding: 0; border-top: 1px solid var(--line); width: 100%; }
.flist li {
  padding-block: 0.95rem;
  border-bottom: 1px solid var(--line);
  font-size: 0.85rem;
  font-weight: 300;
  color: var(--ink-2);
}

.specs { display: grid; border-top: 1px solid var(--line); width: 100%; }
.specs > div {
  display: grid;
  grid-template-columns: minmax(0, 0.4fr) minmax(0, 1fr);
  gap: 1.5rem;
  padding-block: 1.1rem;
  border-bottom: 1px solid var(--line);
  align-items: baseline;
}
.specs dt { font-size: 0.6rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink-3); }
.specs dd { margin: 0; font-size: 0.875rem; color: var(--ink-2); }
@media (max-width: 620px) { .specs > div { grid-template-columns: minmax(0, 1fr); gap: 0.35rem; } }

/* ---------- Quote ---------- */
.quote {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(1.5rem, 3.6vw, 2.9rem);
  line-height: 1.28;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  max-width: 22ch;
  text-wrap: balance;
}

/* ---------- Full bleed ---------- */
.bleed { position: relative; overflow: hidden; background: var(--black); }
.bleed img { width: 100%; height: clamp(340px, 68vh, 720px); object-fit: cover; }
.bleed .media { height: clamp(340px, 68vh, 720px); }
.bleed__cap {
  position: absolute; inset: auto 0 0 0;
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
  color: var(--paper);
}
.bleed::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(8,8,8,0.72), rgba(8,8,8,0.10) 55%, rgba(8,8,8,0.28));
  pointer-events: none;
}
.bleed__cap { z-index: 2; }

/* ---------- Member perks ---------- */
.perks {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(0.7rem, 1.3vw, 1.05rem);
}
@media (max-width: 1040px) { .perks { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .perks { grid-template-columns: minmax(0, 1fr); } }

.perk {
  display: grid;
  gap: 0.45rem;
  align-content: start;
  padding: clamp(1.4rem, 2.1vw, 1.85rem);
  border: 1px solid var(--line);
  transition: border-color 0.45s var(--ease), background 0.45s var(--ease);
}
.perk:hover { border-color: rgba(24, 24, 24, 0.32); background: var(--paper-2); }

/* Partner mark. Shows a monogram until a real logo is dropped into
   images/partners/ — the monogram is the designed state, not a placeholder,
   so the page looks finished either way. */
.perk__mark {
  position: relative;
  width: 104px;
  height: 64px;
  border-radius: 5px;
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
  overflow: hidden;
  margin-bottom: 1rem;
  background: var(--paper);
  transition: border-color 0.4s var(--ease), background 0.4s var(--ease);
}
.perk__mark em {
  font-style: normal;
  font-size: 0.78rem;
  font-weight: 400;
  letter-spacing: 0.12em;
  color: var(--ink-2);
}
/* Most real logos are horizontal wordmarks, so the plate is wide and the
   image is contained inside it rather than cropped to fill. */
.perk__mark img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 8px 11px;
  display: none;
}
.perk__mark.has-logo { background: var(--paper); }
.perk__mark.has-logo img { display: block; }
.perk__mark.has-logo em { display: none; }

.perk:hover .perk__mark { border-color: var(--ink); background: var(--paper-2); }
.inverse .perk__mark { background: transparent; border-color: var(--line-inv); }
.inverse .perk__mark em { color: rgba(255,255,255,0.72); }
.inverse .perk:hover .perk__mark { border-color: rgba(255,255,255,0.6); background: rgba(255,255,255,0.06); }
.perk__offer {
  font-size: clamp(1.7rem, 3vw, 2.4rem);
  font-weight: 100;
  letter-spacing: 0.01em;
  line-height: 1;
}
.perk__for {
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.perk__name {
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: -0.005em;
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--line);
}
.perk__meta { font-size: 0.76rem; color: var(--ink-3); line-height: 1.55; }
.perk__code {
  justify-self: start;
  margin-top: 0.35rem;
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  border: 1px solid var(--line-str, rgba(24,24,24,0.28));
  padding: 0.45em 0.8em;
  border-radius: 100px;
}

/* Club's own offers — emphasised on a dark band */
.perk--house { padding: clamp(1.7rem, 2.8vw, 2.3rem); }
.inverse .perk { border-color: var(--line-inv); }
.inverse .perk:hover { border-color: rgba(255,255,255,0.42); background: rgba(255,255,255,0.045); }
.inverse .perk__name { border-top-color: var(--line-inv); }
.inverse .perk { border-bottom-color: var(--line-inv); }
.inverse .perk__for { color: rgba(255,255,255,0.55); }
.inverse .perk__meta { color: rgba(255,255,255,0.62); }
.inverse .perk__code { border-color: var(--line-inv); }

/* ---------- Third-party embed ----------
   A cross-origin iframe cannot report its content height, so the height is
   set here rather than by the form inside it. If the embedded form is taller
   than this it scrolls internally; raise --embed-h to give it more room. */
.embed {
  --embed-h: 680px;
  position: relative;
  width: 100%;
  min-height: var(--embed-h);
  background: var(--paper);
}
.embed__frame {
  display: block;
  width: 100%;
  height: var(--embed-h);
  min-height: 500px;
  border: 0;
  color-scheme: light;   /* keeps the embed light even in a dark OS theme */
}

/* Loading state.
   The form is a third-party embed and takes a few seconds to answer. Without
   this the visitor stares at blank white space and assumes it's broken.
   Scoped to .js so that if JavaScript fails the form is simply visible. */
.js .embed__frame {
  opacity: 0;
  transition: opacity 0.5s var(--ease);
}
.js .embed.is-loaded .embed__frame { opacity: 1; }

.js .embed__skeleton {
  position: absolute;
  inset: 0;
  display: grid;
  align-content: start;
  gap: 1.6rem;
  padding: 0.5rem 0 0;
  transition: opacity 0.4s var(--ease), visibility 0.4s;
}
.js .embed.is-loaded .embed__skeleton { opacity: 0; visibility: hidden; }

.embed__skeleton span {
  display: block;
  height: 44px;
  border-radius: 3px;
  background: linear-gradient(100deg, var(--paper-2) 30%, var(--paper-3) 50%, var(--paper-2) 70%);
  background-size: 220% 100%;
  animation: embed-shimmer 1.5s linear infinite;
}
.embed__skeleton span:nth-child(1) { width: 32%; height: 12px; }
.embed__skeleton span:nth-child(4) { width: 60%; }
.embed__skeleton span:nth-child(5) { width: 40%; height: 46px; border-radius: 100px; }

.embed__note {
  position: absolute;
  left: 0; bottom: 1.5rem;
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.js .embed.is-loaded .embed__note { opacity: 0; visibility: hidden; transition: opacity 0.3s; }

@keyframes embed-shimmer {
  from { background-position: 120% 0; }
  to   { background-position: -120% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .embed__skeleton span { animation: none; background: var(--paper-2); }
}
@media (max-width: 900px) { .embed { --embed-h: 760px; } }
@media (max-width: 480px) { .embed { --embed-h: 820px; } }

/* ---------- Timetable ---------- */
.tt {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 clamp(2rem, 5vw, 4.5rem);
  border-top: 1px solid var(--ink);
}
@media (max-width: 820px) { .tt { grid-template-columns: minmax(0, 1fr); } }

.tt__day { padding-block: clamp(1.5rem, 2.6vw, 2.1rem); border-bottom: 1px solid var(--line); }

.tt__name {
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  margin-bottom: 1rem;
  display: flex;
  align-items: center;
  gap: 0.7rem;
}
.tt__new {
  font-style: normal;
  font-size: 0.55rem;
  letter-spacing: 0.16em;
  padding: 0.35em 0.7em;
  border-radius: 100px;
  background: var(--ink);
  color: var(--paper);
}

.tt__list { list-style: none; padding: 0; display: grid; gap: 0.2rem; }
.tt__list li {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr) auto;
  gap: 1rem;
  align-items: baseline;
  padding-block: 0.7rem;
  border-bottom: 1px solid var(--line-2);
}
.tt__list li:last-child { border-bottom: 0; }

.tt__time {
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.tt__class {
  font-size: 0.9rem;
  font-weight: 400;
  color: var(--ink);
  letter-spacing: -0.005em;
}
.tt__note {
  display: block;
  font-style: normal;
  font-size: 0.6rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-top: 0.25rem;
}
.tt__who {
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
  text-align: right;
  white-space: nowrap;
}
.tt__day--rest .tt__rest { font-size: 0.85rem; color: var(--ink-3); }

@media (max-width: 560px) {
  .tt__list li { grid-template-columns: minmax(0, 1fr); gap: 0.25rem; }
  .tt__who { text-align: left; }
}

/* ---------- Shorter nav (clubs with fewer pages) ----------
   Belrose carries nine nav items and collapses to the burger at 1220px.
   Carlingford has six, so holding it to Belrose's breakpoint would hide a
   nav that still fits comfortably.

   THE BRAND TEXT FEEDS INTO THIS, which is easy to forget. Measured in the
   browser at each club's own longest header:

     JT | Carlingford              962px   (before the brand was renamed)
     Plus Fitness | Carlingford   1052px
     Plus Fitness | Frenchs Forest 1079px  <- the widest so far

   So this collapses at 1100: the widest club clears it with room for a wider
   fallback font if Inter fails to load. Re-measure if a club gains a nav item
   or a longer name than "Frenchs Forest". */
.hdr--sm .nav { display: flex; }
.hdr--sm .burger { display: none; }
@media (max-width: 1100px) {
  .hdr--sm .nav { display: none; }
  .hdr--sm .burger { display: block; }
}

/* ---------- Pending states ----------
   For things a club genuinely doesn't have yet: a class timetable, coach
   profiles, an enquiry form. An honest empty state beats a grid of fake
   placeholders, and beats silently omitting the section — a visitor can see
   the thing exists and that the detail is coming. */
.pending {
  display: grid;
  gap: 0.75rem;
  padding: clamp(1.75rem, 3.5vw, 2.75rem);
  border: 1px dashed var(--ink-4);
  border-radius: 3px;
  background: var(--paper-2);
}
.pending p { font-size: 0.85rem; max-width: 58ch; }
.pending .h2, .pending .h3 { margin-top: 0.15rem; }

/* A single unsupplied detail inline — an address, a phone number. Dashed so
   it reads as a blank waiting to be filled, never as real content. */
.tbc {
  color: var(--ink-3);
  border-bottom: 1px dashed var(--ink-4);
  font-style: normal;
}

/* ---------- Club directory (group landing page) ----------
   Four clubs across on a wide screen, two on a tablet, one on a phone.
   Cards for clubs that aren't live yet keep the same shape but don't
   pretend to be links — see .club--soon. */
.clubs {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.5rem, 2.6vw, 2.25rem);
  align-items: start;
}
@media (max-width: 1040px) { .clubs { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px)  { .clubs { grid-template-columns: minmax(0, 1fr); } }

.club { display: grid; gap: 1.1rem; align-content: start; }
.club .media { margin-bottom: 0; }
.club__body { display: grid; gap: 0.4rem; }

.club__name {
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  font-weight: 300;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  line-height: 1.2;
  transition: opacity 0.4s var(--ease);
}
.club__meta {
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
}
a.club:hover .club__name { opacity: 0.55; }

/* A club with no pages yet. It reads as deliberately not-yet rather than
   broken: the card is quieter, and it is a div, not an anchor, so there is
   nothing to click and nothing to disappoint. */
.club--soon .media { opacity: 0.55; }
.club--soon .club__name { color: var(--ink-2); }

/* ---------- Campaign banner ----------
   Sits at the top of the hero, above the eyebrow. Solid paper on the dark
   video so it actually reads as an offer rather than another label — it is
   the one element on the page allowed to shout. Inverts on hover like a
   filled button.

   It is time-limited by nature: when the campaign ends, delete the .promo
   block from index.html. Nothing else depends on it. */
.promo {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5em 0.85em;
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
  padding: 0.9em 1.5em;
  border: 1px solid var(--paper);
  border-radius: 100px;
  background: var(--paper);
  color: var(--ink);
  font-size: 0.62rem;
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  line-height: 1;
  transition: background 0.45s var(--ease), color 0.45s var(--ease);
}
.promo:hover { background: transparent; color: var(--paper); }
.promo strong { color: inherit; font-weight: 500; }
.promo__plus { opacity: 0.5; }

/* The end date is the quiet half — present, but not competing with the offer */
.promo em {
  font-style: normal;
  padding-left: 0.85em;
  border-left: 1px solid rgba(24, 24, 24, 0.22);
  opacity: 0.62;
}
.promo:hover em { border-left-color: rgba(255, 255, 255, 0.3); }

/* On a phone the pill would run past the viewport, so it wraps to a block
   and the date drops onto its own line without a divider. */
@media (max-width: 560px) {
  .promo { border-radius: 18px; padding: 1em 1.25em; }
  .promo em { padding-left: 0; border-left: 0; flex-basis: 100%; }
}

/* ---------- Coach profiles ----------
   Three-up on a wide screen, one column on a phone. The photographs are
   cropped out of the PT profile posters and are only 460-600px wide, so the
   grid is capped at three columns on purpose: any wider a column and they
   would be running past their own resolution. See cut-coach-photos.py. */
.coaches {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 3.5vw, 3.25rem) clamp(1.5rem, 2.6vw, 2.5rem);
  align-items: start;
}
@media (max-width: 1040px) { .coaches { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* Two coaches rather than three. A plain three-column grid would leave a gap
   where the third should be, so the pair get a narrower container and sit
   centred under the heading instead of hanging off to one side. */
.coaches--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); max-width: 780px; margin-inline: auto; }

/* A single coach. Same idea as .coaches--2: the card gets a sensible width and
   sits centred under the heading rather than hanging off to one side. The photo
   column is capped so one profile doesn't render a portrait the size of a door. */
.coaches--1 { grid-template-columns: minmax(0, 1fr); max-width: 760px; margin-inline: auto; }
@media (min-width: 700px) {
  .coaches--1 .coach { grid-template-columns: minmax(0, 300px) minmax(0, 1fr); gap: clamp(1.75rem, 3vw, 2.5rem); align-items: start; }
}
@media (max-width: 680px)  { .coaches { grid-template-columns: minmax(0, 1fr); } }

.coach { display: grid; gap: 1.35rem; align-content: start; }

/* The three headshots come from different shoots — one outdoors, one against
   a blue wall, one cut out on black — so they're framed identically and
   anchored to the top, which is the most the crop can do to settle them down. */
.coach__shot img { object-position: 50% 18%; }

.coach__body { display: grid; gap: 0.55rem; align-content: start; }

.coach__name {
  font-size: clamp(1.05rem, 1.6vw, 1.25rem);
  font-weight: 300;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  line-height: 1.2;
}
.coach__role {
  font-size: 0.6rem;
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.coach__bio { font-size: 0.85rem; margin-top: 0.5rem; max-width: none; }

.coach__specs { display: grid; margin-top: 0.9rem; border-top: 1px solid var(--line); }
.coach__specs > div { padding-block: 0.85rem; border-bottom: 1px solid var(--line-2); }
.coach__specs dt {
  font-size: 0.575rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 0.4rem;
}
.coach__specs dd { margin: 0; font-size: 0.8rem; color: var(--ink-2); line-height: 1.6; }

.coach__contact { display: flex; flex-wrap: wrap; gap: 0.6rem 1.4rem; margin-top: 0.9rem; }
.coach__contact .tlink { font-size: 0.6rem; }

/* ---------- Menu (Apex Shake Bar) ---------- */
.menu__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem 2.5rem;
  margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem);
}
.menu__price { display: grid; gap: 0.6rem; justify-items: end; text-align: right; }
@media (max-width: 620px) { .menu__price { justify-items: start; text-align: left; } }

.menu {
  list-style: none;
  padding: 0;
  display: grid;
  width: 100%;
  border-top: 1px solid var(--ink);
}

.mi {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 0 clamp(1.15rem, 2.4vw, 2rem);
  align-items: center;
  padding-block: clamp(1.1rem, 2.2vw, 1.6rem);
  border-bottom: 1px solid var(--line);
}

/* The ingredient photograph, cut from the menu board. Two things here are
   load-bearing:

   The board's cream is painted behind it, so the square tile and the round
   plate meet invisibly — change one and you must change the other.

   And the size is a fixed 88px, not a fluid clamp, because the 1x file holds
   the artwork at its original pixel size: at 88px it renders 1:1 with no
   scaling at all, which is the sharpest this source can be. A fluid width
   would put it on a fractional scale at most viewports and soften it again.
   88 is also DISPLAY in cut-shake-photos.py — the two have to agree. */
.mi__shot {
  width: 88px;
  height: 88px;
  flex: none;
  border-radius: 50%;
  background: var(--cream);
  object-fit: cover;
  transition: transform 0.6s var(--ease-out);
}
.mi:hover .mi__shot { transform: scale(1.05); }

.mi__name {
  font-size: clamp(1.02rem, 1.9vw, 1.3rem);
  font-weight: 300;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  line-height: 1.2;
}
.mi__desc { font-size: 0.83rem; color: var(--ink-3); margin-top: 0.55rem; max-width: 52ch; }

/* Energy sits in a fixed right-hand column so the numbers line up down the
   list. Tabular figures keep the digits on the same rhythm. */
.mi__energy {
  display: grid;
  gap: 0.25rem;
  justify-items: end;
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.mi__cal { font-size: 0.98rem; font-weight: 400; letter-spacing: 0.05em; }
.mi__kj {
  font-style: normal;
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}
/* On a phone the photograph keeps its column and the energy drops under the
   name, so the row still reads as one item rather than three fragments. */
@media (max-width: 560px) {
  .mi { grid-template-columns: auto minmax(0, 1fr); align-items: start; }
  /* Phones are high-density, so they take the 2x file and stay sharp even
     though this width isn't 1:1 with it. */
  .mi__shot { width: 72px; height: 72px; }
  .mi__energy {
    grid-column: 2;
    display: flex;
    gap: 0.85rem;
    align-items: baseline;
    justify-items: start;
    text-align: left;
    margin-top: 0.6rem;
  }
}

/* ---------- Reel (vertical video) ---------- */
.reel {
  position: relative;
  width: 100%;
  max-width: 420px;
  aspect-ratio: 9 / 16;
  background: var(--ink);
  overflow: hidden;
  isolation: isolate;
}
.reel video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.reel__sound {
  position: absolute;
  right: 0.9rem;
  bottom: 0.9rem;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 0.55em;
  padding: 0.7em 1.1em;
  border: 1px solid rgba(255, 255, 255, 0.45);
  border-radius: 100px;
  background: rgba(12, 12, 12, 0.45);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: #fff;
  font-size: 0.58rem;
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  line-height: 1;
  transition: background 0.35s var(--ease), border-color 0.35s var(--ease);
}
.reel__sound:hover { background: rgba(12, 12, 12, 0.75); border-color: rgba(255,255,255,0.8); }

.reel-wrap { display: grid; justify-items: center; gap: 1.25rem; }

/* ---------- Rail ---------- */
.rail {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: clamp(230px, 26vw, 360px);
  gap: clamp(0.75rem, 1.4vw, 1.4rem);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-inline: var(--gutter);
  padding-bottom: 1.25rem;
  scrollbar-width: thin;
}
.rail > * { scroll-snap-align: start; }
.rail::-webkit-scrollbar { height: 2px; }
.rail::-webkit-scrollbar-thumb { background: var(--ink-4); }

/* ---------- Plans ---------- */
.plan {
  border: 1px solid var(--line);
  padding: clamp(1.75rem, 3vw, 2.6rem);
  display: grid;
  gap: 1.6rem;
  align-content: start;
  justify-items: start;
  transition: background 0.5s var(--ease), border-color 0.5s var(--ease);
}
.plan:hover { background: var(--paper-2); }
.plan--feature { background: var(--black); color: var(--paper); border-color: var(--black); }
.plan--feature:hover { background: var(--black); }
.plan--feature p, .plan--feature .flist li { color: rgba(255,255,255,0.62); }
.plan--feature .label { color: rgba(255,255,255,0.55); }
.plan--feature .flist, .plan--feature .flist li { border-color: var(--line-inv); }
.plan--feature .btn { border-color: var(--paper); color: var(--paper); }
.plan--feature .btn:hover { background: var(--paper); color: var(--ink); }
.plan__amt { font-size: clamp(2rem, 4vw, 2.9rem); font-weight: 100; letter-spacing: 0.03em; line-height: 1; }
.plan__per { font-size: 0.6rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink-3); }
.plan--feature .plan__per { color: rgba(255,255,255,0.5); }

/* ---------- Accordion ---------- */
.acc { border-top: 1px solid var(--line); }
.acc details { border-bottom: 1px solid var(--line); }
.acc summary {
  list-style: none;
  cursor: pointer;
  padding-block: 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2rem;
  font-size: 0.78rem;
  font-weight: 400;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  transition: opacity 0.35s var(--ease);
}
.acc summary::-webkit-details-marker { display: none; }
.acc summary:hover { opacity: 0.55; }
.acc summary::after {
  content: "";
  width: 11px; height: 11px; flex: none;
  background:
    linear-gradient(var(--ink), var(--ink)) center/11px 1px no-repeat,
    linear-gradient(var(--ink), var(--ink)) center/1px 11px no-repeat;
  transition: transform 0.45s var(--ease-out);
}
.acc details[open] summary::after { transform: rotate(45deg); }
.acc__body { padding-bottom: 1.75rem; }
.acc__body p { font-size: 0.875rem; }

/* ---------- Forms ---------- */
.field { display: grid; gap: 0.6rem; width: 100%; }
.field label { font-size: 0.6rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--ink-3); }
.field input, .field textarea, .field select {
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line);
  padding: 0.7rem 0;
  font-size: 0.9rem;
  font-weight: 300;
  border-radius: 0;
  width: 100%;
  transition: border-color 0.4s var(--ease);
}
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none;
  border-bottom-color: var(--ink);
}
.field textarea { resize: vertical; min-height: 110px; }
form.stack { gap: 1.9rem; width: 100%; }

/* ---------- Footer ---------- */
.ftr { background: var(--black); color: var(--paper); padding-block: clamp(4rem, 8vw, 6.5rem) 2.5rem; }
.ftr__top {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
  padding-bottom: clamp(3rem, 6vw, 5rem);
}
@media (max-width: 900px) { .ftr__top { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .ftr__top { grid-template-columns: minmax(0, 1fr); } }

.ftr__col { display: grid; gap: 0.85rem; align-content: start; justify-items: start; }
.ftr__col .label { color: rgba(255,255,255,0.42); margin-bottom: 0.3rem; }
.ftr__col a, .ftr__col p {
  font-size: 0.8rem;
  font-weight: 300;
  color: rgba(255,255,255,0.66);
  max-width: none;
  transition: color 0.35s var(--ease);
}
.ftr__col a:hover { color: var(--paper); }

.ftr__mark {
  font-size: clamp(2.6rem, 13vw, 10rem);
  font-weight: 100;
  letter-spacing: 0.06em;
  line-height: 0.92;
  color: rgba(255,255,255,0.10);
  border-top: 1px solid var(--line-inv);
  padding-top: clamp(2rem, 4vw, 3rem);
  user-select: none;
  text-transform: uppercase;
}
.ftr__bot {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1rem;
  padding-top: 2rem;
  font-size: 0.6rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(255,255,255,0.34);
}

/* ---------- Reveal ---------- */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 1s var(--ease-out), transform 1s var(--ease-out);
  transition-delay: var(--d, 0ms);
}
.js [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
  .js [data-reveal] { opacity: 1; transform: none; }
}

/* ---------- Utilities ---------- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; top: -60px; left: var(--gutter); z-index: 200;
  background: var(--ink); color: var(--paper); padding: 0.75rem 1.2rem;
  font-size: 0.65rem; letter-spacing: 0.2em; text-transform: uppercase;
  transition: top 0.3s var(--ease);
}
.skip:focus { top: 0; }
