/* ===== Opener: v2/src/opener.css =====
   Base rules give a complete static hero and statement. That is what visitors without script,
   or with reduced motion, get. Everything scroll-driven is scoped under html.opener-on, which a
   head script adds only when the browser can run the effect, and which opener.js removes again
   if anything fails. */

:root{--night:#0f1512;--night-2:#161e19;--nav-h:85px}
@media(max-width:850px){:root{--nav-h:68px}}

/* ---------- base: a full-screen hero, then the statement as a normal section ---------- */
.stage{position:relative;background:#fff}
.sticky{display:grid;grid-template-columns:100%;background:var(--night)}
.sticky>.wall,.sticky>.open-scrim,.sticky>.open-copy,.sticky>.cue{grid-row:1;grid-column:1}
.sticky>.statement{grid-row:2;grid-column:1}
.ground{display:none}
.wall{position:relative;height:100vh;height:100svh;overflow:hidden}
.tile{margin:0;overflow:hidden;background:var(--night-2)}
.tile video,.tile img{display:block;width:100%;height:100%;object-fit:cover}
.hero-tile{position:absolute;inset:0}
.open-scrim{background:rgba(10,14,11,.42);pointer-events:none}
.open-copy{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:34px;min-height:100vh;min-height:100svh;padding:48px 24px;text-align:center;pointer-events:none}
.open-lockup{display:flex;flex-direction:column;align-items:center;gap:14px;color:#fff}
.hero-mark{width:64px;height:76px;display:block}
.open-word{display:flex;flex-direction:column;font-family:var(--font-brand);font-weight:850;font-size:.95rem;line-height:1.1;letter-spacing:.2em;text-transform:uppercase}
.open-copy h1{margin:0;max-width:none;color:#fff;font-family:var(--font-brand);font-weight:400;font-size:clamp(2rem,4.6vw,3.9rem);line-height:1.08;letter-spacing:-.015em;text-shadow:0 2px 28px rgba(0,0,0,.35)}
.open-copy h1 .sharpen{font-style:normal;font-weight:850}
.cue{display:none}
.statement{background:#fff;color:var(--ink);text-align:center;padding:96px 24px}
.statement-inner{max-width:900px;margin:0 auto}
.statement .disc{display:block;width:112px;height:112px;margin:0 auto 40px}
.statement h2{margin:0 auto;font-family:var(--font-brand);font-weight:850;font-size:clamp(2.2rem,6.2vw,5.4rem);line-height:1.02;letter-spacing:-.03em;max-width:16ch;text-wrap:balance}
.statement h2 em{display:block;font-style:normal;color:var(--forest)}
.statement-after p{margin:28px auto 0;max-width:48ch;color:var(--muted);font-size:1.05rem;line-height:1.7}
.statement-actions{display:flex;gap:12px;flex-wrap:wrap;justify-content:center;margin-top:30px}
.statement-after .brief-link{margin-top:20px}
@media(max-width:560px){.statement-actions .button{padding:12px 16px;font-size:.8rem}}

/* the nav stays compact on small screens in both modes */
@media(max-width:850px){
  #site-header .nav-wrap{flex-wrap:nowrap;padding:0;min-height:68px}
  #site-header .nav-links{width:auto;gap:14px}
  #site-header .nav-links>a:not(.button):not([href="pricing.html"]){display:none}
  #site-header .nav-links .button{display:inline-flex}
}

/* ---------- opener-on: the scroll-driven zoom ---------- */
/* The stage scrolls through 520 large-viewport heights: 360 of motion, then a hold on the finished statement. The sticky frame is one large viewport tall,
   so the mobile URL bar never resizes it; copy sits in a small-viewport box so it is never hidden
   behind browser chrome. */
.opener-on .stage{height:520vh;height:520lvh}
.opener-on .sticky{display:block;position:sticky;top:0;height:100vh;height:100lvh;overflow:hidden}
.opener-on .ground{display:block;position:absolute;inset:0;background:#fff}
.opener-on .wall{position:absolute;inset:0;height:auto;contain:strict}
/* every tile is placed and sized by opener.js at its true on-screen size; nothing is scaled up */
.opener-on .tile{position:absolute;left:0;top:0;width:0;height:0;border-radius:12px;contain:strict}
.opener-on .tile[hidden]{display:none}
.opener-on .hero-tile{inset:auto}
.opener-on .tile.still img{animation:drift 16s ease-in-out infinite alternate}
@keyframes drift{from{transform:scale(1.04) translate(-1.5%,-1%)}to{transform:scale(1.16) translate(1.5%,1.5%)}}
.opener-on .open-scrim{position:absolute;inset:0}
.opener-on .open-copy{position:absolute;left:0;right:0;top:0;height:100vh;height:100svh;min-height:0;padding:0 24px;transform-origin:50% 50%}
.opener-on .open-copy h1 .sharpen{font-weight:400}
/* the brand's sharpen: the phrase comes into focus along Urbanist's weight axis once the face has loaded */
.opener-on.sharpen-go .open-copy h1 .sharpen{animation:sharpen 5600ms cubic-bezier(.16,1,.3,1) 700ms both}
@keyframes sharpen{from{font-weight:400;opacity:.7}to{font-weight:850;opacity:1}}
.opener-on .cue{display:flex;position:absolute;left:0;right:0;top:calc(100vh - 56px);top:calc(100svh - 56px);justify-content:center;align-items:center;gap:10px;font-size:.72rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:#fff;opacity:.85;pointer-events:none;transition:opacity .3s}
.opener-on .cue .icon{animation:nudge 1.6s ease-in-out infinite}
@keyframes nudge{0%,100%{transform:translateY(0)}50%{transform:translateY(5px)}}

/* the statement lands in the small-viewport box, between the nav and the bottom edge */
.opener-on .statement{position:absolute;left:0;right:0;top:0;height:100vh;height:100svh;display:flex;align-items:center;justify-content:center;padding:var(--nav-h) 24px 20px;background:transparent;opacity:0;visibility:hidden;pointer-events:none}
.opener-on .statement-inner{max-height:100%}
.opener-on .statement .disc{width:12vh;width:clamp(56px,12svh,112px);height:12vh;height:clamp(56px,12svh,112px);margin-bottom:4vh;margin-bottom:clamp(16px,4svh,40px)}
.opener-on .statement h2{font-size:clamp(1.9rem,min(6.2vw,7.4vh),5.4rem);font-size:clamp(1.9rem,min(6.2vw,7.4svh),5.4rem)}
.opener-on .statement h2 .ch{visibility:hidden}
.opener-on .statement h2 .ch.on{visibility:visible}
/* the caret is one mark drawn over the headline, placed from the current letter's measured position.
   It sits outside the text runs, so it can't break kerning or re-flow a line in any engine. */
.opener-on #typed{position:relative}
.opener-on #typed.caret-on::after{content:"";position:absolute;left:calc(var(--caret-x,0px) + .05em);top:calc(var(--caret-y,0px) + .1em);width:.07em;height:calc(var(--caret-h,1em) - .18em);background:var(--ink);pointer-events:none;animation:blink 1s steps(1) infinite}
.opener-on #typed.caret-on.caret-start::after{left:calc(var(--caret-x,0px) - .12em)}
@keyframes blink{0%,49%{opacity:1}50%,100%{opacity:0}}
.opener-on .statement-after{opacity:0;visibility:hidden;transition:opacity .9s ease,visibility 0s .9s}
/* inherit, never visible: a child set to visible would show (and take focus) inside a hidden statement */
.opener-on .statement-after.show{opacity:1;visibility:inherit;transition:opacity .9s ease,visibility 0s}
.opener-on .statement-after p{margin-top:clamp(14px,3vh,28px);margin-top:clamp(14px,3svh,28px)}
.opener-on .statement-actions{margin-top:clamp(16px,3.4vh,30px);margin-top:clamp(16px,3.4svh,30px)}
/* short screens keep the line and the way in; the mark and the lede step aside */
@media(max-height:620px){
  .opener-on .statement .disc,.opener-on .statement-after p{display:none}
}
@media(max-height:460px){
  .opener-on .statement h2{max-width:26ch;font-size:clamp(1.4rem,8vh,2.4rem);font-size:clamp(1.4rem,8svh,2.4rem)}
  .opener-on .statement-after .brief-link{display:none}
  .opener-on .statement-actions{margin-top:14px}
  .opener-on .open-copy{gap:16px}
  .opener-on .hero-mark{width:40px;height:48px}
  .opener-on .open-lockup{gap:8px}
  .opener-on .open-copy h1{font-size:clamp(1.5rem,7.6vh,2.6rem);font-size:clamp(1.5rem,7.6svh,2.6rem)}
}

/* the nav waits until the opener has played out; keyboard focus brings it forward at any point */
.opener-on #site-header{position:fixed;top:0;left:0;right:0;z-index:20;opacity:0;pointer-events:none;background:transparent;border-bottom:1px solid transparent;transition:background .3s,border-color .3s}
.opener-on #site-header.solid{background:rgba(255,255,255,.96);border-bottom-color:var(--line)}
.opener-on #site-header:focus-within{opacity:1!important;pointer-events:auto!important;background:rgba(255,255,255,.96)}
/* Chris's fixed mobile call to action follows the nav, and the statement keeps clear of it */
.opener-on .mobile-booking{opacity:0;pointer-events:none}
.opener-on .mobile-booking:focus-within{opacity:1!important;pointer-events:auto!important}
@media(max-width:560px){.opener-on .statement{padding-bottom:calc(76px + env(safe-area-inset-bottom,0px))}}
