/* Registered custom properties. Typing --sc-p gives every calc() a valid 0
   outside an act instead of an invalid substitution, and typing the pointer
   pair lets the 3D stages interpolate them instead of snapping. */
@property --sc-p { syntax: "<number>"; inherits: true; initial-value: 0; }
@property --mx   { syntax: "<number>"; inherits: true; initial-value: 0.5; }
@property --my   { syntax: "<number>"; inherits: true; initial-value: 0.5; }

/* ============================================================================
   Ipic Play. Shared design system (loads after scrollcraft.css on every page)
   ----------------------------------------------------------------------------
   TOKENS      :root overrides the six scrollcraft colour roles and two fonts.
               Grounds: .ground--navy .ground--blue .ground--pad .ground--yellow
               .ground--sand .ground--off (each paints its background, restates
               ink, ink-soft, accent AND color, so inherited text re-inks).
               Dark grounds also set --focus-ring to white.
   CHROME      .bar (fixed yellow bar, 64px / 56px phone), .bar__logo,
               .bar__nav, .bar__cta, .bar__menu (phone toggle), #mat (8px red
               strip under the bar), .menu (full-height yellow sheet, phone).
               --chrome = bar + mat height; body padding-top is NOT applied,
               pages start their first block with padding-top: var(--chrome).
   TYPE        .t-display (Bricolage 800, tight), .t-xl .t-lg .t-md .t-sm
               .t-label (Nunito 700, small, wide tracking). .t-num for tabular
               figures. Body prose is Nunito via --sc-font-text.
   BUTTONS     .btn (navy block, white text), .btn--on-dark (yellow block, navy
               text), .btn--white (white block, navy text), .btn--lg. 4px radius
               everywhere. 44px min tap height. Press = scale(0.97).
               .link (underlined text link, 2px offset).
   LABELS      .chip (theme chip: white on yellow ground, navy ink, 4px radius),
               .price-table (real table, tabular nums), .hours (dl grid).
   LAYOUT      .wrap (max 82rem, gutter), .page-section (fluid block padding),
               .split (two columns, stacks under 860px), .stack (spacing).
   FOOTER      .site-foot (blue ground, links, legal PDFs, socials, credit line)
   ========================================================================== */

/* Fonts, self-hosted (latin subsets straight from Google Fonts v9 / v32).
   Removes the render-blocking third-party stylesheet and its two extra hops. */
@font-face {
  font-family: 'Bricolage Grotesque';
  font-style: normal; font-weight: 700 800; font-stretch: 100%; font-display: swap;
  src: url(assets/fonts/bricolage-grotesque-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* one variable face, one weight range, ONE download. Two rules over the same
   file made the browser fetch nunito-latin.woff2 twice, 38 KB of it inside the
   LCP window. */
@font-face {
  font-family: 'Nunito';
  font-style: normal; font-weight: 400 700; font-display: swap;
  src: url(assets/fonts/nunito-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  --sc-canvas: #F4F1EC;
  --sc-surface: #FFFFFF;
  --sc-ink: #101321;
  --sc-ink-soft: #4A4F63;
  --sc-accent: #C8281A;
  --sc-accent-ink: #FFFFFF;
  --sc-font-display: "Bricolage Grotesque", "Avenir Next Condensed", "Helvetica Neue", Arial, sans-serif;
  --sc-font-text: "Nunito", "Avenir Next", "Segoe UI", system-ui, sans-serif;
  --sc-font-mono: "Nunito", "Avenir Next", system-ui, sans-serif;

  --navy: #101321;
  --blue: #0F5E8F;
  --pad: #B9231A;
  --yellow: #F5CE26;
  --sand: #E8E1D4;
  --off: #F4F1EC;
  --white: #FFFFFF;
  --logo-red: #EF3F2C;
  --logo-blue: #1F96D3;

  --focus-ring: var(--sc-accent);
  --sc-r-sm: 4px; --sc-r-md: 4px; --sc-r-lg: 4px; --sc-r-pill: 4px;
  --sc-shadow-color: 230 30% 6%;

  --bar-h: 64px;
  --mat-h: 8px;
  --chrome: calc(var(--bar-h) + var(--mat-h));
  --logo-h: 44px;

  --sc-t-hero: clamp(2.4rem, 1.3rem + 3.4vw, 4.4rem);
  --sc-track-tight: -0.03em;

  /* Readability floor. The engine's small step bottoms out at 14px on a phone
     and 15.2px on desktop, which is below what a parent reading a price note
     on a bus should be handed. Raised so every body block on the site computes
     at 16px or more on a phone and 17px or more on desktop. Labels (--sc-t-xs)
     are not body copy but were lifted off 12px as well. */
  --sc-t-xs: clamp(0.8125rem, 0.79rem + 0.1vw, 0.875rem);
  --sc-t-sm: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);

  /* height of the phone action bar, so the footer credit is never under it */
  --actbar-h: 0px;
}
@media (max-width: 700px) {
  :root { --bar-h: 56px; --logo-h: 36px; }
}

html { scroll-padding-top: var(--chrome); }
/* The engine centres a focused control with behavior:'instant' precisely so
   focus is never off screen mid-glide; the browser's own sequential-focus
   scroll has to match it, or Tab animates for 900 ms with the target invisible. */
html { scroll-behavior: auto; }
/* display cutouts: the page opts into viewport-fit=cover, so pay the rent */
body { --sc-gutter: max(clamp(1.25rem, 5vw, 5.5rem), env(safe-area-inset-left), env(safe-area-inset-right)); }
body { background: var(--sc-canvas); color: var(--sc-ink); }

/* -------------------------------------------------------------- grounds -- */
.ground--dark,
.ground--navy, .ground--blue, .ground--pad {
  --sc-ink: #FFFFFF; --sc-ink-soft: #B9C3D6; --sc-accent: #FF6A57; --sc-accent-ink: #101321;
  --focus-ring: #FFFFFF;
  color: var(--sc-ink);
}
.ground--navy { background: var(--navy); --sc-canvas: #101321; }
.ground--blue { background: var(--blue); --sc-canvas: #0F5E8F; }
.ground--pad { background: var(--pad); --sc-canvas: #B9231A; }
.ground--yellow {
  background: var(--yellow); --sc-canvas: #F5CE26;
  --sc-ink: #101321; --sc-ink-soft: #3A3D4C; --sc-accent: #B9231A; --sc-accent-ink: #FFFFFF;
  --focus-ring: #101321; color: var(--sc-ink);
}
.ground--sand {
  background: var(--sand); --sc-canvas: #E8E1D4;
  --sc-ink: #101321; --sc-ink-soft: #4A4F63; --sc-accent: #C8281A; --sc-accent-ink: #FFFFFF;
  --focus-ring: #C8281A; color: var(--sc-ink);
}
.ground--off {
  background: var(--off); --sc-canvas: #F4F1EC;
  --sc-ink: #101321; --sc-ink-soft: #4A4F63; --sc-accent: #C8281A; --sc-accent-ink: #FFFFFF;
  --focus-ring: #C8281A; color: var(--sc-ink);
}

/* ---------------------------------------------------- browser surfaces -- */
:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 3px; border-radius: 4px; }
::selection { background: var(--yellow); color: var(--navy); }
.skip {
  position: absolute; left: var(--sc-4); top: -100px; z-index: 200;
  background: var(--navy); color: #fff; padding: var(--sc-3) var(--sc-4);
  border-radius: 4px; font-weight: 700; text-decoration: none;
}
.skip:focus-visible { top: calc(var(--chrome) + var(--sc-2)); outline-color: var(--yellow); }
.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0);
  clip-path: inset(50%); white-space: nowrap;
}

/* ------------------------------------------------------------------ type -- */
.t-display, .t-xl, .t-lg, .t-md {
  font-family: var(--sc-font-display);
  font-weight: 800;
  font-variation-settings: "opsz" 96;
  line-height: var(--sc-leading-none);
  letter-spacing: var(--sc-track-tight);
  text-wrap: balance;
  margin: 0;
}
.t-display { font-size: var(--sc-t-3xl); }
.t-xl { font-size: var(--sc-t-2xl); letter-spacing: var(--sc-track-snug); }
.t-lg { font-size: var(--sc-t-xl); letter-spacing: var(--sc-track-snug); line-height: 1.04; }
.t-md { font-size: var(--sc-t-lg); font-weight: 700; letter-spacing: var(--sc-track-normal); line-height: 1.12; font-variation-settings: "opsz" 40; }
.t-sm { font-size: var(--sc-t-sm); }
.t-label {
  font-family: var(--sc-font-text); font-weight: 700; font-size: var(--sc-t-xs);
  letter-spacing: 0.06em; text-transform: uppercase; color: var(--sc-ink-soft);
}
.t-num, .price-table td, .price-table th { font-variant-numeric: tabular-nums; }
.lede { font-size: var(--sc-t-lg); line-height: 1.5; max-width: 46ch; text-wrap: pretty; margin: 0; }
.prose { max-width: var(--sc-measure); text-wrap: pretty; margin: 0; }
.prose + .prose { margin-top: var(--sc-4); }
p { margin: 0; text-wrap: pretty; }
.ground--dark p, .ground--navy p, .ground--blue p, .ground--pad p { letter-spacing: 0.005em; }

/* ---------------------------------------------------------------- layout -- */
.wrap { width: 100%; max-width: var(--sc-maxw); margin-inline: auto; padding-inline: var(--sc-gutter); }
.page-section { padding-block: var(--sc-section); }
.page-section--first { padding-top: calc(var(--chrome) + var(--sc-8)); }
.split { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sc-7); align-items: start; }
@media (max-width: 860px) { .split { grid-template-columns: 1fr; gap: var(--sc-6); } }
.stack > * + * { margin-top: var(--sc-4); }
.stack > :is(h1, h2, h3) { margin-top: var(--sc-7); }
.stack > :is(h1, h2, h3):first-child { margin-top: 0; }
.rule { height: 1px; border: 0; background: var(--sc-hairline-strong); margin: 0; }

/* --------------------------------------------------------------- buttons -- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sc-2);
  min-height: 44px; padding: 0 var(--sc-5);
  background: var(--navy); color: #fff;
  font-family: var(--sc-font-display); font-weight: 800; font-variation-settings: "opsz" 40;
  font-size: var(--sc-t-base); letter-spacing: -0.005em; line-height: 1;
  text-decoration: none; border: 0; border-radius: 4px; cursor: pointer;
  white-space: nowrap;
  transition: transform 140ms var(--sc-ease-out), background-color 140ms var(--sc-ease-out), box-shadow 140ms var(--sc-ease-out);
  box-shadow: var(--sc-e1);
}
.btn:hover { background: #1B2036; box-shadow: var(--sc-e2); }
.btn:active { transform: scale(0.97); box-shadow: none; }
.btn--on-dark { background: var(--yellow); color: var(--navy); }
.btn--on-dark:hover { background: #FFD83A; }
.btn--white { background: #fff; color: var(--navy); }
.btn--white:hover { background: #FFF8DB; }
.btn--lg { min-height: 56px; padding-inline: var(--sc-6); font-size: var(--sc-t-lg); }
.btn--block { display: flex; width: 100%; }
.btn:focus-visible { outline-color: var(--focus-ring); }
.link { color: inherit; font-weight: 700; text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 0.2em; padding-block: 0.7em; }
.link:hover { text-decoration-thickness: 3px; }
@media (hover: none) { .btn:hover { background: var(--navy); } .btn--on-dark:hover { background: var(--yellow); } .btn--white:hover { background: #fff; } }

/* the bar and the phone action bar are fixed, so the browser's own
   scroll-a-focused-control-into-view has to keep clear of both */
html { scroll-padding-top: calc(var(--chrome) + 8px); scroll-padding-bottom: calc(var(--actbar-h) + 8px); }

/* ---------------------------------------------------------------- chrome -- */
.bar {
  position: fixed; inset: 0 0 auto 0; height: var(--bar-h); z-index: 90;
  background: var(--yellow); color: var(--navy);
  display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: var(--sc-4);
  padding-inline: max(clamp(1rem, 3vw, 2.5rem), env(safe-area-inset-left), env(safe-area-inset-right));
  --focus-ring: #101321;
}
.bar__logo {
  position: relative; display: inline-flex; align-items: center; min-height: 44px;
  line-height: 0; border-radius: 4px;
  transform-origin: 50% 100%; will-change: transform;
}
.bar__logo img { height: var(--logo-h); width: auto; transition: opacity 160ms var(--sc-ease-out); }
/* the white mark, for when the wordmark is off the yellow bar and on the red pad */
.bar__logo-w { position: absolute; left: 0; top: 50%; transform: translateY(-50%); opacity: 0; }
.bar__logo.is-white > img:first-child { opacity: 0; }
.bar__logo.is-white .bar__logo-w { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .bar__logo img { transition: none; } }
.bar__nav { display: flex; justify-content: center; gap: clamp(1rem, 2.4vw, 2.25rem); }
.bar__nav a {
  font-family: var(--sc-font-display); font-weight: 700; font-variation-settings: "opsz" 40;
  font-size: var(--sc-t-base); letter-spacing: -0.01em; color: var(--navy);
  text-decoration: none; padding: var(--sc-2) 0; border-bottom: 2px solid transparent;
  transition: border-color 140ms var(--sc-ease-out);
}
.bar__nav a:hover, .bar__nav a[aria-current="page"] { border-bottom-color: var(--navy); }
.bar__right { display: flex; align-items: center; justify-content: flex-end; gap: var(--sc-3); margin-inline-start: auto; }
.bar__cta { box-shadow: none; }
.bar__menu {
  display: none; min-height: 44px; padding: 0 var(--sc-4);
  background: transparent; color: var(--navy); border: 2px solid var(--navy); border-radius: 4px;
  font-family: var(--sc-font-display); font-weight: 700; font-size: var(--sc-t-base); cursor: pointer;
}
#mat {
  position: fixed; top: var(--bar-h); left: 0; right: 0; height: var(--mat-h); z-index: 89;
  background: var(--pad); transform-origin: top; will-change: transform; overflow: clip;
}
/* the conveyor tape: 24px diagonal stripes at 32 degrees, 6% lighter than the
   pad red, painted once and only ever translated. Its horizontal wrap period is
   21.2 / sin(32deg) = 40px, so play.js can translate by (distance mod 40px) and
   the pattern is seamless. It carries no text and never reads as a progress bar
   because it wraps. */
.mat__tape {
  position: absolute; top: 0; bottom: 0; left: -40px; right: -40px;
  background-image: repeating-linear-gradient(32deg, #C9362B 0 10.6px, transparent 10.6px 21.2px);
  will-change: transform;
}
@media (max-width: 860px) {
  .bar { grid-template-columns: auto 1fr; }
  .bar__nav { display: none; }
  .bar__menu { display: inline-flex; align-items: center; }
  /* The fixed action bar carries "Book a play session" at 56px in thumb reach on
     every page and at every scroll position, so the bar's copy was the third
     instance of one label in a single phone frame and it squeezed the logo to a
     36px target. One label, still five placements, and the header can breathe. */
  .bar__cta { display: none; }
  .bar__logo { min-width: 44px; justify-content: center; }
}
/* phone sheet */
.menu {
  position: fixed; inset: var(--chrome) 0 0 0; z-index: 88;
  background: var(--yellow); color: var(--navy);
  padding: var(--sc-7) var(--sc-gutter) max(var(--sc-8), calc(env(safe-area-inset-bottom) + var(--sc-6)));
  overflow: auto; --focus-ring: #101321;
}
.menu[hidden] { display: none; }
.menu__links { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--sc-2); }
.menu__links a {
  display: block; padding: var(--sc-3) 0; text-decoration: none; color: var(--navy);
  font-family: var(--sc-font-display); font-weight: 800; font-size: var(--sc-t-2xl); letter-spacing: -0.02em;
  border-bottom: 1px solid rgba(16, 19, 33, 0.18);
}
.menu__contact { margin-top: var(--sc-7); display: grid; gap: var(--sc-1); font-weight: 700; }
/* the two highest-intent actions on the only navigation a phone visitor sees:
   full 44px targets, with the row gap tightened so they do not read as one slab */
.menu__contact a { color: var(--navy); display: flex; align-items: center; min-height: 44px; }
.menu__contact span { padding-block-start: var(--sc-2); }
body.menu-open { overflow: hidden; }

/* ---------------------------------------------------------------- labels -- */
.chip {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--sc-4);
  background: #fff; color: var(--navy); border-radius: 4px;
  font-family: var(--sc-font-display); font-weight: 700; font-variation-settings: "opsz" 40;
  font-size: var(--sc-t-base); letter-spacing: -0.005em; box-shadow: var(--sc-e1);
}
.chips { display: flex; flex-wrap: wrap; gap: var(--sc-3); }

.price-table { width: 100%; border-collapse: collapse; font-size: var(--sc-t-base); }
.price-table thead th { white-space: nowrap; }
.price-table th, .price-table td { text-align: left; padding: var(--sc-3) var(--sc-3); border-bottom: 1px solid var(--sc-hairline-strong); }
.price-table th { font-family: var(--sc-font-text); font-weight: 700; font-size: var(--sc-t-sm); color: var(--sc-ink-soft); }
.price-table td:not(:first-child), .price-table th:not(:first-child) { text-align: right; }
.price-table td:not(:first-child) { font-family: var(--sc-font-display); font-weight: 800; font-size: var(--sc-t-lg); }
.price-table tbody tr { transition: opacity 180ms var(--sc-ease-out), transform 180ms var(--sc-ease-out); transform-origin: left center; }
.price-table[data-age] tbody tr { opacity: 0.55; }
.price-table[data-age] tbody tr.is-chosen { opacity: 1; transform: scale(1.02); }
.price-table[data-age] tbody tr.is-chosen td { background: #fff; }
.price-table[data-age="0-2"] tr[data-row="0-2"], .price-table[data-age="3-18"] tr[data-row="3-18"], .price-table[data-age="19"] tr[data-row="19"] { opacity: 1; transform: scale(1.02); }
.price-table[data-age="0-2"] tr[data-row="0-2"] td, .price-table[data-age="3-18"] tr[data-row="3-18"] td, .price-table[data-age="19"] tr[data-row="19"] td { background: #fff; }

.age { border: 0; padding: 0; margin: 0; min-width: 0; }
.age legend { font-family: var(--sc-font-display); font-weight: 800; font-size: var(--sc-t-lg); letter-spacing: -0.01em; padding: 0; margin-bottom: var(--sc-3); }
.age__opts { display: flex; flex-wrap: wrap; gap: var(--sc-2); }
.age__opt { position: relative; }
/* appearance:none, not opacity:0: the control keeps opacity 1 and its own box
   is exactly the visible chip, so keyboard focus never lands on an invisible
   element. The ring is drawn on the chip the reader can actually see. */
.age__opt input { position: absolute; inset: 0; margin: 0; cursor: pointer; appearance: none; -webkit-appearance: none; background: transparent; border: 0; border-radius: 4px; }
.age__opt input:focus-visible { outline: none; }
.age__opt span {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--sc-4);
  border: 2px solid var(--navy); border-radius: 4px; background: transparent; color: var(--navy);
  font-family: var(--sc-font-display); font-weight: 700; font-size: var(--sc-t-base);
  transition: background-color 140ms var(--sc-ease-out), color 140ms var(--sc-ease-out);
}
.age__opt input:checked + span { background: var(--navy); color: #fff; }
.age__opt input:focus-visible + span { outline: 3px solid var(--focus-ring); outline-offset: 3px; }

.hours { display: grid; grid-template-columns: minmax(0, 1fr) max-content; gap: var(--sc-2) var(--sc-5); margin: 0; }
.hours dt { font-weight: 700; }
.hours dd { margin: 0; font-family: var(--sc-font-display); font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.hours dd.hours__note { white-space: normal; }
.stack > .hours { margin-top: var(--sc-4); }
@media (max-width: 700px) {
  .hours { grid-template-columns: 1fr; gap: 0; }
  .hours dt { margin-top: var(--sc-3); }
  .hours dt:first-of-type { margin-top: 0; }
  .hours dd { white-space: normal; }
}

/* --------------------------------------------------- phone action bar -- */
/* The primary action is never behind the Menu on a phone. It is fixed to the
   bottom of the viewport on every page, with WhatsApp beside it as the clearly
   subordinate second action (outlined, one third of the width, lighter weight).
   z-index 70 sits under #pad (80), #mat (89) and .bar (90), so the peak still
   fills the screen; the bar's own CTA carries the label for those two
   viewports. The red top edge is the mat strip's colour, so the bar reads as
   the same chrome family and not as a bolted-on marketing tray. */
.actbar { display: none; }
@media (max-width: 860px) {
  :root { --actbar-h: calc(71px + env(safe-area-inset-bottom)); }
  .actbar {
    display: flex; gap: var(--sc-2); align-items: stretch;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
    background: #fff; border-top: 3px solid var(--pad);
    padding: 6px max(var(--sc-3), env(safe-area-inset-right)) calc(6px + env(safe-area-inset-bottom)) max(var(--sc-3), env(safe-area-inset-left));
    box-shadow: 0 -6px 18px rgba(16, 19, 33, 0.18);
  }
  .actbar__btn {
    display: flex; align-items: center; justify-content: center;
    min-height: 56px; padding: 0 var(--sc-3); border-radius: 4px;
    font-family: var(--sc-font-display); font-variation-settings: "opsz" 40;
    letter-spacing: -0.005em; line-height: 1.05; text-align: center;
    text-decoration: none; white-space: nowrap;
    transition: transform 140ms var(--sc-ease-out), background-color 140ms var(--sc-ease-out);
  }
  /* primary: navy on white, 17.4:1 */
  .actbar__go { flex: 2.1 1 0; background: var(--navy); color: #fff; font-weight: 800; font-size: var(--sc-t-base); }
  /* secondary: outlined, subordinate by weight, size and area */
  .actbar__wa { flex: 1 1 0; background: #fff; color: var(--navy); border: 2px solid var(--navy); font-weight: 700; font-size: var(--sc-t-sm); }
  .actbar__btn:hover { transform: translateY(-3px); }
  .actbar__go:hover { background: #1B2036; }
  .actbar__wa:hover { background: #FFF8DB; }
  .actbar__go:focus-visible { outline: 3px solid #fff; outline-offset: -7px; transform: translateY(-3px); }
  .actbar__wa:focus-visible { outline: 3px solid var(--navy); outline-offset: -7px; transform: translateY(-3px); }
  .actbar__btn:active { transform: scale(0.97); }
}
@media (max-width: 400px) {
  .actbar { gap: 6px; padding-inline: 8px; }
  .actbar__btn { padding-inline: var(--sc-2); }
  .actbar__go { font-size: var(--sc-t-sm); }
  .actbar__wa { font-size: 0.9rem; }
}
@media (hover: none) {
  .actbar__btn:hover { transform: none; }
  .actbar__go:hover { background: var(--navy); }
  .actbar__wa:hover { background: #fff; }
}

/* ---------------------------------------------------------------- footer -- */
.site-foot { font-size: var(--sc-t-sm); }
.site-foot__row { display: flex; flex-wrap: wrap; gap: var(--sc-2) var(--sc-4); align-items: center; }
.site-foot a { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 0.2em; }
.site-foot a:hover { text-decoration-thickness: 2px; }
.site-foot__credit { opacity: 0.78; }
.site-foot .site-foot__row + .site-foot__row { margin-top: var(--sc-3); }
.site-foot svg { width: 20px; height: 20px; flex: none; fill: currentColor; }
/* tap targets: 44px on every contact and nav link, icon and label never split */
.site-foot__row a, .book__strip a, .close__strip a, .facts--stack a {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 6px; min-height: 44px; min-width: 44px;
}

/* --------------------------------------------------------- reduced motion -- */
@media (prefers-reduced-motion: reduce) {
  .btn, .price-table tbody tr, .age__opt span, .actbar__btn { transition: none; }
  .actbar__btn:hover, .actbar__go:focus-visible, .actbar__wa:focus-visible { transform: none; }
}

/* ============================================================ the landing puck
   A pointer-reactive decoration, never a cursor replacement: the system pointer
   is always drawn, at system size, with the reader's own contrast and
   shake-to-find intact. `cursor: none` appears nowhere on this site. Every
   state is pointer-events: none, so it can neither obscure a control nor
   intercept a click. Built only above 861px, on a real mouse, with motion on.
   z-index 95 puts it above #mat (89) and .bar (90) so the --go state is
   actually visible over the bar CTA, and below the skip link (200). The peak
   is unaffected: cur--off already switches the puck off while #pad is on. */
.cur {
  position: fixed; left: 0; top: 0; z-index: 95;
  width: 13px; height: 13px; border-radius: 50%;
  background: #C8281A; opacity: 0;
  pointer-events: none; will-change: transform;
  transition: opacity 220ms var(--sc-ease-out), width 180ms var(--sc-ease-out),
              height 180ms var(--sc-ease-out), background-color 180ms var(--sc-ease-out),
              box-shadow 180ms var(--sc-ease-out);
}
/* the ground under the pointer owns the accent, so the puck is legible on all six */
.cur[data-g="dark"]   { background: #FF6A57; }
.cur[data-g="yellow"] { background: #B9231A; }
.cur.is-on            { opacity: 0.7; }
.cur.is-on.cur--link  { opacity: 1; }
.cur.is-on.cur--go    { opacity: 1; width: 18px; height: 18px; }
.cur.is-on.cur--photo { opacity: 0.92; background: #fff; box-shadow: 0 0 0 1px rgba(16, 19, 33, 0.35); }
.cur.cur--off         { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .cur { display: none; } }
@media (max-width: 860px) { .cur { display: none; } }

/* =========================================================== the button hop
   The trampoline language reaches the controls: 3px up on hover and on focus,
   140ms, and back on release. Transform only, and :active still wins. */
@media (prefers-reduced-motion: no-preference) {
  :root:not([data-calm]) :is(.btn, .book__btn):focus-visible { transform: translateY(-3px); }
}
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  :root:not([data-calm]) :is(.btn, .book__btn):hover { transform: translateY(-3px); }
}
/* the press still wins over the hop, at matching specificity */
:root:not([data-calm]) :is(.btn, .actbar__btn):active { transform: scale(0.97); }
:root:not([data-calm]) .book__btn:active { transform: scale(0.985); }

/* ==================================================== cross-page navigation
   Six real pages, so every navigation between them is a morph rather than a
   white flash. No shared view-transition-name: the tile-into-hero morph is a
   sibling site's move and Play takes only the calm cross-fade. */
@view-transition { navigation: auto; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) {
    animation: none !important;
  }
}
:root[data-calm] ::view-transition-group(*),
:root[data-calm] ::view-transition-old(*),
:root[data-calm] ::view-transition-new(*) { animation: none !important; }

/* Morph A. Choosing an age lifts that row's emphasis out of the table and into
   the "Your price" band above it. Same-document view transition, 0 KB: the
   emphasis travels between two real boxes and the band's own box morphs,
   because its text length differs between the three ages. */
#yourPrice:not([hidden]) { view-transition-name: your-price; }
::view-transition-group(price-row),
::view-transition-group(your-price) {
  animation-duration: 260ms; animation-timing-function: var(--sc-ease-out);
}

/* ================================================== the moving ground: pads
   The floor of a trampoline hall is long soft-edged pads at a shallow angle.
   Each band is painted once with a static gradient and then only ever
   transformed, so there is zero per-frame paint. Three rates in two directions
   shear the ground as you pass it. A sibling of the copy, never an ancestor, so
   contrast is measured on the frame beneath. */
.pads { position: absolute; inset: 0; z-index: 0; pointer-events: none; contain: layout paint; }
.pads__b {
  position: absolute; left: -14%; right: -14%; top: var(--y); height: 11vh;
  border-radius: 999px; transform: rotate(-5deg);
  background: linear-gradient(to right, transparent, var(--tone) 18%, var(--tone) 82%, transparent);
}
@media (prefers-reduced-motion: no-preference) {
  :root:not([data-calm]) .pads__b {
    transform: translate3d(calc((var(--sc-p) - 0.5) * var(--drift, 0px)), 0, 0) rotate(-5deg);
  }
}
.pads__b:nth-child(1) { --drift:  90px; }
.pads__b:nth-child(2) { --drift: -160px; }
.pads__b:nth-child(3) { --drift:  240px; }
/* Band tones: one step off each ground, measured on the composite. The blue
   band moves DOWN rather than up, because a lighter blue put white body copy at
   5.96:1, under this section's own 6:1 floor; #0C4E77 measures 8.85:1. */
.ground--navy   .pads__b { --tone: #1A1F36; }
.ground--blue   .pads__b { --tone: #0C4E77; }
.ground--sand   .pads__b { --tone: #DFD7C7; }
.ground--yellow .pads__b { --tone: #EFC61A; }
