/* ===================================================================
   KUNKUN VISUAL — editorial/cinematic studio layout, mapped onto the
   Brand Audit & Visual DNA tokens (color, type scale, 8pt spacing).
   Navigo / Neue Haas Unica are not open-license — using the audit's
   own documented fallback stack: Archivo + Inter.
   =================================================================== */
:root{
  --ink:#1E2025; --obsidian:#1B1A21; --carbon:#141414; --void:#121116; --graphite:#26282D;
  --paper:#FFFFFF; --bone:#F7F7F7; --mist:#EBEEEA; --steel:#C2C5CD; --slate:#858B9C; --lead:#505562;
  --teal:#1A776E; --teal-light:#2FA093;
  --line:rgba(11,11,11,.14); --line-light:rgba(255,255,255,.16);
  --f-display:'Archivo',Helvetica,Arial,sans-serif; --f-text:'Inter',system-ui,sans-serif;
  --s1:8px; --s2:16px; --s3:24px; --s4:40px; --s5:64px; --s6:104px; --s7:168px;
  --pad:clamp(30px,2.25vw,54px); --max:1720px;
  --ease:cubic-bezier(.22,.61,.36,1);
}
*{box-sizing:border-box;}
html{scroll-behavior:smooth;}
html.lenis,html.lenis body{height:auto;}
.lenis.lenis-smooth{scroll-behavior:auto!important;}
.lenis.lenis-smooth [data-lenis-prevent]{overscroll-behavior:contain;}
.lenis.lenis-stopped{overflow:hidden;}
body{margin:0; background:var(--paper); color:var(--ink); font-family:var(--f-text); font-size:16px; line-height:1.6; overflow-x:hidden; -webkit-font-smoothing:antialiased;}
a{color:inherit; text-decoration:none;}
img{display:block; width:100%; height:100%; object-fit:cover;}
/* the build wraps every image in <picture> to offer WebP first; contents
   means it generates no box, so every layout rule still lands on the img */
picture{display:contents;}
button,input,textarea{font:inherit; color:inherit;}
button{cursor:pointer; background:none; border:none;}
::selection{background:var(--teal); color:#fff;}
@media (prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important; transition-duration:.01ms!important; scroll-behavior:auto!important;}}

.container{max-width:var(--max); margin-inline:auto; padding-inline:var(--pad);}
.grid12{display:grid; grid-template-columns:repeat(12,minmax(0,1fr)); gap:clamp(12px,1.5vw,22px);}
.paper{background:var(--paper); color:var(--ink);}
.bone{background:var(--bone); color:var(--ink);}
.mist{background:var(--mist); color:var(--ink);}
.dark{background:var(--void); color:#fff;}
.section{position:relative;}
/* The one-signal rule, resolved: teal means "this is the page telling you what
   it is". That is the eyebrow and the answer block, and nothing else. */
.eyebrow{font-size:11px; text-transform:uppercase; letter-spacing:.14em; font-weight:600; color:var(--teal);}
.dark .eyebrow{color:var(--teal-light);}
/* GEO answer block: 40–60 word direct answer at the top of each key section */
/* The 40-60 words written to be quoted. Marked as the page's thesis rather
   than left to read as another body paragraph. */
.answer{font-size:17px; line-height:1.6; color:var(--lead); max-width:54ch; margin:0 0 56px;
  padding-left:var(--s2); border-left:2px solid var(--teal);}
.dark .answer{color:var(--steel); border-left-color:var(--teal-light);}
.intro-answer{grid-column:1/8; margin:40px 0 0;}
@media (max-width:900px){ .intro-answer{grid-column:1/-1;} }
.display{font-family:var(--f-display); font-weight:800; letter-spacing:-.03em; line-height:.94;}
.teal{color:var(--teal);}
.dark .teal, .void .teal{color:var(--teal-light);}
.line-mask{overflow:hidden; padding-bottom:.14em; margin-bottom:-.14em;}
.line-mask>span{display:block; transform:translateY(0);}

/* -------- scroll progress -------- */
.scroll-progress{position:fixed; left:0; top:0; width:100%; height:3px; z-index:1001; transform-origin:left; background:var(--teal); transform:scaleX(0);}

/* -------- header -------- */
.site-header{
  position:fixed; z-index:200; top:14px; left:var(--pad); right:var(--pad); max-width:calc(var(--max) - var(--pad)*2); margin:auto;
  height:58px; display:grid; grid-template-columns:1fr auto 1fr; align-items:center; padding:0 18px;
  color:#fff; font-size:12px; text-transform:uppercase; letter-spacing:.1em;
  border:1px solid transparent; border-radius:999px; transition:.4s var(--ease);
}
.site-header.is-scrolled{background:rgba(18,17,22,.78); backdrop-filter:blur(18px) saturate(130%); -webkit-backdrop-filter:blur(18px) saturate(130%); border-color:rgba(255,255,255,.14); box-shadow:0 20px 60px rgba(0,0,0,.22);}
.logo{font-family:var(--f-display); font-weight:800; letter-spacing:-.03em; font-size:16px; justify-self:start;}
.logo span{color:var(--teal-light); font-weight:400;}
.nav{display:flex; gap:6px; padding:4px; border:1px solid rgba(255,255,255,.16); border-radius:999px;}
.nav a{padding:8px 13px; border-radius:999px; transition:.25s;}
.nav a:hover{background:#fff; color:var(--ink);}
.header-cta{justify-self:end; border:0; border-radius:999px; background:#fff; color:var(--ink); padding:11px 16px; font-size:11px; letter-spacing:.1em; transition:.25s;}
.header-cta:hover{background:var(--teal-light); color:#fff; transform:translateY(-2px);}
/* 26x18 of icon inside a 44px target: the bars stay where they were, the
   thumb gets something it can actually hit. */
.nav-toggle{display:none; width:44px; height:44px; position:relative; justify-self:end;
  padding:13px 9px; box-sizing:border-box; background:none; border:0; cursor:pointer;}
.nav-toggle span{position:absolute; left:9px; right:9px; height:2px; background:#fff; transition:.3s var(--ease);}
.nav-toggle span:nth-child(1){top:13px;} .nav-toggle span:nth-child(2){top:21px;} .nav-toggle span:nth-child(3){top:29px;}
.nav-toggle.open span:nth-child(1){transform:translateY(8px) rotate(45deg);}
.nav-toggle.open span:nth-child(2){opacity:0;}
.nav-toggle.open span:nth-child(3){transform:translateY(-8px) rotate(-45deg);}
@media (max-width:900px){ .nav{display:none;} .nav-toggle{display:block;} }
.nav-mobile{position:fixed; inset:0; z-index:190; background:var(--void); color:#fff; padding:120px var(--pad) var(--pad); display:flex; flex-direction:column; gap:8px; opacity:0; pointer-events:none; transform:translateY(-10px); transition:.35s var(--ease);}
.nav-mobile.open{opacity:1; pointer-events:auto; transform:none;}
.nav-mobile a{font-family:var(--f-display); font-weight:700; font-size:34px; letter-spacing:-.02em; padding:12px 0; border-bottom:1px solid rgba(255,255,255,.14);}

/* -------- hero -------- */
.hero{min-height:110svh; background:var(--void); color:#fff; overflow:hidden; position:relative;}
.hero-media{position:absolute; inset:0;}
.hero-media:after{content:""; position:absolute; inset:0; background:linear-gradient(180deg,rgba(0,0,0,.32),rgba(0,0,0,.05) 45%,rgba(0,0,0,.82));}
.hero-topcopy{position:absolute; top:19vh; left:var(--pad); max-width:400px; z-index:2; font-size:13.5px; line-height:1.55; padding:18px; border-left:1px solid rgba(255,255,255,.4);}
.hero-link{display:inline-flex; margin-top:18px; padding-bottom:5px; border-bottom:1px solid var(--teal-light); color:var(--teal-light); font-size:11px; text-transform:uppercase; letter-spacing:.12em;}
.hero-markers{position:absolute; bottom:30vh; right:var(--pad); z-index:2; display:flex; flex-direction:column; align-items:flex-end; gap:9px; font-size:10px; text-transform:uppercase; letter-spacing:.16em; color:var(--steel);}
.hero-markers span.dot{color:var(--teal-light);}
.hero-word{position:absolute; z-index:2; left:calc(var(--pad) - .02em); right:0; bottom:-.1em; font-size:clamp(64px,15.5vw,300px); white-space:nowrap;}
.hero-word .slash{color:var(--teal-light);}
.hero-scroll{position:absolute; z-index:2; left:var(--pad); bottom:6vh; font-size:10px; text-transform:uppercase; letter-spacing:.16em; color:var(--steel); display:flex; align-items:center; gap:10px;}
.hero-scroll:after{content:""; width:1px; height:34px; background:linear-gradient(var(--teal-light),transparent);}

.ticker{border-top:1px solid var(--line-light); border-bottom:1px solid var(--line-light); overflow:hidden; white-space:nowrap; background:var(--void);}
.ticker-track{display:inline-flex; gap:54px; padding:18px 0; animation:tick 28s linear infinite;}
.ticker-track span{font-family:var(--f-display); font-weight:700; font-size:clamp(13px,1.2vw,17px); letter-spacing:-.02em; color:#fff;}
.ticker-track span.dot{color:var(--teal-light);}
@keyframes tick{from{transform:translateX(0);} to{transform:translateX(-50%);}}

/* -------- logo wall: clients + international recognition --------
   Brand Audit p.21 — award logos: uniform 48px height, 40px apart, one colour.
   Assets in assets/logos are white-on-transparent for exactly this reason. */
.logowall{background:var(--bone); color:var(--ink); padding:var(--s5) 0 var(--s4);}
.logowall .eyebrow{margin:0 0 var(--s3);}
.logowall .container + .logo-marquee{margin-bottom:var(--s5);}
.logo-marquee{overflow:hidden; padding:var(--s1) 0; mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);}
.logo-track{display:flex; align-items:center; gap:var(--s4); width:max-content; animation:logoscroll 60s linear infinite;}
.logo-marquee.reverse .logo-track{animation-duration:48s; animation-direction:reverse;}
.logo-track img{height:48px; width:auto; max-width:none; object-fit:contain; flex:none; opacity:.6; transition:opacity .3s var(--ease);}
.logo-track img:hover{opacity:1;}
@keyframes logoscroll{from{transform:translateX(0);} to{transform:translateX(-50%);}}
.logo-marquee:hover .logo-track{animation-play-state:paused;}
@media (max-width:640px){ .logo-track{gap:var(--s3);} .logo-track img{height:34px;} .logowall{padding:var(--s4) 0 var(--s3);} }
@media (prefers-reduced-motion:reduce){
  .logo-track{animation:none; width:auto; flex-wrap:wrap; justify-content:center; row-gap:var(--s3);}
  .logo-track img[aria-hidden="true"]{display:none;}
  .logo-marquee{mask-image:none; -webkit-mask-image:none;}
}

/* -------- intro / statement -------- */
.intro{padding:80px 0 110px;}
.intro-meta{grid-column:1/-1; display:flex; justify-content:space-between; margin-bottom:5vh;}
.intro-title{grid-column:1/12; font-size:clamp(46px,8vw,150px); margin:0;}
.intro-lower{margin-top:8vh; align-items:start;}
.intro-portrait{grid-column:1/6; aspect-ratio:3/2; overflow:hidden; position:relative;}
.keywords{grid-column:6/8; font-size:12px; text-transform:uppercase; line-height:1.9; letter-spacing:.1em; color:var(--lead);}
.intro-copy{grid-column:8/11; font-size:15px; line-height:1.6; color:var(--lead);}
.stats-mini{grid-column:11/13; display:grid; gap:22px;}
.stats-mini strong{font-family:var(--f-display); font-weight:800; font-size:30px; letter-spacing:-.03em; display:block; color:var(--ink);}
.stats-mini span{font-size:10px; text-transform:uppercase; letter-spacing:.1em; color:var(--slate);}
@media (max-width:900px){
  .intro-title{grid-column:1/-1;}
  .intro-portrait{grid-column:1/6;}
  .keywords{grid-column:7/10;}
  .intro-copy{grid-column:1/8; margin-top:40px;}
  .stats-mini{grid-column:9/13; margin-top:40px;}
}
@media (max-width:640px){
  .grid12{grid-template-columns:1fr;}
  .intro-meta{margin-bottom:8vh;}
  .intro-portrait,.keywords,.intro-copy,.stats-mini,.intro-answer{grid-column:auto;}
  .intro-portrait{aspect-ratio:3/2;}
  .stats-mini{grid-template-columns:repeat(3,1fr);}
}

/* -------- media panels: real renders from kunkunvisual.com live in assets/img -------- */
.rp-tag{position:absolute; left:var(--s2); bottom:var(--s2); z-index:2; color:#fff; text-shadow:0 1px 12px rgba(0,0,0,.5);}
.rp-tag .cap{font-size:11px; color:var(--steel); text-transform:uppercase; letter-spacing:.1em;}

/* -------- projects (selected work) -------- */
.projects{padding:120px 0 160px;}
.projects-head{display:flex; justify-content:space-between; align-items:end; margin-bottom:70px;}
.projects-head h2{margin:0; font-size:clamp(46px,7.5vw,120px);}
.project{min-height:auto; position:relative; display:grid; grid-template-columns:repeat(12,minmax(0,1fr)); gap:clamp(12px,1.5vw,22px); align-items:center; padding:6vh 0; border-top:1px solid var(--line);}
.project:last-child{border-bottom:1px solid var(--line);}
.project-media{grid-column:4/11; height:62vh; overflow:hidden; position:relative; display:block;}
.project-copy{grid-column:1/4; align-self:end; padding-bottom:8vh; z-index:2;}
.project-copy h3{margin:0 0 12px; font-size:clamp(34px,5vw,72px);}
.project-copy h3 a{display:block; transition:color .3s var(--ease);}
.project-copy h3 a:hover{color:var(--teal);}
.journal-item h4 a{transition:color .3s var(--ease);}
.journal-item h4 a:hover{color:var(--teal);}
.project-copy p{margin:0; font-size:12px; text-transform:uppercase; letter-spacing:.1em; line-height:1.7; color:var(--slate);}
.project-side{grid-column:11/13; align-self:start; padding-top:8vh; font-size:12px; text-transform:uppercase; letter-spacing:.1em; color:var(--slate);}
.project-thumb{height:150px; margin-top:24px; overflow:hidden;}
.hover-media{transition:transform .5s var(--ease);}
.project:hover .hover-media{transform:scale(1.035);}
@media (max-width:900px){
  .project{display:flex; flex-direction:column; align-items:stretch; padding:50px 0;}
  .project-copy{order:1; padding:0 0 20px;}
  .project-media{order:2; height:52vh;}
  .project-side{order:3; padding:16px 0 0; display:flex; justify-content:space-between;}
  .project-thumb{display:none;}
}

/* -------- capabilities (dark, diagonal) -------- */
.section.diagonal-top{--diag-clear:140px;
  clip-path:polygon(0 3.5vw,100% 0,100% 100%,0 100%); margin-top:-3.5vw;
  padding-top:calc(3.5vw + var(--diag-clear)); position:relative; z-index:2;}
/* a logo strip, not a chapter opening: it wants the band back */
.logowall.diagonal-top{--diag-clear:24px;}
@media (max-width:640px){ .section.diagonal-top{--diag-clear:90px; clip-path:polygon(0 2.5vw,100% 0,100% 100%,0 100%);} }
.capabilities{padding:140px 0 170px;}
.cap-intro{min-height:90vh; display:flex; align-items:center; position:relative; padding:60px 0;}
/* Leave room for the photo rather than letting it sit on top of the type. */
.cap-statement{font-size:clamp(40px,6.4vw,104px); margin:0; font-weight:800;
  letter-spacing:-.03em; line-height:.94;
  max-width:min(1050px, calc(100% - clamp(220px,26vw,380px) - var(--s4)));}
@media (max-width:900px){ .cap-statement{max-width:1050px;} }
.cap-statement span{display:block; color:#4a4c52; transition:color .3s;}
.cap-statement span.active{color:#fff;}
/* Big enough to be a photograph rather than a swatch, and anchored to the
   baseline of the statement instead of floating in the middle of the gap. */
.cap-photo{position:absolute; right:0; bottom:60px; width:clamp(220px,26vw,380px);
  aspect-ratio:4/5; overflow:hidden;}
.cap-row{color:inherit; text-decoration:none; display:grid; grid-template-columns:1fr 1.4fr 3.6fr 3fr; gap:22px; align-items:center; min-height:280px; border-top:1px solid var(--line-light); padding:40px 0;}
.cap-row:last-child{border-bottom:1px solid var(--line-light);}
/* Each capability leads to its own service page, as it does on the old site. */
a.cap-row{transition:background .3s var(--ease);}
a.cap-row:hover{background:rgba(255,255,255,.03);}
a.cap-row:hover h3{color:var(--teal-light);}
a.cap-row h3{transition:color .3s var(--ease);}
a.cap-row:focus-visible{outline:2px solid var(--teal-light); outline-offset:-2px;}
.cap-row .num{font-size:13px; color:var(--steel);}
.cap-row .image{height:190px; overflow:hidden;}
.cap-row h3{margin:0; font-size:clamp(32px,4.2vw,62px);}
.cap-row p{color:var(--steel); line-height:1.6; max-width:400px; margin:0;}
@media (max-width:900px){
  .cap-intro{min-height:auto; padding:70px 0 100px;}
  .cap-photo{display:none;}
  .cap-row{grid-template-columns:1fr; min-height:auto;}
  .cap-row .image{height:46vh;}
}

/* -------- engagement / plans -------- */
.engagement{padding:130px 0;}
.section-title{font-size:clamp(46px,7.5vw,110px); margin:0 0 80px;}
.plans{display:grid; grid-template-columns:repeat(3,1fr); border-top:1px solid var(--line); border-left:1px solid var(--line);}
.plan{min-height:480px; padding:32px; border-right:1px solid var(--line); border-bottom:1px solid var(--line); display:flex; flex-direction:column;}
.plan.dark-card{background:var(--void); color:#fff;}
.plan small{text-transform:uppercase; letter-spacing:.12em; font-size:11px; color:var(--slate);}
.plan.dark-card small{color:var(--steel);}
.plan h3{font-family:var(--f-display); font-weight:700; font-size:clamp(30px,3.6vw,50px); line-height:1; letter-spacing:-.02em; margin:24px 0;}
.plan .price{font-family:var(--f-display); font-weight:600; font-size:24px; margin-bottom:28px; color:var(--teal);}
.plan.dark-card .price{color:var(--teal-light);}
.plan ul{list-style:none; padding:0; margin:0; line-height:2; font-size:13.5px; color:var(--lead);}
.plan.dark-card ul{color:var(--steel);}
.plan a{margin-top:auto; padding-top:14px; border-top:1px solid currentColor; display:flex; justify-content:space-between; font-size:11px; text-transform:uppercase; letter-spacing:.1em;}
@media (max-width:900px){ .plans{grid-template-columns:1fr;} }

/* -------- testimonial / world-stage proof -------- */
.testimonial{padding:130px 0;}
.quote-photo{grid-column:1/3; height:210px; overflow:hidden;}
.quote{grid-column:4/12; font-size:clamp(38px,5.6vw,86px); margin:0; letter-spacing:-.02em;}
.quote-author{grid-column:4/7; margin-top:36px; font-size:13px; line-height:1.7; color:var(--lead);}
.quote-metrics{grid-column:1/-1; display:grid; grid-template-columns:repeat(3,1fr); border-top:1px solid var(--line); margin-top:90px;}
.metric{padding:30px 0; border-right:1px solid var(--line);}
.metric:last-child{border-right:none;}
.metric strong{display:block; font-family:var(--f-display); font-weight:800; font-size:clamp(44px,6vw,88px); letter-spacing:-.03em;}
.metric span{font-size:11px; text-transform:uppercase; letter-spacing:.1em; color:var(--slate);}
@media (max-width:900px){ .quote-photo{grid-column:1/4;} .quote{grid-column:4/-1;} }
@media (max-width:640px){ .quote-photo,.quote,.quote-author{grid-column:auto;} .quote{margin-top:32px;} .quote-metrics{grid-template-columns:1fr;} .metric{border-right:0; border-bottom:1px solid var(--line);} }

/* -------- archive (clients / awards) -------- */
.archive{padding:130px 0;}
.archive h2{font-size:clamp(44px,7vw,110px); margin:0 0 70px;}
.archive-row{position:relative; display:grid; grid-template-columns:1fr 2fr 2fr 1fr; align-items:center; min-height:96px; border-top:1px solid var(--line); font-size:14px; transition:opacity .25s, transform .25s;}
.archive-row:last-child{border-bottom:1px solid var(--line);}
.archive-row:hover{transform:translateX(8px);}
.archive-row .tag{color:var(--slate); font-size:11px; text-transform:uppercase; letter-spacing:.1em;}
.archive-thumb{justify-self:end; width:100px; height:64px; overflow:hidden;}
.archive-preview{position:fixed; left:0; top:0; z-index:150; width:280px; height:350px; pointer-events:none; opacity:0; transform:translate(-50%,-50%) scale(.85); overflow:hidden;}
.archive-row{transition:opacity .25s;}
@media (max-width:900px){ .archive-row{grid-template-columns:.7fr 1.2fr 1.2fr;} .archive-thumb{display:none;} .archive-preview{display:none!important;} }

/* -------- cinematic full-bleed statement -------- */
.cinematic{min-height:100vh; color:#fff; overflow:hidden;}
.cinematic-bg{position:absolute; inset:0;}
.cinematic-bg:after{content:""; position:absolute; inset:0; background:rgba(9,9,12,.62);}
.cinematic-inner{position:relative; z-index:2; min-height:100vh; display:flex; align-items:center; justify-content:center; text-align:center; padding:80px var(--pad);}
.cinematic h2{margin:0; font-size:clamp(52px,10.5vw,190px); max-width:1400px; letter-spacing:-.03em;}
.cinematic-cta{position:absolute; z-index:3; bottom:9vh; left:50%; transform:translateX(-50%); border:1px solid #fff; padding:14px 20px; font-size:11px; text-transform:uppercase; letter-spacing:.12em; transition:.25s;}
.cinematic-cta:hover{background:#fff; color:var(--ink);}

/* -------- big stats -------- */
.big-stats{padding:150px 0;}
.stats-grid{display:grid; grid-template-columns:repeat(2,1fr); border-top:1px solid var(--line); border-left:1px solid var(--line);}
.stat{min-height:300px; padding:38px; border-right:1px solid var(--line); border-bottom:1px solid var(--line);}
.stat strong{display:block; font-family:var(--f-display); font-weight:800; font-size:clamp(64px,10vw,170px); letter-spacing:-.04em; line-height:.85;}
.stat p{margin-top:40px; max-width:250px; font-size:12px; text-transform:uppercase; letter-spacing:.1em; line-height:1.6; color:var(--lead);}
@media (max-width:640px){ .stats-grid{grid-template-columns:1fr;} .stat{min-height:220px;} }

/* -------- journal -------- */
.journal{padding:130px 0 170px;}
.journal-grid{display:grid; grid-template-columns:repeat(3,1fr); gap:20px; align-items:start;}
.journal-item:nth-child(2){margin-top:80px;}
.journal-img{height:46vh; overflow:hidden;}
.journal-meta{display:flex; justify-content:space-between; gap:12px; margin-top:14px; font-size:10px; text-transform:uppercase; letter-spacing:.1em; color:var(--slate);}
.journal-item h4{margin:12px 0 0; font-size:19px; font-weight:600; line-height:1.35;}
@media (max-width:900px){ .journal-grid{grid-template-columns:1fr 1fr;} .journal-item:nth-child(3){display:none;} }
@media (max-width:640px){ .journal-grid{grid-template-columns:1fr;} .journal-item:nth-child(2){margin-top:0;} .journal-item:nth-child(3){display:block;} .journal-img{height:40vh;} }

/* -------- faq -------- */
.faq{padding:130px 0;}
.faq h2{font-size:clamp(42px,6.8vw,110px); margin:0 0 70px;}
.faq-item{border-top:1px solid var(--line);}
.faq-item:last-child{border-bottom:1px solid var(--line);}
.faq-item h2,.faq-item h3{margin:0; font:inherit;}
.faq-q{width:100%; border:0; background:transparent; padding:26px 0; display:flex; justify-content:space-between; color:inherit; font-family:var(--f-display); font-weight:600; font-size:clamp(18px,2.2vw,30px); text-align:left;}
.faq-plus{transition:transform .35s var(--ease); color:var(--teal); font-weight:400;}
.faq-item.open .faq-plus{transform:rotate(45deg);}
/* height:0 hides a panel from the eye but not from a screen reader, so every
   answer was being announced whether or not it was open. visibility takes it
   out of the accessibility tree and the tab order as well. */
.faq-a{height:0; overflow:hidden;}
.faq-item:not(.open) .faq-a{visibility:hidden;}
.faq-item.open .faq-a{visibility:visible;}
.faq-a p{max-width:720px; margin:0; padding:0 0 28px; line-height:1.65; color:var(--lead);}

/* -------- inquiry block: the dedicated request form on /pricing --------
   The page argues that five things move a quotation, and renders them as
   numbered prose-blocks. The form continues that sequence rather than sitting
   under it as a widget: same numbers, same hairline rules, same rhythm. Dark
   ground, because the field styling below it is written for one.

   Teal: the eyebrow keeps the site-wide role, and the focused field takes it
   transiently. The step numbers and the email link stay neutral so the section
   never shows two persistent teal signals at once. */
/* the form lives on its own page now, so it needs its own top spacing rather
   than borrowing a diagonal's padding, and it must clear the fixed header */
.inquiry{padding:150px 0 var(--s6);}
/* /pricing keeps the argument and hands off to that page */
.inquiry-cta{text-align:left;}
.inquiry-cta-btn{display:inline-flex; align-items:center; gap:12px; border:1px solid #fff;
  padding:17px 26px; color:#fff; text-transform:uppercase; font-size:11px; letter-spacing:.16em;
  transition:.25s var(--ease);}
.inquiry-cta-btn:hover{background:#fff; color:var(--ink);}
/* what happens after you send it, answered before you send it */
.inq-next{border-top:1px solid var(--line-light); padding-top:var(--s3); margin-top:var(--s4);}
.inq-next-t{font-size:10px; text-transform:uppercase; letter-spacing:.16em; color:var(--slate); margin:0 0 var(--s2);}
.inq-next ol{margin:0; padding-left:1.2em; color:var(--steel); font-size:14px; line-height:1.65;}
.inq-next li{margin-bottom:10px;}

.inquiry-grid{display:grid; grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr); gap:8vw; align-items:start;}
.inquiry h2{font-size:clamp(34px,4.4vw,64px); margin:0 0 24px; letter-spacing:-.02em;}
.inquiry-aside{position:sticky; top:120px;}

/* one numbered question per row, echoing .prose-block */
.inq-step{display:grid; grid-template-columns:56px minmax(0,1fr); gap:var(--s3);
  border-top:1px solid var(--line-light); padding:var(--s4) 0 var(--s3);}
.inq-step:first-of-type{border-top:0; padding-top:0;}
.inq-num{font-family:var(--f-display); font-weight:600; font-size:12px; letter-spacing:.08em;
  color:var(--slate); font-variant-numeric:tabular-nums; padding-top:6px;}
.inq-q{display:block; font-family:var(--f-display); font-weight:600; font-size:17px;
  letter-spacing:-.01em; color:#fff; margin-bottom:var(--s2);}
.inq-hint{display:block; font-size:13px; line-height:1.5; color:var(--slate); margin:-10px 0 var(--s2);}
.inq-pair{display:grid; grid-template-columns:1fr 1fr; gap:var(--s3);}

/* the contact block is deliberately quieter: the brief is the interesting part */
.inq-you{border-top:1px solid var(--line-light); padding-top:var(--s4); margin-top:var(--s2);
  padding-left:calc(56px + var(--s3));}
.inq-you .inq-q{margin-bottom:var(--s3);}

/* fields, boutique treatment: small tracked label over generous input type */
.inquiry .field{margin-bottom:var(--s3);}
.inquiry .field:last-child{margin-bottom:0;}
.inquiry .field label{font-size:10px; letter-spacing:.16em; color:var(--slate); margin-bottom:10px;}
.inquiry .field input,.inquiry .field textarea,.inquiry .field select{
  font-size:19px; line-height:1.45; padding:8px 0 12px; color:#fff;
  border-bottom:1px solid rgba(255,255,255,.22); transition:border-color .25s var(--ease), box-shadow .25s var(--ease);}
.inquiry .field input::placeholder,.inquiry .field textarea::placeholder{color:#5c6070;}
/* outline:none on the shared rule left keyboard users with no focus cue at all */
.inquiry .field input:focus,.inquiry .field textarea:focus,.inquiry .field select:focus{
  border-bottom-color:var(--teal-light); box-shadow:0 1px 0 var(--teal-light);}
.inquiry .field textarea{min-height:96px;}
/* native selects and date pickers otherwise render in the OS light theme */
.inquiry .field select{appearance:none; -webkit-appearance:none; padding-right:24px; cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23858B9C' stroke-width='1.3'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 2px center; background-size:10px 6px;}
.inquiry .field input[type=date]{color-scheme:dark;}

.inquiry .form-submit{margin-top:var(--s3); margin-left:calc(56px + var(--s3));
  padding:19px 34px; font-size:11px; letter-spacing:.16em;}
.inquiry .form-note{margin-left:calc(56px + var(--s3));}
/* Hiding the whole form on success collapsed the page to almost nothing and
   left a single line of grey text where a 1400px form had been, so the
   confirmation was the easiest thing on the page to miss. It gets the weight
   of a real answer instead, and the note keeps carrying the live region. */
.form-done{margin-left:calc(56px + var(--s3)); max-width:34em; padding-top:var(--s2);}
.form-done h2{font-family:var(--f-display); font-weight:800; letter-spacing:-.02em;
  font-size:clamp(28px,3.2vw,46px); line-height:1.05; margin:var(--s2) 0 var(--s3); color:#fff;}
.form-done p{color:var(--steel); font-size:15px; line-height:1.7; margin:0 0 var(--s3);}
.form-done-links{border-top:1px solid var(--line-light); padding-top:var(--s3);}
.form-done-links a{color:#fff; border-bottom:1px solid rgba(255,255,255,.4);}
.form-sent .form-note{display:none;}
.inquiry .form-note{font-size:14px;}
/* the shared rule only hides .field, which would leave the numbers and
   questions standing over an empty form once it is sent */
.inquiry .form-sent .inq-step,.inquiry .form-sent .inq-you{display:none;}

@media (max-width:900px){
  .inquiry-grid{grid-template-columns:1fr; gap:var(--s4);}
  .inquiry-aside{position:static;}
}
@media (max-width:640px){
  .inq-step{grid-template-columns:1fr; gap:var(--s1); padding:var(--s3) 0 var(--s2);}
  .inq-num{padding-top:0;}
  .inq-pair{grid-template-columns:1fr; gap:0;}
  .inq-you{padding-left:0;}
  .inquiry .form-submit,.inquiry .form-note,.form-done{margin-left:0; width:100%;}
}

/* -------- footer -------- */
.footer{padding:140px 0 0; overflow:hidden; background:var(--void); color:#fff;}
.footer-main{display:grid; grid-template-columns:1fr 1fr; gap:8vw;}
.footer h2{font-size:clamp(48px,7vw,110px); margin:0 0 36px; letter-spacing:-.02em;}
.footer-email{display:inline-block; font-size:clamp(18px,2.6vw,36px); border-bottom:1px solid #fff; padding-bottom:10px; color:var(--teal-light);}
.form-row{display:grid; grid-template-columns:1fr 1fr; gap:20px;}
.field{margin-bottom:26px;}
.field label{display:block; font-size:10px; text-transform:uppercase; letter-spacing:.12em; color:var(--steel); margin-bottom:8px;}
.field input,.field textarea,.field select{width:100%; border:0; border-bottom:1px solid #4a4c52; background:transparent; color:#fff; padding:10px 0; outline:none; font-family:var(--f-text);}
.field textarea{resize:vertical; min-height:80px;}
/* Both of these are the browser painting its own light chrome onto a dark
   form. The option list is drawn by the OS from the select's own colours, and
   Chrome repaints an autofilled input with a hardcoded pale background that no
   background-color can override: only the inset shadow trick reaches it. */
.field select{color-scheme:dark;}
.field select option{background:var(--void); color:#fff;}
/* The open dropdown is painted by the OS, which uses its own selection blue.
   These are the two hooks browsers do honour: the inset shadow is the Firefox
   route, the background the Chromium one. */
.field select option:checked,
.field select option:hover{background:var(--teal); color:#fff;
  box-shadow:0 0 10px 100px var(--teal) inset;}
/* checkboxes, radios, range thumbs and the focus ring pick up the brand too */
:root{accent-color:var(--teal);}
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus,
.field textarea:-webkit-autofill,
.field select:-webkit-autofill{
  -webkit-text-fill-color:#fff; caret-color:#fff;
  -webkit-box-shadow:0 0 0 1000px var(--void) inset;
  box-shadow:0 0 0 1000px var(--void) inset;
  /* the repaint is on a transition, so outrunning it is the only way to stop
     the pale flash returning after the field is touched */
  transition:background-color 9999s ease-out 0s;}
.field input:-webkit-autofill:focus{
  -webkit-box-shadow:0 0 0 1000px var(--void) inset, 0 1px 0 var(--teal-light);
  box-shadow:0 0 0 1000px var(--void) inset, 0 1px 0 var(--teal-light);}
/* the shared rule sets outline:none and replaced it with nothing, so the
   footer form had no focus indicator at all for keyboard users */
.field input:focus,.field textarea:focus,.field select:focus{
  border-bottom-color:var(--teal-light); box-shadow:0 1px 0 var(--teal-light);}
.form-submit{border:1px solid #fff; background:transparent; color:#fff; padding:14px 20px; text-transform:uppercase; font-size:11px; letter-spacing:.12em; transition:.25s;}
.form-submit:hover{background:#fff; color:var(--ink);}
.form-submit[disabled]{opacity:.5; cursor:wait;}
.hp{position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; margin:0;}
.form-note{margin:18px 0 0; font-size:13px; line-height:1.6; color:var(--steel); min-height:1.6em;}
.form-note.ok{color:var(--teal-light);}
.form-note.err{color:#e0a3a3;}
.form-sent .field,.form-sent .form-submit{display:none;}
.form-sent .form-note{font-size:15px; color:#fff;}
.footer-meta{margin-top:100px; display:flex; justify-content:space-between; align-items:end; padding-bottom:28px; font-size:11px; text-transform:uppercase; letter-spacing:.12em; color:var(--steel);}
.socials{display:flex; gap:16px;}
.socials a:hover{color:var(--teal-light);}
.footer-word{font-size:clamp(70px,17vw,320px); white-space:nowrap; margin-left:-.03em; margin-bottom:-.2em; font-weight:800; letter-spacing:-.03em;}
.footer-word .slash{color:var(--teal-light);}
.footer-offices{display:grid; grid-template-columns:1fr 1fr 1fr; gap:40px; margin-top:90px; font-size:13px; line-height:1.7; color:var(--steel); font-style:normal;}
.footer-offices strong{display:block; color:#fff; font-size:10px; text-transform:uppercase; letter-spacing:.12em; margin-bottom:8px; font-weight:600;}
.footer-offices a{border-bottom:1px solid rgba(255,255,255,.25);}
.footer-offices + .footer-meta{margin-top:56px;}
@media (max-width:900px){ .footer-offices{grid-template-columns:1fr 1fr;} }
@media (max-width:640px){ .footer-offices{grid-template-columns:1fr; gap:24px;} }
@media (max-width:900px){ .footer-main{grid-template-columns:1fr;} .form-row{grid-template-columns:1fr;} }
@media (max-width:640px){ .footer-meta{flex-direction:column; align-items:flex-start; gap:20px;} }

/* -------- logo images (official lockup: teal arrow logogram + white wordmark, transparent) -------- */
.logo{display:flex; align-items:center;}
.logo img{height:24px; width:auto; object-fit:contain;}

.hero-word{display:flex; align-items:flex-end; bottom:12vh; font-size:16px;}
.hero-word img{width:clamp(240px,36vw,680px); height:auto; object-fit:contain;}
.hero-scroll{bottom:5vh;}
.footer-word{display:flex; margin-bottom:0; padding-bottom:40px;}
.footer-word img{width:clamp(220px,32vw,600px); height:auto; object-fit:contain;}
.hero-media video{width:100%; height:100%; object-fit:cover;}
.project-media video{width:100%; height:100%; object-fit:cover;}
.project-media .rp-tag{position:absolute; left:var(--s2); bottom:var(--s2); z-index:2; color:#fff;}

/* -------- preloader / grain / cursor (reference DNA) -------- */
/* Solid in the stylesheet, so the curtain is already covering the page on the
   first frame the browser paints. It used to be switched on by JS instead,
   which let the page flash into view before the curtain dropped over it. */
.preloader{display:flex; position:fixed; inset:0; z-index:1000; background:var(--void);
  align-items:center; justify-content:center; overflow:hidden;}
/* The curtain is a grid of solid blocks rather than one panel, so it can be
   dissolved block by block in a random order instead of sliding away. */
.preloader-grid{position:absolute; inset:0; display:grid;
  grid-template-columns:repeat(var(--pcols,24),1fr);
  grid-template-rows:repeat(var(--prows,14),1fr);}
.preloader-grid i{display:block; background:var(--void);
  /* overdraw a hair so sub-pixel rounding cannot show seams between blocks */
  outline:1px solid var(--void); outline-offset:-1px;}
/* The lockup, not a wordmark set in the fallback display face. It sits above
   the dissolving blocks and goes with them. */
.preloader-mark{position:relative; z-index:2; display:block; height:auto;
  width:min(52vw,440px);}
/* Set in <head> where the dissolve cannot run: a background tab gets no
   requestAnimationFrame, and reduced motion should not be made to wait. */
html.no-curtain .preloader{display:none;}
html.is-loading, body.is-loading{overflow:hidden;}
.noise{position:fixed; inset:0; z-index:999; pointer-events:none; opacity:.03; mix-blend-mode:multiply;
  background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");}
.cursor-label{position:fixed; left:0; top:0; z-index:200; width:82px; height:82px; border-radius:50%; background:#fff; color:#000;
  display:grid; place-items:center; text-align:center; font-size:10px; text-transform:uppercase; letter-spacing:.08em;
  opacity:0; pointer-events:none; transform:translate(-50%,-50%) scale(.7);}
.cross{width:14px; height:14px; position:relative; display:inline-block;}
.cross::before,.cross::after{content:""; position:absolute; background:currentColor; left:50%; top:50%; transform:translate(-50%,-50%);}
.cross::before{width:14px; height:1px;}
.cross::after{width:1px; height:14px;}
.cinematic-card{position:absolute; z-index:3; width:220px; height:320px; overflow:hidden; right:8vw; bottom:14vh;
  border:8px solid rgba(255,255,255,.12); box-shadow:0 35px 80px rgba(0,0,0,.35);}
@media (max-width:900px){ .cinematic-card{width:190px; height:260px;} }
@media (max-width:640px){ .cursor-label,.archive-preview{display:none!important;} .cinematic-card{width:150px; height:220px; right:5vw; bottom:9vh;} }
@media (prefers-reduced-motion:reduce){ .cursor-label,.noise{display:none!important;} }

/* -------- interior pages -------- */
/* The band IS the first screen: exactly one viewport, so nothing from the
   section below shows before the visitor scrolls. svh not vh, because on a
   phone 100vh measures the viewport with the browser chrome retracted and
   leaves the same sliver showing. */
.page-hero{background:var(--void); color:#fff;
  padding:calc(58px + var(--s5)) 0 var(--s5);
  min-height:100vh; min-height:100svh;
  display:flex; align-items:center;}
.page-hero > .container{width:100%;}
/* A short window gets tighter padding, not a shorter band: min-height means
   copy taller than the viewport pushes the band down rather than being cut. */
@media (max-height:620px){ .page-hero{padding-block:calc(58px + var(--s3)) var(--s3);} }
/* Two columns from 1000px up: the headline reads left, the answer sits at its
   baseline on the right. Stacked, the right half of the band was empty and the
   dark panel ended in the middle of the first frame with nothing in it. */
@media (min-width:1000px){
  .page-hero .container{display:grid; grid-template-columns:minmax(0,1.15fr) minmax(0,.85fr);
    column-gap:var(--s5); align-items:end;}
  .page-hero .eyebrow{grid-column:1 / -1;}
  .page-hero h1{grid-column:1; margin:0;}
  .page-hero .answer{grid-column:2; margin:0 0 6px; max-width:46ch;}
  .page-hero .eyebrow + h1{margin-top:0;}
}
.page-hero .eyebrow{color:var(--teal-light); margin:0 0 var(--s2);}
/* Scales with the viewport AND with its own length: --len is set per page from
   the character count, so a 90-character article title does not render at the
   size of "Eighteen projects." and run off the bottom of the screen. */
.page-hero h1{font-family:var(--f-display); font-weight:800; letter-spacing:-.03em; line-height:.98;
  margin:0; max-width:18ch; overflow-wrap:break-word;
  font-size:clamp(30px, calc(7vw * var(--len, 1)), calc(110px * var(--len, 1)));}
.page-hero.long h1{max-width:24ch; line-height:1.04;}
.page-hero .answer{color:var(--steel); margin:var(--s3) 0 0;}
@media (max-width:640px){ .answer{padding-left:var(--s1); font-size:16px;} }
.page-body{padding:var(--s7) 0;}
/* This had no top margin at all, so every chapter heading butted against
   whatever ran above it: the post list on /insights, the CTA on /services.
   A heading opening its own section keeps zero, since the band already pads. */
.page-body h2{font-family:var(--f-display); font-weight:700; letter-spacing:-.02em; line-height:1.05;
  font-size:clamp(26px,3.4vw,46px); margin:var(--s6) 0 var(--s3);}
.page-body .container > h2:first-child,
.page-body .container > *:first-child{margin-top:0;}
.page-body h3{font-family:var(--f-display); font-weight:600; letter-spacing:-.01em; font-size:22px; margin:0 0 var(--s1);}
.page-body p{max-width:68ch; color:var(--lead); margin:0 0 var(--s2);}
.prose-block{border-top:1px solid var(--line); padding:var(--s4) 0; display:grid;
  grid-template-columns:1fr 2.4fr; gap:var(--s4); align-items:start;}
.prose-block:last-child{border-bottom:1px solid var(--line);}
.prose-block .num{font-size:13px; color:var(--slate);}
/* A four-column results table cannot squash to 375px without lying about the
   data, so it scrolls inside its own box instead of pushing the page sideways. */
.table-scroll{overflow-x:auto; -webkit-overflow-scrolling:touch; margin-top:var(--s3);}
.award-table{width:100%; min-width:560px; border-collapse:collapse;}
.award-table th{text-align:left; font-size:11px; text-transform:uppercase; letter-spacing:.12em;
  color:var(--slate); font-weight:600; padding:0 var(--s3) var(--s2) 0; border-bottom:1px solid var(--line);}
.award-table td{padding:var(--s2) var(--s3) var(--s2) 0; border-bottom:1px solid var(--line);
  font-size:15px; vertical-align:top;}
.award-table td:first-child{font-weight:600; color:var(--ink);}
.award-table .result{color:var(--teal); white-space:nowrap;}
/* 280px only fits four tracks at 1440, which stranded the fifth service
   line on a row of its own. 240 fits all five, and the last row centres
   itself rather than sitting stranded left at any other width. */
.card-grid{display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
  gap:var(--s3); margin-top:var(--s4); justify-content:center;}
.card{border:1px solid var(--line); padding:var(--s3); display:flex; flex-direction:column; gap:var(--s1);}
.card .media{aspect-ratio:16/9; overflow:hidden; margin:calc(var(--s3) * -1) calc(var(--s3) * -1) var(--s2);}
.card p{font-size:14px; margin:0;}
.card a.more{margin-top:auto; padding-top:var(--s2); font-size:11px; text-transform:uppercase; letter-spacing:.1em; color:var(--teal);}
@media (max-width:900px){ .prose-block{grid-template-columns:1fr; gap:var(--s2);} }
.nav a.is-current,.nav-mobile a.is-current{color:var(--teal-light);}
.lang-switch{font-size:14px!important; letter-spacing:.06em!important; color:var(--teal-light)!important; border-bottom:0!important;}
.nav-mobile .lang-switch{font-family:var(--f-text); font-weight:500; font-size:15px!important; padding-top:var(--s3);}

/* -------- article body -------- */
.article{max-width:760px;}
.article h2{font-family:var(--f-display); font-weight:700; letter-spacing:-.02em; line-height:1.12;
  font-size:clamp(24px,2.8vw,34px); margin:var(--s5) 0 var(--s2);}
.article p{font-size:17px; line-height:1.7; color:var(--lead); margin:0 0 var(--s2); max-width:68ch;}
.article ul{margin:0 0 var(--s3); padding-left:20px; color:var(--lead); font-size:17px; line-height:1.7;}
.article li{margin:var(--s1) 0;}
.article a{color:var(--teal); border-bottom:1px solid currentColor; word-break:break-word;}
.post-list{border-top:1px solid var(--line); margin-top:var(--s4);}
.post-row{display:grid; grid-template-columns:120px 1fr auto; gap:var(--s3); align-items:baseline;
  padding:var(--s3) 0; border-bottom:1px solid var(--line); transition:background .25s;}
.post-row:hover{background:var(--bone);}
.post-row time{font-size:12px; color:var(--slate); letter-spacing:.06em;}
.post-row h3{font-family:var(--f-display); font-weight:600; letter-spacing:-.01em;
  font-size:clamp(17px,1.9vw,22px); line-height:1.3; margin:0;}
.post-row .go{font-size:11px; text-transform:uppercase; letter-spacing:.1em; color:var(--teal);}
@media (max-width:640px){ .post-row{grid-template-columns:1fr; gap:var(--s1);} .post-row .go{display:none;} }

/* -------- project case study -------- */
.work-hero{margin:0 0 var(--s4); aspect-ratio:16/9; overflow:hidden;}
/* Full bleed inside the article measure, matching the article lead images: the
   film is the case study, not an illustration beside it. */
.article > .work-hero{margin-left:50%; transform:translateX(-50%); width:100vw;
  max-width:100vw; margin-top:calc(var(--s6) * -1); margin-bottom:var(--s5);
  max-height:82vh;}
.work-hero img, .work-hero video{width:100%; height:100%; object-fit:cover; display:block;}
/* Play control over the poster. Without it a film hero is indistinguishable
   from a still, and there is nothing to press. */
.work-hero.film{position:relative;}
.film-play{position:absolute; inset:auto auto var(--s3) var(--s3); display:inline-flex;
  align-items:center; gap:10px; padding:12px 20px 12px 14px; border:0; cursor:pointer;
  background:rgba(18,17,22,.72); color:#fff; font:inherit; font-size:12px;
  letter-spacing:.1em; text-transform:uppercase; backdrop-filter:blur(6px);
  transition:background .25s var(--ease), transform .25s var(--ease);}
.film-play:hover{background:var(--teal); transform:translateY(-2px);}
.film-play:focus-visible{outline:2px solid var(--teal-light); outline-offset:3px;}
.film-play svg{width:18px; height:18px; fill:currentColor; flex:none;}
.work-hero.is-playing video{object-fit:contain; background:var(--void);}
@media (max-width:640px){ .film-play{inset:auto auto var(--s2) var(--s2); padding:13px 16px 13px 12px;} }
.work-meta{display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:var(--s3);
  margin:0 0 var(--s5); padding:var(--s3) 0; border-top:1px solid var(--line); border-bottom:1px solid var(--line);}
.work-meta dt{font-size:10px; text-transform:uppercase; letter-spacing:.12em; color:var(--slate); margin-bottom:var(--s1);}
.work-meta dd{margin:0; font-size:14px; line-height:1.45; color:var(--ink);}
/* Case-study gallery. The branding projects are the deliverable, so one hero
   frame is not enough to show what was actually made. */
.work-gallery{display:grid; grid-template-columns:repeat(2,1fr); gap:var(--s2);
  margin:var(--s3) 0 var(--s4);}
.work-gallery figure{margin:0;}
.work-gallery img{width:100%; aspect-ratio:4/3; object-fit:cover; display:block;}
.work-gallery figcaption{font-size:12px; line-height:1.4; color:var(--slate); margin-top:var(--s1);}
@media (max-width:640px){ .work-gallery{grid-template-columns:1fr;} }

/* An inline photograph inside a body section. `wide` breaks out of the 760px
   article measure, because a stage or a studio floor needs the room. */
/* ===================================================================
   VISUAL LANGUAGE — standing rules, 8 Sep 2026, from the client review.
   These apply to every page, not just the ones they were asked for.

   1. A figure marked .wide is full-bleed: the full viewport width, edge to
      edge, whatever container it sits in.
   2. Captions are never shown. They stay in the DOM for screen readers and
      for the record, but nothing prints under an image.
   3. Film in the body plays itself, muted and looping, like the hero.
   4. Galleries mix sizes and grow on hover, and the growth is allowed to
      spill past its cell rather than being clipped.
   =================================================================== */

/* 1. full-bleed anywhere, not only inside .article */
.page-figure.wide,
.media-full{margin-left:50%; transform:translateX(-50%); width:100vw; max-width:100vw;}
/* the films carry their own 2.39:1 letterbox baked into the frame, which read
   as more ghost space between two full-bleed clips. Framing them at 21:9 and
   covering crops those bars off instead of stacking them. */
.page-figure.wide img,.page-figure.wide video,
.media-full img,.media-full video{width:100%; max-height:88vh; object-fit:cover;}
/* 21:9 crops the cinema clips' own letterbox off. A portrait film in that
   band is a thin horizontal slice of a vertical picture, which is what the
   black block on /faq was, so portrait keeps its own shape. */
.page-figure.wide video,.media-full video{aspect-ratio:21/9;}
.page-figure.wide video[data-portrait],
.media-full video[data-portrait]{aspect-ratio:9/16; max-height:88vh; width:auto;
  margin-inline:auto; object-fit:contain; background:var(--void);}
.page-figure.wide:has(video[data-portrait]){display:flex; justify-content:center;
  background:var(--void);}

/* 2. no captions on images, anywhere. Kept for assistive tech. */
figcaption{position:absolute!important; width:1px; height:1px; overflow:hidden;
  clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; margin:-1px; padding:0; border:0;}

/* 4. varied-size gallery that can overflow its cell on hover.
   The section clears its own overflow so a growing tile is not clipped. */
.media-wall{margin-block:var(--s6); margin-left:50%; transform:translateX(-50%);
  width:100vw; max-width:100vw;}

/* A grid tile can only scale on top of its neighbours; they never move. To
   push them the tiles have to share a row and compete for its width, which is
   exactly what flex-grow shares do: raising the hovered tile's share takes
   that width off the others, and the transition animates the give-and-take.
   Rows never wrap, so a tile growing can never bump one onto another line. */
.media-row{display:flex; flex-wrap:nowrap; width:100%;
  height:clamp(200px, 23vw, 400px); overflow:hidden;}
.media-row.banner{height:clamp(260px, 34vw, 620px);}
.media-row figure{flex:1 1 0; min-width:0; margin:0; overflow:hidden; position:relative;
  transition:flex-grow .55s var(--ease);}
.media-row figure.w2{flex-grow:2;}
.media-row figure img,.media-row figure video{width:100%; height:100%; object-fit:cover;
  transition:transform .7s var(--ease);}
/* the hovered tile takes roughly two thirds of the row off its neighbours */
.media-row figure:hover{flex-grow:4;}
.media-row figure.w2:hover{flex-grow:6;}
.media-row figure:hover img,.media-row figure:hover video{transform:scale(1.04);}
@media (max-width:900px){
  .media-row{flex-wrap:wrap; height:auto;}
  .media-row figure{flex:1 1 50%; height:44vw;}
  .media-row.banner figure{flex-basis:100%; height:56vw;}
  .media-row figure:hover,.media-row figure.w2:hover{flex-grow:1;}
}
@media (prefers-reduced-motion:reduce){ .media-row figure:hover,.media-row figure.w2:hover{flex-grow:inherit;} }

/* a growing tile has to be able to leave its section */
.section:has(.media-wall){overflow:visible;}

/* Full-bleed media butts against its neighbour. A white band between two
   films is not spacing, it reads as a rendering fault, and the same gap above
   a full-bleed opener left the section's padding stranded as a white strip.
   Air is spent only where the medium actually changes, image to film. */
.page-figure.wide{margin-block:var(--s6);}
/* The hero is a centred flex box, so a 50% margin inside it is measured
   against the flex line rather than the viewport and full-bleed lands
   off-centre. Hero media stays within the measure. */
.page-hero .page-figure.wide{margin-left:0; transform:none; width:100%; max-width:100%;}

/* -------- article cover -------------------------------------------------
   One wide band cannot hold every cover. The band was 2.22:1 while ten of the
   seventeen sources are 16:9 and three are portrait at 0.80, so a landscape
   shot lost a fifth of its height and a portrait lost nearly two thirds: the
   subject slid out of frame and blur filled the rest.

   So the picture gets a column of its own, near square, which crops a 16:9 and
   a portrait by about the same small amount. The type sits beside it on solid
   ground rather than over the photograph, which needs no scrim and stays
   legible whatever the image is. And the band is short enough that the article
   itself starts inside the first screen instead of the cover taking all of it.
   ------------------------------------------------------------------------ */
.page-hero.article-cover{min-height:0; padding:0; display:block;
  background:var(--void); overflow:hidden;}
/* the cover owns the first screen; svh so a phone's collapsing toolbar does
   not leave a strip of the next section showing under it */
.article-cover .cover-grid{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);
  align-items:stretch; min-height:100svh; max-height:960px;}
/* centred rather than bottom-aligned: over a full screen a bottom-set title
   leaves a void above it that reads as a mistake rather than as space */
.article-cover .cover-copy{display:flex; flex-direction:column; justify-content:center;
  padding:var(--s6) var(--s5) var(--s6) var(--pad);}
.article-cover .cover-copy .eyebrow{color:var(--teal-light); margin:0 0 var(--s3);}
.article-cover .cover-copy h1{margin:0; color:#fff;
  font-family:var(--f-display); font-weight:800; letter-spacing:-.03em; line-height:1.03;
  /* build.py already measures the headline and writes --len; the floor keeps a
     long title reading as a masthead rather than a caption */
  font-size:calc(clamp(30px,3.5vw,60px) * max(var(--len,1), .72)); text-wrap:balance;}
.article-cover .cover-media{margin:0; position:relative; overflow:hidden; min-height:100%;}
.article-cover .cover-media img,
.article-cover .cover-media video{position:absolute; inset:0;
  width:100%; height:100%; object-fit:cover; display:block;}

@media (max-width:900px){
  .article-cover .cover-grid{grid-template-columns:1fr; min-height:0;}
  .article-cover .cover-media{order:-1; aspect-ratio:4/3; min-height:0;}
  .article-cover .cover-copy{padding:var(--s5) var(--pad) var(--s4);}
}

.page-figure.wide{margin-block:var(--s6);}
/* only two full-bleed clips in a row butt together */
.page-figure.wide + .page-figure.wide{margin-top:0;}
.page-figure.wide:has(+ .page-figure.wide){margin-bottom:0;}
.page-figure.wide:has(img) + .page-figure.wide:has(video),
.page-figure.wide:has(video) + .page-figure.wide:has(img){margin-top:var(--s5);}
/* a full-bleed opener sits flush with the top of its band */
.page-body > .container > .page-figure.wide:first-child{margin-top:calc(var(--s7) * -1);}

.page-figure{margin:var(--s3) 0 var(--s4);}
.page-figure img, .page-figure video{width:100%; display:block; aspect-ratio:16/9; object-fit:cover;}
/* Inside an article the image is the editorial, not a decorative band, so it
   runs at its own aspect ratio. Cropping a portrait frame to 16:9 loses the
   subject, which is the whole reason it was worth including. */
.article .page-figure img, .article .page-figure video{aspect-ratio:auto; height:auto; object-fit:contain;}
/* A film inside an article is content. Native controls over a poster, and
   preload="none" so the page costs nothing until somebody presses play. */
.article .page-figure.film video{width:100%; display:block; background:var(--void);
  aspect-ratio:16/9; object-fit:contain;}
/* Inline figures fill the measure instead of sitting narrow with a field of
   white beside them. */
.article .page-figure:not(.wide):not(.badge){width:100%; margin-inline:0;}
.article .page-figure:not(.wide):not(.badge) img{width:100%;}
.page-figure figcaption{font-size:12px; line-height:1.4; color:var(--slate); margin-top:var(--s1); max-width:56ch;}
/* Inside the 760px article measure, `wide` has to break out of the column, not
   just out of the container padding, or a lead image reads as a narrow strip. */
/* Full bleed, edge to edge: the lead image is the opening of the piece, so when
   it comes first it meets the hero band instead of floating below it. */
.article .page-figure.wide{margin-left:50%; transform:translateX(-50%); width:100vw;
  max-width:100vw; margin-block:var(--s6);}
.article > .page-figure.wide:first-child{margin-top:calc(var(--s7) * -1); margin-bottom:var(--s6);}
.article .page-figure.wide img{max-height:82vh; object-fit:cover;}
/* An award seal is a portrait lockup on flat ground: it must not be cropped to
   16:9 like a photograph, and it does not need the full measure. */
/* Seals sit in a row. Three of them stacked down the page is a trophy cabinet;
   side by side they read as one line of evidence. */
.page-figure.badge{display:inline-block; vertical-align:bottom; width:150px;
  margin:var(--s3) var(--s2) var(--s3) 0;}
.page-figure.badge img{aspect-ratio:auto; height:auto; object-fit:contain;}
.page-figure.badge figcaption{font-size:11px;}
/* Editorial rather than a directory: the six lead projects run two-up and
   large, the rest fall back to a denser three-up. */
.work-grid{display:grid; grid-template-columns:repeat(6,1fr); gap:var(--s3) var(--s3); margin-top:var(--s4);}
.work-card{grid-column:span 2;}
.work-card.lead{grid-column:span 3;}
/* The grid only tiles evenly while leads stay even and plain cards stay a
   multiple of three; add a nineteenth project and the last row rags again.
   A lone trailing card centres itself rather than sitting stranded left. */
.work-card:last-child:nth-child(3n+1){grid-column:3 / span 2;}
@media (max-width:1100px){ .work-grid{grid-template-columns:repeat(4,1fr);}
  .work-card{grid-column:span 2;} .work-card.lead{grid-column:span 4;} }
@media (max-width:700px){ .work-grid{grid-template-columns:1fr;}
  .work-card, .work-card.lead{grid-column:span 1;} }
.work-card{display:flex; flex-direction:column; border:1px solid var(--line); overflow:hidden;
  transition:transform .35s var(--ease), border-color .35s;}
.work-card:hover{transform:translateY(-4px); border-color:var(--steel);}
.work-card .shot{aspect-ratio:4/3; overflow:hidden; position:relative; background:var(--mist);}
.work-card.lead .shot{aspect-ratio:16/9;}
.work-card.lead h3{font-size:clamp(26px,2.6vw,38px);}
/* A film project should move. The clip sits over the still and fades in on
   hover, so the card never waits on a video to have something to show. */
.work-card .shot video{position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  opacity:0; transition:opacity .45s var(--ease);}
.work-card:hover .shot video{opacity:1;}
@media (hover:none){ .work-card .shot video{display:none;} }
.work-card .shot img{width:100%; height:100%; object-fit:cover; transition:transform .5s var(--ease);}
.work-card:hover .shot img{transform:scale(1.04);}
.work-card .body{padding:var(--s3); display:flex; flex-direction:column; gap:6px; flex:1;}
.work-card .cat{font-size:10px; text-transform:uppercase; letter-spacing:.12em; color:var(--slate);}
.work-card h3{font-family:var(--f-display); font-weight:700; letter-spacing:-.02em; font-size:22px; margin:0; line-height:1.1;}
.work-card p{margin:0; font-size:14px; color:var(--lead);}
.work-card .award{font-size:11px; color:var(--teal); margin-top:auto; padding-top:var(--s2);}

/* ===================================================================
   LANDING PAGES (paid traffic)
   Built to the Trone Studio pattern the client referenced: a CTA in
   every section rather than one at the end, social proof immediately
   under the hero, and conversion through WhatsApp with the quote form
   as the quieter second option.

   Every button carries data-track, which site.js forwards to whichever
   pixel the page is carrying. No ids live in the markup.
   =================================================================== */
.lp-actions{display:flex; flex-wrap:wrap; gap:var(--s2); align-items:center; margin-top:var(--s4);}
.lp-cta{display:inline-flex; align-items:center; gap:10px; padding:18px 30px;
  font-family:var(--f-text); font-weight:600; font-size:13px; letter-spacing:.1em;
  text-transform:uppercase; border:1px solid transparent; transition:.25s var(--ease);}
/* WhatsApp is the primary route, so it takes the one solid button on screen */
.lp-cta.primary{background:var(--teal); color:#fff;}
.lp-cta.primary:hover{background:var(--teal-light); transform:translateY(-2px);}
.lp-cta.ghost{border-color:currentColor; color:inherit;}
.lp-cta.ghost:hover{background:currentColor;}
.dark .lp-cta.ghost:hover,.lp-band .lp-cta.ghost:hover{color:var(--ink);}
.paper .lp-cta.ghost:hover,.bone .lp-cta.ghost:hover{color:var(--paper);}
.lp-cta .wa{width:18px; height:18px; flex:none;}

/* a closing band, and the same band repeated mid-page so the offer is never
   more than a screen away */
.lp-band{background:var(--void); color:#fff; text-align:left;
  padding-block:var(--s7);}
/* a diagonal already pays for the top, so it only owes the bottom */
.lp-band.diagonal-top{padding-top:calc(3.5vw + var(--diag-clear));}
.lp-band h2{font-family:var(--f-display); font-weight:800; letter-spacing:-.03em;
  font-size:clamp(30px,4.2vw,62px); line-height:1.02; margin:0 0 var(--s3); max-width:18ch;}
.lp-band p{color:var(--steel); max-width:52ch; margin:0;}

/* the numbers the studio already publishes, set as evidence rather than decor */
.lp-stats{display:grid; grid-template-columns:repeat(4,1fr); gap:var(--s3);
  border-top:1px solid var(--line); margin-top:var(--s5); padding-top:var(--s4);}
.lp-stats strong{display:block; font-family:var(--f-display); font-weight:800;
  font-size:clamp(30px,3.6vw,54px); letter-spacing:-.03em; line-height:1;}
.lp-stats span{display:block; margin-top:10px; font-size:11px; text-transform:uppercase;
  letter-spacing:.12em; color:var(--slate);}
@media (max-width:640px){ .lp-stats{grid-template-columns:repeat(2,1fr); gap:var(--s4) var(--s3);} }

/* phone traffic is most of an ad campaign, and it should never have to scroll
   back to find the button */
.lp-sticky{position:fixed; left:0; right:0; bottom:0; z-index:180;
  display:flex; gap:10px; padding:10px var(--pad) calc(10px + env(safe-area-inset-bottom));
  background:rgba(18,17,22,.94); backdrop-filter:blur(14px);
  border-top:1px solid var(--line-light);
  transform:translateY(110%); transition:transform .35s var(--ease);}
.lp-sticky.show{transform:none;}
.lp-sticky .lp-cta{flex:1; justify-content:center; padding:15px 12px; font-size:12px;}
@media (min-width:901px){ .lp-sticky{display:none;} }

/* The reference's actual engine, which the first attempt missed: every section
   closes with a short question, and the button answers it. The question is the
   thing doing the persuading, so it is set as type, not as a caption. */
.lp-ask{font-family:var(--f-display); font-weight:600; letter-spacing:-.01em;
  font-size:clamp(19px,2.1vw,28px); margin:var(--s5) 0 var(--s3); max-width:26ch;}
.lp-band .lp-ask{color:#fff;}

/* Standards and process both run as a numbered vertical list in the reference,
   which the site already has as .prose-block; these only set the rhythm. */
.lp-list{margin-top:var(--s5);}
.lp-list .prose-block:first-child{border-top:1px solid var(--line);}
.lp-band .lp-list .prose-block{border-color:var(--line-light);}
.lp-band .lp-list .prose-block .num{color:var(--teal-light);}
.lp-band .lp-list h3{color:#fff;}
.lp-band .lp-list p{color:var(--steel);}

/* Recognition in place of the reference's client testimonials, because no
   client quote on record exists to print. */
.lp-quotes{display:grid; grid-template-columns:repeat(3,1fr); gap:var(--s3); margin-top:var(--s5);}
.lp-quotes blockquote{margin:0; padding:var(--s4); border:1px solid var(--line);
  display:flex; flex-direction:column; gap:var(--s3);}
.lp-quotes p{font-family:var(--f-display); font-weight:600; font-size:19px;
  line-height:1.35; letter-spacing:-.01em; margin:0;}
.lp-quotes cite{font-style:normal; font-size:11px; text-transform:uppercase;
  letter-spacing:.12em; color:var(--slate); margin-top:auto;}
@media (max-width:900px){ .lp-quotes{grid-template-columns:1fr;} }

/* -------- landing hero ---------------------------------------------------
   Kononenko took Site of the Day on minimalism, bold type and video across
   the page. The homepage already owns that pattern, so the landing hero
   reuses it rather than inventing a second one: film behind, a scrim that is
   dark where the type sits and clear where the picture is, and no furniture.
   The film is a 1.6 MB loop cut from the showreel, not the 11.4 MB reel:
   ad traffic is mostly phones on mobile data. */
.page-hero.lp-hero{min-height:100svh; max-height:1000px; padding:0;
  display:flex; align-items:flex-end; overflow:hidden; background:var(--void);}
.lp-hero .lp-hero-media{position:absolute; inset:0; margin:0; z-index:0;}
.lp-hero .lp-hero-media video{width:100%; height:100%; object-fit:cover; display:block;}
.lp-hero::after{content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background:linear-gradient(180deg, rgba(10,10,12,.55) 0%, rgba(10,10,12,.10) 34%,
                                     rgba(10,10,12,.45) 62%, rgba(10,10,12,.92) 100%);}
.lp-hero .container{position:relative; z-index:2; padding-bottom:var(--s6); padding-top:var(--s7);}
.lp-hero h1{color:#fff; max-width:16ch; text-shadow:0 2px 44px rgba(0,0,0,.45);}
.lp-hero .answer{color:#fff; border-left-color:var(--teal-light); max-width:46ch;}
.lp-hero .eyebrow{color:var(--teal-light);}
@media (max-width:640px){ .page-hero.lp-hero{min-height:92svh;} }

/* ===================================================================
   LANDING LAYOUT, matched to the reference the client sent.
   Measured off tronindo.co.id/trone-studio at 1440: a 1176px measure,
   services as a four-column row list rather than cards, two mirrored
   dark split-bands, a six-across process, and a centred close.
   Only the grid is borrowed; every colour and face is ours.
   =================================================================== */

/* services: number | title | description | tag, one row each */
.lp-rows{margin-top:var(--s5); border-top:1px solid var(--line);}
.lp-row{display:grid; grid-template-columns:70px minmax(0,1.9fr) minmax(0,2.4fr) minmax(0,.9fr);
  gap:var(--s3); align-items:start; padding:var(--s4) 0; border-bottom:1px solid var(--line);
  transition:background .3s var(--ease);}
.lp-row:hover{background:var(--bone);}
.lp-row .n{font-family:var(--f-display); font-weight:600; font-size:12px;
  letter-spacing:.08em; color:var(--slate); padding-top:5px; font-variant-numeric:tabular-nums;}
.lp-row h3{font-family:var(--f-display); font-weight:700; letter-spacing:-.02em;
  font-size:clamp(19px,1.7vw,25px); margin:0; line-height:1.15;}
.lp-row p{margin:0; color:var(--lead); font-size:15px; line-height:1.65;}
.lp-row .tag{font-size:10px; text-transform:uppercase; letter-spacing:.14em;
  color:var(--slate); padding-top:6px;}
@media (max-width:900px){
  .lp-row{grid-template-columns:44px minmax(0,1fr); gap:var(--s2) var(--s3);}
  .lp-row p{grid-column:2;} .lp-row .tag{grid-column:2; padding-top:0;}
}

/* the two dark bands: half type, half picture, the second one mirrored */
.lp-split{background:var(--void); color:#fff; padding-block:var(--s7); overflow:hidden;}
.lp-split .container{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:clamp(var(--s4),5vw,var(--s6)); align-items:center;}
.lp-split.mirror .container > *:first-child{order:2;}
.lp-split h2{font-family:var(--f-display); font-weight:800; letter-spacing:-.03em;
  font-size:clamp(28px,3.6vw,52px); line-height:1.04; margin:0 0 var(--s3);}
.lp-split > .container > figure{margin:0; aspect-ratio:4/5; overflow:hidden;}
.lp-split figure img,.lp-split figure video{width:100%; height:100%; object-fit:cover;}
.lp-split .lp-ask{color:#fff;}
.lp-split .lp-list .prose-block{border-color:var(--line-light);}
.lp-split .lp-list .prose-block .num{color:var(--teal-light);}
.lp-split .lp-list h3{color:#fff;}
.lp-split .lp-list p{color:var(--steel);}
@media (max-width:900px){
  .lp-split .container{grid-template-columns:1fr;}
  .lp-split.mirror .container > *:first-child{order:0;}
  .lp-split > .container > figure{aspect-ratio:16/10;}
}

/* process: six across, the way the reference runs it */
.lp-steps{display:grid; grid-template-columns:repeat(6,minmax(0,1fr)); gap:var(--s3);
  margin-top:var(--s5); border-top:1px solid var(--line); padding-top:var(--s4);}
.lp-step .n{font-family:var(--f-display); font-weight:700; font-size:12px;
  letter-spacing:.08em; color:var(--teal); margin-bottom:var(--s2); font-variant-numeric:tabular-nums;}
.lp-step h3{font-family:var(--f-display); font-weight:700; letter-spacing:-.01em;
  font-size:16px; line-height:1.2; margin:0 0 10px;}
.lp-step p{margin:0; font-size:13.5px; line-height:1.6; color:var(--lead);}
@media (max-width:1100px){ .lp-steps{grid-template-columns:repeat(3,minmax(0,1fr)); gap:var(--s4) var(--s3);} }
@media (max-width:640px){ .lp-steps{grid-template-columns:repeat(2,minmax(0,1fr));} }

/* the close is the one centred thing on the page */
.lp-close{text-align:center;}
.lp-close h2{margin-inline:auto; max-width:22ch;}
.lp-close p{margin-inline:auto;}
.lp-close .lp-ask{margin-inline:auto;}
.lp-close .lp-actions{justify-content:center;}

/* ===================================================================
   PLAYGROUND
   The reference for this is Lusion, whose signature is tactile,
   cursor-reactive play. Lusion ships 1.2 MB of Three.js with a hundred
   shader materials to do it. That would undo the whole performance
   pass on the very pages it sits on, so this is the same idea on a 2D
   canvas with no library at all: the studio's own work as bodies you
   can shove, throw and knock into each other, and click to open.
   =================================================================== */
.play{background:var(--void); color:#fff; padding-block:var(--s7) 0; overflow:hidden;}
.play h2{font-family:var(--f-display); font-weight:800; letter-spacing:-.03em;
  font-size:clamp(30px,4.2vw,62px); line-height:1.02; margin:0 0 var(--s3); max-width:18ch;}
.play p{color:var(--steel); max-width:50ch; margin:0;}
/* The stage is lit, not flat: two pools of light on a dark fall-off, so the
   shapes sit in a room instead of floating on a swatch. The hue is a custom
   property the scene writes on every click, which turns the ground with the
   objects rather than leaving one material changing against a fixed panel.
   Registering it is what lets it travel rather than snap. */
@property --play-hue{syntax:'<number>'; inherits:true; initial-value:173;}
.play-stage{position:relative; margin-top:var(--s5);
  height:clamp(380px,56vh,620px); cursor:grab;
  --play-hue:173;
  background:
    radial-gradient(118% 86% at 50% 4%,
      hsl(var(--play-hue) 38% 24% / .62) 0%, transparent 60%),
    radial-gradient(88% 68% at 14% 104%,
      hsl(calc(var(--play-hue) + 46) 32% 18% / .55) 0%, transparent 56%),
    linear-gradient(180deg, #15181f 0%, #0b0c10 62%, #08090c 100%);
  transition:--play-hue .75s var(--ease);}
/* Grain and a vignette: the last two things the reference does that the
   geometry cannot. The vignette holds the eye off the corners; the grain
   breaks the banding a wide dark gradient always shows on an 8-bit screen.
   Two layers rather than one, because a grain heavy enough to read would
   otherwise drag the vignette down with it. Both are paint, so they cost
   the renderer nothing and sit over whichever canvas is running. */
.play-stage::before,
.play-stage::after{content:''; position:absolute; inset:0; z-index:1;
  pointer-events:none;}
.play-stage::before{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:140px 140px; opacity:.055; mix-blend-mode:overlay;}
.play-stage::after{background-image:
  radial-gradient(74% 64% at 50% 44%, rgba(0,0,0,0) 40%, rgba(3,4,6,.66) 100%);}
@media (prefers-reduced-motion:reduce){
  .play-stage::before, .play-stage::after{display:none;}
}
.play-stage:active{cursor:grabbing;}
.play-stage canvas{display:block; width:100%; height:100%;}
.play-hint{position:absolute; left:var(--pad); bottom:var(--s3); z-index:2;
  font-size:10px; text-transform:uppercase; letter-spacing:.16em; color:var(--slate);
  pointer-events:none; transition:opacity .4s var(--ease);}
.play-stage.touched .play-hint{opacity:0;}
/* Without a pointer there is nothing to play with, and without script or
   canvas there is nothing at all, so the tiles stay a plain grid of links. */
.play-fallback{display:none; grid-template-columns:repeat(4,1fr); gap:2px; margin-top:var(--s5);}
.play-fallback a{display:block; aspect-ratio:1; overflow:hidden;}
.play-fallback img{width:100%; height:100%; object-fit:cover;}
.no-canvas .play-stage{display:none;}
.no-canvas .play-fallback{display:grid;}
@media (hover:none){
  .play-stage{height:clamp(300px,44vh,420px);}
}
@media (prefers-reduced-motion:reduce){
  .play-stage{display:none;}
  .play-fallback{display:grid;}
}
@media (max-width:640px){ .play-fallback{grid-template-columns:repeat(2,1fr);} }

/* a looping clip that becomes the whole film on click is a control, so it
   should look like one */
video[data-full]{cursor:pointer;}

/* the WebGL massing sits over the 2D floor; only one of them ever runs */
.play-stage canvas{position:absolute; inset:0; width:100%; height:100%;}
.play-stage .play-3d{display:none;}
.play-stage.is-3d .play-3d{display:block;}
.play-stage.is-3d .play-2d{display:none;}

/* ===================================================================
   LANDING SHELL — body.lp
   A paid landing page stands on its own: one ground, no alternating
   bands, and no site nav to leak the traffic you paid for. The only
   way off the page is a call to action or the logo.
   =================================================================== */
body.lp{background:var(--void); color:#fff;}
body.lp .paper,body.lp .bone,body.lp .mist,
body.lp .page-body,body.lp .faq,body.lp .logowall,body.lp .lp-close{
  background:var(--void); color:#fff;}
body.lp h1,body.lp h2,body.lp h3{color:#fff;}
body.lp p,body.lp li{color:var(--steel);}
body.lp .answer{color:#fff; border-left-color:var(--teal-light);}
body.lp .eyebrow{color:var(--teal-light);}
/* every hairline has to invert with the ground or it disappears */
body.lp .lp-rows,body.lp .lp-row,body.lp .lp-steps,
body.lp .faq-item,body.lp .lp-stats,body.lp .lp-quotes blockquote{border-color:var(--line-light);}
body.lp .lp-row:hover{background:rgba(255,255,255,.04);}
body.lp .lp-row p,body.lp .lp-step p,body.lp .lp-quotes cite{color:var(--slate);}
body.lp .lp-step .n{color:var(--teal-light);}
body.lp .faq-q{color:#fff;}
body.lp .lp-cta.ghost{border-color:rgba(255,255,255,.45); color:#fff;}
body.lp .lp-cta.ghost:hover{background:#fff; color:var(--ink);}
/* the diagonals were cut between two different grounds; on one ground they
   only leave a notch, so they go */
body.lp .section.diagonal-top{clip-path:none; margin-top:0;
  padding-top:calc(var(--diag-clear));}
/* the logo wall sat on bone and its marks are dark ink */
body.lp .logowall img{filter:invert(1) brightness(1.6); opacity:.62;}
body.lp .logowall img:hover{opacity:1;}

/* no nav, because every nav link is a way to leave a page you paid to
   land someone on. The logo and one call to action stay. */
body.lp .site-header .nav,
body.lp .site-header .nav-toggle{display:none;}
body.lp .site-header{grid-template-columns:1fr auto;}
