/* Satoshi, self-hosted. Previously fetched from api.fontshare.com on every page load,
   which made the typeface depend on a third party being reachable. When it was not —
   offline, a firewall, a blocker — text fell back to Helvetica/Arial, and the different
   letter widths pushed copy out of boxes that had been tuned to fit it. Serving the four
   faces from this folder removes that failure mode entirely. url() here resolves against
   the stylesheet, which sits beside index.html, so these paths are correct. */
@font-face{font-family:'Satoshi';src:url(assets/fonts/satoshi-300.5481680c.woff2) format('woff2');font-weight:300;font-style:normal;font-display:swap}
@font-face{font-family:'Satoshi';src:url(assets/fonts/satoshi-400.d4db658f.woff2) format('woff2');font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:'Satoshi';src:url(assets/fonts/satoshi-500.cd790237.woff2) format('woff2');font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:'Satoshi';src:url(assets/fonts/satoshi-700.71a6023c.woff2) format('woff2');font-weight:700;font-style:normal;font-display:swap}

:root{
  --black:#050505;
  --pure:#000;
  --champagne:#F1E8D7;
  --champagne-2:#E7DAC4;
  --silver:#ADA69B;
  --muted:rgba(241,232,215,.60);
  --hair:rgba(241,232,215,.16);
  --font:"Satoshi","Helvetica Neue",Arial,sans-serif;
  --ease:cubic-bezier(.19,1,.22,1);
  --img-crowdchamp:url(assets/img/crowd-champagne.0953d2be.webp);
  --img-star:url(assets/img/star.be46766d.webp);
  --img-crowdwarm:url(assets/img/crowd-warm.701de01e.webp);
  --img-arch:url(assets/img/architecture.eefae259.webp);
  --img-immersive:url(assets/img/immersive.282a8185.webp);
  --img-hospitality:url(assets/img/hospitality.e7061931.webp);
  --img-crowdmono:url(assets/img/crowd-mono.51367cfd.webp);
  --img-futurewarm:url(assets/img/future-warm.dfda1c7b.webp);
  --img-founder:url(assets/img/founder.2f6d6115.webp);
  --p-emotion:url(assets/img/pillar-emotion.7019a113.webp);
  --p-atmosphere:url(assets/img/pillar-atmosphere.b40b113b.webp);
  --p-connection:url(assets/img/pillar-connection.3c43833f.webp);
  --p-culture:url(assets/img/pillar-culture.a85f2bf1.webp);
  --p-entertainment:url(assets/img/pillar-entertainment.c6fd6b55.webp);
  --p-technology:url(assets/img/pillar-technology.53c5d031.webp);
  --p-movement:url(assets/img/pillar-movement.5402c686.webp);
  --p-memory:url(assets/img/pillar-memory.83a0a143.webp);
  --logo-loft:url(assets/img/logo-loft.d0fefc4e.webp);
  --logo-vybe:url(assets/img/logo-vybe.c785ca9a.webp);
  --logo-evento:url(assets/img/logo-evento.3dbbcc25.webp);
}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{background:var(--black);color:var(--champagne);font-family:var(--font);-webkit-font-smoothing:antialiased;overflow-x:hidden;overflow-y:hidden}
body.entered{overflow-y:auto}
::selection{background:var(--champagne);color:#000}
img{display:block;max-width:100%}

.grain{position:fixed;inset:-50%;z-index:60;pointer-events:none;opacity:.045;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  animation:grain 6s steps(6) infinite}
@keyframes grain{0%{transform:translate(0,0)}20%{transform:translate(-3%,2%)}40%{transform:translate(2%,-3%)}60%{transform:translate(-2%,-2%)}80%{transform:translate(3%,2%)}100%{transform:translate(0,0)}}

.progress{position:fixed;top:0;left:0;height:2px;width:0;background:linear-gradient(90deg,var(--champagne),var(--champagne-2));z-index:70}

/* spotlight cursor */
#spotlight{position:fixed;top:0;left:0;width:600px;height:600px;border-radius:50%;pointer-events:none;z-index:40;
  transform:translate3d(-1000px,-1000px,0);will-change:transform;opacity:0;transition:opacity .6s var(--ease);mix-blend-mode:screen;
  background:radial-gradient(circle,rgba(241,232,215,.13),rgba(241,232,215,.05) 36%,transparent 68%)}
body.entered #spotlight{opacity:1}
@media(hover:none),(prefers-reduced-motion:reduce){#spotlight{display:none}}

/* ---------------- interactive intro gate ---------------- */
/* -webkit-touch-callout:none is load-bearing, not cosmetic. The gate asks for a 1100ms
   press on an <img>, which is exactly iOS's "Save Image / Copy" long-press gesture — without
   this Safari interrupts the hold with its own share sheet. */
#intro{position:fixed;inset:0;z-index:100;background:var(--pure);overflow:hidden;
  display:flex;align-items:center;justify-content:center;cursor:pointer;-webkit-user-select:none;user-select:none;
  -webkit-touch-callout:none;
  transition:opacity .8s var(--ease),transform 1.3s cubic-bezier(.5,0,.1,1),filter 1s var(--ease);touch-action:none}
#intro .logo,#intro .content{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;pointer-events:none}
#intro.gone{opacity:0;transform:scale(1.6);filter:blur(8px);pointer-events:none}
#intro .introbg{position:absolute;inset:-6%;z-index:0}
#intro .introbg .frame{position:absolute;inset:0;background-size:cover;background-position:center;opacity:0;
  filter:blur(17px) brightness(.42) saturate(.92);animation:loop 24s infinite}
#intro .introbg .f1{background-image:var(--img-crowdchamp);animation-delay:0s}
#intro .introbg .f2{background-image:var(--img-arch);animation-delay:6s}
#intro .introbg .f3{background-image:var(--img-crowdwarm);animation-delay:12s}
#intro .introbg .f4{background-image:var(--img-immersive);animation-delay:18s}
#intro .introscrim{position:absolute;inset:0;z-index:1;background:radial-gradient(circle at 50% 48%,rgba(5,5,5,.5),rgba(5,5,5,.9) 75%)}
#intro .glow{position:absolute;z-index:2;width:560px;height:560px;left:0;top:0;
  transform:translate3d(calc(var(--mx,50vw) - 280px),calc(var(--my,50vh) - 280px),0);
  background:radial-gradient(circle,rgba(241,232,215,.10),transparent 62%);pointer-events:none;mix-blend-mode:screen;transition:opacity .5s}
#intro .content{position:relative;z-index:3;display:flex;flex-direction:column;align-items:center;gap:38px;text-align:center}
/* Required, not cosmetic. Every <img> carries width/height attributes so the browser
   can reserve the right space before the file arrives (no content shifting on load).
   The catch: an attribute still supplies any axis CSS leaves unset, so a rule setting
   only `height` would take width=1912 from the attribute and stretch the wordmark.
   Releasing BOTH axes here means the intrinsic aspect ratio always governs, while any
   rule that explicitly sets a dimension still wins on specificity. Do not remove. */
img{width:auto;height:auto}
#intro .logo{width:clamp(180px,22vw,250px);height:auto;opacity:0;animation:logoIn 1.3s var(--ease) .35s forwards;will-change:transform,filter}
#intro .hold{display:flex;flex-direction:column;align-items:center;gap:18px;opacity:0;animation:fadeUp 1.1s var(--ease) .95s forwards}
#intro .track{width:min(260px,60vw);height:1px;background:var(--hair);position:relative;overflow:hidden}
#intro .fill{position:absolute;inset:0;background:linear-gradient(90deg,var(--champagne-2),var(--champagne));transform:scaleX(0);transform-origin:left;will-change:transform}
#intro .prompt{font-size:11px;letter-spacing:.34em;text-transform:uppercase;color:var(--silver)}
#intro .prompt b{color:var(--champagne);font-weight:500}
#intro .prompt.idle{animation:pulse 2.6s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:.55}50%{opacity:1}}
@keyframes logoIn{to{opacity:1}}

/* ---------------- nav ---------------- */
/* safe-area insets keep the bar clear of the notch in landscape; they resolve to 0 on
   any device without one, so the desktop box is unchanged. */
nav{position:fixed;top:0;left:0;right:0;z-index:50;display:flex;align-items:center;justify-content:space-between;
  padding:26px clamp(20px,5vw,66px);
  padding-left:max(clamp(20px,5vw,66px),env(safe-area-inset-left));
  padding-right:max(clamp(20px,5vw,66px),env(safe-area-inset-right));
  transition:background .4s,padding .4s var(--ease),border-color .4s}
/* -webkit- twin is required: Safari only shipped the unprefixed property in v18, so
   without this the nav is a flat dark bar on iOS 17 and earlier. */
nav.scrolled{background:rgba(5,5,5,.72);-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);padding-top:18px;padding-bottom:18px;border-bottom:1px solid var(--hair)}
.brand{height:30px;opacity:0;transform:translateY(-10px)}
.brand img{height:100%}
.menu{display:flex;align-items:center;gap:clamp(18px,2.4vw,40px);opacity:0;transform:translateY(-10px)}
.menu a{color:var(--champagne);text-decoration:none;font-size:12px;letter-spacing:.2em;text-transform:uppercase;font-weight:400;position:relative;padding:5px 0}
.menu a:not(.cta)::after{content:"";position:absolute;left:0;bottom:0;height:1px;width:0;background:var(--champagne);transition:width .45s var(--ease)}
.menu a:not(.cta):hover::after{width:100%}
.menu .cta{border:1px solid var(--hair);border-radius:100px;padding:10px 22px;transition:.4s var(--ease)}
.menu .cta:hover{background:var(--champagne);color:#000;border-color:var(--champagne)}
.sndbtn{display:inline-flex;align-items:center;justify-content:center;background:none;border:none;cursor:pointer;color:var(--champagne);padding:4px;opacity:.78;transition:opacity .3s;-webkit-tap-highlight-color:transparent}
.sndbtn:hover{opacity:1}
.sndbtn svg{width:17px;height:17px;display:block}
.sndbtn .wv,.sndbtn .sl{transition:opacity .3s}
.sndbtn .sl{opacity:0}
.sndbtn.muted .wv{opacity:0}
.sndbtn.muted .sl{opacity:1}
.ready .brand,.ready .menu{animation:navIn 1s var(--ease) forwards}
.ready .menu{animation-delay:.15s}
@keyframes navIn{to{opacity:1;transform:none}}
@media(max-width:760px){.menu a:not(.cta){display:none}}

/* ---------------- hero ---------------- */
/* 100vh first as a fallback: svh needs iOS 15.4+, and a browser that doesn't know the
   unit discards the whole declaration — which would leave the hero with no height at all. */
.hero{position:relative;height:100vh;height:100svh;overflow:hidden;display:flex;flex-direction:column;justify-content:flex-end}
.hero-bg{position:absolute;inset:-8% 0;z-index:0;will-change:transform;
  /* instant-paint stand-in: approximates the plume so the hero never flashes empty */
  background:radial-gradient(60% 55% at 62% 52%,rgba(241,232,215,.09),transparent 72%)}
/* wrapper handles the one-time reveal; the two videos inside cross-fade forever */
.hero-vids{position:absolute;inset:0;opacity:0;transition:opacity 1.4s var(--ease)}
.hero-vids.ready{opacity:1}
.hero-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* portrait crops a 16:9 frame hard — bias toward the denser side of the plume */
@media(max-width:760px){.hero-video{object-position:68% center}}
@keyframes loop{0%{opacity:0}4%{opacity:1}25%{opacity:1}29%{opacity:0}100%{opacity:0}}
.hero-scrim{position:absolute;inset:0;z-index:1;
  background:linear-gradient(180deg,rgba(5,5,5,.55) 0%,rgba(5,5,5,.15) 32%,rgba(5,5,5,.25) 55%,rgba(5,5,5,.82) 88%,var(--black) 100%),
             radial-gradient(120% 80% at 50% 40%,transparent 40%,rgba(5,5,5,.5) 100%)}
.hero-inner{position:relative;z-index:2;padding:0 clamp(20px,5vw,66px) clamp(56px,10vh,120px);will-change:transform,opacity}

.kicker{display:flex;align-items:center;gap:15px;margin-bottom:26px;font-size:11px;letter-spacing:.34em;text-transform:uppercase;color:var(--silver);opacity:0}
.kicker .ln{width:clamp(46px,7vw,92px);height:1px;background:var(--hair)}
.ready .kicker{animation:fadeUp 1.1s var(--ease) .55s forwards}

h1{font-weight:400;line-height:1.08;letter-spacing:-.025em;font-size:clamp(44px,8.6vw,150px);color:var(--champagne);max-width:16ch}
h1 .line{display:block;padding-bottom:.02em}
h1 .line>span{display:block}
h1 .word{display:inline-block}
h1 .word.b{font-weight:700}
h1 .ch{display:inline-block;transform:translate(var(--tx,0),var(--ty,0)) rotate(var(--rot,0deg)) scale(var(--sc,1));opacity:0;will-change:transform,opacity}
.ready h1 .ch{transform:none;opacity:1;transition:transform 1.1s cubic-bezier(.16,1,.3,1) var(--dly,0s),opacity .6s ease var(--dly,0s)}
h1 em{font-style:normal;font-weight:700}

.sub{margin-top:30px;max-width:52ch;font-size:clamp(15px,1.35vw,19px);line-height:1.62;color:var(--muted);font-weight:400;opacity:0}
.ready .sub{animation:fadeUp 1.1s var(--ease) 1.1s forwards}

/* bottom clears the home indicator on notched iPhones; 26px everywhere else */
.herofoot{position:absolute;z-index:2;bottom:calc(26px + env(safe-area-inset-bottom));
  left:max(clamp(20px,5vw,66px),env(safe-area-inset-left));
  right:max(clamp(20px,5vw,66px),env(safe-area-inset-right));
  display:flex;align-items:flex-end;justify-content:space-between;opacity:0}
.ready .herofoot{animation:fadeUp 1.1s var(--ease) 1.35s forwards}
.scrollcue{display:flex;flex-direction:column;align-items:flex-end;gap:12px;font-size:11px;letter-spacing:.26em;text-transform:uppercase;color:var(--silver);text-align:right}
.scrollcue .bar{width:1px;height:46px;background:linear-gradient(var(--champagne),transparent);animation:drop 2s var(--ease) infinite}
.herofoot .tag{font-size:11px;letter-spacing:.26em;text-transform:uppercase;color:var(--silver);text-align:left}
@keyframes drop{0%{transform:scaleY(0);transform-origin:top}45%{transform:scaleY(1);transform-origin:top}55%{transform-origin:bottom}100%{transform:scaleY(0);transform-origin:bottom}}

/* ---------------- statement ---------------- */

.reveal{opacity:0;transform:translateY(42px);transition:opacity 1.1s var(--ease),transform 1.1s var(--ease)}
.reveal.in{opacity:1;transform:none}.reveal.d2{transition-delay:.24s}

@keyframes fadeUp{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes explode{0%{transform:scale(1.65);opacity:0;filter:blur(18px)}55%{opacity:1}100%{transform:scale(1);opacity:1;filter:blur(0)}}

/* =================== full site sections =================== */
.sec{position:relative;z-index:5;padding:clamp(62px,10.5vh,132px) clamp(20px,5vw,66px);background:var(--black)}
.sec .wrap{max-width:1240px;margin:0 auto;position:relative;z-index:2}
.sec-head{margin-bottom:clamp(44px,8vh,88px)}
.eyebrow2{font-size:11px;letter-spacing:.34em;text-transform:uppercase;color:var(--silver);display:flex;align-items:center;gap:14px;margin-bottom:24px}
.eyebrow2 .ln{width:56px;height:1px;background:var(--hair)}
.sec-title{font-weight:400;line-height:1.05;letter-spacing:-.02em;font-size:clamp(30px,5vw,76px);color:var(--champagne);max-width:20ch}
.sec-title b{font-weight:700}

/* reveal + stagger */
.stagger>*{opacity:0;transform:translateY(38px);transition:opacity .9s var(--ease),transform .9s var(--ease)}
.stagger.in>*{opacity:1;transform:none}
.stagger.in>*:nth-child(1){transition-delay:0s}.stagger.in>*:nth-child(2){transition-delay:.06s}
.stagger.in>*:nth-child(3){transition-delay:.12s}.stagger.in>*:nth-child(4){transition-delay:.18s}
.stagger.in>*:nth-child(5){transition-delay:.24s}.stagger.in>*:nth-child(6){transition-delay:.3s}
.stagger.in>*:nth-child(7){transition-delay:.36s}.stagger.in>*:nth-child(8){transition-delay:.42s}

/* buttons — each with its own interaction */
.btn{position:relative;display:inline-flex;align-items:center;gap:12px;padding:16px 30px;border-radius:100px;
  font-size:12px;letter-spacing:.18em;text-transform:uppercase;font-weight:500;color:var(--champagne);
  border:1px solid var(--hair);background:transparent;cursor:pointer;text-decoration:none;overflow:hidden;
  -webkit-tap-highlight-color:transparent;transition:color .45s var(--ease),border-color .45s var(--ease)}
.btn>*{position:relative;z-index:2}
.btn:active{transform:scale(.97)}.btn--draw .b{bottom:0;right:0;height:1px;width:0}.btn--draw .r{right:0;top:0;width:1px;height:0}.btn--draw:hover .l,.btn--draw:hover .r{height:100%}

/* era (what is EI) */
.era{overflow:hidden}
.era .bg{position:absolute;inset:-12% 0;z-index:0;background:var(--img-star) center/cover;opacity:1;will-change:transform}
.era .scrim{position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,var(--black),rgba(5,5,5,.55) 28%,rgba(5,5,5,.55) 72%,var(--black)),linear-gradient(90deg,rgba(5,5,5,.9),rgba(5,5,5,.35))}
.era .lead{font-weight:400;line-height:1.16;letter-spacing:-.015em;font-size:clamp(24px,3.8vw,54px);color:var(--champagne);max-width:20ch}
.era .lead .dim{color:var(--silver)}
.era .lead b{font-weight:700}
.era .cols{margin-top:44px;display:grid;grid-template-columns:1fr 1fr;gap:clamp(24px,4vw,60px);max-width:1000px}
@media(max-width:760px){.era .cols{grid-template-columns:1fr}}
.era .cols p{font-size:clamp(14px,1.2vw,17px);line-height:1.65;color:var(--muted)}
.era .cols p b{color:var(--champagne);font-weight:500}

/* pillars */
.grid-pillars{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
@media(max-width:960px){.grid-pillars{grid-template-columns:repeat(2,1fr)}}
@media(max-width:520px){.grid-pillars{grid-template-columns:1fr}}
.pcard{position:relative;aspect-ratio:1/1;border:1px solid var(--hair);overflow:hidden;display:flex;flex-direction:column;justify-content:flex-end;padding:22px;background:#0b0a0c;transition:border-color .5s var(--ease)}
.pcard .pimg{position:absolute;inset:0;z-index:0;background-size:cover;background-position:center;filter:grayscale(.12);transform:scale(1.02);transition:transform .85s var(--ease),filter .6s}
.pcard .pscrim{position:absolute;inset:0;z-index:1;background:linear-gradient(0deg,rgba(5,5,5,.92),rgba(5,5,5,.2) 52%,rgba(5,5,5,.42));transition:opacity .5s}
.pcard .pn{position:absolute;top:20px;left:22px;z-index:2;font-size:11px;letter-spacing:.2em;color:var(--silver)}
.pcard h3{position:relative;z-index:2;font-size:clamp(19px,1.7vw,23px);font-weight:500;color:var(--champagne)}
.pcard p{position:relative;z-index:2;font-size:13px;line-height:1.5;color:var(--muted);margin-top:8px}
.pcard:hover{border-color:rgba(241,232,215,.5)}
.pcard:hover .pimg{transform:scale(1.09);filter:grayscale(0)}
.pcard:hover .pscrim{opacity:.85}

/* list (industries) */
.list{border-top:1px solid var(--hair)}
.li{position:relative;display:grid;grid-template-columns:64px 1fr;gap:4px 22px;align-items:baseline;padding:11px 10px;border-bottom:1px solid var(--hair);transition:background .5s var(--ease)}
.li .n{font-size:12px;letter-spacing:.2em;color:var(--silver)}
.li h3{grid-column:2;font-size:clamp(27px,3.1vw,46px);font-weight:400;color:var(--champagne);transition:transform .5s var(--ease)}
.li p{grid-column:2;font-size:20px;line-height:1.5;color:var(--muted);max-width:60ch;margin-top:5px;opacity:.55;transition:opacity .5s,transform .5s}
.li:hover{background:linear-gradient(90deg,rgba(241,232,215,.05),transparent 70%)}
.li:hover h3{transform:translateX(12px)}
.li:hover p{opacity:1;transform:translateX(12px)}
/* The .55 opacity is a hover affordance — it exists so the row brightens under the
   cursor. Touch has no hover, so on a phone it never lifts and the text sits at 2.5:1
   against the black, well under the 4.5:1 minimum. Show it in full there. */
@media(hover:none){.li p{opacity:1}}
@media(max-width:560px){.li{grid-template-columns:1fr}.li h3,.li p{grid-column:1}}

/* what we create */
.grid-create{display:grid;grid-template-columns:1fr 1fr;gap:0;background:transparent;border:none}
@media(max-width:720px){.grid-create{grid-template-columns:1fr}}
/* .cc is now just the flip stage: it keeps the grid hairline trick and holds the
   perspective. All card chrome (bg / border / padding) moved onto the two faces.
   The scroll-in stagger still animates .cc itself, so the flip lives on .cc-inner
   — two transforms on one element would overwrite each other. */
.cc{position:relative;margin:-1px 0 0 -1px;min-height:clamp(215px,21vw,270px);perspective:1400px}
.cc-inner{position:absolute;inset:0;transform-style:preserve-3d;transition:transform .75s var(--ease)}
/* Pointer devices only, and that scoping is load-bearing. On iOS a tap leaves :hover stuck
   on the element until you tap somewhere else, and the tabindex the script adds for keyboard
   access means a tap also focuses the card, satisfying :focus-within. Either one pinned
   .cc-inner at 180deg, so removing the .flipped class did nothing and the X read as dead. */
@media(hover:hover){
  .cc:hover .cc-inner,.cc:focus-within .cc-inner{transform:rotateY(180deg)}
}
/* Opaque faces, 1px apart in Z. backface-visibility was doing ALL the hiding here, and some
   browsers do not honour it in this arrangement — a face carrying overflow:hidden inside a
   preserve-3d parent, with .cc-img adding a filter and its own stacking context. Where it
   fails the front keeps painting and shows through the 3%-opaque back MIRRORED, so the card
   title stayed legible in reverse after the flip. An opaque surface sitting nearer the viewer
   occludes what is behind it in every renderer, so this no longer asks the browser for a
   feature. The front's own background is invisible either way: all eight fronts carry a
   full-bleed .cc-img plus scrim on top of it.
   TO REVERT: .cc-face background was rgba(5,5,5,.42); .cc-back background was
   rgba(241,232,215,.03); .cc-back transform was plain rotateY(180deg); .cc-front had no rule. */
.cc-face{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-start;
  background:#0b0a0c;border:1px solid var(--hair);padding:34px 30px;
  -webkit-backface-visibility:hidden;backface-visibility:hidden;overflow:hidden}
.cc-front{-webkit-transform:translateZ(1px);transform:translateZ(1px)}
.cc-back{justify-content:center;background:#0b0a0c;
  -webkit-transform:rotateY(180deg) translateZ(1px);transform:rotateY(180deg) translateZ(1px)}
/* Front face WITH an image — opt-in via .cc-front--img, so fronts without one
   keep their current top-aligned layout untouched. Scrim matches .pcard in
   section 03 so the two card systems read the same. */
.cc-front--img{justify-content:flex-end}
.cc-front--img .cc-img{position:absolute;inset:0;z-index:0;background-size:cover;background-position:center;filter:grayscale(.12)}
.cc-front--img .cc-scrim{position:absolute;inset:0;z-index:1;background:linear-gradient(0deg,rgba(5,5,5,.92),rgba(5,5,5,.2) 52%,rgba(5,5,5,.42))}
.cc-front--img .cn{position:absolute;top:34px;left:30px;z-index:2}
.cc-front--img h3{position:relative;z-index:2;margin:0}
.cc-front--img .bar{z-index:3}
.cc .cn{font-size:12px;letter-spacing:.2em;color:var(--silver)}
.cc h3{font-size:clamp(19px,2vw,26px);font-weight:500;color:var(--champagne);margin:14px 0 10px}
.cc p{font-size:clamp(18px,1.55vw,23px);line-height:1.45;color:var(--muted)}
.cc .bar{position:absolute;left:0;top:0;bottom:0;width:2px;background:var(--champagne);transform:scaleY(0);transform-origin:top;transition:transform .55s var(--ease)}
.cc:hover .bar{transform:scaleY(1)}
/* touch: no hover, so flip each card as it scrolls into view (JS adds .flipped) */
@media(hover:none){.cc.flipped .cc-inner{transform:rotateY(180deg)}}
@media(prefers-reduced-motion:reduce){.cc-inner{transition:none}}

/* internal structure */

/* founder */
/* Founder sits tighter to its neighbours than the other sections: its own top and
   bottom padding is trimmed from clamp(62px,10.5vh,132px) to roughly 85px, so each
   adjacent gap drops from ~226px to ~198px. Only this section is affected. */
.founder{overflow:hidden;padding-top:clamp(46px,7.9vh,99px);padding-bottom:clamp(46px,7.9vh,99px)}
.founder .wrap{display:grid;grid-template-columns:.85fr 1fr;gap:clamp(30px,6vw,88px);align-items:center}
@media(max-width:860px){.founder .wrap{grid-template-columns:1fr}}
/* Lift the text so his gaze lands on it. His eye line measures 25.1% down the
   photo; the columns are centre-aligned, so the text's centre starts at 50% of
   the row and needs to come up 24.9%. `top` on a relatively-positioned grid item
   resolves against the grid area height, which the taller photo defines — and it
   shifts paint only, so the photo and the section height are unaffected.
   Desktop only: below 860px the grid stacks and an offset would just leave a gap. */
@media(min-width:861px){.founder .wrap>.reveal:last-child{position:relative;top:-12%}}
/* Frameless: the portrait carries its own feathered alpha edge and dissolves
   straight into the section, so the old border, backing panel and bottom
   gradient are gone — any of them would have re-drawn the rectangle. */
.founder .media{position:relative;line-height:0}
/* Continues the portrait's own backdrop light past the photo edge so it spills into
   the section instead of stopping at the frame. Centre and colour are sampled from
   the photograph itself: glow core sits at 49.1%/27.1% of the image, hue rgb(255,226,199).
   Peak alpha .085 lands at ~0.0166 where the photo edge measures 0.0145 — no seam. */
.founder .media::before{content:"";position:absolute;z-index:0;pointer-events:none;
  left:-28%;right:-28%;top:-20%;bottom:-14%;
  background:radial-gradient(ellipse 46% 34% at 49.4% 35.1%,
    rgba(255,226,199,.085) 0%,rgba(255,226,199,.045) 32%,
    rgba(255,226,199,.018) 58%,rgba(255,226,199,0) 78%)}
.founder .media .im{display:block;width:100%;height:auto;position:relative;z-index:1}
.founder h2{font-weight:400;line-height:1.07;letter-spacing:-.02em;font-size:clamp(30px,4.2vw,60px);color:var(--champagne)}
.founder .bio{margin-top:26px;font-size:clamp(15px,1.2vw,18px);line-height:1.68;color:var(--muted);max-width:52ch}
.founder .belief{margin-top:30px;padding-top:26px;border-top:1px solid var(--hair);font-size:clamp(19px,1.9vw,28px);line-height:1.4;color:var(--champagne);font-weight:500;max-width:22ch}

/* universe */
.universe{overflow:hidden}
.marquee{position:relative;z-index:2;overflow:hidden;border-top:1px solid var(--hair);padding:28px 0}
.marquee:last-of-type{border-bottom:1px solid var(--hair)}
.mtrack{display:flex;width:max-content;animation:scrollx 44s linear infinite;will-change:transform;backface-visibility:hidden}
.marquee.rev .mtrack{animation-direction:reverse;animation-duration:56s}
.mtrack:hover{animation-play-state:paused}
/* logo marks. Height mirrors the old text line-box — clamp(20px,2.3vw,34px) at
   ~1.2 line-height — so each bar keeps exactly the height it had with wordmarks.
   margin-right stays 56px, the old inter-item spacing. */
.mtrack span{display:flex;align-items:center;flex:none;margin-right:56px;height:clamp(30px,3.4vw,50px)}
.mtrack img{height:100%;width:auto;max-width:240px;object-fit:contain;opacity:.72;transition:opacity .3s var(--ease)}
.mtrack span:hover img{opacity:1}
/* edge fades from the supplied design — stops marks hard-clipping at the bar ends */
.marquee::before,.marquee::after{content:"";position:absolute;top:0;bottom:0;width:clamp(60px,10vw,180px);z-index:2;pointer-events:none}
.marquee::before{left:0;background:linear-gradient(90deg,var(--black),transparent)}
.marquee::after{right:0;background:linear-gradient(270deg,var(--black),transparent)}
@keyframes scrollx{to{transform:translateX(-50%)}}

/* projects */
/* every anchor target, not just #projects — otherwise the nav covers the heading you
   just jumped to. */
section[id],header[id]{scroll-margin-top:90px}

/* closing */
.closing{position:relative;min-height:100vh;min-height:100svh;display:flex;align-items:center;overflow:hidden}
.closing .bg{position:absolute;inset:-8% 0;z-index:0;background:var(--black);will-change:transform}
.closing .scrim{position:absolute;inset:0;z-index:1;background:radial-gradient(120% 100% at 50% 50%,rgba(5,5,5,.5),rgba(5,5,5,.92)),linear-gradient(0deg,var(--black),transparent 45%),linear-gradient(180deg,var(--black),transparent 30%)}
.closing .wrap{position:relative;z-index:2;text-align:center;max-width:1100px;margin:0 auto;padding:0 clamp(20px,5vw,40px)}
.closing h2{font-weight:400;line-height:1.06;letter-spacing:-.025em;font-size:clamp(34px,7vw,116px);color:var(--champagne)}
.closing h2 b{font-weight:700}
.cta-row{margin-top:clamp(40px,6vh,60px);display:flex;flex-wrap:wrap;gap:16px;justify-content:center}

/* footer */
footer{position:relative;z-index:5;background:var(--black);border-top:1px solid var(--hair);padding:clamp(48px,8vh,84px) clamp(20px,5vw,66px)}
footer .wrap{max-width:1240px;margin:0 auto;display:flex;justify-content:space-between;align-items:flex-end;gap:30px;flex-wrap:wrap}
footer .fl img{height:32px;opacity:.9}
footer .fl p{margin-top:16px;font-size:12px;letter-spacing:.18em;text-transform:uppercase;color:var(--silver)}
footer .fr{text-align:right;font-size:12px;letter-spacing:.08em;color:var(--silver);line-height:2}
footer .fr a{color:var(--champagne);text-decoration:none;transition:opacity .3s}
footer .fr a:hover{opacity:.6}

@media(prefers-reduced-motion:reduce){
  *{animation:none!important;transition-duration:.001s!important}
  .stagger>*{opacity:1;transform:none}
  .era .bg,.closing .bg,.founder .media .im{transform:none}
  #intro .glow{display:none}
  #intro .introbg .f1{opacity:1}#intro .introbg .frame:not(.f1){opacity:0}
  #intro .logo,#intro .hold{opacity:1}
  .brand,.menu,.kicker,.sub,.herofoot{opacity:1;transform:none}
  h1 .ch{transform:none;opacity:1;filter:none}
  .hero-vids{opacity:1;transition:none}
  .reveal{opacity:1;transform:none}
}

/* section 04 — dynamic wireframe globe background (added) */
#industries{overflow:hidden}
#industries .globe-bg{position:absolute;inset:0;z-index:0;pointer-events:none;display:block}
@media(prefers-reduced-motion:reduce){#industries .globe-bg{opacity:.85}}

/* section 06 — Proprietary Concepts logo cards (added) */
.grid-concepts{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-top:clamp(22px,3.5vh,38px)}
@media(max-width:860px){.grid-concepts{grid-template-columns:1fr}}
.ccard{position:relative;aspect-ratio:16/9;border:1px solid var(--hair);display:flex;align-items:center;justify-content:center;padding:clamp(26px,3vw,44px);overflow:hidden;background:#0b0a0c;transition:border-color .5s var(--ease),transform .5s var(--ease)}
.ccard::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--champagne);transform:scaleX(0);transform-origin:left;transition:transform .5s var(--ease)}
.ccard:hover{border-color:rgba(241,232,215,.4);transform:translateY(-4px)}
.ccard:hover::after{transform:scaleX(1)}
.ccard .clogo{width:100%;height:100%;background-repeat:no-repeat;background-position:center;background-size:contain;opacity:.85;transition:opacity .5s var(--ease),transform .6s var(--ease)}
.ccard:hover .clogo{opacity:1;transform:scale(1.05)}
/* Own Projects only (LOFT / VYBE / EVENTO): shrink the marks inside the card.
   Scoped with 3 classes so the 12 event logos in .grid-events are untouched.
   Card size is unchanged — only the logo box shrinks; .ccard's flex centring
   then keeps each mark centred on both axes. */
.grid-concepts .ccard .clogo{width:62%;height:62%}
/* LOFT (card 1) and VYBE (card 2) sit visually heavier than EVENTO at the same
   box, so they get a tighter one. Positional — matches the card order in index.html. */
.grid-concepts .ccard:nth-child(1) .clogo,
.grid-concepts .ccard:nth-child(2) .clogo{width:52%;height:52%}

/* section 06 — Experience & Events Concepts logo wall (added) */
.grid-events{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin-top:clamp(22px,3.5vh,38px)}
@media(max-width:1100px){.grid-events{grid-template-columns:repeat(4,1fr)}}
@media(max-width:760px){.grid-events{grid-template-columns:repeat(3,1fr)}}
@media(max-width:480px){.grid-events{grid-template-columns:repeat(2,1fr)}}
.grid-events .ccard{aspect-ratio:4/3;background:#000;padding:0}
.grid-events .clogo{--s:1;--y:0%;width:100%;height:100%;background-size:contain;background-position:center;background-repeat:no-repeat;opacity:.9;transform:translateY(var(--y)) scale(var(--s));transition:opacity .5s var(--ease),transform .6s var(--ease)}
.grid-events .ccard:hover .clogo{opacity:1;transform:translateY(var(--y)) scale(calc(var(--s) * 1.06))}
/* per-box optical adjustments — measured from each logo's own content bounds */
.grid-events .ccard:nth-child(1) .clogo{--s:.85}    /* human: tallest mark in the grid */
.grid-events .ccard:nth-child(2) .clogo{--y:-6.5%}  /* dayxyz: centre sat at 56.5% */
.grid-events .ccard:nth-child(4) .clogo{--s:.88}    /* ashyrra: 86% tall vs ~55% average */
.grid-events .ccard:nth-child(9) .clogo{--y:-6.4%}  /* tellavision: 58.0% -> matches afterall at 51.6% */

/* section — interactive spotlight backbone (added) */
.backbone{position:relative;display:grid;grid-template-columns:1fr clamp(240px,30vw,440px) 1fr;gap:clamp(8px,2vw,34px);min-height:clamp(540px,74vh,820px);margin-top:clamp(6px,1.5vh,14px);align-items:stretch}
.bb-col{list-style:none;display:flex;flex-direction:column;justify-content:space-around;padding:26px 0;margin:0}
.bb-left{align-items:flex-end;text-align:right}
.bb-right{align-items:flex-start;text-align:left}
.cap{position:relative;font-size:clamp(12.5px,1.25vw,17px);letter-spacing:.13em;text-transform:uppercase;font-weight:500;color:var(--champagne);opacity:.24;line-height:1.32;max-width:15ch;cursor:default;transition:opacity .45s var(--ease),transform .45s var(--ease),letter-spacing .45s var(--ease)}
.bb-left .cap{transform:translateX(-8px)}
.bb-right .cap{transform:translateX(8px)}
.cap.on{opacity:1;transform:translateX(0);letter-spacing:.16em}
.bb-left .cap::after{content:"";position:absolute;right:-16px;top:50%;height:1px;width:0;background:var(--champagne);transition:width .45s var(--ease)}
.bb-left .cap.on::after{width:12px}
.bb-right .cap::before{content:"";position:absolute;left:-16px;top:50%;height:1px;width:0;background:var(--champagne);transition:width .45s var(--ease)}
.bb-right .cap.on::before{width:12px}
/* Backbone labels run on ONE line each (they were capped at 15ch, so the longer
   ones broke over 2-3 lines and the left/right pairs stopped sitting level).
   Scoped to .bb-col so the founder caption, which also uses .cap, is untouched. */
.bb-col .cap{max-width:none;white-space:nowrap}
/* Below ~1372px there is no bleed left to take, and the 30vw spine leaves the
   columns too narrow for the longest label — let them wrap rather than overflow. */
@media(max-width:1371px){.bb-col .cap{white-space:normal}}
/* Let the backbone bleed past the 1240px .wrap so the single-line labels have room.
   Collapses to 0 below ~1372px viewport, so it can never cause a horizontal scrollbar. */
#projects .backbone{--bleed:clamp(0px,calc((100vw - 1372px) / 2),170px);margin-left:calc(-1 * var(--bleed));margin-right:calc(-1 * var(--bleed))}
.bb-spine{position:relative;display:flex;align-items:center;justify-content:center;min-height:0}
.bb-img{max-width:100%;max-height:clamp(520px,72vh,800px);width:auto;height:auto;object-fit:contain;opacity:.4;transition:opacity .5s var(--ease)}
.bb-glow{position:absolute;left:0;top:0;width:440px;height:440px;margin:-220px 0 0 -220px;border-radius:50%;pointer-events:none;z-index:4;opacity:0;mix-blend-mode:screen;background:radial-gradient(circle,rgba(241,232,215,.18),rgba(241,232,215,.06) 42%,transparent 70%);transition:opacity .4s var(--ease);will-change:transform}
@media(hover:none){.cap{opacity:.82!important;transform:none!important}.bb-glow{display:none}.bb-left .cap::after,.bb-right .cap::before{display:none}}
@media(max-width:820px){
  .backbone{grid-template-columns:1fr 1fr;min-height:0;gap:16px 22px}
  .bb-spine{grid-column:1 / -1;order:-1;margin-bottom:8px}
  .bb-img{max-height:280px;opacity:.5}
  .bb-col{justify-content:flex-start;padding:0}
  .bb-left,.bb-right{align-items:flex-start;text-align:left}
  .bb-col .cap{max-width:none;white-space:normal}   /* stacked layout: let them wrap again */
}

/* closing CTA — background video (added) */
.closing .cta-vids{position:absolute;inset:0;z-index:0;opacity:0;transition:opacity 1.4s var(--ease)}
.closing .cta-vids.ready{opacity:1}
.closing .cta-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}

/* unified atmospheric blend — each section emerges from / dissolves into black (added) */
.sec{overflow:hidden}
.sbg{position:absolute;inset:-14% 0;z-index:0;background-size:cover;background-position:center;opacity:.68;will-change:transform}
.sscrim{position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,var(--black) 0%,rgba(5,5,5,.44) 20%,rgba(5,5,5,.44) 80%,var(--black) 100%),linear-gradient(90deg,rgba(5,5,5,.34),rgba(5,5,5,.16))}

/* animated starfield overlay — sits above the scrim so the glow reads, below .wrap (z-index 2) */
.starfx{position:absolute;inset:0;z-index:1;pointer-events:none;display:block}

/* era (section 02) — background video. Lives inside .bg so it inherits the parallax. */
.era .era-vids{position:absolute;inset:0;z-index:0;opacity:0;transition:opacity 1.4s var(--ease)}
.era .era-vids.ready{opacity:1}
.era .era-video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
/* A/B: ?stars=off in the URL, or press S, to hide the starfield over the video */
.era.no-stars .starfx{display:none}

/* section 03 — pillars reveal softly, top row then bottom row (added) */
.grid-pillars.stagger>*{transform:translateY(48px);transition:opacity 1.15s var(--ease),transform 1.15s var(--ease)}
.grid-pillars.stagger.in>*:nth-child(1){transition-delay:0s}
.grid-pillars.stagger.in>*:nth-child(2){transition-delay:.08s}
.grid-pillars.stagger.in>*:nth-child(3){transition-delay:.16s}
.grid-pillars.stagger.in>*:nth-child(4){transition-delay:.24s}
.grid-pillars.stagger.in>*:nth-child(5){transition-delay:.58s}
.grid-pillars.stagger.in>*:nth-child(6){transition-delay:.66s}
.grid-pillars.stagger.in>*:nth-child(7){transition-delay:.74s}
.grid-pillars.stagger.in>*:nth-child(8){transition-delay:.82s}

/* section 04 — industries rows ease in softly, one after another (added) */
.list.stagger>*{transform:translateY(48px);transition:opacity 1.15s var(--ease),transform 1.15s var(--ease)}
.list.stagger.in>*:nth-child(1){transition-delay:0s}
.list.stagger.in>*:nth-child(2){transition-delay:.13s}
.list.stagger.in>*:nth-child(3){transition-delay:.26s}
.list.stagger.in>*:nth-child(4){transition-delay:.39s}
.list.stagger.in>*:nth-child(5){transition-delay:.52s}
.list.stagger.in>*:nth-child(6){transition-delay:.65s}
.list.stagger.in>*:nth-child(7){transition-delay:.78s}

/* section 05 — create cards ease in softly, row by row (added) */
.grid-create.stagger>*{transform:translateY(48px);transition:opacity 1.15s var(--ease),transform 1.15s var(--ease)}
.grid-create.stagger.in>*:nth-child(1){transition-delay:0s}
.grid-create.stagger.in>*:nth-child(2){transition-delay:.06s}
.grid-create.stagger.in>*:nth-child(3){transition-delay:.2s}
.grid-create.stagger.in>*:nth-child(4){transition-delay:.26s}
.grid-create.stagger.in>*:nth-child(5){transition-delay:.4s}
.grid-create.stagger.in>*:nth-child(6){transition-delay:.46s}
.grid-create.stagger.in>*:nth-child(7){transition-delay:.6s}
.grid-create.stagger.in>*:nth-child(8){transition-delay:.66s}

/* ================= 07 — orbital diagram =================
   All classes ei- prefixed so page styles cannot reach in; no background of
   its own, so the section starfield shows through. Dithering comes from the
   site's global .grain. */
.ei-wrap{margin-top:clamp(30px,5vh,56px)}
.ei{
    --champagne:#F2E9DB; --silver:#B8B2A7;
    --t-title:clamp(20px,2.035cqw,77px);
    --t-sub:clamp(15.6px,1.383cqw,52px);
    --t-num:clamp(9px,0.781cqw,30px);
    --gap:clamp(3px,0.42cqw,17px);
    position:relative; width:100%; aspect-ratio:1.8/1; container-type:inline-size;
    background:transparent; overflow:hidden;
    font-family:Satoshi,"Helvetica Neue",Helvetica,Arial,sans-serif;
    -webkit-font-smoothing:antialiased;
  }

  /* ---------- nucleus: the logo, lit from behind ---------- */
  .ei-nucleus{position:absolute;left:50%;top:50%;translate:-50% -50%;width:19.02%;
    aspect-ratio:1912/334;z-index:2;pointer-events:none}
  .ei-nucleus svg{width:100%;height:100%;display:block;
    filter:drop-shadow(0 0 0.9cqw rgba(255,246,230,.55))
           drop-shadow(0 0 2.6cqw rgba(242,233,219,.30))}
  /* Bloom is SMALL and BRIGHT on purpose. A wide, ultra-faint gradient only has a
     handful of 8-bit levels to work with and renders as hard concentric bands —
     that is exactly what produced the phantom "rings" in the previous build. */
  .ei-bloom{position:absolute;left:50%;top:50%;translate:-50% -50%;
    width:46%;aspect-ratio:1.9/1;z-index:1;pointer-events:none;
    background:radial-gradient(ellipse at center,
      rgba(255,248,236,.34) 0%, rgba(255,246,230,.20) 18%,
      rgba(242,233,219,.085) 40%, rgba(232,220,200,.028) 64%, rgba(232,220,200,0) 82%);
    filter:blur(0.7cqw)}

  /* ---------- rings ---------- */
  .ei-art{position:absolute;inset:0;width:100%;height:100%;display:block;z-index:0}
  /* rings are STATIC — each one fixed at its own angle, evenly offset from the next */
  .ei-spin{transform-box:view-box;transform-origin:2160px 1200px;
    transform:rotate(var(--tilt))}
  /* the glow is a second, much wider stroke underneath — no SVG filter, so it stays cheap */
  .ei-halo{fill:none;stroke:var(--champagne);stroke-width:16;stroke-opacity:0;
    transition:stroke-opacity .45s ease}
  .ei-line{fill:none;stroke:var(--silver);stroke-width:2.6;stroke-opacity:.42;
    transition:stroke-opacity .45s ease,stroke .45s ease,stroke-width .45s ease}
  .ei-mark{fill:none;stroke:var(--champagne);stroke-width:1.7;stroke-opacity:.30;
    transition:stroke-opacity .45s ease,stroke-width .45s ease}
  .ei-dot{fill:#FFF8EC;fill-opacity:.75;filter:drop-shadow(0 0 0) ;
    transition:fill-opacity .45s ease,r .45s ease,filter .45s ease}
  .ei-hit{cursor:pointer}

  /* --- 1: hovering the LABEL lights the ring moderately --- */
  .ei:has(.ei-cat[data-c="1"] .ei-label:hover) [data-r="1"] .ei-halo,.ei:has(.ei-cat[data-c="1"] .ei-label:focus-within) [data-r="1"] .ei-halo{stroke-opacity:.10}
  .ei:has(.ei-cat[data-c="1"] .ei-label:hover) [data-r="1"] .ei-line,.ei:has(.ei-cat[data-c="1"] .ei-label:focus-within) [data-r="1"] .ei-line{stroke-opacity:.82;stroke:var(--champagne);stroke-width:2.9}
  .ei:has(.ei-cat[data-c="1"] .ei-label:hover) [data-r="1"] .ei-mark,.ei:has(.ei-cat[data-c="1"] .ei-label:focus-within) [data-r="1"] .ei-mark{stroke-opacity:.66}
  .ei:has(.ei-cat[data-c="1"] .ei-label:hover) [data-r="1"] .ei-dot ,.ei:has(.ei-cat[data-c="1"] .ei-label:focus-within) [data-r="1"] .ei-dot {fill-opacity:.85;r:9;filter:drop-shadow(0 0 14px rgba(255,248,236,.6))}
  /* --- 1: hovering the DOT lights it fully --- */
  .ei:has(.ei-cat[data-c="1"] .ei-hit:hover) [data-r="1"] .ei-halo{stroke-opacity:.22}
  .ei:has(.ei-cat[data-c="1"] .ei-hit:hover) [data-r="1"] .ei-line{stroke-opacity:1;stroke:var(--champagne);stroke-width:3.4}
  .ei:has(.ei-cat[data-c="1"] .ei-hit:hover) [data-r="1"] .ei-mark{stroke-opacity:1;stroke-width:2}
  .ei:has(.ei-cat[data-c="1"] .ei-hit:hover) [data-r="1"] .ei-dot {fill-opacity:1;r:13;filter:drop-shadow(0 0 26px rgba(255,248,236,.95))}
  /* --- 2: hovering the LABEL lights the ring moderately --- */
  .ei:has(.ei-cat[data-c="2"] .ei-label:hover) [data-r="2"] .ei-halo,.ei:has(.ei-cat[data-c="2"] .ei-label:focus-within) [data-r="2"] .ei-halo{stroke-opacity:.10}
  .ei:has(.ei-cat[data-c="2"] .ei-label:hover) [data-r="2"] .ei-line,.ei:has(.ei-cat[data-c="2"] .ei-label:focus-within) [data-r="2"] .ei-line{stroke-opacity:.82;stroke:var(--champagne);stroke-width:2.9}
  .ei:has(.ei-cat[data-c="2"] .ei-label:hover) [data-r="2"] .ei-mark,.ei:has(.ei-cat[data-c="2"] .ei-label:focus-within) [data-r="2"] .ei-mark{stroke-opacity:.66}
  .ei:has(.ei-cat[data-c="2"] .ei-label:hover) [data-r="2"] .ei-dot ,.ei:has(.ei-cat[data-c="2"] .ei-label:focus-within) [data-r="2"] .ei-dot {fill-opacity:.85;r:9;filter:drop-shadow(0 0 14px rgba(255,248,236,.6))}
  /* --- 2: hovering the DOT lights it fully --- */
  .ei:has(.ei-cat[data-c="2"] .ei-hit:hover) [data-r="2"] .ei-halo{stroke-opacity:.22}
  .ei:has(.ei-cat[data-c="2"] .ei-hit:hover) [data-r="2"] .ei-line{stroke-opacity:1;stroke:var(--champagne);stroke-width:3.4}
  .ei:has(.ei-cat[data-c="2"] .ei-hit:hover) [data-r="2"] .ei-mark{stroke-opacity:1;stroke-width:2}
  .ei:has(.ei-cat[data-c="2"] .ei-hit:hover) [data-r="2"] .ei-dot {fill-opacity:1;r:13;filter:drop-shadow(0 0 26px rgba(255,248,236,.95))}
  /* --- 3: hovering the LABEL lights the ring moderately --- */
  .ei:has(.ei-cat[data-c="3"] .ei-label:hover) [data-r="3"] .ei-halo,.ei:has(.ei-cat[data-c="3"] .ei-label:focus-within) [data-r="3"] .ei-halo{stroke-opacity:.10}
  .ei:has(.ei-cat[data-c="3"] .ei-label:hover) [data-r="3"] .ei-line,.ei:has(.ei-cat[data-c="3"] .ei-label:focus-within) [data-r="3"] .ei-line{stroke-opacity:.82;stroke:var(--champagne);stroke-width:2.9}
  .ei:has(.ei-cat[data-c="3"] .ei-label:hover) [data-r="3"] .ei-mark,.ei:has(.ei-cat[data-c="3"] .ei-label:focus-within) [data-r="3"] .ei-mark{stroke-opacity:.66}
  .ei:has(.ei-cat[data-c="3"] .ei-label:hover) [data-r="3"] .ei-dot ,.ei:has(.ei-cat[data-c="3"] .ei-label:focus-within) [data-r="3"] .ei-dot {fill-opacity:.85;r:9;filter:drop-shadow(0 0 14px rgba(255,248,236,.6))}
  /* --- 3: hovering the DOT lights it fully --- */
  .ei:has(.ei-cat[data-c="3"] .ei-hit:hover) [data-r="3"] .ei-halo{stroke-opacity:.22}
  .ei:has(.ei-cat[data-c="3"] .ei-hit:hover) [data-r="3"] .ei-line{stroke-opacity:1;stroke:var(--champagne);stroke-width:3.4}
  .ei:has(.ei-cat[data-c="3"] .ei-hit:hover) [data-r="3"] .ei-mark{stroke-opacity:1;stroke-width:2}
  .ei:has(.ei-cat[data-c="3"] .ei-hit:hover) [data-r="3"] .ei-dot {fill-opacity:1;r:13;filter:drop-shadow(0 0 26px rgba(255,248,236,.95))}
  /* --- 4: hovering the LABEL lights the ring moderately --- */
  .ei:has(.ei-cat[data-c="4"] .ei-label:hover) [data-r="4"] .ei-halo,.ei:has(.ei-cat[data-c="4"] .ei-label:focus-within) [data-r="4"] .ei-halo{stroke-opacity:.10}
  .ei:has(.ei-cat[data-c="4"] .ei-label:hover) [data-r="4"] .ei-line,.ei:has(.ei-cat[data-c="4"] .ei-label:focus-within) [data-r="4"] .ei-line{stroke-opacity:.82;stroke:var(--champagne);stroke-width:2.9}
  .ei:has(.ei-cat[data-c="4"] .ei-label:hover) [data-r="4"] .ei-mark,.ei:has(.ei-cat[data-c="4"] .ei-label:focus-within) [data-r="4"] .ei-mark{stroke-opacity:.66}
  .ei:has(.ei-cat[data-c="4"] .ei-label:hover) [data-r="4"] .ei-dot ,.ei:has(.ei-cat[data-c="4"] .ei-label:focus-within) [data-r="4"] .ei-dot {fill-opacity:.85;r:9;filter:drop-shadow(0 0 14px rgba(255,248,236,.6))}
  /* --- 4: hovering the DOT lights it fully --- */
  .ei:has(.ei-cat[data-c="4"] .ei-hit:hover) [data-r="4"] .ei-halo{stroke-opacity:.22}
  .ei:has(.ei-cat[data-c="4"] .ei-hit:hover) [data-r="4"] .ei-line{stroke-opacity:1;stroke:var(--champagne);stroke-width:3.4}
  .ei:has(.ei-cat[data-c="4"] .ei-hit:hover) [data-r="4"] .ei-mark{stroke-opacity:1;stroke-width:2}
  .ei:has(.ei-cat[data-c="4"] .ei-hit:hover) [data-r="4"] .ei-dot {fill-opacity:1;r:13;filter:drop-shadow(0 0 26px rgba(255,248,236,.95))}
  /* --- 5: hovering the LABEL lights the ring moderately --- */
  .ei:has(.ei-cat[data-c="5"] .ei-label:hover) [data-r="5"] .ei-halo,.ei:has(.ei-cat[data-c="5"] .ei-label:focus-within) [data-r="5"] .ei-halo{stroke-opacity:.10}
  .ei:has(.ei-cat[data-c="5"] .ei-label:hover) [data-r="5"] .ei-line,.ei:has(.ei-cat[data-c="5"] .ei-label:focus-within) [data-r="5"] .ei-line{stroke-opacity:.82;stroke:var(--champagne);stroke-width:2.9}
  .ei:has(.ei-cat[data-c="5"] .ei-label:hover) [data-r="5"] .ei-mark,.ei:has(.ei-cat[data-c="5"] .ei-label:focus-within) [data-r="5"] .ei-mark{stroke-opacity:.66}
  .ei:has(.ei-cat[data-c="5"] .ei-label:hover) [data-r="5"] .ei-dot ,.ei:has(.ei-cat[data-c="5"] .ei-label:focus-within) [data-r="5"] .ei-dot {fill-opacity:.85;r:9;filter:drop-shadow(0 0 14px rgba(255,248,236,.6))}
  /* --- 5: hovering the DOT lights it fully --- */
  .ei:has(.ei-cat[data-c="5"] .ei-hit:hover) [data-r="5"] .ei-halo{stroke-opacity:.22}
  .ei:has(.ei-cat[data-c="5"] .ei-hit:hover) [data-r="5"] .ei-line{stroke-opacity:1;stroke:var(--champagne);stroke-width:3.4}
  .ei:has(.ei-cat[data-c="5"] .ei-hit:hover) [data-r="5"] .ei-mark{stroke-opacity:1;stroke-width:2}
  .ei:has(.ei-cat[data-c="5"] .ei-hit:hover) [data-r="5"] .ei-dot {fill-opacity:1;r:13;filter:drop-shadow(0 0 26px rgba(255,248,236,.95))}
  /* --- 6: hovering the LABEL lights the ring moderately --- */
  .ei:has(.ei-cat[data-c="6"] .ei-label:hover) [data-r="6"] .ei-halo,.ei:has(.ei-cat[data-c="6"] .ei-label:focus-within) [data-r="6"] .ei-halo{stroke-opacity:.10}
  .ei:has(.ei-cat[data-c="6"] .ei-label:hover) [data-r="6"] .ei-line,.ei:has(.ei-cat[data-c="6"] .ei-label:focus-within) [data-r="6"] .ei-line{stroke-opacity:.82;stroke:var(--champagne);stroke-width:2.9}
  .ei:has(.ei-cat[data-c="6"] .ei-label:hover) [data-r="6"] .ei-mark,.ei:has(.ei-cat[data-c="6"] .ei-label:focus-within) [data-r="6"] .ei-mark{stroke-opacity:.66}
  .ei:has(.ei-cat[data-c="6"] .ei-label:hover) [data-r="6"] .ei-dot ,.ei:has(.ei-cat[data-c="6"] .ei-label:focus-within) [data-r="6"] .ei-dot {fill-opacity:.85;r:9;filter:drop-shadow(0 0 14px rgba(255,248,236,.6))}
  /* --- 6: hovering the DOT lights it fully --- */
  .ei:has(.ei-cat[data-c="6"] .ei-hit:hover) [data-r="6"] .ei-halo{stroke-opacity:.22}
  .ei:has(.ei-cat[data-c="6"] .ei-hit:hover) [data-r="6"] .ei-line{stroke-opacity:1;stroke:var(--champagne);stroke-width:3.4}
  .ei:has(.ei-cat[data-c="6"] .ei-hit:hover) [data-r="6"] .ei-mark{stroke-opacity:1;stroke-width:2}
  .ei:has(.ei-cat[data-c="6"] .ei-hit:hover) [data-r="6"] .ei-dot {fill-opacity:1;r:13;filter:drop-shadow(0 0 26px rgba(255,248,236,.95))}

  /* ---------- labels ---------- */
  .ei-cat{position:absolute;inset:0;z-index:3;pointer-events:none}
  .ei-hit{position:absolute;width:4.7%;aspect-ratio:1;border-radius:50%;
    translate:-50% -50%;pointer-events:auto}
  .ei-label{position:absolute;display:flex;flex-direction:column;gap:var(--gap);
    pointer-events:auto;cursor:default}
  .ei-num{font-size:var(--t-num);letter-spacing:.353em;color:var(--champagne);opacity:.62;
    text-shadow:0 0 .55cqw rgba(5,5,5,.95),0 0 1.3cqw rgba(5,5,5,.75);
    transition:opacity .45s ease}
  .ei-title{font-size:var(--t-title);font-weight:500;letter-spacing:.133em;line-height:1.2;
    color:var(--champagne);
    text-shadow:0 0 .6cqw rgba(5,5,5,.98),0 0 1.6cqw rgba(5,5,5,.85);
    transition:text-shadow .45s ease}
  .ei-sub{font-size:var(--t-sub);font-weight:300;letter-spacing:.02em;line-height:1.46;
    color:var(--silver);opacity:.8;
    text-shadow:0 0 .5cqw rgba(5,5,5,.95),0 0 1.2cqw rgba(5,5,5,.7);
    transition:opacity .45s ease,color .45s ease}
  .ei-cat:hover .ei-num,.ei-cat:focus-within .ei-num{opacity:1}
  .ei-cat:hover .ei-sub,.ei-cat:focus-within .ei-sub{opacity:1;color:var(--champagne)}
  .ei-cat:hover .ei-title,.ei-cat:focus-within .ei-title{
    text-shadow:0 0 .6cqw rgba(5,5,5,.98),0 0 1.6cqw rgba(5,5,5,.85),0 0 1.1cqw rgba(242,233,219,.5)}

/* ---- closing CTA: hold to reveal the phone number ---------------------------
   Reuses the intro's hold gesture (1100ms, fill sweeps, decays on release).
   A <button>, not a link, so keyboard users get Space/Enter for free. */
/* touch-action:none, not manipulation. Under `manipulation` the page stays scrollable
   during the 1100ms hold, so a few px of thumb drift is read as a scroll, fires
   pointercancel and resets the fill to zero. The intro gate already uses `none`. */
.btn--hold{cursor:pointer;overflow:hidden;-webkit-user-select:none;user-select:none;
  -webkit-touch-callout:none;
  touch-action:none;background:transparent;font:inherit}
/* the revealed number is an <a>, so it needs the button's box explicitly */
a.btn--tel{text-decoration:none;touch-action:manipulation}
.btn--hold .btn-fill{position:absolute;inset:0;z-index:1;background:var(--champagne);
  transform:scaleX(0);transform-origin:left;pointer-events:none}
.btn--hold .btn-txt,.btn--hold .btn-num{position:relative;z-index:2;
  transition:color .35s var(--ease)}
/* once the fill passes under the text it must read dark, not champagne-on-champagne */
.btn--hold.filling .btn-txt{color:#000}
.btn--hold.revealed{border-color:var(--champagne);color:#000}
.btn--hold.revealed .btn-fill{transform:scaleX(1)}
.btn--hold.revealed .btn-num{color:#000;letter-spacing:.06em;font-variant-numeric:tabular-nums}
@media (prefers-reduced-motion:reduce){.btn--hold .btn-fill{transition:none}}

/* ================= 07 — label geometry, lifted out of inline styles =================
   These six blocks were style="" attributes on each .ei-label. Inline styles beat every
   media query, so the sub-900px stacked layout below could not have overridden them.
   Values are copied verbatim — desktop is pixel-identical to the previous build. */
.ei-cat[data-c="1"] .ei-label{left:50%;top:23.8%;transform:translate(-50%,-100%);width:35cqw;align-items:center;text-align:center}
.ei-cat[data-c="2"] .ei-label{left:68.6%;top:33.17%;transform:translateY(-50%);width:27cqw;align-items:flex-start;text-align:left}
.ei-cat[data-c="3"] .ei-label{left:68.6%;top:66.83%;transform:translateY(-50%);width:27cqw;align-items:flex-start;text-align:left}
.ei-cat[data-c="4"] .ei-label{left:50%;top:80.5%;transform:translateX(-50%);width:35cqw;align-items:center;text-align:center}
.ei-cat[data-c="5"] .ei-label{left:31.4%;top:66.83%;transform:translate(-100%,-50%);width:27cqw;align-items:flex-end;text-align:right}
.ei-cat[data-c="6"] .ei-label{left:31.4%;top:33.17%;transform:translate(-100%,-50%);width:27cqw;align-items:flex-end;text-align:right}
.ei-cat[data-c="1"] .ei-hit{left:50.0000%;top:27.5000%}
.ei-cat[data-c="2"] .ei-hit{left:64.0741%;top:33.1667%}
.ei-cat[data-c="3"] .ei-hit{left:64.0741%;top:66.8333%}
.ei-cat[data-c="4"] .ei-hit{left:50.0000%;top:77.6667%}
.ei-cat[data-c="5"] .ei-hit{left:35.9259%;top:66.8333%}
.ei-cat[data-c="6"] .ei-hit{left:35.9259%;top:33.1667%}
/* .ei-title is an <h3> now; it inherited h3's bold, and the class already sets 500 */
.ei-title{margin:0}
.ei-sub{margin:0}

/* ---- 07 below 960px: the ring cannot carry the labels ----
   Type is sized in cqw with a 20px floor, so below roughly 980px the text stops shrinking
   while the container keeps going. At 393px the box is 353x196 and the six labels need
   200-340px of height each — they overlapped, and .ei's overflow:hidden clipped the remains.
   Stack them as a plain numbered list and drop the ring, which carries no information alone.

   960px is the measured floor, not a guess: at 920px labels 02 and 03 intersect each other,
   which no amount of overflow can fix. From 960px up they clear one another and only need
   room to sit outside the box — see the band rule below. */
@media(max-width:959px){
  .ei-wrap{margin-top:clamp(22px,4vh,38px)}
  .ei{aspect-ratio:auto;height:auto;overflow:visible;display:block;
      --t-title:clamp(16px,4.2vw,21px);
      --t-sub:clamp(13.5px,3.4vw,16px);
      --t-num:11px;
      --gap:9px}
  .ei-art,.ei-bloom,.ei-nucleus,.ei-hit{display:none}
  .ei-cat{position:static;display:block;pointer-events:auto;border-top:1px solid var(--hair)}
  .ei-cat:last-of-type{border-bottom:1px solid var(--hair)}
  /* must carry the same specificity as the .ei-cat[data-c="n"] .ei-label rules above —
     a media query adds none, so a bare .ei-label would lose to them and the labels would
     stay absolutely positioned on top of one another. */
  .ei-cat[data-c] .ei-label{position:static;left:auto;top:auto;transform:none;width:auto;
    align-items:flex-start;text-align:left;padding:20px 2px}
  .ei-num{opacity:.75;text-shadow:none}
  .ei-title{text-shadow:none;letter-spacing:.1em;line-height:1.25}
  .ei-sub{opacity:.9;text-shadow:none;max-width:52ch}
}

/* ================= mobile navigation =================
   Below 760px the three section links are hidden and, until now, nothing replaced them.
   The hamburger opens them as a full-screen overlay in the site's own type. */
.navtoggle{display:none;width:32px;height:32px;flex-direction:column;align-items:center;justify-content:center;
  gap:6px;background:none;border:none;padding:0;cursor:pointer;-webkit-tap-highlight-color:transparent}
.nt-bar{display:block;width:20px;height:1px;background:var(--champagne);
  transition:transform .4s var(--ease),opacity .3s}
.navtoggle[aria-expanded="true"] .nt-bar:first-child{transform:translateY(3.5px) rotate(45deg)}
.navtoggle[aria-expanded="true"] .nt-bar:last-child{transform:translateY(-3.5px) rotate(-45deg)}

.navmenu{position:fixed;inset:0;z-index:55;display:flex;align-items:center;justify-content:center;
  background:rgba(5,5,5,.97);-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);
  opacity:0;visibility:hidden;transition:opacity .5s var(--ease),visibility .5s;
  padding:calc(90px + env(safe-area-inset-top)) 24px calc(40px + env(safe-area-inset-bottom))}
.navmenu.open{opacity:1;visibility:visible}
.navmenu-inner{display:flex;flex-direction:column;align-items:center;gap:clamp(20px,3.6vh,32px);text-align:center}
.navmenu a{color:var(--champagne);text-decoration:none;text-transform:uppercase;font-weight:400;
  font-size:clamp(21px,6.4vw,32px);letter-spacing:.1em;
  opacity:0;transform:translateY(16px);
  transition:opacity .55s var(--ease),transform .55s var(--ease)}
.navmenu.open a{opacity:1;transform:none}
.navmenu.open a:nth-child(1){transition-delay:.08s}
.navmenu.open a:nth-child(2){transition-delay:.14s}
.navmenu.open a:nth-child(3){transition-delay:.20s}
.navmenu.open a:nth-child(4){transition-delay:.28s}
.navmenu .nm-cta{margin-top:10px;border:1px solid var(--hair);border-radius:100px;
  padding:15px 32px;font-size:12px;letter-spacing:.2em}
/* the toggle lives inside <nav>, which must therefore outrank the overlay while it is open */
body.menu-open nav{z-index:56}
body.entered.menu-open{overflow-y:hidden}

@media(min-width:761px){.navmenu{display:none}}
@media(max-width:760px){
  .navtoggle{display:inline-flex}
  /* 'Build With Us' wrapped to two lines at 393px, pushing the bar to 106px tall — 13% of
     the screen. Tighter type and a smaller wordmark keep it on one line. */
  .brand{height:22px}
  .menu{gap:14px}
  .menu .cta{font-size:10px;letter-spacing:.12em;padding:9px 15px;white-space:nowrap}
  /* the hero paragraph and the SCROLL cue overlapped by 58x17px — give the footer its
     own band rather than letting the two share one. */
  .hero-inner{padding-bottom:calc(118px + env(safe-area-inset-bottom))}
}

/* ================= 06 cards: tap to flip on touch =================
   Previously each card auto-flipped once as it scrolled past and stayed on its text side,
   so the artwork was never seen on a phone. Now the visitor turns them. */
@media(hover:none){
  .cc{cursor:pointer;-webkit-tap-highlight-color:transparent}
  .cc-face::after{position:absolute;right:16px;bottom:13px;z-index:4;
    font-size:17px;line-height:1;color:var(--champagne);opacity:.55;pointer-events:none}
  .cc-front::after{content:"+"}
  .cc-back::after{content:"\00d7"}
  .cc:focus-visible{outline:1px solid var(--champagne);outline-offset:-1px}
}

/* ---- closing CTA on touch: the button stays put, the number appears beneath it ----
   A 1100ms hold is awkward on a phone and easy to abort, so touch gets a single tap.
   The button remains in place and the number is revealed underneath as plain text with
   a tel: link, rather than taking the button's place. Pointer devices keep the hold and
   the swap exactly as they were. */
.btn--tel .btn-hint{display:none}
@media(hover:none){
  .cta-row{flex-direction:column;align-items:center;gap:14px}
  /* not a second pill — the number reads as a line of text under the button */
  a.btn--tel{border-color:transparent;background:none;padding:2px 0;overflow:visible;
    flex-direction:column;gap:7px}
  a.btn--tel .btn-fill{display:none}
  a.btn--tel.revealed{border-color:transparent;color:var(--champagne)}
  a.btn--tel.revealed .btn-num{color:var(--champagne);font-weight:500;
    font-size:clamp(19px,5.4vw,24px);letter-spacing:.06em}
  a.btn--tel .btn-hint{display:block;color:var(--silver);opacity:.62;
    font-size:10px;letter-spacing:.2em;text-transform:uppercase}
}

/* ---- 07 between 960 and 1199px: keep the ring, stop guillotining its labels ----
   Label 01 hangs off top:23.8% with translateY(-100%), so it needs boxHeight x 0.238 of
   headroom. Its own height is pinned near 142px by the 20px/15.6px type floors, which needs
   a ~597px box — the 1.8:1 ratio only reaches that at about 1200px viewport. Below that,
   label 01 pushed past the top edge and label 04 past the bottom, and overflow:hidden cut
   them off. Letting them sit outside the box costs nothing: they land in the section's own
   padding, measured 96-141px clear of the heading above. From 1200px up nothing overflows,
   so the original overflow:hidden is left exactly as it was. */
@media(min-width:960px) and (max-width:1199px){
  .ei{overflow:visible}
  .ei-wrap{padding:52px 0}
}

/* ---- 06 cards: stop the front bleeding through the back on iOS ----
   .cc-back was background:rgba(241,232,215,.03) — 3% opaque. Both faces do set
   backface-visibility:hidden, but iOS Safari handles that unreliably when the face also
   carries overflow:hidden inside a preserve-3d parent (both true here) and .cc-img adds a
   filter, which spawns its own stacking context. The front therefore kept painting and a
   3%-opaque back had nothing to cover it with.

   Two changes, touch only, so the desktop look is untouched:
   1. opaque faces — even if backface-visibility fails, the near face hides the far one;
   2. 1px of Z between them — coplanar faces z-fight, and after the 180deg rotation this
      puts the back 2px nearer the viewer, so it wins outright.
   All eight fronts carry a full-bleed image, so making the front opaque changes nothing
   visible; #0b0a0c matches .pcard and .ccard elsewhere on the page. */
@media(hover:none){
  .cc-inner{-webkit-transform-style:preserve-3d;transform-style:preserve-3d}
  .cc-face{background:#0b0a0c}
  .cc-front{-webkit-transform:translateZ(1px);transform:translateZ(1px)}
  .cc-back{background:#0b0a0c;
    -webkit-transform:rotateY(180deg) translateZ(1px);transform:rotateY(180deg) translateZ(1px)}
}

/* ---- 04 backbone on mobile: give the captions room ----
   .bb-col is a flex column with no gap, so the twelve captions sat flush against each
   other — measured 0px between every pair. At 166px per column most of them wrap onto two
   lines, so consecutive entries read as one solid block of type.
   The min-height reserves two lines for every entry, which also keeps the left and right
   columns level with each other instead of drifting apart as line counts differ. */
@media(max-width:820px){
  .bb-col{gap:18px}
  .bb-col .cap{min-height:2.64em}   /* 2 x the 1.32 line-height */
}

/* ---- 09 marquee on mobile: uniform slots ----
   At the 30px row height the marks ranged from 18px wide (Rolls-Royce) to 164px
   (Anastasia Beverly Hills) — a 9x spread, and the narrow ones were specks on a phone.
   A fixed slot per logo gives an even rhythm and, just as importantly, makes the track
   width independent of whether the images have loaded yet: the row is 22 slots wide from
   first paint, so the -50% wrap is exact from the very first frame instead of drifting as
   stragglers arrive. Row height goes 30px -> 40px so the marks actually read. */
@media(max-width:760px){
  .marquee{padding:22px 0}
  .mtrack span{width:104px;height:40px;margin-right:24px;justify-content:center}
  .mtrack img{width:100%;height:100%;max-width:none;object-fit:contain}
}

/* ---- closing CTA: the number sits behind the button, not beside it ----
   Guard against the bug that put it there: `hidden` on a .btn does nothing, because
   .btn{display:inline-flex} outranks the UA's [hidden]{display:none}. Restore it for any
   element that might rely on the attribute later. */
.btn[hidden]{display:none}

/* Pointer devices: the two share one spot and cross-fade. The button stays in flow so the
   stack keeps its size; the number is absolutely centred over it. visibility, not opacity
   alone — opacity would leave the number selectable and screen-readable before the hold. */
/* visibility is stepped, not interpolated, so never give it a duration — it gets a 0s
   transition with a DELAY instead. Appearing: delay 0, so it becomes visible at the start
   and the opacity fade is actually seen. Disappearing: delay matches the fade, so the
   element stays hit-testable-free only once it has finished fading out. Transitioning
   visibility itself leaves it stuck at its start value whenever the transition does not
   run to completion. */
.cta-stack{position:relative;display:inline-flex}
.cta-stack #ctaHold{transition:opacity .45s var(--ease),visibility 0s linear 0s}
.cta-stack .btn--tel{position:absolute;left:50%;top:0;transform:translateX(-50%);
  white-space:nowrap;opacity:0;visibility:hidden;
  transition:opacity .55s var(--ease),visibility 0s linear .55s}
.cta-stack.revealed .btn--tel{opacity:1;visibility:visible;
  transition:opacity .55s var(--ease),visibility 0s linear 0s}
.cta-stack.revealed #ctaHold{opacity:0;visibility:hidden;pointer-events:none;
  transition:opacity .45s var(--ease),visibility 0s linear .45s}

/* Touch keeps the arrangement chosen earlier: the button stays put and the number appears
   underneath it, so the CTA never disappears from under a thumb mid-tap. */
@media(hover:none){
  .cta-stack{flex-direction:column;align-items:center;gap:14px}
  .cta-stack .btn--tel{position:static;left:auto;top:auto;transform:none;
    display:none;opacity:1;visibility:visible}
  .cta-stack.revealed .btn--tel{display:flex}
  .cta-stack.revealed #ctaHold{opacity:1;visibility:visible;pointer-events:auto}
}


/* ===== 10 — The Film ==========================================================
   A poster and a play control. The <video> carries preload="none", so the only
   thing this section costs on landing is the still. */
.film .filmbox{position:relative;aspect-ratio:16/9;overflow:hidden;
  border:1px solid var(--hair);background:#0b0a0c;margin-top:clamp(26px,4vh,44px)}
.film-play{position:absolute;inset:0;width:100%;height:100%;padding:0;margin:0;
  border:none;background:none;cursor:pointer;display:block;-webkit-tap-highlight-color:transparent}
.film-poster{width:100%;height:100%;object-fit:cover;filter:grayscale(.18);
  transition:transform .8s var(--ease),filter .6s var(--ease)}
.film-play:hover .film-poster{transform:scale(1.03);filter:grayscale(0)}
.film-btn{position:absolute;left:50%;top:50%;translate:-50% -50%;
  width:clamp(62px,6.5vw,88px);aspect-ratio:1;border-radius:50%;
  border:1px solid var(--hair);background:rgba(5,5,5,.34);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  display:flex;align-items:center;justify-content:center;color:var(--champagne);
  transition:background .45s var(--ease),border-color .45s var(--ease),transform .45s var(--ease)}
.film-btn svg{width:42%;height:42%;margin-left:6%}
.film-play:hover .film-btn{background:var(--champagne);color:#000;
  border-color:var(--champagne);transform:translate(-50%,-50%) scale(1.06)}
.film-dur{position:absolute;right:clamp(14px,2vw,22px);bottom:clamp(12px,2vw,18px);
  font-size:11px;letter-spacing:.2em;color:var(--champagne);opacity:.75}
.film-video{position:absolute;inset:0;width:100%;height:100%;background:#000;display:block}
.film-video iframe{width:100%;height:100%;border:0;display:block}
/* explicit, because .btn[hidden] taught us an author rule can outrank the UA one.
   Both need it: .film-video sets display:block and .film-play sets display:block,
   so in each case the author rule would otherwise beat the UA [hidden] rule. */
.film-video[hidden],.film-play[hidden]{display:none}
@media(hover:none){ .film-btn{background:rgba(5,5,5,.5)} }
