/* IMAWA — dark-first. Post-delivery 1 (02/09).
   Brief: less "skincare", more entertainment production.
   Blacker grounds, bigger logo, smaller headline, immediate visual impact. */

:root{
  --black:#000000;
  --ink-900:#0A0A0A;
  --ink-800:#111111;
  --ink-700:#181818;
  --line:rgba(235,235,235,.14);
  --line-2:rgba(235,235,235,.28);

  --cream:#BAA47B;
  --cream-soft:#D6C7A8;
  --paper:#EBEBEB;
  --paper-70:rgba(235,235,235,.70);
  --paper-45:rgba(235,235,235,.45);

  --font:"Plus Jakarta Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
  --pad:clamp(20px,5vw,72px);
  --maxw:1560px;
  --ease:cubic-bezier(.22,.61,.36,1);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scroll-padding-top:72px}
body{margin:0;background:var(--ink-900);color:var(--paper);font-family:var(--font);
  font-weight:400;line-height:1.5;-webkit-font-smoothing:antialiased;overflow-x:hidden}
img,video{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
.wrap{max-width:var(--maxw);margin:0 auto;padding-inline:var(--pad)}
.skip{position:absolute;left:-9999px}
.skip:focus{left:12px;top:12px;background:var(--paper);color:var(--black);padding:10px 16px;z-index:200}

/* ================= header ================= */
.hdr{position:fixed;left:0;right:0;top:0;z-index:100;background:rgba(10,10,10,.72);
  backdrop-filter:blur(16px);border-bottom:1px solid var(--line);
  transition:transform .45s var(--ease)}
.hdr.is-hidden{transform:translateY(-100%)}
.hdr-in{display:flex;align-items:center;justify-content:space-between;gap:24px;
  max-width:var(--maxw);margin:0 auto;padding:15px var(--pad)}
/* logo noticeably bigger per the brief */
.logo img{height:20px;width:auto}
.nav{display:flex;align-items:center;gap:clamp(18px,2.6vw,40px)}
.mlink{position:relative;display:inline-block;overflow:hidden;vertical-align:top;
  font-size:13px;letter-spacing:.14em;text-transform:uppercase;line-height:1.4;height:1.4em}
.mlink span{display:block;transition:transform .45s var(--ease)}
.mlink span::after{content:attr(data-t);display:block;color:var(--cream)}
.mlink:hover span,.mlink:focus-visible span{transform:translateY(-1.4em)}
.mlink[aria-current="page"] span::after{color:var(--paper)}

.burger{display:none;width:34px;height:34px;align-items:center;justify-content:center}
.burger span{display:block;width:22px;height:1px;background:var(--paper);position:relative;
  transition:background .2s var(--ease)}
.burger span::before,.burger span::after{content:"";position:absolute;left:0;width:22px;height:1px;
  background:var(--paper);transition:transform .35s var(--ease),top .35s var(--ease)}
.burger span::before{top:-7px}.burger span::after{top:7px}
.burger[aria-expanded="true"] span{background:transparent}
.burger[aria-expanded="true"] span::before{top:0;transform:rotate(45deg)}
.burger[aria-expanded="true"] span::after{top:0;transform:rotate(-45deg)}

/* ================= hero ================= */
.hero{background:var(--black);padding:clamp(56px,11vh,120px) 0 clamp(34px,6vh,64px);
  position:relative;overflow:hidden}
/* faint texture, keeps the black from reading flat */
.hero::after{content:"";position:absolute;inset:0;pointer-events:none;opacity:.5;
  background:radial-gradient(120% 80% at 50% -10%,rgba(186,164,123,.13),transparent 62%)}
.hero .wrap{position:relative;z-index:1}
/* headline smaller than before, subheader sits under it */
.hero h1{margin:0;font-weight:300;letter-spacing:-.03em;line-height:1;
  font-size:clamp(3rem,11.5vw,10.5rem)}
/* optical alignment: pull each line left by its first glyph's side
   bearing, measured by render, so the ink lines up with the logo. */
.line{display:block;overflow:hidden;margin-left:calc(var(--lsb,0em) * -1)}
.line>i{display:block;font-style:normal;transform:translateY(102%);
  animation:riseIn .95s var(--ease) .15s forwards}
.line:nth-child(2)>i{animation-delay:.27s}
@keyframes riseIn{to{transform:translateY(0)}}
.hero__sub{margin:clamp(16px,2.2vw,24px) 0 0;max-width:52ch;
  font-size:clamp(.98rem,1.35vw,1.25rem);line-height:1.5;color:var(--paper-70);font-weight:300;
  opacity:0;animation:fadeUp .9s var(--ease) .4s forwards}
@keyframes fadeUp{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}

/* ================= showreel ================= */
.reel{background:var(--black);padding:0 0 clamp(40px,7vh,80px)}
.reel__frame{position:relative;width:100%;aspect-ratio:16/9;overflow:hidden;
  background:var(--ink-800);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.reel__frame video,.reel__frame img{width:100%;height:100%;object-fit:cover}
.reel__slot{position:absolute;inset:0;display:flex;flex-direction:column;gap:12px;
  align-items:center;justify-content:center;text-align:center;padding:24px;
  background:repeating-linear-gradient(45deg,#141414 0 18px,#181818 18px 36px);color:var(--paper-45)}
.reel__slot b{display:block;font-size:clamp(1rem,2vw,1.5rem);font-weight:300;color:var(--paper-70)}
.reel__slot span{font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--cream)}
.reel__cap{display:flex;flex-wrap:wrap;gap:10px;justify-content:space-between;
  margin-top:14px;font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--paper-45)}

/* ================= sections ================= */
.sec{padding:clamp(56px,9vh,110px) 0}
.sec--flush{padding-bottom:0}
.sec--black{background:var(--black)}
.eyebrow{font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--cream);
  margin:0 0 18px;font-weight:600}
.h2{margin:0 0 clamp(24px,3.4vw,42px);font-weight:300;letter-spacing:-.03em;
  line-height:1;font-size:clamp(1.9rem,5vw,3.8rem)}
.lede{font-size:clamp(1.05rem,1.9vw,1.6rem);font-weight:300;line-height:1.42;max-width:34ch;margin:0}

/* ================= selected work ================= */
.workbar{display:flex;flex-wrap:wrap;gap:22px;align-items:flex-end;
  justify-content:space-between;margin:0 0 26px}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin:0;padding:0;list-style:none}
.chip{border:1px solid var(--line-2);border-radius:999px;padding:8px 18px;font-size:12px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--paper-70);transition:.25s var(--ease)}
.chip:hover{border-color:var(--paper);color:var(--paper)}
.chip[aria-pressed="true"]{background:var(--paper);border-color:var(--paper);color:var(--black)}
.viewbar{display:flex;align-items:center;gap:9px}
.viewbar .lbl2{font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--paper-45)}
.vbtn{border:1px solid var(--line-2);border-radius:999px;padding:7px 15px;font-size:12px;
  color:var(--paper-70);transition:.25s var(--ease)}
.vbtn:hover{border-color:var(--paper);color:var(--paper)}
.vbtn[aria-pressed="true"]{background:var(--cream);border-color:var(--cream);color:var(--black)}

/* full-bleed, edge to edge, photos touching */
.grid{display:grid;gap:0;width:100%}
.grid[data-view="2"]{grid-template-columns:repeat(auto-fit,minmax(min(100%,560px),1fr))}
.grid[data-view="3"]{grid-template-columns:repeat(auto-fit,minmax(min(100%,380px),1fr))}
.card{position:relative;display:block;overflow:hidden;background:var(--ink-800)}
.card__media{position:relative;aspect-ratio:16/10;overflow:hidden}
.grid[data-view="3"] .card__media{aspect-ratio:4/3}
.card__media img{width:100%;height:100%;object-fit:cover;
  transition:transform .9s var(--ease),filter .6s var(--ease);filter:grayscale(1)}
.card:hover .card__media img{transform:scale(1.05);filter:grayscale(0)}
.ph{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  background:repeating-linear-gradient(45deg,#141414 0 16px,#191919 16px 32px);
  color:var(--paper-45);font-size:11px;letter-spacing:.2em;text-transform:uppercase}
.card__ov{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:flex-end;
  gap:10px;padding:clamp(18px,2.4vw,30px);
  background:linear-gradient(to top,rgba(0,0,0,.86),rgba(0,0,0,.10) 62%,transparent)}
.card__ov h3{margin:0;font-size:clamp(1.15rem,2.2vw,1.9rem);font-weight:300;letter-spacing:-.02em}
.tags{display:flex;flex-wrap:wrap;gap:6px;margin:0;padding:0;list-style:none;
  opacity:0;transform:translateY(8px);transition:.45s var(--ease)}
.card:hover .tags{opacity:1;transform:none}
.tag{font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  border:1px solid var(--line-2);border-radius:999px;padding:4px 10px;color:var(--paper-70)}
.card.is-hidden{display:none}

/* ================= services ================= */
.svc{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.svc li{border-bottom:1px solid var(--line)}
.svc .row{display:flex;align-items:baseline;gap:clamp(16px,4vw,56px);
  padding:clamp(20px,3.2vw,34px) 0;transition:padding-left .45s var(--ease)}
.svc li:hover .row{padding-left:16px}
.svc li:hover .t{color:var(--cream)}
.svc .n{font-size:11px;color:var(--cream);font-weight:600;min-width:34px;letter-spacing:.1em}
.svc .t{font-size:clamp(1.3rem,3.4vw,2.5rem);font-weight:300;letter-spacing:-.025em;
  flex:1;min-width:0;transition:color .35s var(--ease)}

/* ================= how we work ================= */
.steps{display:grid;gap:0;margin-top:10px;background:var(--black);
  grid-template-columns:repeat(auto-fit,minmax(min(100%,180px),1fr));
  border-top:1px solid var(--line)}
.step{background:var(--black);padding:clamp(22px,3vw,36px);
  border-bottom:1px solid var(--line);border-right:1px solid var(--line);
  transition:background .4s var(--ease)}
.step:hover{background:var(--ink-700)}
.step .n{font-size:11px;letter-spacing:.2em;color:var(--cream);font-weight:600}
.step h3{margin:12px 0 0;font-size:clamp(1.15rem,2.3vw,1.65rem);
  font-weight:300;letter-spacing:-.02em;color:var(--paper)}

/* ================= client logos ================= */
.logos{overflow:hidden;padding:clamp(24px,3vw,38px) 0;
  border-block:1px solid var(--line);background:var(--black)}
.logos__track{display:flex;align-items:center;width:max-content;
  animation:logoslide 42s linear infinite}
.logos__track img{height:clamp(15px,1.8vw,24px);width:auto;
  margin-inline:clamp(24px,3.8vw,58px);opacity:.42;
  transition:opacity .4s var(--ease)}
.logos__track img:hover{opacity:1}
.logos:hover .logos__track{animation-play-state:paused}
@keyframes logoslide{to{transform:translateX(-50%)}}

/* ================= contact ================= */
.contact{background:var(--black);padding:clamp(64px,11vh,130px) 0 clamp(30px,5vh,56px);
  text-align:center;position:relative;overflow:hidden}
.contact::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(100% 70% at 50% 110%,rgba(186,164,123,.14),transparent 60%)}
.contact .wrap{position:relative;z-index:1}
.contact h2{margin:0;font-weight:300;letter-spacing:-.035em;line-height:1;
  font-size:clamp(2.6rem,9vw,7.5rem)}
.contact .inq{margin:clamp(26px,4vw,42px) 0 0;font-size:11px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--cream)}
.mailto{display:inline-block;margin-top:12px;font-size:clamp(1.05rem,2.4vw,1.75rem);
  font-weight:300;letter-spacing:-.01em;border-bottom:1px solid var(--line-2);
  padding-bottom:5px;transition:border-color .35s var(--ease),color .35s var(--ease)}
.mailto:hover{border-color:var(--cream);color:var(--cream)}
/* oversized wordmark closing the page */
.contact__mark{display:block;width:100%;
  margin:clamp(52px,9vw,104px) 0 0;opacity:.26}
.ftr-btm{display:flex;flex-wrap:wrap;gap:14px;justify-content:space-between;
  margin-top:clamp(34px,5vw,56px);padding-top:20px;border-top:1px solid var(--line);
  font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--paper-45)}

/* ================= about page ================= */
.prose{max-width:62ch;margin-inline:auto}
.prose p{font-size:clamp(1rem,1.35vw,1.15rem);line-height:1.7;color:var(--paper-70);margin:0 0 1.2em}
.prose p.big{font-size:clamp(1.2rem,2.2vw,1.65rem);color:var(--paper);font-weight:300;line-height:1.4}
.centered{text-align:center}

/* ================= reveal ================= */
.rv{opacity:0;transform:translateY(22px);
  transition:opacity .8s var(--ease),transform .8s var(--ease)}
.rv.in{opacity:1;transform:none}

/* ================= mobile ================= */
@media (max-width:900px){
  .nav{position:fixed;left:0;right:0;top:var(--navtop,58px);bottom:0;background:var(--ink-900);
    flex-direction:column;align-items:stretch;gap:0;padding:10px var(--pad) 40px;
    overflow-y:auto;transform:translateX(100%);transition:transform .45s var(--ease);
    display:flex;visibility:hidden}
  .nav.open{transform:translateX(0);visibility:visible}
  .mlink{height:auto;overflow:visible;font-size:17px;padding:18px 0;
    border-bottom:1px solid var(--line)}
  .mlink span::after{display:none}
  .mlink:hover span,.mlink:focus-visible span{transform:none}
  .burger{display:flex}
  body.nav-open{overflow:hidden}
  .svc .row{flex-direction:column;gap:6px}
  .workbar{gap:16px}
}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important;scroll-behavior:auto!important}
  .rv{opacity:1;transform:none}
  .line>i{transform:none}
  .hero__sub{opacity:1}
  .tags{opacity:1;transform:none}
}

/* ======================================================================
   POST-DELIVERY 2 — intro curtain, lightbox, festival banner
   ====================================================================== */

/* ---------- intro curtain ---------- */
.intro{height:170svh;position:relative;background:var(--black)}
.intro__inner{position:sticky;top:0;height:100svh;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:clamp(20px,3vw,34px);
  padding:0 var(--pad);text-align:center;overflow:hidden}
.intro__inner::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(90% 60% at 50% 45%,rgba(186,164,123,.15),transparent 65%)}
.intro__logo{position:relative;z-index:1;width:min(78vw,900px);
  transform-origin:center center;will-change:transform,opacity}
.intro__sub{position:relative;z-index:1;margin:0;max-width:44ch;
  font-size:clamp(.95rem,1.5vw,1.3rem);font-weight:300;line-height:1.5;color:var(--paper-70);
  will-change:opacity}
.scrolldown{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;
  gap:10px;margin-top:clamp(8px,2vw,20px);font-size:10px;letter-spacing:.24em;
  text-transform:uppercase;color:var(--paper-45);will-change:opacity}
.scrolldown:hover{color:var(--cream)}
.scrolldown i{display:block;width:1px;height:46px;background:linear-gradient(to bottom,
  transparent,var(--cream));position:relative;overflow:hidden}
.scrolldown i::after{content:"";position:absolute;left:0;top:-46px;width:1px;height:46px;
  background:linear-gradient(to bottom,transparent,var(--paper));
  animation:dropline 1.9s var(--ease) infinite}
@keyframes dropline{0%{transform:translateY(0)}60%,100%{transform:translateY(92px)}}
/* header logo fades in as the intro mark lands in the bar */
.hdr .logo img{opacity:var(--logo-op,1);transition:opacity .25s linear}

/* ---------- headline: 30% smaller than before ---------- */
.hero h1{font-size:clamp(2.1rem,8vw,7.35rem)}

/* ---------- services: smaller, no hover (they link nowhere) ---------- */
.svc .t{font-size:clamp(1.05rem,2.2vw,1.65rem)}
.svc .row{padding:clamp(14px,2vw,22px) 0}
.svc li:hover .row{padding-left:0}
.svc li:hover .t{color:inherit}

/* ---------- work cards become play triggers ---------- */
.card{cursor:pointer;border:0;padding:0;text-align:left;width:100%;font:inherit;color:inherit}
.card__play{position:absolute;left:50%;top:50%;width:clamp(44px,4.5vw,64px);aspect-ratio:1;
  transform:translate(-50%,-50%) scale(.85);border-radius:50%;
  border:1px solid rgba(235,235,235,.6);background:rgba(0,0,0,.30);backdrop-filter:blur(3px);
  display:grid;place-items:center;opacity:0;transition:.45s var(--ease);z-index:2}
.card:hover .card__play,.card:focus-visible .card__play{opacity:1;transform:translate(-50%,-50%) scale(1)}
.card__play::after{content:"";border-left:11px solid var(--paper);
  border-top:7px solid transparent;border-bottom:7px solid transparent;margin-left:3px}
.card__src{font-size:10px;letter-spacing:.14em;text-transform:uppercase;color:var(--cream)}

/* ---------- festival banner inside work ---------- */
.fest{margin-top:clamp(28px,4vw,52px);border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);background:var(--black)}
.fest__img{width:100%;height:auto;display:block;opacity:.85;
  transition:opacity .5s var(--ease)}
.fest:hover .fest__img{opacity:1}
.fest__cap{display:flex;flex-wrap:wrap;align-items:center;gap:16px;justify-content:space-between;
  padding:14px var(--pad);font-size:11px;letter-spacing:.18em;text-transform:uppercase;
  color:var(--paper-45)}
.fest__cap img{height:26px;width:auto;opacity:.6}

/* ---------- lightbox ---------- */
.lb{position:fixed;inset:0;z-index:300;display:none;background:rgba(0,0,0,.95);
  padding:max(4vmin,54px) 4vmin 4vmin}
.lb.open{display:grid;place-items:center}
.lb__box{width:min(96vw,1360px);aspect-ratio:16/9;background:#000;position:relative}
.lb__box iframe,.lb__box video{position:absolute;inset:0;width:100%;height:100%;border:0}
.lb__close{position:absolute;top:14px;right:16px;z-index:310;width:44px;height:44px;
  border:1px solid var(--line-2);border-radius:50%;display:grid;place-items:center;
  color:var(--paper);font-size:20px;line-height:1;transition:.25s var(--ease)}
.lb__close:hover{background:var(--paper);color:var(--black)}
.lb__title{position:absolute;left:0;right:64px;top:-34px;font-size:12px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--paper-45)}
body.lb-open{overflow:hidden}

@media (prefers-reduced-motion:reduce){
  .intro{height:auto}
  .intro__inner{position:static;height:auto;padding-block:clamp(60px,12vh,120px)}
  .scrolldown i::after{animation:none}
}


/* ======================================================================
   POST-DELIVERY 3 — nav hidden on arrival, centred hero
   ====================================================================== */

/* nav bar is absent on load; it drops in once the mark has landed */
.hdr.is-top{transform:translateY(-100%)}

/* the travelling mark rides above the bar it is heading into */
.intro__inner{z-index:120}
.intro{height:150svh}

/* hero now occupies the middle of the screen, where the mark started */
.hero{min-height:100svh;display:grid;place-items:center;
  padding:clamp(40px,8vh,96px) 0;text-align:center}
.hero .wrap{width:100%}
.hero h1{margin-inline:auto}
/* centred text: no side-bearing pull, it would throw the centring off */
.line{margin-left:0}
.hero__sub{margin:clamp(18px,2.4vw,30px) auto 0;max-width:46ch;animation:none;opacity:1}

/* headline animates when it scrolls into view, not on page load */
.line>i{animation:none}
.rv.in .line>i{animation:riseIn .95s var(--ease) forwards}
.rv.in .line:nth-child(2)>i{animation-delay:.12s}

@media (prefers-reduced-motion:reduce){
  .hdr.is-top{transform:none}
  .line>i,.rv.in .line>i{animation:none;transform:none}
}


/* ---------- featured Messi block ---------- */
.reel{background:var(--black);padding:0 0 clamp(34px,5vh,64px)}
.reel__frame{position:relative;display:block;width:100%;aspect-ratio:16/9;overflow:hidden;
  border:0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:0;background:var(--ink-800);cursor:pointer}
.reel__frame img{width:100%;height:100%;object-fit:cover;
  transition:transform .9s var(--ease),filter .6s var(--ease);filter:grayscale(1)}
.reel__frame:hover img,.reel__frame:focus-visible img{transform:scale(1.03);filter:grayscale(0)}
.reel__frame .card__play{width:clamp(58px,6vw,92px);opacity:.9}
.reel__frame:hover .card__play{opacity:1}
.reel__cap{display:flex;flex-wrap:wrap;gap:10px;justify-content:space-between;
  margin-top:14px;font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--paper-45)}

/* festival banner sits inside the work column, not edge to edge */
.fest{margin:clamp(28px,4vw,52px) 0 0;border:1px solid var(--line)}
.fest__cap{padding:14px 18px}


/* ======================================================================
   POST-DELIVERY 4
   ====================================================================== */

/* "Two up" must mean two. auto-fill with a 560px minimum was fitting three
   columns on a wide screen, so the label and the layout disagreed. */
.grid[data-view="2"]{grid-template-columns:repeat(2,minmax(0,1fr))}
.grid[data-view="3"]{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:900px){
  .grid[data-view="2"],.grid[data-view="3"]{grid-template-columns:1fr}
}

/* the intro mark leaves straight up — no sideways flight */
.intro__logo{transform-origin:center top}
.intro__sub{margin:0;max-width:44ch}

/* festival banner edge to edge again */
.fest{margin:clamp(28px,4vw,52px) 0 0;border:0;
  border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.fest__cap{padding:14px var(--pad)}


/* ======================================================================
   POST-DELIVERY 5 — mark and headline share one stage
   ====================================================================== */

/* Long enough to play the swap and then hold the headline, so nothing
   scrolls past an empty screen. */
.intro{height:200svh}
.intro__inner{gap:clamp(18px,2.6vw,30px)}

/* both sit in the same grid cell: one leaves, the other arrives in place */
.intro__swap{position:relative;z-index:1;display:grid;width:100%;
  place-items:center;min-height:clamp(120px,22vh,230px)}
.intro__swap > *{grid-area:1/1}
.intro__logo{width:min(78vw,900px);transform-origin:center top;
  will-change:transform,opacity}
.intro__head{margin:0;font-weight:300;letter-spacing:-.03em;line-height:1;
  font-size:clamp(2.1rem,8vw,7.35rem);opacity:0;will-change:opacity,transform}
.intro__head .line{overflow:visible}
.intro__head .line>i{transform:none;animation:none}
.intro__sub{position:relative;z-index:1;margin:0 auto;max-width:44ch}


/* ======================================================================
   POST-DELIVERY 6
   ====================================================================== */

/* The bar was sticky, so it reserved 51px of layout even while translated
   out of view - that reserved strip showed the body colour above the intro's
   pure black and read as a grey band. Fixed takes it out of the flow, so the
   intro starts at the very top of the viewport. */
.hdr{will-change:transform}
/* About has no intro, so its first section must clear the fixed bar */
.hero{padding-top:calc(clamp(40px,8vh,96px) + 56px)}


/* The close glyph was the "times" character, whose vertical metrics sit high
   in the em box, so it never optically centred in the circle. Drawn instead. */
.lb__close{font-size:0;line-height:0}
.lb__close i{position:relative;display:block;width:16px;height:16px}
.lb__close i::before,.lb__close i::after{content:"";position:absolute;
  top:50%;left:50%;width:16px;height:1.5px;background:currentColor;
  transform-origin:center}
.lb__close i::before{transform:translate(-50%,-50%) rotate(45deg)}
.lb__close i::after{transform:translate(-50%,-50%) rotate(-45deg)}


/* ======================================================================
   POST-DELIVERY 7 — the bar sits on top, solid
   ====================================================================== */

/* It was translucent with a blur, so whatever scrolled underneath showed
   through it. Solid black hides it outright and matches the intro exactly,
   so no tonal band appears where the two meet. */
.hdr{background:var(--black);backdrop-filter:none}

/* The intro stage used to outrank the bar (z-index 120) so the travelling
   mark could ride over it. The mark is fully faded by 44% and the bar only
   arrives at 45%, so that is no longer needed - and it let the headline
   paint over the bar on short viewports. */
.intro__inner{z-index:1}


/* The banner carried a top margin, leaving a gap between the last row of the
   grid and the banner. Flush against it instead - the grid is gapless, so a
   gap only here read as a mistake. */
.fest{margin-top:0}

/* Work cards are never hidden waiting for a reveal.
   A fade-in is decoration; an invisible portfolio grid is a broken page, and
   any reveal that depends on a callback can leave content stuck at opacity 0.
   Text blocks keep .rv - if one of those misses, the page still reads. */
.grid .card{opacity:1;transform:none}


/* ======================================================================
   POST-DELIVERY 8
   ====================================================================== */

/* --- 3. close the gap above Selected work (both breakpoints) --- */
.reel{padding-bottom:0}
#work.sec--flush{padding-top:clamp(26px,4vh,46px)}

/* --- 4. the mobile menu could not work ---
   .hdr carried will-change:transform, and a will-change/transform ancestor
   becomes the containing block for position:fixed descendants - so the panel
   was being laid out against the 51px bar instead of the viewport. */
.hdr{will-change:auto}
body.nav-open .hdr{transform:none}

/* --- 6. Let's talk sits higher, centred between services and the mark --- */
.contact{padding-top:clamp(40px,6vh,80px)}
.contact__mark{margin-top:clamp(40px,7vw,84px)}

/* --- 7. the closing mark rises into place --- */
.contact__mark{opacity:0;transform:translateY(46px);
  transition:opacity 1s var(--ease),transform 1.1s var(--ease)}
.contact__mark.in{opacity:.26;transform:none}

/* --- 5. About reads as an article, not a poster --- */
.hero{min-height:auto;padding:calc(clamp(56px,11vh,110px) + 56px) 0 clamp(14px,2.5vh,26px)}
.hero + .sec{padding-top:clamp(20px,3vh,36px)}
.prose p{line-height:1.62;margin:0 0 .95em}
.prose p.big{margin-bottom:1.1em}

@media (max-width:900px){
  /* --- 1 + 2. mark and headline closer, block properly centred --- */
  .intro__swap{min-height:0}
  .intro__logo{width:min(66vw,420px)}
  .intro__inner{gap:clamp(14px,3.5vw,22px)}
  .intro__sub{font-size:1rem;line-height:1.45}
  .scrolldown{margin-top:clamp(14px,4vw,26px)}

  /* --- 9. no view switcher on mobile: the grid is one column --- */
  .viewbar{display:none}
  .workbar{gap:14px}

  /* --- 4. full-screen black panel, large type, bar stays clickable above --- */
  .nav{position:fixed;inset:0;top:0;z-index:99;background:var(--black);
    justify-content:center;gap:0;padding:calc(56px + 6vh) var(--pad) 8vh;
    overflow-y:auto}
  .nav.open{transform:none}
  .mlink{font-size:clamp(1.6rem,7vw,2.4rem);letter-spacing:-.01em;text-transform:none;
    padding:clamp(14px,2.6vh,22px) 0;border-bottom:1px solid var(--line)}
  .mlink:last-of-type{border-bottom:0}
  .burger{position:relative;z-index:101}

  .contact h2{font-size:clamp(2.4rem,13vw,4rem)}
  .contact__mark{margin-top:clamp(30px,9vw,60px)}
}


/* ======================================================================
   POST-DELIVERY 9 — mobile intro: one shared measure
   ====================================================================== */
@media (max-width:900px){
  /* Mark, headline and subheadline all run to the same width - the content
     column - instead of three different measures.
     "entertainment." is the longest line at roughly 7.3em, so filling a
     column of ~90vw needs about 12.3vw of type. */
  .intro__logo{width:100%}
  .intro__sub{max-width:100%}
  .intro__head{font-size:clamp(2.2rem,13.2vw,4.6rem)}
  .intro__swap{width:100%}
}


/* ======================================================================
   POST-DELIVERY 10
   ====================================================================== */

/* The closing mark rose because moving "Let's talk" up cut its top margin,
   not because of the animation. Restored, and now it sits the same distance
   above the rule as the rule sits above the copyright line. */
.contact__mark{margin-top:clamp(56px,9vw,104px)}

@media (max-width:900px){
  /* The menu panel is a child of the bar, so it painted over the wordmark:
     the panel carries z-index 99 while the logo sat at auto. Lift the logo,
     as the burger already is, so both stay above the open panel. */
  .logo{position:relative;z-index:101}
  .contact__mark{margin-top:clamp(46px,11vw,76px)}
}


/* ======================================================================
   POST-DELIVERY 11 — the rule sits centred between mark and copyright
   ====================================================================== */

/* The gap above the rule was clamp(34px,5vw,56px) while the gap below it was
   a flat 20px, so the mark read as floating well clear of the line while the
   copyright sat tight under it. The asset has no transparent padding - its box
   edge is the ink edge - so matching the two values matches what you see.
   The mark's own top margin grows by the same amount the gap loses, so the
   mark moves down to the rule rather than the rule moving up to the mark. */
.ftr-btm{margin-top:20px}
.contact__mark{margin-top:clamp(92px,14vw,140px)}

@media (max-width:900px){
  .contact__mark{margin-top:clamp(72px,16vw,112px)}
}


/* Mobile only: the intro mark sits 10% inside the column the headline and
   subheadline fill, rather than running the full width with them. */
@media (max-width:900px){
  .intro__logo{width:90%}
}


/* Measured on the live page: the mark's ink sat 20px above the rule while the
   copyright's glyphs sat 22px below it - the 2px is the text's half-leading,
   since padding lands on the line box, not the letters. Matching the glyphs
   rather than the box makes the two gaps read as equal. */
.ftr-btm{margin-top:22px}


/* ======================================================================
   POST-DELIVERY 12 — the closing mark rises out of a mask
   ====================================================================== */

/* It used to fade in. Now a clipping box hides it and the mark slides up out
   of that box at its final opacity the whole way, so it is revealed rather
   than faded up. The mask keeps the mark's layout height, so nothing shifts. */
.markmask{overflow:hidden;margin-top:clamp(92px,14vw,140px);line-height:0}
.contact__mark{display:block;width:100%;margin:0;
  opacity:.26;
  transform:translateY(102%);
  transition:transform 1.15s var(--ease)}
.contact__mark.in{opacity:.26;transform:translateY(0)}

@media (max-width:900px){
  .markmask{margin-top:clamp(72px,16vw,112px)}
  .contact__mark{margin:0}
}
@media (prefers-reduced-motion:reduce){
  .contact__mark{transform:none}
}


/* ======================================================================
   POST-DELIVERY 13 — one black
   ====================================================================== */

/* .sec declared no background, so it showed the body's --ink-900 (#0A0A0A)
   while the sections around it painted --black (#000). Against pure black
   that 10/255 difference read as a grey panel behind Selected work.
   Everything is one black now. */
body{background:var(--black)}
.sec{background:var(--black)}


/* ======================================================================
   POST-DELIVERY 14 — no hover on touch, so cards light up at the centre
   ====================================================================== */

/* A touch screen never fires :hover, so on mobile the colour, the tags and the
   play affordance were unreachable - every card stayed grey and bare. The
   card nearest the middle of the screen now carries .is-active, which mirrors
   the hover state exactly, so the grid lights up and dims as it scrolls past.
   Desktop keeps :hover and never gets the class. */
@media (max-width:900px){
  .card.is-active .card__media img{transform:scale(1.05);filter:grayscale(0)}
  .card.is-active .tags{opacity:1;transform:none}
  .card.is-active .card__play{opacity:1;transform:translate(-50%,-50%) scale(1)}
  .reel__frame.is-active img{transform:scale(1.03);filter:grayscale(0)}
  .reel__frame.is-active .card__play{opacity:1}
}

/* Belt and braces for the strip: the track keeps its own height from the
   declared image box, so it cannot collapse while the files decode. */
.logos__track img{flex:0 0 auto}


/* ======================================================================
   POST-DELIVERY 15 — festival flyer moves into the lightbox
   ====================================================================== */

.fest{margin-top:0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.fest__trigger{display:flex;width:100%;align-items:center;justify-content:space-between;
  gap:16px;padding:14px var(--pad);cursor:pointer;
  font-size:11px;letter-spacing:.18em;text-transform:uppercase;color:var(--paper-45);
  transition:color .3s var(--ease)}
.fest__trigger:hover,.fest__trigger:focus-visible{color:var(--paper)}
.fest__mark{height:26px;width:auto;opacity:.55;transition:opacity .3s var(--ease)}
.fest__trigger:hover .fest__mark,.fest__trigger:focus-visible .fest__mark{opacity:1}

/* the lightbox also carries stills now, which are not 16:9 */
.lb__box.is-img{aspect-ratio:auto;background:transparent;display:grid;place-items:center}
.lb__box.is-img img{position:static;width:100%;height:auto;max-height:82vh;object-fit:contain}


/* ======================================================================
   POST-DELIVERY 16 — the lightbox caption never sits on the image
   ====================================================================== */

/* The caption was absolutely positioned at top:-34px, which only holds for a
   single line: a second line grew downwards and landed on the picture. It is
   in normal flow now, in a row above the frame with the close button, so any
   number of lines pushes the frame down instead of covering it. */
.lb.open{display:grid;place-items:center}
.lb__inner{width:min(96vw,1360px);display:flex;flex-direction:column;gap:10px}
.lb__head{display:flex;align-items:flex-start;gap:14px;justify-content:space-between}
.lb__title{position:static;margin:0;flex:1;min-width:0;
  font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  line-height:1.5;color:var(--paper-45)}
.lb__close{position:static;flex:0 0 auto;width:38px;height:38px;margin-top:-8px}
.lb__box{width:100%;aspect-ratio:16/9;background:#000;position:relative}
.lb__box.is-img{aspect-ratio:auto;background:transparent;display:grid;place-items:center}
.lb__box.is-img img{position:static;width:100%;height:auto;max-height:76vh;object-fit:contain}

@media (max-width:900px){
  .lb{padding:4vmin}
  .lb__title{font-size:10px;letter-spacing:.12em}
  .lb__box.is-img img{max-height:70vh}
}


/* ======================================================================
   POST-DELIVERY 17 — marquee slides by pixels, not a percentage
   ====================================================================== */

/* Travel is exactly one set width, handed in from JS, so the loop never
   re-resolves against a changing track and the track stays small. */
@keyframes logoslide{from{transform:translateX(0)}
                     to{transform:translateX(calc(var(--mq-shift,50%) * -1))}}
.logos__track{animation:logoslide var(--mq-dur,20s) linear infinite}

/* Pause on hover only where hovering is real. On a touch screen :hover latches
   after a tap and would leave the strip stopped. */
.logos:hover .logos__track{animation-play-state:running}
@media (hover:hover){
  .logos:hover .logos__track{animation-play-state:paused}
}


/* No will-change here: it pins a composited layer for the life of the page,
   and this strip is exactly where blank stretches were showing. The animation
   composites fine without it now that the track is small. */

/* ======================================================================
   POST-DELIVERY 18 — floating nav, descenders, reduced motion
   ====================================================================== */

/* Seamless: no rule and no panel, so the wordmark and menu float. */
.hdr{border-bottom:0;background:transparent;backdrop-filter:none}

/* A .line box is exactly 1em tall, so with line-height:1 the descenders
   (g, y, p, q, j) fall outside it and overflow:hidden clips them - the g in
   "original" on About. Grow the clip box downwards and cancel it with an equal
   negative margin: the descender shows and the leading does not move. */
.line{padding-bottom:.22em;margin-bottom:-.22em}

/* The curtain was two full viewports of scroll. Shorter. */
.intro{height:160svh}

/* With Reduce Motion on, the intro was broken rather than simplified:
   .intro{height:auto} sat in a reduced-motion block but a later top-level
   .intro{height:200svh} outranked it - media queries add no specificity, so
   source order decided - while .intro__inner{position:static} did win. The
   result was a full-height section with its content collapsed at the top and a
   viewport of empty black below. The headline never appeared either, since
   .intro__head{opacity:0} is only undone by the script, which this mode skips.
   These come last, so they hold. */
@media (prefers-reduced-motion:reduce){
  .intro{height:auto}
  .intro__inner{position:static;height:auto;padding-block:clamp(56px,11vh,110px)}
  .intro__swap{display:block;min-height:0;width:auto}
  .intro__swap > *{grid-area:auto}
  .intro__logo{margin:0 auto;transform:none;opacity:1}
  .intro__head{opacity:1;transform:none;text-align:center;
    margin-top:clamp(18px,3vw,32px)}
  .contact__mark{opacity:.26;transform:none}
  .scrolldown{opacity:1}
}

/* ======================================================================
   POST-DELIVERY 19 — the featured film plays in place
   ====================================================================== */

/* Mounted only once the block is actually on screen and torn down when it
   leaves, so nothing is fetched until it is wanted. It sits over the poster
   and ignores pointer events, so the frame stays a single click target that
   opens the film with sound. */
.reel__video{position:absolute;inset:0;width:100%;height:100%;border:0;z-index:1;
  pointer-events:none;opacity:0;transition:opacity .9s var(--ease)}
.reel__video.in{opacity:1}
.reel__frame .card__play{z-index:2}
.reel__frame .reel__sound{position:absolute;right:16px;bottom:14px;z-index:2;
  font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--paper-45);
  opacity:0;transition:opacity .4s var(--ease);pointer-events:none}
.reel__frame:hover .reel__sound{opacity:1}

/* ======================================================================
   POST-DELIVERY 20 — the film peeks while the headline lands
   ====================================================================== */

/* The pinned panel is shorter than the screen, so the section beneath it -
   the featured film - is already showing along the bottom by the time the
   headline and the bar arrive. 82svh puts its top edge where it was marked. */
.intro__inner{height:82svh}
.reel__sound{opacity:0}
.reel__frame:hover .reel__sound{opacity:1}

/* ======================================================================
   POST-DELIVERY 21 — Reduce Motion keeps the piece, loses the movement
   ====================================================================== */

/* The previous pass unstacked the intro entirely under Reduce Motion, so the
   mark, the headline and the subheadline all landed at once with no sequence -
   which is what the client was seeing and reporting as "no animation".
   Reducing motion should not mean removing the work. The structure and the
   order stay: the panel is still pinned and the mark still hands over to the
   headline in the same spot. What goes is the part the preference is actually
   about - the large travel and the scaling. They cross-fade in place instead,
   driven by scroll position, so nothing moves on its own. */
@media (prefers-reduced-motion:reduce){
  .intro{height:160svh}
  .intro__inner{position:sticky;top:0;height:82svh;
    padding-block:0;justify-content:center}
  .intro__swap{display:grid;min-height:clamp(120px,22vh,230px);width:100%}
  .intro__swap > *{grid-area:1/1}
  .intro__logo{margin:0;transform:none}
  .intro__head{text-align:center;margin-top:0}
  .scrolldown{opacity:1}
  .contact__mark{transform:none;opacity:.26}
}

/* ======================================================================
   POST-DELIVERY 22 — the sound control is reachable on touch
   ====================================================================== */

/* It was hover-only, so on a phone nobody could see that sound was available
   at all. Browsers will not autoplay with audio, so the offer has to be
   visible: a quiet pill while the film is muted, gone once it is not. */
.reel__sound{opacity:1;pointer-events:auto;cursor:pointer;
  right:auto;left:50%;bottom:clamp(14px,2.4vw,24px);transform:translateX(-50%);
  display:inline-flex;align-items:center;gap:8px;
  padding:9px 16px;border:1px solid var(--line-2);border-radius:999px;
  background:rgba(0,0,0,.45);backdrop-filter:blur(6px);
  color:var(--paper);font-size:10px;letter-spacing:.2em;
  transition:opacity .4s var(--ease),border-color .3s var(--ease)}
.reel__sound::before{content:"";width:0;height:0;
  border-left:7px solid currentColor;
  border-top:5px solid transparent;border-bottom:5px solid transparent}
.reel__sound:hover{border-color:var(--paper)}
.reel__frame.has-sound .reel__sound{opacity:0;pointer-events:none}

/* ======================================================================
   POST-DELIVERY 23 — the lightbox always fits the window
   ====================================================================== */

/* The frame was only ever constrained by width: min(96vw, 1360px) with a 16:9
   ratio. Nothing capped its height, so on any window that is wide relative to
   its height the video ran past the bottom edge - 146px over on 1440x760, and
   exactly at the limit on 1280x832. The YouTube control bar went with it, which
   is why the fullscreen button was unreachable.

   The width is now also capped by what the height allows, so the frame shrinks
   to fit instead of overflowing. --lb-chrome covers the padding, the caption
   row and the gap around it. vh first for older engines, svh where supported,
   which is what mobile needs while the address bar moves. */
.lb{--lb-chrome:150px}
.lb__inner{width:min(96vw, calc((100vh - var(--lb-chrome)) * 16 / 9), 1360px)}
@supports (height:100svh){
  .lb__inner{width:min(96vw, calc((100svh - var(--lb-chrome)) * 16 / 9), 1360px)}
}

/* Stills keep the full width and are capped by height instead. */
.lb.is-still .lb__inner{width:min(96vw,1360px)}
.lb.is-still .lb__box.is-img img{max-height:calc(100vh - var(--lb-chrome))}
@supports (height:100svh){
  .lb.is-still .lb__box.is-img img{max-height:calc(100svh - var(--lb-chrome))}
}

@media (max-width:900px){
  .lb{--lb-chrome:120px}
}

/* ======================================================================
   POST-DELIVERY 24 — the sound pill is a pill, not a bar
   ====================================================================== */

/* The earlier rule was written as .reel__sound, one class, while the original
   is .reel__frame .reel__sound - two. So the original right:16px outranked the
   new right:auto, and with left:50% set as well the element stretched from the
   middle of the frame all the way to its right edge. It looked like a wide bar,
   and a click anywhere across that invisible width landed on it. Matching the
   original specificity lets it collapse back to its content. */
.reel__frame .reel__sound{
  left:50%;right:auto;bottom:clamp(14px,2.4vw,24px);
  transform:translateX(-50%);
  width:auto;max-width:max-content;
  display:inline-flex;align-items:center;gap:7px;
  padding:8px 14px;border:1px solid var(--line-2);border-radius:999px;
  background:rgba(0,0,0,.45);backdrop-filter:blur(6px);
  color:var(--paper);font-size:10px;letter-spacing:.18em;
  opacity:1;pointer-events:auto;cursor:pointer;
  transition:opacity .4s var(--ease),border-color .3s var(--ease)}
.reel__frame .reel__sound:hover{border-color:var(--paper)}
.reel__frame.has-sound .reel__sound{opacity:0;pointer-events:none}

/* The sound pill is gone: sound switches on by itself at the visitor's first
   interaction anywhere on the page, so a separate control was only ever an
   extra thing to mis-click. Kept hidden in case the markup lingers anywhere. */
.reel__sound{display:none}

/* The player API swaps the element it is given for its own iframe, so the
   positioned box is now a wrapper and the iframe simply fills it. */
.reel__video iframe{display:block;width:100%;height:100%;border:0}

/* ======================================================================
   POST-DELIVERY 25 — sound is a control, not a one-way switch
   ====================================================================== */

/* Sound could be turned on but never off. This is a real button and a sibling
   of the frame, not a child of it, so a tap can never fall through to the
   handler that opens the film - which is what kept happening before. */
.reel__stage{position:relative}
.reel__mute{position:absolute;right:clamp(14px,2vw,22px);bottom:clamp(14px,2vw,22px);
  z-index:3;display:inline-flex;align-items:center;gap:7px;
  padding:8px 14px;border:1px solid var(--line-2);border-radius:999px;
  background:rgba(0,0,0,.5);backdrop-filter:blur(6px);
  color:var(--paper-45);font-size:10px;letter-spacing:.18em;text-transform:uppercase;
  cursor:pointer;transition:color .3s var(--ease),border-color .3s var(--ease)}
.reel__mute:hover{color:var(--paper);border-color:var(--paper)}
.reel__mute i{position:relative;width:9px;height:9px;
  border-left:6px solid currentColor;
  border-top:5px solid transparent;border-bottom:5px solid transparent}
.reel__mute i::after{content:"";position:absolute;left:-7px;top:50%;
  width:13px;height:1px;background:currentColor;transform:translateY(-50%) rotate(-45deg)}
.reel__mute.is-on{color:var(--paper)}
.reel__mute.is-on i::after{display:none}

/* ======================================================================
   POST-DELIVERY 26 — the film sits higher on phones
   ====================================================================== */

/* The pinned panel is what decides how much of the film shows beneath it:
   whatever height it does not take, the film fills. At 82svh only 18svh of it
   appeared, which left a stretch of black between the scroll cue and the
   picture. Shorter panel on phones, so the film arrives sooner and higher. */
@media (max-width:900px){
  .intro__inner{height:70svh}
}

/* Sound control centred under the film rather than tucked to the right. */
.reel__mute{left:50%;right:auto;transform:translateX(-50%)}

/* ======================================================================
   POST-DELIVERY 27 — peek without moving the content
   ====================================================================== */

/* Shortening the panel was the wrong lever: the content centres inside it, so
   trimming its height took the space off the top as well and pushed everything
   up. The panel goes back to the full screen, which is what keeps the block
   centred, and the film is pulled up into the empty space underneath instead.
   Measured: the content ends at 69% of the screen, so a 25% rise clears the
   scroll cue with room to spare. The panel is a positioned, stacked element,
   so the film needs to be lifted above it to be seen at all. */
@media (max-width:900px){
  .intro__inner{height:100svh}
  .reel{position:relative;z-index:2;margin-top:-25svh}
}

/* ======================================================================
   POST-DELIVERY 28 — sound control matches the play button
   ====================================================================== */

/* It was a text pill: darker ground, heavier-reading outline and far too much
   button for a phone. Same circle, same weight and same treatment as play now,
   carrying a speaker icon that shows its state instead of a word. */
.reel__mute{
  width:clamp(44px,4.5vw,64px);height:auto;aspect-ratio:1;
  padding:0;border-radius:50%;
  border:1px solid rgba(235,235,235,.6);
  background:rgba(0,0,0,.30);backdrop-filter:blur(3px);
  display:grid;place-items:center;gap:0;
  color:var(--paper);font-size:0;letter-spacing:0;
  transition:background .3s var(--ease),border-color .3s var(--ease)}
.reel__mute:hover{background:rgba(0,0,0,.5);border-color:var(--paper)}
.reel__mute svg{width:46%;height:46%;overflow:visible;
  fill:none;stroke:currentColor;stroke-width:1.7;
  stroke-linecap:round;stroke-linejoin:round}
.reel__mute .ico-body{fill:currentColor;stroke:currentColor;stroke-width:1.2}
.reel__mute .ico-wave{display:none}
.reel__mute.is-on .ico-wave{display:block}
.reel__mute.is-on .ico-slash{display:none}

/* Same size as the play button it sits beside, not the smaller grid one. */
.reel__mute{width:clamp(58px,6vw,92px)}

/* ======================================================================
   POST-DELIVERY 29 — desktop centring, smaller control, none on phones
   ====================================================================== */

/* The panel was only put back to full height inside the phone breakpoint, so
   desktop kept centring its content inside 82svh and sat high. Same treatment
   here: full-height panel to hold the block centred, and the film lifted into
   the empty space below it instead. */
.intro__inner{height:100svh}
.reel{position:relative;z-index:2;margin-top:-18svh}

/* Much smaller. The stroke and the soft ground stay - only the scale changes. */
.reel__mute{width:clamp(30px,2.6vw,38px)}
.reel__mute svg{width:52%;height:52%;stroke-width:2}
.reel__mute .ico-body{stroke-width:1.4}

@media (max-width:900px){
  /* Sound starts by itself on phones, so the control only appears in the case
     where it did not - and vanishes the moment audio is running. */
  .reel__mute.is-on{display:none}
}

/* ======================================================================
   POST-DELIVERY 30 — play affordance clears once the film is running
   ====================================================================== */

/* Firefox kept the ring drawn over the playing film. It is only meant to say
   "this opens", so it goes as soon as the film is actually running - the host
   gets .in from onReady - and comes back on hover, where it means something. */
.reel__frame .card__play{transition:opacity .45s var(--ease)}
.reel__stage.is-live .reel__frame .card__play{opacity:0}
.reel__stage.is-live .reel__frame:hover .card__play{opacity:1}

/* ======================================================================
   POST-DELIVERY 31 — festivals become a gallery
   ====================================================================== */

/* The strip used to open a single banner. It now opens every festival mark
   and award at once, scrolling inside the lightbox. */
.fest__trigger{justify-content:space-between}
.fest__count{display:inline-grid;place-items:center;min-width:24px;height:24px;
  padding:0 7px;border:1px solid var(--line-2);border-radius:999px;
  font-size:10px;letter-spacing:.06em;color:var(--paper-45)}
.fest__trigger:hover .fest__count{color:var(--paper);border-color:var(--paper)}

/* Nine marks, every one on a different ground - cyan, green, white, black,
   transparent. Keying them to one colour would destroy most of them, so each
   sits on its own light tile instead and simply reads as what it is. */
.fest__grid{display:grid;gap:clamp(10px,1.4vw,18px);width:100%;
  grid-template-columns:repeat(auto-fill,minmax(min(100%,190px),1fr))}
.fest__tile{margin:0;display:grid;place-items:center;aspect-ratio:4/3;
  padding:clamp(14px,1.8vw,24px);border-radius:3px;background:var(--paper)}
.fest__tile img{max-width:100%;max-height:100%;width:auto;height:auto;
  object-fit:contain}

/* The gallery scrolls rather than being squeezed into a 16:9 frame. */
.lb.is-gallery .lb__inner{width:min(96vw,1180px)}
.lb.is-gallery .lb__box{aspect-ratio:auto;background:transparent;
  max-height:calc(100vh - var(--lb-chrome));overflow-y:auto;overscroll-behavior:contain}
@supports (height:100svh){
  .lb.is-gallery .lb__box{max-height:calc(100svh - var(--lb-chrome))}
}
.lb.is-gallery .lb__box > div{position:static;padding-right:4px}

/* ======================================================================
   POST-DELIVERY 32 — the festival gallery reads, and enlarges
   ====================================================================== */

/* The marks were being served at 720px and then squeezed into 190px tiles,
   so a poster like the Mar del Plata flyer was unreadable. The files are now
   the full originals, the tiles are bigger and carry a name, and every tile
   is a button that opens a slideshow. Block 31 styled .fest__tile as the
   paper box itself; the box is now .fest__shot, so the old paper, padding,
   centring and 4/3 ratio have to be unset here. */
.fest__grid{gap:clamp(14px,1.9vw,22px);
  grid-template-columns:repeat(auto-fill,minmax(min(100%,250px),1fr))}
.fest__tile{appearance:none;-webkit-appearance:none;border:0;border-radius:0;
  background:none;padding:0;margin:0;color:var(--paper-45);font:inherit;
  text-align:left;cursor:zoom-in;display:grid;gap:10px;place-items:stretch;
  aspect-ratio:auto}
/* Flex, not grid: as a grid item the image sized its own track, so a portrait
   poster grew its tile and shouldered the rest of the row out of place.
   min-height:0 lets max-height resolve against the 4/3 box instead. */
.fest__shot{display:flex;align-items:center;justify-content:center;
  aspect-ratio:4/3;overflow:hidden;border-radius:3px;
  background:var(--paper);padding:clamp(14px,1.8vw,22px);
  transition:transform .35s var(--ease)}
.fest__shot img{flex:0 1 auto;min-width:0;min-height:0;
  max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain}
.fest__name{font-size:12px;letter-spacing:.04em;line-height:1.35;
  transition:color .3s var(--ease)}
.fest__tile:hover .fest__shot,.fest__tile:focus-visible .fest__shot{transform:translateY(-3px)}
.fest__tile:hover .fest__name,.fest__tile:focus-visible .fest__name{color:var(--paper)}

/* The slideshow is mounted on <body>, not inside .lb, so neither the
   lightbox's own overflow:auto nor any transformed ancestor can clip it.
   .lb sits at z-index 300, so this goes above it. */
.fv{position:fixed;inset:0;z-index:400;display:none;background:rgba(8,8,8,.97);
  grid-template-rows:auto minmax(0,1fr) auto;gap:clamp(10px,2vh,18px);
  padding:clamp(12px,2vw,22px)}
.fv.open{display:grid}
.fv__head{display:flex;align-items:center;justify-content:space-between;gap:16px}
.fv__count{font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  color:var(--paper-45)}
.fv__close{appearance:none;-webkit-appearance:none;background:none;padding:0;
  width:44px;height:44px;display:grid;place-items:center;cursor:pointer;
  border:1px solid var(--line-2);border-radius:999px;color:var(--paper-45);
  transition:color .3s var(--ease),border-color .3s var(--ease)}
.fv__close:hover,.fv__close:focus-visible{color:var(--paper);border-color:var(--paper)}
.fv__close i{position:relative;display:block;width:16px;height:16px}
.fv__close i::before,.fv__close i::after{content:"";position:absolute;top:50%;left:0;
  width:100%;height:1px;background:currentColor}
.fv__close i::before{transform:rotate(45deg)}
.fv__close i::after{transform:rotate(-45deg)}

.fv__stage{position:relative;display:flex;align-items:center;
  justify-content:center;min-height:0;overflow:hidden}
.fv__img{flex:0 1 auto;min-width:0;min-height:0;
  max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;
  background:var(--paper);border-radius:3px;padding:clamp(10px,1.6vw,24px)}
.fv__nav{position:absolute;top:50%;translate:0 -50%;appearance:none;
  -webkit-appearance:none;background:rgba(8,8,8,.6);padding:0;cursor:pointer;
  width:52px;height:52px;display:grid;place-items:center;
  border:1px solid var(--line-2);border-radius:999px;color:var(--paper-45);
  transition:color .3s var(--ease),border-color .3s var(--ease),background .3s var(--ease)}
.fv__nav:hover,.fv__nav:focus-visible{color:var(--paper);border-color:var(--paper);
  background:rgba(8,8,8,.85)}
.fv__nav--prev{left:0}
.fv__nav--next{right:0}
.fv__nav i{display:block;width:12px;height:12px;border-top:1px solid currentColor;
  border-right:1px solid currentColor}
.fv__nav--prev i{rotate:-135deg;margin-left:4px}
.fv__nav--next i{rotate:45deg;margin-right:4px}

.fv__foot{text-align:center;font-size:13px;line-height:1.4;color:var(--paper-45);
  padding:0 clamp(48px,8vw,80px)}

@media (max-width:700px){
  .fest__grid{grid-template-columns:repeat(auto-fill,minmax(min(100%,150px),1fr))}
  .fv__nav{width:44px;height:44px}
  .fv__nav--prev{left:-4px}
  .fv__nav--next{right:-4px}
  .fv__img{padding:10px}
}
@media (prefers-reduced-motion:reduce){
  .fest__shot{transition:none}
  .fest__tile:hover .fest__shot,.fest__tile:focus-visible .fest__shot{transform:none}
}
