@font-face{
  font-family:"Humane";
  src:url("fonts/Humane-Regular.ttf") format("truetype");
  font-weight:400;
  font-style:normal;
  font-display:swap;
}

/* ---------- tokens ---------- */
:root{
  --first-color:#000;
  --second-color:#fff;
  --third-color:#ffffffb3;
  --primary-font:Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;
  --display-font:"Bebas Neue",Impact,"Arial Narrow",sans-serif;
  --wordmark-font:"Humane","Arial Narrow",sans-serif;

  --font-h2:4rem;
  --font-h3:1.7rem;
  --font-h4:1.4rem;
  --font-h5:1.2rem;
  --font-h6:.9rem;
  --font-work-title:1rem;

  --lh-page:1.1;
  --lh-paragraph:1.3;
  --lh-tight:.85;

  --page-width:100%;
}

*,*::before,*::after{box-sizing:border-box;}

html,body{margin:0;padding:0;}

body{
  background-color:var(--first-color);
  color:var(--second-color);
  font-family:var(--primary-font);
  font-size:14px;
  line-height:var(--lh-page);
  font-weight:500;
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  /* clip, not hidden: overflow-x:hidden makes body a scroll container, which
     silently kills position:sticky on the work rows. clip does not. */
  overflow-x:clip;
}

.top-main{position:relative;z-index:4;}

/* ---------- nav ---------- */
.nav{
  position:absolute;
  top:0;left:0;right:0;
  z-index:6;
  display:flex;
  align-items:center;
  justify-content:space-between;
  padding:28px 2% 0;
}

.nav-logo{
  font-family:var(--display-font);
  font-size:var(--font-h3);
  letter-spacing:2px;
  text-transform:uppercase;
  color:var(--second-color);
  text-decoration:none;
  display:inline-flex;
  align-items:flex-start;
  gap:3px;
}

.nav-links{display:flex;align-items:center;gap:26px;}

.nav-link{
  display:inline-flex;
  align-items:center;
  gap:8px;
  text-decoration:none;
  color:var(--second-color);
  font-family:var(--display-font);
  font-size:var(--font-work-title);
  letter-spacing:.7px;
  text-transform:uppercase;
}
.nav-dot{
  width:6px;height:6px;border-radius:50%;
  background:var(--second-color);
  opacity:.35;
  transform:scale(.6);
  transition:transform .35s cubic-bezier(.22,1,.36,1),opacity .35s ease;
}
.nav-link:hover .nav-dot{transform:scale(1);opacity:1;}
.nav-link-text{
  position:relative;
  transition:opacity .3s ease;
}
.nav-link:hover .nav-link-text{opacity:.65;}

/* sliding pill CTA */
.nav-cta{
  position:relative;
  display:inline-block;
  overflow:hidden;
  border:1px solid #ffffff2e;
  border-radius:100px;
  padding:11px 22px;
  text-decoration:none;
  color:var(--second-color);
  /* deliberately no backdrop-filter: it sits over an animating canvas and
     forces the compositor to re-blur the backdrop on every frame */
  background:#ffffff12;
  font-family:var(--display-font);
  font-size:var(--font-work-title);
  letter-spacing:.9px;
  text-transform:uppercase;
  line-height:1;
  transition:border-color .35s ease,background .35s ease;
}
.nav-cta:hover{border-color:#ffffff6b;background:#ffffff17;}

/* single-line window; the track slides exactly one line on hover */
.nav-cta-window{display:block;height:1em;overflow:hidden;}
.nav-cta-track{
  display:block;
  transition:transform .45s cubic-bezier(.22,1,.36,1);
}
.nav-cta-track > span{
  display:block;
  height:1em;
  line-height:1;
  white-space:nowrap;
}
.nav-cta:hover .nav-cta-track{transform:translateY(-1em);}

/* ---------- hero ---------- */
.hero{
  position:relative;
  min-height:700px;
  height:100vh;
  padding:0 2% 300px;
  overflow:hidden;
}

.absolute-effect{
  position:absolute;
  inset:0;
  width:100%;
  height:100%;
  display:block;
  /* own compositor layer, so scrolling never repaints it */
  transform:translateZ(0);
  backface-visibility:hidden;
}

/* static wordmark, only when the canvas cannot run */
.logo-main{
  display:none;
  position:absolute;
  left:0;right:0;
  top:52%;
  margin:0;
  text-align:center;
  font-family:var(--wordmark-font);
  font-weight:400;
  font-size:34vh;
  line-height:var(--lh-tight);
  letter-spacing:-.02em;
  text-transform:uppercase;
  color:var(--second-color);
}

/* sits directly under the wordmark; --mark-bottom is published by hero.js
   from the real glyph box, so it tracks the mark at any viewport size */
.container.down{
  position:absolute;
  top:calc(var(--mark-bottom, 62vh) + 46px);
  left:0;right:0;
  z-index:3;
  pointer-events:none;
}

.right-studio-text{
  display:flex;
  flex-flow:column;
  justify-content:center;
  align-items:center;
  row-gap:40px;
}

.max-w-center{
  text-align:center;
  width:100%;
  max-width:400px;
  margin-inline:auto;
}
.max-w-center._300{max-width:430px;}

.about-title{
  font-size:var(--font-h3);
  line-height:var(--lh-paragraph);
  font-weight:600;
  margin:0;
}
.about-title.small{font-size:var(--font-h5);}

/* ---------- bottom row ---------- */
.container-bottom{
  position:absolute;
  inset:auto 0 30px;
  z-index:2;
  width:var(--page-width);
  margin-inline:auto;
}

.bottom-grid{
  display:grid;
  grid-template-columns:1fr 1fr 1fr;
  grid-template-rows:auto;
  place-items:end stretch;
  column-gap:10px;row-gap:10px;
  padding-inline:2%;
}

.top-text{
  font-family:var(--display-font);
  font-size:var(--font-work-title);
  font-weight:500;
  letter-spacing:.7px;
  text-transform:uppercase;
  margin:0;
  opacity:1;
}
.top-text.big{font-size:var(--font-h5);font-weight:300;letter-spacing:.7px;}

.lighter-color{opacity:.43;}

.service-list p{line-height:1.35;}

/* bottom row: services left, scroll centred, featured right */
.services-cell{justify-self:start;text-align:left;}
.scroll-cell{justify-self:center;text-align:center;}
.featured-cell{justify-self:end;text-align:right;}

.arrow{
  display:inline-block;
  margin-right:4px;
  animation:nudge 2.2s ease-in-out infinite;
}
@keyframes nudge{
  0%,100%{transform:translateY(0);opacity:.55;}
  50%{transform:translateY(4px);opacity:1;}
}

/* reveal */
.reveal{opacity:0;transform:translateY(14px);}
.is-in .reveal{
  opacity:1;transform:none;
  transition:opacity .9s cubic-bezier(.22,1,.36,1),transform .9s cubic-bezier(.22,1,.36,1);
}
.is-in .reveal:nth-child(2){transition-delay:.08s;}

/* ---------- work section ---------- */
.section{
  position:relative;
  z-index:10;
  background-color:var(--first-color);
  padding:5% 2%;
}

.container{
  position:relative;
  z-index:30;
  width:100%;
  max-width:1400px;
  margin-inline:auto;
}

.work-head{padding-bottom:10px;}

/* each row sticks under the previous one and stacks as you scroll */
.service-grid{
  display:grid;
  grid-template-columns:1fr 4fr;
  column-gap:16px;row-gap:16px;
  padding:50px 0;
  border-bottom:1px solid #ffffff26;
  background-color:var(--first-color);
  position:sticky;
  top:80px;
}

.item-grid{
  display:grid;
  grid-template-columns:1fr 1fr 1fr;
  column-gap:50px;row-gap:50px;
}

.photo-wrapper{
  position:relative;
  display:flex;
  align-items:center;
  justify-content:center;
  border-radius:20px;
  overflow:hidden;
}
.photo-wrapper.add-px{aspect-ratio:2;}

.work-photo-first{
  display:block;
  width:100%;
  height:100%;
  object-fit:cover;
}

.service-copy{
  margin:0;
  font-size:.95rem;
  line-height:1.5;
  color:var(--third-color);
}

/* whole row is the link; sticky already gives us the containing block */
.row-link{
  position:absolute;
  inset:0;
  z-index:3;
}

.row-view{
  margin:16px 0 0;
  font-family:var(--display-font);
  font-size:var(--font-work-title);
  letter-spacing:.7px;
  text-transform:uppercase;
  color:var(--second-color);
  opacity:.55;
  transition:opacity .3s ease;
}
.service-grid:hover .row-view{opacity:1;}

.work-photo-first{transition:transform .7s cubic-bezier(.22,1,.36,1);}
.service-grid:hover .work-photo-first{transform:scale(1.04);}
.about-title.no-top{transition:opacity .3s ease;}
.service-grid:hover .about-title.no-top{opacity:.75;}

.margin-10{margin-top:10px;}
.margin-20{margin-top:20px;}

.flex-category{display:flex;flex-wrap:wrap;column-gap:5px;row-gap:5px;}

/* category pill */
.top-text.color{
  font-family:var(--primary-font);
  font-size:var(--font-h6);
  font-weight:500;
  letter-spacing:0;
  text-transform:none;
  background-color:#333;
  border-radius:7px;
  padding:5px 9px;
  display:inline-block;
}
/* the row number, inverted */
.top-text.color.white{
  background-color:var(--second-color);
  font-family:var(--display-font);
  color:var(--first-color);
  font-size:var(--font-h5);
  font-weight:600;
  letter-spacing:.5px;
  padding:3px 8px;
}

/* ---------- fallback / responsive ---------- */
.no-webgl .absolute-effect{display:none;}
.no-webgl .logo-main{display:block;}

/* The canvas stays live at every width. The static mark is only ever shown
   when WebGL is unavailable, which is handled by .no-webgl above. */
@media (max-width:991px){
  /* svh, so the mobile URL bar cannot make the hero taller than the screen */
  .hero{min-height:0;height:100svh;padding:0 5% 0;}
  .nav{padding:20px 5% 0;}
  .nav-links{display:none;}
  .container-bottom{bottom:18px;}
  /* .container-bottom is absolute against the hero's padding box, so left:0 is
     the outer edge. The grid has to supply the gutter itself. */
  .bottom-grid{padding-inline:5%;}
  .about-title{font-size:var(--font-h4);}
  .about-title.small{font-size:1.05rem;}
  .max-w-center._300{max-width:380px;}
  .container.down{top:calc(var(--mark-bottom, 56vh) + 30px);}

  .service-grid{grid-template-columns:.3fr 4fr;padding:36px 0;}
  .item-grid{column-gap:30px;row-gap:30px;}
  .about-title.no-top{font-size:var(--font-h4);}
  .photo-wrapper.add-px{border-radius:10px;}
}

@media (max-width:767px){
  .container.down{top:calc(var(--mark-bottom, 52vh) + 22px);}
  .max-w-center._300{max-width:320px;}
  .about-title.small{font-size:.95rem;}

  /* services across the top, then featured and scroll sharing one line */
  .bottom-grid{grid-template-columns:1fr 1fr;row-gap:16px;}
  .services-cell{grid-column:1 / -1;grid-row:1;}
  .service-list{
    display:grid;
    grid-template-columns:1fr 1fr;
    column-gap:14px;
    row-gap:1px;
  }
  .featured-cell{grid-column:1;grid-row:2;justify-self:start;text-align:left;}
  .scroll-cell{grid-column:2;grid-row:2;justify-self:end;text-align:right;}

  .top-text{font-size:.72rem;}
  .top-text.big{font-size:.8rem;}
  .nav-logo{font-size:1.3rem;}
  .nav-cta{padding:9px 16px;font-size:.8rem;}

  /* rows stop sticking and stack normally; three columns is too narrow here */
  .service-grid{
    display:flex;flex-flow:column;
    /* NOT static: .row-link is absolute inset:0 and would otherwise resolve
       against .container, stacking all 13 links over the whole section so the
       last one in the DOM swallows every tap */
    position:relative;
    padding:30px 0;row-gap:16px;
  }
  .item-grid{display:flex;flex-flow:column;row-gap:18px;}
  .section{padding:14% 5%;}
  .about-title.no-top{font-size:1.25rem;}
  .service-copy{font-size:.9rem;}
  .top-text.color{font-size:.78rem;padding:4px 8px;}
  .top-text.color.white{font-size:1rem;}
}

@media (max-width:479px){
  .max-w-center._300{max-width:270px;}
  .about-title.small{font-size:.88rem;}
  .top-text,.top-text.big{font-size:.68rem;}
  .service-list{column-gap:10px;}
}

@media (prefers-reduced-motion:reduce){
  .arrow{animation:none;}
  .reveal{opacity:1;transform:none;}
}

/* live site preview used in place of a still, scaled to the row */
.work-preview{
  position:absolute;
  top:0;left:0;
  width:1280px;
  height:640px;
  border:0;
  transform-origin:top left;
  pointer-events:none;
  background:#0b0b0d;
}

/* rows with no destination: no hover affordance, no pointer */
.service-grid.is-static{cursor:default;}
.service-grid.is-static:hover .work-photo-first{transform:none;}
.service-grid.is-static:hover .about-title.no-top{opacity:1;}

/* ---------- contact ---------- */
.section.contact{padding-top:9%;padding-bottom:5%;}

.contact-head{max-width:74ch;}

.contact-title{
  font-family:var(--display-font);
  font-size:clamp(3.4rem,12vw,10rem);
  line-height:.88;
  letter-spacing:1px;
  text-transform:uppercase;
  margin:18px 0 0;
}

.contact-lede{
  margin:22px 0 0;
  font-size:1.05rem;
  line-height:1.55;
  color:var(--third-color);
  max-width:52ch;
}

.contact-rows{margin-top:56px;border-top:1px solid #ffffff26;}

.contact-row{
  display:grid;
  grid-template-columns:minmax(90px,140px) 1fr auto;
  align-items:center;
  gap:20px;
  padding:26px 0;
  border-bottom:1px solid #ffffff26;
  text-decoration:none;
  color:var(--second-color);
  transition:padding-left .35s cubic-bezier(.22,1,.36,1);
}
.contact-row:hover{padding-left:14px;}

.contact-label{
  font-family:var(--display-font);
  font-size:var(--font-work-title);
  letter-spacing:1.2px;
  text-transform:uppercase;
  color:#ffffff5c;
}

.contact-value{
  font-family:var(--display-font);
  font-size:clamp(1.5rem,4vw,3rem);
  line-height:1;
  letter-spacing:.5px;
  text-transform:uppercase;
  transition:opacity .3s ease;
}
.contact-row:hover .contact-value{opacity:.7;}

.contact-arrow{
  font-size:1.4rem;
  color:#ffffff5c;
  transition:transform .35s cubic-bezier(.22,1,.36,1),color .3s ease;
}
.contact-row:hover .contact-arrow{transform:translate(4px,-4px);color:var(--second-color);}

.contact-foot{
  display:flex;
  justify-content:space-between;
  align-items:center;
  gap:16px;
  margin-top:56px;
}

@media (max-width:767px){
  .section.contact{padding:16% 5% 12%;}
  .contact-row{grid-template-columns:1fr auto;gap:6px 12px;padding:20px 0;}
  .contact-label{grid-column:1 / -1;}
  .contact-value{font-size:1.35rem;word-break:break-word;}
  .contact-foot{flex-flow:column;align-items:flex-start;gap:8px;margin-top:40px;}
}

/* no rule under the last project; it read as a divider against the contact section */
.service-wrapper .service-grid:last-child{border-bottom:0;}

/* no full-width rules at the top of the contact block */
.contact-rows{border-top:0;}
.section.contact{border-top:0;}

/* ---------- PM layout: nav links left, name right, no CTA ---------- */
.nav-links{display:flex;align-items:center;gap:26px;}
.nav-logo{letter-spacing:2.4px;}

/* the hero footer now carries only the scroll cue */
.bottom-grid._2{grid-template-columns:1fr;}
.bottom-grid._2 .scroll-cell{justify-self:center;text-align:center;}

@media (max-width:991px){
  /* only two items now, so they stay visible */
  .nav-links{display:flex;gap:18px;}
  .nav-logo{font-size:1.1rem;letter-spacing:1.6px;}
}

@media (max-width:767px){
  .nav-links{gap:14px;}
  .nav-link{font-size:.78rem;}
  .nav-logo{font-size:.95rem;letter-spacing:1.2px;}
  .bottom-grid._2{grid-template-columns:1fr;}
}

/* name hard left, links dead centre, nothing on the right */
.nav{
  display:grid;
  grid-template-columns:1fr auto 1fr;
  align-items:center;
}
.nav-logo{justify-self:start;}
.nav-links{justify-self:center;}
.nav-dot{display:none;}

/* name left, single link hard right */
.nav{grid-template-columns:1fr auto;}
.nav-links{justify-self:end;}

/* ---------- pill button: panel wipes up from below on hover ---------- */
.pill-btn{
  position:relative;
  display:grid;
  overflow:hidden;
  border-radius:50em;
  background:var(--second-color);
  color:var(--first-color);
  text-decoration:none;
  justify-self:end;
  isolation:isolate;
}

/* both faces share one grid cell, so the pill is as wide as the longer label */
.pill-face{
  grid-area:1/1;
  display:flex;
  align-items:center;
  justify-content:center;
  min-height:2.7rem;
  padding:.6em 1.25em;
  font-family:var(--display-font);
  font-size:var(--font-h5);
  letter-spacing:.6px;
  text-transform:uppercase;
  line-height:1;
  white-space:nowrap;
}

/* parked one full height below, then wipes up over the front face */
.pill-back{
  background:#e6e3e3;
  color:var(--first-color);
  border-radius:50em;
  transform:translateY(100%);
  transition:transform .45s cubic-bezier(.22,1,.36,1);
}
.pill-btn:hover .pill-back,
.pill-btn:focus-visible .pill-back{transform:translateY(0);}

@media (max-width:767px){
  .pill-face{min-height:2.3rem;padding:.5em 1em;font-size:1rem;}
}

@media (max-width:767px){
  /* no rules between stacked project rows on mobile */
  .service-grid{border-bottom:0;}
}

@media (max-width:767px){
  /* the hero footer carries only the scroll cue now; the old 3-cell mobile
     rules still forced it into column 2, hard right */
  .bottom-grid._2{grid-template-columns:1fr;}
  .bottom-grid._2 .scroll-cell{
    grid-column:1;grid-row:1;
    justify-self:center;
    text-align:center;
  }
}

/* ---------- hero contact card (bottom right, desktop only) ---------- */
/* the hero footer keeps the scroll cue dead centre; the card takes the
   right-hand track, so column 1 stays empty on purpose */
.bottom-grid._2{grid-template-columns:1fr auto 1fr;}
.bottom-grid._2 .scroll-cell{grid-column:2;grid-row:1;justify-self:center;text-align:center;}
.bottom-grid._2 .hero-card{grid-column:3;grid-row:1;}

.hero-card{
  justify-self:end;
  display:flex;
  align-items:flex-end;
  gap:12px;
  pointer-events:auto;
}

/* photo and panel are the same height at rest */
.hero-card-pic{
  width:4.6rem;
  height:4.6rem;
  flex:none;
  border-radius:16px;
  object-fit:cover;
  object-position:center;
  display:block;
  background:#1b1b1f;
}

.hero-card-panel{
  position:relative;
  min-width:230px;
  min-height:4.6rem;
  display:flex;
  flex-flow:column;
  justify-content:center;
  border:1px solid #ffffff1f;
  border-radius:16px;
  padding:12px 20px 12px 16px;
  /* deliberately no backdrop-filter: it sits over the hero canvas and would
     force the compositor to re-blur the backdrop on every pointer frame */
  background:#ffffff14;
}

.hero-card-dot{
  position:absolute;
  top:-3px;right:14px;
  width:7px;height:7px;
  border-radius:50%;
  background:#4ade80;
  box-shadow:0 0 0 0 #4ade8099;
  animation:cardPulse 2.6s ease-out infinite;
}
@keyframes cardPulse{
  0%{box-shadow:0 0 0 0 #4ade8066;}
  70%{box-shadow:0 0 0 9px #4ade8000;}
  100%{box-shadow:0 0 0 0 #4ade8000;}
}

.hero-card-head{overflow:clip;}
.hero-card-cta{
  margin:0;
  font-family:var(--display-font);
  font-size:1.05rem;
  letter-spacing:.7px;
  text-transform:uppercase;
  color:var(--second-color);
}
.hero-card-role{
  margin:2px 0 0;
  font-size:.72rem;
  line-height:1.3;
  color:#ffffff80;
}

/* the reveal: 0fr to 1fr animates real height, no max-height guessing */
.hero-card-more{
  display:grid;
  grid-template-rows:0fr;
  opacity:0;
  margin-top:0;
  transition:
    grid-template-rows .6s cubic-bezier(.22,1,.36,1),
    opacity .4s ease,
    margin-top .6s cubic-bezier(.22,1,.36,1);
}
.hero-card:hover .hero-card-more,
.hero-card:focus-within .hero-card-more{
  grid-template-rows:1fr;
  opacity:1;
  margin-top:12px;
}
.hero-card-more-in{
  min-height:0;
  overflow:hidden;
  display:flex;
  flex-flow:column;
  gap:10px;
}

.hero-card-row{
  display:flex;
  flex-flow:column;
  gap:2px;
  padding-top:8px;
  border-top:1px dotted #ffffff26;
}
.hero-card-row.first{padding-top:0;border-top:0;}

.hero-card-label{
  margin:0;
  font-size:.68rem;
  letter-spacing:.4px;
  color:#ffffff80;
}
.hero-card-link{
  color:var(--second-color);
  font-size:.85rem;
  font-weight:600;
  text-decoration:none;
}
.hero-card-link:hover{
  text-decoration:underline dotted #ffffff80;
  text-underline-offset:3px;
  text-decoration-thickness:1px;
}

.hero-card-link.with-icon{
  display:inline-flex;
  align-items:center;
  gap:6px;
}
.hero-card-ext{font-size:.8em;opacity:.6;}
.hero-card-link.with-icon:hover{text-decoration:none;opacity:.75;}

@media (max-width:991px){
  .hero-card-pic{width:60px;height:60px;}
  .hero-card-panel{min-width:200px;min-height:60px;}
}

@media (max-width:767px){
  /* mobile never gets the card; the footer goes back to the lone scroll cue */
  .hero-card{display:none;}
  .bottom-grid._2{grid-template-columns:1fr;}
  .bottom-grid._2 .scroll-cell{
    grid-column:1;grid-row:1;
    justify-self:center;
    text-align:center;
  }
}

/* ---------- hero bottom-left: what the role covers ---------- */
/* column 1 of the ._2 grid was empty; the scroll cue and the contact card
   already own columns 2 and 3 */
.bottom-grid._2 .services-cell{
  grid-column:1;grid-row:1;justify-self:start;text-align:left;
}
@media (max-width:767px){
  /* mobile keeps the lone scroll cue */
  .hide-mobile{display:none;}
}

/* ---------- nav: Projects dead centre, contact pill hard right ---------- */
/* .nav is re-declared at top level further up as a two-column grid, so this
   has to come after it to win on source order. */
.nav{grid-template-columns:1fr auto 1fr;}
.nav-links{justify-self:center;}
.nav > .pill-btn{justify-self:end;}

@media (max-width:767px){
  /* mobile keeps name left, pill right, no middle column */
  .nav-links{display:none;}
  .nav{grid-template-columns:1fr auto;}
}

/* ---------- floating golden ticket ---------- */
/* Sized and positioned from the live layout by ticket-loader.js; this rule owns
   only the stacking and the pointer contract. It stays pointer-transparent and
   the engine flips it to auto solely while the cursor is on the cloth, so links,
   hovers and page scrolling behave as if it were not here. */
.ticket-float{
  position:absolute;
  z-index:20;
  pointer-events:none;
  max-width:100vw;
  overflow:hidden;
  -webkit-user-select:none;user-select:none;
  -webkit-tap-highlight-color:transparent;
}

/* ---------- room for the ticket on phones ---------- */
/* The band between the last project and "Let's talk" was 92px here against
   147px on /work, which forced the sheet down to a size that read as an
   afterthought. Pushing the heading down gives it the same room, and the
   placement is measured from the live layout so the ticket grows on its own.
   Mobile only: desktop already has 410px of clear height and is untouched. */
@media (max-width:767px){
  .section.contact{padding-top:calc(16% + 104px);}
}
