@font-face{
  font-family: 'Isamo Sans Display';
  src: url('../fonts/isamo-sans-display.otf') format('opentype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

@font-face{
  font-family: 'Steps Mono';
  src: url('../fonts/Steps-Mono-Thin.otf') format('opentype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

@font-face{
  font-family: 'Snap-it Mono';
  src: url('../fonts/Snap-itmono-1.6-Regular.otf') format('opentype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

@font-face{
  font-family: 'Trispace Expanded';
  src: url('../fonts/Trispace_Expanded-Light.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
  font-display: swap;
}

:root{
  --bg: #ffffff;
  --fg: #111111;
  --muted: #777777;
  --accent: #111111;   /* set at runtime to the active image's dominant color */
  --header-h: 96px;
  --font: 'Trispace Expanded', 'Arial Narrow', Arial, sans-serif;
  --safe-v: 110px;  /* vertical clearance so images never touch header/footer text */
}

*{ box-sizing: border-box; }

html, body{
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  overflow: hidden;
  /* stop the browser's horizontal swipe = back/forward navigation gesture */
  overscroll-behavior-x: none;
  touch-action: pan-y;
  transition: background-color .4s ease, color .4s ease;
}

/* Dark mode — toggled by pinching the trackpad. */
body.dark{ --bg: #0a0a0a; --fg: #f0f0f0; }
body.dark .nav-arrow{ color: #f0f0f0; }

a{ color: inherit; text-decoration: none; }
button{ font-family: inherit; }

/* Header — full-screen centered overlay over the gallery, blended with the
   images underneath via mix-blend-mode: difference */
.site-header{
  position: fixed;
  inset: 0;
  height: 100%;
  z-index: 20;
  pointer-events: none;            /* let clicks pass through to the gallery */
  mix-blend-mode: difference;
}

.site-header a{ pointer-events: auto; }

.site-nav{
  position: relative;
  width: 100%;
  height: 100%;
  font-size: 15px;                 /* Steps Mono is wide/monospace — smaller to avoid overlap */
  letter-spacing: 0.02em;
  color: #ffffff;                  /* white source => clean difference invert */
}

.site-nav .nav-left,
.site-nav .nav-right{
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
}

.site-nav .nav-left{ left: 28px; }
.site-nav .nav-right{ right: 28px; }

/* lorenzo ferrara — top centre */
.site-nav .logo{
  position: absolute;
  top: 2%;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
}
/* "about" is all lowercase, so it optically sits lower than "bureauLL" (which
   has tall caps). Nudge it up so the two read as aligned. */
body.about .site-nav .logo{ transform: translate(-50%, -0.22em); }

/* Logo hover icons — two random SVGs appear HUGE (spanning the full width),
   centered on the page, with a tiny gap, fading + motion-blurring in
   sequentially. White (the difference blend inverts them against the gallery,
   like the rest of the header text). The common height is computed in JS so the
   pair fills the width while keeping both icons exactly the same height. */
.logo-icons{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  /* height set inline by JS */
}
.logo-icon{
  height: 100%;
  display: flex;
  align-items: center;
  opacity: 0;
  filter: blur(22px);
  transition: opacity .4s ease, filter .4s ease;
}
.logo-icon.in{ opacity: 1; filter: blur(0); }
.logo-icon svg{ height: 100%; width: auto; display: block; fill: #fff; }

/* project title — dead centre; clickable to enter description mode */
.site-nav .proj-title{
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  white-space: nowrap;
  text-align: center;
  pointer-events: auto;
  cursor: pointer;
}

/* description-mode side labels: year (left, was email) + client (right, was
   instagram). Hidden normally; faded in with body.info-open. */
.site-nav .info-side{
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  white-space: nowrap;
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;
}
.site-nav .info-year-side{ left: 28px; }
.site-nav .info-client-side{ right: 28px; }
.site-nav .info-client-side a.swap{ justify-items: end; }  /* anchor swap to the right edge */
body.info-open .site-nav .info-side{ opacity: 1; }
@media (max-width: 560px){
  .site-nav .info-year-side{ left: 14px; }
  .site-nav .info-client-side{ right: 14px; }
}

/* project page number — bottom centre */
.site-nav .page-num{
  position: absolute;
  bottom: 28px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
}

.site-nav a:hover{ opacity: .65; }

/* Label-on-hover swap: shows a short label ("email" / "instagram") that, on
   hover, fades+motion-blurs into the real value. Both states share one grid
   cell so the link sizes to the wider of the two. */
.site-nav a.swap{ display: inline-grid; opacity: 1; }
.site-nav a.swap:hover{ opacity: 1; }   /* override the generic dim */
.site-nav a.swap > span{
  grid-area: 1 / 1;
  transition: opacity .35s ease, filter .35s ease;
}
.site-nav a.swap .swap-label{ opacity: 1; filter: blur(0); }
.site-nav a.swap .swap-hover{ opacity: 0; filter: blur(8px); }
.site-nav a.swap:hover .swap-label{ opacity: 0; filter: blur(8px); }
.site-nav a.swap:hover .swap-hover{ opacity: 1; filter: blur(0); }
/* keep the right-hand link anchored to its right edge */
.site-nav .nav-right.swap{ justify-items: end; }

/* Project flash — brief, huge, full-width centered title shown when the
   PROJECT changes (not on media-within-project changes). Same difference
   blend as the rest of the header; driven entirely by JS (opacity via WAAPI). */
.proj-flash{
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  width: 100%;
  text-align: center;
  color: #ffffff;
  opacity: 0;
  font-size: clamp(36px, 9vw, 150px);
  letter-spacing: 0.01em;
  line-height: 1.05;
  white-space: normal;      /* wrap long titles onto multiple lines */
  overflow-wrap: break-word;
  padding: 0 16px;
}

/* Small window / mobile: keep EVERY label at the same 15px size (no shrinking).
   Instead of shrinking to avoid overlap, move the side links down to the bottom
   row so the crowded vertical-centre row holds only the (wrapping) title. */
@media (max-width: 700px){
  .site-nav .nav-left,
  .site-nav .nav-right,
  .site-nav .info-side{
    top: auto;
    bottom: 28px;
    transform: none;
  }
  .site-nav .nav-left,
  .site-nav .info-year-side{ left: 14px; }
  .site-nav .nav-right,
  .site-nav .info-client-side{ right: 14px; }

  /* centre title/heading wraps instead of overflowing or overlapping */
  .site-nav .proj-title{
    white-space: normal;
    max-width: calc(100vw - 32px);
    overflow-wrap: break-word;
  }

  /* keep the swap links compact — don't reserve the wider hover value's width,
     which would push the bottom row over the edge; the hover value overlays */
  .site-nav a.swap .swap-hover{ position: absolute; top: 0; }
  .site-nav .nav-right.swap .swap-hover{ right: 0; }
}

/* Opening splash — quick montage of random images + the double LL */
#splash{
  position: fixed;
  inset: 0;
  z-index: 60;                 /* above everything, incl. header (20) */
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  opacity: 1;
  transition: opacity .5s ease;
}
#splash.out{ opacity: 0; pointer-events: none; }
.splash-img{
  position: absolute;
  inset: 0;
  margin: auto;                   /* centre within the frame */
  width: auto;
  height: auto;
  max-width: calc(100vw - 32px);              /* same side margins as the site */
  max-height: calc(100vh - var(--safe-v) * 2); /* clear header/footer, like the gallery */
  object-fit: contain;            /* fit, not crop */
  display: block;
}
.splash-ll{
  position: relative;
  z-index: 1;
  display: flex;
  gap: 12px;
  align-items: center;
  justify-content: center;
  mix-blend-mode: difference;   /* white icons invert over the frame, like the header */
}
body.splashing{ overflow: hidden; }

/* Fullscreen viewer */
.viewer{
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

/* Overview — a grid of every project's media, shown when scrolling down. */
.overview{
  position: fixed;
  inset: 0;
  z-index: 16;                 /* over the gallery, under the header (20) */
  background: var(--bg);
  overflow: hidden;            /* no scroll — columns grow so all tiles fit */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--safe-v) 16px 40px;
  opacity: 0;
  filter: blur(30px);          /* fade + motion blur on open/close */
  pointer-events: none;
  transition: opacity .45s ease, filter .45s ease;
}
.overview.show{ opacity: 1; filter: blur(0); pointer-events: auto; }

/* sharp preview media, brought IN FRONT of the titles on hover */
.overview-media{
  position: absolute;
  inset: var(--safe-v) 16px;      /* same clearance/size as the gallery images */
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity .35s ease;
  pointer-events: none;           /* never steals hover from the titles */
  z-index: 2;                     /* above the list */
}
.overview-media.show{ opacity: 1; }
.overview-media img,
.overview-media video{
  max-width: 70vw;
  max-height: 26vh;               /* much smaller than the gallery — a small peek */
  width: auto;
  height: auto;
  object-fit: contain;            /* fit, not crop */
  display: block;
}

/* vertical, centred list of project titles */
.overview-list{
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  max-height: 100%;
}
.overview-title{
  appearance: none;
  background: none;
  border: 0;
  padding: .04em 0;
  margin: 0;
  width: 100%;                   /* full-width rows: no hover gaps between titles */
  font: inherit;
  font-size: 15px;               /* same size as the rest of the site */
  line-height: 1.6;
  color: var(--fg);              /* full black */
  text-align: center;
  cursor: pointer;
  transition: opacity .3s ease;
}
.overview-title:focus{ outline: none; }

/* hide gallery chrome that doesn't apply while the overview is open */
body.overview-open .site-nav .page-num,
body.overview-open .site-nav .proj-title,
body.overview-open .nav-arrow{ opacity: 0; pointer-events: none; }

/* Gallery stage — fills the screen; header overlays it */
.viewer-stage{
  position: absolute;
  top: var(--safe-v);
  left: 0;
  right: 0;
  bottom: var(--safe-v);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  user-select: none;
}

.viewer-stage img,
.viewer-stage video{
  max-width: 92vw;
  max-height: 100%;
  object-fit: contain;
  display: block;
}
/* blur-up: the tiny thumbnail shows blurred, then sharpens when the full-res
   image arrives (progressive loading for poor connections) */
.viewer-stage img{ transition: filter .45s ease; }
.viewer-stage img.lqip{ filter: blur(16px); }

@media (max-width: 560px){
  :root{ --safe-v: 80px; }
}

.nav-arrow{
  position: absolute;
  bottom: 28px;                    /* same baseline as the page number below */
  z-index: 15;
  padding: 0;
  border: none;
  background: none;
  color: #000;                     /* full black */
  font-family: var(--font);
  font-size: 15px;                 /* same size as the rest of the header text */
  line-height: 1;
  cursor: pointer;
}

.nav-arrow-left{ left: 28px; }
.nav-arrow-right{ right: 28px; }

@media (max-width: 560px){
  .nav-arrow{ font-size: 10px; }
  .nav-arrow-left{ left: 14px; }
  .nav-arrow-right{ right: 14px; }
}

/* Project info — revealed by scrolling down, with a fade + motion blur. The
   background goes fully SOLID (the gallery image disappears); the only thing
   kept from the header is the small centred title, which acts as the heading.
   Sits BELOW the header (z-index 18 < 20) so that small title stays on top. */
.project-info{
  position: fixed;
  inset: 0;
  z-index: 18;
  /* frosted glass: the gallery stays visible behind, blurred, with a light tint
     for readability (instead of being fully hidden). */
  background: color-mix(in srgb, var(--bg) 60%, transparent);
  -webkit-backdrop-filter: blur(28px);
  backdrop-filter: blur(28px);
  opacity: 0;
  filter: blur(40px);        /* strong motion blur on the gallery↔description transition */
  pointer-events: none;
  transition: opacity .6s ease, filter .6s ease;
}
.project-info.show{
  opacity: 1;
  filter: blur(0);
  pointer-events: auto;       /* click anywhere on it to dismiss */
  cursor: pointer;
}
/* description text block — top of the window, aligned with bureauLL, left
   aligned, spanning the full window width, same body size as everywhere. */
.info-inner{
  position: absolute;
  top: 2%;
  left: 28px;
  right: 28px;
  width: auto;
  text-align: left;
  color: var(--fg);
  font-size: 15px;            /* same body size as everywhere else */
  line-height: 1.2;
}
.info-title{ display: none; } /* the small header title is the heading now */
.info-meta{
  display: flex;
  gap: 1.2em;
  flex-wrap: wrap;
  font-size: 15px;
  opacity: .7;
  margin-bottom: 1em;
}
.info-desc{
  margin: 0;
  font-size: 15px;
  line-height: 1.2;
  white-space: pre-wrap;   /* preserve paragraph breaks (\n\n) */
  pointer-events: auto;    /* let the instagram links inside be clickable */
}
.info-desc a{ text-decoration: underline; text-underline-offset: 2px; }
.info-desc a:hover{ opacity: .65; }
@media (max-width: 560px){
  .info-inner{ left: 14px; right: 14px; }
}

/* In description mode keep ONLY the small title: hide the rest of the header
   and the nav arrows (fade them out). */
.site-nav .nav-left,
.site-nav .nav-right,
.site-nav .logo,
.site-nav .page-num,
.nav-arrow{ transition: opacity .35s ease; }
body.info-open .site-nav .nav-left,
body.info-open .site-nav .nav-right,
body.info-open .site-nav .logo,
body.info-open .site-nav .page-num,
body.info-open .nav-arrow{ opacity: 0; pointer-events: none; }

/* About page (toggled from the logo; reuses the dark moodboard background).
   Shown over the gallery, below the header so the centred "<3" stays on top. */
.about-page{
  position: fixed;
  inset: 0;
  z-index: 17;
  background: var(--bg);   /* opaque — fully covers the gallery behind it */
  color: var(--fg);
  opacity: 0;
  filter: blur(30px);
  pointer-events: none;    /* click-through while hidden */
  /* crossfade (show/hide) + smooth dark-mode colour change */
  transition: opacity .5s ease, filter .5s ease, background-color .4s ease, color .4s ease;
}
.about-page.show{ opacity: 1; filter: blur(0); pointer-events: auto; }

/* In about mode, hide email/instagram/page number/arrows; keep "<3" + logo. */
body.about .site-nav .nav-left,
body.about .site-nav .nav-right,
body.about .site-nav .page-num,
body.about .nav-arrow{ opacity: 0; pointer-events: none; }

/* id-format photos replacing email (left) and instagram (right). On hover the
   photo crossfades (fade + motion blur) to the person's name. */
.id-photo{
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 132px;
  height: 170px;                 /* ~35:45 ID ratio */
}
.id-left{ left: 28px; }
.id-right{ right: 28px; }
.id-photo .id-img,
.id-photo .id-name{
  position: absolute;
  inset: 0;
  transition: opacity .4s ease, filter .4s ease, color .4s ease;
}
.id-photo .id-img{
  background: #e8e8e8 center / cover no-repeat;
  opacity: 1;
  filter: blur(0);
}
.id-photo .id-name{
  display: flex;
  align-items: center;
  font-size: 15px;
  line-height: 1.2;
  color: var(--fg);
  opacity: 0;
  filter: blur(12px);
}
/* Léa's name hugs the left edge (outward); Lorenzo's hugs the right edge. */
.id-left .id-name{ justify-content: flex-start; text-align: left; }
.id-right .id-name{ justify-content: flex-end; text-align: right; }
.id-left .id-img{ background-image: url('../images/id-left.jpg?v=2'); }
.id-right .id-img{ background-image: url('../images/id-right.jpg'); }
.id-photo:hover .id-img{ opacity: 0; filter: blur(12px); }
.id-photo:hover .id-name{ opacity: 1; filter: blur(0); }

/* Contact — centered epigraph at the bottom. Sits ABOVE the description panel
   (z 19 > 18) so it stays visible/sharp in description mode. */
.about-footer{
  position: fixed;
  left: 0;
  right: 0;
  bottom: 28px;
  z-index: 19;
  text-align: center;
  white-space: pre-line;
  font-size: 15px;
  letter-spacing: 0.02em;   /* match the page-number tracking */
  line-height: normal;      /* match the page-number line-height (baseline aligns) */
  color: var(--fg);
  opacity: 0;
  pointer-events: none;
  transition: opacity .5s ease, color .4s ease;
}
body.about .about-footer{ opacity: 1; }

@media (max-width: 560px){
  .id-photo{ width: 92px; height: 118px; }
  .id-left{ left: 14px; }
  .id-right{ right: 14px; }
  .about-footer{ bottom: 14px; font-size: 12px; }
}

/* About page */

.about{
  max-width: 640px;
  margin: 0 auto;
  padding: calc(var(--header-h) + 40px) 24px 60px;
  font-size: 20px;
  line-height: 1.6;
}
