/* ==========================================================================
   Site — matches the Figma "Home" / "Project pages – Opened nav with
   breadcrumbs" frames (node 17:1978). Font, weight and letter-spacing are
   Kara's (tokens.css). The previous designs live in site-backups/.
   ========================================================================== */

:root {
  --m-s: 4px;  --m-m: 8px;  --m-l: 16px;  --m-xl: 24px;
  --br: 5px;
  --fs: 11px;  --lh: 14px;
  --d-fast: .24s; --d: .32s; --d-slow: .64s;
  --ease: cubic-bezier(.645, .045, .355, 1);
  --nav-w: 440px;
  --nav-w-open: 520px;   /* desktop: the menu widens to this when open */
  --nav-h: 40px;   /* two lines: the name, then the page */
  --nav-bg: rgb(244 244 244 / 0.7);
  --nav-blur: blur(20px);
  --nav-overlay-blur: blur(60px);   /* the open-menu overlay: much softer than the bar */
  --nav-text: #000;
  --nav-muted: rgb(0 0 0 / 0.45);
  --nav-line: rgb(0 0 0 / 0.06);
  --thumb-w: 134px;
  --thumb-h: 65px;
  --strip-bottom: 16px;   /* desktop: the thumbnail strip close to the bottom (phones: 8px) */
  --nav-top: 16px;        /* desktop: the nav close to the top (phones: 8px) */
}

*, *::before, *::after { box-sizing: border-box; }
html, body { width: 100%; height: 100%; margin: 0; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; scrollbar-width: none; }
html::-webkit-scrollbar { display: none; }
body {
  background: #fff;
  color: var(--color-text-primary);
  font-family: var(--font-family);
  font-weight: var(--font-weight);
  font-size: var(--fs);
  line-height: var(--lh);
  letter-spacing: var(--type-body-ls, -0.025em);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-synthesis: none;
}
h1, h2, h3, p, ul, ol, dl, dd, figure { margin: 0; padding: 0; font: inherit; }
ul, ol { list-style: none; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; letter-spacing: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
img, video { display: block; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
:focus { outline: none; }
:focus-visible { outline: 1px solid #fff; outline-offset: 2px; }

.site { animation: fade-in var(--d-slow) var(--ease) both; }
.site.is-leaving { opacity: 0; transition: opacity var(--d) var(--ease); }
@keyframes fade-in { from { opacity: 0; } }
.fade-media { opacity: 0; transition: opacity var(--d-slow) var(--ease); }
.fade-media.is-loaded { opacity: 1; }

/* ---- Nav (every page) ------------------------------------------------------
   A slim dark bar centred at the top: current project (Home) or the
   breadcrumb trail (other pages) on the left, ⋮ on the right. Opens downward
   into label / content rows — the site's About, Services, Clients, Awards,
   Contact and Selected work. Same colour everywhere. */
.nav { position: fixed; top: var(--nav-top); left: 50%; z-index: 10; display: flex; flex-direction: column; gap: 2px; width: var(--nav-w); max-width: calc(100vw - 2 * var(--m-m)); transform: translateX(-50%); color: var(--nav-text); }
/* the bar: page / project name on the left, ⋮ on the right, one black box */
.nav__top { display: flex; }
.nav__bar { border-radius: var(--br); background: var(--nav-bg); -webkit-backdrop-filter: var(--nav-blur); backdrop-filter: var(--nav-blur); }   /* frosted: see-through grey, page blurred behind */
/* open: the bar disappears into the overlay (only the dots stay, to close it) */
.nav__bar { transition: background-color var(--d) var(--ease); }
.nav.is-open .nav__bar { background-color: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; }
/* no background of its own: the colour comes from the page backdrop, so there is
   only one layer fading in and out */
.nav__body-box { border-radius: var(--br); background: transparent; }
.nav__bar { position: relative; flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center; align-items: stretch; gap: 1px; height: var(--nav-h); padding: 0 9px; }   /* the name on top, the page under it */
.nav__owner { position: relative; z-index: 1; align-self: flex-start; color: var(--nav-text); transition: opacity var(--d) var(--ease); }   /* Kara Sloane: back to the home page */
.nav.is-open .nav__owner { opacity: 0; pointer-events: none; }   /* open: fades with the page text */
@media (hover: hover) { .nav__owner:hover { opacity: .7; } }
.nav__crumbs { flex: none; min-width: 0; align-self: flex-start; display: flex; align-items: center; gap: 14px; overflow: hidden; white-space: nowrap; transition: opacity var(--d) var(--ease); }
/* the left half of the bar is the link (the whole half, not just the text) */
/* (the links are just their text; only the text and the dots are clickable) */
/* the nav text fades in on each page and out when leaving (carousel changes stay instant) */
.nav__crumbs.is-entering { animation: fade-in var(--d-slow) var(--ease) both; }
.nav.is-open .nav__crumbs { opacity: 0; pointer-events: none; }   /* open: the text fades away */
.nav__crumbs.is-leaving { opacity: 0; }
.nav__crumbs a { flex: none; color: var(--nav-text); transition: color var(--d-fast) var(--ease), opacity var(--d-fast) var(--ease); }
.nav__crumbs a.is-muted { color: var(--nav-muted); }   /* "Home" greyed out on project pages */
.nav__crumbs span { flex: none; color: var(--nav-text); cursor: default; }   /* the project name on its own page: not a link */
/* project pages: the text sits above the dropdown's tap area, so tapping the name does nothing */
.nav__crumbs:has(span) { position: relative; z-index: 1; flex: none; }
@media (hover: hover) { .nav__crumbs a:hover { opacity: .7; } .nav__crumbs a.is-muted:hover { color: var(--nav-text); opacity: 1; } }
/* the right half of the bar opens the dropdown; the dots sit at its far right */
.nav__toggle { position: absolute; top: 0; right: 0; width: 40px; height: 100%; display: flex; align-items: center; justify-content: flex-end; padding-right: 9px; padding-top: calc(var(--lh) + 1px); }   /* the dots sit level with the second line (the project name) */
.nav__dots { display: flex; flex-direction: row; gap: 2px;   /* side by side */ transition: gap var(--d-fast) var(--ease); }
.nav__dots i { width: 2px; height: 2px; border-radius: 50%; background: currentColor; }
.nav.is-open .nav__dots, .nav__toggle:hover .nav__dots { gap: 3.5px; }
/* the dropdown: its own box under the bar, fading in (with the page backdrop behind it) */
/* out of the layout (absolute), so while hidden it takes no space: otherwise the nav's
   invisible box would cover the page and block the carousel on phones */
.nav__body { position: absolute; top: calc(100% + 4px); left: 0; right: 0; opacity: 0; visibility: hidden; transition: opacity var(--d) var(--ease), visibility 0s linear var(--d); }
.nav.is-open .nav__body { opacity: 1; visibility: visible; transition: opacity var(--d) var(--ease); }
.nav__body-box { overflow: hidden; }
.nav__scroll { max-height: calc(100svh - 2 * var(--nav-top) - var(--nav-h) - 4px); overflow-y: auto; scrollbar-width: none; overscroll-behavior: contain; touch-action: pan-y; -webkit-overflow-scrolling: touch; }   /* a swipe in the menu scrolls the menu, never the page behind it */
.nav__scroll::-webkit-scrollbar { display: none; }

/* label / content rows — also used for the project info on project pages */
.rows { margin: 0 9px; border-top: 1px solid var(--nav-line); }   /* inset, so the lines line up with the text */
.row { display: grid; grid-template-columns: 18% 1fr; gap: var(--m-m); padding: 21px 0 21px; border-bottom: 1px solid var(--nav-line); }   /* sections close together, a grey line between them */
.row:last-child { border-bottom: 0; }
.row--gap { border-top: 1px solid var(--nav-line); }   /* grey, like the other lines */
.row__label { color: var(--nav-text); }
.row__content { min-width: 0; display: flex; flex-direction: column; gap: 10px; color: var(--nav-text); }   /* min-width: keeps the client roll inside the screen */
.row__content a { color: var(--nav-text); transition: opacity var(--d-fast) var(--ease); }   /* all text the same dark colour; hover fades it */
@media (hover: hover) { .row__content a:hover { opacity: .5; } }
.work-list { display: flex; flex-direction: column; gap: 2px; }   /* selected work: a little space between the names */
.nav__scroll > .rows:first-child { border-top: 0; }   /* no line above the first row, so nothing flashes in when the menu opens */

/* ---- Home: full-screen projects + equal-width thumbnail strip -------------- */
body.home { overflow: hidden; }
html:has(body.home) { overscroll-behavior: none; }
.slider { position: relative; overflow: hidden; width: 100vw; height: 100lvh; }
/* iOS Safari: taller than the screen so the page runs under its bars. Touch screens only:
   desktop Safari passes the same test, and there it pushed every background off-centre */
@supports (hanging-punctuation: first) and (font: -apple-system-body) and (-webkit-appearance: none) {
  @media (hover: none) and (pointer: coarse) {
    .slider { height: calc(320px + 100svh); }
    body.home #main { min-height: calc(320px + 100svh); }   /* tall enough for site.js to scroll it 160px straight away */
    body.home .nav-backdrop, body.home .gate-blur { min-height: calc(320px + 100svh); }   /* menu and password overlays: the same, behind both bars */
  }
}
/* phones: like the version that reached the top — only <body> blocks scrolling, the page itself
   keeps normal overscroll, so Safari still draws what runs past the screen, behind both bars */
@media (max-width: 767px) {
  html:has(body.home) { overscroll-behavior: auto; overscroll-behavior-x: contain; }
}
/* Chrome on phones: no drawing behind the toolbars, so exactly the visible screen —
   backgrounds stay centred and less zoomed in (class set in site.js) */
html.is-chrome-mobile .slider { height: 100svh; }
html.is-chrome-mobile body.home #main, html.is-chrome-mobile body.home .nav-backdrop, html.is-chrome-mobile body.home .gate-blur { min-height: 0; }   /* (not Safari's taller page: it made the page scrollable, shifting the carousel) */
/* chromePosition (content.js): where it crops, for Chrome on phones only */
html.is-chrome-mobile .slider__slide[data-cp] img, html.is-chrome-mobile .slider__slide[data-cp] video { object-position: var(--cp) !important; }
/* chromeZoom (content.js): a zoom from the bottom for Chrome on phones only */
/* chromeZoomOrigin (content.js): Chrome's own zoom point, where the phone one is set for Safari's taller carousel */
@media (max-width: 767px) { html.is-chrome-mobile .slider__slide[data-pz] img, html.is-chrome-mobile .slider__slide[data-pz] video { transform-origin: var(--pzo-c, var(--pzo, 50% 100%)); } }
html.is-chrome-mobile .slider__slide[data-cz] img, html.is-chrome-mobile .slider__slide[data-cz] video { transform: scale(var(--cz)); transform-origin: 50% 100%; }
.slider__slide { position: absolute; inset: 0; opacity: 0; }   /* switches instantly, no fade */
.slider__grain { position: absolute; inset: 0; z-index: 1; pointer-events: none; mix-blend-mode: overlay; background-size: 220px; background-image: url("data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27220%27 height=%27220%27%3E%3Cfilter id=%27g%27%3E%3CfeTurbulence type=%27fractalNoise%27 baseFrequency=%270.85%27 numOctaves=%272%27 stitchTiles=%27stitch%27/%3E%3CfeColorMatrix type=%27saturate%27 values=%270%27/%3E%3C/filter%3E%3Crect width=%27100%25%27 height=%27100%25%27 filter=%27url(%23g)%27/%3E%3C/svg%3E"); }   /* grain (content.js): fine colourless noise blended over the slide */
.slider__slide.is-active { opacity: 1; }
.slider__slide video { opacity: 0; transition: opacity var(--d) var(--ease); }   /* shows once it actually plays; until then the poster picture behind it (.slider__poster) */
.slider__slide video.is-playing { opacity: 1; }
.slider__canvas { position: absolute; inset: 0; width: 100%; height: 100%; }   /* a slide drawn through a canvas (content.js: canvas) */
.slider__slide img, .slider__slide video {
  position: absolute; inset: 0; width: 100%; height: 100%; max-width: none; object-fit: cover;
  object-position: var(--bg-pos, 50% 50%);
  transform: scale(var(--bg-zoom, 1)); transform-origin: var(--bg-origin, 50% 50%);
}
/* framed (content.js): not full screen — a small crop in the given shape (e.g. "4 / 5"),
   centred on a white page with lots of space around it */
.slider__slide[data-fr] { background: #fff; }
.slider__frame {
  position: absolute; top: 50svh; left: 50%; height: 64svh; aspect-ratio: var(--fr);
  overflow: hidden; transform: translate(-50%, -50%);
}
/* frameZoom: the picture zooms inside its box (the box stays the same size) */
.slider__frame img, .slider__frame video { transform: scale(var(--fz, 1)) !important; transform-origin: 50% 100%;   /* zooms from the bottom, so the bottom edge stays in view */ }
@media (max-width: 767px) {
  .slider__frame { height: auto; width: 60vw; }
}
/* its strip thumbnail: the same small crop on white */
.thumbs__item[data-fr] { position: relative; background: #fff; }
.thumbs__crop {
  position: absolute; top: 50%; left: 50%; height: 74%; aspect-ratio: var(--fr);
  overflow: hidden; transform: translate(-50%, -50%);
}
.thumbs__item .thumbs__crop img { width: 100%; height: 100%; object-fit: cover; transform: scale(var(--fz, 1)); transform-origin: 50% 100%; }
.thumbs { position: fixed; inset: 0; z-index: 3; cursor: pointer; touch-action: none; user-select: none; -webkit-user-select: none; }
/* home, with a mouse: the pointer over the carousel is a "View" label (site.js) instead of the arrow */
body.has-view-cursor .thumbs, body.has-view-cursor .thumbs * { cursor: none; }   /* incl. the strip links, so only "View" shows */
.view-cursor { position: fixed; top: 0; left: 0; z-index: 6; pointer-events: none; color: #fff; white-space: nowrap; opacity: 0; transition: opacity var(--d-fast) var(--ease); }
.view-cursor.is-on { opacity: 1; }
.thumbs.is-dragging { cursor: grabbing; }   /* (touch only now: no mouse dragging) */
.thumbs__container { position: absolute; left: 0; bottom: var(--strip-bottom); width: 100vw; height: var(--thumb-h); overflow: hidden; }
.thumbs__track { position: absolute; top: 0; left: 0; display: flex; gap: 3px; height: var(--thumb-h); will-change: transform; }
.thumbs__item { flex: none; width: var(--thumb-w); height: var(--thumb-h); overflow: hidden; border-radius: var(--br); background: #222; transition: background-color .3s ease-out; }   /* same corners as the nav */
.thumbs__item img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--d-fast) var(--ease), opacity .3s ease-out; }   /* hover fades in and out softly */
@media (hover: hover) { .thumbs__item:hover { background: #fff; } .thumbs__item:hover img { opacity: .88; } }   /* hover: a light white wash */

/* ---- Project pages (last round's grid, with the new nav on top) --------------
   White page, 2-column grid of rounded images with small gaps, then the
   details: title · intro + strategy · Agency / Role / Disciplines / Impact rows. */
/* desktop: full width, 8px around the page edges, the same as between the images */
.page { padding: calc(2 * var(--nav-top) + var(--nav-h)) 40px 32px; }   /* desktop: 40px at the sides, a little less at the bottom; the nav sits centred between the top of the page and the images (phones: 8px, below) */
.casestudy__gallery { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
.casestudy__block { position: relative; grid-column: span 2; }
.casestudy__block--half { grid-column: span 1; }
.casestudy__block--phone-only { display: none; }   /* phones only (shown in the phones section below) */
.casestudy__media { position: relative; overflow: hidden; border-radius: var(--br); background: #fff; aspect-ratio: 16 / 10; }   /* white while it loads: pictures fade in over the page white */
/* an item's own background (bg in content.js) and its shading / tint wait for the picture or
   poster and fade in with it (is-ready), so a background never shows on its own */
.casestudy__media[data-bg]::before { content: ""; position: absolute; inset: 0; background: var(--bgx); }
.casestudy__media > img, .casestudy__media > video { position: relative; }   /* above that background layer */
.casestudy__media > .casestudy__poster { position: absolute; inset: 0; }   /* a video's poster, under the video (site.js) */
.casestudy__media > video.fade-media { transition: none; }   /* the video appears straight over its poster the moment it plays, no fade */
.casestudy__media[data-bg]::before, .casestudy__media > span { opacity: 0; transition: opacity var(--d-slow) var(--ease); }
.casestudy__media.is-ready[data-bg]::before { opacity: 1; }
.casestudy__media.is-ready > span { opacity: var(--o, 1); }
.casestudy__block--half .casestudy__media { aspect-ratio: 8 / 10; }
.casestudy__shade { position: absolute; pointer-events: none; }   /* bgShade: see site.js */
.casestudy__overlay { position: absolute; inset: 0; background: #000; pointer-events: none; }   /* opacity set per item */
.casestudy__media img, .casestudy__media video { width: 100%; height: 100%; object-fit: cover; }
/* project info: the name in the left column, every section stacked in the right one
   (same spacing and lines as the dropdown rows) */
.casestudy__info { display: grid; grid-template-columns: 1fr 62%; gap: var(--m-m); margin-top: 48px; }
/* desktop: the project name on the left, the sections on the right */
.casestudy__title { grid-column: 1; grid-row: 1; padding: 22px 10px 22px; color: #000; }
.info-stack { grid-column: 2; }
.info-block { display: grid; grid-template-columns: 20% 1fr; gap: var(--m-m); margin: 0 10px; padding: 22px 0 22px; border-bottom: 1px solid rgb(0 0 0 / 0.06); }   /* heading left, text right */
.info-block:last-child { border-bottom: 0; }
.info-block__label { color: #000; }
.info-block__content { display: flex; flex-direction: column; gap: 10px; color: #000; }
.info-link { color: inherit; text-decoration: underline; text-decoration-color: #bdbdbd; text-underline-offset: 2px; text-decoration-skip-ink: none; transition: opacity var(--d-fast) var(--ease); }   /* e.g. the agency, linked to its site */
@media (hover: hover) { .info-link:hover { opacity: .6; } }
.casestudy__next { grid-column: 2; justify-self: end; display: block; margin: 0 10px; margin-top: 24px; padding: 22px 0 22px; color: #000; text-align: right; transition: opacity var(--d) var(--ease); }   /* one link, on the right: "Next: …" */
@media (hover: hover) { .casestudy__next:hover { opacity: .5; } }
.casestudy__next a { text-decoration: underline; text-underline-offset: 2px; text-decoration-skip-ink: none; }   /* one unbroken line, also under g, y, p */

/* ---- Desktop: backgrounds marked desktopZoom (content.js) zoom a little from the bottom, lifting the picture */
@media (min-width: 768px) {
  .casestudy__media[data-zd] img, .casestudy__media[data-zd] video { transform: scale(var(--zd)); transform-origin: var(--zo, 50% 50%); }   /* project images: per-image zoom (desktopZoom) */
  .slider__slide[data-dz] img, .slider__slide[data-dz] video { transform: scale(var(--dz)); transform-origin: var(--dzo, 50% 100%); }   /* from the bottom, or desktopZoomOrigin */
  /* the menu: the slim bar widens when it opens so the info has room, like the narrowed bar on phones */
  .nav { transition: width .45s var(--ease); }
  .nav.is-open { width: var(--nav-w-open); }
  .nav__body { top: calc(100% - 12px); }   /* desktop: the menu text starts higher, where the faded bar text was */
  .nav__scroll { max-height: calc(100svh - 2 * var(--nav-top) - var(--nav-h) + 12px); }
  /* opening: the bar widens first (the dots slide over), then the text fades in */
  .nav.is-open .nav__body { transition: opacity var(--d) var(--ease) .4s; }
  /* closing: the text fades out first, then the bar narrows */
  .nav.is-closing { transition-delay: var(--d); }
}


/* ---- Laptops (up to 16" MacBook width): smaller carousel thumbnails; big monitors keep the full size */
@media (min-width: 768px) and (max-width: 1800px) {
  :root { --thumb-w: 118px; --thumb-h: 57px; }
}

/* ---- Large wide screens (past laptop width): text 2px bigger */
@media (min-width: 1801px) {
  :root { --fs: 13px; --lh: 17px; --nav-w-open: 640px; --nav-h: 44px; }   /* the open menu wider; the bar a touch taller */
  .nav__bar { padding-left: 10px; }   /* a little more room around the bar text (not the dots) */
  .nav__toggle { padding-top: calc(var(--lh) + 2px); }   /* dots stay level with the second line */
  .row { grid-template-columns: 24% 1fr; }   /* menu: more room between each heading and its text */
  .nav__body { top: calc(100% + 12px); }   /* menu text lower */
  .nav__scroll { max-height: calc(100svh - 2 * var(--nav-top) - var(--nav-h) - 12px); }
  .page { padding-left: 120px; padding-right: 120px; padding-bottom: 96px; }   /* project pages: wider side margins, a little less at the bottom */
  .slider__slide[data-dz] img, .slider__slide[data-dz] video { transform-origin: var(--dzo-w, var(--dzo, 50% 100%)); }   /* home: a wide-screen zoom point (wideZoomOrigin in content.js) */
}

/* ---- Phones ------------------------------------------------------------------ */
@media (max-width: 767px) {
  .slider__slide[data-pp] img, .slider__slide[data-pp] video { object-position: var(--pp) !important; }   /* phones: per-background crop from content.js (phonePosition) */
  .slider__slide[data-pz] img, .slider__slide[data-pz] video { transform: scale(var(--pz)); transform-origin: var(--pzo, 50% 100%); }   /* phones: zoom from the bottom (phoneZoom), lifting the picture */
  .slider__slide[data-pc] img { object-fit: contain; transform: scale(var(--pz, 1)); transform-origin: var(--pzo, 50% 50%); }   /* phones: the whole picture fits (phoneContain), enlarged by phoneZoom from the centre, on the slide's bg colour */
  :root { --thumb-w: 86px; --thumb-h: 47px; --strip-bottom: 8px; }
  .nav { top: var(--m-m); width: calc(100vw - 2 * var(--m-m)); transition: width .45s var(--ease); }
  /* project pages: once scrolled, the bar narrows (back to full width at the top, or when the menu opens) */
  .nav.is-compact:not(.is-open) { width: calc(100vw - 2 * 47px); }
  /* opening from the narrowed bar: the bar widens first (the dots slide over), then the text simply fades in */
  .nav.is-compact.is-open .nav__body { transition: opacity var(--d) var(--ease) .4s; }
  /* closing: the text fades out first, then the bar narrows */
  .nav.is-closing { transition-delay: var(--d); }
  .nav__scroll { max-height: calc(100svh - var(--m-m) - var(--nav-h) - 8px); max-height: calc(100dvh - var(--m-m) - var(--nav-h) - 8px); padding-bottom: calc(env(safe-area-inset-bottom) + 40px); }   /* phones: the menu fills exactly the part of the screen you can see (dvh follows Safari's bars as they show and hide), so anything below scrolls into view and stays there */
  .row { grid-template-columns: 1fr; gap: 8px; padding: 17px 0 17px; }   /* phones: each heading above its text, "About:" */
  .row__label::after { content: ":"; }
  /* phones: edges line up with the nav */
  .page { padding: var(--m-m) var(--m-m) var(--m-l); }
  .casestudy__info { grid-template-columns: 24% 1fr; gap: 6px; }   /* like the dropdown on phones */
  .casestudy__gallery { gap: var(--m-m); }   /* phones: same space between images as at the page edges */
  .casestudy__block--half { grid-column: span 2; }   /* phones: side-by-side images stack, full width */
  .casestudy__block--phone-pair { grid-column: span 1; }   /* phones: this pair stays side by side (phonePair) */
  .casestudy__block--phone-tall .casestudy__media { aspect-ratio: 8 / 10; }   /* phones: as tall as those stacked images */
  .casestudy__block--phone-wide .casestudy__media { aspect-ratio: 16 / 10; }   /* phones: side-by-side images that stack as wide ones instead of tall */
  .casestudy__block--phone-only { display: block; }
  .casestudy__block--desktop-only { display: none; }   /* desktop only (desktopOnly in content.js) */
  .casestudy__media[data-pp] img, .casestudy__media[data-pp] video { object-position: var(--pp) !important; }   /* phones: per-image crop (phonePosition) */
  .casestudy__media[data-zp] img, .casestudy__media[data-zp] video { transform: scale(var(--zp)); transform-origin: var(--zop, var(--zo, 50% 50%)); }   /* phones: per-image zoom (phoneZoom) */
  .casestudy__block--phone-frame .casestudy__media { aspect-ratio: 8 / 10; background: var(--frame); }   /* phones: tall box in the video's own grey... */
  .casestudy__block--phone-frame .casestudy__media img, .casestudy__block--phone-frame .casestudy__media video { object-fit: contain; }   /* ...with the whole picture inside, not zoomed */
  /* phoneFade: the frame colour fades in over the top and bottom edges of the picture */
  .casestudy__media[data-pf]::after { content: ""; position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(to bottom, var(--frame) 0, var(--frame) var(--fe), transparent calc(var(--fe) + 12%), transparent calc(100% - var(--fe) - 12%), var(--frame) calc(100% - var(--fe)), var(--frame) 100%); }
  /* phones: carousel thumbnails a little smaller and closer */
  .thumbs__track { gap: 3px; }
  /* phones: dropdown content starts higher (the bar text fades out when it opens) */
  /* phones: the menu's scroll area runs from the very top of the screen to the bottom, so its text
     scrolls all the way up; the padding keeps it starting just under the bar, as before. The bar
     (faded out while open) lets touches through to it; only the ⋮ button stays on top. */
  .nav__body { top: calc(-1 * var(--m-m)); }
  .nav__scroll { padding-top: calc(var(--m-m) + var(--nav-h) + 2px); }
  .nav.is-open .nav__scroll { max-height: 100svh; max-height: 100dvh; }
  .nav__top { position: relative; z-index: 2; }
  .nav.is-open .nav__top { pointer-events: none; }
  .nav.is-open .nav__toggle { pointer-events: auto; }
  .nav__scroll .row { padding-right: 27px; }   /* the text stays clear of the ⋮ button as it scrolls past; the lines still run to the edge */
  .nav__scroll > .rows:first-child > .row:first-child { padding-top: 0; }   /* (same spot as before: the row's top padding moved into the gap above) */
  /* phones: project images start below the nav; the info stacks in one column */
  .page { padding-top: calc(var(--m-m) + var(--nav-h) + var(--m-m)); }
  /* room under the "Next" link, on iPhone Safari only (class set in site.js): it treats a tap
     near the very bottom of the screen as "show the toolbar", so there the link sits above
     that strip and opens on the first tap; other browsers keep the small gap */
  html.is-ios-safari .page { padding-bottom: calc(80px + env(safe-area-inset-bottom)); }
  .casestudy__info { grid-template-columns: 1fr; gap: 0; }
  .info-stack { grid-column: 1; }
  .casestudy__title { margin: 0 10px 4px; padding: 30px 0 10px; border-bottom: 2px solid rgb(0 0 0 / 0.06); }   /* phones: the project name as its own section, a grey line below it (like the others, 1px thicker) */
  .info-block { grid-template-columns: 1fr; gap: 8px; padding: 18px 0 18px; }   /* phones: each heading above its text, "About:", like the dropdown */
  .info-block__label::after { content: ":"; }
  .casestudy__next { margin-top: 10px; padding: 18px 0 18px; }   /* phones: a little closer to the info above */
  .casestudy__info { margin-top: 4px; }
  .casestudy__next { grid-column: 1; justify-self: start; text-align: left; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 1ms !important; transition-duration: 1ms !important; }
}

/* ---- Clients: a horizontal credits roll inside the nav ------------------------ */
.marquee { width: 100%; overflow: hidden; }   /* no edge fade */
.clients-roll { display: none; }   /* clients: the list, except on standard laptops (below) */
@media (min-width: 768px) and (max-width: 1800px) {
  .clients-roll { display: block; }
  .clients-list { display: none; }
  .row { padding: 16px 0 16px; }   /* tighter, so the whole menu fits on a laptop screen */
  .row__content { gap: 8px; }
}
.marquee__track { display: flex; width: max-content; will-change: transform; }   /* moved by site.js */
.marquee__track ul { display: flex; gap: 18px; padding-right: 18px; white-space: nowrap; }

/* ---- Carousel: white stroke framing the selected (centred) thumbnail ---------- */
.thumbs__frame {
  position: absolute;
  left: 50%;
  bottom: calc(var(--strip-bottom) - 1.5px);
  width: calc(var(--thumb-w) + 3px);     /* the 1.5px stroke sits right against the image */
  height: calc(var(--thumb-h) + 3px);
  transform: translateX(-50%);
  border: 1.5px solid #d6d6d6;
  border-radius: calc(var(--br) + 1.5px);   /* the thumbnail corner plus the stroke */
  pointer-events: none;
}

/* ---- Open nav: the whole page behind it goes black ---------------------------- */
/* part of the page (not fixed) and as tall as it, set by site.js, so on phones it also
   runs under Safari's top and bottom bars and fades across the whole screen */
.nav-backdrop { position: absolute; top: 0; left: 0; width: 100%; height: var(--doc-h, 100%); min-height: 100%; z-index: 9; background: #fff; -webkit-backdrop-filter: var(--nav-overlay-blur); backdrop-filter: var(--nav-overlay-blur); opacity: 0; visibility: hidden; transition: opacity var(--d) var(--ease), visibility 0s linear var(--d); }
.nav-backdrop.is-on { opacity: 1; visibility: visible; transition: opacity var(--d) var(--ease); }

/* ---- Carousel: a line on a track -----------------------------------------------------
   The thumbnail strip is still there (invisible) so dragging, swiping and scrolling
   work as before; along the bottom, a see-through grey track across the screen with a
   short white line that travels along it with the pictures (site.js: indicateAt). */
.thumbs__container, .thumbs__frame { opacity: 0; }
.ind-bar { position: fixed; overflow: hidden; left: 50%; bottom: 24px; z-index: 4; width: 240px; height: 3px; border-radius: 2px; background: var(--nav-bg); -webkit-backdrop-filter: var(--nav-blur); backdrop-filter: var(--nav-blur); transform: translateX(-50%); pointer-events: none; }   /* centred, not the full width */
.ind__dot { position: absolute; top: 0; left: 0; height: 100%; border-radius: 2px; background: #555; will-change: transform; }   /* dark grey, on the nav's frosted grey */
@media (max-width: 767px) { .ind-bar { width: 160px; bottom: 20px; } }

/* ---- Password modal on project pages (mountGate in site.js): over everything, nav included, the page blurred beneath */
html.is-gated:not(:has(body.home)), html.is-gated body { overflow: hidden; }   /* the page underneath can't scroll; on the home page only <body> (already locked), so the carousel keeps its place under Safari's bars */
html.is-gated .view-cursor { display: none; }   /* home: no "View" label over the modal */
/* the blur: page content from the very top, as tall as the page (site.js), so on iPhone Safari it
   also runs behind the address and tool bars, end to end (pinned layers stop at the bars) */
.gate-blur { position: absolute; top: 0; left: 0; z-index: 19; width: 100%; min-height: 100%; background: rgb(255 255 255 / 0.6); -webkit-backdrop-filter: blur(28px); backdrop-filter: blur(28px); transition: opacity .4s var(--ease); }
.gate-blur.is-leaving { opacity: 0; }
/* the box: pinned to the screen and centred in what you can see */
.gate { position: fixed; inset: 0; z-index: 20; display: grid; place-items: center; padding: 0 16px; transition: opacity .4s var(--ease); }
.gate.is-leaving { opacity: 0; pointer-events: none; }
.gate__box { position: relative; width: min(420px, 100%); padding: 44px 24px 12px; border-radius: var(--br); background: #fff; }   /* white box, its content as before */
.gate__close { position: absolute; top: 6px; right: 6px; display: grid; place-items: center; width: 28px; height: 28px; color: #000; }
.gate__text { padding-right: 24px; }   /* clear of the X */
.gate__text { color: #000; margin-bottom: 22px; }
.gate__text a { color: inherit; transition: opacity var(--d-fast) var(--ease); }
@media (hover: hover) { .gate__text a:hover { opacity: .5; } }   /* same hover as the links in the menu */
.gate__field { display: flex; align-items: center; height: 31px; border-radius: var(--br); background: rgb(244 244 244); }
.gate__input { flex: 1 1 auto; min-width: 0; height: 100%; padding: 0 12px; border: 0; background: none; font: inherit; letter-spacing: inherit; color: #000; outline: none; }
.gate__input::placeholder { color: #858585; opacity: 1; }
.gate__go { flex: none; width: 34px; height: 100%; color: #000; }
.gate__error { height: 1.2em; line-height: 1.2em; margin-top: 8px; font-size: .85em; color: #858585; }   /* "Incorrect password", a little smaller than the text */
.gate__form.is-wrong .gate__field { animation: gate-shake .35s var(--ease); }
@keyframes gate-shake { 20% { transform: translateX(-5px); } 45% { transform: translateX(4px); } 70% { transform: translateX(-2px); } 100% { transform: none; } }
@media (max-width: 767px) {
  .gate__field { height: 40px; }
  .gate__box { padding: 40px 16px 10px; }
  .gate__error { font-size: 9px; }   /* phones: "Incorrect password" a little smaller */
  .gate__text { padding-right: 0; }   /* phones: the short first line is already clear of the X, so the email line gets the full width */
  .gate__close { top: 4px; right: 4px; }
}
@media (min-width: 1801px) {
  .gate__box { width: min(calc(28em + 72px), 100%); }   /* wide screens: the box grows with the text, so the email stays on its line */
}
