/* ============================================================
   Renatha Andrade — portfolio
   Palette, type scale and spacing all live in :root.
   ============================================================ */

:root{
  --paper:#F1EFEA;
  --ink:#000000;
  --ash:#8B8880;
  --ash-soft:#C6C3BC;
  --foot-bed:#6E6C68;      /* footer bed — grey */
  --foot-ink:#F1EFEA;      /* footer type */

  --footer-h:1.55rem;
  --topbar-h:2.9rem;
  --gut:clamp(1rem, 3.2vw, 2.6rem);
  /* the line both the hero sentence and the project index sit on */
  --stage-floor:calc(var(--footer-h) + clamp(1rem, 3vw, 2.2rem));

  --fs-micro:clamp(.58rem, .52rem + .14vw, .68rem);
  --fs-small:clamp(.72rem, .66rem + .20vw, .84rem);
  --fs-body:clamp(.86rem, .79rem + .28vw, 1.02rem);
  --fs-lead:clamp(1.02rem, .88rem + .62vw, 1.42rem);
  --fs-title:clamp(2.1rem, 1.2rem + 5.5vw, 3.2rem);

  --ease:cubic-bezier(.16,1,.3,1);
}

*,*::before,*::after{box-sizing:border-box;}
html{-webkit-text-size-adjust:100%;scrollbar-gutter:stable;}
/* no reserved gutter on a page that never scrolls */
html:has(body.is-home){scrollbar-gutter:auto;}
/* No background on html: the body's own colour then fills the whole
   canvas, including the reserved scrollbar gutter and anything below
   short content. Painting html here breaks that and leaves pale bands. */
body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:"Instrument Sans", Arial, Helvetica, sans-serif;
  font-size:var(--fs-body);font-weight:400;line-height:1.42;letter-spacing:-.005em;
  font-feature-settings:"ss01" 1,"cv01" 1;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;padding-bottom:var(--footer-h);
}
img,video{display:block;max-width:100%;height:auto;}
figure{margin:0;}
a{color:inherit;text-decoration:none;}
p{margin:0 0 .85em;} p:last-child{margin-bottom:0;}
h1,h2,h3{margin:0;font-weight:500;line-height:1.06;letter-spacing:-.028em;}
em,i{font-style:italic;}
:focus-visible{outline:2px solid var(--ink);outline-offset:3px;}

.skip{position:absolute;left:-9999px;top:0;background:var(--ink);color:var(--paper);
  padding:.6rem 1rem;z-index:2000;font-size:var(--fs-small);}
.skip:focus{left:.5rem;top:.5rem;}
.sr{position:absolute!important;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;}

.hl{text-decoration:underline;text-decoration-thickness:.06em;
  text-underline-offset:.16em;text-decoration-skip-ink:none;
  box-decoration-break:clone;-webkit-box-decoration-break:clone;}
/* no underline on the Info page's own bio text */
body.is-info .info__body .hl{text-decoration:none;}


/* ============================================================
   CUSTOM CURSOR — a black ball that inverts what it crosses
   ============================================================ */
@media (hover:hover) and (pointer:fine){
  html.has-cursor,html.has-cursor *{cursor:none;}
  .cursor{
    position:fixed;top:0;left:0;z-index:1500;pointer-events:none;
    width:14px;height:14px;
    transform:translate3d(-100px,-100px,0);
    opacity:0;transition:opacity .2s;
    will-change:transform;
    mix-blend-mode:difference;   /* must sit here, not on the child */
  }
  /* the visible dot is a child, so the click feedback is a GPU transform
     rather than a width/height change that forces layout every frame */
  .cursor i{display:block;width:100%;height:100%;border-radius:50%;
    background:#fff;
    transition:transform .22s var(--ease);}
  html.cursor-down .cursor i{transform:scale(.5);}
  .cursor.is-live{opacity:1;}
}

/* ============================================================
   TOP BAR — two layers: frosted pane (masked so the blur melts
   away downwards) and, above it, the words blending straight
   against the page.
   ============================================================ */
.topglass{
  position:fixed;top:0;left:0;right:0;z-index:78;pointer-events:none;
  height:calc(var(--topbar-h) * 1.6);
  -webkit-backdrop-filter:blur(9px) saturate(1.12);
  backdrop-filter:blur(9px) saturate(1.12);
  -webkit-mask-image:linear-gradient(to bottom,#000 0,#000 36%,rgba(0,0,0,.5) 64%,transparent 100%);
  mask-image:linear-gradient(to bottom,#000 0,#000 36%,rgba(0,0,0,.5) 64%,transparent 100%);
}
.topbar{
  position:fixed;top:0;left:0;right:0;height:var(--topbar-h);z-index:300;
  display:flex;align-items:center;justify-content:space-between;gap:.5rem;
  padding-inline:var(--gut);
  background:transparent;color:#fff;mix-blend-mode:difference;
}
/* same 4-column split as the original single-row bar: brand takes the
   first quarter (left-aligned), the three links share the rest, with
   Contact right-aligned at the far edge — restored after the hamburger
   markup split the bar into a brand element plus a links element */
.topbar__brand{flex:1 1 0;text-align:left;}
.topbar__nav{flex:3 1 0;display:flex;align-items:center;}
.topbar__nav a{flex:1 1 0;text-align:center;}
.topbar__nav a:last-child{text-align:right;}
.topbar a{
  font-size:var(--fs-micro);font-weight:500;letter-spacing:.18em;text-transform:uppercase;
  white-space:nowrap;color:inherit;
  transition:opacity .3s var(--ease);
}
/* hover one, the others recede */
.topbar:hover a{opacity:.38;}
.topbar a:hover,.topbar a:focus-visible{opacity:1;}
.topbar a[aria-current="page"]{opacity:.5;}
.topbar :focus-visible{outline-color:#fff;}

/* hamburger — hidden until the small breakpoint below. Anchored straight
   to .topbar (its nearest positioned ancestor) with top:50%, rather than
   sitting as a flex child — flex alignment left it sitting high and off
   the brand text's centre on mobile Safari, so this pins it by the bar's
   own height instead of trusting the row's cross-axis centring. */
.menu-btn{
  display:none;position:absolute;top:50%;right:var(--gut);z-index:220;
  transform:translateY(-50%);
  width:1.7rem;height:1.7rem;margin:0;padding:0;border:0;background:none;
  -webkit-appearance:none;appearance:none;font:inherit;
  cursor:pointer;color:inherit;
}
/* the top bar stays put; opening the menu just drops the bottom one away */
.menu-btn__bar{
  position:absolute;left:50%;width:1.4rem;height:1.5px;
  background:currentColor;
  transform:translateX(-50%);
  transition:top .3s var(--ease),opacity .3s var(--ease);
}
.menu-btn__bar:first-child{top:.55rem;}
.menu-btn__bar:last-child{top:1.05rem;}
.menu-btn.is-open .menu-btn__bar:last-child,
html.nav-open .menu-btn__bar:last-child{top:1.55rem;opacity:0;}

/* the full-screen list — only ever shown on small screens, as an
   overlay outside the blended top bar so it can carry its own solid
   background rather than inverting against whatever is behind it */
.mobilenav{display:none;}

/* On the homepage the bar crosses photographs, so it goes back to
   inverting itself against them. A blended group inverts every colour
   inside it, so the accent steps aside there. */
body.is-home .topbar{color:#fff;mix-blend-mode:difference;}
body.is-home .topbar a[aria-current="page"]{color:#fff;}
body.is-home .topbar :focus-visible{outline-color:#fff;}

@supports not ((backdrop-filter:blur(2px)) or (-webkit-backdrop-filter:blur(2px))){
  .topglass{background:linear-gradient(to bottom,var(--paper) 62%,rgba(241,239,234,0) 100%);}
}
@media (max-width:600px){
  .topbar{padding-inline:1rem;gap:.25rem;}
  .topbar a{letter-spacing:.07em;}
  .topbar__nav{display:none;}
  .menu-btn{display:block;right:1rem;}

  .mobilenav{
    display:flex;flex-direction:column;justify-content:center;gap:1.5rem;
    position:fixed;inset:0;z-index:210;padding:6rem 1.7rem 3rem;
    background:var(--ink);
    transform:translateX(100%);
    transition:transform .4s var(--ease);
  }
  .mobilenav a{
    font-size:clamp(1.5rem,7vw,2.1rem);font-weight:500;letter-spacing:-.01em;
    text-transform:none;color:var(--paper);opacity:1;
  }
  .mobilenav a[aria-current="page"]{opacity:.5;}
  html.nav-open .mobilenav{transform:translateX(0);}
  html.nav-open{overflow:hidden;}
}

/* ============================================================
   FOOTER — grey bed, dark grey type, its own melting blur above
   ============================================================ */
.footglass{display:none;}
.footer{
  position:fixed;left:0;right:0;bottom:0;height:var(--footer-h);z-index:70;
  background:var(--foot-bed);color:var(--foot-ink);
  display:flex;align-items:center;overflow:hidden;white-space:nowrap;
}
.footer__track{display:flex;width:max-content;animation:slide-back 38s linear infinite;}
.footer span{font-size:.6rem;letter-spacing:.06em;font-weight:400;padding-right:2.2rem;
  text-transform:lowercase;}
.footer:hover{opacity:.72;}
@keyframes slide{from{transform:translateX(0);}to{transform:translateX(-50%);}}
/* opposite direction to the reel above it */
@keyframes slide-back{from{transform:translateX(-50%);}to{transform:translateX(0);}}

main{padding-top:var(--topbar-h);}
.wrap{padding-inline:var(--gut);}

/* ============================================================
   ENTRY REVEAL — things arrive rather than appear
   ============================================================ */
/* Gated on html.js, which is set by an inline script in <head>.
   With JavaScript off — or broken — nothing is ever hidden. */
html.js [data-reveal]{opacity:0;transform:translateY(8px);}
html.js.ready [data-reveal]{
  opacity:1;transform:none;
  transition:opacity .5s var(--ease),transform .5s var(--ease);
  transition-delay:var(--d,0ms);
}

/* ============================================================
   HOME — one screen of photographs
   ============================================================ */
body.is-home{overflow:hidden;padding-bottom:0;background:#000;}
body.is-home main{padding-top:0;}

.stagehome{
  position:relative;
  height:100vh;
  height:100svh;          /* runs under the footer, so the blur above it
                             never smears the page colour into the photos */
  overflow:hidden;
}

/* a single large sentence, inverted straight over the photographs */
.statement{
  position:absolute;z-index:20;left:0;right:0;
  bottom:var(--stage-floor);
  margin:0;padding-inline:var(--gut);
  color:#fff;mix-blend-mode:difference;pointer-events:none;
  font-size:clamp(1.3rem,.5rem + 2.9vw,3.7rem);
  line-height:1.1;letter-spacing:-.03em;font-weight:500;
  max-width:23ch;text-wrap:balance;
  max-height:calc(100% - var(--topbar-h) - 3rem);
}
.statement .hl{text-decoration-thickness:.05em;text-underline-offset:.12em;}

/* the homepage banner — a big, bold sentence spanning the full width at
   the top of the stage, blended straight over the photographs beneath */
.herostmt{
  position:absolute;z-index:20;left:0;right:0;
  top:calc(var(--topbar-h) + 1.4rem);
  margin:0;padding-inline:var(--gut);
  color:#fff;mix-blend-mode:difference;pointer-events:none;
  font-size:clamp(1.7rem,1rem + 3.6vw,4.4rem);
  line-height:1.04;letter-spacing:-.02em;font-weight:700;
  max-width:none;
}
.herostmt .hl{text-decoration-thickness:.05em;text-underline-offset:.12em;}

/* corner index — the project list, bottom-right */
.mark{position:absolute;z-index:20;color:#fff;mix-blend-mode:difference;
  font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;font-weight:500;}
.mark--br{right:var(--gut);bottom:var(--stage-floor);text-align:right;}
.mark a{color:inherit;display:block;transition:opacity .25s var(--ease);}
.mark--br:hover a{opacity:.3;}
.mark--br a:hover,.mark--br a:focus-visible{opacity:1;}
.mark i{font-style:normal;font-variant-numeric:tabular-nums;padding-right:.5em;opacity:.6;}
@media (max-width:900px){.mark--br{display:none;}}
/* back on the phone-width homepage, with a thumb-sized tap target per row */
@media (max-width:600px){
  .mark--br{display:block;font-size:.7rem;letter-spacing:.1em;}
  .mark--br a{padding:.32rem 0;}
}

/* ---- the reel: continuous, draggable, only the hovered frame inverts ---- */
.reel{position:absolute;inset:0;overflow:hidden;background:var(--ink);touch-action:pan-y;}
.reel__track{display:flex;height:100%;width:max-content;
  will-change:transform;transform:translateZ(0);backface-visibility:hidden;}
.reel.is-dragging{cursor:grabbing;}

.reel__item{position:relative;display:block;flex:0 0 auto;height:100%;
  overflow:hidden;background:var(--ink);}
.reel__item img{height:100%;width:auto;max-width:clamp(230px,32vw,520px);
  object-fit:cover;transition:filter .3s var(--ease);
  -webkit-user-drag:none;user-select:none;}
/* a black wash over every frame, so the reel reads as one darker, more
   even surface rather than a strip of bright, unrelated photos */
.reel__item::after{
  content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:rgba(0,0,0,.5);transition:background .3s var(--ease);
}
.reel__item:hover::after{background:rgba(0,0,0,.12);}
.reel__item:hover img{filter:invert(1);}

.reel__meta{
  position:absolute;left:0;right:0;bottom:var(--footer-h);z-index:2;padding:.8rem .9rem;
  display:flex;justify-content:space-between;align-items:flex-end;gap:.6rem;
  mix-blend-mode:difference;color:#fff;
  opacity:0;transform:translateY(.4rem);
  transition:opacity .3s var(--ease),transform .3s var(--ease);
}
.reel__item:hover .reel__meta{opacity:1;transform:none;}
.reel__ttl{font-size:var(--fs-small);font-weight:500;letter-spacing:-.02em;line-height:1.15;}
.reel__ttl em{display:block;font-style:italic;font-weight:400;font-size:var(--fs-micro);
  letter-spacing:0;opacity:.8;}
.reel__yr{font-size:var(--fs-micro);letter-spacing:.12em;font-variant-numeric:tabular-nums;}
@media (hover:none){.reel__meta{opacity:1;transform:none;}}

@media (max-width:600px){
  /* Width tied to the viewport height (not just width) so a photo keeps
     roughly its own shape instead of being squeezed into a tall sliver
     as the screen gets narrower. */
  .reel__item img{max-width:min(86vw, 58vh);}
  /* the title/year caption just gets clipped at phone widths — hide it
     rather than show a cut-off word */
  .reel__meta{display:none;}
  .herostmt{font-size:clamp(1.3rem,6.4vw,2.1rem);top:calc(var(--topbar-h) + .8rem);}
}

/* ============================================================
   WORK — two projects to a row. Each sits on a black field with
   its caption on a pale strip directly beneath, and the frames
   inside cycle on their own.
   ============================================================ */
.wgrid{
  display:grid;grid-template-columns:repeat(2, minmax(0,1fr));
  gap:clamp(.5rem, 1.4vw, 1.1rem);
  padding-bottom:clamp(2rem, 5vw, 3.5rem);
}
.wcell{display:flex;flex-direction:column;min-width:0;}

.slot{
  position:relative;display:block;
  background:var(--ink);
  aspect-ratio:16 / 10;
  overflow:hidden;
}
.slot img{
  position:absolute;inset:0;margin:auto;
  width:auto;height:auto;max-width:86%;max-height:86%;
  object-fit:contain;                       /* nothing is ever cropped */
  opacity:0;
  will-change:opacity;                      /* keep the crossfade on the
    compositor, so it never stutters waiting on layout/paint */
  transition:opacity .45s var(--ease),filter .3s var(--ease);
}
.slot img.is-on{opacity:1;}
/* the site's hover language, here too */
.slot:hover img,.slot:focus-visible img{filter:invert(1);}

.wcap{
  background:#E7E5E0;color:var(--ink);
  padding:clamp(.5rem,1vw,.75rem) clamp(.6rem,1.1vw,.9rem);
  font-size:var(--fs-micro);line-height:1.5;
  display:block;
}
.wcap b{font-weight:500;}
.wcap i{font-style:italic;}
.wcap .meta{color:var(--ash);}
.wcap .arw{display:inline-block;transition:transform .35s var(--ease);}
.wcell:hover .wcap .arw{transform:translate(.2em,-.2em);}
.wcap .desc{color:#55534E;}

@media (max-width:760px){
  .wgrid{grid-template-columns:1fr;gap:.7rem;}
  .slot{aspect-ratio:4 / 3;}
}

/* ============================================================
   PROJECT PAGES
   ============================================================ */
.phead{display:grid;grid-template-columns:minmax(0,1.25fr) 5.5rem minmax(0,1.4fr);
  gap:clamp(.8rem,2.5vw,2.4rem);padding:clamp(2rem,5vw,3.6rem) 0 clamp(1.4rem,3vw,2.2rem);
  align-items:start;}
.phead__title{font-size:var(--fs-title);font-weight:500;letter-spacing:-.04em;line-height:.94;}
.phead__sub{font-style:italic;font-size:var(--fs-body);color:var(--ash);margin-top:.35em;}
.phead__num{font-size:var(--fs-small);color:var(--ash);font-variant-numeric:tabular-nums;
  line-height:1.5;}
.phead__summary{font-size:var(--fs-body);max-width:46ch;}
.meta{margin-top:1.15rem;display:grid;gap:.32rem;font-size:var(--fs-small);}
.meta div{display:grid;grid-template-columns:7.5rem minmax(0,1fr);gap:.6rem;}
.meta dt{color:var(--ash);} .meta dd{margin:0;}
@media (max-width:760px){
  .phead{grid-template-columns:1fr;gap:.9rem;}
  .phead__num{order:-1;}
  .meta div{grid-template-columns:6rem minmax(0,1fr);}
}

.figure{margin:0 0 clamp(.4rem,1.2vw,1rem);}
/* looping clips read as moving images, not players */
.figure--loop video{pointer-events:none;}
.figure img,.figure video{width:100%;height:auto;}
.figure figcaption{font-size:var(--fs-micro);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ash);padding-top:.45rem;}
.stage.dark .figure figcaption{color:rgba(255,255,255,.5);}
.stage{background:var(--paper);}
.stage.dark{background:var(--ink);}
.stage__inner{padding:clamp(.9rem,2.4vw,2rem) var(--gut);}
.stage.dark .figure{background:var(--ink);}
.stage.dark .stage__inner > .figure img,
.stage.dark .stage__inner > .figure video{
  width:100%;height:auto;max-height:82vh;object-fit:contain;}

.ptext{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.35fr);
  gap:clamp(.8rem,3vw,3rem);padding:clamp(1.8rem,4.5vw,3.2rem) 0;align-items:start;}
.ptext__label{font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;
  color:var(--ash);}
.ptext__body{max-width:62ch;font-size:var(--fs-body);}
.ptext__role{font-size:var(--fs-small);}
.ptext__role strong{font-weight:500;}
@media (max-width:760px){.ptext{grid-template-columns:1fr;gap:.5rem;}}

.gal{display:grid;grid-template-columns:repeat(12,1fr);gap:clamp(.35rem,1vw,.9rem);
  padding-block:clamp(.6rem,2vw,1.4rem);}
.gal .figure{grid-column:span 6;}
.gal .figure.wide{grid-column:span 12;}
.gal .figure.tall{grid-column:span 6;}
.gal .figure img{width:100%;height:auto;}
.stage.dark .gal .figure img{width:100%;height:auto;max-height:88vh;object-fit:contain;}
@media (max-width:760px){
  .gal .figure,.gal .figure.wide,.gal .figure.tall{grid-column:span 12;}
}

.next{padding:clamp(2.4rem,6vw,4.4rem) 0 clamp(3rem,6vw,4.6rem);}
.next__label{font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;
  color:var(--ash);margin-bottom:.5rem;}
.next__link{font-size:clamp(1.7rem,.9rem + 2.4vw,3.4rem);font-weight:500;letter-spacing:-.04em;
  display:block;margin-top:.5rem;line-height:.98;}
.next__link .arw{display:inline-block;transition:transform .4s var(--ease);}
.next__link:hover .arw{transform:translate(.3em,-.3em);}
.next__link em{font-style:italic;font-weight:400;color:var(--ash);
  font-size:.38em;display:block;margin-top:.4em;letter-spacing:-.015em;}
.next__link:hover{opacity:.55;}
.next__link{transition:opacity .3s var(--ease);}

/* ============================================================
   PROJECT COMPOSITION
   One scale governs the whole page: --pgut between neighbouring
   images, --pmar at the page edges, --prhy between blocks. Every
   composition below is built from those three, so nothing is
   spaced by eye.
   ============================================================ */
:root{
  --pgut:clamp(.4rem, 1vw, .85rem);
  --pmar:var(--gut);
  --prhy:clamp(1.6rem, 4.5vw, 3.4rem);
}

.pb{background:var(--ink);padding-block:var(--prhy);}
.pb:first-of-type{padding-top:clamp(1rem, 2.5vw, 2rem);}
.pb__in{padding-inline:var(--pmar);}
.pb img,.pb video{display:block;width:100%;height:auto;}
.pb figure{margin:0;}   /* spacing comes from the scale, never from a figure */
.pb figcaption{font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.45);padding-top:.7rem;padding-inline:var(--pmar);}
.pb--film figcaption{padding-inline:var(--pmar);text-align:center;}

/* one image, held to a column and centred */
.pb--single .pb__in{max-width:46rem;margin-inline:auto;}
/* a smaller presentation for the vinyl overview */
.project--pity-party .pb--compact .pb__in{max-width:34rem;margin-inline:auto;}
/* one image across the measure */
.pb--wide .pb__in{max-width:78rem;margin-inline:auto;}
/* the opening frame: small, centred, plenty of black around it */
.pb--hero .pb__in{max-width:32rem;margin-inline:auto;}
/* original project-wide film presentation */
.pb--film .pb__in{max-width:78rem;margin-inline:auto;}
.pb--vpair .pb__in{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--pgut);max-width:62rem;margin-inline:auto;}
.vcell{background:var(--ink);overflow:hidden;}
.vcell figure,.vcell video{width:100%;height:100%;}
.vcell video{object-fit:cover;}
.pb--film video{width:100%;height:auto;}

/* Pity Party-specific film presentation */
.project--pity-party .pb--film{
  min-height:100svh;
  display:grid;
  align-items:center;
  padding-block:clamp(4.5rem,8vw,7rem);
}
.project--pity-party .pb--film .pb__in{max-width:44rem;margin-inline:auto;}
.project--pity-party .pb--vpair .pb__in{
  gap:var(--pgut);width:70%;max-width:none;margin-inline:auto;padding-inline:0;}
.project--pity-party .pb--vpair .vcell{aspect-ratio:2/3!important;}
.project--pity-party .pb--vpair .vcell video{object-fit:cover;object-position:50% 50%;}
.project--pity-party .pb--film .figure{aspect-ratio:16/9;overflow:hidden;}
.project--pity-party .pb--film video{
  width:100%;height:100%;object-fit:cover;
  transform:scale(2.7);transform-origin:50% 52%;
}

/* DEBRIS pocket calendar follows the vertical rhythm of the Figma reference */
.project--debris-calendar .pb--hero .pb__in{max-width:48rem;}
.project--debris-calendar .pb--film .pb__in{max-width:58rem;}
.project--debris-calendar .pb--single .pb__in{max-width:34rem;}
.project--debris-calendar .pb--wide .pb__in{width:88%;max-width:88rem;margin-inline:auto;padding-inline:0;}
/* The blue calendar-stack photograph follows the scale of the opening image. */
.project--debris-calendar .pb--film + .pb--wide .pb__in{width:auto;max-width:48rem;margin-inline:auto;padding-inline:var(--pmar);}
.project--debris-calendar .pb--pair .pb__in{max-width:46rem;}
.project--debris-calendar .pb--pair{padding-bottom:clamp(14rem,26vw,28rem);}

/* Project boundaries: keep only the entry and exit breathing room consistent. */
/* The opening media sits in the centre of its black stage on every project. */
main > .wrap + .pb{padding-block:60px;}
main > .wrap + .stage.dark > .stage__inner{padding-block:60px;}
main > .pb:has(+ .wrap .next){padding-bottom:60px;}
main > .stage.dark:has(+ .wrap .next) > .stage__inner{padding-bottom:60px;}
main > .stage.dark:has(+ .wrap .next) .gal{padding-bottom:0;}
/* Compensate the existing text and caption treatments at the exit boundary. */
.project--debris-magazine main > .pb:has(+ .wrap .next){padding-bottom:36px;}
.project--cached main > .pb:has(+ .wrap .next),
.project--debris-calendar main > .pb:has(+ .wrap .next),
.project--pity-party main > .pb:has(+ .wrap .next){padding-bottom:68px;}
.project--fbaup-gallery main > .stage.dark:has(+ .wrap .next) > .stage__inner,
.project--garfield main > .stage.dark:has(+ .wrap .next) > .stage__inner{padding-bottom:45px;}


/* two side by side, equal, one gutter apart. Both are upright frames of the
   same proportion, so they simply sit next to each other — nothing is cut. */
.pb--pair .pb__in{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--pgut);max-width:62rem;margin-inline:auto;align-items:start;}
/* the two must match exactly in width and height, so they fill one shared
   box. The box takes the average of their proportions, which splits the
   trimming between them instead of loading it all onto one. */
.pb--pair figure{background:var(--ink);overflow:hidden;}
.pb--pair img{width:100%;height:100%;object-fit:cover;object-position:50% 50%;}

/* three side by side, equal columns — nothing cropped, each keeps its own
   native proportion inside its cell. */
.pb--trio .pb__in{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));
  gap:var(--pgut);max-width:78rem;margin-inline:auto;align-items:start;}
.pb--trio img{width:100%;height:auto;object-fit:contain;}
@media (max-width:700px){
  .pb--trio .pb__in{grid-template-columns:1fr;}
}

/* the record and wrapped sleeve share a row without trimming either image */
.project--pity-party .pb--piecepair{
  min-height:100svh;
  display:grid;
  align-items:center;
  padding-block:clamp(4.5rem,8vw,7rem);
}
.project--pity-party .pb--piecepair .pb__in{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--pgut);max-width:72rem;margin-inline:auto;align-items:center;}
.project--pity-party .pb--piecepair figure:first-child{width:72%;justify-self:center;}
.project--pity-party .pb--piecepair img{width:100%;height:auto;object-fit:contain;}
/* visually equalise the gap to the following full-screen film while keeping
   both media blocks isolated when either one is centred in the viewport */
@media (min-width:641px){
  .project--pity-party .pb--piecepair + .pb--film{margin-top:-22svh;}
}

/* two columns, the right one dropped by a fixed fraction of the width so the
   offset scales with the layout. Each photograph keeps its own proportion —
   there is no shared cell to force them into, so nothing is cropped. */
.pb--stagger .pb__in{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:var(--pgut);max-width:52rem;margin-inline:auto;align-items:start;}
.qcol{display:flex;flex-direction:column;gap:var(--pgut);}
.qcol--a{margin-top:0;}          /* the left column starts at the top */
.qcol--b{margin-top:9%;}
.pb--stagger figure{margin:0;}
.pb--stagger img{width:100%;height:auto;}

/* the page grid, as one piece */
.pb--spreads .pb__in{max-width:86rem;margin-inline:auto;}
.pb--spreads img{width:100%;height:auto;}

@media (max-width:640px){
  .pb--pair .pb__in,.pb--stagger .pb__in{grid-template-columns:1fr;}
  .project--pity-party .pb--piecepair .pb__in,
  .project--pity-party .pb--vpair .pb__in{grid-template-columns:1fr;}
  .project--pity-party .pb--vpair .pb__in{width:92%;}
  .qcol--b{margin-top:0;}
  .pb--hero .pb__in{max-width:18rem;}
}


/* ------------------------------------------------------------
   CAROUSEL — one month at a time, with arrows either side.
   Every sheet occupies the same frame, so the block does not
   jump as you move between them.
   ------------------------------------------------------------ */
.pb--carousel .pb__in{max-width:40rem;margin-inline:auto;}
.carousel{position:relative;padding-inline:3rem;box-sizing:border-box;}
.ctrack{list-style:none;margin:0;padding:0;position:relative;
  aspect-ratio:828 / 1170;background:var(--ink);}
.cslide{position:absolute;inset:0;opacity:0;pointer-events:none;
  transition:opacity .4s var(--ease);}
.cslide.is-on{opacity:1;pointer-events:auto;}
.cslide img{width:100%;height:100%;object-fit:contain;cursor:zoom-in;}

.carrow{
  position:absolute;top:50%;transform:translateY(-50%);z-index:3;
  width:2.4rem;height:2.4rem;border:1px solid rgba(255,255,255,.3);
  border-radius:50%;padding:0;background:transparent;color:rgba(255,255,255,.75);
  display:grid;place-items:center;cursor:pointer;
  transition:background .25s var(--ease),border-color .25s var(--ease),
    color .25s var(--ease),transform .25s var(--ease);
}
.carrow:hover{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.6);color:#fff;}
.carrow:focus-visible{outline:2px solid var(--paper);outline-offset:3px;}
.carrow--prev{left:0;}
.carrow--next{right:0;}
.carrow:hover{transform:translateY(-50%) scale(1.06);}
.carrow svg{width:1rem;height:1rem;fill:none;stroke:currentColor;
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;}

.clabel{margin:.8rem 0 0;font-size:var(--fs-micro);letter-spacing:.16em;
  text-transform:uppercase;color:rgba(255,255,255,.65);
  display:flex;justify-content:space-between;gap:1rem;}
.clabel span{color:rgba(255,255,255,.4);font-variant-numeric:tabular-nums;}

.cdots{display:flex;flex-wrap:wrap;justify-content:center;gap:.35rem;margin-top:.6rem;}
.cdot{width:.5rem;height:.5rem;border-radius:50%;border:0;padding:0;cursor:pointer;
  background:rgba(255,255,255,.28);transition:background .25s var(--ease);}
.cdot:hover{background:rgba(255,255,255,.6);}
.cdot.is-on{background:rgba(255,255,255,.95);}
.cdot:focus-visible{outline:2px solid var(--paper);outline-offset:2px;}

/* the poster-showcase carousel (FBAUP Gallery etc.) is deliberately kept
   narrower than the stage on desktop, but that same 73% of an already
   narrow phone screen left almost nothing to see — nearly full width
   below the tablet breakpoint instead */
.carouselwrap{max-width:73%;margin-inline:auto;}
@media (max-width:760px){
  .carouselwrap{max-width:94%;}
}
@media (max-width:600px){
  .carousel{padding-inline:1.8rem;}
  .carrow{width:1.7rem;height:1.7rem;}
}
@media (prefers-reduced-motion:reduce){
  .cslide{transition:none;}
}

/* ------------------------------------------------------------
   LIGHTBOX — tap any carousel photo to see it full-screen, with
   its own close button and prev/next, independent of the strip
   behind it.
   ------------------------------------------------------------ */
.lightbox{
  position:fixed;inset:0;z-index:950;
  display:flex;align-items:center;justify-content:center;
  background:rgba(0,0,0,.95);
  padding:4rem 3.4rem;box-sizing:border-box;
  opacity:0;transition:opacity .3s var(--ease);
}
.lightbox.is-open{opacity:1;}
.lightbox[hidden]{display:none;}
.lightbox__img{max-width:100%;max-height:100%;object-fit:contain;display:block;}
.lightbox__close,.lightbox__nav{
  position:absolute;z-index:2;border:1px solid rgba(255,255,255,.3);
  border-radius:50%;padding:0;background:rgba(0,0,0,.35);color:#fff;
  display:grid;place-items:center;cursor:pointer;
  transition:background .25s var(--ease),border-color .25s var(--ease);
}
.lightbox__close:hover,.lightbox__nav:hover{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.6);}
.lightbox__close{top:1rem;right:1rem;width:2.6rem;height:2.6rem;}
.lightbox__nav{top:50%;transform:translateY(-50%);width:2.8rem;height:2.8rem;}
.lightbox__prev{left:1rem;}
.lightbox__next{right:1rem;}
.lightbox__close svg,.lightbox__nav svg{width:1.1rem;height:1.1rem;fill:none;stroke:currentColor;
  stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round;}
.lightbox__count{
  position:absolute;left:0;right:0;bottom:1rem;margin:0;text-align:center;
  font-size:var(--fs-micro);letter-spacing:.14em;text-transform:uppercase;
  color:rgba(255,255,255,.55);font-variant-numeric:tabular-nums;
}
html.lb-open{overflow:hidden;}
@media (max-width:600px){
  .lightbox{padding:5rem 1rem 3rem;}
  .lightbox__close{top:.7rem;right:.7rem;width:2.3rem;height:2.3rem;}
  .lightbox__nav{width:2.4rem;height:2.4rem;}
  .lightbox__prev{left:.5rem;}
  .lightbox__next{right:.5rem;}
}
@media (prefers-reduced-motion:reduce){
  .lightbox{transition:none;}
}

/* ============================================================
   ABOUT — black, white type, all of it on a single screen
   ============================================================ */
body.is-info{background:var(--ink);color:var(--paper);}

body.is-info .pagehead h1{color:var(--paper);}
body.is-info .pagehead p{color:#8F8C85;}
body.is-info :focus-visible{outline-color:var(--paper);}

.info__head{display:flex;align-items:baseline;justify-content:space-between;
  gap:1rem;flex-wrap:wrap;
  padding:clamp(1.6rem, 4vw, 2.8rem) 0 clamp(.7rem, 1.6vw, 1.2rem);}
.info__head h1{font-size:clamp(1.1rem, .9rem + .8vw, 1.6rem);font-weight:500;
  letter-spacing:-.03em;}
.info__head p{font-size:var(--fs-small);color:#8F8C85;font-style:italic;}

.info{
  display:grid;
  grid-template-columns:minmax(0,.62fr) minmax(0,1.15fr) minmax(0,1.05fr);
  gap:clamp(1rem,3.2vw,3rem);
  align-items:start;
  padding-bottom:clamp(1rem,3vw,2rem);
}
.info__portrait{background:#000;overflow:hidden;width:100%;
  aspect-ratio:1 / 1.06;}
.info__portrait img{width:100%;height:100%;object-fit:cover;object-position:50% 45%;}

.info__body{font-size:clamp(.95rem,.85rem + .42vw,1.22rem);line-height:1.34;
  letter-spacing:-.015em;color:var(--paper);}
.info__body p+p{margin-top:.7em;}

/* filled by column: left is what a visitor wants first (what she does,
   where she's based, how to reach her), right is supporting detail
   (education, tools, CV) */
.info__cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  grid-auto-flow:column;grid-template-rows:repeat(3,minmax(0,auto));
  gap:clamp(.8rem,1.8vw,1.4rem) clamp(1rem,2.4vw,2rem);}
.info__col h2{font-size:var(--fs-micro);letter-spacing:.16em;text-transform:uppercase;
  color:#8F8C85;font-weight:500;margin-bottom:.3rem;}
.info__col p{font-size:var(--fs-small);color:var(--paper);line-height:1.45;}
.info__col a{border-bottom:1px solid rgba(241,239,234,.35);
  transition:background .25s,color .25s,padding .25s,border-color .25s;}
.info__col a:hover,.info__col a:focus-visible{
  background:var(--paper);color:var(--ink);border-color:transparent;padding-inline:.2em;}

@media (max-width:900px){
  .info{grid-template-columns:minmax(0,.5fr) minmax(0,1fr);}
  .info__cols{grid-column:1 / -1;}
}
@media (max-width:600px){
  .info{grid-template-columns:1fr;gap:1.8rem;}
  .info__portrait{max-width:16rem;margin-bottom:.2rem;}
  .info__body{font-size:1.05rem;line-height:1.5;}
  /* one column, not two — each block gets room to breathe instead of
     being squeezed side by side */
  .info__cols{grid-template-columns:1fr;grid-auto-flow:row;gap:1.3rem;}
  .info__col h2{margin-bottom:.45rem;}
  .info__col p{font-size:.92rem;line-height:1.55;}
}

.pagehead{padding:clamp(1.6rem,4vw,2.8rem) 0 clamp(.8rem,2vw,1.4rem);
  display:flex;align-items:baseline;justify-content:space-between;gap:1rem;flex-wrap:wrap;}
.pagehead h1{font-size:clamp(1.1rem,.9rem + .8vw,1.6rem);font-weight:500;letter-spacing:-.03em;}
.pagehead p{font-size:var(--fs-small);color:var(--ash);max-width:34ch;font-style:italic;}

/* ---------- load glitch ---------- */
.glitch{position:fixed;inset:0;z-index:1200;pointer-events:none;
  backdrop-filter:invert(1);-webkit-backdrop-filter:invert(1);}
.glitch b{position:absolute;left:0;right:0;display:block;
  backdrop-filter:invert(1);-webkit-backdrop-filter:invert(1);}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;}
  .footer__track{animation:none;}
  body.is-home{overflow:auto;}
  html.js [data-reveal]{opacity:1;transform:none;}
  .reel__meta{opacity:1;transform:none;}
  .cursor{display:none;}
}
