/* ==========================================================================
   Cotswold Training Club: motion kit styles.

   Paired with assets/motion.js. Two root classes decide everything:
   .mo-on  the engine is running, so elements start hidden and are revealed
   .mo-off the visitor asked for reduced motion, so nothing here applies and
           the page renders in its resting state

   Nothing is hidden by CSS alone. If the script never runs, neither class is
   set and every rule below is inert, which means a broken script can never
   leave a landing page blank.
   ========================================================================== */

/* ---------------------------------------------------------------- reveals */
.mo-on [data-rise]  { opacity: 0; transform: translateY(26px); }
.mo-on [data-scale] { opacity: 0; transform: scale(.955); }
.mo-on [data-wipe]  { clip-path: inset(0 0 100% 0); }
.mo-on [data-wipe="left"] { clip-path: inset(0 100% 0 0); }

.mo-on [data-rise], .mo-on [data-scale] {
  transition: opacity .62s cubic-bezier(.22,1,.36,1), transform .62s cubic-bezier(.22,1,.36,1);
}
.mo-on [data-wipe] { transition: clip-path .82s cubic-bezier(.65,0,.35,1); }

.mo-on [data-rise].mo-in, .mo-on [data-scale].mo-in { opacity: 1; transform: none; }
.mo-on [data-wipe].mo-in { clip-path: inset(0 0 0 0); }

/* Headlines revealed a word at a time, each word rising out of a mask. */
.mo-w { display: inline-block; overflow: hidden; vertical-align: bottom; padding-bottom: .06em; }
.mo-w__i {
  display: inline-block; will-change: transform;
  transform: translateY(105%);
  transition: transform .78s cubic-bezier(.22,1,.36,1);
}
.mo-on [data-split].mo-in .mo-w__i { transform: none; }
.mo-off [data-split] .mo-w__i, :not(.mo-on) [data-split] .mo-w__i { transform: none; }

/* ------------------------------------------------------------- parallax */
[data-par] { will-change: transform; }
.mo-on [data-par] > img,
.mo-on [data-par] > video { transform: translate3d(0, var(--par, 0px), 0) scale(1.14); }

/* -------------------------------------------------------- progress rail */
.mo-bar {
  position: fixed; inset: 0 0 auto 0; height: 3px; z-index: 90;
  background: linear-gradient(90deg, var(--olive), var(--sage));
  transform: scaleX(0); transform-origin: 0 50%;
  will-change: transform; pointer-events: none;
}

/* --------------------------------------------------------- chapter rail */
.rail {
  position: fixed; left: 22px; top: 50%; transform: translateY(-50%);
  z-index: 60; display: none; flex-direction: column; gap: 12px;
  opacity: 0; transition: opacity .4s ease; pointer-events: none;
}
.rail.on { opacity: 1; pointer-events: auto; }
@media (min-width: 1320px) { .rail { display: flex; } }   /* only where the gutter is wide enough for it */
.rail a {
  width: 10px; height: 10px; border-radius: 50%;
  background: rgba(20,26,14,.2); position: relative;
  transition: background .3s ease, transform .3s ease;
}
.rail a.on { background: var(--olive); transform: scale(1.5); }
.rail a::after {
  content: attr(data-label); position: absolute; left: 20px; top: 50%;
  transform: translateY(-50%) translateX(-4px);
  white-space: nowrap; font-size: .72rem; font-weight: 800;
  letter-spacing: .08em; text-transform: uppercase; color: var(--olive);
  opacity: 0; transition: opacity .25s ease, transform .25s ease; pointer-events: none;
}
/* The label is a hover affordance only. Showing it for the live chapter as
   well put standing text in the gutter, which collided with the copy on a
   1440 viewport where the wrap leaves 130px either side. */
.rail a:hover::after, .rail a:focus-visible::after { opacity: 1; transform: translateY(-50%); }

/* ------------------------------------------------------------- magnets */
[data-magnet] { transition: transform .28s cubic-bezier(.22,1,.36,1); }
.mo-on [data-magnet] { transform: translate3d(var(--mx,0), var(--my,0), 0); }

/* ---------------------------------------------------------- pinned run
   A tall section with a sticky panel inside it. Scrolling the tall part
   advances the steps rather than the page, so the thirty days play out as
   one continuous move instead of a list you skim past. */
.pin { position: relative; }
.pin__sticky {
  position: sticky; top: 0; min-height: 100svh;
  display: flex; align-items: center; overflow: hidden;
  padding: 96px 0 clamp(40px, 7vh, 80px);
}
.pin__grid {
  display: grid; gap: clamp(24px, 4vw, 56px); align-items: center;
  grid-template-columns: 1fr;
}   /* no width here: it shares an element with .wrap, which sets the width */
@media (min-width: 900px) { .pin__grid { grid-template-columns: 1fr 1.15fr; } }
.pin__track { display: flex; gap: 16px; align-items: stretch; }
.pin__line {
  flex: 0 0 3px; border-radius: 2px; background: rgba(255,255,255,.14);
  position: relative; overflow: hidden;
}
.pin__fill {
  position: absolute; inset: 0; background: var(--sage);
  transform-origin: 50% 0; transform: scaleY(0);
}
.pin__steps { display: grid; gap: 4px; flex: 1 1 auto; }
.pin__step {
  padding: 11px 0; opacity: .34; transform: translateX(-6px);
  transition: opacity .45s ease, transform .45s ease;
}
.pin__step.is-live { opacity: 1; transform: none; }
/* Only the live step opens its paragraph. Five steps with five paragraphs is
   taller than a laptop viewport, and the run has to hold still on one screen. */
.pin__step p {
  max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height .5s cubic-bezier(.22,1,.36,1), opacity .35s ease, margin .5s ease;
}
.pin__step.is-live p { max-height: 9em; opacity: 1; margin-top: 6px; }
.pin__step .n {
  font-size: .72rem; font-weight: 800; letter-spacing: .12em;
  text-transform: uppercase; color: var(--sage); display: block; margin-bottom: 3px;
}
.pin__step h3 { color: #fff; font-size: clamp(1.15rem, 2.2vw, 1.5rem); margin: 0 0 4px; }
.pin__step p { color: rgba(255,255,255,.72); margin: 0; font-size: .95rem; }
.pin__art {
  position: relative; border-radius: 10px; overflow: hidden;
  aspect-ratio: 4 / 3; background: var(--ink-deep);
}
.pin__art img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity .6s ease, transform 1.4s ease;
  transform: scale(1.08);
}
.pin__art img.is-live { opacity: 1; transform: scale(1); }
.pin__badge {
  position: absolute; left: 14px; bottom: 14px; z-index: 2;
  background: rgba(13,18,8,.82); backdrop-filter: blur(6px);
  color: #fff; font-size: .74rem; font-weight: 800; letter-spacing: .1em;
  text-transform: uppercase; padding: 8px 14px; border-radius: 500px;
}

/* ============================================== the interactive gallery */
.gal__bar {
  display: flex; gap: 8px; flex-wrap: wrap; justify-content: center;
  margin: 0 0 22px;
}
.chip {
  border: 1px solid var(--line); background: var(--white); cursor: pointer;
  border-radius: 500px; padding: 9px 18px; font: inherit; font-size: .88rem;
  font-weight: 700; color: var(--body); transition: all .25s ease;
}
.chip:hover { border-color: var(--olive); color: var(--olive); }
.chip[aria-pressed="true"] { background: var(--olive); border-color: var(--olive); color: #fff; }
.chip .c { opacity: .6; font-weight: 600; margin-left: 6px; font-size: .8em; }

.gal {
  display: grid; gap: 10px;
  grid-template-columns: repeat(2, 1fr);
  grid-auto-rows: clamp(112px, 30vw, 150px);
}
@media (min-width: 860px) {
  .gal { gap: 14px; grid-template-columns: repeat(4, 1fr); grid-auto-rows: clamp(140px, 13vw, 196px); }
}
.gal button {
  position: relative; border: 0; padding: 0; cursor: pointer; background: var(--mist);
  border-radius: 7px; overflow: hidden; width: 100%; height: 100%;
  transition: transform .5s cubic-bezier(.22,1,.36,1), opacity .35s ease, filter .35s ease;
}
.gal button.wide { grid-column: span 2; grid-row: span 2; }
.gal button.gone { display: none; }
.gal img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .7s cubic-bezier(.22,1,.36,1);
}
.gal button:hover img { transform: scale(1.07); }
.gal button:focus-visible { outline: 3px solid var(--olive); outline-offset: 3px; }
.gal__zoom {
  position: absolute; top: 10px; right: 10px; width: 32px; height: 32px;
  border-radius: 500px; background: rgba(255,255,255,.9); color: var(--ink);
  display: grid; place-items: center; font-size: 1rem; font-weight: 800;
  opacity: 0; transform: scale(.7); transition: all .3s cubic-bezier(.22,1,.36,1);
}
.gal button:hover .gal__zoom { opacity: 1; transform: none; }

/* the viewer */
.viewer {
  position: fixed; inset: 0; z-index: 120; display: none;
  background: rgba(9,12,6,.986); backdrop-filter: blur(10px);
}
.viewer.on { display: grid; grid-template-rows: 1fr auto; }
.viewer__stage { position: relative; display: grid; place-items: center; padding: 56px 16px 8px; min-height: 0; }
.viewer__stage img {
  max-width: min(1180px, 94vw); max-height: 100%; width: auto; height: auto;
  border-radius: 8px; box-shadow: 0 30px 80px -20px rgba(0,0,0,.7);
  animation: viewerIn .45s cubic-bezier(.22,1,.36,1);
}
@keyframes viewerIn { from { opacity: 0; transform: scale(.965); } to { opacity: 1; transform: none; } }
.viewer__cap {
  text-align: center; color: #fff; padding: 12px 16px 4px;
  font-weight: 700; font-size: 1rem;
}
.viewer__cap span { display: block; color: rgba(255,255,255,.55); font-weight: 500; font-size: .85rem; margin-top: 3px; }
.viewer__rail {
  display: flex; gap: 8px; overflow-x: auto; padding: 12px 16px max(16px, env(safe-area-inset-bottom));
  scrollbar-width: none; justify-content: flex-start;
}
.viewer__rail::-webkit-scrollbar { display: none; }
.viewer__rail button {
  flex: 0 0 auto; width: 74px; height: 52px; border: 0; padding: 0; cursor: pointer;
  border-radius: 5px; overflow: hidden; opacity: .42; background: none;
  transition: opacity .25s ease, transform .25s ease; outline-offset: 2px;
}
.viewer__rail button[aria-current="true"] { opacity: 1; transform: translateY(-3px); box-shadow: 0 0 0 2px var(--sage); }
.viewer__rail img { width: 100%; height: 100%; object-fit: cover; }
.viewer__nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 48px; height: 48px; border-radius: 500px; border: 0; cursor: pointer;
  background: rgba(255,255,255,.12); color: #fff; font-size: 1.4rem;
  display: grid; place-items: center; transition: background .25s ease;
}
.viewer__nav:hover { background: rgba(255,255,255,.24); }
.viewer__nav.prev { left: 14px; }
.viewer__nav.next { right: 14px; }
.viewer__x {
  position: absolute; top: 14px; right: 14px; width: 44px; height: 44px;
  border-radius: 500px; border: 0; cursor: pointer; z-index: 2;
  background: rgba(255,255,255,.12); color: #fff; font-size: 1.5rem;
  display: grid; place-items: center;
}
.viewer__x:hover { background: rgba(255,255,255,.24); }
.viewer__count {
  position: absolute; top: 20px; left: 20px; color: rgba(255,255,255,.6);
  font-size: .82rem; font-weight: 800; letter-spacing: .1em;
}
@media (max-width: 700px) { .viewer__nav { display: none; } }


/* Dense packing so the gallery still closes up when a filter hides most of
   it: without this a two-by-two tile leaves a hole behind whatever is left. */
.gal { grid-auto-flow: dense; }

/* The pinned run is five screens tall, which is a lot of nothing on a phone
   with a short viewport, so it collapses to an ordinary stacked section and
   every step is simply visible. */
@media (max-width: 760px), (max-height: 620px) {
  .pin { height: auto !important; }
  .pin__step, .pin__step p { opacity: 1; }
  .pin__step p { max-height: none; margin-top: 6px; }
  .pin__sticky { position: static; min-height: 0; padding: clamp(56px,8vw,104px) 0; }
  .pin__step { opacity: 1; transform: none; }
  .pin__art { margin-top: 26px; }
  .pin__art img { opacity: 0; }
  .pin__art img.is-live { opacity: 1; }
  .pin__line { display: none; }
}

/* Reduced motion: the sticky run is a plain section, and everything that the
   engine would have revealed is simply there. */
.mo-off .pin, :root:not(.mo-on) .pin { height: auto !important; }
.mo-off .pin__sticky, :root:not(.mo-on) .pin__sticky {
  position: static; min-height: 0; padding: clamp(56px,8vw,104px) 0;
}
.mo-off .pin__step, :root:not(.mo-on) .pin__step { opacity: 1; transform: none; }
.mo-off .pin__art img:not(.is-live), :root:not(.mo-on) .pin__art img:not(.is-live) { display: none; }
.mo-off .pin__art img.is-live, :root:not(.mo-on) .pin__art img.is-live { opacity: 1; transform: none; }
.mo-off .mo-bar, :root:not(.mo-on) .mo-bar { display: none; }
.mo-off .rail, :root:not(.mo-on) .rail { display: none; }


/* Anchored jumps must clear the sticky header. */
[id] { scroll-margin-top: 84px; }


/* ================================================== what people say: the wall
   Two rows that drift in opposite directions and can be thrown by hand. The
   rows are ordinary horizontally scrolling elements, so a trackpad, a
   scrollbar and a keyboard all work on them before any script runs. */
.wall2 { display: grid; gap: 16px; }
.wall2__row {
  display: flex; gap: 16px; overflow-x: auto; overscroll-behavior-x: contain;
  scrollbar-width: none; padding: 4px 0 6px;
  cursor: grab; touch-action: pan-y;
}
.wall2__row::-webkit-scrollbar { display: none; }
.wall2__row.is-dragging { cursor: grabbing; user-select: none; }
.wall2__row .review {
  flex: 0 0 clamp(268px, 74vw, 350px);
  margin: 0; transition: transform .35s cubic-bezier(.22,1,.36,1), box-shadow .35s ease;
}
.wall2__row .review:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.wall2__row .review .who { display: flex; flex-direction: column; gap: 2px; }
.wall2__row .review .who b { color: var(--ink); }
.wall2__row .review .who span {
  font-size: .7rem; letter-spacing: .1em; color: var(--olive); font-weight: 800;
}
.wall2__hint {
  margin: 4px 0 0; text-align: center; font-size: .84rem; color: var(--muted);
}
.wall2__hint a { font-weight: 700; }

/* The rows are edge to edge, so they read as a wall running past the page
   rather than as two boxes sitting in it. */
@media (min-width: 900px) {
  #reviews .wrap { width: 100%; max-width: none; padding-inline: 0; }
  #reviews .head, #reviews .wall2__hint { width: min(100% - 48px, 1180px); margin-inline: auto; }
  .wall2__row { padding-inline: max(24px, calc((100vw - 1180px) / 2)); }
}

/* ------------------------------------------------------------ film tiles */
.film { position: relative; }
.film video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  z-index: 1; animation: filmIn .3s ease;
}
@keyframes filmIn { from { opacity: 0; } to { opacity: 1; } }

/* -------------------------------------------------------------- faq ------ */
.faq .a-wrap { overflow: hidden; height: 0; transition: height .3s cubic-bezier(.22,1,.36,1); }
.faq details[open] .a-wrap { height: auto; }
.faq summary { cursor: pointer; }
.faq summary::marker, .faq summary::-webkit-details-marker { content: ""; display: none; }

/* --------------------------------------------------------- the scroll cue */
.cue {
  display: flex; align-items: center; gap: 10px; margin: 26px 0 0;
  font-size: .74rem; font-weight: 800; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
  transition: opacity .4s ease;
}
.cue i {
  width: 22px; height: 34px; border: 2px solid var(--olive); border-radius: 500px;
  position: relative; flex: 0 0 auto;
}
.cue i::after {
  content: ""; position: absolute; left: 50%; top: 7px; width: 4px; height: 4px;
  margin-left: -2px; border-radius: 50%; background: var(--olive);
  animation: cueDrop 1.7s cubic-bezier(.65,0,.35,1) infinite;
}
@keyframes cueDrop {
  0% { transform: translateY(0); opacity: 0; }
  25% { opacity: 1; }
  75% { transform: translateY(13px); opacity: 0; }
  100% { transform: translateY(13px); opacity: 0; }
}
.mo-on .cue.gone { opacity: 0; pointer-events: none; }
.mo-off .cue, :root:not(.mo-on) .cue { display: none; }

/* ------------------------------------------------------------ card lift */
.card, .coach .shot { transition: transform .45s cubic-bezier(.22,1,.36,1), box-shadow .45s ease; }
.card:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); }
.coach:hover .shot { transform: translateY(-5px) scale(1.012); }
.card img { transition: transform .7s cubic-bezier(.22,1,.36,1); }
.card { overflow: hidden; }
.card:hover img { transform: scale(1.05); }
