/* ==================================================================
   NAPA Records — one-page site
   Figma: NAPA / HP-bigtypo-fon2 (node 1-426)

   Every size below is measured off the 1728 px-wide design and written
   as `clamp(min, <measured>/1728 vw, measured)`, so the layout is an
   exact scale of the comp at 1728 and degrades sensibly either side.
   Section heights in the comp: hero 1182 · work 1110 · story 1483 ·
   studios 2322 · team 1656 · contacts 1113 · map 727 · footer 433.
   ================================================================== */

/* ---------- tokens ---------- */
:root{
  /* brand — sampled from the exported SVGs */
  --purple:#8A61AF;
  --black:#000;
  --white:#fff;
  --ink:#111;
  --ink-soft:#636363;      /* small paragraphs (studios) */
  --ink-mute:#202020;      /* contacts body copy */
  --line-grey:#636363;     /* contacts field rules */
  --grey-icon:#B4B4B4;
  --line-dark:rgba(0,0,0,.16);
  --line-light:rgba(255,255,255,.22);
  --on-dark-soft:rgba(255,255,255,.72);

  /* type — swap these two for the licensed brand faces */
  --font-display:'Unbounded',system-ui,sans-serif;
  --font-body:'Inter','Helvetica Neue',Arial,system-ui,sans-serif;

  /* gutters, as measured per band of the comp */
  --gutter:clamp(20px,9.491vw,164px);      /* work · story · studios · team */
  --gutter-mid:clamp(20px,5.208vw,90px);   /* contacts */
  --gutter-ftr:clamp(20px,6.887vw,119px);  /* footer */
  --gutter-edge:clamp(18px,3.067vw,53px);  /* header */
  --maxw:1400px;
  --radius:6px;

  /* Display scale — solved from Unbounded's measured advances at
     letter-spacing 0 (weight 800): cap .75em, x-height .575em,
     ascent .995em, descent .245em, and
       NAPA 3.6784em · Records 5.3146em · Our 2.3270em · Studios 4.9970em
       Team 3.5174em · Contacts 6.1151em · Story 3.6087em · work 3.2592em
     Size = widest panel width / (advance + .15em), see .boxed below:
       hero    Records 784 → 143px  (NAPA    then 548, comp 549)
       studios Studios 763 → 148px  (Our     then 367, comp 351)
       team    Team    653 → 178px  (Our     then 441, comp 440) */
  --fs-hero:clamp(42px,8.275vw,143px);
  --fs-studios:clamp(42px,8.565vw,148px);
  --fs-team:clamp(46px,10.301vw,178px);
  /* 'work' x-height measured clear of the card bottoms: 248 px, not the
     284 I first read (the cards end at y1804, right where the glyphs
     start). Cross-checked against the 'k' stem position in the comp
     (x1543 → 425 px), so 430 px. At 494 px only 8 px of the k's ink
     cleared the viewport edge; at 430 px, 174 px of 316 does — which is
     what the comp shows. */
  --fs-giant:clamp(86px,24.884vw,430px);
  --fs-story:clamp(28px,3.588vw,62px);       /* 'Story' 224 wide */
  --fs-contacts:clamp(38px,4.919vw,85px);    /* cap height 64 */
  --fs-bp:clamp(52px,16vw,277px);            /* 'Projects' ends at ~96% */
  --fs-card:clamp(20px,2.026vw,35px);
  --fs-svc:clamp(16px,1.215vw,21px);
  --fs-body:clamp(12.5px,.868vw,15px);
  --fs-contact:clamp(16px,1.273vw,22px);
  --fs-label:clamp(10px,.637vw,11px);

  --ease:cubic-bezier(.22,.61,.36,1);
}

/* ---------- reset ---------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
html:focus-within{scroll-behavior:smooth}
body{
  margin:0;background:var(--white);color:var(--ink);
  font:400 var(--fs-body)/1.6 var(--font-body);
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}
img{display:block;max-width:100%;height:auto}
svg{display:block}
ul,ol{margin:0;padding:0;list-style:none}
h1,h2,h3,p,figure{margin:0}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
:focus-visible{outline:2px solid var(--purple);outline-offset:3px}

.sprite{position:absolute;width:0;height:0;overflow:hidden}
.wrap{max-width:calc(var(--maxw) + 2*var(--gutter));margin-inline:auto;padding-inline:var(--gutter)}
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
.skip{position:absolute;left:-9999px;top:0;z-index:200;background:var(--purple);color:#fff;padding:12px 18px}
.skip:focus{left:8px;top:8px}

.sect--dark{background:var(--black);color:var(--white)}
.sect--light{background:var(--white);color:var(--ink)}

/* ---------- shared display type ----------
   Comp: white/purple panels hug the glyphs — 6 px side, 3 px top,
   11 px bottom at a 184 px font, i.e. .033 / .016 / .06 em.        */
/* Even .125em of visible background on all four sides.
   Vertically: with Unbounded's ascent .995 / descent .245 / cap .75, the
   gap above the cap and below the baseline each come to line-height/2 −
   .375em, so line-height:1 gives exactly .125em top and bottom. None of
   the panelled words has a descender, so the baseline is the optical
   bottom edge.
   Horizontally: the glyphs carry their own side bearings (~.05em on R, N,
   T, O), which add to whatever padding is set — so the inline padding is
   .075em, and .075 + ~.05 bearing reads as the same .125em gap. Measured
   on the comp: hero panel ink sits L20 R15 T14 B15 from the edges. */
.boxed{
  display:inline-block;
  padding:0 .075em;
  line-height:1;
}
.boxed--white{background:var(--white);color:var(--purple)}
.boxed--purple{background:var(--purple);color:var(--white)}

.h-boxed{
  display:flex;flex-direction:column;align-items:flex-start;
  gap:.09em;                        /* 13 px @145 */
  margin-left:-.075em;              /* pull the panel out so the glyph edge sits on the gutter */
  white-space:nowrap;
  font:800 var(--fs-studios)/1 var(--font-display);
  letter-spacing:0;
}
.h-boxed--team{font-size:var(--fs-team)}

.h-plain{font:800 var(--fs-story)/.97 var(--font-display);letter-spacing:0}
.rule{display:block;width:clamp(28px,2.66vw,46px);height:1px;background:currentColor;opacity:.5;margin-top:clamp(14px,1.39vw,24px)}

.p-lead{margin-top:clamp(16px,1.62vw,28px);max-width:46ch;font-size:var(--fs-body);line-height:1.62;color:var(--ink-soft)}
/* Both Our Studios paragraphs are hidden pending real copy — the intro next
   to the heading and the longer one lower down. Delete these two lines to
   bring them back; the strings are still in i18n.js. */
.studios__intro .p-lead{display:none}
.studios__foot .p-note{display:none}
.p-note{font-size:var(--fs-body);line-height:1.62;color:var(--ink-soft)}
.p-note--light{color:var(--on-dark-soft)}

.art{position:absolute;pointer-events:none;user-select:none;height:auto;overflow:visible}

/* ---------- illustration effects ----------------------------------
   Three effects, applied selectively:

   1. Draw-on sweep. A soft-edged mask rect travels across the artwork,
      played once when it scrolls into view. The paths are filled
      outlines, not strokes, so stroke-dasharray is unavailable — this is
      the closest equivalent that needs no re-export.
   2. Cursor spotlight — KNIGHT ONLY. A radialGradient whose centre follows
      the pointer supplies its fill. The other three take a flat brand
      purple from .art__ink.
   3. Levitation — FLOWER ONLY. Every path inside its flower-animate group
      drifts a few user units and returns, slowly and out of phase. This is
      why the flower is inlined rather than <use>d: CSS cannot reach into
      <use> shadow content.

   Revealed is the DEFAULT state: main.js adds .is-armed (hidden) only when
   motion is allowed, so with JS off or reduced motion the art just shows. */
.art__sweep{transform-box:view-box;transform:translateX(var(--aw))}
.art.is-armed .art__sweep{transform:translateX(0)}
.art.is-armed.is-drawn .art__sweep{animation:art-draw 1.6s cubic-bezier(.36,.66,.28,1) both}
@keyframes art-draw{from{transform:translateX(0)}to{transform:translateX(var(--aw))}}

.art__ink{fill:var(--purple)}

/* Spotlight, knight only. The band behind it is now brand purple and the
   knight is white line art, so the cursor can't go brighter than the base —
   instead the line rests at a muted lavender, still clearly lighter than the
   #8A61AF behind it, and lifts to pure white where the cursor is. Same "the
   cursor lights it up" read as before, inverted for the lighter band. */
.art--knight .art__s0{stop-color:#FFFFFF}   /* under the cursor */
.art--knight .art__s1{stop-color:#F6EFFC}
.art--knight .art__s2{stop-color:#D5C0EA}   /* at rest — still reads white-ish */

/* Levitation, flower only. Offsets, duration and a negative delay come from
   the markup (build-html.py, deterministic per path) so the 28 paths drift
   out of phase. `alternate` returns each to its origin — nothing creeps. */
.art--flower .lev{
  transform-box:fill-box;transform-origin:center;
  animation:lev var(--ld,5s) ease-in-out var(--lt,0s) infinite alternate;
}
@keyframes lev{
  from{transform:translate(0,0) rotate(0deg)}
  to{transform:translate(var(--lx,0),var(--ly,0)) rotate(var(--lr,0deg))}
}

/* ==================================================================
   HEADER — logo x53 y34, nav centred, pill right (comp)
   ================================================================== */
.hdr{
  position:fixed;inset:0 0 auto;z-index:100;color:#fff;
  padding:clamp(14px,1.968vw,34px) var(--gutter-edge);
  transition:background-color .35s var(--ease),backdrop-filter .35s var(--ease),padding .35s var(--ease);
}
.hdr.is-stuck{
  background:rgba(0,0,0,.82);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  padding-block:clamp(10px,1.1vw,19px);
}
.hdr__in{position:relative;display:flex;align-items:center;gap:24px}
.hdr__logo{flex:0 0 auto;width:clamp(44px,3.993vw,69px)}      /* 69 × 76 */
.mark{width:100%;aspect-ratio:69/76;color:currentColor}

.nav{
  position:absolute;left:50%;transform:translateX(-50%);
  display:flex;gap:clamp(16px,2.14vw,37px);font-size:clamp(14px,.984vw,17px);white-space:nowrap;
}
.nav a{position:relative;padding-block:4px}
.nav a::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:currentColor;
  transform:scaleX(0);transform-origin:left;transition:transform .3s var(--ease);
}
.nav a:hover::after,.nav a.is-active::after{transform:scaleX(1)}
.nav a.is-active{color:var(--purple)}

.hdr__right{display:flex;align-items:center;gap:clamp(12px,1.16vw,20px);margin-left:auto}
/* Hidden for now — EN only. Remove this display:none and restore the
   stored/navigator lookup in main.js pickLang() to bring it back. */
.lang{display:none;align-items:center;gap:6px;font:600 clamp(11px,.752vw,13px)/1 var(--font-body);letter-spacing:.06em}
.lang__btn{opacity:.5;transition:opacity .25s var(--ease),color .25s var(--ease)}
.lang__btn:hover{opacity:.85}
.lang__btn[aria-pressed="true"]{opacity:1;color:var(--purple)}
.lang__sep{opacity:.35}


.burger{display:none;width:34px;height:22px;position:relative;flex:0 0 auto}
.burger span{position:absolute;left:2px;right:2px;height:2px;background:currentColor;transition:transform .3s var(--ease)}
.burger span:first-child{top:5px}
.burger span:last-child{bottom:5px}
.burger[aria-expanded="true"] span:first-child{transform:translateY(5px) rotate(45deg)}
.burger[aria-expanded="true"] span:last-child{transform:translateY(-5px) rotate(-45deg)}

/* Opens by fading the panel in and letting the links rise one after another;
   closes with a quicker fade. visibility waits for the fade on the way out,
   so the closed menu is still unfocusable and hidden from screen readers. */
.mmenu{
  position:fixed;inset:0;z-index:99;display:grid;place-items:center;color:#fff;
  background:rgba(0,0,0,.94);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  opacity:0;visibility:hidden;transition:opacity .25s var(--ease),visibility 0s linear .25s;
}
.mmenu.is-open{opacity:1;visibility:visible;transition:opacity .35s var(--ease)}
.mmenu nav{display:grid;gap:22px;text-align:center;font:700 26px/1 var(--font-display)}
.mmenu a{opacity:0;transform:translateY(16px);transition:opacity .2s var(--ease),transform .2s var(--ease)}
.mmenu.is-open a{opacity:1;transform:none;transition:opacity .45s var(--ease),transform .45s var(--ease)}
.mmenu.is-open a:nth-child(1){transition-delay:.06s}
.mmenu.is-open a:nth-child(2){transition-delay:.11s}
.mmenu.is-open a:nth-child(3){transition-delay:.16s}
.mmenu.is-open a:nth-child(4){transition-delay:.21s}
.mmenu.is-open a:nth-child(5){transition-delay:.26s}

/* ==================================================================
   HERO — comp 1728 × 1182
   panels x62 y639/795 (144 h, 13 gap) · sub x164 · dots 6 px, bottom 59
   waveform 1315 × 482 at x407 y173
   ================================================================== */
.hero{
  position:relative;min-height:100svh;display:flex;flex-direction:column;justify-content:flex-end;
  overflow:hidden;background:#0c0910;color:#fff;isolation:isolate;
  /* The band is one viewport tall, so the gap under the copy follows the
     viewport's height, not its width: on a 1920 × 1080 screen a width-based
     178 px left the copy floating up into the waveform. */
  --hero-pb:clamp(40px,8svh,110px);
  padding:0 var(--gutter-edge) var(--hero-pb);
}
.hero__media{position:absolute;inset:0;z-index:0}
/* hero2.jpg carries its own blur and grade, so it is shown as-is: no CSS
   filter and no scrim on top */
.hero__img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.wave{
  position:absolute;z-index:1;pointer-events:none;
  left:23.55%;                                  /* 407 / 1728 */
  top:clamp(56px,10.01vw,173px);
  width:76.1%;                                  /* 1315 / 1728 */
  height:auto;
}

.hero__in{position:relative;z-index:2;margin-left:clamp(0px,.521vw,9px)}   /* 62 − 53 header gutter */
.hero__h{
  display:flex;flex-direction:column;align-items:flex-start;gap:.092em;   /* 13 px @141 */
  font:800 var(--fs-hero)/1 var(--font-display);letter-spacing:0;
}
.hero__sub{
  margin-top:clamp(22px,2.95vw,51px);
  margin-left:clamp(0px,5.903vw,102px);          /* x164 − x62 */
  max-width:clamp(240px,25.5vw,440px);   /* wider than the comp: the new intro copy is ~3× longer */
  font-size:clamp(12.5px,.868vw,15px);line-height:1.15;color:rgba(255,255,255,.92);
}

/* ==================================================================
   OUR WORK — comp band 1182…2292 (1110 h)
   giant type left 455 (26.33 %) · arrows y+211 · cards y+307, 446 × 316, gap 17
   flower 637 × 699 at x110, overhanging the band by 208
   ================================================================== */
/* comp band 1182…2292: 'Our' cap top at +137, arrows +211, cards +307…622,
   'work' x-height top +655 (a 33 px gap under the cards), baseline +902.
   overflow-x:clip still trims the giant type's bleed on the right, but leaves
   the vertical axis alone so the flower can carry on into the projects band
   below — `overflow:hidden` would have forced the other axis too.
   Deliberately NO z-index here: it stays in the page's stacking context so
   the flower can slot *between* .bp's background and .bp's text. See .bp. */
.work{
  position:relative;
  overflow-x:clip;overflow-y:visible;
  padding:clamp(46px,4.456vw,77px) 0 clamp(60px,8.507vw,147px);
}
.work__type{
  position:relative;z-index:1;
  display:flex;flex-direction:column;margin-left:26.33%;
  font:800 var(--fs-giant)/1.03 var(--font-display);   /* comp: 'Our' cap top y1319 → 'work' baseline y2084 */
  letter-spacing:0;white-space:nowrap;color:var(--black);pointer-events:none;
}
.work__inner{position:absolute;z-index:2;left:0;right:0;top:clamp(58px,12.21vw,211px)}

.arrows{
  display:flex;gap:clamp(10px,1.39vw,24px);
  padding-inline-start:calc(var(--gutter) + clamp(0px,1.1vw,19px));
  margin-bottom:clamp(24px,4.34vw,75px);
}
.arrow{width:clamp(42px,4.167vw,72px);transition:transform .3s var(--ease),opacity .3s var(--ease)}
.arrow svg{width:100%;aspect-ratio:3/1;fill:currentColor}
.arrow[data-dir="1"] svg{transform:scaleX(-1)}
.arrow[data-dir="-1"]:hover{transform:translateX(-4px)}
.arrow[data-dir="1"]:hover{transform:translateX(4px)}
.arrow[disabled]{opacity:.25;cursor:default;transform:none}

.rail{
  display:flex;gap:clamp(10px,.984vw,17px);
  padding-inline:var(--gutter);
  overflow-x:auto;scroll-behavior:smooth;   /* no scroll-snap: the rails drag freely */
  scroll-padding-inline:var(--gutter);
  scrollbar-width:none;-ms-overflow-style:none;
}
.rail::-webkit-scrollbar{display:none}
/* grab-and-drag (main.js → initDrag); touch keeps native scrolling */
@media (hover:hover) and (pointer:fine){
  .rail{cursor:grab}
  .rail .card{cursor:grab}
  .rail.is-dragging,.rail.is-dragging .card{cursor:grabbing}
}
.rail.is-dragging{scroll-behavior:auto;user-select:none}
/* no hover zoom kicking in under the cursor mid-drag */
.rail.is-dragging .card img{transform:none}
.rail img{-webkit-user-drag:none}
.rail>li{flex:0 0 auto}

.card{
  position:relative;display:block;overflow:hidden;border-radius:var(--radius);background:#111;
  width:clamp(258px,25.81vw,446px);height:clamp(183px,18.287vw,316px);
  text-align:left;   /* video tiles are <button>s, which centre by default */
}
.card img{width:100%;height:100%;object-fit:cover;transition:transform .8s var(--ease)}
.card:hover img{transform:scale(1.045)}
.card__scrim{position:absolute;inset:0;background:linear-gradient(180deg,transparent 38%,rgba(0,0,0,.78) 100%)}
.card__meta{position:absolute;left:clamp(14px,1.447vw,25px);right:clamp(14px,1.447vw,25px);bottom:clamp(12px,1.273vw,22px);color:#fff}
.card__t{display:block;margin-bottom:clamp(5px,.46vw,8px);font:700 var(--fs-card)/1.05 var(--font-display);letter-spacing:0}
.card__c{
  display:block;
  font:700 clamp(8.5px,.637vw,11px)/1.35 var(--font-body);
  letter-spacing:.055em;text-transform:uppercase;
}

/* comp: 637×699 at x110 y1801, i.e. top level with the card bottoms and
   running 208 px past the band's bottom edge, where it is clipped */
.art--flower{z-index:0;left:clamp(8px,6.366vw,110px);bottom:clamp(-208px,-12.037vw,-60px);width:clamp(190px,36.87vw,637px)}

/* ==================================================================
   VIDEO LIGHTBOX
   Native <dialog>, so Esc, the focus trap and ::backdrop are the
   platform's job. The dialog fills the viewport and centres the frame,
   which is what makes "click outside to close" a one-line target test.
   ================================================================== */
.lb{
  width:100%;max-width:none;height:100%;max-height:none;
  margin:0;border:0;padding:clamp(16px,4vw,64px);
  background:transparent;color:#fff;overflow:hidden;
}
.lb:not([open]){display:none}
.lb[open]{display:grid;place-items:center}
.lb::backdrop{
  background:rgba(10,8,14,.66);
  -webkit-backdrop-filter:blur(20px) saturate(.9);backdrop-filter:blur(20px) saturate(.9);
}

.lb__frame{
  position:relative;margin:0;width:min(100%,1180px);
  aspect-ratio:16/9;border-radius:var(--radius);overflow:hidden;
  background:#000;box-shadow:0 40px 90px rgba(0,0,0,.55);
}
.lb__video{width:100%;height:100%;display:block;object-fit:cover;background:#000}

/* Full-frame click target with the circle as the affordance, so clicking
   anywhere on the poster starts playback. Hidden once it is playing, or the
   native controls would be unreachable underneath it. */
.lb__play{
  position:absolute;inset:0;display:grid;place-items:center;
  background:linear-gradient(180deg,rgba(0,0,0,.04) 40%,rgba(0,0,0,.42));
  transition:opacity .3s var(--ease);
}
.lb__play svg{width:clamp(58px,6.5vw,84px);height:auto}
.lb__play circle{fill:rgba(255,255,255,.14);stroke:rgba(255,255,255,.9);stroke-width:2}
.lb__play path{fill:#fff}
.lb__play:hover circle{fill:rgba(255,255,255,.26)}

.lb__meta{
  position:absolute;left:clamp(18px,2.6vw,46px);bottom:clamp(18px,2.6vw,46px);
  right:clamp(18px,2.6vw,46px);pointer-events:none;
  transition:opacity .3s var(--ease);
}
.lb__t{display:block;font:700 clamp(24px,2.6vw,46px)/1.05 var(--font-display);letter-spacing:0}
.lb__c{
  display:block;margin-top:.6em;max-width:22ch;
  font:700 clamp(9px,.75vw,13px)/1.35 var(--font-body);
  letter-spacing:.055em;text-transform:uppercase;
}
.lb.is-playing .lb__play,.lb.is-playing .lb__meta{opacity:0;pointer-events:none}

.lb__x{
  position:absolute;top:clamp(14px,2vw,34px);right:clamp(14px,2vw,34px);
  width:clamp(30px,2.4vw,42px);aspect-ratio:1;display:grid;place-items:center;
  border-radius:50%;color:#fff;transition:background-color .25s var(--ease);
}
.lb__x svg{width:58%;height:auto;fill:none;stroke:currentColor;stroke-width:1.6}
.lb__x:hover{background:rgba(255,255,255,.16)}

.lb[open]::backdrop{animation:lb-fade .3s var(--ease) both}
.lb[open] .lb__frame{animation:lb-rise .34s var(--ease) both}
@keyframes lb-fade{from{opacity:0}to{opacity:1}}
@keyframes lb-rise{from{opacity:0;transform:translateY(14px) scale(.985)}to{opacity:1;transform:none}}

/* ==================================================================
   OUR BELOVED PROJECTS
   Mockup is 890 wide: text left 5.6%, collage x163..867 y170..550, all
   three display lines one size. Here the type starts on the site's usual
   --gutter instead, and is sized so the longest line ("Projects",
   5.4060em in Unbounded) ends at ~96% of the width:
     (96% − 9.49%) / 5.4060 = 16vw.
   Vertical offsets are that 16vw scaled by the mockup's em ratios, so the
   whole composition scales with the viewport.
   ================================================================== */
/* Not positioned, on purpose. An unpositioned block paints its background
   early (CSS 2.1 painting step 3), below every positioned element — so the
   flower hanging out of .work (absolutely positioned, step 6) lands on top of
   this band's black, while .bp__head is positioned and later in the DOM, so
   "Our" paints over the flower in turn. Adding position:relative here would
   lift the black background above the flower and hide it again. */
.bp{
  overflow:hidden;
  padding:clamp(36px,6.30vw,109px) 0 clamp(48px,10.02vw,173px);
}
.bp__type{
  display:flex;flex-direction:column;margin:0;
  font:800 var(--fs-bp)/.93 var(--font-display);
  letter-spacing:0;color:#fff;white-space:nowrap;
}
/* Out of flow, so it sits beside the collage instead of pushing it down —
   the collage has to tuck back up under the "Our" line as it does in the
   mockup. Absolute positioning is relative to .bp__head's padding box, so
   left:var(--gutter) lands on the same edge as the type. */
.bp__head{position:relative}
.bp__intro{
  position:absolute;top:100%;left:var(--gutter);
  margin-top:clamp(8px,1vw,18px);
  /* the mockup's width (141 of 890); the collage now starts at 27.3%,
     so this clears it */
  max-width:clamp(190px,15.84vw,274px);
  font-size:var(--fs-body);line-height:1.6;color:var(--on-dark-soft);
}

/* Collage box locked to the mockup's aspect, so the % positions on each
   poster hold at every width. The PNGs carry their own tilt and shadow —
   no CSS rotation, only placement.
   The outer box is the .wrap box (minus padding) so the collage and the type
   stay aligned above 1728, where .wrap centres and a full-bleed child would
   drift away from it. The inner list is 89% of that, pinned right: shrinking
   it moves the leftmost poster from 18.3% to 27.3% and frees the width the
   intro paragraph needs. Everything inside is in % of the list, so the whole
   arrangement scales with it. */
.bp__collage-box{
  max-width:calc(var(--maxw) + 2*var(--gutter));margin-inline:auto;
  margin-top:clamp(-62px,-3.61vw,-20px);
}
.bp__collage{
  position:relative;width:92%;margin-left:auto;aspect-ratio:890/380;
}
/* Hover scale lives in poster-motion.js (spring-driven transform on the img,
   Velký vlastenecký výlet held at 1.1 and raised to z 20). No CSS hover here. */
.bp__item{position:absolute;z-index:var(--z,1)}
.bp__item img{width:100%;height:auto}

.bp__type--foot{margin-top:.065em}

/* Below ~1100 the gutter and the collage's left edge converge, so the intro
   goes back into flow above the collage rather than overlapping a poster. */
@media (max-width:1100px){
  .bp__intro{position:static;left:auto;max-width:46ch;margin-top:clamp(12px,2vw,24px)}
  .bp__collage-box{margin-top:clamp(14px,2.5vw,30px)}
  .bp__collage{width:100%;margin-left:0}
}
@media (max-width:860px){
  /* phone sizing of the collage is in the RESPONSIVE block at the end */
}

/* ==================================================================
   OUR STORY — comp band 2292…3775 (1483 h)
   list x164 w878 · top rule 2 px at y+157 · row pitch 113
   heading x1291 y+169 · knight 519 × 846 at right 0, overhang 45
   ================================================================== */
/* overflow visible + a z-index above .studios (2) so the knight's feet
   carry over into the next band rather than being cut at the edge */
.story{
  position:relative;z-index:3;background:var(--purple);
  padding:clamp(56px,9.086vw,157px) 0 clamp(70px,10.5vw,181px);
}
.story__grid{display:grid;grid-template-columns:minmax(0,878fr) minmax(0,522fr);gap:0}
.svc{border-top:2px solid rgba(255,255,255,.85)}
.svc__item:not(:last-child){border-bottom:1px solid var(--line-light)}
.svc__hd{margin:0;font:inherit}
.svc__btn{
  display:flex;align-items:flex-start;gap:clamp(14px,1.5vw,26px);
  width:100%;text-align:left;
  min-height:clamp(52px,6.54vw,113px);
  padding:clamp(14px,2.2vw,38px) 0 clamp(14px,2.2vw,38px);
}
/* comp: the number's cap top sits level with the title's cap top */
.svc__n{
  flex:0 0 auto;width:2ch;padding-top:.29em;
  font:500 var(--fs-label)/1.3 var(--font-body);
  color:#959595;letter-spacing:.04em;
}
.svc__t{font-size:var(--fs-svc);line-height:1.3}
.svc__ico{
  position:relative;flex:0 0 auto;margin-left:auto;align-self:flex-start;
  width:clamp(10px,.8vw,14px);height:clamp(10px,.8vw,14px);
  margin-top:.42em;opacity:.5;transition:opacity .25s var(--ease);
}
.svc__ico::before,.svc__ico::after{
  content:"";position:absolute;inset:50% 0 auto;height:1px;background:currentColor;
  transition:transform .3s var(--ease);
}
.svc__ico::after{transform:rotate(90deg)}
.svc__btn:hover .svc__ico{opacity:1}
.svc__item.is-open .svc__ico::after{transform:rotate(0deg)}
.svc__panel{overflow:hidden;height:0;transition:height .38s var(--ease)}
.svc__body{
  padding:0 0 clamp(18px,2.2vw,38px) calc(2ch + clamp(14px,1.5vw,26px));
  max-width:56ch;font-size:var(--fs-body);line-height:1.65;color:var(--on-dark-soft);
}

.story__side{padding-left:clamp(0px,14.41vw,249px);padding-top:clamp(4px,.694vw,12px)}
.art--knight{right:0;bottom:clamp(-60px,-3.472vw,-20px);width:clamp(190px,30.035vw,519px)}

/* ==================================================================
   OUR STUDIOS — comp band 3775…6097 (2322 h)
   heading y+185 · main photo x877 (50.75 %) 851 × 914 at y+195
   gallery photos y+1323, height 619, gap 61 · arrows 89 above
   note x869 w757 · big N 763 wide at left −267 · ear 405² right 97, overhang 166
   ================================================================== */
.studios{position:relative;z-index:2;padding-top:clamp(46px,10.706vw,185px)}
.studios__top{display:grid;grid-template-columns:50.75% 49.25%;align-items:start}
.studios__intro{position:relative;z-index:1;padding-left:var(--gutter);padding-right:clamp(16px,2vw,40px)}
.studios__hero{margin-top:clamp(6px,.579vw,10px)}
.studios__hero img{width:100%;aspect-ratio:851/914;object-fit:cover;border-radius:var(--radius) 0 0 var(--radius)}

.studios__gal{position:relative;z-index:1;margin-top:clamp(40px,9.2vw,159px)}
/* Full-bleed like the rail it controls — NOT inside .wrap, which centres and
   caps at 1728, so above that width the arrows drifted right of the photos. */
.studios__gal .arrows{padding-inline-start:var(--gutter);margin-bottom:clamp(28px,5.15vw,89px)}
.rail--studio{gap:clamp(16px,3.53vw,61px)}
.rail--studio figure{margin:0;border-radius:var(--radius);overflow:hidden;background:#eee}
.rail--studio img{height:clamp(300px,35.82vw,619px);width:auto;max-width:none;object-fit:cover}

.studios__foot{position:relative;z-index:0;padding-top:clamp(44px,6.71vw,116px);padding-bottom:clamp(52px,8.51vw,147px)}
.studios__foot .p-note{margin-left:50.29%;width:min(33.22%,40ch)}          /* x869, w574 */
.bign{
  position:absolute;left:0;bottom:0;overflow:hidden;pointer-events:none;
  width:clamp(180px,28.82vw,498px);height:clamp(200px,35.42vw,612px);color:var(--black);
}
.bign svg{
  /* Verified against the comp: stroke 34 px, right edge at x498, and the
     two visible stem edges land within 3 px. The diagonal band's phase is
     ~70 px out — the comp's instance is scaled slightly differently. */
  position:absolute;bottom:clamp(-240px,-13.889vw,-80px);left:clamp(-267px,-15.45vw,-90px);
  width:clamp(280px,44.16vw,763px);max-width:none;aspect-ratio:55.5/63.9;
  fill:currentColor;
}
/* 1693×3726, so 2.2× as tall as it is wide. Sits in the empty lower-left of
   the contacts grid and hangs ~260 px into the map. */
.art--ear{right:clamp(4px,5.613vw,97px);bottom:clamp(-166px,-9.606vw,-40px);width:clamp(150px,23.44vw,405px)}
.art--tower{left:clamp(-24px,1.736vw,30px);bottom:clamp(-260px,-15.046vw,-70px);width:clamp(140px,21.99vw,380px)}

/* ==================================================================
   OUR TEAM — comp band 6097…7753 (1656 h)
   panels x1006 (58.22 %) y+64 · photos 347 × 406 at x164/538/912, gap 27
   row 1 at y+265, row pitch 654
   ================================================================== */
.team{position:relative;z-index:1;padding:clamp(150px,15.336vw,265px) 0 clamp(64px,9.2vw,159px)}
/* comp: panels start at y+64 while row 1 of the photos starts at y+265,
   so the head floats over the grid instead of pushing it down */
.team__head{
  position:absolute;top:clamp(24px,3.704vw,64px);left:0;right:0;
  display:grid;grid-template-columns:60.14% 39.86%;
  pointer-events:none;
}
.team__head>*{pointer-events:auto}
.team__head .h-boxed{grid-column:2}
.team__head .p-note{grid-column:2;margin-top:clamp(18px,2.6vw,45px);max-width:47ch}

.people{
  display:grid;grid-template-columns:repeat(3,24.786%);      /* 347 / 1400 */
  column-gap:1.929%;                                        /* 27 / 1400 */
  row-gap:clamp(30px,2.72vw,47px);
  justify-content:start;
}
.people>li:nth-child(3){grid-column:1}
.person img{width:100%;aspect-ratio:347/406;object-fit:cover;filter:grayscale(1) contrast(1.04)}
.person__n{margin-top:clamp(14px,1.5vw,26px);font:700 clamp(10px,.66vw,11.5px)/1.2 var(--font-body);letter-spacing:.075em;text-transform:uppercase}
.person__r{margin-top:.7em;font-size:clamp(11px,.752vw,13px);color:var(--on-dark-soft)}
.person__b{margin-top:clamp(14px,1.39vw,24px);font-size:clamp(11.5px,.752vw,13px);line-height:1.6;color:var(--on-dark-soft)}

/* ==================================================================
   CONTACTS — comp band 7753…8866 (1113 h)
   heading cap top y+87, bleeds 50 px past the left edge
   left col x93 · right col x678 (38 % of the 1548 content box)
   ================================================================== */
/* No overflow:hidden here — the tower has to hang into the map band. The
   Contacts heading still gets clipped at the viewport edge by
   body{overflow-x:hidden}. z-index keeps the tower above the map, which
   follows in the DOM. */
.contact{position:relative;z-index:3;color:var(--ink-mute);padding:clamp(50px,5.035vw,87px) 0 clamp(52px,7.29vw,126px)}
.contact .wrap{padding-inline:var(--gutter-mid)}
.contact__h{
  font:800 var(--fs-contacts)/.9 var(--font-display);letter-spacing:0;
  /* break out of the centred .wrap to the viewport's own left edge,
     then 34 px further, so the C is clipped at every window width */
  margin-left:calc(50% - 50vw - clamp(10px,1.968vw,34px));
}
/* Comp puts the address rule and the first person's last rule on the same
   line (both y8180). Rather than tune a margin, the left block and card 1
   share grid row 1 — the people list is a subgrid, so its rows are the
   parent's rows — and the address field is pushed to that row's bottom
   edge with margin-top:auto. Stays aligned if the copy changes.
   --contact-rows is set by main.js from the number of cards. */
.contact__grid{
  display:grid;
  grid-template-columns:34% 62%;
  column-gap:4%;
  row-gap:clamp(24px,2.89vw,50px);
  grid-template-rows:repeat(var(--contact-rows,3),auto);
  margin-top:clamp(28px,3.01vw,52px);
}
.contact__left{grid-column:1;grid-row:1;display:flex;flex-direction:column}
.contact__left .social{margin-bottom:clamp(20px,2.55vw,44px)}
.contact__left .field{margin-top:auto}

.social{display:flex;gap:clamp(8px,1.215vw,21px)}
.social a{
  display:block;width:clamp(17px,1.215vw,21px);aspect-ratio:1;
  color:var(--grey-icon);transition:color .3s var(--ease);
}
.social a:hover{color:var(--purple)}
.social svg{width:100%;aspect-ratio:1;fill:currentColor}
.social--light a{color:rgba(255,255,255,.42)}
.social--light a:hover{color:var(--purple)}

.field{margin-top:clamp(20px,2.55vw,44px);padding-bottom:clamp(9px,.868vw,15px);border-bottom:1px solid var(--line-grey)}
.field__label{display:block;font-size:var(--fs-label);color:var(--ink-mute)}
.field__val{margin-top:.25em;font-size:var(--fs-contact);line-height:1.35}

.contact__people{
  grid-column:2;grid-row:1/-1;
  display:grid;grid-template-rows:subgrid;
  gap:clamp(24px,2.89vw,50px);
}
.pcard__n{font:600 var(--fs-contact)/1.32 var(--font-body);color:var(--black)}
.pcard__r{font:400 var(--fs-contact)/1.32 var(--font-body);color:var(--black)}
.pcard .field{margin-top:clamp(10px,.81vw,14px)}
.pcard .field a{transition:color .25s var(--ease)}
.pcard .field a:hover{color:var(--purple)}

/* ==================================================================
   MAP (727 h) + FOOTER (433 h)
   ================================================================== */
.map{background:#ededed}
.map__frame{position:relative;height:clamp(300px,42.072vw,727px);overflow:hidden}
.map__frame iframe{width:100%;height:100%;border:0}
/* live map sits over the link placeholder; removed again if the key fails */
.map__canvas{position:absolute;inset:0;background:#e5e5e5}
/* brand pin: tip on the address. The OverlayView sets left/top to the
   point, the translate hangs the drop above it. */
.map__marker{
  position:absolute;display:block;width:clamp(64px,8.56vw,148px);
  transform:translate(-50%,-100%);transition:transform .3s var(--ease);
}
.map__marker svg{display:block;width:100%;aspect-ratio:148/190;overflow:visible}
.map__marker path{fill:#000}
.map__marker use{color:#fff}
.map__marker:hover{transform:translate(-50%,calc(-100% - 4px))}
.map__ph{
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(10px,1.2vw,20px);width:100%;height:100%;text-align:center;
  background:#ededed;color:var(--ink);
  transition:background-color .3s var(--ease);
}
.map__pin{width:clamp(48px,4.3vw,74px);aspect-ratio:149/180;fill:currentColor}
.map__addr{font-size:var(--fs-contact);line-height:1.35}
.map__cta{font:700 clamp(10px,.694vw,12px)/1 var(--font-body);letter-spacing:.1em;text-transform:uppercase;color:var(--purple)}
.map__ph:hover{background:#e6e6e6}

.ftr{background:var(--black);color:#fff;padding-block:clamp(46px,5.15vw,89px)}
.ftr .wrap{padding-inline:var(--gutter-ftr)}
.ftr__grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto;gap:clamp(30px,4vw,70px);align-items:start}
.ftr__logo{display:block;width:clamp(44px,3.993vw,69px)}
.ftr__addr{margin-top:clamp(20px,2.95vw,51px);font-size:var(--fs-body);line-height:1.55;color:rgba(255,255,255,.9)}
.ftr__nav{display:grid;gap:clamp(14px,1.74vw,30px);font-size:clamp(13px,.926vw,16px)}
.ftr__nav a{opacity:.9;transition:color .25s var(--ease),opacity .25s var(--ease)}
.ftr__nav a:hover{color:var(--purple);opacity:1}
.ftr .social{justify-content:flex-end}

/* ==================================================================
   MOTION
   ================================================================== */
[data-rv]{opacity:0;transform:translateY(22px);transition:opacity .8s var(--ease),transform .8s var(--ease)}
[data-rv].is-in{opacity:1;transform:none}
[data-rv="type"]{transform:translateY(3%) scale(.986);transform-origin:left center}
/* The waveform no longer pulses: wave-motion.js bends each string under the
   cursor and wave-light.js drives its fill. Nothing in CSS may transform or
   fill .wave path, or the two would fight. */

@media (prefers-reduced-motion:reduce){
  html:focus-within{scroll-behavior:auto}
  .art__sweep{transform:translateX(var(--aw))!important;animation:none!important}
  .art--flower .lev{animation:none!important}
  .lb[open]::backdrop,.lb[open] .lb__frame{animation:none!important}
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}
  [data-rv]{opacity:1;transform:none}
}

/* ==================================================================
   RESPONSIVE
   ================================================================== */
@media (max-width:1100px){
  .story__grid{grid-template-columns:1fr}
  .story__side{order:-1;padding-left:0;margin-bottom:clamp(24px,4vw,44px)}
  .art--knight{opacity:.4;width:44vw;bottom:0}
  .studios__top{grid-template-columns:1fr;gap:26px}
  .studios__hero{padding-left:var(--gutter)}
  .studios__hero img{border-radius:var(--radius)}
  .studios__foot .p-note{margin-left:var(--gutter);width:auto;max-width:46ch}
  .team{padding-top:clamp(40px,6vw,80px)}
  .team__head{position:static;grid-template-columns:1fr;margin-bottom:clamp(30px,5vw,60px)}
  .team__head .h-boxed,.team__head .p-note{grid-column:1}
  .people{grid-template-columns:repeat(2,1fr);column-gap:clamp(16px,2vw,27px)}
  .people>li:nth-child(3){grid-column:auto}
  /* Stacked: the third contact card now occupies the lower left, so the
     tower gets a dedicated gap. --tower-h drives the height, the gap and the
     overhang together: content stops exactly where the tower starts, and the
     remaining 38% hangs into the map. */
  .contact{--tower-h:clamp(200px,26vw,330px);padding-bottom:calc(var(--tower-h) * .62)}
  .art--tower{width:calc(var(--tower-h) / 2.2);left:-2vw;bottom:calc(var(--tower-h) * -.38)}
  .contact__grid{grid-template-columns:1fr;gap:clamp(30px,4vw,50px);grid-template-rows:none}
  .contact__left{grid-column:1;grid-row:auto}
  .contact__left .field{margin-top:clamp(20px,2.55vw,44px)}
  .contact__people{grid-column:1;grid-row:auto;grid-template-rows:none}
  .ftr__grid{grid-template-columns:1fr 1fr}
  .ftr .social{justify-content:flex-start;grid-column:1/-1}
}

@media (max-width:860px){
  .nav{display:none}
  .burger{display:block}
  .work{padding:clamp(88px,15vw,130px) 0 clamp(50px,10vw,90px)}
  .work__type{margin-left:0;font-size:22vw;line-height:.8}
  .work__inner{position:static;margin-top:clamp(24px,5vw,44px)}
  .art--flower{position:relative;left:auto;bottom:auto;margin:clamp(20px,6vw,40px) 0 0 var(--gutter);width:46vw}
  .studios__foot{padding-bottom:clamp(100px,34vw,200px)}
  .bign{width:38vw;height:44vw}
  .art--ear{width:44vw;right:3vw;bottom:0;transform:translateY(24%)}
  .people{grid-template-columns:1fr;row-gap:clamp(30px,7vw,50px)}
  .contact__h{font-size:clamp(38px,12vw,70px)}
  .ftr__grid{grid-template-columns:1fr}
  .hero__sub{margin-left:0}
  /* Phone hero: the copy is centred on the screen and a size up, and the
     waveform moves to the bottom edge. Equal padding
     top and bottom (the top one clears the header) keeps the centre true;
     the waveform (its width × 482/1315 tall) fits in what is left below. */
  .hero{
    --wave-w:calc(100vw - 2*var(--gutter-edge));
    justify-content:center;
    padding-block:clamp(72px,20vw,110px);
  }
  .hero__h{font-size:clamp(46px,13.2vw,96px)}
  .hero__sub{font-size:clamp(14px,3.9vw,17px);max-width:34ch;line-height:1.3}
  .wave{top:auto;bottom:6svh;left:var(--gutter-edge);width:var(--wave-w)}

  /* Our work: the flower sits to the right of "Our" instead of stacking a
     whole screen of white above it, and the type lines up with the arrows. */
  .work{padding-top:clamp(28px,8vw,56px)}
  .art--flower{display:block;margin:0 var(--gutter) 0 auto;width:38vw}
  .work__type{margin-left:calc(var(--gutter) + clamp(0px,1.1vw,19px) - .04em);margin-top:-19vw}

  /* Beloved projects: the posters occupy x 18.3…98.2 % of the collage (the
     desktop intro sits in the empty left part). Scale the collage so that
     span fills the screen less 16 px a side, and shift it left by the gap. */
  .bp__collage{
    --span:calc(100vw - 32px);
    width:calc(var(--span) * 1.2516);
    margin-left:calc(16px - var(--span) * .2291);
  }
}
