/* ==========================================================================
   PCP Home — Phase 2 redesign. Layered on top of site.css and scoped to
   body.page-home so the other pages are untouched until their own phase.
   ========================================================================== */

.page-home {
  /* --pcp-black is now #050505 site-wide in site.css :root — no override needed here. */
  --panel-bg: rgba(255, 255, 255, 0.04);
  --panel-border: rgba(212, 175, 55, 0.20);
  --dur: 700ms;
  --dur-slow: 1100ms;
  background-color: #050505;
  color: rgba(255, 255, 255, 0.86);
  font-size: 1.0625rem;                         /* 17px body */
}

/* --- Type scale ------------------------------------------------------- */
.page-home h1 { font-size: clamp(2.5rem, 6.2vw, 5.5rem); line-height: 0.98; font-weight: 500; letter-spacing: 0.01em; }
.page-home h2 { font-size: clamp(2.4rem, 4.4vw, 3.5rem); line-height: 1.02; font-weight: 500; letter-spacing: 0.005em; }


.page-home p { max-width: var(--measure); }
.page-home .eyebrow { font-size: 0.75rem; }
.page-home .accent { color: var(--pcp-gold); }

/* --- Layout helpers ----------------------------------------------------- */




.page-home .surface-navy-solid {
  background: linear-gradient(180deg, #071426 0%, #0B1F3A 100%);
  border-top: 1px solid rgba(212, 175, 55, 0.10);
  border-bottom: 1px solid rgba(212, 175, 55, 0.10);
}

/* --- Header / brand ---------------------------------------------------- */
/* Home's own header tint. Driven by --hdr (assets/js/header.js) exactly like
   the base rule in site.css, so the bar can start transparent over the hero
   instead of snapping between two fixed values. */
.page-home .site-header {
  /* Solid black, always. The alpha used to be scrubbed by --hdr (header.js) so
     the bar could start transparent over the hero — but with the room now on a
     fixed layer behind the whole page, "transparent" meant the mansion showed
     through the header itself. A flat #000000 puts the logo, the nav and the
     CTA back on a plain bar. --hdr still drives the hairline below, so the
     border keeps its original fade-in. */
  background-color: #000000;
  border-bottom-color: rgba(212, 175, 55, calc(0.10 * var(--hdr, 1)));
}
.page-home .brand { display: inline-flex; align-items: center; gap: 0.85rem; }
.page-home .brand-logo { height: 3.25rem; width: auto; display: block; }
.page-home .brand-logo-lg { height: 4.5rem; }
.page-home .brand-name {
  font-size: 0.64rem; line-height: 1.35; letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(255,255,255,0.7); font-weight: 500;
}
.page-home .nav-link { font-size: 0.875rem; letter-spacing: 0.1em; padding: 0.75rem 0.15rem; }
.page-home .nav-link::after { bottom: 0.45rem; }
.page-home .mobile-nav .nav-link { font-size: 1rem; padding: 0.95rem 0; }
.page-home .mobile-nav { background: linear-gradient(180deg, #050505 0%, #071426 100%); }

/* --- Progress bar --------------------------------------------------------- */
.page-home .progress-bar { position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 60; pointer-events: none; }
.page-home .progress-bar span {
  display: block; height: 100%; width: 100%;
  background: linear-gradient(90deg, var(--pcp-gold), #F1D27A);
  transform: scaleX(0); transform-origin: left;
  box-shadow: 0 0 12px rgba(212,175,55,0.6);
}

/* --- Buttons: 12px radius, 14px semibold, glow + subtle scale ------------ */
.page-home .btn {
  border-radius: 12px;
  font-size: 0.875rem;
  letter-spacing: 0.08em;
  padding: 1rem 1.75rem;
  min-height: 3.25rem;
  overflow: hidden;
}
.page-home .btn-sm { padding: 0.7rem 1.2rem; min-height: 2.75rem; font-size: 0.8rem; }
.page-home .btn-lg { padding: 1.1rem 2.2rem; min-height: 3.5rem; }
.page-home .btn-primary::before {
  content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; pointer-events: none;
  background: linear-gradient(115deg, transparent 35%, rgba(255,255,255,0.5) 50%, transparent 65%);
  transform: translateX(-130%);
  transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}
.page-home .btn-primary:hover::before { transform: translateX(130%); }
.page-home .btn-primary:hover { transform: translateY(-2px) scale(1.02); box-shadow: 0 1px 0 rgba(255,255,255,0.45) inset, 0 18px 44px -14px rgba(212,175,55,0.8), 0 0 0 1px rgba(212,175,55,0.3); }
.page-home .btn-primary:active { transform: translateY(0) scale(0.99); }
.page-home .btn-secondary { background: transparent; }
.page-home .btn-text { font-size: 0.875rem; letter-spacing: 0.08em; min-height: 2.75rem; }

/* --- Word reveal ---------------------------------------------------------- */
.page-home .split-words .wm { display: inline-block; overflow: hidden; vertical-align: bottom; padding-bottom: 0.08em; margin-bottom: -0.08em; }
.page-home .split-words .w {
  display: inline-block;
  opacity: 0;
  transform: translateY(105%);
  transition: opacity var(--dur) ease, transform var(--hero-word-duration, 900ms) cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(var(--i, 0) * var(--hero-word-stagger, 70ms));
}
.page-home .split-words.is-visible .w { opacity: 1; transform: translateY(0); }
.page-home .split-words.reveal { transform: none; }  /* let the words carry the motion */

/* Hold the entrance until the metrics are final -----------------------------
   Montserrat comes from Google Fonts with display=swap, so the first frames
   are laid out in the fallback face and every word changes width when the
   real one lands -- on this headline 40-70px per word, plus a sideways shift.
   Starting the entrance before that means the words slide while the line is
   also re-flowing underneath them.

   The preloader cannot cover this. On a refresh it finds pcp:opened in
   sessionStorage and runs in brief mode, where the cap is 350ms, so the
   curtain is long gone before a slow font arrives -- which is precisely the
   refresh case this is about. So the headline waits for itself, in home.js,
   and this is the state it waits in. Placed after the .is-visible rule
   deliberately: same specificity, so it wins while it is on. The failsafe
   below is an animation, which outranks both, so a stuck hold still cannot
   keep the headline off the page. */
.page-home .split-words.hero-hold .w {
  opacity: 0;
  transform: translateY(105%);
  transition: none;
}

/* FAILSAFE — the headline is never allowed to stay invisible ----------------
   Two separate rules hide it before JavaScript touches it: .reveal puts the
   <h1> at opacity 0, and .w puts every word at opacity 0 behind its mask.
   Both are cleared by .is-visible, which only ever arrives from JavaScript --
   site.js, or home.js's own net -- and both of those are in turn held behind
   PCPPreloader.onDone. That is a chain of four things that each have to work
   for the headline to be readable at all, and if any link fails the hero is
   simply blank. It is the one piece of text on the page that must never be
   missing, so it also gets a route to visible that needs no script.

   A 1ms animation on a long delay does that: it is inert until it fires, so
   the real entrance plays untouched (3 words finish in ~1.04s at the current
   stagger), and if nothing has revealed the headline by then it is forced to
   its finished state. forwards makes that stick. This mirrors the release
   animation the preloader already arms on itself for the same reason. */
@keyframes pcpHeroHeadingFailsafe { to { opacity: 1; transform: none; } }
.page-home #hero-title.reveal,
.page-home #hero-title .w {
  animation: pcpHeroHeadingFailsafe 1ms linear 2400ms forwards;
}

/* Setup threw partway. assets/js/home.js marks the headline rather than
   leaving it half-split and hidden; show whatever exists, plainly. */
.page-home .split-words.split-failed .w {
  opacity: 1; transform: none; transition: none; animation: none;
}

/* --- Hero ------------------------------------------------------------------ */
.page-home .hero {
  position: relative;
  /* 85px, the header's real height. It was 84, which left the hero box one
     pixel past the bottom of the viewport — and .scroll-cue is positioned
     from that bottom edge, so the cue inherited the overrun. */
  min-height: calc(100svh - 85px);
  /* align-items centres vertically; justify-items must stretch so the content
     column fills the hero and .wrap's side padding actually applies. With
     place-items:center the item sized to its content and the CTAs ran flush
     to the screen edges on narrow viewports. */
  display: grid;
  align-items: center;
  justify-items: stretch;
  overflow: hidden;
  text-align: center;
  isolation: isolate;

  /* Single source of truth for the headline reveal timing. The CSS
     transition below and assets/js/hero.js both read these, so anything
     synchronised to the headline (the Phoenix spark) cannot drift. */
  --hero-word-stagger: 70ms;
  --hero-word-duration: 900ms;

  /* Written each frame by hero.js, 0 → 1 across the headline reveal.
     Everything atmospheric below scales off this one number. */
  --hero-energy: 0;
}

/* Near-black with a deep navy undertone. The warm light is deliberately
   faint here — it grows with --hero-energy rather than starting bright. */
.page-home .hero-bg { position: absolute; inset: -12% 0; z-index: -3; will-change: transform;
  background:
    radial-gradient(58% 42% at 50% 106%, rgba(232, 106, 36, 0.10), transparent 72%),
    radial-gradient(52% 46% at 50% 96%, rgba(212, 175, 55, 0.09), transparent 72%),
    radial-gradient(72% 62% at 50% 0%, rgba(11, 31, 58, 0.85), transparent 70%),
    linear-gradient(180deg, #050505 0%, #071426 100%);
}

/* Ambient warmth that rises as the words land. Opacity and scale only. */
.page-home .hero-ambient {
  position: absolute; left: 50%; top: 62%;
  width: min(120vw, 1500px); height: min(120vw, 1500px);
  transform: translate(-50%, -50%) scale(calc(0.9 + 0.1 * var(--hero-energy)));
  z-index: -3; pointer-events: none;
  background: radial-gradient(closest-side, rgba(212, 175, 55, 0.13), transparent 62%);
  opacity: calc(0.28 + 0.72 * var(--hero-energy));
}

/* Barely-there haze sitting just above the base, below the type. */
.page-home .hero-haze {
  position: absolute; inset: 0; z-index: -3; pointer-events: none;
  background:
    radial-gradient(70% 40% at 22% 78%, rgba(11, 31, 58, 0.45), transparent 70%),
    radial-gradient(60% 35% at 82% 26%, rgba(7, 20, 38, 0.40), transparent 70%);
  opacity: calc(0.6 + 0.4 * var(--hero-energy));
}

/* Sparse microscopic gold dust, local to the hero. */
.page-home .hero-particles { position: absolute; inset: 0; z-index: -2; pointer-events: none;
  opacity: calc(0.45 + 0.55 * var(--hero-energy));
}

.page-home .hero-rays { position: absolute; inset: -20% -10%; z-index: -2; will-change: transform;
  opacity: calc(0.14 + 0.24 * var(--hero-energy));
  background: conic-gradient(from 180deg at 50% 100%, transparent 0deg, rgba(212,175,55,0.08) 8deg, transparent 16deg, transparent 30deg, rgba(212,175,55,0.06) 38deg, transparent 46deg, transparent 314deg, rgba(212,175,55,0.06) 322deg, transparent 330deg, transparent 344deg, rgba(212,175,55,0.08) 352deg, transparent 360deg);
  -webkit-mask-image: radial-gradient(60% 70% at 50% 100%, #000 30%, transparent 100%);
  mask-image: radial-gradient(60% 70% at 50% 100%, #000 30%, transparent 100%);
}
/* Optional photo layer. Add a cinematic photo: <img class="hero-photo" src="..." alt=""> inside .hero */
.page-home .hero-photo { position: absolute; inset: -8% 0; z-index: -3; width: 100%; height: 116%; object-fit: cover; opacity: 0.45; filter: saturate(0.7) contrast(1.1) sepia(0.15); will-change: transform; }
/* --- Hero background video --------------------------------------------------
   Same z-index (-3) as .hero-bg and the .hero-photo slot; DOM order places it
   above the base gradient and below the haze/ambient/particles/rays/vignette,
   which is exactly how the other -3 layers already stack. Nothing above it
   changes, so the hero's existing tuning is preserved.

   opacity + filter mirror the .hero-photo treatment so the footage sits inside
   the PCP palette rather than fighting it. */
.page-home .hero-video {
  position: absolute; inset: 0; z-index: -3;
  width: 100%; height: 100%;
  /* A <video> is a replaced element with an intrinsic size; without the
     max-width it can report a box wider than the hero on narrow viewports and
     widen the document. .hero already has overflow-x: clip, this is belt and
     braces so no horizontal scrollbar can appear. */
  max-width: 100%;
  object-fit: cover;
  opacity: 0.80;
  filter: saturate(0.85) contrast(1.04);
  pointer-events: none;
}

/* Readability veil. A separate element rather than an edit to .hero-vignette,
   so the original hero is restored untouched wherever the video is absent. */
.page-home .hero-video-veil {
  position: absolute; inset: 0; z-index: -3; pointer-events: none;
  background:
    linear-gradient(180deg, rgba(5, 5, 5, 0.58) 0%, rgba(7, 20, 38, 0.34) 34%,
                    rgba(7, 20, 38, 0.38) 64%, rgba(5, 5, 5, 0.72) 100%),
    radial-gradient(78% 58% at 50% 52%, rgba(7, 20, 38, 0.20), transparent 78%);
}

/* On phones object-fit: cover crops to the centre of the frame — the brightest
   part of this footage — and the lede paragraph sits directly on it. Desktop has
   ample contrast headroom; narrow viewports do not, so deepen the veil and ease
   the video there. Measured, not guessed: this holds the lede above WCAG AA
   (4.5:1) against the brightest frame of the loop. */
@media (max-width: 767px) {
  .page-home .hero-video { opacity: 0.66; }
  .page-home .hero-video-veil {
    background:
      linear-gradient(180deg, rgba(5, 5, 5, 0.62) 0%, rgba(7, 20, 38, 0.54) 34%,
                      rgba(7, 20, 38, 0.58) 64%, rgba(5, 5, 5, 0.78) 100%),
      radial-gradient(88% 62% at 50% 52%, rgba(7, 20, 38, 0.40), transparent 82%);
  }
}

/* Reduced motion: no moving background. Both layers drop out and the hero falls
   back to precisely the gradient it had before the video existed. */
@media (prefers-reduced-motion: reduce) {
  .page-home .hero-video,
  .page-home .hero-video-veil { display: none; }
}

.page-home .hero-vignette { position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(180deg, rgba(5,5,5,0.55) 0%, rgba(5,5,5,0.0) 30%, rgba(5,5,5,0.0) 70%, rgba(5,5,5,0.85) 100%);
}
.page-home .hero-logo {
  height: clamp(6.5rem, 12vw, 10rem); width: auto; margin: 0 auto;
  filter: drop-shadow(0 0 28px rgba(212,175,55,0.35)) drop-shadow(0 18px 40px rgba(0,0,0,0.6));
}
/* min-width:0 lets the grid item shrink to the viewport instead of holding its
   content width; the explicit side padding restores the gutter that the old
   `padding: … 0 …` shorthand was cancelling out of .wrap. */
.page-home .hero-content {
  width: 100%;
  min-width: 0;
  /* Bottom padding reserves the absolute scroll cue's footprint (~6.5rem)
     plus breathing room under the reservation window's note. */
  padding: clamp(3rem, 8vh, 6rem) 1.25rem clamp(8rem, 15vh, 10rem);
}
@media (min-width: 640px) {
  .page-home .hero-content { padding-left: 2rem; padding-right: 2rem; }
}
.page-home .hero .lede { margin-left: auto; margin-right: auto; }
.page-home .scroll-cue {
  position: absolute; left: 50%; bottom: 1.75rem; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 0.6rem;
  font-size: 0.65rem; letter-spacing: 0.25em; text-transform: uppercase; color: rgba(255,255,255,0.62);
}
.page-home .scroll-cue i { display: block; width: 1px; height: 3rem; background: linear-gradient(180deg, var(--pcp-gold), transparent); overflow: hidden; position: relative; }
.page-home .scroll-cue i::after { content: ""; position: absolute; left: 0; top: -100%; width: 100%; height: 100%; background: linear-gradient(180deg, transparent, #fff); animation: cue 2.2s cubic-bezier(0.22, 1, 0.36, 1) infinite; }
@keyframes cue { to { transform: translateY(200%); } }

/* --- Statement (The Question) ---------------------------------------------- */



/* --- Lack list (The Problem) ----------------------------------------------- */







/* --- Phoenix sequence (The Shift) ------------------------------------------ */
.page-home .sequence { position: relative; height: 380vh; }
.page-home .sequence.static { height: auto; }
.page-home .stage {
  position: sticky; top: 0; height: 100vh; height: 100svh;
  display: grid; place-items: center; overflow: hidden; isolation: isolate;
  /* Moved here from .stage-bg's base colour. An element's own background paints
     BELOW its negative-z-index children, so the stage keeps its black ground
     while .stage-bg's glows can now sit above the video. With no video showing
     the stage renders exactly as it did before. */
  background: #050505;
}
.page-home .sequence.static .stage { position: relative; height: auto; min-height: 80vh; padding: var(--section-y) 0; }
.page-home .stage-inner { position: relative; width: 100%; max-width: 1400px; height: 100%; display: grid; grid-template-rows: 1fr auto; place-items: center; padding: 0 1.25rem; }
.page-home .stage-art { position: relative; width: min(70vw, 34rem); aspect-ratio: 1; display: grid; place-items: center; }

/* Phoenix art is rendered by assets/js/phoenix-journey.js on a fixed canvas layer. .stage-art stays as the positional anchor. */

.page-home .captions { position: relative; width: 100%; min-height: 11rem; padding: 0 0 clamp(2rem, 6vh, 4rem); text-align: center; }
.page-home .captions p {
  position: absolute; left: 0; right: 0; top: 0; margin: 0 auto;
  font-family: "Cormorant Garamond", Georgia, serif; font-size: clamp(1.6rem, 3.2vw, 2.6rem); line-height: 1.15; font-weight: 500; color: #fff;
  opacity: 0; transform: translateY(14px);
  transition: opacity var(--dur) ease, transform var(--dur) cubic-bezier(0.22, 1, 0.36, 1);
  max-width: 34rem;
}
.page-home .captions .cap-label { display: block; font-family: Inter, sans-serif; font-size: 0.68rem; letter-spacing: 0.25em; text-transform: uppercase; color: var(--pcp-gold); margin-bottom: 0.85rem; }
.page-home .sequence[data-stage="0"] .captions p:nth-child(1),
.page-home .sequence[data-stage="1"] .captions p:nth-child(2),
.page-home .sequence[data-stage="2"] .captions p:nth-child(3),
.page-home .sequence[data-stage="3"] .captions p:nth-child(4),
.page-home .sequence[data-stage="4"] .captions p:nth-child(5) {
  opacity: 1; transform: translateY(0);
  /* The incoming caption waits for the outgoing one to clear. Without this
     both sit at ~50% mid-transition and two lines overlap in the same space. */
  transition-delay: calc(var(--dur) * 0.45);
}
.page-home .sequence.static .captions { min-height: 0; }
.page-home .sequence.static .captions p { position: static; opacity: 1; transform: none; margin: 1rem auto; }
/* --- THE SHIFT chapter environment -------------------------------------------
   --shift-energy is written by assets/js/phoenix-journey.js (0 well before the
   chapter, 1 from the pin onward). Depth, gold and a faint orange warmth all
   rise with it, so the environment change is tied to scroll, not to a timer. */
.page-home .stage-bg { position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(46% 38% at 50% 62%, rgba(232, 106, 36, calc(0.05 * var(--shift-energy, 0))), transparent 70%),
    radial-gradient(56% 46% at 50% 58%, rgba(212, 175, 55, calc(0.10 * var(--shift-energy, 0))), transparent 72%),
    radial-gradient(60% 50% at 50% 60%, rgba(11, 31, 58, calc(0.70 + 0.18 * var(--shift-energy, 0))), transparent 70%);
  /* The #050505 base that used to close this stack now lives on .stage, so the
     ignition glows above keep rendering while the video shows through beneath
     them. Every --shift-energy gradient is unchanged. */
}

/* Quieten everything else so the chapter reads as the important one: the
   global ambient layer steps back as the Phoenix takes the light. */
.page-home .pcp-cinematic-bg { opacity: calc(1 - 0.5 * var(--shift-energy, 0)); }

/* More negative space around the statement while it is on the stage. */
.page-home .captions { min-height: 12.5rem; padding-bottom: clamp(2.5rem, 7vh, 5rem); }
.page-home .stage-art { width: min(74vw, 37rem); }

/* --- Glass panels (Ecosystem) ------------------------------------------------ */
/* Premium base: deep navy over black, an extremely thin gold edge, and a
   single internal top light. No heavy glow — depth comes from layering. */
.page-home .panel {
  position: relative;
  background:
    linear-gradient(180deg, rgba(255,255,255,0.055) 0%, rgba(255,255,255,0.018) 42%, rgba(7,20,38,0.42) 100%),
    linear-gradient(180deg, #0A1524 0%, #070E1A 100%);
  border: 1px solid rgba(212, 175, 55, 0.16);
  border-radius: 20px;
  padding: 2rem;
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  transition: transform 550ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 550ms ease, border-color 550ms ease;
  will-change: transform;
}
.page-home .panel::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(60% 40% at 20% 0%, rgba(212,175,55,0.12), transparent 70%);
  opacity: 0; transition: opacity 550ms ease;
}
/* .is-hovered carries every non-transform change; the transform itself belongs
   to InteractiveCard, so there is no CSS hover transform to fight it. */
.page-home .panel.is-hovered {
  border-color: rgba(212, 175, 55, 0.42);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.10),
    0 30px 60px -34px rgba(0, 0, 0, 0.95),
    0 0 0 1px rgba(212, 175, 55, 0.10);
}
.page-home .panel.is-hovered::before { opacity: 1; }
/* icon activates, supporting text gains depth */
.page-home .panel .icon-line { transition: color 450ms ease, border-color 450ms ease, background-color 450ms ease, transform 550ms cubic-bezier(0.22, 1, 0.36, 1); }
.page-home .panel.is-hovered .icon-line { color: var(--pcp-gold-light); border-color: rgba(212, 175, 55, 0.52); background-color: rgba(212, 175, 55, 0.12); transform: translateY(-2px); }
.page-home .panel h3, .page-home .panel p { transition: color 450ms ease; }
.page-home .panel.is-hovered p { color: rgba(255, 255, 255, 0.74); }
.page-home .panel > * { position: relative; }
.page-home .panel h3 { font-size: 1.75rem; font-weight: 500; margin-top: 1.5rem; }
.page-home .panel p { font-size: 0.975rem; color: rgba(255,255,255,0.6); margin-top: 0.6rem; line-height: 1.6; }
.page-home .panel-featured { background: linear-gradient(180deg, rgba(212,175,55,0.10), rgba(255,255,255,0.03) 45%); border-color: rgba(212,175,55,0.4); }
.page-home .panel-featured h3 { font-size: 2.1rem; }
.page-home .icon-line { width: 2.75rem; height: 2.75rem; display: grid; place-items: center; border-radius: 12px; border: 1px solid rgba(212,175,55,0.3); color: var(--pcp-gold); background: rgba(212,175,55,0.06); }
.page-home .icon-line svg { width: 1.3rem; height: 1.3rem; }
.page-home .path { display: flex; flex-wrap: wrap; align-items: center; gap: 0.75rem 1rem; font-family: "Cormorant Garamond", Georgia, serif; font-size: clamp(1.35rem, 2vw, 1.75rem); color: rgba(255,255,255,0.85); }
.page-home .path svg { width: 1.1rem; height: 1.1rem; color: var(--pcp-gold); }

/* --- Photo slots + mask reveal ----------------------------------------------- */
.page-home .photo-slot {
  position: relative; overflow: hidden; border-radius: 20px; border: 1px solid rgba(212,175,55,0.22);
  background:
    radial-gradient(70% 60% at 30% 20%, rgba(11,31,58,0.9), transparent 70%),
    radial-gradient(60% 50% at 80% 100%, rgba(212,175,55,0.18), transparent 70%),
    linear-gradient(160deg, #071426, #050505);
}
.page-home .photo-slot img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: saturate(0.75) contrast(1.1) brightness(0.85) sepia(0.12); }
.page-home .photo-slot::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(5,5,5,0.05) 0%, rgba(5,5,5,0.55) 100%); pointer-events: none; }
.page-home .photo-slot .slot-note { position: absolute; left: 1.25rem; bottom: 1.1rem; z-index: 1; font-size: 0.62rem; letter-spacing: 0.22em; text-transform: uppercase; color: rgba(255,255,255,0.6); }
.page-home .mask-reveal { clip-path: inset(0 100% 0 0 round 20px); transition: clip-path 1200ms cubic-bezier(0.22, 1, 0.36, 1); }
.page-home .mask-reveal.is-visible { clip-path: inset(0 0 0 0 round 20px); }

/* --- Journey (Before → Journey → After) -------------------------------------- */
.page-home .journey { position: relative; display: grid; gap: 2.5rem; }
@media (min-width: 900px) { .page-home .journey { grid-template-columns: repeat(3, 1fr); gap: 2rem; } }
.page-home .journey::before { content: ""; position: absolute; left: 0.6rem; top: 0.6rem; bottom: 0.6rem; width: 1px; background: linear-gradient(180deg, rgba(212,175,55,0.6), rgba(212,175,55,0.1)); }
@media (min-width: 900px) { .page-home .journey::before { left: 0.6rem; right: 0.6rem; top: 0.6rem; bottom: auto; height: 1px; width: auto; background: linear-gradient(90deg, rgba(212,175,55,0.15), rgba(212,175,55,0.7), rgba(212,175,55,0.15)); } }
.page-home .journey > li { position: relative; padding-left: 2.25rem; }
@media (min-width: 900px) { .page-home .journey > li { padding-left: 0; padding-top: 2.25rem; } }
.page-home .journey .dot { position: absolute; left: 0; top: 0.1rem; width: 1.25rem; height: 1.25rem; border-radius: 999px; border: 1px solid var(--pcp-gold); background: #050505; display: grid; place-items: center; }
@media (min-width: 900px) { .page-home .journey .dot { top: 0; left: 0; } }
.page-home .journey .dot::after { content: ""; width: 0.4rem; height: 0.4rem; border-radius: 999px; background: var(--pcp-gold); }
.page-home .journey .label { font-size: 0.7rem; letter-spacing: 0.25em; text-transform: uppercase; color: var(--pcp-gold); }
.page-home .journey h3 { font-size: 1.75rem; font-weight: 500; margin-top: 0.5rem; }
.page-home .journey p { font-size: 0.975rem; color: rgba(255,255,255,0.62); margin-top: 0.6rem; }

/* --- Quote ------------------------------------------------------------------------ */
.page-home .quote { font-family: "Cormorant Garamond", Georgia, serif; font-size: clamp(1.5rem, 2.6vw, 2.15rem); line-height: 1.25; font-weight: 500; font-style: italic; color: rgba(255,255,255,0.92); }

/* --- Testimonial + stats --------------------------------------------------------- */
.page-home .stat { padding: 1.75rem 1.5rem; border-left: 1px solid rgba(212,175,55,0.25); }
.page-home .stat .stat-number { color: #fff; }
.page-home .stat dt { font-size: 0.7rem; letter-spacing: 0.22em; text-transform: uppercase; color: rgba(255,255,255,0.5); margin-top: 0.6rem; }

/* --- Orientation glow CTA -------------------------------------------------------- */
.page-home .glow-cta {
  position: relative; overflow: hidden; border-radius: 28px;
  border: 1px solid rgba(212,175,55,0.35);
  background: #070707;
  padding: clamp(3rem, 7vw, 6rem) clamp(1.5rem, 5vw, 5rem);
  text-align: center;
  isolation: isolate;
}
.page-home .glow-cta::before {
  content: ""; position: absolute; inset: -40% -20%; z-index: -1;
  background:
    radial-gradient(45% 45% at 50% 100%, rgba(232,106,36,0.42), transparent 70%),
    radial-gradient(60% 55% at 50% 100%, rgba(212,175,55,0.35), transparent 70%);
  filter: blur(20px);
}
.page-home .glow-cta::after {
  content: ""; position: absolute; left: 10%; right: 10%; bottom: 0; height: 1px; z-index: 0;
  background: linear-gradient(90deg, transparent, rgba(241,210,122,0.9), transparent);
}
.page-home .glow-cta .hero-logo { height: clamp(4.5rem, 7vw, 6rem); }

/* --- Footer ------------------------------------------------------------------------ */
/* Plain black. The old fade started at rgba(5,5,5,0), so the top third of the
   footer was translucent and the page's fixed room showed through it. A flat
   #050505 — the same Phoenix Black the fade already resolved to below 30% —
   closes it without changing the colour the footer has always been.
   Border and margin are untouched. */
/* The gap above the footer is the same size, but it is now padding rather than
   margin. A margin sits OUTSIDE the background box, so those 140px painted
   nothing and the page's fixed room showed through as a bright band directly
   above the footer. As padding it is inside the box, so the footer's own black
   covers it. Identical rendered spacing — the distance from the closing
   section to the footer content, and the page height, are unchanged. */
.page-home .site-footer { border-top: 1px solid rgba(212,175,55,0.12); padding-top: var(--section-y); background: #050505; }
.page-home .footer-title { font-family: Inter, sans-serif; font-size: 0.7rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--pcp-gold); font-weight: 600; }
.page-home .signature { font-family: "Cormorant Garamond", Georgia, serif; font-size: 1.75rem; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--pcp-gold); }
.page-home .social { width: 2.75rem; height: 2.75rem; display: grid; place-items: center; border-radius: 12px; border: 1px solid rgba(212,175,55,0.28); color: var(--pcp-gold); background: rgba(212,175,55,0.05); transition: transform 450ms cubic-bezier(0.22, 1, 0.36, 1); }
.page-home .social svg { width: 1.1rem; height: 1.1rem; }
.page-home .social:hover { transform: translateY(-2px); border-color: var(--pcp-gold); }
.page-home .social:active { transform: translateY(0); }
.page-home .link-muted { font-size: 0.95rem; }

/* --- Reduced motion ------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .page-home .split-words .w { opacity: 1; transform: none; transition: none; }
  .page-home .mask-reveal { clip-path: none; transition: none; }
  .page-home .scroll-cue i::after { animation: none; }
  .page-home .btn-primary::before { display: none; }
  .page-home .captions p { transition: none; }
}

/* --- Late refinements ------------------------------------------------------------- */
.page-home .path-step { display: inline-flex; align-items: center; gap: 0.75rem; white-space: nowrap; }
.page-home .photo-slot .slot-mark { position: absolute; left: 50%; top: 50%; width: clamp(5rem, 12vw, 9rem); height: auto; transform: translate(-50%, -50%); opacity: 0.14; filter: grayscale(0.2); pointer-events: none; }

/* --- Phoenix journey canvas layer --------------------------------------------------- */
/* Fixed, full-viewport, blended with `screen` so the Phoenix only adds light and never darkens type.
   z-index 40 keeps it beneath the site header (50). */
.page-home .phoenix-layer {
  position: fixed; inset: 0; width: 100%; height: 100%;
  z-index: 40; pointer-events: none;
  mix-blend-mode: screen;
}

/* --- Hero CTA sequencing + interaction ---------------------------------------
   The CTAs hold until the headline has essentially landed, so the opening
   resolves as one movement. Hidden only when JS is confirmed running
   (.pcp-js, set inline in <head>) — without JS they are simply visible. */
.pcp-js .page-home .hero [data-hero-seq] {
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 700ms ease, transform 900ms cubic-bezier(0.22, 1, 0.36, 1);
}
.pcp-js .page-home .hero [data-hero-seq].is-in {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .pcp-js .page-home .hero [data-hero-seq] { opacity: 1 !important; transform: none !important; transition: none; }
}

/* Wrapper carries the magnetic offset so the button keeps its own hover
   transform — GSAP writing inline transform on the button would cancel it. */
.page-home .magnetic { display: inline-block; will-change: transform; }
.page-home .magnetic > .btn { width: 100%; }
@media (max-width: 767px) { .page-home .magnetic { display: block; width: 100%; } }

/* Restrained CTA illumination: the border lights, and a soft interior glow
   rises. No neon, no flare — both are opacity/shadow only. */
.page-home .hero .btn-secondary {
  position: relative;
  border-color: rgba(212, 175, 55, 0.42);
  transition: border-color 600ms ease, box-shadow 600ms ease, transform 450ms cubic-bezier(0.22, 1, 0.36, 1);
}
.page-home .hero .btn-secondary::after {
  background: radial-gradient(120% 100% at 50% 120%, rgba(212, 175, 55, 0.16), transparent 70%);
  opacity: 0;
  transition: opacity 600ms ease;
}
.page-home .hero .btn-secondary:hover {
  border-color: rgba(212, 175, 55, 0.85);
  box-shadow: 0 0 0 1px rgba(212, 175, 55, 0.18), 0 14px 36px -18px rgba(212, 175, 55, 0.45);
}
.page-home .hero .btn-secondary:hover::after { opacity: 1; }

.page-home .hero .btn-primary {
  transition: transform 450ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 600ms ease;
}
.page-home .hero .btn-primary:hover {
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.45) inset,
              0 16px 40px -14px rgba(212, 175, 55, 0.7),
              0 0 0 1px rgba(212, 175, 55, 0.28);
}

/* --- Global Connection: 3D Earth at night ------------------------------------
   The canvas is drawn by assets/js/globe.js. Copy is choreographed from the
   same scroll progress and never hidden by CSS, so it is readable even if the
   library never loads. Desktop: Earth right, typography left. Mobile: copy
   stacks above a lower, lighter globe. */
.page-home .globe-section { position: relative; }
.page-home .globe-pin { position: relative; height: 380vh; }
.page-home .globe-pin.static { height: auto; }
.page-home .globe-stage {
  position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; isolation: isolate;
  background: radial-gradient(60% 50% at 66% 52%, rgba(11, 31, 58, 0.55), transparent 70%), #050505;
}
.page-home .globe-pin.static .globe-stage { position: relative; height: auto; min-height: 100svh; }
/* The deep-navy fade that used to ease this top edge is gone. It existed
   because the stage was opaque near-black and the section above carried the
   page's navy, so the two needed a join. Neither is true now: both sit on the
   same fixed room, so there is no boundary to ease — and a 16vh band across
   the full width was itself the frame-like edge above the globe. */
.page-home .globe-stage::before { display: none; }
.page-home .globe-canvas { position: absolute; inset: 0; z-index: 0; }
.page-home .globe-canvas canvas { display: block; width: 100%; height: 100%; }
.page-home .globe-copy { position: relative; z-index: 1; height: 100%; display: grid; align-items: center; pointer-events: none; }
.page-home .globe-text { max-width: 34rem; pointer-events: auto; }
.page-home .globe-title { font-size: clamp(2.1rem, 4.1vw, 3.6rem); line-height: 1.04; margin-top: 1.5rem; }
.page-home .globe-line { display: block; will-change: transform, opacity; }
.page-home .globe-text .eyebrow, .page-home .globe-links { will-change: transform, opacity; }
.page-home .globe-links {
  margin-top: 2.25rem; display: flex; flex-wrap: wrap; gap: 0.7rem 1.5rem;
  font-size: 0.74rem; letter-spacing: 0.18em; text-transform: uppercase; color: rgba(255, 255, 255, 0.6);
}
.page-home .globe-links li { display: inline-flex; align-items: center; gap: 0.6rem; transition: color 600ms ease; }
.page-home .globe-links li::before {
  content: ""; width: 6px; height: 6px; border-radius: 999px;
  background: rgba(212, 175, 55, 0.22);
  box-shadow: 0 0 0 0 rgba(212, 175, 55, 0);
  transition: background-color 600ms ease, box-shadow 600ms ease;
}
.page-home .globe-links li.is-lit { color: rgba(255, 255, 255, 0.86); }
.page-home .globe-links li.is-lit::before { background: var(--pcp-gold-light); box-shadow: 0 0 10px 2px rgba(212, 175, 55, 0.32); }
.page-home .globe-links-note { font-size: 0.58rem; color: var(--pcp-gold); letter-spacing: 0.22em; }
@media (min-width: 1024px) {
  .page-home .globe-copy { grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); }
  .page-home .globe-text { grid-column: 1; }
  /* Start the canvas below the navigation, the same move the phone layout
     already makes with top: 26% further down.

     The header is sticky and opaque, so it sits over the top of the stage the
     whole way through this chapter. With the canvas at inset 0 the globe
     centres on the middle of the VIEWPORT, which put 6-16px of its top behind
     the bar: measured with the header hidden, its top edge landed at y=74 on
     a 1440x900 laptop and y=64 at 1440x780, against an 85px header.

     Insetting the canvas makes it the clear area instead, and assets/js/
     globe.js sizes the Earth from this element's own box (fitDistance reads
     host.clientHeight), so the globe both re-centres and re-fits into the
     space that is actually visible. Nothing else in the section moves: the
     copy is positioned by .globe-copy, which is untouched. */
  .page-home .globe-canvas { top: var(--globe-canvas-top, 85px); }
}
@media (max-width: 1023px) {
  .page-home .globe-copy { align-items: start; padding-top: clamp(5.5rem, 13vh, 8rem); }
  .page-home .globe-text { max-width: 30rem; }
  .page-home .globe-canvas { top: 26%; }
}
/* No-WebGL / low-end fallback: a quiet dark disc so the composition still reads. */
.page-home .globe-fallback {
  position: absolute; left: 66%; top: 52%; width: min(70vw, 34rem); aspect-ratio: 1;
  transform: translate(-50%, -50%); border-radius: 50%;
  background: radial-gradient(circle at 36% 34%, #10233f 0%, #071426 44%, #030a14 70%, transparent 71%);
  box-shadow: 0 0 90px 12px rgba(11, 31, 58, 0.55), inset -30px -20px 80px rgba(0, 0, 0, 0.85);
}
@media (max-width: 1023px) { .page-home .globe-fallback { left: 50%; top: 68%; } }

/* --- PCP ecosystem map -------------------------------------------------------
   PCP at the centre, the seven pillars around it, thin champagne lines between.
   Nodes are real buttons (focusable, readable, selectable); the connective lines
   are one inline SVG whose paths are rewritten from the node positions each
   frame. No WebGL, no canvas: at this node count the DOM is cheaper and the
   type stays crisp. Movement is a very slow lissajous drift, only while the
   section is on screen. Positions/depth/copy come from the markup. */
.page-home .eco-map { --eco-squash: 0.78; position: relative; }

.page-home .eco-stage {
  position: relative;
  height: clamp(30rem, 46vw, 41rem);
  isolation: isolate;
}
.page-home .eco-ambient {
  position: absolute; inset: -12% -6%; z-index: 0; pointer-events: none;
  background:
    radial-gradient(40% 40% at 50% 50%, rgba(212, 175, 55, 0.1), transparent 66%),
    radial-gradient(66% 60% at 50% 47%, rgba(11, 31, 58, 0.75), transparent 74%),
    radial-gradient(90% 80% at 50% 50%, transparent 52%, rgba(5, 5, 5, 0.5));
}

/* Connective lines. The viewBox is set to the stage's pixel box by the script,
   so path coordinates are plain pixels and strokes never skew. */
.page-home .eco-lines {
  position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%;
  overflow: visible; pointer-events: none;
}
.page-home .eco-line {
  fill: none;
  stroke: rgba(212, 175, 55, 0.62);
  stroke-width: 1;
  stroke-linecap: round;
  opacity: 0.55;
  transition: opacity 620ms var(--ease-spring), stroke 620ms var(--ease-spring);
}
.page-home .eco-line.eco-ring-line { stroke: rgba(212, 175, 55, 0.4); stroke-dasharray: 2 5; opacity: 0.34; }
.page-home .eco-map.is-focused .eco-line { opacity: 0.13; }
.page-home .eco-map.is-focused .eco-line.is-lit {
  opacity: 1; stroke: rgba(241, 210, 122, 0.9);
  filter: drop-shadow(0 0 6px rgba(212, 175, 55, 0.45));
}

/* Centre */
.page-home .eco-core {
  position: absolute; left: 50%; top: 50%; z-index: 3;
  transform: translate(-50%, -50%);
  display: grid; place-items: center;
  width: clamp(11rem, 17vw, 14.5rem); aspect-ratio: 1;
  border: 0; background: none; padding: 0;
  color: var(--pcp-white); cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.page-home .eco-core > * { grid-area: 1 / 1; }
.page-home .eco-core-bloom {
  width: 260%; aspect-ratio: 1; border-radius: 50%; pointer-events: none;
  background: radial-gradient(50% 50% at 50% 50%, rgba(212, 175, 55, 0.23), rgba(212, 175, 55, 0.06) 44%, transparent 68%);
  opacity: 0.9; transition: opacity 700ms var(--ease-spring);
}
.page-home .eco-core-ring {
  width: 100%; aspect-ratio: 1; border-radius: 50%; pointer-events: none;
  border: 1px solid rgba(212, 175, 55, 0.5);
  background:
    radial-gradient(62% 62% at 50% 34%, rgba(14, 38, 69, 0.97), rgba(5, 7, 12, 0.99) 74%);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.05) inset,
    0 0 0 1px rgba(212, 175, 55, 0.08),
    0 34px 80px -34px rgba(212, 175, 55, 0.4);
  transition: border-color 700ms var(--ease-spring), box-shadow 700ms var(--ease-spring);
}
.page-home .eco-core-ring-2 {
  width: 128%; border-color: rgba(212, 175, 55, 0.2); background: none; box-shadow: none;
  animation: eco-breathe 18s ease-in-out infinite;
}
@keyframes eco-breathe { 0%, 100% { opacity: 0.55; transform: scale(1); } 50% { opacity: 1; transform: scale(1.02); } }
.page-home .eco-core-face { display: grid; justify-items: center; gap: 0.5rem; padding: 0 1rem; pointer-events: none; }
.page-home .eco-core-mark {
  font-family: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  font-size: clamp(2.15rem, 3.4vw, 3rem); font-weight: 500; line-height: 1;
  letter-spacing: 0.05em; color: var(--pcp-white);
  text-shadow: 0 0 26px rgba(212, 175, 55, 0.3);
}
.page-home .eco-core-full {
  font-size: 0.58rem; letter-spacing: 0.19em; text-transform: uppercase; line-height: 1.55;
  color: rgba(255, 255, 255, 0.62); max-width: 8.8rem; text-align: center;
  transition: color 620ms var(--ease-spring);
}
.page-home .eco-core:hover .eco-core-ring,
.page-home .eco-core:focus-visible .eco-core-ring,
.page-home .eco-core.is-active .eco-core-ring {
  border-color: rgba(212, 175, 55, 0.7);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.07) inset, 0 0 0 1px rgba(212, 175, 55, 0.2), 0 40px 90px -30px rgba(212, 175, 55, 0.62);
}
.page-home .eco-core:hover .eco-core-full,
.page-home .eco-core.is-active .eco-core-full { color: rgba(255, 255, 255, 0.78); }
.page-home .eco-core:active { transform: translate(-50%, -50%) scale(0.985); }
.page-home .eco-core:focus-visible { outline: none; }
.page-home .eco-core:focus-visible .eco-core-ring-2 { border-color: rgba(212, 175, 55, 0.62); }

/* Nodes */
.page-home .eco-nodes { position: absolute; inset: 0; z-index: 2; margin: 0; padding: 0; list-style: none; }
.page-home .eco-node {
  position: absolute;
  left: calc(50% + (var(--nx) - 0.5) * var(--eco-squash) * 100%);
  top: calc(var(--ny) * 100%);
  transform: translate(-50%, -50%);
  display: grid; justify-items: center; gap: 0.7rem;
  width: max-content; max-width: 11rem; padding: 0.5rem 0.7rem;
  border: 0; background: none; text-align: center; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  will-change: transform, opacity;
}
.page-home .eco-dot {
  position: relative; width: 0.55rem; height: 0.55rem; border-radius: 50%;
  background: var(--pcp-gold-light);
  box-shadow: 0 0 0 1px rgba(212, 175, 55, 0.5), 0 0 14px 2px rgba(212, 175, 55, 0.35);
  transition: box-shadow 560ms var(--ease-spring), background-color 560ms var(--ease-spring);
}
.page-home .eco-dot::after {
  content: ''; position: absolute; inset: -0.85rem; border-radius: 50%;
  border: 1px solid rgba(212, 175, 55, 0.18);
  opacity: 0; transform: scale(0.7);
  transition: opacity 620ms var(--ease-spring), transform 620ms var(--ease-spring);
}
.page-home .eco-label {
  font-size: 0.7rem; letter-spacing: 0.17em; text-transform: uppercase; line-height: 1.45;
  color: rgba(255, 255, 255, 0.74);
  transition: color 560ms var(--ease-spring);
}
.page-home .eco-node[data-eco-depth="far"] .eco-label { color: rgba(255, 255, 255, 0.56); }
.page-home .eco-node[data-eco-depth="far"] .eco-dot { box-shadow: 0 0 0 1px rgba(212, 175, 55, 0.34), 0 0 10px 1px rgba(212, 175, 55, 0.22); }

.page-home .eco-node:hover .eco-label,
.page-home .eco-node:focus-visible .eco-label,
.page-home .eco-node.is-active .eco-label { color: var(--pcp-white); }
.page-home .eco-node:hover .eco-dot,
.page-home .eco-node:focus-visible .eco-dot,
.page-home .eco-node.is-active .eco-dot {
  background: #FFF6DE;
  box-shadow: 0 0 0 1px rgba(241, 210, 122, 0.85), 0 0 22px 5px rgba(212, 175, 55, 0.55);
}
.page-home .eco-node:hover .eco-dot::after,
.page-home .eco-node:focus-visible .eco-dot::after,
.page-home .eco-node.is-active .eco-dot::after { opacity: 1; transform: scale(1); border-color: rgba(212, 175, 55, 0.4); }
.page-home .eco-node:focus-visible { outline: none; }
.page-home .eco-node:focus-visible .eco-label { text-decoration: underline; text-underline-offset: 0.35em; text-decoration-color: rgba(212, 175, 55, 0.6); }
.page-home .eco-node.is-muted { opacity: 0.55; }

/* Readout: reserved space under the centre so nothing reflows when it fills. */
.page-home .eco-readout {
  position: absolute; z-index: 3; left: 50%; top: 50%; transform: translate(-50%, 0);
  margin-top: clamp(6.2rem, 9.5vw, 8.2rem);
  width: min(30rem, 82%); min-height: 4.5rem;
  display: grid; gap: 0.35rem; justify-items: center; text-align: center;
  pointer-events: none;
}
.page-home .eco-readout-name {
  font-size: 0.62rem; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--pcp-gold); opacity: 0; transition: opacity 480ms var(--ease-spring);
}
.page-home .eco-readout-text {
  font-size: 0.85rem; line-height: 1.65; color: rgba(255, 255, 255, 0.74);
  opacity: 0; transform: translateY(6px);
  transition: opacity 520ms var(--ease-spring), transform 520ms var(--ease-spring);
}
.page-home .eco-readout.is-shown .eco-readout-name { opacity: 1; }
.page-home .eco-readout.is-shown .eco-readout-text { opacity: 1; transform: translateY(0); }

/* Guard: the script sets each node's entrance from-state. Hidden only while
   scripting is available and the map has not been taken over yet; the rescue
   pass in assets/js/reveals.js stamps data-eco-ready if that never happens. */
.pcp-js .page-home .eco-map:not([data-eco-ready]) .eco-node,
.pcp-js .page-home .eco-map:not([data-eco-ready]) .eco-line { opacity: 0; }

@media (max-width: 1023px) {
  .page-home .eco-map { --eco-squash: 0.92; }
  .page-home .eco-stage { height: clamp(27rem, 88vw, 34rem); }
  .page-home .eco-node { max-width: 7.4rem; padding: 0.4rem 0.35rem; gap: 0.55rem; }
  .page-home .eco-label { font-size: 0.6rem; letter-spacing: 0.12em; }
  .page-home .eco-core { width: clamp(8.5rem, 34vw, 11rem); }
  .page-home .eco-core-full { font-size: 0.5rem; letter-spacing: 0.16em; max-width: 7rem; }
  /* Below the stage on small screens: there is no room inside it. It is a
     sibling of the stage, so returning it to normal flow puts it underneath. */
  .page-home .eco-readout {
    position: static; transform: none; margin: 1.5rem auto 0;
    width: min(30rem, 100%); min-height: 6rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .page-home .eco-core-ring-2 { animation: none; }
  .page-home .eco-node, .page-home .eco-line, .page-home .eco-readout-text { transition-duration: 1ms; }
  .page-home .eco-readout-text { transform: none; }
}

/* --- Community cinematic media ----------------------------------------------
   A black stage holding one large frame and three smaller ones. Every frame is
   a self-contained shell: abstract texture, slow light, optional particles, a
   mount for real footage, and a vignette. Media is injected into .media-mount
   by assets/js/community.js; until then the texture carries the frame, so an
   unconfigured slot reads as an intentional dark panel, never a broken box.
   Only transform and opacity are animated. */
.page-home .community-section {
  position: relative; isolation: isolate; overflow: hidden;
  padding: var(--section-y) 0;
  background: #050505;
}
.page-home .community-glow {
  position: absolute; inset: -20% -10% auto; height: 90%; z-index: 0; pointer-events: none;
  /* The navy radial that used to sit alongside the gold one is removed: at
     0.72 it read as a solid blue panel filling the top-right of the section,
     which is the separate background this area should not have. The gold
     accent stays — it is a light source, not a ground. */
  background:
    radial-gradient(42% 50% at 20% 2%, rgba(212, 175, 55, 0.11), transparent 68%);
}
.page-home .community-section > .wrap { position: relative; z-index: 1; }
.page-home .community-head { max-width: 46rem; }
.page-home .community-title { font-size: clamp(2rem, 4.4vw, 3.9rem); }

/* ---- the frame shell ---- */
.page-home .media-frame {
  position: relative; overflow: hidden; isolation: isolate;
  border-radius: var(--radius);
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(16, 34, 58, 0.55), transparent 62%),
    linear-gradient(168deg, #0d1728 0%, #080d18 48%, #05070c 100%);
  box-shadow:
    0 0 0 1px rgba(212, 175, 55, 0.26),
    0 1px 0 rgba(255, 255, 255, 0.07) inset,
    0 0 0 1px rgba(255, 255, 255, 0.03) inset,
    0 40px 90px -50px rgba(0, 0, 0, 0.95),
    0 24px 70px -46px rgba(212, 175, 55, 0.3);
  transition: box-shadow 700ms var(--ease-spring), transform 700ms var(--ease-spring);
}
/* Letterbox rather than 16:9: cinematic, and it does not swamp the page. */
.page-home .media-frame-hero { aspect-ratio: 21 / 9; }
.page-home .community-clip .media-frame { aspect-ratio: 4 / 5; }

/* ---- abstract texture: slow, low-contrast light blooms ---- */
.page-home .media-texture { position: absolute; inset: 0; z-index: 0; }
.page-home .media-drift {
  position: absolute; display: block; border-radius: 50%;
  will-change: transform, opacity;
}
.page-home .media-drift-1 {
  width: 86%; aspect-ratio: 1; left: -10%; top: -18%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(212, 175, 55, 0.17), rgba(212, 175, 55, 0.045) 46%, transparent 72%);
  animation: media-drift-a 68s ease-in-out infinite;
}
.page-home .media-drift-2 {
  width: 100%; aspect-ratio: 1; right: -16%; bottom: -26%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(11, 31, 58, 0.95), rgba(11, 31, 58, 0.3) 44%, transparent 72%);
  animation: media-drift-b 84s ease-in-out infinite;
}
.page-home .media-drift-3 {
  width: 68%; aspect-ratio: 1; left: 36%; top: 22%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(232, 106, 36, 0.09), transparent 68%);
  animation: media-drift-c 96s ease-in-out infinite;
}
@keyframes media-drift-a {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); opacity: 0.75; }
  50%      { transform: translate3d(14%, 18%, 0) scale(1.16); opacity: 1; }
}
@keyframes media-drift-b {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1.04); opacity: 0.9; }
  50%      { transform: translate3d(-16%, -12%, 0) scale(1); opacity: 0.6; }
}
@keyframes media-drift-c {
  0%, 100% { transform: translate3d(0, 0, 0) scale(0.9); opacity: 0.5; }
  50%      { transform: translate3d(-20%, 14%, 0) scale(1.2); opacity: 0.9; }
}

/* ---- one very slow raking light pass ---- */
.page-home .media-sheen {
  position: absolute; z-index: 1; top: -60%; bottom: -60%; left: -55%; width: 52%;
  background: linear-gradient(90deg, transparent, rgba(255, 244, 214, 0.022) 34%, rgba(255, 244, 214, 0.05) 50%, rgba(255, 244, 214, 0.022) 66%, transparent);
  filter: blur(6px);
  transform: rotate(14deg) translate3d(0, 0, 0);
  animation: media-sheen 26s cubic-bezier(0.45, 0, 0.55, 1) infinite;
  will-change: transform, opacity;
  pointer-events: none;
}
@keyframes media-sheen {
  0%        { transform: rotate(14deg) translate3d(0, 0, 0); opacity: 0; }
  12%       { opacity: 1; }
  62%       { opacity: 1; }
  72%, 100% { transform: rotate(14deg) translate3d(300%, 0, 0); opacity: 0; }
}
.page-home .community-clip .media-sheen { animation-duration: 34s; }
.page-home .community-clip:nth-child(2) .media-sheen { animation-delay: -11s; }
.page-home .community-clip:nth-child(3) .media-sheen { animation-delay: -22s; }

.page-home .media-particles { position: absolute; inset: 0; z-index: 2; pointer-events: none; }

/* ---- the mount that real footage lands in ---- */
.page-home .media-mount { position: absolute; inset: 0; z-index: 3; }
.page-home .media-mount video,
.page-home .media-mount img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity 1200ms var(--ease-spring);
}
.page-home .media-frame.is-showing .media-mount video,
.page-home .media-frame.is-showing .media-mount img { opacity: 1; }
/* Footage replaces the stand-in rather than layering over it. */
.page-home .media-frame.is-showing .media-texture,
.page-home .media-frame.is-showing .media-sheen,
.page-home .media-frame.is-showing .media-particles { opacity: 0; }
.page-home .media-texture, .page-home .media-particles { transition: opacity 900ms var(--ease-spring); }
.page-home .media-sheen { transition: opacity 900ms var(--ease-spring); }

/* Colour treatment over real footage, per the brand's image rules. */
.page-home .media-vignette {
  position: absolute; inset: 0; z-index: 4; pointer-events: none; opacity: 0;
  transition: opacity 1200ms var(--ease-spring);
  background:
    radial-gradient(78% 74% at 50% 42%, transparent 42%, rgba(5, 5, 5, 0.62)),
    linear-gradient(to top, rgba(5, 5, 5, 0.62), transparent 58%);
}
.page-home .media-frame.is-showing .media-vignette { opacity: 1; }
.page-home .media-frame.is-showing::after {
  content: ''; position: absolute; inset: 0; z-index: 5; pointer-events: none;
  background: linear-gradient(to top, rgba(11, 31, 58, 0.5), rgba(212, 175, 55, 0.05));
  mix-blend-mode: multiply;
}

/* ---- development-only slot label (localhost, or ?media=debug) ---- */
.page-home .media-slot {
  position: absolute; z-index: 8; left: 0.85rem; bottom: 0.85rem;
  max-width: calc(100% - 1.7rem);
  padding: 0.32rem 0.6rem; border-radius: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.62rem; letter-spacing: 0.02em; line-height: 1.5;
  color: rgba(241, 210, 122, 0.82);
  background: rgba(5, 5, 5, 0.66);
  border: 1px solid rgba(212, 175, 55, 0.22);
  backdrop-filter: blur(6px);
  pointer-events: none; overflow-wrap: anywhere;
}

/* ---- layout ---- */
.page-home .community-hero { margin: clamp(2.5rem, 5vw, 4rem) 0 0; }
.page-home .community-strip {
  margin: clamp(1rem, 1.7vw, 1.5rem) 0 0; padding: 0; list-style: none;
  display: grid; gap: clamp(1rem, 1.7vw, 1.5rem); grid-template-columns: repeat(3, 1fr);
}
/* A little vertical rhythm so the three do not read as a filmstrip. */
.page-home .community-clip:nth-child(2) { transform: translateY(clamp(0.75rem, 1.6vw, 1.5rem)); }
.page-home .community-clip:nth-child(3) { transform: translateY(clamp(1.5rem, 3.2vw, 3rem)); }

@media (hover: hover) and (pointer: fine) {
  .page-home .media-frame:hover {
    box-shadow:
      0 0 0 1px rgba(212, 175, 55, 0.32),
      0 1px 0 rgba(255, 255, 255, 0.07) inset,
      0 44px 100px -48px rgba(0, 0, 0, 0.95),
      0 28px 80px -40px rgba(212, 175, 55, 0.4);
  }
}

@media (max-width: 767px) {
  .page-home .community-strip { grid-template-columns: repeat(2, 1fr); }
  .page-home .community-clip:nth-child(3) { grid-column: span 2; transform: none; }
  .page-home .community-clip:nth-child(3) .media-frame { aspect-ratio: 16 / 10; }
  .page-home .community-clip:nth-child(2) { transform: none; }
  .page-home .media-frame-hero { aspect-ratio: 5 / 4; }
}

@media (prefers-reduced-motion: reduce) {
  .page-home .media-drift, .page-home .media-sheen { animation: none; }
  /* Held at a composed position rather than the animation's start frame. */
  .page-home .media-drift-1 { transform: translate3d(7%, 9%, 0) scale(1.08); opacity: 0.9; }
  .page-home .media-drift-2 { transform: translate3d(-8%, -6%, 0) scale(1.02); opacity: 0.75; }
  .page-home .media-drift-3 { transform: translate3d(-10%, 7%, 0) scale(1.05); opacity: 0.7; }
  .page-home .media-sheen { opacity: 0.55; transform: rotate(14deg) translate3d(180%, 0, 0); }
}

/* ==========================================================================
   THE CLOSING — the final cinematic chapter
   Not another climax. The Phoenix sequence peaked earlier on this page, so
   this movement subtracts: near-black, the official mark low and large
   behind everything, dust that slows, and the brand signature signing off
   into the footer.

   Defaults are VISIBLE — closing.js animates from a hidden state at
   runtime — so with no JS, no GSAP or reduced motion the ending still reads
   as a finished composition.
   ========================================================================== */

.page-home .closing {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  /* Was clamp(5rem, 12vh, 9rem) — 108px, which met the footer's own 48 and
     put 156px under the last chapter while every other boundary on the site
     had settled to 96. Now the same half-inch as everything else. */
  padding-bottom: var(--section-y);
  /* Solid black. The old base faded from transparent at 0% to #030303, which
     is what let the page's fixed room show through the top third of this
     section. A flat #000000 closes it completely: nothing behind this section
     is visible any more. The faint gold accent above it is kept — it is this
     section's own light, not a background showing through. */
  background:
    radial-gradient(120% 80% at 50% 12%, rgba(212, 175, 55, 0.045) 0%, transparent 62%),
    #000000;
}

/* --- The mark ---------------------------------------------------------- */

/* Large, centred, and deliberately faint. The opacity ceiling is the whole
   reason it cannot overpower the CTA sitting on top of it. */
.page-home .closing-mark {
  position: absolute;
  left: 50%;
  top: 46%;
  z-index: 0;
  width: min(52rem, 88vw);
  transform: translate(-50%, -50%);
  pointer-events: none;
}

/* The dimming lives on the IMAGE, not the wrapper. closing.js fades the
   wrapper 0 → 1, so if the ceiling were on the wrapper the animation would
   overwrite it with an inline opacity:1 and the mark would drown the CTA. */
.page-home .closing-mark img {
  display: block;
  width: 100%;
  height: auto;
  opacity: 0.11;
  /* Bleed the edges into the ground so it reads as light, not a pasted PNG. */
  mask-image: radial-gradient(closest-side, #000 42%, transparent 82%);
  -webkit-mask-image: radial-gradient(closest-side, #000 42%, transparent 82%);
}

/* --- Ambient dust ------------------------------------------------------ */

.page-home .closing-dust {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.page-home .closing-mote {
  position: absolute;
  width: 2px;
  height: 2px;
  border-radius: 50%;
  background: rgba(241, 210, 122, 0.85);
  box-shadow: 0 0 6px rgba(212, 175, 55, 0.55);
  will-change: transform, opacity;
}

/* --- Content ----------------------------------------------------------- */

.page-home .closing-inner {
  position: relative;
  z-index: 2;
  text-align: center;
}

.page-home .closing-title { letter-spacing: -0.03em; }

.page-home .closing-lede { max-width: 40rem; color: rgba(255, 255, 255, 0.62); }

.page-home .closing-action {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  margin-top: clamp(2.5rem, 6vh, 3.5rem);
}

.page-home .closing-note {
  margin: 0;
  font-size: 0.82rem;
  color: rgba(255, 255, 255, 0.62);
}

/* --- The sign-off ------------------------------------------------------ */

.page-home .closing-cadence {
  margin-top: clamp(5rem, 14vh, 10rem);
  padding-top: clamp(2.5rem, 6vh, 4rem);
  border-top: 1px solid rgba(212, 175, 55, 0.14);
}

/* Three beats, spaced like a spoken cadence rather than a heading. */
.page-home .closing-beats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4em clamp(1.25rem, 4vw, 3rem);
  /* These are <p> elements, so they inherit the page's 42rem prose cap and
     would sit left of centre without this. */
  max-width: none;
  margin: 0 auto;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: clamp(1.5rem, 3.4vw, 2.6rem);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.1;
  color: rgba(255, 255, 255, 0.9);
}

.page-home .closing-welcome {
  max-width: none;
  margin: clamp(1.75rem, 4vh, 2.5rem) auto 0;
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: clamp(1.15rem, 2.2vw, 1.6rem);
  font-weight: 500;
  font-style: italic;
  letter-spacing: 0.02em;
  background: linear-gradient(140deg, #F1D27A 0%, #D4AF37 46%, #B8891B 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

@media (prefers-reduced-motion: reduce) {
  .page-home .closing-dust { display: none; }
  .page-home .closing-mark { transform: translate(-50%, -50%) !important; }
}

/* --- QA pass: clip decorative layers; mobile touch targets ---------------- */
/* Ambient glows, rays and sheens are positioned past the viewport edge by
   design. Clip them at the section so they never widen the document. `clip`
   rather than `hidden`, so no scroll container is created. */
.page-home .hero,
.page-home .community-section,
.page-home .section.surface-navy-solid { overflow-x: clip; }

@media (max-width: 767px) {
  /* Ecosystem nodes measured 34–38px tall. Centre the content in a 44px
     minimum; the node is translate-centred on its anchor, so the visual
     position does not move. */
  .page-home .eco-node { min-height: 2.75rem; align-content: center; }
  /* Path steps were nowrap and could exceed the viewport. */
  .page-home .path-step { white-space: normal; }
}

/* ==========================================================================
   Mobile pass — home
   ========================================================================== */
@media (max-width: 767px) {
  /* Two pinned chapters at 380vh each are ~7.6 screens of thumb-scrolling. The
     Phoenix and globe choreography are fractions of the pin, so shortening it
     compresses the timing rather than cutting anything. */
  .page-home .sequence { height: 340vh; }
  .page-home .globe-pin { height: 300vh; }

  /* The far-depth nodes are scaled to 0.885 by the map, which took a 44px
     button to 39px. Sized so even the smallest lands past 44px. */
  .page-home .eco-node { min-height: 3.2rem; }

  /* Reserved readout space is dead space until a node is tapped. Tighter, but
     still held so the reveal cannot shift the cards beneath it. */
  .page-home .eco-readout { min-height: 4.5rem; margin-top: 1rem; }

  /* Filter blur on a moving element is a per-frame cost on mobile. The sheen
     still moves; it is simply no longer blurred. */
  .page-home .media-sheen { filter: none; }
}
@media (max-width: 767px) {
  /* Seven cards each carrying a backdrop blur is seven blurs re-sampled on
     every scroll frame. The cards sit on a solid navy slab here, so the glass
     was buying nothing visible. */
  .page-home .panel { -webkit-backdrop-filter: none; backdrop-filter: none; }
  /* One static glow; a softer radius reads identically at this size. */
  .page-home .glow-cta::before { filter: blur(12px); }
}

/* ==========================================================================
   PCP in motion + Members' achievements — media card grids
   --------------------------------------------------------------------------
   Reuses the Community frame (texture → sheen → mount → vignette) so the
   stand-ins and the real footage share one visual language. Only the grid
   and the caption are new.
   ========================================================================== */
/* No margin/padding/list-style reset here: Tailwind's preflight already zeroes
   them, and a reset at this specificity (0,2,0) silently beat the markup's
   `mt-14` (0,1,0) — the grid sat flush against its heading. */
.page-home .moments-grid {
  display: grid; gap: 1.25rem;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.page-home .moment figure { margin: 0; }
/* These six are VIDEO slots, not picture cards. The frame is the exact shape
   of the footage that goes in it — 848x464, the native size of the video in
   card 1 — so the border sits on the video's own edge with no black space
   inside it, and nothing has to be cropped or letterboxed to fit.
   4 / 3 was a photographic ratio and left bands above and below the footage.
   The five empty slots carry the same shape, ready for their own videos. */
.page-home .moment .media-frame { aspect-ratio: 848 / 464; }
.page-home .moments-grid-tall .moment .media-frame { aspect-ratio: 4 / 5; }
/* Each frame's sheen drifts on its own clock, so the grid never pulses in unison. */
.page-home .moment:nth-child(2) .media-sheen { animation-delay: -7s; }
.page-home .moment:nth-child(3) .media-sheen { animation-delay: -14s; }
.page-home .moment:nth-child(4) .media-sheen { animation-delay: -21s; }
.page-home .moment:nth-child(5) .media-sheen { animation-delay: -28s; }
.page-home .moment:nth-child(6) .media-sheen { animation-delay: -35s; }
/* Hover: the same restrained lift the Community frames use. */
@media (hover: hover) and (pointer: fine) {
  .page-home .moment .media-frame:hover { transform: translateY(-3px); }
}
.page-home .media-caption {
  display: flex; align-items: baseline; gap: 0.75rem;
  margin-top: 0.9rem;
  font-size: 0.72rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
}
.page-home .media-caption-n {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: 1.05rem; letter-spacing: 0; text-transform: none;
  color: var(--pcp-gold); font-weight: 600;
}
@media (max-width: 1023px) { .page-home .moments-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 639px)  { .page-home .moments-grid { grid-template-columns: 1fr; gap: 1rem; } }

/* ==========================================================================
   Hero CTA hierarchy + reservation window
   --------------------------------------------------------------------------
   "Reserve My Slot" is the primary conversion action: gold fill, a soft gold
   glow, a slow light sweep on a 5-second cadence, and a small hover lift.
   "Discover PCP" steps back to a dark translucent navy with a thin gold
   border. Only transform and opacity animate; nothing flashes.
   ========================================================================== */

/* ---- primary: RESERVE MY SLOT → ---- */
.page-home .hero .btn-primary {
  overflow: hidden;                              /* clips the sweep */
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.35) inset,
    0 14px 38px -16px rgba(212, 175, 55, 0.62),
    0 0 0 1px rgba(212, 175, 55, 0.22),
    0 0 28px -10px rgba(212, 175, 55, 0.35);     /* the resting glow */
}
/* The light sweep: a soft diagonal highlight crosses once in ~1.3s, then rests
   off-button for the remainder of each 5s cycle. z-index 0 keeps it under the
   label (.btn-primary > * is z-index 1) and above the gold fill. */
.page-home .hero .btn-primary::before {
  content: "";
  position: absolute; top: -30%; bottom: -30%; left: 0; width: 34%;
  background: linear-gradient(105deg,
    transparent 0%, rgba(255, 250, 230, 0) 32%, rgba(255, 250, 230, 0.55) 50%, rgba(255, 250, 230, 0) 68%, transparent 100%);
  transform: translateX(-180%) skewX(-18deg);
  animation: cta-sweep 5s cubic-bezier(0.45, 0, 0.2, 1) infinite;
  pointer-events: none; z-index: 0;
}
@keyframes cta-sweep {
  0%   { transform: translateX(-180%) skewX(-18deg); }
  26%  { transform: translateX(480%)  skewX(-18deg); }
  100% { transform: translateX(480%)  skewX(-18deg); }
}
.page-home .hero .btn-primary:hover {
  transform: translateY(-3px);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.45) inset,
    0 20px 46px -16px rgba(212, 175, 55, 0.75),
    0 0 0 1px rgba(212, 175, 55, 0.32),
    0 0 40px -8px rgba(212, 175, 55, 0.5);
}
.page-home .hero .btn-primary:active { transform: translateY(-1px) scale(0.985); }
.page-home .btn-arrow {
  width: 1rem; height: 1rem; flex: none;
  transition: transform 380ms var(--ease-spring);
}
@media (hover: hover) and (pointer: fine) {
  .page-home .hero .btn-primary:hover .btn-arrow { transform: translateX(4px); }
}

/* ---- secondary: DISCOVER PCP ---- */
.page-home .hero .btn-secondary {
  background: rgba(7, 20, 38, 0.55);             /* dark translucent navy */
  border-color: rgba(212, 175, 55, 0.42);         /* thin gold border */
  color: var(--pcp-gold-light);
}
.page-home .hero .btn-secondary:hover { background: rgba(7, 20, 38, 0.72); }

/* ---- reservation window ---- */
.page-home .hero-window {
  margin-top: 1.75rem;
  display: flex; flex-direction: column; align-items: center; gap: 0.6rem;
  transition: opacity 320ms ease;
}
/* Reveals with the CTAs, one beat later. */
.pcp-js .page-home .hero .hero-window[data-hero-seq] { transition-delay: 180ms; }
.page-home .hero-window-glass {
  display: inline-flex; align-items: center; gap: 0.85rem;
  padding: 0.6rem 1.2rem;
  border-radius: 999px;
  background: rgba(7, 20, 38, 0.42);
  border: 1px solid rgba(212, 175, 55, 0.22);
  box-shadow: 0 0 0 1px rgba(212, 175, 55, 0.05), 0 10px 30px -18px rgba(212, 175, 55, 0.35);
  -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px);
  transition: border-color 900ms ease, box-shadow 900ms ease;
}
.page-home .hero-window-label {
  font-size: 0.62rem; font-weight: 600; letter-spacing: 0.22em; text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
  transition: color 600ms ease;
}
.page-home .hero-window-diamond { font-size: 0.7rem; color: rgba(212, 175, 55, 0.7); }
.page-home .hero-window-time {
  font-family: "Cormorant Garamond", Georgia, serif;
  font-size: 1.4rem; font-weight: 600; letter-spacing: 0.04em; line-height: 1;
  color: var(--pcp-gold-light);
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 18px rgba(212, 175, 55, 0.35);
  transition: text-shadow 900ms ease;
}
.page-home .hero-window-time[hidden] { display: none; }
.page-home .hero-window-colon { display: inline-block; animation: window-colon 2s ease-in-out infinite; }
@keyframes window-colon { 50% { opacity: 0.35; } }
.page-home .hero-window-note {
  margin: 0; font-size: 0.78rem; color: rgba(255, 255, 255, 0.55);
  transition: color 600ms ease;
}
/* Under 02:00 the glow gathers — still gold, still quiet. */
.page-home .hero-window.is-urgent .hero-window-glass {
  border-color: rgba(212, 175, 55, 0.42);
  box-shadow: 0 0 0 1px rgba(212, 175, 55, 0.12), 0 12px 34px -16px rgba(212, 175, 55, 0.55), 0 0 26px -6px rgba(212, 175, 55, 0.28);
}
.page-home .hero-window.is-urgent .hero-window-time { text-shadow: 0 0 24px rgba(212, 175, 55, 0.55); }
/* The end: a brief dip while the copy changes, then a calmer resting state. */
.page-home .hero-window.is-ending { opacity: 0.35; }
.page-home .hero-window.is-ended .hero-window-glass { border-color: rgba(212, 175, 55, 0.18); box-shadow: none; }
.page-home .hero-window.is-ended .hero-window-label { color: rgba(255, 255, 255, 0.78); }
/* With the time hidden, the separator would trail the label — hide it too. */
.page-home .hero-window.is-ended .hero-window-diamond { display: none; }

/* ---- mobile: room for the window above the absolute scroll cue ---- */
@media (max-width: 767px) {
  .page-home .hero-content { padding-bottom: 8.25rem; }
  .page-home .hero-window { margin-top: 1.5rem; }
  .page-home .hero-window-glass { padding: 0.55rem 0.95rem; gap: 0.65rem; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
  .page-home .hero-window-label { font-size: 0.58rem; }
  .page-home .hero-window-time { font-size: 1.2rem; }
  .page-home .hero-window-note { font-size: 0.74rem; padding: 0 0.75rem; }
}

@media (prefers-reduced-motion: reduce) {
  .page-home .hero .btn-primary::before { animation: none; display: none; }
  .page-home .hero-window-colon { animation: none; }
  .page-home .hero .btn-primary:hover .btn-arrow { transform: none; }
}

/* ==========================================================================
   Members' achievements — horizontal rail
   --------------------------------------------------------------------------
   Everything here is scoped to .ach-carousel / .ach-track. The cards keep the
   shared .moment and .media-frame classes so they inherit the Community frame
   language (texture, sheen, mount, vignette) and the video.js mounting, but no
   shared rule is modified — the PCP Commercial section uses the same .moment
   and .moments-grid classes on this very page and must not move.

   Layout is native overflow scrolling plus scroll-snap, so trackpad, touch
   swipe and keyboard all work with no JavaScript. achievements.js only adds
   the arrows, drag-to-scroll and the disabled states.
   ========================================================================== */
.page-home .ach-carousel {
  --ach-pad: 1.25rem;                 /* matches .wrap's gutter */
  /* Lines the first card up with the heading inside .wrap, while letting the
     rail itself run full-bleed to the viewport edge. */
  --ach-gutter: max(var(--ach-pad), calc((100% - 1400px) / 2 + var(--ach-pad)));
  position: relative;
  margin-top: clamp(2.5rem, 4.5vw, 3.5rem);
}
@media (min-width: 640px) { .page-home .ach-carousel { --ach-pad: 2rem; } }

.page-home .ach-track {
  display: flex;
  gap: clamp(1rem, 1.6vw, 1.5rem);
  margin: 0;
  padding: 0.5rem var(--ach-gutter) 0.75rem;   /* vertical room for the hover lift */
  list-style: none;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--ach-gutter);
  scroll-behavior: smooth;
  /* Keeps a horizontal flick from chaining into the page/back-navigation. */
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.page-home .ach-track::-webkit-scrollbar { display: none; }
.page-home .ach-track:focus-visible {
  outline: 2px solid var(--pcp-gold);
  outline-offset: 4px;
  border-radius: var(--radius);
}

.page-home .ach-item {
  flex: 0 0 auto;
  /* ~2.9 cards at 1440 (the next one peeks), ~1.15 at 390. */
  width: clamp(16rem, 30vw, 27rem);
  scroll-snap-align: start;
}
@media (max-width: 767px) { .page-home .ach-item { width: 78vw; } }

/* Cinematic 16:9. Beats .moment .media-frame's 4/3 and .moments-grid-tall's
   4/5 on specificity rather than by edit order. */
.page-home .ach-track .ach-item .media-frame { aspect-ratio: 16 / 9; }

/* Placeholder play mark: an outline only, no fill, no label. It fades out the
   moment real footage mounts, so it never sits on top of a video. */
.page-home .ach-play {
  position: absolute; z-index: 6; left: 50%; top: 50%;
  width: clamp(2.6rem, 3.6vw, 3.4rem); aspect-ratio: 1;
  transform: translate(-50%, -50%);
  border: 1px solid rgba(212, 175, 55, 0.28);
  border-radius: 50%;
  pointer-events: none;
  transition: opacity 900ms var(--ease-spring), border-color 700ms var(--ease-spring);
}
.page-home .ach-play::after {
  content: ''; position: absolute; left: 56%; top: 50%;
  transform: translate(-50%, -50%);
  border-left: 0.55rem solid rgba(212, 175, 55, 0.40);
  border-top: 0.38rem solid transparent;
  border-bottom: 0.38rem solid transparent;
}
.page-home .media-frame.is-showing .ach-play { opacity: 0; }

/* Hover: the restrained lift the rest of the site uses, plus a slightly
   brighter gold edge. Scale stays at 1.015. */
@media (hover: hover) and (pointer: fine) {
  .page-home .ach-track .ach-item .media-frame {
    transition: box-shadow 700ms var(--ease-spring), transform 700ms var(--ease-spring);
  }
  .page-home .ach-track .ach-item:hover .media-frame {
    transform: translateY(-4px) scale(1.015);
    box-shadow:
      /* Matches the thicker resting edge below, one step brighter so hover
         still reads as a lift rather than the ring suddenly thinning. */
      0 0 0 2px rgba(212, 175, 55, 0.72),
      0 1px 0 rgba(255, 255, 255, 0.07) inset,
      0 0 0 1px rgba(255, 255, 255, 0.03) inset,
      0 44px 100px -48px rgba(0, 0, 0, 0.95),
      0 30px 80px -38px rgba(212, 175, 55, 0.42);
  }
  .page-home .ach-track .ach-item:hover .ach-play { border-color: rgba(212, 175, 55, 0.52); }
}

/* ---- navigation ---- */
.page-home .ach-nav {
  position: absolute; z-index: 4;
  /* Centred on the frame rather than the card, so the caption is not counted. */
  top: calc(50% - 1.6rem);
  display: grid; place-items: center;
  width: 3rem; height: 3rem; padding: 0;
  border-radius: 50%;
  color: var(--pcp-gold-light);
  background: rgba(7, 20, 38, 0.62);
  border: 1px solid rgba(212, 175, 55, 0.34);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  cursor: pointer;
  transition: opacity 500ms ease, border-color 500ms ease,
              box-shadow 500ms ease, transform 500ms var(--ease-spring);
}
.page-home .ach-nav-prev { left: calc(var(--ach-gutter) - 1.5rem); }
.page-home .ach-nav-next { right: calc(var(--ach-gutter) - 1.5rem); }
.page-home .ach-nav:hover {
  border-color: rgba(212, 175, 55, 0.72);
  box-shadow: 0 0 0 1px rgba(212, 175, 55, 0.22), 0 0 30px -6px rgba(212, 175, 55, 0.55);
  transform: scale(1.04);
}
.page-home .ach-nav:active { transform: scale(0.98); }
.page-home .ach-nav:focus-visible { outline: 2px solid var(--pcp-gold); outline-offset: 3px; }
.page-home .ach-nav[disabled] { opacity: 0.22; pointer-events: none; }

/* Touch devices swipe; the arrows would only cover a card. */
@media (max-width: 767px), (hover: none) { .page-home .ach-nav { display: none; } }

/* Drag-to-scroll affordance, desktop pointers only. */
@media (hover: hover) and (pointer: fine) {
  .page-home .ach-track { cursor: grab; }
  .page-home .ach-track.is-dragging { cursor: grabbing; scroll-behavior: auto; scroll-snap-type: none; }
  .page-home .ach-track.is-dragging .ach-item { pointer-events: none; }
}

@media (prefers-reduced-motion: reduce) {
  .page-home .ach-track { scroll-behavior: auto; }
  .page-home .ach-track .ach-item:hover .media-frame { transform: none; }
  .page-home .ach-nav:hover { transform: none; }
}

/* Shown only once window.pcpAchievements carries a real member name. */
.page-home .ach-member {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.7rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(212, 175, 55, 0.78);
}

/* ==========================================================================
   Shared cinematic background zone (.bbz)
   --------------------------------------------------------------------------
   One stationary photograph behind everything from "Members doing the
   business" to "Build the person / leader / future".

   HOW IT STAYS STILL: .bbz-layer is position: sticky, one viewport tall, and
   pulled back out of flow with an equal negative margin. It pins at the top of
   the viewport for the entire height of the zone and unpins at its end, so the
   image looks fixed yet is clipped to this range exactly — visible nowhere
   above it and nowhere below it. background-attachment: fixed is deliberately
   avoided: iOS Safari either ignores it or renders it at the wrong scale.

   Costs no JavaScript, no scroll listener, and no layout height.
   ========================================================================== */
.page-home .bbz {
  position: relative;
  /* Keeps the layer's z-index local, so nothing here can reorder itself
     against the header or the global atmosphere layer. No transform or filter
     anywhere in this block — either would make this a containing block for
     the position: fixed descendants the Phoenix sequence relies on. */
  isolation: isolate;
  /* REQUIRED, and measured: the sticky layer's negative margin zeroes its
     margin box, so the browser's sticky clamping lets the BORDER box travel a
     full viewport past the end of the zone — the photograph was bleeding 900px
     down into the globe section. This trims it to the zone exactly.
     clip, not hidden: hidden would create a scroll container and break both
     this layer and the Phoenix sequence's own sticky stage. */
  overflow: clip;
}

/* The room now lives on the page's single fixed layer (.pcp-cinematic-bg, see
   below) rather than on a per-zone sticky layer, so it is one continuous
   ground for the whole page with no seam where a zone starts or ends. This
   element stays in the markup — the zone still supplies the z-index and the
   surface-clearing rules underneath — but it no longer paints anything.

   A sticky layer could only ever cover its own zone, which is what produced
   the separate background block under the globe. */
.page-home .bbz-layer { display: none; }

.page-home .bbz-image {
  position: absolute;
  inset: 0;
  background-image: url('../media/backgrounds/pcp-business-background.png');
  background-size: cover;          /* fills the viewport, proportions intact */
  background-position: 50% 50%;    /* holds the staircase on the centre line */
  background-repeat: no-repeat;
}

/* Readability veil. Deeper at the two ends so the zone joins the dark sections
   above and below it without a visible seam, and steady through the middle so
   the room stays legible behind the copy. */
.page-home .bbz-veil {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg,
      rgba(3, 10, 20, 0.96) 0%,
      rgba(3, 10, 20, 0.84) 12%,
      rgba(3, 10, 20, 0.82) 88%,
      rgba(3, 10, 20, 0.96) 100%);
}

/* Content rides above the ground. */
.page-home .bbz > section { position: relative; z-index: 1; }

/* The zone supplies one continuous ground, so the per-section navy fills
   inside it are removed and the shared veil provides that darkness instead —
   otherwise Seven Pillars (a solid fill) would hide the photograph entirely
   and the 0.85 navy sections would leave only a sliver of it.
   Scoped to .bbz: the identical classes elsewhere on the site are untouched. */
.page-home .bbz .surface-navy,
.page-home .bbz .surface-navy-solid { background: none; }

@media (prefers-reduced-motion: reduce) {
  /* Sticky is not animation — the image is stationary by definition and there
     is nothing to disable. Left explicit so the intent is on the record. */
  .page-home .bbz-layer { position: sticky; }
}

/* ==========================================================================
   Phoenix stage — looping background video
   --------------------------------------------------------------------------
   Scoped to the 100vh sticky stage where the five captions cross-fade. It does
   not extend to the text block below the sequence, nor to any other section.

   Layer order inside .stage (which is isolation: isolate, so these stay local):
     .stage (background #050505)  the ground, and the fallback
     .stage-video     z-index -3  the loop
     .stage-veil      z-index -2  readability overlay
     .stage-bg        z-index -1  the existing --shift-energy ignition glows
     .stage-inner                 Phoenix canvas + captions, untouched
   ========================================================================== */
.page-home .stage-video {
  position: absolute;
  inset: 0;
  z-index: -3;
  width: 100%;
  height: 100%;
  /* A <video> is a replaced element with an intrinsic size; without this it can
     report a box wider than the stage on narrow viewports. */
  max-width: 100%;
  object-fit: cover;
  object-position: 50% 50%;
  pointer-events: none;
  /* Fades in once the first frame has decoded, so the stage never flashes from
     black to video. Opacity only — nothing here moves or reflows. */
  opacity: 0;
  transition: opacity 1200ms var(--ease-spring);
}
.page-home .stage-video.is-showing { opacity: 1; }

/* Readability veil. Deeper at the top and bottom so the stage still reads as a
   dark cinematic pane and the captions hold their contrast wherever they land. */
.page-home .stage-veil {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  background:
    linear-gradient(180deg,
      rgba(3, 10, 20, 0.90) 0%,
      rgba(3, 10, 20, 0.78) 28%,
      rgba(3, 10, 20, 0.80) 72%,
      rgba(3, 10, 20, 0.93) 100%);
}

@media (prefers-reduced-motion: reduce) {
  /* home.js never mounts the source in this case; the rule is belt and braces
     so a cached element cannot show a moving picture. */
  .page-home .stage-video { display: none; }
}

/* ==========================================================================
   The room, as ONE fixed ground for the whole page
   --------------------------------------------------------------------------
   .pcp-cinematic-bg is the single position:fixed, inset:0, z-index:-1 layer
   that already sits behind all content (created by assets/js/ambience.js and
   documented in transitions.css). Painting the mansion here means:

     * it never scrolls — the layer is fixed, so the room holds still while
       the page moves over it;
     * there is no seam and no separate background block, because there is
       only one layer rather than one per zone;
     * every section that clears its own fill shows the same continuous
       ground, including the globe stage.

   The veil is the same gradient the per-zone layer used (0.82-0.96), so the
   dark treatment behind the copy is unchanged and text stays readable.

   Scoped to .page-home: the other pages have no mansion ground and are
   deliberately left exactly as they are.
   ========================================================================== */
.page-home .pcp-cinematic-bg {
  background-image:
    linear-gradient(180deg,
      rgba(3, 10, 20, 0.96) 0%,
      rgba(3, 10, 20, 0.84) 12%,
      rgba(3, 10, 20, 0.82) 88%,
      rgba(3, 10, 20, 0.96) 100%),
    url('../media/backgrounds/pcp-business-background.png');
  background-size: cover, cover;
  background-position: 50% 50%;
  background-repeat: no-repeat;
}

/* ==========================================================================
   A frame that holds a video shows the video — nothing on top of it
   --------------------------------------------------------------------------
   Every decorative layer on .media-frame exists to push AMBIENT footage back
   so copy can sit over it. A card carrying a real player is not ambient: the
   viewer chose to watch it, and nothing should be laid over the picture. So
   each of these is switched off wherever a video is actually mounted:

     .media-vignette                 z-4  radial + bottom black falloff
     .media-frame.is-showing::after  z-5  navy/gold multiply tint
     .media-frame::before            z-6  the shared media legibility veil
     .media-texture / .media-sheen        the empty-slot stand-in

   :has(.media-mount video) matches on the presence of the video itself rather
   than on a slot name, so this covers card 1, the two added to the top row,
   and any card filled later — while every EMPTY slot keeps its placeholder
   texture and all its veils exactly as they are.

   The frame keeps its gold edge and rounded corners: those come from
   box-shadow and border-radius on .media-frame, which are untouched here.
   ========================================================================== */
.page-home .media-frame:has(.media-mount video) .media-vignette,
/* display, not opacity: .media-sheen and .media-drift run keyframe
   animations, and an animated value beats a normal declaration — so
   `opacity: 0` here would simply be ignored while the sheen kept sweeping. */
.page-home .media-frame:has(.media-mount video) .media-texture,
.page-home .media-frame:has(.media-mount video) .media-sheen,
.page-home .media-frame:has(.media-mount video) .media-particles {
  display: none;
}

/* The two pseudo-element veils. */
.page-home .media-frame:has(.media-mount video)::before,
.page-home .media-frame:has(.media-mount video)::after {
  content: none;
}

/* Plain black underneath, so nothing of the frame's own navy gradient can
   show at any edge. The video covers it completely. */
.page-home .media-frame:has(.media-mount video) {
  background: #000000;
}

.page-home .media-frame:has(.media-mount video) .media-mount video {
  /* Fills the frame edge to edge, all the way to the bottom — no letterbox
     band, no gap, and no fade. object-fit: contain would show the whole frame
     but leave black bands above and below, which is the opposite of what is
     wanted here. */
  object-fit: cover;
  /* The mount fades footage in from 0 via .is-showing, which is added from the
     video's loadeddata handler. A player with controls is not auto-started, so
     that class cannot be relied on; held at 1 so the picture is never dimmed. */
  opacity: 1;
  filter: none;
}

/* ==========================================================================
   A bolder gold edge — PCP in motion + Members' achievements
   --------------------------------------------------------------------------
   Both sections hold video, and the 1px / 0.26 ring the shared .media-frame
   uses was too faint to frame footage. Here it is 2px at 0.55: thicker and
   clearly visible, still a light edge rather than an outline.

   Drawn with box-shadow, not border, which is why nothing moves: a shadow is
   painted outside the box and takes no part in layout, so the frames keep
   their exact 848/464 size and the grid and carousel are untouched. The other
   four shadow layers are repeated verbatim — only the first line changes.

   Scoped to .moment (the six slots) and .ach-track .ach-item (the carousel).
   Community clips, the hero frame and every other .media-frame keep the
   original 1px edge.
   ========================================================================== */
.page-home .moment .media-frame,
.page-home .ach-track .ach-item .media-frame {
  box-shadow:
    0 0 0 2px rgba(212, 175, 55, 0.55),
    0 1px 0 rgba(255, 255, 255, 0.07) inset,
    0 0 0 1px rgba(255, 255, 255, 0.03) inset,
    0 40px 90px -50px rgba(0, 0, 0, 0.95),
    0 24px 70px -46px rgba(212, 175, 55, 0.3);
}

/* ==========================================================================
   Home — let the room through the remaining sections and cards
   --------------------------------------------------------------------------
   The mansion already sits on .pcp-cinematic-bg for this page. What stopped
   it showing everywhere were a handful of surfaces whose base layer was a
   fully opaque gradient. Each is repeated below with that base converted to
   the SAME hue at 0.62 alpha — the decorative layers above it, the borders,
   the radii and the shadows are untouched, so every card keeps its shape and
   its edge and only what shows behind it changes.

   Deliberately NOT touched, so these two keep their current backgrounds:
     .hero / .hero-bg          "Rise beyond who you were."
     [data-ambience="shift"]   "Enter an environment built for transformation."
   Neither selector below can reach inside them.
   ========================================================================== */

/* Ecosystem panels and the icon cards (.pcp-icard also carries .panel). */
.page-home .panel {
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.055) 0%, rgba(255, 255, 255, 0.018) 42%, rgba(7, 20, 38, 0.42) 100%),
    linear-gradient(180deg, rgba(10, 21, 36, 0.62) 0%, rgba(7, 14, 26, 0.62) 100%);
}

/* The photo stand-in. */
.page-home .photo-slot {
  background:
    radial-gradient(70% 60% at 30% 20%, rgba(11, 31, 58, 0.9), transparent 70%),
    radial-gradient(60% 50% at 80% 100%, rgba(212, 175, 55, 0.18), transparent 70%),
    linear-gradient(160deg, rgba(7, 20, 38, 0.62), rgba(5, 5, 5, 0.62));
}

/* Every media frame: the six PCP in motion slots, the achievements carousel
   and the community frames. Card 1 of PCP in motion keeps its own solid black
   base from the rule further up (higher specificity) — the video fills that
   frame edge to edge, so nothing would show behind it anyway. */
.page-home .media-frame {
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(16, 34, 58, 0.55), transparent 62%),
    linear-gradient(168deg, rgba(13, 23, 40, 0.62) 0%, rgba(8, 13, 24, 0.62) 48%, rgba(5, 7, 12, 0.62) 100%);
}

/* ==========================================================================
   GOLD DUST — contained to the hero → Members' Achievements range
   --------------------------------------------------------------------------
   This replaces the site-wide ambient dust, which was a position:fixed,
   full-viewport canvas: it could only ever be faded, never confined, so it
   kept showing up outside the range.

   This layer is absolutely positioned over the range instead, and clipped to
   it. home.js measures the hero and the achievements section and writes --top
   and --h, so the box tracks the real sections through any reflow.

   overflow: clip, not hidden: hidden would make this a scroll container.
   z-index -1 keeps it behind the sections' own translucent surfaces, which is
   where ambient dust belongs; the sections are semi-transparent, so it reads
   through them exactly as the old field did.
   ========================================================================== */
.page-home #main { position: relative; }

.page-home .range-dust {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--range-dust-top, 0px);
  height: var(--range-dust-h, 0px);
  z-index: -1;
  overflow: clip;
  pointer-events: none;
}
/* The canvas the field mounts fills the box and is clipped by it. */
.page-home .range-dust .pcp-canvas-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* ==========================================================================
   Pillar cards that carry their own photograph
   --------------------------------------------------------------------------
   All seven pillars carry a picture inside the box. Each names its file in
   --pillar-photo; the veil, the sizing and the gold edge are shared, so a
   card's photograph is one line rather than another copy of this block.

   Nothing else picks this up. .panel-featured appears exactly once on the
   site, and each data-pillar value names a single card — Opportunity, the one
   without a picture, keeps the translucent panel it already had, and the page's own
   background is untouched.

   The image is clipped by the rule further down that gives all seven cards
   background-clip: padding-box and overflow: hidden, so it stops at the
   inside edge of the border and cannot cross the rounded corner.

   Declared at the end of the file on purpose. The .panel rule further up
   matches at the same specificity, so a rule placed next to the original
   .panel-featured declaration would have lost on order and done nothing.

   Layer order is top-first: the readability veil, then the photograph. The
   veil is deepest at the top and bottom, where the icon, the heading and the
   paragraph sit, and lighter across the middle so the picture still reads. A
   background is painted inside the border box, so the 20px corners clip the
   image on their own — border and radius come from .panel untouched.
   ========================================================================== */
.page-home .panel-featured {
  --pillar-photo: url('../media/backgrounds/personal-development-bg.jpg');
}
.page-home [data-pillar="leadership"] {
  --pillar-photo: url('../media/backgrounds/leadership-bg.jpg');
}
.page-home [data-pillar="business"] {
  --pillar-photo: url('../media/backgrounds/business-bg.jpg');
}
.page-home [data-pillar="community"] {
  --pillar-photo: url('../media/backgrounds/community-bg.jpg');
}
.page-home [data-pillar="mentorship"] {
  --pillar-photo: url('../media/backgrounds/mentorship-bg.jpg');
}
.page-home [data-pillar="education"] {
  --pillar-photo: url('../media/backgrounds/education-bg.jpg');
}
.page-home [data-pillar="opportunity"] {
  --pillar-photo: url('../media/backgrounds/opportunity-bg.jpg');
}

.page-home .panel-featured,
.page-home [data-pillar="leadership"],
.page-home [data-pillar="business"],
.page-home [data-pillar="community"],
.page-home [data-pillar="mentorship"],
.page-home [data-pillar="education"],
.page-home [data-pillar="opportunity"] {
  background-image:
    linear-gradient(180deg,
      rgba(4, 9, 18, 0.90) 0%,
      rgba(4, 9, 18, 0.72) 38%,
      rgba(4, 9, 18, 0.78) 68%,
      rgba(4, 9, 18, 0.92) 100%),
    var(--pillar-photo);
  background-size: auto, cover;
  background-position: 0% 0%, 50% 50%;
  background-repeat: no-repeat, no-repeat;
  /* The gold edge the featured card has always had; the same weight is used
     here so the two photographed cards read as a pair. */
  border-color: rgba(212, 175, 55, 0.4);
}

/* ==========================================================================
   The seven pillar cards — one gold edge, and the picture kept inside it
   --------------------------------------------------------------------------
   [data-pillar] names exactly those seven cards. The one other .panel on this
   page, the list in the ecosystem section, carries no data-pillar and is left
   alone.

   BORDER
   The seven were not equal: the two photographed cards sat at 0.4 and the
   other five at 0.16, so the row read as two different treatments. All seven
   are 2px at 0.55 now — thicker and clearly visible, the same on every card.

   Doubling the border costs no layout: box-sizing is border-box, so the outer
   size of each card is unchanged and only the content box moves in by 1px.

   CLIPPING
   background-clip was border-box, which paints a background UNDER the border.
   With a semi-transparent gold edge that meant the photograph showed through
   the border itself — the image reaching past where the card should end.
   padding-box stops it at the inside edge, so the border reads as a border.

   overflow: hidden is the belt to that braces: the rounded corner clips any
   layer inside the card, so nothing can cross it. A card's own box-shadow is
   painted outside the border box and is not clipped by this, so the lift on
   hover is unaffected.
   ========================================================================== */
.page-home .panel[data-pillar] {
  border: 2px solid rgba(212, 175, 55, 0.55);
  background-clip: padding-box;
  overflow: hidden;
}

/* Hover still reads as a brightening rather than the edge thinning back. */
.page-home .panel[data-pillar].is-hovered {
  border-color: rgba(212, 175, 55, 0.85);
}

/* ==========================================================================
   One size for every video card on this page
   --------------------------------------------------------------------------
   The business rail and the achievements feature are the same size, and they
   stay that way because they read the SAME value rather than two clamps that
   happen to agree today. Change this line and both sections move together.

   It is a HEIGHT. Both sections size their frames by height so that cards
   whose footage is a different shape still line up top and bottom — see the
   two blocks below.

   On a phone the value becomes the content column's own 16:9 height, which is
   exactly what the achievements frame works out to there, so the two match at
   every width and not only on a laptop.
   ========================================================================== */
.page-home {
  --video-card-h: clamp(11rem, 29vw, 26rem);
}
@media (max-width: 767px) {
  /* --ach-gutter is 1.25rem below 640px, so the column is 100vw - 2.5rem. */
  .page-home { --video-card-h: calc((100vw - 2.5rem) * 9 / 16); }
}

/* ==========================================================================
   Members doing the business — a filmstrip of whole videos
   --------------------------------------------------------------------------
   The section reuses .ach-carousel / .ach-track / .ach-item wholesale, so the
   scrolling, snapping, drag, arrows and gutter are literally the achievements
   rail's — one implementation, not a second one that can drift. Everything
   below is the two things that differ.

   SIZED BY HEIGHT, NOT WIDTH. The three files are not one shape:
   business-meeting.mp4 is 848x464 (1.828) and the other two are 1920x1080
   (1.778). Any single frame ratio crops one of them, so each frame takes its
   own video's ratio from --media-ar, which assets/js/achievements.js reads
   off the file itself. Nothing is cropped and nothing is stretched.

   Fixing the HEIGHT rather than the width is what keeps that from looking
   ragged: every card is exactly as tall as its neighbours, so the gold edges
   line up top and bottom, and it is the WIDTH that varies by the 2.7% the
   ratios differ by — which is what a filmstrip of real footage looks like
   anyway. Had the width been fixed instead, the bottoms would step by 9px.

   The height itself is --video-card-h, the page's one video size, so these
   cards are exactly the achievements feature's size. Roughly 1.9 cards per
   view on a laptop, the next one peeking.

   --media-ar defaults to 16/9 so the three empty slots, which have no video
   to measure, still read as the same shape as the rest of the rail.
   ========================================================================== */
.page-home .biz-rail .ach-item { width: auto; }

.page-home .biz-rail .ach-item figure,
.page-home .biz-rail .ach-item .media-frame {
  height: var(--video-card-h);
}
/* Beats .ach-track .ach-item .media-frame's flat 16/9 at the same (0,4,0)
   specificity by being declared later — which is why this block is last. */
.page-home .biz-rail .ach-track .ach-item .media-frame,
.page-home .biz-rail .ach-item .media-frame {
  aspect-ratio: var(--media-ar, 16 / 9);
  width: auto;
}

/* No mobile override: --video-card-h already becomes the column's own 16:9
   height there, which is the achievements frame's height exactly. */

/* ==========================================================================
   Members' achievements — one feature video
   --------------------------------------------------------------------------
   The section is no longer a filmstrip of six, so .ach-feature turns the rail
   into a single frame. It still rides on .ach-carousel / .ach-track /
   .ach-item, which is what keeps the full-bleed gutter, the gold edge, the
   frame language and the play gate identical to the rest of the page.

   SIZED BY HEIGHT from --video-card-h, the same token .biz-rail reads, so the
   feature and the business cards are one size and cannot drift apart as the
   viewport changes.

   SHAPE is the rail's 16 / 9, which is the film's own 1920x1080, so nothing
   is cropped and nothing is stretched and no override is needed here.

   On a phone the frame is simply the content column, which already makes it
   slightly larger than the business cards at 86vw, and a fixed height would
   only fight the narrower screen.

   With a single card there is nothing to scroll: the snap and overflow on
   .ach-track are inert, and the markup carries no arrows.
   ========================================================================== */
/* Centred on the screen, the way the business rail centres whichever card is
   its subject. That rail gets there with padding, because a scroll container
   can only bring its first and last card to the middle if there is room
   beside them; this one has a single card and nothing to scroll, so the flex
   line is simply centred. Same result, and exact — justify-content measures
   the card that is actually there, where the padding formula works from the
   nominal 16:9 width and leaves a differently shaped film a few pixels off. */
.page-home .ach-feature .ach-track { justify-content: center; }

.page-home .ach-feature .ach-item {
  width: auto;
  scroll-snap-align: none;
}
.page-home .ach-feature .ach-item figure,
.page-home .ach-feature .ach-item .media-frame {
  height: var(--video-card-h);
}
.page-home .ach-feature .ach-item .media-frame { width: auto; }

@media (max-width: 767px) {
  .page-home .ach-feature .ach-item { width: 100%; }
  .page-home .ach-feature .ach-item figure,
  .page-home .ach-feature .ach-item .media-frame { height: auto; }
}

/* ==========================================================================
   The business rail reads as a centre stage
   --------------------------------------------------------------------------
   One card is the one being watched and the others are visibly waiting their
   turn, so there is never a question of which video is the subject.

   HOW THE SIZE CHANGES. The scale is on the <figure> INSIDE the card, never
   on the card itself. Scroll snapping measures the card's box, so scaling the
   card would move the very position the browser is snapping to, and the rail
   would chase itself. Scaling a child leaves the layout box alone: the
   spacing, the snap points and the scroll width never move, and only the
   picture grows and shrinks.

   A uniform scale cannot crop or stretch anything — the frame keeps its
   aspect ratio exactly, and the gold edge and the 16px corners scale with it.

   Only transform and opacity change, both on a spring, so this stays on the
   compositor.

   CENTRING THE END CARDS. scroll-snap-align: center lines a card's middle up
   with the middle of the rail, which the first and last card can only reach
   if there is room beside them — hence the padding. It never falls below
   --ach-gutter, so on a narrow screen the rail still starts where the heading
   does.
   ========================================================================== */
.page-home .biz-rail .ach-track {
  /* The nominal 16:9 width the card height implies, halved, is the room the
     first and last card need beside them to reach the middle.

     Derived HERE rather than from a --video-card-w token: the var()s inside a
     custom property are resolved on the element that declares it, so a token
     declared on .page-home would keep .page-home's --video-card-h and quietly
     ignore the phone override on .biz-rail below. Reading --video-card-h at
     the point of use picks up whatever value this element has inherited. */
  padding-inline: max(var(--ach-gutter), calc((100% - var(--video-card-h) * 16 / 9) / 2));
  scroll-padding-inline: 0;
}
.page-home .biz-rail .ach-item { scroll-snap-align: center; }

.page-home .biz-rail .ach-item figure {
  transform: scale(0.84);
  opacity: 0.62;
  transition: transform 620ms var(--ease-spring), opacity 620ms var(--ease-spring);
  will-change: transform;
}
.page-home .biz-rail .ach-item.is-center figure {
  transform: scale(1);
  opacity: 1;
}

/* A card off to the side is a target, not a player: one press brings it to
   the middle (assets/js/achievements.js), so it should read as pressable. */
@media (hover: hover) and (pointer: fine) {
  .page-home .biz-rail .ach-item:not(.is-center) { cursor: pointer; }
  .page-home .biz-rail .ach-item:not(.is-center):hover figure { opacity: 0.8; }
}

@media (prefers-reduced-motion: reduce) {
  .page-home .biz-rail .ach-item figure { transition: none; }
}

/* --- The centre stage on a phone ------------------------------------------
   The arrows are hidden below 768px, so the only thing telling a visitor the
   rail slides is seeing part of the next card. At the full content column a
   centred card leaves 20px on each side, which the gap swallows whole, and
   the neighbours sit completely off screen: no arrows, no peek, no clue.

   So on a phone the centre card gives up a little width to buy that peek, the
   gap tightens, and the side cards are scaled less hard — at this size the
   difference only has to be legible, not dramatic. This is the one place the
   business rail is not the same size as the achievements frame; there simply
   is not room for both.
   ------------------------------------------------------------------------ */
@media (max-width: 767px) {
  .page-home .biz-rail { --video-card-h: calc(70vw * 9 / 16); }
  .page-home .biz-rail .ach-track { gap: 0.75rem; }
  .page-home .biz-rail .ach-item figure { transform: scale(0.9); }
  .page-home .biz-rail .ach-item.is-center figure { transform: scale(1); }
}

/* ==========================================================================
   The community section — one clearly visible gold edge on all four boxes
   --------------------------------------------------------------------------
   [data-community] is on the "Transformation doesn't happen in isolation."
   section and nowhere else, so this reaches that section's hero frame and its
   three clips and nothing beyond it.

   The edge was the shared .page-home .media-frame ring: 1px at 0.26 alpha,
   which on a dark photograph barely registered. It is now 2px at 0.55 — the
   same weight and the same gold the video frames and the seven pillar cards
   already carry, so this reads as the site's edge rather than a new one.

   NOTHING MOVES. The edge is drawn with box-shadow, not border: a shadow is
   painted outside the box and takes no part in layout, so the frames keep
   their exact sizes (1336x573 for the hero, 429x537 for each clip), their
   16px corners, their aspect ratios and every gap between them. Only the
   first shadow layer changes; the inset highlights and the two drop shadows
   below it are repeated verbatim from the rule this overrides.

   Same hue throughout: rgb(212, 175, 55), untouched.
   ========================================================================== */
.page-home [data-community] .media-frame {
  box-shadow:
    0 0 0 2px rgba(212, 175, 55, 0.55),
    0 1px 0 rgba(255, 255, 255, 0.07) inset,
    0 0 0 1px rgba(255, 255, 255, 0.03) inset,
    0 40px 90px -50px rgba(0, 0, 0, 0.95),
    0 24px 70px -46px rgba(212, 175, 55, 0.3);
}

/* ==========================================================================
   "Before. Journey. After." — the photo box gets the community section's edge
   --------------------------------------------------------------------------
   Matched to .page-home [data-community] .media-frame above: the same 2px and
   the same rgba(212, 175, 55, 0.55), so the two sections read as one family.
   It was 1px at 0.22 alpha, which on this dark gradient barely showed.

   Scoped to this section by its heading id, and .photo-slot appears exactly
   once in the whole site anyway, so nothing else can pick this up.

   NOTHING MOVES. Tailwind's preflight sets box-sizing: border-box globally,
   so doubling the border keeps the element's outer size at 1336x509 and only
   moves its content box in by 1px. The 20px corners, the margins around it
   and the gradients inside it are untouched — only border-width and
   border-color are set here.

   Only ONE box in this section has an edge at all. The three Before / Journey
   / After entries are timeline text with a dot, carrying no border and no
   radius, and giving them one would be adding boxes rather than thickening
   them, so they are left as they are.
   ========================================================================== */
.page-home [aria-labelledby="story-title"] .photo-slot {
  border-width: 2px;
  border-color: rgba(212, 175, 55, 0.55);
}

/* ==========================================================================
   Hero statistics row
   --------------------------------------------------------------------------
   Sits directly under the reservation window. Four equal columns on a laptop,
   a 2x2 grid on a phone — equal-width tracks either way, so no figure gets
   more room than another whatever the numbers happen to be.

   The dark-and-gold language is the page's own: the figures use the display
   serif and .text-gold-gradient's gold, and the labels use the same uppercase
   micro-type and tracking as .eyebrow elsewhere on this page.

   The hairline separators are drawn with a border on the cell, not a gap, so
   they cannot change the track widths. They are dropped on the phone grid,
   where a 2x2 with rules reads as a table rather than a row of figures.

   tabular-nums keeps the digits the same width while counting, so a figure
   does not jitter as it rises from 0 to 5,000.
   ========================================================================== */
.page-home .hero-stats {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  align-items: start;
  gap: 0;
  margin: clamp(2.25rem, 4vw, 3.25rem) auto 0;
  padding: 0;
  list-style: none;
  max-width: 58rem;
  width: 100%;
}
.page-home .hero-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5rem;
  padding: 0 clamp(0.5rem, 1.4vw, 1.25rem);
  border-left: 1px solid rgba(212, 175, 55, 0.18);
}
.page-home .hero-stat:first-child { border-left: 0; }

.page-home .hero-stat-value {
  font-family: "Cormorant Garamond", Georgia, serif;
  /* Eased down about 13% on request — 2.9rem to 2.5rem at the top of the
     clamp, 1.9 to 1.65 at the bottom. Size only: the gold gradient, the
     tabular figures, the tracking, the weight and the row's layout and
     gaps are all as they were. */
  font-size: clamp(1.65rem, 2.95vw, 2.5rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  background: linear-gradient(180deg, #f1d27a 0%, var(--pcp-gold) 58%, #a8842c 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
.page-home .hero-stat-label {
  /* Down in step with the figure above it, so the pairing keeps its
     proportions rather than the caption suddenly crowding a smaller number. */
  font-size: 0.54rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.58);
  line-height: 1.3;
}

@media (max-width: 639px) {
  .page-home .hero-stats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: clamp(1.25rem, 5vw, 1.75rem) 0;
    max-width: 24rem;
  }
  /* A 2x2 with rules reads as a table; the grid alone carries the grouping. */
  .page-home .hero-stat { border-left: 0; }
}

/* ==========================================================================
   Hero — one screen, whatever the screen is
   --------------------------------------------------------------------------
   The whole opening (logo, eyebrow, headline, lede, buttons, reservation
   window, four figures) has to land inside the first viewport with no scroll.

   WHY IT DID NOT. Every size in the hero was driven by viewport WIDTH: the
   logo at 12vw, the headline at 6.2vw, the content padding at 8vh/15vh. On a
   laptop that is wide and short — 1366x768 is the common case — a wide screen
   asked for large type while a short screen had no room for it, and the stack
   ran 1021px tall inside a 768px window: 210px below the fold.

   THE FIX is to let HEIGHT have a vote. Every value below is
   min(<width-based>, <height-based>), so the width still sets the scale on a
   tall screen and the height takes over the moment the screen is short. One
   set of numbers covers every viewport instead of a breakpoint per laptop.

   svh, not vh: on mobile browsers vh is the tallest the viewport ever gets
   (address bar hidden), which is exactly the measurement that overflows while
   the bar is showing. svh is the smallest, so the hero fits from first paint.

   Nothing about the statistics changes here: same four values, same markup,
   same count-up. Only the type scale and the gaps move.
   ========================================================================== */
.page-home .hero-content {
  /* was clamp(3rem, 8vh, 6rem) / clamp(8rem, 15vh, 10rem) — 177px at 768px.
     The bottom still clears the absolute .scroll-cue, which occupies the
     lowest ~6.5rem of the hero. */
  padding-top: clamp(0.75rem, 2.5svh, 2.25rem);
  padding-bottom: clamp(6.5rem, 12svh, 8rem);
}

.page-home .hero-logo {
  /* was clamp(6.5rem, 12vw, 10rem), then compacted to
     clamp(3.5rem, min(8vw, 10.5svh), 7rem); every term is now ~22% larger.
     The min(width, height) shape is kept, so the mark still gives way on a
     short screen instead of pushing the stack below the fold. */
  height: clamp(4.25rem, min(9.75vw, 12.8svh), 8.5rem);
}

.page-home .hero .eyebrow { margin-top: clamp(0.75rem, 2svh, 1.75rem); }

.page-home .hero h1 {
  /* was clamp(2.5rem, 6.2vw, 5.5rem) */
  font-size: clamp(2rem, min(5.4vw, 7svh), 4.5rem);
  margin-top: clamp(0.5rem, 1.5svh, 1.25rem);
}

.page-home .hero .lede {
  font-size: clamp(1rem, min(1.25vw, 2.1svh), 1.1875rem);
  margin-top: clamp(0.75rem, 1.9svh, 1.75rem);
}

.page-home .hero .hero-actions { margin-top: clamp(1rem, 2.7svh, 2.5rem); }
.page-home .hero .hero-window  { margin-top: clamp(0.75rem, 1.9svh, 1.75rem); }
.page-home .hero .hero-stats   { margin-top: clamp(1rem, 2.6svh, 2.5rem); }

/* --- Narrow screens: the same reclaim, keyed to width ---------------------
   The block above is keyed to max-height, which a tall phone (390x844) never
   matches even though it has the same problem: at full size the scroll cue
   reserves ~101px of bottom padding, the hero grows past the viewport, and
   the cue lands on top of the figures instead of below them.

   So a narrow screen gets the small cue and the matching padding too. This is
   furniture only — no type, no figure and no label changes size here.
   ------------------------------------------------------------------------ */
@media (max-width: 639px) {
  .page-home .hero-content { padding-bottom: clamp(3.25rem, 7svh, 4.5rem); }
  .page-home .scroll-cue { bottom: 0.7rem; gap: 0.35rem; }
  .page-home .scroll-cue i { height: 1.6rem; }

  /* A narrow column wraps the headline and the lede onto more lines than a
     wide one, so a phone needs the tighter scale whether or not it is also
     short. The lede is the only type that changes: it wrapped to five lines,
     and 15px at a 1.5 line-height gives a line back and still reads easily. */
  /* On a narrow screen it is the clamp MINIMUM that is active, not the
     min() — a 390px phone asks for 9.75vw = 38px — so the floor is what
     actually sets the size here, and it carries the same ~22%. */
  .page-home .hero-logo { height: clamp(3.05rem, min(9.75vw, 11svh), 6.1rem); }
  .page-home .hero .lede { font-size: 0.9375rem; line-height: 1.5; }

  .page-home .hero .eyebrow      { margin-top: clamp(0.5rem, 1.5svh, 1rem); }
  .page-home .hero h1            { margin-top: clamp(0.4rem, 1.2svh, 0.9rem); }
  .page-home .hero .lede         { margin-top: clamp(0.5rem, 1.4svh, 1rem); }
  .page-home .hero .hero-actions { margin-top: clamp(0.75rem, 2svh, 1.5rem); }
  .page-home .hero .hero-window  { margin-top: clamp(0.5rem, 1.4svh, 1rem); }
  .page-home .hero .hero-stats   { margin-top: clamp(0.75rem, 2svh, 1.5rem); }
  .page-home .hero-stats { row-gap: 0.45rem; }
  .page-home .hero-window { gap: 0.35rem; }

}

/* --- Short screens: reclaim the decoration, never the content -------------
   A 375x667 phone and a 1280x600 laptop share one problem: the hero's fixed
   furniture takes a large share of a small window. The bottom padding alone
   was 104px, reserved for the scroll cue.

   So on a short viewport the CUE gets smaller and sits lower, and the padding
   that reserves it shrinks to match; the buttons give up some of their
   generous padding while staying above a 44px tap target. The type, the
   figures and the labels are not touched — nothing readable gets smaller and
   nothing is hidden.
   ------------------------------------------------------------------------ */
@media (max-height: 720px) {
  /* On a short screen the cue is the one thing here that is not content: it
     is aria-hidden decoration whose only job is to say "there is more below",
     which a visitor discovers anyway. Shrinking it was not enough — even at
     its smallest it still landed on the figures — so it stands down and the
     padding that reserved it goes back to the content it was crowding.
     Everything the visitor actually reads stays on screen. */
  .page-home .scroll-cue { display: none; }
  .page-home .hero-content {
    padding-top: clamp(0.35rem, 1.5svh, 1rem);
    padding-bottom: clamp(1rem, 2.5svh, 1.75rem);
  }
  .page-home .hero .btn-lg { padding-top: 0.9rem; padding-bottom: 0.9rem; }
  .page-home .hero .hero-actions { gap: 0.6rem; }
  .page-home .hero-stats { row-gap: 0.45rem; }
  .page-home .hero-window { gap: 0.35rem; }
}

/* One tier tighter again, for the small phones that are still short after the
   block above: 360x640 and the like. Only the furniture moves — the buttons
   sit side by side instead of stacked, which is where the last 70px live, and
   they keep a 44px tap target. */
@media (max-height: 700px) and (max-width: 639px) {
  .page-home .hero .hero-actions { flex-direction: row; gap: 0.5rem; }
  .page-home .hero .hero-actions > .magnetic { width: auto; flex: 1 1 0; min-width: 0; }
  /* .btn ships white-space: nowrap and 0.14em of tracking. Side by side in a
     ~156px column that tracking alone costs "Reserve My Slot" about 27px and
     the label was being clipped, so the tracking comes down with the size.
     Nothing is hidden: the check is scrollWidth <= clientWidth. */
  .page-home .hero .hero-actions .btn {
    width: 100%;
    padding-left: 0.5rem;
    padding-right: 0.5rem;
    font-size: 0.72rem;
    letter-spacing: 0.06em;
  }
  .page-home .hero .hero-actions .btn-arrow { display: none; }

}

/* --- "Before. Journey. After." — the photograph shows as itself -----------
   The slot was built to hold a stand-in, so it carried two things meant to
   dress up an empty box: a dark gradient painted over the whole slot
   (.photo-slot::after) and a colour treatment on the image
   (saturate .75 / contrast 1.1 / brightness .85 / sepia .12). With a real
   photograph in it, both are just a veil over the picture, so both are off.

   The watermark and the "Member photography" label were removed from the
   markup rather than hidden here, because they were placeholder content
   rather than styling.

   The frame is untouched: the 2px gold edge set above stays, as do the 20px
   corners and overflow: hidden, which is what clips the photograph to the
   box. Scoped by the section's heading id, and .photo-slot appears once in
   the whole site, so nothing else is affected.
   ------------------------------------------------------------------------ */
.page-home [aria-labelledby="story-title"] .photo-slot::after { content: none; }
.page-home [aria-labelledby="story-title"] .photo-slot img { filter: none; }

/* ==========================================================================
   The community section's one landscape frame
   --------------------------------------------------------------------------
   [data-community-wide] is on this one frame and nowhere else.

   NO ASPECT RATIO IS SET HERE, deliberately. The collage is an <img> at
   width:100%; height:auto, so the picture's own 2672x1030 decides how tall
   the frame is at every width. Fixing a ratio here would be the thing that
   crops it: the frame previously forced 21/8 and, on a phone, 16/9.

   No background image and no background colour either — both were there to
   carry the picture and to give the slot a surface while its file was
   missing. The <img> is the picture now, and it fills the frame.

   The gold ring and the 16px corners are NOT declared here: the element is a
   .media-frame inside [data-community], so it inherits the 2px
   rgba(212,175,55,0.55) edge already set for this section. overflow: hidden
   comes from .media-frame too, and it is what holds the picture inside the
   rounded corners.

   The margin is the one the three-clip grid used, so the spacing around the
   frame is unchanged.
   ========================================================================== */
.page-home .community-wide {
  margin: clamp(1rem, 1.7vw, 1.5rem) 0 0;
  padding: 0;
}
/* .media-frame::before is a legibility veil — a linear-gradient to the top
   from rgba(0,0,0,0.62), absolutely positioned at inset 0 and z-index 6, so
   it covers the whole frame. It exists so captions laid over a video stay
   readable. There is no text over this picture, so the veil only darkens the
   collage; it is switched off here. ::after is already none for this frame. */
.page-home .community-wide .media-frame::before { content: none; }

.page-home .community-wide .media-frame img {
  display: block;
  width: 100%;
  height: auto;
  /* The site-wide .img-frame treatment tints and darkens photographs; this
     one is shown as it is. */
  filter: none;
}

/* ==========================================================================
   The first business card's poster carries its own play button
   --------------------------------------------------------------------------
   6-dimension-poster.png is a finished thumbnail: the title card, the gold
   edge and a play mark are all painted into the image itself. The site's own
   .pcp-play would therefore be a SECOND play icon sitting on top of the one
   already in the picture, so it is hidden on this card only.

   Nothing replaces it as the affordance. assets/js/site.js already listens
   for a click on the <video> and starts playback if it is paused, and the
   poster is painted by that same <video> element — so the picture is the
   button. Pressing it swaps the poster for the footage.

   ONLY UNTIL THE FIRST PLAY. :not(.has-played) is the whole point of the
   rule: .has-played is set once, on the first play, and never removed, so
   the suppression lasts exactly as long as the poster does. From then on the
   card behaves like every other one — the mark comes back on every pause and
   goes away again on play, which is the gate's own behaviour and needs no
   help from here. Hiding it outright, as this rule first did, left a paused
   video with no visible control at all.

   [data-poster-has-play] is on that one card and nowhere else. No gradient
   and no overlay is added here: the frame's ::before veil is already off for
   any frame holding a video, and the texture, sheen and vignette layers are
   off with it.
   ========================================================================== */
.page-home [data-poster-has-play] .media-frame:not(.has-played) .pcp-play {
  display: none;
}

/* The picture is the button, so it should read as one. */
@media (hover: hover) and (pointer: fine) {
  .page-home [data-poster-has-play] .media-frame video { cursor: pointer; }
}

/* ==========================================================================
   The hero after the logo, the label and the scroll cue came out
   --------------------------------------------------------------------------
   Three things left the hero and each one was holding space:

     .hero-logo        ~8.5rem tall, plus its own gap to the label
     .hero .eyebrow    the line of gold caps, and the gap above it
     .scroll-cue       absolutely positioned in the lowest ~6.5rem, which is
                       the only reason .hero-content carried that much bottom
                       padding

   Left alone, the block would sit high with a band of empty hero under it.
   The headline now opens the hero, so it takes no top margin of its own, and
   the padding is rebalanced around what is actually left.

   Only the hero is touched. The navbar, the page background, every other
   section and all the copy are exactly as they were. */
.page-home .hero h1 { margin-top: 0; }

.page-home .hero-content {
  /* Was clamp(0.75rem, 2.5svh, 2.25rem) over clamp(6.5rem, 12svh, 8rem). The
     bottom no longer has a cue to clear, so the two ends are brought close to
     even and the shorter stack sits centred in the hero rather than high in
     it. */
  padding-top: clamp(2.5rem, 7svh, 5.5rem);
  padding-bottom: clamp(2.5rem, 7svh, 5.5rem);
}

@media (max-width: 639px) {
  .page-home .hero-content {
    padding-top: clamp(1.5rem, 4svh, 3rem);
    padding-bottom: clamp(1.5rem, 4svh, 3rem);
  }
}

/* ==========================================================================
   The hero headline — larger, gold, and the thing you see first
   --------------------------------------------------------------------------
   Design only. The words are untouched: "Rise beyond who you were." is the
   same string, in the same <h1>, with the same reveal. Nothing is added and
   nothing is taken away — only size, weight, colour, tracking and the air
   around it change.

   THE GOLD IS APPLIED PER WORD, not to the <h1>. assets/js/home.js splits the
   headline into <span class="wm"><span class="w">word</span></span>, and .w
   is transformed and sits inside an overflow:hidden mask. background-clip:
   text on the <h1> has to clip a single background box to glyphs that are
   each painted in their own transformed layer, which is exactly the case that
   breaks. Filling each .w instead gives every word its own ramp and cannot
   come apart. The <h1> keeps the same fill for the state before the split
   runs, and for JS-off.
   ========================================================================== */
.page-home .hero h1,
.page-home .hero h1 .w {
  /* The DARKEST stop is what sets this headline's contrast, because that is
     the end of the ramp and it lands over the brightest part of the film —
     the gold phoenix sits directly under the words. Two ramps were measured
     and rejected before this one: ending at #AE861F gave 2.71:1 and ending
     at #C79A28 gave 2.97:1 at 1920x1080, both under the 3.0 that large text
     needs. This ends at the brand gold #D4AF37 and measures 3.67:1 at the
     worst viewport, so the whole ramp sits in the lighter half. The light
     end is free to go as bright as it likes; only the bottom is at risk. */
  background: linear-gradient(170deg, #FBF0CC 0%, #F3DC92 26%, #E6C85B 60%, #D4AF37 100%);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ...and the moment the words exist, the <h1> gives its own copy up.
   The note above has it right that clipping one background box to glyphs that
   each sit in their own transformed layer is the case that breaks, but the
   <h1> was still left in the selector above, so it kept doing exactly that
   alongside the per-word fill: Chromium clips the <h1>'s gradient to the glyph
   outlines in the <h1>'s own coordinate space, which ignores both the
   translateY on .w and the overflow:hidden on .wm. Every word therefore
   painted twice during the reveal -- once correctly inside its mask, once as
   an unmasked ghost -- and on a narrow screen the ghost of one line landed on
   top of another, which is the jumbled headline this fixes. Measured over 72
   painted frames of a cold phone load: 21 ghosted before, 0 after.

   assets/js/home.js sets .words-split as soon as it has wrapped the words, so
   the fill above still covers the pre-split paint and the JS-off case, which
   is what it was there for. */
.page-home .hero h1.words-split {
  background: none;
  -webkit-background-clip: border-box;
  background-clip: border-box;
}

.page-home .hero h1 {
  /* Up from clamp(2rem, min(5.4vw, 7svh), 4.5rem). The min(vw, svh) shape is
     kept deliberately: it is what stops a big headline from pushing the
     buttons and the statistics off a short laptop screen. Every term grew by
     the same proportion, so the type still gives way on a short viewport. */
  font-size: clamp(2.45rem, min(6.6vw, 8.6svh), 5.6rem);

  /* 800, against the site-wide 700. The variable face loaded in the head runs
     to 800, so this is a real weight, not a synthesised one. !important is
     needed to beat the `*` rule in typography.css, which is itself important. */
  font-weight: 800 !important;

  /* Large type wants tighter tracking and tighter leading than body copy;
     at this size the default 0.01em reads loose and the lines read apart. */
  letter-spacing: -0.022em;
  line-height: 0.92;

  /* Drop-shadow, not text-shadow: the glyphs are transparent and filled by a
     background, so a text-shadow would be painted straight through them. This
     lifts the headline off the film behind it without dimming the picture. */
  filter: drop-shadow(0 2px 14px rgba(0, 0, 0, 0.78))
          drop-shadow(0 1px 3px rgba(0, 0, 0, 0.6))
          drop-shadow(0 0 46px rgba(212, 175, 55, 0.20));
}

/* More room above and below it than the rest of the stack gets, so the
   headline reads as the subject rather than as the first of six things. */
.page-home .hero .lede { margin-top: clamp(1rem, 2.4svh, 2rem); }

@media (max-width: 639px) {
  .page-home .hero h1 { letter-spacing: -0.018em; line-height: 0.96; }
}

/* ==========================================================================
   The hero as a single column down the middle
   --------------------------------------------------------------------------
   "Discover PCP" has been removed, so there is one call to action instead of
   two. Three things follow from that, and they are all this block does.

   1. A LONE BUTTON SHOULD NOT BE FULL WIDTH ON A PHONE. The pair needed
      w-full to stack into two even bars; on its own that reads as a banner
      rather than a button, so it is given its natural width and centred.

   2. THE STACK IS NARROWER NOW, so the headline carries more of the hero and
      the gap under it can close a little.

   3. THE LEDE SITS ON THE BRIGHTEST PART OF THE FILM. The gold phoenix is
      directly behind it, and at 0.68 white it measured 4.64:1 — over the 4.5
      line, but only just, and it reads washed where the wings are brightest.
      Raised to 0.86 and given a shadow of its own. This changes no text and
      does not touch the film or its veil: brighter type, not a darker page.
   ========================================================================== */
/* ==========================================================================
   The hero as two groups, not one stack
   --------------------------------------------------------------------------
   Asked for: the headline and the description higher up, the button lower,
   and a noticeably bigger gap between the two.

   Done with ONE auto margin, and no new elements — the markup is a flat run
   of five siblings (h1, lede, actions, window, stats) and no text, wrapper or
   attribute is added to it.

   .hero-content is made a flex column that fills the hero's full height
   (align-self: stretch; the hero is a grid that was centring it). Inside a
   flex column, `margin-top: auto` on one child absorbs every pixel of free
   space above it. So the headline and the description settle at the top, the
   button and everything under it settle at the bottom, and the empty hero
   between them becomes the gap rather than padding nobody chose.

   It also scales by itself: on a tall screen there is more free space and the
   gap opens; on a short one there is none left to give and the stack simply
   closes up, which is what keeps the statistics on screen at 600px high. */
.page-home .hero-content {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  /* stretch, not center: the children keep their own widths and their own
     mx-auto / text-align, exactly as they had them. */
  align-items: stretch;
  /* Smaller than the clamp(2.5rem, 7svh, 5.5rem) it had, so the headline
     starts nearer the top of the hero. */
  padding-top: clamp(1.25rem, 3.4svh, 2.75rem);
  padding-bottom: clamp(1.5rem, 4svh, 3.25rem);
}

.page-home .hero .hero-actions {
  /* The gap. Everything from here down is pushed to the foot of the hero. */
  margin-top: auto;
  /* Still a floor, for the short screens where `auto` resolves to nothing. */
  padding-top: clamp(1.25rem, 3svh, 2.75rem);
}

/* Phones keep the same two-group behaviour, so the headline is at the top
   there too and the button is at the foot — that was the whole point of the
   change, and centring the stack on a phone would have undone it. The bottom
   padding is a little deeper than the desktop's, which takes some of the free
   space back out of the gap without stranding anything. */
@media (max-width: 639px) {
  .page-home .hero-content {
    padding-top: clamp(1rem, 2.5svh, 2rem);
    padding-bottom: clamp(1.75rem, 6svh, 3.5rem);
  }
}
.page-home .hero .hero-actions > .magnetic,
.page-home .hero .hero-actions > .magnetic > .btn {
  width: auto;
}

.page-home .hero .lede {
  /* Fully opaque. At 0.68 and then at 0.86 the glyphs were part backdrop, and
     the backdrop here is the lit wing of the phoenix. */
  color: #FFFFFF;
  /* Solid-coloured text, so a text-shadow paints behind the glyphs where it
     belongs — unlike the headline, which is filled by a background and needs
     drop-shadow instead. */
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.72), 0 2px 14px rgba(0, 0, 0, 0.5);
}

/* A scrim for the text column, and only the text column.

   Measured, not guessed. The brightest 5% of the film behind the lede is
   rgb(126,128,71) — the lit wing — which is luminance 0.199. Against that,
   even pure white text reaches only 4.21:1, under the 4.5 that body copy
   needs, and the semi-transparent white it had before was worse: 3.53:1 at
   1440 and 3.81:1 at 1920. Brightening the type cannot fix this on its own;
   the ground under it has to come down.

   So the ground comes down WHERE THE WORDS ARE and nowhere else. An ellipse
   behind the content column, soft enough to have no visible edge, leaves the
   phoenix and the map bright everywhere around it. The film, its veil, its
   opacity and its behaviour are all untouched — this sits above them. */
.page-home .hero-content { position: relative; }
.page-home .hero-content::before {
  content: "";
  position: absolute;
  inset: -6% -8%;
  z-index: -1;
  pointer-events: none;
  /* RESHAPED for the two-group layout. When the whole stack sat together in
     the middle, one ellipse centred on it was right. Now the words are at the
     top and the foot of the hero and the middle is deliberately empty — it is
     where the phoenix shows through — so a centred ellipse was darkening the
     one part of the film with no text on it at all.

     Two bands instead, top and bottom, fading out completely by 44% and
     starting again at 58%. The phoenix is at full brightness between them.
     Re-measured after the change: see the figures in the block above. */
  background: linear-gradient(180deg,
    rgba(4, 9, 18, 0.44) 0%,
    rgba(4, 9, 18, 0.30) 22%,
    rgba(4, 9, 18, 0.08) 38%,
    transparent 46%,
    /* THE LOWER HALF IS BURGUNDY, NOT NAVY.
       rgba(4, 9, 18, …) is a near-black blue. Over the lower hero it was the
       black gradient at the foot of the video: it climbed to 0.385 and it was
       the wrong colour for the page it ends on, so the bottom of the frame
       cooled towards black while everything around it is #260000. Same shape,
       same job — hold the copy legible over moving footage — in the ground
       colour, so the darkening now reads as the page arriving rather than as
       a black band laid over the film.

       Lower peak than the 0.30/0.385 it had (0.22), because the edge fade in
       transitions.css now reaches much further up and the two stack. Measured
       after the change: every line of hero copy still clears AA.

       The top half above 46% is untouched — it is not at the bottom edge and
       it is not what was asked for. */
    rgba(38, 0, 0, 0) 56%,
    rgba(38, 0, 0, 0.04) 64%,
    rgba(38, 0, 0, 0.10) 72%,
    rgba(38, 0, 0, 0.17) 80%,
    rgba(38, 0, 0, 0.22) 88%,
    /* 0.385 is exactly where the old 84%->100% ramp already was at this
       point, so every pixel above here is unchanged and the copy keeps the
       scrim it was measured against.

       From here the scrim lets go, because this is where it started showing.
       The hero's bottom edge is at 94.64% of this box — a constant, since the
       box and its -6% overhang are both proportions of the same element — and
       0.44 navy over the vignette's opaque #260000 composites to rgb(23,4,8),
       while the page below it is rgb(38,0,0). That mismatch was a hard line
       across the full width, and no amount of softening the video's own fade
       could remove it, because the scrim is painted on top of that fade.

       It is released only in the band below the lowest text, which ends at
       93.7% on a 360px phone and 92.1% on desktop — so the fade lives in
       clear space at every width and no text loses cover. */
    rgba(38, 0, 0, 0.22) 93.7%,
    rgba(38, 0, 0, 0.14) 94.05%,
    rgba(38, 0, 0, 0.05) 94.4%,
    rgba(38, 0, 0, 0) 94.64%,
    rgba(38, 0, 0, 0) 100%);
}

/* The small line under the reservation pill sits on the same bright band. */
.page-home .hero .hero-window {
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.7);
}

/* ==========================================================================
   The hero film, shown as it was shot
   --------------------------------------------------------------------------
   Seven layers sat between the viewer and this video, each one added when the
   hero's background was a gradient that needed atmosphere rather than footage
   that needs none. Together they cost it roughly half its light and most of
   its colour. Audited and dealt with one at a time:

     .hero-video        opacity 0.8 + saturate(0.85)   -> full opacity, no filter
     .hero-video-veil   a flat dark wash over all of it -> gone
     .hero-haze         a navy radial across the lower left -> gone
     .hero-vignette     0.55 black at the top edge      -> eased right back
     .hero-rays         gold, 0.38                      -> kept; it adds light
     .hero-ambient      a gold bloom                    -> kept; it adds light
     .hero-content::before  the scrim under the words   -> KEPT, and it is the
                            only thing now standing between the film and the
                            copy, which is why it stays.

   Nothing is deleted from the markup: every layer is still in the page and
   every rule above is still in this file, so removing this block puts the old
   atmosphere back exactly.
   ========================================================================== */
.page-home .hero-video {
  opacity: 1;
  filter: none;
}
@media (max-width: 767px) {
  /* The phone override took it down to 0.66 for contrast. The scrim does that
     job now, and it does it only where the text is. */
  .page-home .hero-video { opacity: 1; }
}

.page-home .hero-video-veil,
.page-home .hero-haze { display: none; }

/* The vignette is kept, because an unframed video bleeding into the section
   below it looks like a mistake — but as a soft edge, not a dark wash. */

/* The button a little lower.

   The whole bottom group — button, reservation status, statistics — is
   bottom-anchored by the auto margin above it, so the only thing holding it
   up off the foot of the hero is .hero-content's bottom padding. Trimming
   that lowers the button, and brings the three down together so the spacing
   between them is untouched.

   How far it can go is set by the statistics, which must stay on screen: they
   were already finishing 43px from the bottom at 1080 and 24px at 600. This
   takes roughly a third of that back and no more. */
.page-home .hero-content { padding-bottom: clamp(1rem, 2.6svh, 2.1rem); }

@media (max-width: 639px) {
  .page-home .hero-content { padding-bottom: clamp(1.25rem, 4.5svh, 2.75rem); }
}

/* ==========================================================================
   Pill corners on the two Reserve buttons
   --------------------------------------------------------------------------
   WHY THEY WERE NOT ROUND ALREADY. .btn in site.css is 999px — a pill
   everywhere on the site. The Home page alone overrides it: `.page-home .btn`
   further up this file sets 12px, and that is what both of these were
   picking up. So this is a Home-page problem and the fix belongs here.

   Scoped to the two that were asked for, by where they sit rather than by
   what they say, because the hero one changes its own label to "Check
   Available Slots" when the reservation window ends and a text-based hook
   would stop matching at that moment.

   .site-header covers the bar and the mobile menu panel, which are the same
   component at two sizes; rounding one and not the other would show as a
   square button on a phone.

   Radius only. The padding, min-height, font, letter-spacing, colour,
   gradient, hover lift, shimmer and position are all left exactly as the
   rules above set them. */
.page-home .site-header .btn,
.page-home .hero-actions .btn {
  border-radius: 999px;
}

/* The hero CTA keeps the width it had before its arrow was removed.

   The arrow was a child of a content-sized button, so taking it out took its
   own width and the flex gap beside it with it: 249px became 223px. The brief
   was to remove the arrow and leave the size alone, and those two only hold
   together if the 26px comes back as padding. 13px a side, on top of
   .page-home .btn-lg's 2.2rem.

   The orbit follows automatically — its host is the wrapper, which is sized
   by the button — so the dots keep tracing the same outline. */
.page-home .hero-actions .btn {
  padding-left: calc(2.2rem + 13px);
  padding-right: calc(2.2rem + 13px);
}

/* The two-line title has to actually hold two lines.

   "PHOENIX COMPREHENSIVE" is 21 characters, and measured at this weight it
   needs 14.06em of width. The <br> in the markup fixes where the second line
   starts, but it cannot stop the FIRST line wrapping inside itself, which is
   what was happening: three lines, not two.

   Two things were in the way. The headline carried max-w-5xl — a 1024px cap —
   inside a content column 1336px wide, so it was wrapping with 312px of room
   to spare. That cap is gone from the markup; at every width from 1280 up the
   line now fits at the size it already had, with nothing else changed.

   A phone is the real constraint: 350px of usable width over 14.06em means
   the type cannot exceed about 6.2vw, where the floor of the clamp above was
   holding it at 10vw. So the floor comes down here, and only here. It is a
   genuine trade — the headline is smaller on a phone than it was — and it is
   the price of two lines for a word pair this long. */
/* The second break is phone-only. On a wide screen the title reads on two
   lines and that break must not exist; a <br> with display: none produces no
   line break at all, so one declaration switches it off.

   NOTE THE SPACE before that <br> in the markup. Hiding the element removes
   the break AND any whitespace that only existed around it, so without a
   real space there the two words ran together as PHOENIXCOMPREHENSIVE on
   every desktop width. On a phone the break shows and that trailing space
   collapses at the end of the line, where it costs nothing. */
.page-home .hero h1 .hero-break-phone { display: none; }

@media (max-width: 639px) {
  /* Three lines on a phone: PHOENIX / COMPREHENSIVE / PROJECT. */
  .page-home .hero h1 .hero-break-phone { display: inline; }

  /* Sized to the LONGEST line, which is now "COMPREHENSIVE" rather than
     "PHOENIX COMPREHENSIVE". Measured at this weight: 9.2em against roughly
     9.7em of usable width, so 9vw fits with a few percent to spare at every
     phone size from 360 to 430. That is 35px at 390, against the 23.8px the
     two-line version was held to — half as big again. */
  .page-home .hero h1 { font-size: clamp(1.9rem, 9vw, 2.9rem); }
}

/* ==========================================================================
   Portrait phones: clearance between the emblem and the button
   --------------------------------------------------------------------------
   Measured first. The film is object-fit: cover, so on a tall narrow screen
   it is cropped at the SIDES and shows its full height — which puts the PCP
   emblem in the middle of the hero, right where the button had settled. At
   390x844 there were 15px between the emblem's foot and the top of the
   button; at 375x667 and 360x640 they genuinely overlapped.

   The button is bottom-anchored by the auto margin above it, so the only way
   to lower it is to reclaim height from BELOW. Trimming the content's bottom
   padding lowers the statistics by the same amount, and they were already
   finishing 38px from the foot of the screen, so most of this comes from the
   gaps and the row rhythm instead — those lower the button without carrying
   the statistics down with it.

   orientation: portrait, as asked. A phone turned sideways has a short hero
   and a quite different problem, and is left alone. */
@media (max-width: 639px) and (orientation: portrait) {
  /* Below the button: every pixel taken here is a pixel the button drops,
     and the hero stays exactly the height of the screen while it happens —
     nothing grows, nothing scrolls, and the film keeps its original scale.
     There were 206px under the button and this reclaims about 30 of them. */
  .page-home .hero .hero-window { margin-top: clamp(0.2rem, 0.5svh, 0.4rem); }
  .page-home .hero .hero-stats  { margin-top: clamp(0.3rem, 0.8svh, 0.6rem); }
  .page-home .hero-stats { gap: clamp(0.35rem, 1.4vw, 0.6rem) 0; }
  .page-home .hero-content { padding-bottom: clamp(0.4rem, 1svh, 0.75rem); }
}

/* Short portrait phones get a tighter foot still.

   Below about 700px of height the hero has to hold the title, the lede, the
   emblem in the film, the button, the window and four figures, and there is
   not enough room for all of it. Everything that can be taken from the block
   under the button is taken here — the window's own padding included — so the
   button sits as low as it can without pushing the statistics off screen. */
@media (max-width: 639px) and (orientation: portrait) and (max-height: 700px) {
  .page-home .hero .hero-window { margin-top: 0.15rem; }
  .page-home .hero .hero-stats  { margin-top: 0.3rem; }
  .page-home .hero-stats { gap: 0.3rem 0; }
  .page-home .hero-content { padding-bottom: 0.35rem; }
}

/* Three figures, not four.

   "50+ Success Stories" was removed from the markup. The row was declared as
   four equal columns, so three items would have sat in the left three with a
   fourth column of empty space beside them — the row reading off-centre
   against a centred hero. Matching the column count to what is actually there
   keeps the row even and centred, which is the arrangement that was already
   designed; nothing else about the figures, their type, colour, dividers or
   spacing changes.

   On a phone the row is two columns, and three items would leave the last one
   alone and off to one side. It spans both instead, so it sits centred under
   the pair above it. */
.page-home .hero-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); }

@media (max-width: 639px) {
  .page-home .hero-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .page-home .hero-stat:last-child { grid-column: 1 / -1; }
}

/* ==========================================================================
   The marquee between the hero and "PCP in motion"
   --------------------------------------------------------------------------
   Gold, spaced capitals on black, each phrase followed by a small gold dot,
   running right to left without a visible join.

   HOW THE SEAM IS HIDDEN. The nine phrases are in the markup twice and the
   track moves exactly -50% of its own width. At the end of one cycle the
   second copy occupies the first copy's starting position to the pixel, so
   the jump back to 0 changes nothing on screen. No JavaScript, no clones
   made at runtime, and nothing to resynchronise after a resize.

   Only transform is animated, so this runs on the compositor and costs no
   layout or paint per frame.

   The speed is set in seconds here, but it is a DISTANCE problem: the track
   is a fixed width, so a fixed duration gives a fixed px/s. Measured at
   1440: the run is about 2,900px, and 46s puts it near 63px/s — slow enough
   to read a phrase as it passes. The phone override shortens the duration
   in step with the smaller type so the speed stays about the same.
   ========================================================================== */
.ticker {
  position: relative;
  overflow: hidden;
  /* The page ground, not #000000. This bar is the first thing under the hero,
     and while it stayed pure black it laid a hard black band across a #260000
     page — the hero could fade as softly as it liked and would still end on a
     visible line, because the line was this bar, not the fade. Theme token, so
     it follows the ground colour if that ever moves again. */
  background-color: var(--pcp-burgundy);
  padding-block: clamp(0.85rem, 1.9vw, 1.35rem);
  /* The bar is decorative furniture, not a section: no top or bottom rule,
     nothing that reads as a box. */
}

.ticker-track {
  display: flex;
  width: max-content;
  animation: ticker-scroll 46s linear infinite;
  will-change: transform;
}

.ticker-run {
  display: flex;
  align-items: center;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ticker-run li {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  white-space: nowrap;
  text-transform: uppercase;
  font-size: clamp(0.72rem, 1.05vw, 0.92rem);
  letter-spacing: 0.34em;
  line-height: 1;
  color: var(--pcp-gold, #D4AF37);
}

/* The separator. On every item, the last one included, so the distance
   across the join is the same as everywhere else. */
.ticker-run li::after {
  content: "";
  flex-shrink: 0;
  width: 0.3rem;
  height: 0.3rem;
  margin: 0 clamp(1.5rem, 3.2vw, 2.75rem);
  border-radius: 50%;
  background-color: var(--pcp-gold, #D4AF37);
  /* The letter-spacing above puts a trailing gap after the last character;
     pulling the dot back by that much keeps it optically centred. */
  margin-left: calc(clamp(1.5rem, 3.2vw, 2.75rem) - 0.34em);
}

@keyframes ticker-scroll {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-50%, 0, 0); }
}

@media (max-width: 639px) {
  .ticker-track { animation-duration: 34s; }
}

/* Motion off: the phrases stay, the movement stops, and the row scrolls by
   hand instead of being cut off. */
@media (prefers-reduced-motion: reduce) {
  .ticker-track { animation: none; }
  .ticker { overflow-x: auto; }
  .ticker-run:last-child { display: none; }
}

/* ==========================================================================
   "Members doing the business" — one centred column above the carousel
   --------------------------------------------------------------------------
   Was a 12-column split: heading in the left eight, paragraph in the right
   four, both bottom-aligned. It is now a single centred stack sitting over
   the rail. The eyebrow is gone from the markup; the heading and the
   paragraph are the same words, moved and centred, not rewritten.

   The rail below is untouched. It was already a centre-focused carousel —
   the middle card at full size, the ones beside it smaller, and a press on
   a side card brings it to the middle (assets/js/achievements.js).
   ========================================================================== */
.page-home .biz-head {
  max-width: 52rem;
  margin-inline: auto;
  text-align: center;
}

/* The rule was a 4rem bar hanging on the left edge of the old right-hand
   column. Centred, it reads as a divider between the heading and the line
   under it, which is what it now is. */
.page-home .biz-head .rule-gold {
  margin: clamp(1.25rem, 2.4vw, 2rem) auto clamp(1rem, 2vw, 1.5rem);
  background: linear-gradient(90deg, transparent, var(--pcp-gold), transparent);
}

.page-home .biz-head p {
  max-width: 40rem;
  margin-inline: auto;
}

/* ==========================================================================
   The ticker: a full-bleed stripe with a gold hairline top and bottom
   --------------------------------------------------------------------------
   It spans the screen, as it always did. It was briefly inset to a centred
   column; that was meant for the carousel below and has been undone here.
   ========================================================================== */
.ticker {
  /* Full width, edge to edge — the inset belonged to the carousel below, not
     here. The gold hairlines stay: those were asked for on the ticker. */
  border-top: 1px solid rgba(212, 175, 55, 0.4);
  border-bottom: 1px solid rgba(212, 175, 55, 0.4);
}

/* ---- the ticker drops towards the heading it belongs to ----------------
   It sat hard against the section above it with the full --section-y below,
   which read as a lid on the hero rather than an opening line for "Members
   doing the business". It moves down by --ticker-drop, and the section below
   gives back exactly that much of its top padding — so the HEADING DOES NOT
   MOVE, nor does anything after it, and the page is the same height.

   Done with padding rather than a negative bottom margin on the ticker: the
   margin would have pulled the next section's box up THROUGH the stripe, and
   anything that section ever paints would land on top of it.

   --ticker-drop is declared on the page so both rules can read it; a custom
   property reaches descendants, not siblings. */
/* Scaled with --section-y: it used to take 45.6px out of a 100px pad, and
   against 48px that would have left the heading almost touching the
   stripe. Same share of a smaller number. */
.page-home { --ticker-drop: clamp(0.85rem, 1.5vw, 1.35rem); }
.page-home .ticker { margin-top: var(--ticker-drop); }
.page-home .ticker + .section { padding-top: calc(var(--section-y) - var(--ticker-drop)); }

/* ==========================================================================
   The business rail: two cards at a time, advancing on a timer
   --------------------------------------------------------------------------
   Centred and inset from both screen edges, showing exactly two cards, and
   still a native scroller — which is what keeps the arrows, the swipe and
   the drag working. assets/js/achievements.js moves it on a three-second
   timer and keeps it wrapped inside its own length.

   WIDTH, NOT HEIGHT, is what sizes the cards now. "Exactly two at a time"
   is a statement about width, and the rail used to be sized by height with
   the width falling out of each film's own shape — which made the count per
   view depend on the footage. Each card is now half the container less half
   the gap.

   Nothing is cropped by this. The height still follows each film's real
   --media-ar, so the two shapes in the rail (1.778 and 1.828) differ by
   about nine pixels of height and nothing is cut. They are aligned to the
   top so that difference reads as a detail rather than a misalignment.
   ========================================================================== */
.page-home .biz-loop {
  /* Held in a custom property, not just applied as a width, because the card
     width below is derived from it. A percentage on the card cannot be used:
     its parent is the max-content track, whose width is decided BY the cards,
     and that circle resolves to a collapsed 24px card. Measuring against the
     viewport instead breaks the loop. */
  --biz-w: min(76rem, calc(100vw - clamp(2.5rem, 7vw, 5rem)));
  --biz-gap: clamp(0.85rem, 1.6vw, 1.5rem);
  /* A lane down each side, OUTSIDE the scroll port, holding the arrows.
     They used to float over the cards; giving them their own room is what
     makes a whole frame visible rather than one with a button sitting on its
     corner. The cards give up this width, which is the "slightly smaller"
     part. The minimum is one arrow wide (3rem) so the button never reaches
     back over the port edge on a narrow laptop. */
  --biz-pad: clamp(3rem, 4vw, 3.75rem);
  /* Two across, inside the arrow lanes — named, because the arrows need the
     frame's height and the only way to it is through the card's width. Both
     are derived here, on the element that declares the parts they are built
     from: a var() inside a custom property resolves against the element that
     DECLARES it, not the one that uses it. */
  --biz-card-w: calc((var(--biz-w) - 2 * var(--biz-pad) - var(--biz-gap)) / 2);
  --biz-frame-h: calc(var(--biz-card-w) * 9 / 16);
  width: var(--biz-w);
  margin-inline: auto;
  position: relative;
}

/* ---- the rail's own reserved space -------------------------------------
   The cards were 416px tall around a 303px frame: the figure still carried
   --video-card-h from the old height-driven rail, which left 113px of empty
   card under every film. That is most of what still read as a gap between
   the carousel and "Proof in progress" after the section padding came down
   — and it was inside the component, not between the sections, which is why
   trimming the padding alone never fixed it.

   The card is now the height of its frame, and the track keeps just enough
   room underneath for the frames' glow, which its own overflow would
   otherwise clip. Scoped to .biz-loop: the achievements feature and the
   Founder rail still size themselves the way they did.

   The arrows do not move — they are placed from the FRAME's height and the
   track's TOP padding, neither of which changes here. */
.page-home .biz-loop .ach-item figure { height: auto; }

/* The scroller. */
.page-home .biz-loop .biz-loop-track {
  display: flex;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.page-home .biz-loop .biz-loop-track::-webkit-scrollbar { display: none; }
.page-home .biz-loop .biz-loop-track:focus-visible {
  outline: 2px solid var(--pcp-gold);
  outline-offset: 4px;
}

/* Both halves of the loop are plain flex rows inside the one scroller. */
.page-home .biz-loop .ach-track {
  display: flex;
  gap: var(--biz-gap);
  overflow: visible;
  margin: 0;
  padding: 0.5rem 0 0.75rem;
  width: max-content;
  scroll-snap-type: none;
}

/* NO PARTIAL CARDS.

   The arrow lanes used to be padding ON the scroller. Padding is inside the
   scroll port, so the next card scrolled straight through it and sat at the
   edge half-shown — the slivers in the screenshot. The port is now exactly
   two cards and one gap wide and centred, and the lanes are the space left
   over on either side of it, outside the port entirely. Anything that is not
   one of the two whole cards is past the port's edge and clipped by its own
   overflow. */
.page-home .biz-loop .biz-loop-track {
  width: calc(var(--biz-w) - 2 * var(--biz-pad));
  margin-inline: auto;
  padding-inline: 0;
  scroll-padding-inline: 0;
}
/* The seam between the two halves needs the same gap as everywhere else. */
.page-home .biz-loop .ach-track + .ach-track { margin-left: var(--biz-gap); }

/* Room under the films for their glow, which the scroller's overflow would
   otherwise cut off square. It has to come AFTER the .ach-track rule above:
   that one sets `padding` in shorthand at the same specificity, and a
   shorthand declared later wins over a padding-block declared earlier
   however tidy the earlier one looks. Only the BOTTOM changes — the arrows
   are placed from the top padding, and moving that would move them. */
.page-home .biz-loop .ach-track { padding-bottom: 1.25rem; }


.page-home .biz-loop .ach-item {
  flex: 0 0 auto;
  align-self: flex-start;
  scroll-snap-align: start;
  width: var(--biz-card-w);
}
/* Nothing is the subject here, so nothing is scaled or dimmed. */
.page-home .biz-loop .ach-item figure { transform: none; opacity: 1; }
.page-home .biz-loop .ach-item:not(.is-center) { cursor: default; }

/* ONE SHAPE FOR EVERY CARD.

   The frames used to take their aspect ratio from their own footage, through
   the --media-ar that achievements.js measures off each file. Three of the
   films are 1920x1080 and one is 848x464, so that card came out 294.8px tall
   against the others' 303.1px — a visible 8px step in a row of two.

   The frame is now a fixed 16/9 for all of them and the film is fitted
   INSIDE it with object-fit: contain, so the odd one out letterboxes by
   about four pixels top and bottom instead of changing the furniture around
   it. Nothing is cropped: contain never cuts, it only adds bars.

   Carries .ach-track so it outweighs .biz-rail's own (0,4,0) --media-ar
   rule further up this file, which would otherwise still be in charge.
   --media-ar is left alone — the Founder rail reads it, and so does the
   achievements feature. */
.page-home .biz-loop .ach-track .ach-item .media-frame,
.page-home .biz-loop .ach-item .media-frame {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
}

/* contain, not cover: show the whole frame of film and bar off the rest.

   This rail is the exception to the page's rule. "A video fills its frame
   edge to edge, no letterbox band" is set further up this file, deliberately,
   for every .media-frame on the home page — and it has to keep applying
   everywhere else. It is written as
     .page-home .media-frame:has(.media-mount video) .media-mount video
   which is (0,4,2); a plain .page-home .biz-loop [data-pcp-video] > video is
   only (0,3,1) and quietly lost to it. The selector below is that same shape
   with .biz-loop added, so it outweighs it here and nowhere else.

   Cover was cropping the 848x464 film to fill a 16/9 box. Contain shows all
   of it and pays about four pixels of black top and bottom, which is the
   trade asked for: whole picture, matching frames.

   The bars are black: .media-frame:has(.media-mount video) is already
   painted #000 further up, and the mount matches it once its footage is
   showing, so nothing of the designed texture reads through the band. */
.page-home .biz-loop .media-frame:has(.media-mount video) .media-mount video,
.page-home .biz-loop .media-frame:has(.media-mount img) .media-mount img {
  object-fit: contain;
}
.page-home .biz-loop [data-pcp-video] > video,
.page-home .biz-loop [data-pcp-video] > img { object-fit: contain; }
.page-home .biz-loop [data-pcp-video].is-showing { background-color: #000000; }

/* ---- THE WORLD IS CHANGING — the standing panel -------------------------
   It was a card inside the rail and is now a panel above the heading, so
   the width is no longer derived from the cards. It is stated here instead,
   from the same two numbers the rail uses — the rail's own width less its
   two arrow lanes — which is exactly the width of the scroll port, so the
   panel's edges line up with the films below it to the pixel.

   That is also why it sits OUTSIDE .wrap in the markup: .wrap is the 1400px
   text column, centred with its own padding, and a panel inside it would
   have come out 20px narrower on each side than the full-bleed rail. */
.page-home .biz-statement {
  /* The frame is gone: no ring, no panel fill, no rounded box. The words
     stand on the page, and the three video slots below carry the only edges
     in here. The measure is kept, because it is what lines this block up
     with the film strip further down. */
  --stmt-w: min(76rem, calc(100vw - clamp(2.5rem, 7vw, 5rem)));
  --stmt-pad: clamp(3rem, 4vw, 3.75rem);
  width: calc(var(--stmt-w) - 2 * var(--stmt-pad));
  /* The slots follow immediately, so the space below the paragraph is the
     gap to THEM, not the gap to the next section — that now belongs to
     .reels-loop. */
  margin: 0 auto clamp(1.75rem, 3.5vw, 2.75rem);
}

.page-home .biz-statement .biz-slide-inner {
  width: 100%;
  max-width: 52rem;
  margin-inline: auto;
  text-align: center;
}

/* The same size and weight as "Members doing the business" below it. */
.page-home .biz-statement .biz-slide-title {
  margin: 0;
  font-size: clamp(2.4rem, 4.4vw, 3.5rem);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.03em;
  color: #fff;
}

.page-home .biz-statement .biz-slide-body {
  margin: clamp(1rem, 2vw, 1.5rem) auto 0;
  max-width: 46rem;
  font-size: clamp(0.95rem, 1.15vw, 1.0625rem);
  line-height: 1.7;
  color: rgba(255, 255, 255, 0.72);
}

/* ---- the three empty video slots ----------------------------------------
   The slots carry .biz-loop, so the carousel itself — card width, the
   two-up scroll port, the arrow lanes, the phone override — is the business
   rail's, to the pixel, and assets/js/achievements.js drives both from the
   same code. Only the look of an empty slot is set here.

   A .media-frame was the obvious thing to put in each one, since that is
   what the films below sit in. It is the wrong thing: an empty .media-frame
   wears the designed texture, the sheen and the vignette, and reads as a
   video that failed to load rather than as a slot waiting for one. (That is
   why the three empty cards were taken out of the film rail in the first
   place — see the note in build/pages/home.html.) A plain framed panel says
   "nothing here yet" and nothing else. */
.page-home .reels-loop {
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}

.page-home .reels-loop .biz-reel {
  position: relative;            /* the mount is laid over it */
  overflow: hidden;              /* so the footage takes the slot's radius */
  width: 100%;
  /* The three clips are 1920x1080, 1920x1080 and 1280x720 — all exactly
     16/9, which is also the film rail's shape. So the slot's ratio IS each
     video's own ratio and there is nothing to crop or letterbox. */
  aspect-ratio: 16 / 9;
  border-radius: 16px;
  /* The same gold edge the film frames wear, drawn the same way — a shadow,
     so it takes no part in layout. */
  box-shadow: 0 0 0 2px rgba(212, 175, 55, 0.55),
              0 30px 70px -45px rgba(0, 0, 0, 0.9);
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(212, 175, 55, 0.07) 0%, transparent 62%),
    linear-gradient(180deg, #0a0a0b 0%, #050506 100%);
}

/* The footage fills the slot. assets/js/video.js puts the poster and then
   the player inside .media-mount; this only sizes them.

   NOTHING IS LAID OVER THE PICTURE. No texture, no sheen, no vignette, no
   gradient — the .media-frame wrapper the film rail uses carries all three
   and is deliberately absent here. The slot's own background sits BEHIND
   the video and is covered by it.

   contain, not cover: the ratios already agree to three decimal places, so
   the two render identically today, and contain is the one that cannot
   start cropping if a clip is ever swapped for one of another shape. */
.page-home .reels-loop .biz-reel .media-mount {
  position: absolute;
  inset: 0;
}
.page-home .reels-loop .biz-reel [data-pcp-video] > video,
.page-home .reels-loop .biz-reel [data-pcp-video] > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: inherit;
  /* VISIBLE. `.page-home .media-mount video { opacity: 0 }` further up this
     file hides anything that lands in a mount until its .media-frame is
     told to reveal it — and these slots have no .media-frame, so without
     this they stay invisible for ever. The frame rail gets round the same
     rule with a :has() selector; here it is simpler to say it outright.
     video.js puts each clip's poster on the element's own poster attribute,
     so the picture is there from the first paint rather than after a fade.

     filter: none for the same reason — the mount's treatment is meant for
     footage sitting inside a designed frame, and nothing is to be laid over
     or applied to these. */
  opacity: 1;
  filter: none;
}

/* ---- the one control the two rails have --------------------------------
   The native bar is removed by assets/js/reel-player.js and never comes
   back; this is what replaces it, on the slots rail and the film rail
   alike. One button in the middle: a triangle when paused, two bars while
   playing. No timeline, because there is nothing to drag to.

   .media-frame already carries position: relative, as .biz-reel does, so
   the button centres on whichever of the two actually holds the video. */
.page-home [data-reel-player] .reel-play {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
  z-index: 4;                    /* over the footage, under nothing */
  display: grid;
  place-items: center;
  width: clamp(3.25rem, 5.5vw, 4.25rem);
  height: clamp(3.25rem, 5.5vw, 4.25rem);
  padding: 0;
  border-radius: 50%;
  border: 1px solid rgba(212, 175, 55, 0.55);
  /* Dark enough to hold the mark against a bright frame, sheer enough that
     it is plainly a button sitting ON the picture rather than a panel
     covering it. */
  background: rgba(8, 8, 9, 0.52);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  color: var(--pcp-gold-light, #F4D98B);
  cursor: pointer;
  transition: transform 320ms var(--ease-spring), opacity 260ms ease,
              border-color 260ms ease, background-color 260ms ease,
              box-shadow 260ms ease;
}
.page-home [data-reel-player] .reel-play svg {
  width: 42%;
  height: 42%;
  fill: currentColor;
}

/* PAUSED: the play mark is there, always.
   PLAYING: it gets out of the way entirely, and comes back under the
   pointer. Nothing should sit on a film that someone chose to watch.

   The hover is on the FRAME, not the button, so anywhere on the picture
   brings it back rather than only the 60px it occupies. focus-within is the
   keyboard's equivalent — without it the control would be unreachable to
   anyone not using a mouse. pointer-events go with the opacity so an
   invisible button is never in the way of a click on the picture. */
.page-home [data-reel-player] .is-playing .reel-play {
  opacity: 0;
  pointer-events: none;
}

/* The hover and focus-within reveals that used to sit here are gone. The
   focus-within one was the reason the mark came STRAIGHT BACK after you
   pressed it: clicking the button focuses it, the frame then matches
   :focus-within, and the control reappeared over the film it had just
   started. Hover did the same to anyone whose cursor stayed on the picture.

   Pausing is not lost with them. The picture itself is a click target —
   see the video 'click' handler in assets/js/reel-player.js, drag-guarded
   so a swipe on the rail does not toggle playback.

   The one exception is a keyboard. :focus-visible only matches a focus that
   did not come from a pointer, so the control stays hidden for everyone
   watching and still reachable for someone tabbing to it, who would
   otherwise have no way to pause at all. */
.page-home [data-reel-player] .is-playing .reel-play:focus-visible {
  opacity: 1;
  pointer-events: auto;
}

/* A touchscreen has no pointer to hover WITH, so "show it on hover" would
   mean "never show it" — and the only way to pause would be to know that
   tapping the picture works. The mark stays, quietly, where there is no
   hover to depend on. */
/* A touchscreen used to keep the mark at 0.5 opacity through playback,
   because "show it on hover" means "never show it" without a pointer. The
   brief asks for it hidden while playing on mobile as well, and tapping the
   picture pauses, so the exception is no longer needed. */

/* The feature frame carries its own decorative play mark in the markup.
   With a real button in the same place that would be two marks, so it
   stands down wherever this player is in charge. */
.page-home [data-reel-player] .ach-play { display: none; }

.page-home [data-reel-player] .reel-play:hover {
  border-color: rgba(212, 175, 55, 0.95);
  background: rgba(8, 8, 9, 0.68);
  color: #fff;
  box-shadow: 0 0 0 1px rgba(212, 175, 55, 0.25),
              0 0 34px -6px rgba(212, 175, 55, 0.65);
  transform: scale(1.06);
}
.page-home [data-reel-player] .reel-play:focus-visible {
  outline: 2px solid var(--pcp-gold, #D4AF37);
  outline-offset: 3px;
  opacity: 1;
}
.page-home [data-reel-player] .reel-play:active { transform: scale(0.96); }

@media (prefers-reduced-motion: reduce) {
  .page-home [data-reel-player] .reel-play { transition: opacity 260ms ease, border-color 260ms ease; }
  .page-home [data-reel-player] .reel-play:hover,
  .page-home [data-reel-player] .reel-play:active { transform: none; }
}

/* Nothing in a slot is pressable yet, so it must not offer a grab cursor. */
.page-home .reels-loop .ach-item { cursor: default; }

/* One card at a time on a phone, where two would be unreadable. */
@media (max-width: 767px) {
  .page-home .biz-loop { --biz-pad: 0rem; --biz-card-w: var(--biz-w); }
  /* No arrow lanes there either, so the panel is the full measure and still
     matches the single card below it. */
  .page-home .biz-statement { --stmt-pad: 0rem; }
}

/* The arrows sit just inside the container's edges, and level with the
   MIDDLE OF THE FRAME.

   50% of the rail is not that point. The card is taller than the frame it
   holds — the figure still carries the old height-driven rail's
   --video-card-h, which leaves room under the frame for its glow — so
   centring on the container put both arrows 30.8px below the middle of the
   artwork. That is the "slightly too low".

   Measured from the top of the track instead: its 0.5rem of top padding,
   plus half a frame, less half a button. The frame's height is now a known
   quantity because every card is a fixed 16/9 (see above), which is what
   makes this arithmetic possible at all. */
.page-home .biz-loop .ach-nav {
  top: calc(0.5rem + (var(--biz-frame-h) / 2) - 1.5rem);
}
.page-home .biz-loop .ach-nav-prev { left: 0; }
.page-home .biz-loop .ach-nav-next { right: 0; }

/* Motion off: the timer never starts (see achievements.js) and the rail is
   an ordinary scroller. The duplicate half is hidden so a screen reader and
   a keyboard user meet each film once. */
@media (prefers-reduced-motion: reduce) {
  .page-home .biz-loop .biz-loop-track { scroll-behavior: auto; }
  .page-home .biz-loop .ach-track[aria-hidden="true"] { display: none; }
}

/* Drag needs the browser to stop helping.

   mountRail() drags by writing scrollLeft directly. The scroller above is
   scroll-behavior: smooth with mandatory snapping, and between them they
   animate and then pull back every write, so a drag moved the rail nowhere.
   The existing .is-dragging rules targeted .ach-track — the <ul> — which is
   no longer the scroller, so they never reached it. Both now land on the
   element that actually scrolls. */
.page-home .biz-loop .biz-loop-track.is-dragging {
  scroll-behavior: auto;
  scroll-snap-type: none;
  cursor: grabbing;
}
.page-home .biz-loop .biz-loop-track.is-dragging .ach-item { pointer-events: none; }

/* The seam between the business rail and Members' achievements used to be
   patched here, taking a fraction off each side, because two 100px paddings
   met and left 209px of nothing. --section-y is now 48px a side, so this
   boundary gets the same inch as every other one and needs no special case.
   What remains of the gap is the rail's own reserved space, handled below. */

/* ==========================================================================
   PCP PARTNERS ACHIEVEMENTS — the gold boundary, and video beside the words
   --------------------------------------------------------------------------
   THE DIVIDER. A flat 1px line in the brand gold, marking the end of the
   video section above. Deliberately NOT .rule-gold: that one is a
   transparent→gold→transparent gradient with a soft centre, which is the
   opposite of what a boundary should look like. One colour, no gradient, no
   glow, no shadow, full width of the content column.

   Spacing is balanced by hand rather than inherited: the section's own top
   padding is removed and replaced with the same gap the line gets below it,
   so the rule sits exactly between the two sections instead of hard against
   the heading.

   THE SPLIT. Video left, heading and description together on the right,
   centred on each other vertically. One grid, one breakpoint. Below 900px it
   is not a grid at all, so the two simply stack in source order — film, then
   words — with nothing to overflow and no column to crush.
   ========================================================================== */
.page-home .ach-divider {
  height: 1px;
  background-color: var(--pcp-gold);
  background-image: none;
  box-shadow: none;
  margin: 0 0 clamp(2.25rem, 4vw, 3.25rem);
}

/* The section's top padding becomes the divider's breathing room, so the
   boundary is not sitting under 100px of empty space. */
.page-home .ach-section { padding-top: clamp(2.25rem, 4vw, 3.25rem); }

/* Compact: the heading, the rule and the line under it were spaced for a
   centred stack with the full width to fill. In a column beside a video they
   only need to be read as one block. */
.page-home .ach-split-text.biz-head .rule-gold {
  margin-block: clamp(0.85rem, 1.5vw, 1.15rem) clamp(0.7rem, 1.2vw, 1rem);
}
.page-home .ach-split-text.biz-head > h2 { margin-bottom: 0; }
.page-home .ach-split-text.biz-head > p  { margin-bottom: 0; }

/* The film fills its column at its own landscape shape. .ach-feature sizes by
   --video-card-h with width:auto, which is right for a full-bleed rail and
   wrong for a grid cell: here the column sets the width and 16/9 sets the
   height. --ach-gutter goes to zero because the card no longer has to line
   itself up with .wrap — it is already inside it. */
.page-home .ach-split .ach-carousel { margin-top: 0; --ach-gutter: 0px; }
.page-home .ach-split .ach-track { padding-inline: 0; }
.page-home .ach-split .ach-feature .ach-item { width: 100%; }
.page-home .ach-split .ach-feature .ach-item figure { height: auto; width: 100%; }
.page-home .ach-split .ach-feature .ach-item .media-frame {
  height: auto;
  width: 100%;
  aspect-ratio: var(--media-ar, 16 / 9);
}

@media (min-width: 900px) {
  .page-home .ach-split {
    display: grid;
    grid-template-columns: minmax(0, 1.08fr) minmax(0, 1fr);
    gap: clamp(1.75rem, 3.2vw, 3rem);
    align-items: center;
  }
  /* .biz-head is kept on the text column so .rule-gold keeps its treatment,
     but its centring is for a full-width stack and has to come off here. */
  .page-home .ach-split-text.biz-head {
    max-width: none;
    margin-inline: 0;
    text-align: left;
  }
  .page-home .ach-split-text.biz-head .rule-gold { margin-inline: 0; }
}

@media (max-width: 899px) {
  .page-home .ach-split { display: block; }
  .page-home .ach-split-text.biz-head { margin-top: clamp(1.25rem, 4vw, 1.75rem); }
}

/* ==========================================================================
   Slide indicators under the business rail
   --------------------------------------------------------------------------
   Four dots for four films. The active one is a gold pill, the rest are small
   muted circles.

   WHY THE PILL IS A CHILD AND THE GROWTH IS A scaleX. The obvious build is to
   transition the button's width from 7px to 22px, and it is the wrong one
   twice over: width is a layout property, so every dot to the right of the
   active one shuffles on each advance, and this page's rule is that only
   transform and opacity are ever animated. The button therefore keeps a fixed
   22px box at all times and the span inside it is squeezed to a circle with
   scaleX — the row is geometrically still, and the only things moving are a
   transform and an opacity.

   Only [data-rail-dots] gets them, which is the business rail alone.
   ========================================================================== */
.page-home .rail-dots {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.35rem;
}

.page-home .rail-dot {
  display: grid;
  place-items: center;
  width: 22px;
  height: 16px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.page-home .rail-dot > span {
  display: block;
  width: 22px;
  height: 7px;
  border-radius: 999px;
  background-color: var(--pcp-gold);
  /* 22 x 0.318 = 7px: the same width as its height, so an inactive dot is a
     true circle rather than a short bar. */
  transform: scaleX(0.318);
  opacity: 0.34;
  transition: transform 420ms var(--ease-spring), opacity 300ms ease;
}

.page-home .rail-dot:hover > span { opacity: 0.6; }
.page-home .rail-dot:active > span { opacity: 0.8; }

.page-home .rail-dot.is-active > span {
  transform: scaleX(1);
  opacity: 1;
}
.page-home .rail-dot.is-active:hover > span { opacity: 1; }

.page-home .rail-dot:focus-visible {
  outline: 2px solid var(--pcp-gold);
  outline-offset: 2px;
  border-radius: 999px;
}

@media (prefers-reduced-motion: reduce) {
  .page-home .rail-dot > span { transition: none; }
}

/* ==========================================================================
   The ticker's gap under the statistics
   --------------------------------------------------------------------------
   The statistics row is deliberately UNBOXED: it is the plain row it always
   was, with no frame of any kind. A dashed-and-solid gold box was tried here
   and taken back out — besides being wrong for the hero, the padding it added
   grew upward from a bottom-anchored row and pulled the Reserve button up
   into the phoenix mark in the footage behind it.

   What remains is the ticker's own drop, which is unrelated to the box: the
   section below gives back exactly the same amount of top padding, so the
   heading after the stripe does not move and the page keeps its height. It
   cannot be pushed much past this — --section-y is 28px on a phone and the
   give-back is `--section-y - --ticker-drop`, which has to stay positive.
   ========================================================================== */
.page-home { --ticker-drop: clamp(1.15rem, 2vw, 1.85rem); }

/* ==========================================================================
   Achievements: the words start where the film starts, and read a little
   larger beside it
   --------------------------------------------------------------------------
   ALIGNMENT. The two columns were centred on each other, which left the
   heading floating in the middle of the frame's height. `start` puts the top
   of the text block on the top edge of the video. The h2 already carries no
   top margin, so its first line box begins exactly at the column's top and
   nothing has to be nudged to compensate.

   SIZE. A clamp of its own rather than a multiplier on the shared .h-caps
   scale, because this heading now lives in a half-width column and the
   shared scale is tuned for a full-width centred stack.

   The floor is deliberately close to where it already was. On a phone the
   column is the full 350px and "ACHIEVEMENTS" is a single unbreakable word
   that already spans about 320px of it at the current size; a desktop-sized
   increase applied there would push it to the edge or force a break. So the
   phone keeps its proportions and only the wider screens gain.
   ========================================================================== */
.page-home .ach-split-text.biz-head > h2 {
  font-size: clamp(2.45rem, 1.2rem + 3.1vw, 3.95rem);
  line-height: 1.02;
}

@media (min-width: 900px) {
  .page-home .ach-split { align-items: start; }
}

/* ==========================================================================
   The Reserve button sits lower, clear of the phoenix in the footage
   --------------------------------------------------------------------------
   The mark is part of WEBSITE BG 07.mp4, not an element on the page, so no
   amount of z-index or margin on a logo moves it: the only thing that can
   change is where the button lands over it. Measured on the paused frame,
   the mark ends at row 502 of the hero and the button was starting at 523 —
   21px, which reads as the button sitting on top of it.

   Everything from .hero-actions down is pinned to the foot of the hero by a
   single `margin-top: auto`, so the button's position is set by the total
   height BELOW it. Trimming this one gap therefore lowers the button and
   leaves the reservation window, the note and the statistics exactly where
   they are — which is the only reason it is this property and not the
   hero's bottom padding, which would have dragged the whole group down into
   the fade.
   ========================================================================== */
.page-home .hero-window { margin-top: 1.1rem; }
@media (max-width: 767px) { .page-home .hero-window { margin-top: 1rem; } }

/* ==========================================================================
   SEVEN PILLARS — the map beside the words, and seven matching cards
   --------------------------------------------------------------------------
   TWO COLUMNS. Map left in a gold frame, heading and the three-step path
   right, centred on each other. Below 1024px the grid collapses and the two
   simply stack in source order — map, then words.

   RE-FITTING THE MAP IS THE WHOLE JOB. .eco-stage took its height from the
   VIEWPORT (clamp(30rem, 46vw, 41rem)) while its width came from its
   container. That is fine full-bleed, where the two track each other, and
   wrong in a half-width column: the box would keep a ~700px height at ~600px
   of width, and the nodes — placed at percentages of each axis — would be
   pulled into a tall oval with the outer labels hanging past the frame. The
   stage therefore takes an aspect-ratio here, so its height follows its own
   width, and --eco-squash tightens the horizontal spread to match the
   narrower box. Verified by measurement: all seven nodes, the core and the
   readout sit inside the frame with no pair overlapping.
   ========================================================================== */
.page-home .eco-split {
  display: grid;
  gap: clamp(1.75rem, 3vw, 3rem);
}

/* 1280, not 1024. The two-column split is only safe while the map's column
   stays wide enough for the diagram: the node labels are real text at a
   fixed size and they do not shrink with the box, so below roughly 1200px
   of viewport the outer labels start colliding — measured at 1024px, where
   Personal Development overlapped both Leadership and Opportunity and the
   core's rings pushed past the frame. Above 1280 the column is ~574px and
   everything clears. Below it the section simply stacks, which gives the
   map the full width and is the geometry it was built for. */
@media (min-width: 1280px) {
  .page-home .eco-split {
    grid-template-columns: minmax(0, 1.04fr) minmax(0, 0.96fr);
    align-items: center;
  }
}

.page-home .eco-frame {
  position: relative;
  border: 1px solid rgba(212, 175, 55, 0.38);
  border-radius: 22px;
  padding: clamp(0.7rem, 1.4vw, 1.25rem);
  /* Dark Wine Red, flat — the same fill the six cards carry, so the frame
     and the cards read as one set. The gold edge above is untouched, and so
     is everything drawn inside: the nodes, their labels, the connecting
     lines and the PCP core all come from the markup and the canvas, not
     from this. */
  background: #3B0005;
  overflow: hidden;
}

/* These three re-fit the diagram to a half-width column, so they belong to
   the two-column case ONLY. Applied at every width they were actively
   harmful: on a phone the stage's own rule gives it 480px of height, and
   swapping that for an aspect-ratio against a 326px-wide box collapsed it to
   306px and pushed the labels into each other. */
@media (min-width: 1280px) {
  /* Left at the stock 0.78. Squash was briefly dropped to 0.68 to keep the
     outer labels inside the frame, which measurement says was never the
     problem — nothing spills at this width — and it actively caused one:
     Community (nx 0.68) and Mentorship (nx 0.32) sit at the same height, so
     the ONLY thing holding them apart is horizontal spread, and squashing
     pulls them together. They collided at 1280 because of it. */
  .page-home .eco-split .eco-map { --eco-squash: 0.78; }
  .page-home .eco-split .eco-stage {
    height: auto;
    aspect-ratio: 1 / 0.94;
    min-height: 19rem;
  }
  .page-home .eco-split .eco-node { max-width: 8rem; }
}

.page-home .eco-split-text .path { justify-content: flex-start; }
@media (max-width: 1279px) {
  .page-home .eco-split-text { text-align: center; }
  .page-home .eco-split-text .path { justify-content: center; }
}

/* ==========================================================================
   The seven pillar cards
   --------------------------------------------------------------------------
   One frame, seven times: rounded dark card, a quiet gold edge, a gold
   emblem centred at the top, then the title and the description exactly as
   they were written. No text is touched by anything in this block.

   THE PHOTOGRAPHS ARE OFF. Each card carried its own --pillar-photo behind a
   dark veil, which is the one thing that cannot survive "give each card the
   same layout": seven different pictures are seven different cards. The
   block that sets them is left in the file directly above, so putting them
   back is a matter of deleting the background line below.

   FLEX, NOT GRID, for the row. Seven cards in a four-column grid leave a
   hole in the last row; wrapped flex with justify-content: center lands them
   4 + 3 with the short row centred under the long one.
   ========================================================================== */
.page-home .eco-pillars {
  --pillar-gap: clamp(0.9rem, 1.5vw, 1.25rem);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--pillar-gap);
}

.page-home .eco-pillars > .panel {
  flex: 0 1 calc((100% - 3 * var(--pillar-gap)) / 4);
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: clamp(1.5rem, 2.1vw, 1.9rem) clamp(1.05rem, 1.7vw, 1.4rem);
  border: 1px solid rgba(212, 175, 55, 0.28);
  border-radius: 20px;
  /* Burgundy Red, flat. The shorthand also clears the background-size /
     position / repeat the photograph block further up sets, so nothing of
     the old per-pillar picture is left behind. The gold edge, the radial
     sheen on .panel::before, the icons and the type are all untouched —
     this line is the card's fill and nothing else. */
  background: #3B0005;
}

/* The emblem: centred, round, gold. Each card keeps the icon it already had —
   figure, star, case, group, shield, book, key — so all seven are distinct
   and all seven are drawn in the same 1.5-weight line style. */
.page-home .eco-pillars > .panel .icon-line {
  width: 3.4rem;
  height: 3.4rem;
  margin: 0 0 clamp(0.95rem, 1.5vw, 1.25rem);
  border-radius: 999px;
  border: 1px solid rgba(212, 175, 55, 0.45);
  background: rgba(212, 175, 55, 0.1);
  color: var(--pcp-gold);
}
.page-home .eco-pillars > .panel .icon-line svg { width: 1.55rem; height: 1.55rem; }

/* The featured card's 2.1rem heading would break the set; one size for all. */
/* A step down from clamp(1.05rem, 1.35vw, 1.22rem) / clamp(0.88rem, 1vw,
   0.95rem), so the type sits under the larger emblem rather than competing
   with it. About 8% in each case — the words are unchanged and the measure,
   line-height and spacing are as they were. The phone sizes further down
   are left alone: the tile is 50px there, not 81px, so the balance the
   reduction is correcting does not arise, and that copy is already small. */
.page-home .eco-pillars > .panel h3 {
  font-size: clamp(0.98rem, 1.24vw, 1.12rem);
  margin-bottom: 0.6rem;
}
.page-home .eco-pillars > .panel p {
  font-size: clamp(0.82rem, 0.92vw, 0.89rem);
  line-height: 1.7;
  margin-bottom: 0;
}

@media (max-width: 1023px) {
  .page-home .eco-pillars > .panel { flex: 0 1 calc((100% - var(--pillar-gap)) / 2); }
}
@media (max-width: 599px) {
  .page-home .eco-pillars > .panel { flex: 1 1 100%; }
}

/* On a phone the frame's own padding is what breaks the diagram. The stage
   is 350px wide there and the padding took 24px of it; the node labels are
   fixed-size text that does not shrink to match, so Community and Mentorship
   ran into each other. Measured both ways: 326px wide overlaps, 350px does
   not. The frame keeps its gold edge and gives the padding back, and the
   nodes are pulled a little further in to cover what is left. */
@media (max-width: 767px) {
  .page-home .eco-frame {
    padding: 0.25rem;
    border-radius: 16px;
  }
  /* Wider, not narrower, for the reason above: Community and Mentorship are
     level with each other and the bottom of a 340px stage is where they are
     closest. 0.9 puts ~110px between their centres, which clears both words,
     and the outer pair (Education at nx 0.14, Business at 0.86) still finish
     well inside the frame — checked at 360, 390 and 430. */
  .page-home .eco-split .eco-map { --eco-squash: 0.9; }
}

/* The three-step path on one line beside the heading. At the inherited
   1.75rem the row needs 660px in a 621px column, so it broke as
   "The person > The leader" / "> The entrepreneur" — two steps and then a
   lone arrow, which reads as a mistake. Six per cent is all that was in it;
   this scales with the column so it still fits at 1280, where the column is
   narrowest, and never grows past its original size. */
@media (min-width: 1280px) {
  .page-home .eco-split-text .path { font-size: clamp(1.2rem, 1.6vw, 1.45rem); }
}

/* ==========================================================================
   Seven Pillars — a smaller diagram, heading level with the frame
   --------------------------------------------------------------------------
   The frame is capped rather than left to fill half the row, and the column
   is capped with it so there is no slack beside it. At 1440 the stage goes
   from 630px to roughly 400px.

   It can shrink this far because of what the labels actually need, measured
   rather than guessed: Community and Mentorship sit at the same height, so
   the binding constraint is the gap between their centres, which is
   0.36 x squash x stageWidth. At 0.78 squash that is 0.281 x width, and the
   two words need about 83px between centres — so anything above ~300px of
   stage clears them. 400px keeps a comfortable margin over that and over the
   node drift.

   align-items: start puts the heading's first line on the frame's top edge.
   With the three-step path gone the right column is only the heading, so the
   heading takes the size the column can afford — otherwise a short line of
   type sits beside a 400px graphic and the row reads as half empty.
   ========================================================================== */
@media (min-width: 1280px) {
  .page-home .eco-split {
    grid-template-columns: minmax(0, 27rem) minmax(0, 1fr);
    align-items: start;
  }
  .page-home .eco-split .eco-stage { min-height: 0; }
  .page-home .eco-split-text > h2 {
    font-size: clamp(2.8rem, 3.6vw, 4.2rem);
    line-height: 1.03;
    margin-top: -0.12em;      /* optical: the cap-height, not the line box */
  }
}

/* width:100% matters. The frame is a grid item, and `margin-inline: auto`
   (or justify-self: center) switches off stretch alignment, which leaves the
   item sized to its content — and its content is an aspect-ratio box with no
   intrinsic width, so the whole frame collapsed to its own padding: 42x42
   with the diagram at zero. A definite width gives the aspect-ratio
   something to resolve against, and max-width still caps it. */
.page-home .eco-frame {
  width: 100%;
  max-width: 27rem;
  justify-self: center;
}

/* ==========================================================================
   Pillar cards on phones: icon tile left, words right
   --------------------------------------------------------------------------
   Grid, not flex, and no new markup: the card's three children are a flat
   run of icon / h3 / p, so two named rows in one column pair put the title
   and the description beside the tile without wrapping them in a div.

   The tile keeps the gold it has on desktop but becomes a rounded square
   rather than a circle, and stops shrinking — flex-basis auto on a grid
   track plus min-width: 0 on the text column is what keeps a long word from
   pushing the card past the screen.

   Desktop is untouched: everything here is inside the phone query.
   ========================================================================== */
@media (max-width: 599px) {
  .page-home .eco-pillars > .panel {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    grid-template-areas:
      "icon title"
      "icon desc";
    align-items: start;
    column-gap: 0.9rem;
    row-gap: 0.3rem;
    text-align: left;
    padding: 1.05rem 1.1rem;
  }
  .page-home .eco-pillars > .panel .icon-line {
    grid-area: icon;
    align-self: start;
    width: 2.9rem;
    height: 2.9rem;
    margin: 0;
    border-radius: 14px;
  }
  .page-home .eco-pillars > .panel .icon-line svg { width: 1.35rem; height: 1.35rem; }
  .page-home .eco-pillars > .panel h3 {
    grid-area: title;
    margin-bottom: 0;
    font-size: 1.02rem;
    line-height: 1.3;
  }
  .page-home .eco-pillars > .panel p {
    grid-area: desc;
    font-size: 0.86rem;
    line-height: 1.6;
    /* long single words (URLs, compounds) break instead of widening the card */
    overflow-wrap: anywhere;
  }
}

/* The diagram is ~40% narrower than it was, so its labels have to be
   re-proportioned to it — they are fixed-size text and do not shrink with
   the box. Both values apply at EVERY width, because the frame is capped at
   27rem everywhere now, so the stacked layout has the same small stage as
   the split and the same constraint.

   The binding pair is Community and Mentorship: level with each other, so
   only horizontal spread separates them. At 0.64rem each word is about 68px
   wide, needing ~78px between centres; 0.95 squash gives 133px on a 390px
   stage and 106px on a 310px phone. The outer pair (Education, Business)
   still finish ~30px and ~17px inside the frame at those two sizes, which is
   why this is 0.95 and not 1.0. */
.page-home .eco-split .eco-map { --eco-squash: 0.95; }

/* Only from 1024 up. Below that the stylesheet already drops labels to
   0.6rem for the narrow screens, and this selector is more specific than
   that rule — so applied everywhere it QUIETLY ENLARGED the phone labels
   from 0.6 to 0.64 and put Community and Mentorship back into each other.
   The phones keep their own smaller size and simply take the extra spread. */
@media (min-width: 1024px) {
  .page-home .eco-split .eco-label {
    font-size: 0.64rem;
    letter-spacing: 0.12em;
  }
}

/* THE CORE HAS TO SCALE WITH THE STAGE, NOT THE VIEWPORT.
   .eco-core is clamp(11rem, 17vw, 14.5rem) — 232px at 1440 — which was
   right when the stage was 630px wide and is not when it is 390px: the
   opaque disc (.eco-core-ring, 100% of the core) grew to 59% of the stage
   and swallowed the inner end of every label. "OPPORTUNI…", "…DERSHIP",
   "EDUCATIO…" and "…USINESS" were all cut off by it.

   A percentage resolves against the stage, because the core is absolutely
   positioned inside it, so the disc now keeps the same share of the diagram
   at every size. The lettering inside is scaled to match — below the old
   size, but on a disc that is also smaller, so it reads the same. */
.page-home .eco-split .eco-core { width: 44%; }
.page-home .eco-split .eco-core-mark { font-size: clamp(1.6rem, 7.5cqw, 2.1rem); }
.page-home .eco-split .eco-core-full { font-size: 0.52rem; max-width: 7.6rem; letter-spacing: 0.16em; }
.page-home .eco-split .eco-core-face { padding: 0 0.6rem; gap: 0.35rem; }

/* ==========================================================================
   Six pillar cards: three across, two down
   --------------------------------------------------------------------------
   Grid rather than the wrapped flex row this used. Flex was chosen when there
   were seven cards and the last row had to be centred under the first; with
   six there is no short row, and grid is the better tool because its rows are
   equal height by default — every card in a row matches the tallest, which is
   what "same width and height" asks for and what flex-basis could not promise.
   ========================================================================== */
@media (min-width: 1024px) {
  .page-home .eco-pillars {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    /* 1fr, not the default auto: grid rows size to their own content, so the
       top row came out 323px against the bottom row's 249px purely because
       Personal Development has the longest description. Equal rows make all
       six boxes the same height, which is what the three-by-two asks for. */
    grid-auto-rows: 1fr;
    align-items: stretch;
  }
  .page-home .eco-pillars > .panel { flex: none; width: auto; }
}

@media (min-width: 600px) and (max-width: 1023px) {
  .page-home .eco-pillars {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: 1fr;
    align-items: stretch;
  }
  .page-home .eco-pillars > .panel { flex: none; width: auto; }
}

/* ==========================================================================
   Phones: the same horizontal card, tightened
   --------------------------------------------------------------------------
   The icon stays left and the words stay right; everything around them comes
   in. The description is the one thing NOT reduced far — 0.82rem with 1.55
   line-height is still comfortable reading, and shrinking it was the easy way
   to make the cards fit that would have cost the most.

   min-width: 0 on the text column is what actually prevents the overflow: a
   grid track's default is auto, which refuses to shrink below the longest
   word, and that is what pushes a card past the screen edge.
   ========================================================================== */
@media (max-width: 599px) {
  .page-home .eco-pillars { --pillar-gap: 0.7rem; }

  .page-home .eco-pillars > .panel {
    grid-template-columns: auto minmax(0, 1fr);
    column-gap: 0.75rem;
    row-gap: 0.2rem;
    padding: 0.8rem 0.85rem;
    border-radius: 16px;
  }
  .page-home .eco-pillars > .panel .icon-line {
    width: 2.35rem;
    height: 2.35rem;
    border-radius: 12px;
  }
  .page-home .eco-pillars > .panel .icon-line svg { width: 1.15rem; height: 1.15rem; }
  .page-home .eco-pillars > .panel h3 {
    font-size: 0.94rem;
    line-height: 1.25;
  }
  .page-home .eco-pillars > .panel p {
    font-size: 0.82rem;
    line-height: 1.55;
  }
}

/* ==========================================================================
   Global connection: the globe in its own column, and a shorter section
   --------------------------------------------------------------------------
   The canvas is a grid item now, so the absolute positioning and the two
   insets that went with it (top: 85px on desktop to clear the sticky header,
   top: 26% on phones) are all undone — a grid item cannot run under the
   header, so there is nothing left to clear.

   HEIGHT. The stage was min-height: 100svh, inherited from when it was a
   sticky panel inside a 380vh pin. Nothing is pinned any more, so it takes
   its height from its content plus padding, which is what makes the section
   compact: on a 900px-tall desktop it drops from a forced 900px to the
   height the two columns actually need.

   THE MASK has to be turned off here, and it needs this specificity to do
   it: the rule in transitions.css fades the bottom 12% of the canvas, which
   was right when the canvas was a full-bleed layer whose bottom was empty
   space, and clips the sphere now that the Earth fills its own box.
   transitions.css loads AFTER home.css, so an equally specific rule here
   would lose; .globe-copy in the selector is what wins it.
   ========================================================================== */
.page-home .globe-copy .globe-canvas {
  position: relative;
  inset: auto;
  top: auto;
  width: 100%;
  aspect-ratio: 1;
  align-self: center;
  -webkit-mask-image: none;
  mask-image: none;
}

.page-home .globe-pin.static .globe-stage {
  min-height: 0;
  padding-block: clamp(2.25rem, 4.5vw, 3.75rem);
}

.page-home .globe-copy { height: auto; align-items: center; }

@media (min-width: 1024px) {
  .page-home .globe-copy {
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
    column-gap: clamp(2rem, 4vw, 4rem);
    align-items: center;
  }
  .page-home .globe-copy .globe-canvas { grid-column: 2; grid-row: 1; }
  .page-home .globe-text { grid-column: 1; grid-row: 1; }
}

@media (max-width: 1023px) {
  /* Stacked: words, then globe. The padding-top that used to push the copy
     clear of a full-bleed canvas is gone with the canvas that needed it. */
  .page-home .globe-copy {
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    padding-top: 0;
    row-gap: clamp(1.5rem, 5vw, 2.5rem);
  }
  .page-home .globe-text { max-width: 34rem; }
  .page-home .globe-copy .globe-canvas {
    width: min(78vw, 24rem);
    margin-inline: auto;
  }
}

/* "The world is changing" keeps the position it always had: hard against the
   space the section above already provides. An inch of margin-top was tried
   here and taken back out — it is the stylesheet's own `margin: 0 auto ...`
   that applies again now, so the block sits where it did before. */

/* The one pillar emblem that is an image, not a line icon.
   The circle clips it, so the artwork's own rounded-square frame becomes the
   emblem's disc and sits inside the same gold ring the other five have. The
   source is square and the box is square, so `contain` fills it exactly and
   nothing is stretched in either direction. */
.page-home .eco-pillars > .panel .icon-line.icon-image {
  overflow: hidden;
  padding: 0;
}
.page-home .eco-pillars > .panel .icon-line.icon-image img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* ==========================================================================
   Pillar emblems as image tiles
   --------------------------------------------------------------------------
   Bigger, and a rounded square instead of a small circle: the emblem reads
   as a tile at the top of the card rather than a bullet beside the heading.

   NOTHING IS CROPPED OR STRETCHED. The five line icons are SVG and scale by
   definition; the one photographic emblem is square and sits in a square
   box under object-fit: contain, so both dimensions scale by the same
   factor and the whole image stays inside the frame. The circle used to
   clip that image's own rounded corners — a square frame has nothing to
   clip, which is the other reason this shape suits it.

   Mobile keeps the horizontal card asked for earlier (tile left, words
   right); only the tile's size and radius follow the new style there.
   ========================================================================== */
.page-home .eco-pillars > .panel .icon-line {
  width: clamp(4.5rem, 5.6vw, 5.5rem);
  height: clamp(4.5rem, 5.6vw, 5.5rem);
  border-radius: 18px;
  margin-bottom: clamp(1rem, 1.6vw, 1.35rem);
}
/* The glyph fills more of its tile. A percentage of the tile keeps both
   axes on the same factor, so every line icon grows at its own proportions
   and none is stretched. The image emblem is deliberately NOT touched here:
   it already fills its tile edge to edge at object-fit: contain, and the
   only way to make its artwork bigger would be to scale past the frame and
   crop its own border off, which the brief rules out. */
.page-home .eco-pillars > .panel .icon-line svg {
  width: 64%;
  height: 64%;
}
.page-home .eco-pillars > .panel .icon-line.icon-image {
  /* The artwork carries its own ground and border, so the tile's translucent
     gold fill would only show as a rim behind it. */
  background: transparent;
  border-color: rgba(212, 175, 55, 0.45);
}
.page-home .eco-pillars > .panel .icon-line.icon-image img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

@media (max-width: 599px) {
  .page-home .eco-pillars > .panel .icon-line {
    width: 3.1rem;
    height: 3.1rem;
    border-radius: 14px;
    margin-bottom: 0;
  }
  /* Grown in step with the desktop tiles — same share of a smaller tile,
     so the phone card reads the same way rather than keeping a small glyph
     in a frame that now looks empty next to it. */
  .page-home .eco-pillars > .panel .icon-line svg { width: 60%; height: 60%; }
}

/* ==========================================================================
   Pillar emblems: the supplied artwork, unframed and larger
   --------------------------------------------------------------------------
   All six cards now carry an image rather than a line icon, and each file
   already contains its own rounded-square frame and gold edge. The tile's
   border, fill and radius therefore come off — left on, they drew a second
   frame around a frame. What remains is a plain box the image sits in.

   NOT STRETCHED, NOT CROPPED: every file is square (1254x1254) and the box
   is square, so object-fit: contain scales both axes by one factor and the
   whole image stays inside. No overflow:hidden anywhere near it, so there
   is nothing that could clip an edge.

   Noticeably larger: 81px -> about 118px at 1440, and 50px -> 67px on a
   phone. The box grew rather than the artwork being pushed past its frame,
   which is the only way to gain size without cropping the file's own edge.
   ========================================================================== */
.page-home .eco-pillars > .panel .icon-line {
  /* Sized against the CARD, not the viewport: the brief is about how large
     the tile reads relative to its card, and a percentage here resolves
     against the panel's content box, so the proportion holds whether the
     card is 432px wide on a desktop or 367px at 1200.

     aspect-ratio with height:auto keeps the box square from the width
     alone — no second measurement to keep in step, and the square box is
     what lets object-fit: contain fill it with a square file at exactly
     1:1, so nothing is stretched and no edge is cut. */
  width: 62%;
  max-width: 15rem;
  height: auto;
  aspect-ratio: 1;
  border: 0;
  background: none;
  border-radius: 0;
  overflow: visible;
  padding: 0;
}

.page-home .eco-pillars > .panel .icon-line img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

@media (max-width: 599px) {
  /* The phone card is the horizontal one — emblem in a left column, words
     to the right — so a percentage of the card would swallow the text.
     A fixed box, raised in step with the desktop tiles. */
  .page-home .eco-pillars > .panel .icon-line {
    width: 5.25rem;
    height: 5.25rem;
    aspect-ratio: auto;
    max-width: none;
    border-radius: 0;
  }
}

/* ==========================================================================
   The six cards inside one screen
   --------------------------------------------------------------------------
   Two rows have to clear the header on a standard desktop, so the three
   things that set a card's height — the emblem, the vertical padding and the
   gap under the emblem — are all measured against viewport HEIGHT as well as
   the card's width. A width-only size cannot know whether it has 900px or
   768px to live in, and that is the dimension running out here.

   min(48%, 22vh) takes whichever is smaller: the card's proportion on a tall
   screen, the screen's budget on a short one. So the emblem stays prominent
   at 1440x900 (198px, about 46% of the card) and steps down by itself on a
   768-tall laptop rather than pushing the second row under the fold.

   Horizontal padding is untouched — the brief asks for vertical only — and
   the text, colours, order and the three-by-two grid are all unchanged.
   ========================================================================== */
.page-home .eco-pillars {
  --pillar-gap: clamp(0.75rem, 1.1vw, 1rem);
}

.page-home .eco-pillars > .panel {
  padding-block: clamp(0.75rem, 1.6vh, 1.35rem);
}

.page-home .eco-pillars > .panel .icon-line {
  /* 42, not 44: at 1280x800 the block cleared the fold by a single pixel,
     which is not a fit — a late-loading font or a scrollbar appearing would
     take it back. Two per cent of the card buys about 15px of headroom at
     the tightest size and costs 7px of emblem at the widest. */
  width: min(42%, 20vh);
  max-width: 12rem;
  margin-bottom: clamp(0.45rem, 1.1vh, 0.85rem);
}

/* The last of the height, and the only one that is not padding or emblem:
   the description's leading. 1.7 was set when the cards had room; at 1.55 a
   five-line paragraph on a 1280-wide card gives back about 10px, which is
   what puts the shorter laptops inside one screen. The words, the size and
   the colour are untouched — this is leading only, and 1.55 is still
   comfortable for a paragraph this short. */
.page-home .eco-pillars > .panel p {
  line-height: 1.55;
}

.page-home .eco-pillars > .panel h3 {
  margin-bottom: 0.45rem;
}

@media (max-width: 599px) {
  /* Phones scroll normally, so none of the above applies: the horizontal
     card keeps its own fixed emblem and its own padding. */
  .page-home .eco-pillars > .panel {
    padding-block: 0.8rem;
  }
  .page-home .eco-pillars > .panel .icon-line {
    width: 5.25rem;
    max-width: none;
    margin-bottom: 0;
  }
}

/* ==========================================================================
   Section call-to-action
   --------------------------------------------------------------------------
   One centred Reserve button, used at the foot of several sections. It only
   positions the button — .btn / .btn-primary / .btn-lg supply every visual
   detail, so it matches the hero's button and follows it if that ever
   changes. No width is forced on the link, so the button keeps its own
   intrinsic size on a phone rather than stretching edge to edge.
   ========================================================================== */
.page-home .section-cta {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.7rem, 1.2vw, 0.95rem);
  margin-top: clamp(1.75rem, 3.2vw, 2.75rem);
  /* Where the CTA follows a full-bleed rail rather than content inside .wrap,
     it still needs the page's gutter so it cannot sit under the edge. */
  padding-inline: clamp(1.25rem, 4vw, 2rem);
}

/* THE PILL. .btn is 999px site-wide but .page-home overrides it to 12px for
   this page, which is why the hero has its own rule restoring the pill. This
   is the same restoration for the section buttons, so all of them match. */
.page-home .section-cta .btn,
.page-home .closing-action .btn {
  border-radius: 999px;
}

/* The orientation button sits in .closing-action, so it needs the same host
   and spacing treatment the section CTAs get. */
.page-home .closing-action .btn-orbit-host { display: inline-flex; border-radius: 999px; }
.page-home .closing-action .cta-window { margin-top: clamp(0.6rem, 1.1vw, 0.9rem); }

/* The host must hug the button exactly: .btn-orbit is inset:0 against it, so
   the dot's path IS the button's outline. A bare <span> is inline and would
   give the orbit a box that does not match. */
.page-home .section-cta .btn-orbit-host {
  display: inline-flex;
  border-radius: 999px;
}

/* The countdown under each button. Same wording and the same clock as the
   hero's — reservation-window.js drives every [data-reservation-window]
   mount — in a single quiet line rather than the hero's glass panel, so it
   reads as a footnote to the button and not a second component. */
.page-home .cta-window {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0;
  padding: 0.3rem 0.95rem;
  border: 1px solid rgba(212, 175, 55, 0.22);
  border-radius: 999px;
  background: rgba(212, 175, 55, 0.05);
  font-size: 0.64rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.62);
  transition: opacity 320ms ease;
}

.page-home .cta-window-time {
  font-family: var(--font-display, inherit);
  font-size: 0.86rem;
  letter-spacing: 0.06em;
  color: var(--pcp-gold);
  font-variant-numeric: tabular-nums;
}

.page-home .cta-window-colon { opacity: 0.6; margin-inline: 0.05em; }

/* THE GAP UNDER THE FIRST CTA. The gallery's button and the "Members doing
   the business" heading were reading as one block. The button does not move:
   the heading and everything after it in that wrap come down instead. */
.page-home .section-cta + .wrap {
  margin-top: clamp(2rem, 2.5vw, 2.25rem);
}

/* ==========================================================================
   Three sections compressed to one viewport
   --------------------------------------------------------------------------
   Each had to lose height without losing content, so the levers are the same
   three in every case: the section's own vertical padding, the gaps between
   its blocks, and the one element that dominates its height — the globe, the
   video cards, the list rows. Sizes that dominate are tied to viewport
   HEIGHT, because that is the dimension running out.
   ========================================================================== */

/* ---- Global Connection ---- */
.page-home .globe-pin.static .globe-stage {
  padding-block: clamp(1.25rem, 2.4vw, 2rem);
}
/* The globe is the tall element. Capping it against vh is what lets the
   heading, the country list, the globe and the button share one screen. */
.page-home .globe-copy .globe-canvas {
  max-width: min(34rem, 54vh);
  margin-inline: auto;
}
.page-home .globe-section .section-cta {
  margin-top: clamp(1rem, 1.8vw, 1.5rem);
}

/* ---- Members doing the business ----
   Deliberately empty. This section was compressed to fit one viewport and
   that has been undone: the rail's card width (--biz-w), the gap above the
   rail, the gap down to its button and the head's rhythm are all back to
   the stylesheet's original values. The button, its orbiting dot and its
   countdown stay — they are not sizing — and so does the 32-40px gap added
   earlier between the gallery's button and this heading, which was its own
   separate request. */

/* ---- Business ---- */
.page-home section[aria-labelledby="business-title"] {
  padding-block: clamp(0.75rem, 1.8vh, 1.5rem);
}
/* The heading stack's own rhythm. mt-6 / mt-7 were set for a section with
   room; the words and their order are untouched, only the air between. */
.page-home section[aria-labelledby="business-title"] h2 { margin-top: clamp(0.5rem, 1vh, 0.9rem); }
.page-home section[aria-labelledby="business-title"] .lede { margin-top: clamp(0.65rem, 1.3vh, 1.05rem); }
.page-home section[aria-labelledby="business-title"] .lede + .reveal { margin-top: clamp(0.7rem, 1.4vh, 1.15rem); }
/* Top of the list level with the top of the heading, instead of the two
   columns being centred against each other. */
.page-home section[aria-labelledby="business-title"] .grid {
  align-items: start;
}
.page-home section[aria-labelledby="business-title"] li {
  padding-block: clamp(0.4rem, 1.05vh, 0.8rem);
}
/* "01" a step down — it was competing with the row's own heading. */
.page-home section[aria-labelledby="business-title"] li .n {
  font-size: 1.05rem;
  line-height: 1.5;
}
.page-home section[aria-labelledby="business-title"] .section-cta {
  margin-top: clamp(0.75rem, 1.4vh, 1.25rem);
}
