/* ==========================================================================
   RNGD Visuals — v2 (dragonfly.xyz-inspired direction)
   ========================================================================== */

@font-face {
  font-family: 'Archivo Var';
  src: local('Archivo');
}

:root{
  --bg:#000000;
  --bg-raised:#0a0a0a;
  --ink:#f4f2ec;
  --muted:#8a8a86;
  --dim:#4d4d4a;
  --line:rgba(244,242,236,.12);
  --line-soft:rgba(244,242,236,.06);
  --accent:#ff4419;
  --accent-dim:rgba(255,68,25,.35);
  --accent-ink:#ff805c;
  --serif: 'Fraunces', Georgia, serif;
  --sans: 'Archivo', 'Arial Narrow', Helvetica, sans-serif;
  --mono: 'IBM Plex Mono', 'Courier New', monospace;
  --wrap: 1400px;
  --pad: clamp(1.25rem, 3vw, 3rem);
}

/* Only widen the shell once there is room for both it and the side rails —
   below this the margins are worth more as rail space than as content width. */
@media (min-width:2000px){
  :root{ --wrap: 1560px; }
}

*{box-sizing:border-box;}
body{
  margin:0;
  background:var(--bg);
  color:var(--ink);
  font-family:var(--sans);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
body.intro-lock{overflow:hidden;height:100vh;}
img{max-width:100%;display:block;}
a{color:inherit;text-decoration:none;}
ul{list-style:none;margin:0;padding:0;}
h1,h2,h3,h4,p{margin:0;}

.wrap{
  max-width:var(--wrap);
  margin:0 auto;
  padding-left:var(--pad);
  padding-right:var(--pad);
  position:relative;
  z-index:2;
}

/* ---------- background texture layer ---------- */
.texture{
  position:fixed;
  inset:0;
  z-index:0;
  pointer-events:none;
  opacity:.55;
}
.texture canvas{width:100%;height:100%;display:block;}
.grain{
  position:fixed;
  inset:0;
  z-index:1;
  pointer-events:none;
  opacity:.04;
  mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---------- intro / paw-print loader ---------- */
#intro-screen{
  position:fixed;
  inset:0;
  z-index:200;
  background:#000;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  gap:2.2rem;
  transition:opacity .9s cubic-bezier(.16,1,.3,1), visibility .9s;
}
#intro-screen.leaving{opacity:0;pointer-events:none;}
#intro-screen.hidden{display:none;}
#paw-canvas{
  width:min(60vw,60vh,480px);
  height:min(60vw,60vh,480px);
  cursor:none;
}
.intro-word{
  font-family:'Clash Display', var(--sans);
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:.01em;
  font-size:clamp(1.3rem,3vw,2rem);
  color:var(--ink);
  opacity:.92;
}
.intro-loadbar{
  width:min(280px,60vw);
  height:1px;
  background:var(--line);
  position:relative;
  overflow:hidden;
}
.intro-loadbar-fill{
  position:absolute;
  inset:0 auto 0 0;
  width:0%;
  background:var(--accent);
  transition:width .1s linear;
}
.intro-pct{
  font-family:var(--mono);
  font-size:.72rem;
  letter-spacing:.1em;
  color:var(--muted);
}

/* ---------- nav fade-in after intro ---------- */
.nav-cap{opacity:1;transition:opacity .8s cubic-bezier(.16,1,.3,1);}
.nav-cap.nav-hidden{opacity:0;pointer-events:none;}

/* ---------- corner marks: studio location / page index / studio hours / scroll position ---------- */
.corner-marks{position:fixed;inset:0;z-index:40;pointer-events:none;}
.corner-mark{
  position:absolute;
  font-family:var(--mono);
  font-size:.68rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--muted);
  opacity:.7;
}
.corner-mark.tl{top:1.5rem;left:1.5rem;}
.corner-mark.tr{top:1.5rem;right:1.5rem;}
.corner-mark.bl{bottom:1.5rem;left:1.5rem;}
.corner-mark.br{bottom:1.5rem;right:1.5rem;color:var(--accent);}
@media (max-width:720px){
  .corner-marks{display:none;}
}

/* ---------- back-to-top ---------- */
.back-to-top{
  position:fixed;
  right:1.5rem;
  bottom:3.6rem;
  z-index:45;
  width:2.8rem;
  height:2.8rem;
  border-radius:50%;
  border:1px solid var(--line);
  background:rgba(10,10,10,.85);
  backdrop-filter:blur(6px);
  color:var(--ink);
  display:flex;
  align-items:center;
  justify-content:center;
  cursor:pointer;
  opacity:0;
  transform:translateY(12px);
  pointer-events:none;
  transition:opacity .4s cubic-bezier(.16,1,.3,1), transform .4s cubic-bezier(.16,1,.3,1), border-color .2s, color .2s;
}
.back-to-top svg{width:16px;height:16px;}
.back-to-top.visible{opacity:1;transform:none;pointer-events:auto;}
.back-to-top:hover{border-color:var(--accent);color:var(--accent);}
@media (max-width:720px){
  .back-to-top{right:1rem;bottom:1rem;}
}

/* ---------- nav ---------- */
.nav-cap{
  position:fixed;
  top:1.4rem;
  left:50%;
  transform:translateX(-50%);
  z-index:50;
  display:flex;
  align-items:center;
  gap:0;
  background:rgba(10,10,10,.9);
  backdrop-filter:blur(10px);
  border:1px solid var(--line);
  border-radius:999px;
  padding:.55rem .5rem .55rem 1.1rem;
  font-family:var(--mono);
  font-size:.72rem;
  letter-spacing:.06em;
}
.nav-cap .nav-mark{
  display:flex;
  align-items:center;
  gap:.5rem;
  /* The wordmark is two words now, so it could break across lines inside the
     narrow capsule; and unlike .nav-links it had no uppercase rule of its own. */
  text-transform:uppercase;
  white-space:nowrap;
  color:var(--accent);
  font-weight:600;
  padding-right:1rem;
  border-right:1px solid var(--line);
  margin-right:1rem;
}
.nav-cap .nav-mark .glyph{font-size:1rem;}
.nav-links{display:flex;align-items:center;gap:1.1rem;}
.nav-links a{color:var(--muted);transition:color .2s;text-transform:uppercase;}
.nav-links a:hover, .nav-links a.active{color:var(--ink);}
.nav-dots{display:flex;gap:.28rem;margin:0 1rem;}
.nav-dots span{width:4px;height:4px;border-radius:50%;background:var(--dim);}
.nav-dots span.on{background:var(--accent);}
.nav-menu-btn{
  color:var(--ink);
  background:var(--bg-raised);
  border:1px solid var(--line);
  border-radius:999px;
  padding:.5rem 1rem;
  cursor:pointer;
  font-family:var(--mono);
  font-size:.72rem;
  letter-spacing:.08em;
  text-transform:uppercase;
}
/* ---------- mobile nav toggle + overlay menu ---------- */
.nav-toggle{
  display:none;
  width:2.1rem;height:2.1rem;
  margin-left:.4rem;
  align-items:center;justify-content:center;
  flex-direction:column;gap:5px;
  background:none;border:none;cursor:pointer;padding:0;
}
.nav-toggle span{
  display:block;width:17px;height:1.5px;background:var(--ink);
  transition:transform .3s cubic-bezier(.16,1,.3,1), opacity .2s;
}
body.menu-open .nav-toggle span:nth-child(1){transform:translateY(3.25px) rotate(45deg);}
body.menu-open .nav-toggle span:nth-child(2){transform:translateY(-3.25px) rotate(-45deg);}

.mobile-menu{
  position:fixed;inset:0;z-index:190;
  background:rgba(10,10,10,.97);
  backdrop-filter:blur(14px);
  display:flex;flex-direction:column;
  justify-content:center;
  padding:6rem 2rem 3rem;
  opacity:0;visibility:hidden;
  transition:opacity .35s ease, visibility .35s;
}
body.menu-open .mobile-menu{opacity:1;visibility:visible;}
/* The overlay (z-index:190) otherwise covers the nav capsule (z-index:50),
   which buries the very button that closes it — the hamburger already
   animates into an X above, but no tap could reach it. On a phone that left
   no way out of the menu except following a link. */
body.menu-open .nav-cap{z-index:200;}
.mobile-menu a{
  font-family:var(--sans);
  font-weight:700;
  text-transform:uppercase;
  font-size:2.1rem;
  letter-spacing:-.02em;
  color:var(--ink);
  padding:.5rem 0;
  border-bottom:1px solid var(--line);
  transform:translateY(12px);opacity:0;
  transition:transform .5s cubic-bezier(.16,1,.3,1), opacity .5s, color .2s;
}
body.menu-open .mobile-menu a{transform:none;opacity:1;}
.mobile-menu a:nth-child(1){transition-delay:.06s;}
.mobile-menu a:nth-child(2){transition-delay:.12s;}
.mobile-menu a:nth-child(3){transition-delay:.18s;}
.mobile-menu a:nth-child(4){transition-delay:.24s;}
.mobile-menu a:nth-child(5){transition-delay:.30s;}
.mobile-menu a.active{color:var(--accent);}
.mobile-menu .mm-foot{
  margin-top:2.5rem;
  font-family:var(--mono);font-size:.75rem;
  color:var(--muted);letter-spacing:.06em;
  border:none;padding:0;
  transform:none;opacity:1;
}
.mobile-menu .mm-foot a{
  font-family:var(--mono);font-size:.75rem;font-weight:400;
  text-transform:none;letter-spacing:.04em;
  border:none;padding:0;color:var(--accent);
  transform:none;opacity:1;
}
@media (max-width:640px){
  .nav-links{display:none;}
  .nav-toggle{display:flex;}
  .nav-dots{display:none;}
}

/* ---------- persistent WhatsApp CTA ---------- */
.wa-fab{
  position:fixed;left:1.4rem;bottom:1.4rem;z-index:180;
  display:flex;align-items:center;gap:.6rem;
  padding:.7rem 1.1rem .7rem .85rem;
  border-radius:999px;
  background:rgba(10,10,10,.85);
  backdrop-filter:blur(10px);
  color:var(--ink);
  border:1px solid var(--line);
  font-family:var(--mono);font-size:.72rem;
  letter-spacing:.08em;text-transform:uppercase;
  transition:transform .25s cubic-bezier(.16,1,.3,1),
             border-color .25s, color .25s, background .25s, opacity .35s;
}
.wa-fab:hover{
  transform:translateY(-2px);
  border-color:var(--accent);
  color:var(--accent);
  background:var(--bg-raised);
}
.wa-fab svg{
  width:1.15rem;height:1.15rem;flex:none;
  fill:var(--accent);transition:fill .25s;
}
.wa-fab:hover svg{fill:var(--accent);}
body.menu-open .wa-fab, body.modal-lock .wa-fab{opacity:0;pointer-events:none;}
@media (max-width:640px){
  /* on mobile the hero CTA buttons are left-aligned, so the FAB moves right
     and the back-to-top stacks above it instead of colliding with either */
  .wa-fab{left:auto;right:1rem;bottom:1rem;padding:.75rem;}
  .wa-fab .wa-label{display:none;}
}
@media (max-width:720px){
  .back-to-top{right:1rem;bottom:5.2rem;}
}

/* ---------- section chrome ---------- */
.section{position:relative;padding:9rem 0;border-top:1px solid var(--line-soft);}
.section:first-of-type{border-top:none;}
.section-tag{
  display:flex;
  align-items:center;
  gap:.8rem;
  font-family:var(--mono);
  font-size:.75rem;
  letter-spacing:.12em;
  text-transform:uppercase;
  color:var(--accent);
  margin-bottom:1.6rem;
}
.section-tag .num{
  color:var(--muted);
  border:1px solid var(--line);
  border-radius:999px;
  padding:.15rem .6rem;
}
.section-tag::after{
  content:'';
  flex:1;
  height:1px;
  background:var(--line);
}

.display{
  font-family:var(--sans);
  font-stretch:condensed;
  font-weight:700;
  letter-spacing:-.01em;
  line-height:.94;
  text-transform:uppercase;
  color:var(--ink);
}
.display em{
  font-style:normal;
  color:var(--accent);
}

h2.section-title{
  font-size:clamp(2.1rem,4.6vw,4rem);
  font-family:var(--sans);
  font-weight:700;
  text-transform:uppercase;
  letter-spacing:-.01em;
  line-height:1.02;
  max-width:20ch;
}

/* ---------- section head: title left, supporting copy right ----------
   Keeps big headlines from stranding half the row empty on wide screens. */
.section-head{
  display:grid;
  grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);
  gap:clamp(2rem,5vw,5rem);
  align-items:end;
}
.section-head .head-aside{
  padding-bottom:.4rem;
  border-left:1px solid var(--line);
  padding-left:clamp(1.2rem,2vw,2rem);
}
.section-head .head-aside p{
  color:var(--muted);
  font-size:.95rem;
  line-height:1.7;
  max-width:46ch;
}
.section-head .head-aside p + p{margin-top:.9rem;}
.section-head .head-aside .aside-kicker{
  display:block;
  font-family:var(--mono);
  font-size:.68rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--accent);
  margin-bottom:.8rem;
}
@media (max-width:940px){
  .section-head{grid-template-columns:1fr;gap:1.8rem;}
  .section-head .head-aside{border-left:none;padding-left:0;border-top:1px solid var(--line);padding-top:1.2rem;}
}

/* ---------- side rails: faded frames living in the outer margins ----------
   Only rendered once the viewport is actually wider than the content shell,
   so they fill dead space instead of competing with it. */
.rail{
  position:absolute;
  top:0;
  bottom:0;
  width:calc((100% - var(--wrap)) / 2);
  display:none;
  z-index:2;
  pointer-events:none;
  /* Hard guarantee that frames can never bleed out of their own section and
     over the neighbouring one, whatever the section height works out to. */
  overflow:hidden;
}
.rail.left{left:0;}
.rail.right{right:0;}
.rail-inner{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:.9rem;
  /* Fixed rather than vh: a viewport-relative offset changes the stack height
     with window height, which on short-but-wide screens pushed the last frame
     past the section and got it clipped mid-photo. */
  padding:8rem 1.1rem 0;
}
.rail-shot{
  display:block;
  width:100%;
  /* Frames are sized by the rail, and the rail grows with the margin. Without
     a cap they balloon on ultra-wide screens until the stack is taller than
     its own section and spills over the next one. */
  max-width:230px;
  border:1px solid var(--line-soft);
  overflow:hidden;
  aspect-ratio:3/4;
  pointer-events:auto;
  opacity:.2;
  filter:grayscale(.8) saturate(.4) contrast(1.05);
  transition:opacity .55s cubic-bezier(.16,1,.3,1), filter .55s cubic-bezier(.16,1,.3,1), border-color .4s;
}
.rail-shot img{width:100%;height:100%;object-fit:cover;display:block;}
.rail.left .rail-inner{-webkit-mask-image:linear-gradient(to right,transparent,#000 72%);mask-image:linear-gradient(to right,transparent,#000 72%);}
.rail.right .rail-inner{-webkit-mask-image:linear-gradient(to left,transparent,#000 72%);mask-image:linear-gradient(to left,transparent,#000 72%);}
.rail-shot:hover{opacity:1;filter:none;border-color:var(--accent-dim);}
.rail-label{
  font-family:var(--mono);
  font-size:.62rem;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--dim);
  writing-mode:vertical-rl;
  margin:.4rem auto;
}
.rail.right .rail-label{transform:rotate(180deg);}
/* Short sections (e.g. one with padding-top:0) cannot fit the standard
   8rem offset + label + two frames; the second frame got clipped in half by
   the rail's own overflow:hidden. `.rail.compact` pulls the stack up and is
   paired with a single frame in the markup. */
.rail.compact .rail-inner{padding-top:5rem;}
/* Rails only once the outer margin is actually wide enough to hold a legible
   frame. The rail is (100vw - var(--wrap)) / 2 minus its own padding, so at the
   old 1460px trigger each frame computed to ~2x3px — visible specks with a 1px
   border, which read as broken rather than decorative. 1680px is the first
   width where a frame is ~105px wide. */
@media (min-width:1680px){
  .rail{display:block;}
}
.lede{
  font-family:var(--serif);
  font-style:italic;
  font-weight:400;
  color:var(--muted);
  font-size:1.15rem;
  line-height:1.5;
  max-width:48ch;
}

/* ---------- hero ---------- */
.hero{
  min-height:100vh;
  display:flex;
  flex-direction:column;
  justify-content:center;
  padding-top:8rem;
  padding-bottom:4rem;
  position:relative;
}
.hero-eyebrow{
  font-family:var(--mono);
  font-size:.78rem;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--muted);
  display:flex;
  align-items:center;
  gap:.6rem;
  margin-bottom:1.4rem;
}
.hero-eyebrow .dot{width:6px;height:6px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px var(--accent);}
.hero h1{
  font-family:var(--sans);
  font-weight:800;
  text-transform:uppercase;
  letter-spacing:-.015em;
  line-height:.9;
  font-size:clamp(3.4rem,9.5vw,8.5rem);
  color:var(--ink);
}
.hero h1 em{
  font-style:normal;
  -webkit-text-stroke:1.5px var(--accent);
  color:transparent;
}
.hero-sub{
  margin-top:2rem;
  display:flex;
  justify-content:space-between;
  align-items:flex-end;
  gap:2rem;
  flex-wrap:wrap;
  border-top:1px solid var(--line);
  padding-top:1.6rem;
}
.hero-sub .lede{margin:0;}
.hero-stats{
  display:flex;
  gap:2.4rem;
  font-family:var(--mono);
  font-size:.72rem;
  letter-spacing:.08em;
  text-transform:uppercase;
  color:var(--muted);
}
.hero-stats strong{display:block;color:var(--ink);font-size:1rem;font-family:var(--sans);font-weight:700;}

.hero-cta{display:flex;gap:1rem;flex-wrap:wrap;margin-top:2rem;}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;
  align-items:center;
  gap:.6rem;
  font-family:var(--mono);
  font-size:.78rem;
  letter-spacing:.08em;
  text-transform:uppercase;
  padding:.9rem 1.6rem;
  border-radius:999px;
  border:1px solid var(--line);
  transition:all .25s ease;
}
.btn-solid{background:var(--accent);border-color:var(--accent);color:#0a0a0a;font-weight:600;}
.btn-solid:hover{background:#ff5c33;}
.btn-ghost{color:var(--ink);}
.btn-ghost:hover{border-color:var(--accent);color:var(--accent);}
.btn-arrow{transition:transform .25s;}
.btn:hover .btn-arrow{transform:translateX(3px);}

/* ---------- marquee ---------- */
.marquee{
  border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);
  overflow:hidden;
  padding:1.1rem 0;
}
.marquee-track{
  display:flex;
  gap:3rem;
  white-space:nowrap;
  animation:scroll-x 32s linear infinite;
  font-family:var(--mono);
  font-size:.85rem;
  letter-spacing:.1em;
  text-transform:uppercase;
  color:var(--muted);
}
.marquee-track span{display:flex;align-items:center;gap:3rem;}
.marquee-track span::after{content:'◆';color:var(--accent);font-size:.5rem;}
@keyframes scroll-x{from{transform:translateX(0);}to{transform:translateX(-50%);}}

/* ---------- grid of verticals ---------- */
.grid-4{
  display:grid;
  grid-template-columns:repeat(4,1fr);
  border-top:1px solid var(--line);
  border-left:1px solid var(--line);
}
.grid-4 .cell{
  border-right:1px solid var(--line);
  border-bottom:1px solid var(--line);
  padding:2.2rem 1.8rem;
  position:relative;
  transition:background .25s;
}
.grid-4 .cell:hover{background:var(--bg-raised);}
.grid-4 .cell .cell-num{
  font-family:var(--mono);
  font-size:.75rem;
  color:var(--accent);
  display:block;
  margin-bottom:1.6rem;
}
.grid-4 .cell h3{
  font-family:var(--sans);
  font-weight:700;
  text-transform:uppercase;
  font-size:1.15rem;
  letter-spacing:-.01em;
  margin-bottom:.7rem;
}
.grid-4 .cell p{color:var(--muted);font-size:.9rem;line-height:1.5;}
.grid-4.cols-3{grid-template-columns:repeat(3,1fr);}
@media (max-width:900px){
  .grid-4,
  .grid-4.cols-3{grid-template-columns:repeat(2,1fr);}
}
@media (max-width:560px){
  .grid-4,
  .grid-4.cols-3{grid-template-columns:1fr!important;}
}

/* ---------- statement ---------- */
.statement{text-align:left;}
.statement h2{
  font-family:var(--sans);
  font-weight:700;
  text-transform:uppercase;
  font-size:clamp(2.2rem,6vw,5rem);
  line-height:1.02;
  letter-spacing:-.015em;
  max-width:18ch;
}
.statement h2 em{font-style:normal;color:var(--accent);}

/* ---------- case list (portfolio) ---------- */
.case-row{
  display:grid;
  grid-template-columns:80px 1.4fr 1fr auto;
  align-items:center;
  gap:2rem;
  padding:1.7rem 0;
  border-bottom:1px solid var(--line);
  transition:background .2s;
}
.case-row:hover{background:var(--bg-raised);}
.case-row .idx{font-family:var(--mono);color:var(--muted);font-size:.85rem;}
.case-row .title{font-family:var(--sans);font-weight:700;text-transform:uppercase;font-size:1.3rem;letter-spacing:-.01em;}
.case-row .tags{display:flex;gap:.5rem;flex-wrap:wrap;}
.case-row .tag{
  font-family:var(--mono);
  font-size:.68rem;
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--muted);
  border:1px solid var(--line);
  border-radius:999px;
  padding:.25rem .7rem;
}
.case-row .go{font-family:var(--mono);font-size:1.2rem;color:var(--accent);}
@media (max-width:760px){
  .case-row{grid-template-columns:40px 1fr;grid-template-areas:"idx title" ". tags" ". go";row-gap:.6rem;}
  .case-row .idx{grid-area:idx;}
  .case-row .title{grid-area:title;font-size:1.05rem;}
  .case-row .tags{grid-area:tags;}
  .case-row .go{grid-area:go;justify-self:start;}
}

/* ---------- media placeholder ---------- */
.media-ph{
  background:
    linear-gradient(135deg, rgba(255,68,25,.08), rgba(255,255,255,.02)),
    repeating-linear-gradient(45deg, rgba(244,242,236,.04) 0 1px, transparent 1px 14px);
  border:1px solid var(--line);
  aspect-ratio:4/3;
  display:flex;
  align-items:center;
  justify-content:center;
  position:relative;
  color:var(--dim);
  font-family:var(--mono);
  font-size:.7rem;
  letter-spacing:.08em;
  text-transform:uppercase;
}
.media-ph::before{content:attr(data-label);}
.media-ph.wide{aspect-ratio:16/9;}
.media-ph.has-img{padding:0;color:transparent;background:none;overflow:hidden;cursor:pointer;}
.media-ph.has-img::before{content:none;}
.media-ph.has-img img{
  width:100%;height:100%;object-fit:cover;display:block;
  filter:saturate(.94) contrast(1.03);
  transition:transform .8s cubic-bezier(.16,1,.3,1);
}
.media-ph.has-img:hover img{transform:scale(1.05);}

/* ---------- freestanding photo (outside the case-list grid) ---------- */
.shot{border:1px solid var(--line);overflow:hidden;background:var(--bg-raised);}
.shot img{
  width:100%;height:100%;object-fit:cover;display:block;
  filter:saturate(.94) contrast(1.03);
  transition:transform .8s cubic-bezier(.16,1,.3,1);
}
.shot:hover img{transform:scale(1.05);}

/* ---------- video tile: poster by default, hover to preview-play, click to open lightbox ---------- */
.media-ph.has-vid{padding:0;color:transparent;background:#000;overflow:hidden;cursor:pointer;}
.media-ph.has-vid::before{content:none;}
.media-ph.has-vid video{
  width:100%;height:100%;object-fit:cover;display:block;
  filter:saturate(.94) contrast(1.03);
}
.media-ph.has-vid .play-badge{
  position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  pointer-events:none;transition:opacity .3s;
}
.media-ph.has-vid .play-badge span{
  width:3.2rem;height:3.2rem;border-radius:50%;
  background:rgba(10,10,10,.55);backdrop-filter:blur(2px);
  border:1px solid rgba(244,242,236,.35);
  display:flex;align-items:center;justify-content:center;
  color:var(--ink);font-size:1.1rem;padding-left:.15rem;
}
.media-ph.has-vid.playing .play-badge{opacity:0;}

/* ---------- lightbox: click-to-play video with audio ---------- */
/* The lightbox is a material arriving, not a panel being switched on: the
   scrim blurs in while the media scales up, both on the same curve, so it
   reads as depth rather than a hard cut. display:none can't transition, so
   visibility carries the "not there" state instead. */
#lightbox{
  position:fixed;inset:0;z-index:300;
  background:rgba(0,0,0,.92);
  display:flex;align-items:center;justify-content:center;
  padding:3rem 1.5rem;
  opacity:0;
  visibility:hidden;
  pointer-events:none;
  backdrop-filter:blur(0px);
  transition:opacity .32s cubic-bezier(.16,1,.3,1),
             backdrop-filter .32s cubic-bezier(.16,1,.3,1),
             visibility .32s;
}
#lightbox.open{
  opacity:1;
  visibility:visible;
  pointer-events:auto;
  backdrop-filter:blur(14px);
}
#lightbox video,
#lightbox img{
  max-width:min(92vw,1280px);max-height:86vh;
  width:auto;height:auto;
  border:1px solid var(--line);
  background:#000;
  transform:scale(.965);
  transition:transform .32s cubic-bezier(.16,1,.3,1);
}
#lightbox.open video,
#lightbox.open img{transform:scale(1);}
/* YouTube player for the long-form films: sized as a 16:9 box that fits the
   same limits as the native video above. */
#lightbox-frame{
  width:min(92vw,1280px,calc(86vh * 16 / 9));
  aspect-ratio:16/9;height:auto;
  border:1px solid var(--line);
  background:#000;
}
#lightbox-close{
  position:fixed;top:1.5rem;right:1.5rem;z-index:301;
  width:2.8rem;height:2.8rem;border-radius:50%;
  border:1px solid var(--line);background:rgba(10,10,10,.85);
  color:var(--ink);display:none;align-items:center;justify-content:center;
  cursor:pointer;font-size:1.3rem;
}
#lightbox.open ~ #lightbox-close{display:flex;}
#lightbox-close:hover{border-color:var(--accent);color:var(--accent);}
body.modal-lock{overflow:hidden;height:100vh;}

/* ---------- client project media grid ---------- */
.media-grid{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  gap:1rem;
  align-items:stretch;
}
.media-grid .media-ph.has-img{aspect-ratio:4/3;}
.media-grid .media-ph.has-vid{aspect-ratio:9/16;}
.media-grid .stacked-images{aspect-ratio:9/16;height:auto;}
.media-grid .stacked-images .media-ph.has-img{aspect-ratio:auto;}
/* Grid items default to min-width:auto, which lets an item's intrinsic size
   push its column past the viewport. Nothing in this grid needs that. */
.media-grid > *{min-width:0;}
@media (max-width:900px){
  .media-grid{grid-template-columns:repeat(2,1fr);}
}
@media (max-width:560px){
  .media-grid{grid-template-columns:1fr;}
}

/* ---------- films & documentaries: landscape, long-form ---------- */
.film-grid{
  display:grid;
  grid-template-columns:repeat(2,1fr);
  gap:2.2rem 1.6rem;
}
.film-item{display:flex;flex-direction:column;gap:.9rem;}
.film-tile{
  position:relative;
  aspect-ratio:16/9;
  overflow:hidden;
  background:#000;
  border:1px solid var(--line);
  cursor:pointer;
  display:block;
  width:100%;
  padding:0;
}
.film-tile img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .7s cubic-bezier(.16,1,.3,1), opacity .4s;
  opacity:.82;
}
.film-tile:hover img, .film-tile:focus-visible img{transform:scale(1.04);opacity:1;}
/* Hover preview: a short silent excerpt laid over the poster. It stays
   invisible until it is actually playing, so a slow load shows the poster
   rather than a black box. */
.film-tile .film-preview{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .35s;pointer-events:none;
}
.film-tile.previewing .film-preview{opacity:1;}
.film-tile.previewing .film-play span{opacity:0;}
.film-play{
  position:absolute;inset:0;
  display:flex;align-items:center;justify-content:center;
  pointer-events:none;
}
.film-play span{
  width:4.2rem;height:4.2rem;border-radius:50%;
  border:1px solid rgba(255,255,255,.55);
  background:rgba(10,10,10,.42);
  backdrop-filter:blur(6px);
  display:flex;align-items:center;justify-content:center;
  color:#fff;font-size:1rem;padding-left:.2rem;
  transition:background .35s, border-color .35s, transform .35s cubic-bezier(.16,1,.3,1);
}
.film-tile:hover .film-play span,
.film-tile:focus-visible .film-play span{
  background:var(--accent);border-color:var(--accent);transform:scale(1.08);
}
.film-runtime{
  position:absolute;right:.7rem;bottom:.7rem;
  font-family:var(--mono);font-size:.66rem;letter-spacing:.08em;
  color:#fff;background:rgba(10,10,10,.72);
  padding:.28rem .5rem;border-radius:2px;
  pointer-events:none;
}
.film-head{display:flex;align-items:baseline;gap:.8rem;flex-wrap:wrap;}
.film-head h3{
  font-family:var(--sans);font-weight:700;text-transform:uppercase;
  font-size:1.15rem;letter-spacing:-.01em;line-height:1.1;
}
.film-kind{
  font-family:var(--mono);font-size:.64rem;letter-spacing:.14em;
  text-transform:uppercase;color:var(--accent);
}
.film-item p{color:var(--muted);font-size:.92rem;line-height:1.6;max-width:46ch;}
@media (max-width:820px){
  .film-grid{grid-template-columns:1fr;gap:2.6rem;}
}

/* ---------- case row now links out to a project page ---------- */
.case-link{display:block;text-decoration:none;color:inherit;}
.case-link:hover .case-row{background:var(--bg-raised);}
.case-teaser-cta{
  display:inline-flex;align-items:center;gap:.5rem;
  font-family:var(--mono);font-size:.72rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--accent);margin-top:1rem;
}

/* ---------- full-bleed image band with dark overlay (statement sections) ---------- */
/* z-index:0 lifts the band just above the drifting particle canvas (.texture,
   z-index 0, earlier in the DOM) so nothing speckles across the photograph.
   It stays below .grain (z-index 1), so the site-wide film grain still runs
   over it and the band doesn't read as a detached, different-textured slab. */
.img-band{position:relative;isolation:isolate;z-index:0;}
.img-band img{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2;
  filter:saturate(.85) contrast(1.05) brightness(.75);
}
.img-band::before{
  content:'';position:absolute;inset:0;z-index:-1;
  background:linear-gradient(180deg, rgba(0,0,0,.55), rgba(0,0,0,.8) 60%, var(--bg) 100%);
}

/* ---------- footer ---------- */
footer{border-top:1px solid var(--line);padding:5rem 0 2.5rem;}
.footer-grid{
  display:grid;
  grid-template-columns:1.6fr 1fr 1fr 1fr;
  gap:2rem;
  padding-bottom:3rem;
}
.footer-brand{
  font-family:var(--sans);
  font-weight:800;
  text-transform:uppercase;
  font-size:1.4rem;
  letter-spacing:-.01em;
}
.footer-brand span{color:var(--accent);}
.footer-grid p{color:var(--muted);font-size:.88rem;line-height:1.6;margin-top:1rem;max-width:32ch;}
.footer-col h4{
  font-family:var(--mono);
  font-size:.72rem;
  letter-spacing:.1em;
  text-transform:uppercase;
  color:var(--muted);
  margin-bottom:1.1rem;
}
.footer-col a, .footer-col p{
  display:block;
  font-size:.9rem;
  color:var(--ink);
  margin-bottom:.6rem;
  transition:color .2s;
}
.footer-col a:hover{color:var(--accent);}
.footer-bottom{
  display:flex;
  justify-content:space-between;
  gap:1rem;
  flex-wrap:wrap;
  border-top:1px solid var(--line);
  padding-top:1.6rem;
  font-family:var(--mono);
  font-size:.72rem;
  letter-spacing:.06em;
  text-transform:uppercase;
  color:var(--dim);
}
@media (max-width:900px){
  .footer-grid{grid-template-columns:1fr 1fr;}
}
@media (max-width:420px){
  /* Two columns cannot hold the contact block on a small phone: the email is a
     single unbreakable ~165px token, so the grid overflowed the viewport at
     320px and sat at exactly zero slack at 375px. */
  .footer-grid{grid-template-columns:1fr;gap:2.2rem;}
}
/* Belt and braces: a long address can wrap rather than widen the page. */
.footer-grid > *{min-width:0;}
.footer-col a, .footer-col p, .footer-grid p{overflow-wrap:anywhere;}

/* ---------- reveal on scroll ---------- */
.reveal{
  opacity:0;
  transform:translateY(36px);
  transition:opacity 1.1s cubic-bezier(.16,1,.3,1), transform 1.1s cubic-bezier(.16,1,.3,1);
  transition-delay:var(--d,0s);
  will-change:opacity,transform;
}
.reveal.in{opacity:1;transform:none;}

/* ---------- parallax-ready media ---------- */
[data-parallax]{will-change:transform;}

/* ---------- misc ---------- */
.two-col{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:4rem;
  align-items:start;
}
.two-col .media-ph.has-vid{aspect-ratio:9/16;}
.stacked-images{display:flex;flex-direction:column;gap:.8rem;height:100%;}
.stacked-images .media-ph{flex:1;min-height:0;}
@media (max-width:820px){
  .two-col{grid-template-columns:1fr!important;gap:2.5rem;}
  /* Scoped to .two-col on purpose. Unscoped, these also hit the stacks inside
     .media-grid, where `flex:none` lets each photo fall back to its own
     intrinsic height; the stack's `aspect-ratio:9/16` then turns that tall
     content height back into a huge WIDTH, blowing the grid column (and the
     whole page) sideways by up to ~950px on phones. */
  .two-col .stacked-images{height:auto;}
  .two-col .stacked-images .media-ph{flex:none;aspect-ratio:3/2;}
}

.rule{height:1px;background:var(--line);width:100%;}

.center{text-align:center;}
.center .section-tag{justify-content:center;}
.center .section-tag::after{display:none;}
.mx-auto{margin-left:auto;margin-right:auto;}

.subhero{
  padding:11rem 0 4rem;
  border-bottom:1px solid var(--line-soft);
}
.subhero h1{
  font-family:var(--sans);
  font-weight:800;
  text-transform:uppercase;
  letter-spacing:-.015em;
  line-height:.96;
  font-size:clamp(2.6rem,6.5vw,5.2rem);
}
.subhero h1 em{font-style:normal;color:var(--accent);}
.subhero .lede{margin-top:1.4rem;}

.accordion-item{border-bottom:1px solid var(--line);}
.accordion-head{
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:1.5rem;
  padding:1.8rem 0;
  cursor:pointer;
  font-family:var(--sans);
  font-weight:700;
  text-transform:uppercase;
  font-size:1.2rem;
  letter-spacing:-.01em;
}
.accordion-head .n{color:var(--accent);font-family:var(--mono);font-size:.85rem;margin-right:1.2rem;font-weight:400;}
.accordion-plus{font-family:var(--mono);color:var(--muted);font-size:1.3rem;transition:transform .25s;}
.accordion-item.open .accordion-plus{transform:rotate(45deg);color:var(--accent);}
.accordion-body{
  max-height:0;
  overflow:hidden;
  transition:max-height .35s ease;
}
.accordion-item.open .accordion-body{max-height:340px;}
.accordion-body-inner{padding:0 0 2rem;color:var(--muted);font-size:.95rem;line-height:1.7;}
.accordion-body-inner ul{margin-top:.8rem;}
.accordion-body-inner li{padding-left:1.2rem;position:relative;margin-bottom:.4rem;}
.accordion-body-inner li::before{content:'—';position:absolute;left:0;color:var(--accent);}

.pricing-card{
  border:1px solid var(--line);
  padding:2.4rem;
}
.pricing-card.featured{border-color:var(--accent-dim);background:var(--bg-raised);}
.pricing-card .tag{font-family:var(--mono);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase;color:var(--accent);}
.pricing-card h3{font-family:var(--sans);font-weight:700;text-transform:uppercase;font-size:1.5rem;margin:.8rem 0 1rem;}
.pricing-card p{color:var(--muted);font-size:.92rem;line-height:1.6;}
.pricing-card ul{margin-top:1.4rem;}
.pricing-card li{font-size:.88rem;color:var(--muted);padding-left:1.2rem;position:relative;margin-bottom:.6rem;}
.pricing-card li::before{content:'—';position:absolute;left:0;color:var(--accent);}

.form-grid{display:grid;grid-template-columns:1fr 1fr;gap:1.2rem;}
.field{display:flex;flex-direction:column;gap:.5rem;margin-bottom:1.2rem;}
.field.full{grid-column:1/-1;}
.field label{font-family:var(--mono);font-size:.7rem;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);}
.field input, .field select, .field textarea{
  background:var(--bg-raised);
  border:1px solid var(--line);
  color:var(--ink);
  padding:.85rem 1rem;
  font-family:var(--sans);
  font-size:.95rem;
  border-radius:2px;
}
.field input:focus, .field select:focus, .field textarea:focus{
  outline:none;border-color:var(--accent);
}
.field textarea{resize:vertical;min-height:120px;}
@media (max-width:640px){.form-grid{grid-template-columns:1fr;}}

/* ---------- enquiry form actions + status ---------- */
.form-actions{display:flex;gap:1rem;flex-wrap:wrap;align-items:center;margin-top:.4rem;}
.form-status{
  margin-top:1rem;font-family:var(--mono);font-size:.78rem;
  line-height:1.5;letter-spacing:.02em;min-height:1.2em;
}
.form-status.ok{color:#5dcaa5;}
.form-status.error{color:var(--accent);}

/* ---------- proof strip (retainer facts) ---------- */
.proof-strip{
  display:grid;grid-template-columns:repeat(3,1fr);
  border-top:1px solid var(--line);border-left:1px solid var(--line);
}
.proof-strip .proof{
  border-right:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:1.9rem 1.6rem;
}
.proof-strip .proof strong{
  display:block;font-family:var(--sans);font-weight:800;
  font-size:2.4rem;line-height:1;letter-spacing:-.02em;
  color:var(--ink);margin-bottom:.5rem;
}
.proof-strip .proof > span{
  font-family:var(--mono);font-size:.74rem;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);line-height:1.5;display:block;
}
.proof-strip .proof strong span{
  display:inline;font-family:inherit;color:inherit;
  letter-spacing:-.01em;text-transform:lowercase;margin-left:.1em;
}
@media (max-width:760px){
  .proof-strip{grid-template-columns:1fr;}
}

/* ---------- case study narrative block ---------- */
.case-brief{
  display:grid;grid-template-columns:repeat(3,1fr);gap:0;
  border-top:1px solid var(--line);border-left:1px solid var(--line);
  margin-bottom:2.5rem;
}
.case-brief .cb{
  border-right:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:1.7rem 1.5rem;
}
.case-brief .cb h4{
  font-family:var(--mono);font-size:.7rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--accent);margin-bottom:.7rem;
}
.case-brief .cb p{color:var(--muted);font-size:.92rem;line-height:1.6;}
@media (max-width:760px){
  .case-brief{grid-template-columns:1fr;}
}

/* ---------- about page ---------- */
.about-lead{display:grid;grid-template-columns:1fr 1.15fr;gap:3.5rem;align-items:start;}
.about-lead .about-copy p{margin-bottom:1.1rem;}
@media (max-width:820px){
  .about-lead{grid-template-columns:1fr;gap:2.5rem;}
}
.kit-list{
  display:grid;grid-template-columns:repeat(2,1fr);
  border-top:1px solid var(--line);border-left:1px solid var(--line);
}
.kit-list div{
  border-right:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:1.4rem 1.5rem;
}
.kit-list h4{
  font-family:var(--mono);font-size:.7rem;letter-spacing:.1em;
  text-transform:uppercase;color:var(--accent);margin-bottom:.5rem;
}
.kit-list p{color:var(--muted);font-size:.92rem;line-height:1.6;}
@media (max-width:560px){
  .kit-list{grid-template-columns:1fr;}
}

/* ==========================================================================
   Accessibility & motion preferences
   ========================================================================== */

/* ---------- skip link ---------- */
.skip-link{
  position:absolute;
  left:.75rem;
  top:-4rem;
  z-index:400;
  background:var(--accent);
  color:#0a0a0a;
  font-family:var(--mono);
  font-size:.75rem;
  letter-spacing:.08em;
  text-transform:uppercase;
  font-weight:600;
  padding:.7rem 1.1rem;
  border-radius:999px;
  transition:top .2s ease;
}
.skip-link:focus{top:.75rem;}

/* ---------- visible keyboard focus ----------
   The custom chrome removes default outlines, which left keyboard users with
   no indication of position. Scoped to :focus-visible so mouse clicks stay clean. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
.media-ph:focus-visible,
.rail-shot:focus-visible,
[tabindex]:focus-visible{
  outline:2px solid var(--accent);
  outline-offset:3px;
  border-radius:2px;
}
.field input:focus-visible,
.field select:focus-visible,
.field textarea:focus-visible{
  outline-offset:0;
  border-color:var(--accent);
}
/* the nav capsule is already pill-shaped — match it so the ring doesn't box a pill */
.nav-cap a:focus-visible,
.btn:focus-visible,
.nav-menu-btn:focus-visible{border-radius:999px;}

/* ---------- reduced motion ----------
   Honour the OS setting: stop the looping marquee outright, and collapse
   transitions/animations rather than removing the end state, so reveal-on-scroll
   content still ends up visible instead of stuck at opacity:0. */
/* ---------- press feedback ----------
   Feedback belongs on pointer-down, not on release: an element that only
   reacts to hover feels dead the moment you actually commit to pressing it,
   and on touch there is no hover at all, so this is the only feedback there
   is. Short and compositor-only so it can't lag the press. */
.btn:active,
.nav-menu-btn:active,
.nav-links a:active,
.mobile-menu a:active,
.case-teaser-cta:active,
.accordion-head:active,
#lightbox-close:active,
.back-to-top:active,
.media-ph.has-vid:active,
.media-ph.has-img:active,
.rail-shot:active{
  transform:scale(.975);
  transition:transform 90ms ease-out;
}
/* The magnetic-pull script writes an inline transform on .btn-solid, which
   would win over the rule above — dim it instead so the press still lands. */
.btn-solid:active{filter:brightness(.92);}

/* ---------- reduced transparency ----------
   Five surfaces on this site are translucent. When the OS asks for less of
   it, make them solid rather than merely less blurred. */
@media (prefers-reduced-transparency: reduce){
  .nav-cap,
  .mobile-menu,
  .back-to-top,
  #lightbox-close{
    background:#0a0a0a;
    backdrop-filter:none;
  }
  #lightbox{background:#000;backdrop-filter:none;}
  .grain{display:none;}
}

/* ---------- increased contrast ----------
   Near-solid surfaces with a defined border, and muted copy pulled up to
   full ink so nothing important sits at low contrast. */
@media (prefers-contrast: more){
  :root{
    --muted:#cfcdc7;
    --dim:#9a9a95;
    --line:rgba(244,242,236,.4);
  }
  .nav-cap,
  .mobile-menu,
  .back-to-top{background:#000;border-color:var(--line);}
  .rail-shot{opacity:.75;filter:none;}
  .texture{display:none;}
}

@media (prefers-reduced-motion: reduce){
  /* Deliberately not a blanket transition kill: opacity and colour changes
     aid comprehension and aren't vestibular triggers, so they stay. What goes
     is movement — transforms, parallax, looping animation. */
  *,
  *::before,
  *::after{
    animation-duration:.001ms !important;
    animation-iteration-count:1 !important;
    scroll-behavior:auto !important;
    transition-property:opacity, color, background-color, border-color, filter !important;
    transition-duration:.2s !important;
  }
  .marquee-track{animation:none !important;transform:none !important;}
  .reveal{opacity:1 !important;transform:none !important;}
  .media-ph.has-img:hover img,
  .shot:hover img{transform:none !important;}
  .rail-shot{opacity:.5;filter:none;}
  #lightbox video,
  #lightbox img{transform:none !important;}
  #intro-screen{display:none !important;}
  body.intro-lock{overflow:auto;height:auto;}
}

/* ---------- touch: no hover to reveal with ----------
   The rails and media tiles hide their payoff behind :hover. On a touch
   device that event never comes, so the frames would sit dimmed at 20%
   permanently. Lift them to a legible resting state instead. */
@media (hover:none){
  .rail-shot{opacity:.55;filter:grayscale(.35) saturate(.7);}
  .media-ph.has-vid .play-badge{opacity:1;}
}

/* ---------- portfolio collage: full-screen opener that fades into the page ----------
   A fixed layer of brand tiles that fills the viewport edge to edge — the grid
   template below is a complete tiling, so there is no empty space at any size.
   collage.js fades it out (tiles staggered) over the first screen of scroll;
   .collage-spacer holds that screen so the regular portfolio rises into view
   exactly as the collage finishes fading. */
.collage{
  /* starts below the nav capsule (which sits ~22px from the top and ends at
     ~75px) with a matching ~22px gap, so no tile ever sits behind the menu;
     overflow clips the grid as it slides up past that edge */
  --collage-top:6rem;
  position:fixed;left:0;right:0;bottom:0;top:var(--collage-top);z-index:30;
  background:var(--bg);
  overflow:hidden;
}
.collage.gone{visibility:hidden;}
/* tiles start hidden; collage.js fades them in one after another */
.collage .ct{opacity:0;}
body.collage-on .wa-fab,
body.collage-on .back-to-top,
body.collage-on .corner-marks{opacity:0;pointer-events:none;}
.corner-marks{transition:opacity .35s;}
.collage-spacer{height:200vh;height:200svh;}  /* = the grid's height: two screens */
.collage-grid{
  /* two screens tall: collage.js slides it up through the first screen
     of scroll, then fades it out over the second */
  display:grid;width:100%;gap:0;
  height:calc(2 * (100vh - 6rem));height:calc(2 * (100svh - var(--collage-top)));
  grid-template-columns:repeat(6,1fr);
  grid-template-rows:repeat(8,1fr);
  grid-template-areas:
    "a a b c c d"
    "a a e e f d"
    "g h e e f i"
    "g h j k l i"
    "m m n o o x"
    "q r n o o p"
    "q w s s t p"
    "v v s s t u";
  will-change:transform;
}
.ct{
  position:relative;overflow:hidden;display:block;min-width:0;min-height:0;
  color:#fff;text-decoration:none;background:#111;
  will-change:opacity,transform;
}
.ct-a{grid-area:a}.ct-b{grid-area:b}.ct-c{grid-area:c}.ct-d{grid-area:d}
.ct-e{grid-area:e}.ct-f{grid-area:f}.ct-g{grid-area:g}.ct-h{grid-area:h}
.ct-i{grid-area:i}.ct-j{grid-area:j}.ct-k{grid-area:k}.ct-l{grid-area:l}
.ct-m{grid-area:m}.ct-n{grid-area:n}.ct-o{grid-area:o}.ct-p{grid-area:p}
.ct-q{grid-area:q}.ct-r{grid-area:r}.ct-s{grid-area:s}.ct-t{grid-area:t}
.ct-u{grid-area:u}.ct-v{grid-area:v}.ct-w{grid-area:w}.ct-x{grid-area:x}
.ct img,.ct video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;
  transition:transform 1s cubic-bezier(.16,1,.3,1), filter .5s;
}
/* bottom scrim so the label reads on any photo */
.ct::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top, rgba(0,0,0,.72) 0%, rgba(0,0,0,.15) 38%, rgba(0,0,0,0) 60%);
}
.ct-label{
  position:absolute;left:clamp(.7rem,1.2vw,1.2rem);right:clamp(.7rem,1.2vw,1.2rem);bottom:clamp(.6rem,1.1vw,1.1rem);
  z-index:1;display:flex;flex-direction:column;gap:.25rem;
}
.ct-name{
  font-family:var(--sans);font-weight:700;text-transform:uppercase;
  font-size:clamp(.82rem,1.25vw,1.2rem);letter-spacing:-.01em;line-height:1.05;
}
.ct-kind{
  font-family:var(--mono);font-size:clamp(.55rem,.7vw,.66rem);
  letter-spacing:.14em;text-transform:uppercase;color:var(--accent-ink);
}
.ct-cta{
  position:absolute;top:clamp(.6rem,1vw,1rem);right:clamp(.6rem,1vw,1rem);z-index:1;
  font-family:var(--mono);font-size:.66rem;letter-spacing:.12em;text-transform:uppercase;
  color:#fff;background:rgba(10,10,10,.55);backdrop-filter:blur(8px);
  border:1px solid rgba(255,255,255,.35);border-radius:999px;padding:.42rem .8rem;
  opacity:0;transform:translateY(-4px);
  transition:opacity .3s, transform .3s cubic-bezier(.16,1,.3,1), background .3s, border-color .3s;
}
.ct:hover img,.ct:hover video,.ct:focus-visible img,.ct:focus-visible video{transform:scale(1.05);}
.ct:hover .ct-cta,.ct:focus-visible .ct-cta{opacity:1;transform:none;background:var(--accent);border-color:var(--accent);}
.ct:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;}
/* touch screens have no hover: keep the button visible */
@media (hover:none){ .ct-cta{opacity:1;transform:none;} }

.collage-cue{
  /* sits just under the nav capsule — tile labels live at the bottom of
     each tile, so the top edge is the one place it can't cover a name */
  position:absolute;left:50%;top:1rem;z-index:2;transform:translateX(-50%);
  font-family:var(--mono);font-size:.66rem;letter-spacing:.14em;text-transform:uppercase;
  color:#fff;background:rgba(10,10,10,.6);backdrop-filter:blur(8px);
  border:1px solid rgba(255,255,255,.25);border-radius:999px;padding:.5rem 1rem;
  pointer-events:none;white-space:nowrap;
}
.collage-cue span{display:inline-block;animation:cue-bob 1.8s ease-in-out infinite;margin-left:.4rem;}
@keyframes cue-bob{0%,100%{transform:translateY(0)}50%{transform:translateY(3px)}}

/* phones: a taller 3-column tiling of the same eleven tiles */
@media (max-width:700px){
  .collage-grid{
    grid-template-columns:repeat(3,1fr);
    grid-template-rows:repeat(12,1fr);
    grid-template-areas:
      "a a b"
      "a a c"
      "d e e"
      "f e e"
      "g h i"
      "j k l"
      "m m n"
      "o o n"
      "o o p"
      "q r p"
      "s t u"
      "v w x";
  }
  .ct-cta{display:none;}
  .ct-label{left:.5rem;right:.5rem;bottom:.45rem;gap:.15rem;}
  .ct-name{font-size:.72rem;}
  .ct-kind{font-size:.5rem;letter-spacing:.1em;}
  .collage-cue{display:none;}  /* phones scroll by instinct; it would cover a tile name */
}
@media (prefers-reduced-motion: reduce){
  .collage-cue span{animation:none;}
  .ct img,.ct video{transition:none;}
}

/* ---------- photo-masonry: full, uncropped photos at their natural shape ----------
   For photography-led client pages (Sopa Lodges, Elewana Collection), where a
   fixed 4:3 tile would cut heads and horizons off portrait and panoramic shots. */
.photo-masonry{columns:3 260px;column-gap:1rem;}
.photo-masonry .media-ph{
  aspect-ratio:auto;break-inside:avoid;margin:0 0 1rem;display:block;
}
.photo-masonry .media-ph.has-img img{height:auto;}
.photo-hero{margin-bottom:1rem;}
.photo-hero .media-ph{aspect-ratio:auto;display:block;}
.photo-hero .media-ph.has-img img{height:auto;}
@media (max-width:700px){ .photo-masonry{columns:2 140px;column-gap:.6rem;} .photo-masonry .media-ph{margin-bottom:.6rem;} }

/* ---------- location list under a client heading (e.g. Sopa Lodges) ---------- */
.loc-list{list-style:none;margin:1rem 0 1.4rem;padding:0;display:flex;flex-direction:column;gap:.7rem;}
.loc-list li{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;}
.loc-country{
  font-family:var(--mono);font-size:.64rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--accent);min-width:5.5rem;
}
.loc-name{
  font-family:var(--mono);font-size:.7rem;letter-spacing:.06em;text-transform:uppercase;
  color:var(--ink);border:1px solid var(--line);border-radius:999px;padding:.32rem .75rem;
}
@media (max-width:700px){ .loc-country{min-width:100%;} .loc-name{font-size:.62rem;} }
