/* Kuba Czarnotta — portfolio. Values come from the Framer project's color styles and text styles. */

:root {
  --bg: rgb(15, 14, 8);
  --beige: rgb(230, 228, 219);
  --green: rgb(12, 233, 100);
  --gray: rgb(92, 107, 115);

  --serif: "Instrument Serif", "Times New Roman", serif;
  --sans: "DM Sans", system-ui, -apple-system, sans-serif;

  --content: 90%;
  --content-max: 1152px;
  --nav-h: 64px;
  --footer-h: 600px;
  /* One motion rhythm for the whole site */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --t-fast: 200ms;   /* hover colour, glow */
  --t-ui: 450ms;     /* labels, buttons, menus */
  --t-slow: 800ms;   /* photos, page changes */
  --t-hover: 380ms;     /* hover in: slow enough to feel elegant */
  --t-hover-out: 300ms; /* hover out: a little quicker than in */
  --t-press: 160ms;     /* press feedback */

  /* The footer's green gradient and its grain (also used by the phone menu) */
  --brand-gradient: linear-gradient(125deg, rgb(148, 148, 142) 0%, rgb(136, 188, 160) 28%, rgb(80, 222, 146) 48%, rgb(10, 246, 112) 68%, rgb(0, 255, 84) 88%);
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");

  /* Type scale: one display size for page titles, the rest stays as in Framer */
  --display: clamp(64px, 9vw, 136px);
  --display-s: clamp(44px, 6vw, 88px);

  /* 1% of the screen height; "small" viewport where supported, so iOS bars don't make sections jump */
  --vh: 1vh;
}
@supports (height: 1svh) { :root { --vh: 1svh; } }

::selection { background: var(--green); color: var(--bg); }

.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

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

html { -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: 100%; scroll-behavior: smooth; background: var(--bg); }

body {
  margin: 0;
  background: var(--bg);
  color: var(--beige);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip; /* clip, not hidden: "hidden" turns body into a scroll box when the menu locks scrolling, and pinned parts jump */
}

img { display: block; max-width: 100%; height: auto; }
a, button, .ph, .card, .video { touch-action: manipulation; }
/* press feedback on touch for links that have no other (the blue flash is gone) */
.roll:active, .tlink:active, a.ph:active, .nav__panel a:active, .nav__toggle:active, .post__next:active { opacity: 0.6; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, p { margin: 0; font-weight: 400; }

.serif { font-family: var(--serif); font-weight: 400; line-height: 1.2; }
.t-56 { font-size: 56px; letter-spacing: -2.1px; }
.t-50 { font-size: 50px; letter-spacing: -2.1px; }
.t-48 { font-size: 48px; }
.t-28 { font-size: 28px; }
.t-display { font-size: var(--display); letter-spacing: -0.03em; line-height: 0.92; }
.green { color: var(--green); }

.wrap { width: var(--content); max-width: var(--content-max); margin-inline: auto; }

.skip {
  position: absolute; left: 16px; top: -60px; z-index: 100;
  padding: 8px 16px; background: var(--green); color: var(--bg); border-radius: 64px;
}
.skip:focus { top: 16px; }

:focus-visible { outline: 2px solid var(--green); outline-offset: 4px; }

/* ---------- Motion ---------- */
/* Page changes: one calm step. The old page fades out quickly, then the new one fades in.
   Nothing else gets its own layer, so nothing moves on its own. */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: page-out var(--t-fast) var(--ease) both; }
::view-transition-new(root) { animation: page-in var(--t-ui) var(--ease) 120ms both; }
@keyframes page-out { to { opacity: 0; } }
@keyframes page-in { from { opacity: 0; } }
.nav { view-transition-name: nav; }
/* With the phone menu open, the bar (which contains the menu) fades with the page instead of standing still */
.nav.is-open { view-transition-name: none; }
/* Closing without animation (coming back to a page that was left with the menu open) */
.nav.no-anim .nav__panel, .nav.no-anim .nav__inner, .nav.no-anim .nav__scrim, .nav.no-anim .nav__toggle span { transition: none !important; }
::view-transition-group(nav),
::view-transition-old(nav),
::view-transition-new(nav) { animation: none; }

/* Photos fade in over their own average colour instead of popping in. */
.js img[data-fade] { opacity: 0; transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease); }
.js img[data-fade].is-loaded { opacity: 1; }

/* Section headings rise in once, the first time they scroll into view. */
.js main h2,
.js .post__next { opacity: 0; transform: translateY(8px); transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease); }
.js main h2.is-in,
.js .post__next.is-in { opacity: 1; transform: none; }

/* Safety net: main.js adds .js-ready when it runs. Without it, nothing stays hidden. */
@keyframes show-anyway { to { opacity: 1; transform: none; visibility: visible; } }
@keyframes hide-anyway { to { opacity: 0; visibility: hidden; } }
.js:not(.js-ready) img[data-fade],
.js:not(.js-ready) main h2,
.js:not(.js-ready) .post__next,
.js:not(.js-ready) .grid,
.js:not(.js-ready) .footer { animation: show-anyway 0s 2.5s forwards; }
.js:not(.js-ready) .collage .ph { animation: show-anyway 0s 2.5s forwards; }
.js:not(.js-ready) .preloader { animation: hide-anyway 0s 2.5s forwards; }

/* ---------- Page layers: content scrolls over a fixed footer ---------- */
.page { position: relative; z-index: 1; background: var(--bg); }
.footer-spacer { height: var(--footer-h); pointer-events: none; }

/* ---------- Navigation ---------- */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 20; pointer-events: none; /* only its links/buttons take taps */
  height: var(--nav-h);
  display: flex; align-items: center; justify-content: center;
}
.nav__links {
  width: var(--content);
  display: flex; justify-content: space-between; align-items: center; gap: 20px;
  list-style: none; margin: 0; padding: 0;
}
.nav > nav { display: contents; }
.nav a, .nav button, .nav__panel { pointer-events: auto; }
.nav__toggle { display: none; }
.nav__panel,
.nav__scrim { display: none; }

/* Rolling label with underline — Framer "Button/Filter Link" */
.roll {
  position: relative; display: inline-flex; flex-direction: column;
  font-size: 15px; line-height: 20px; color: var(--beige);
  background: none; border: 0; padding: 12px 0; cursor: pointer; font-family: inherit;
}
.roll__label { display: block; height: 20px; overflow: hidden; }
.roll__label > span {
  display: block; height: 20px; white-space: nowrap;
  transition: transform var(--t-hover-out) var(--ease), opacity var(--t-hover-out) var(--ease);
}
.roll__label > span:first-child { opacity: 0.8; }
.roll::after {
  content: ""; height: 1px; background: var(--beige);
  transform: scaleX(0); transform-origin: right;
  transition: transform var(--t-hover-out) var(--ease);
}
.roll:focus-visible .roll__label > span { transform: translateY(-20px); transition-duration: var(--t-hover); }
.roll:focus-visible::after,
.roll[aria-pressed="true"]::after { transform: scaleX(1); transform-origin: left; }
.roll--16 { font-size: 16px; }
.roll[aria-pressed="true"] .roll__label > span:first-child { opacity: 1; }
.roll__n { margin-left: 6px; font-size: 12px; line-height: 1; opacity: 0.5; }
@media (max-width: 480px) { .filters .roll__n { display: none; } } /* four filters stay on one row on a phone; the count is still in each aria-label */

/* ---------- Pill button — Framer "Button Icon" ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 16px 32px;
  border: 1px solid currentColor; border-radius: 64px;
  font-family: var(--sans); font-size: 18px; font-weight: 500; line-height: 1.4;
  white-space: nowrap;
  transition: gap var(--t-hover-out) var(--ease), box-shadow var(--t-hover-out) var(--ease), transform var(--t-press) var(--ease);
}
.btn svg { width: 14px; height: 14px; flex: none; transition: opacity var(--t-fast) var(--ease), transform var(--t-hover-out) var(--ease); }
.btn:focus-visible { transition-duration: var(--t-hover), var(--t-hover), var(--t-press); }

/* Press feedback: anything you click gives a little */
.btn:active,
.video:active { transform: scale(0.97); }
.video { transition: transform var(--t-press) var(--ease); }
.btn--primary { color: var(--green); }
.btn--secondary { color: var(--bg); }
.btn--tertiary { color: var(--beige); }
.btn--primary svg,
.btn--secondary svg { opacity: 0; width: 0; transform: translateX(-6px); }
.btn:focus-visible { gap: 16px; }
.btn--primary:focus-visible svg,
.btn--secondary:focus-visible svg { opacity: 1; width: 14px; transform: none; }
.btn--tertiary svg { width: 16px; height: 16px; }
.btn__label { transition: filter var(--t-fast) var(--ease), opacity var(--t-fast) var(--ease); }
.btn__label.is-swapping { filter: blur(2px); opacity: 0.3; }
/* Framer's hover glow */
.btn--primary:focus-visible { box-shadow: 0 0 20px -3px var(--green); }
.btn--tertiary:focus-visible { box-shadow: 0 0 20px -3px var(--beige); }
.btn--secondary:focus-visible { box-shadow: 0 0 20px -3px rgba(15, 14, 8, 0.6); }

/* Hover effects only where there is a mouse, so nothing "sticks" after a tap.
   Hover in takes --t-hover; leaving falls back to the quicker --t-hover-out. */
@media (hover: hover) and (pointer: fine) {
  .roll:hover .roll__label > span { transform: translateY(-20px); transition-duration: var(--t-hover); }
  .roll:hover::after { transform: scaleX(1); transform-origin: left; transition-duration: var(--t-hover); }
  .btn:hover { gap: 16px; transition-duration: var(--t-hover), var(--t-hover), var(--t-press); }
  .btn:hover svg { transition-duration: var(--t-fast), var(--t-hover); }
  .btn--primary:hover svg,
  .btn--secondary:hover svg { opacity: 1; width: 14px; transform: none; }
  .btn--tertiary:hover svg { transform: translateX(-4px); }
  .btn--primary:hover { box-shadow: 0 0 20px -3px var(--green); }
  .btn--tertiary:hover { box-shadow: 0 0 20px -3px var(--beige); }
  .btn--secondary:hover { box-shadow: 0 0 20px -3px rgba(15, 14, 8, 0.6); }
  .tlink:hover .tlink__in span { transform: translateY(-22px); transition-duration: var(--t-hover); }
  .ph:hover img { transform: scale(1.03); }
  .post__next:hover .post__next-img img { transform: scale(1.04); }
  .post__next:hover .post__next-title { color: var(--green); }
  .video:hover img { transform: scale(1.02); }
  .video:hover .video__play { box-shadow: 0 0 20px -3px var(--green); }
  .ticker:hover .ticker__track { animation-play-state: paused; }
}


/* ---------- Footer ---------- */
.footer {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 0;
  height: var(--footer-h);
  display: flex; flex-direction: column; justify-content: flex-end;
  overflow: hidden; color: var(--bg);
  background: var(--brand-gradient);
}
.footer::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: var(--grain);
  mix-blend-mode: multiply; opacity: 0.5;
}
.footer > * { position: relative; }
/* The footer waits under the page. Phones skip painting parts of the page during a fast
   scroll, and it would show through those gaps — so it stays hidden until the end of the
   page is about one screen away (main.js adds .is-near). */
.js .footer:not(.is-near) { visibility: hidden; }
.footer__body {
  flex: 1; width: var(--content); max-width: var(--content-max); margin-inline: auto;
  display: flex; flex-direction: column; justify-content: space-around;
}
.footer__cta { display: flex; justify-content: space-between; align-items: center; gap: 24px; }
.footer__links {
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  padding: 15px 0; list-style: none; margin: 0;
  border-top: 1px solid rgba(15, 14, 8, 0.18);
}
.footer__copy { font-size: 14px; font-weight: 500; opacity: 0.75; }
.footer__name {
  font-family: var(--serif); line-height: 0.8; white-space: nowrap;
  font-size: 19.4vw; width: max-content; margin: 0 auto -0.04em;
}
.footer--contact { --footer-h: 450px; }

/* Text link with rolling hover — Framer "Text Link ani" */
.tlink { display: inline-block; padding: 11px 0; font-size: 16px; font-weight: 500; line-height: 22px; }
.tlink__in { display: block; height: 22px; overflow: hidden; }
.tlink__in span { display: block; transition: transform var(--t-hover-out) var(--ease); }
.tlink__in span + span { opacity: 0.7; }
.tlink:focus-visible .tlink__in span { transform: translateY(-22px); }

/* ---------- Preloader ---------- */
.preloader {
  position: fixed; inset: 0; z-index: 50; background: var(--bg);
  display: flex; align-items: center; justify-content: center;
  transition: transform var(--t-slow) var(--ease) 0.1s;
}
.preloader.is-done { transform: translateY(-100%); }
.preloader.is-gone { display: none; }
.preloader__name {
  font-size: 100px; letter-spacing: -2.1px;
  opacity: 0; transform: translateY(12px);
  animation: name-in var(--t-ui) var(--ease) 80ms forwards;
}
@keyframes name-in { to { opacity: 1; transform: none; } }
/* Framer's three photos, revealed one after another (~1 s in all) */
.preloader img {
  position: absolute; object-fit: cover;
  clip-path: inset(100% 0 0 0);
}
/* the reveal starts once the photos are loaded */
.preloader.is-ready img { animation: photo-in var(--t-ui) var(--ease) forwards; }
.preloader img:nth-of-type(1) { width: 233px; height: 299px; left: 7.7%; bottom: 13%; animation-delay: 150ms; }
.preloader img:nth-of-type(2) { width: 269px; height: 167px; right: 19%; top: 21%; animation-delay: 300ms; }
.preloader img:nth-of-type(3) { width: 192px; height: 235px; right: 13%; bottom: 8%; animation-delay: 450ms; }
.preloader__name { position: relative; z-index: 2; }
@keyframes photo-in { to { clip-path: inset(0 0 0 0); } }
html:not(.js) .preloader,
.seen .preloader { display: none; }
html:not(.seen) body:has(.preloader:not(.is-done):not(.is-gone)) .nav { visibility: hidden; }
.js:not(.js-ready) .nav { animation: show-anyway 0s 2.5s forwards; }

/* ---------- Home ---------- */
.hero { position: relative; }
.hero__sticky {
  position: sticky; top: 0; z-index: 3; height: calc(100 * var(--vh));
  display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 60px;
  padding-bottom: 100px; pointer-events: none;
}
.hero__sticky > * { width: var(--content); max-width: 1280px; }
.collage .ph { position: relative; z-index: 1; display: block; overflow: hidden; }
/* on short screens a photo shrinks so it is always seen whole */
.collage .ph { max-width: calc((calc(100 * var(--vh)) - 96px) * var(--ar, 0.8)); }
/* Home photos appear as they scroll in: from transparent, rising 50px into place */
.js .collage .ph {
  opacity: 0; transform: translateY(50px);
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
.js .collage .ph.is-in { opacity: 1; transform: none; }
/* every photo frame clips its own zoom: the photo grows inside, the frame and the gaps stay put */
.ph { display: block; overflow: hidden; }
.ph img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--t-slow) var(--ease); }
.hero__intro {
  font-size: clamp(26px, 3.4vw, 46px); line-height: 1.12; letter-spacing: -0.01em;
  transition: opacity var(--t-fast) linear;
}
/* same left edge as the name; lines kept to ~40 characters */
.hero__sticky > .hero__intro { width: var(--content); padding-right: max(0px, calc(90vw - 40ch)); }

/* Collage: an editorial cascade on a 12-column grid. Each photo has its own cells, so photos
   can never overlap, whatever the screen. The "random" feel comes from the mix of sizes and
   from each photo's drop inside its row (margin-top, in vw so it scales with the photos). */
.collage {
  width: var(--content); max-width: 1280px; margin-inline: auto;
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: 2vw; row-gap: 9vw; align-items: start;
}
/* hero: photos rise over the pinned name, the first one peeking at the bottom of the first screen */
.collage--hero { margin-top: calc(-18 * var(--vh)); padding-bottom: 9vw; }
.collage--gallery { margin-top: 0; margin-bottom: 120px; }

.c1 { grid-row: 1; grid-column: 2 / span 6; }
.c2 { grid-row: 1; grid-column: 9 / span 4; margin-top: 26vw; }
.c3 { grid-row: 2; grid-column: 5 / span 4; }

.g1 { grid-row: 1; grid-column: 8 / span 4; }
.g2 { grid-row: 1; grid-column: 1 / span 6; margin-top: 18vw; }
.g3 { grid-row: 2; grid-column: 7 / span 5; }
.g4 { grid-row: 2; grid-column: 2 / span 4; margin-top: 22vw; }
.g5 { grid-row: 3; grid-column: 2 / span 6; }
.g6 { grid-row: 3; grid-column: 9 / span 4; margin-top: 16vw; }
.g7 { grid-row: 4; grid-column: 4 / span 6; } /* the section closes on one large photo */

.cta {
  min-height: calc(100 * var(--vh)); padding-bottom: 100px;
  display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 100px;
}
.cta__row { width: var(--content); display: flex; justify-content: space-between; align-items: center; gap: 24px; }

.ticker { width: 100%; height: calc(50 * var(--vh)); overflow: hidden; }
.ticker__track { display: flex; gap: 2px; height: 100%; width: max-content; animation: ticker var(--ticker-dur, 60s) linear infinite; }
.ticker:focus-within .ticker__track,
.ticker.is-paused .ticker__track { animation-play-state: paused; }
.ticker .ph { height: 100%; flex: none; aspect-ratio: 4 / 5; }
.ticker .ph { filter: grayscale(1); } /* as in the Framer design: the strip is black and white */
@keyframes ticker { to { transform: translateX(-50%); } }

/* ---------- Portfolio ---------- */
.listing { padding: calc(100px + var(--nav-h)) 0 200px; }
.listing__head { display: flex; flex-direction: column; align-items: flex-start; gap: 20px; padding-bottom: 56px; }
.filters { display: flex; flex-wrap: wrap; align-items: center; gap: 0 32px; list-style: none; margin: 0; padding: 0; }
.grid { display: flex; align-items: flex-start; gap: 5px; }
.grid__col { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.card { position: relative; display: block; overflow: hidden; }
.card__img { display: block; overflow: hidden; }
.grid { transition: opacity var(--t-fast) var(--ease); }
.js .grid:not(.is-ready) { visibility: hidden; }
.grid.is-changing { opacity: 0; }
.card img { width: 100%; transition: transform var(--t-slow) var(--ease); }
.card[hidden] { display: none; }
.card__caption { display: flex; flex-direction: column; gap: 2px; padding: 10px 2px 14px; }
.card__title { font-family: var(--serif); font-size: 22px; line-height: 1.1; }
.card__meta { font-size: 13px; opacity: 0.7; }
@media (hover: hover) and (pointer: fine) {
  .card__caption {
    position: absolute; inset: auto 0 0 0; padding: 48px 16px 16px;
    background: linear-gradient(transparent, rgba(15, 14, 8, 0.85));
    opacity: 0; transform: translateY(8px);
    transition: opacity var(--t-hover-out) var(--ease), transform var(--t-hover-out) var(--ease);
  }
  .card:hover img { transform: scale(1.03); }
  .card:hover .card__caption,
  .card:focus-visible .card__caption { opacity: 1; transform: none; transition-duration: var(--t-hover); }
}
.card__img { transition: transform var(--t-press) var(--ease); }
.card:active .card__img { transform: scale(0.98); }
/* After a filter change, the photos on screen come in one after another */
.card { transition: opacity var(--t-ui) var(--ease), transform var(--t-ui) var(--ease); }
.grid.is-staggering .card { opacity: 0; transform: translateY(8px); transition: none; }

/* ---------- Project ---------- */
.post { padding: 100px 0; }
.post .wrap { max-width: 1158px; }
.post__head { display: flex; flex-direction: column; align-items: flex-start; gap: 32px; margin-bottom: 80px; }
.post__head .btn { font-size: 15px; padding: 10px 22px; }
.post__title { font-size: var(--display-s); line-height: 0.95; letter-spacing: -0.02em; max-width: 14em; }
.post__info { display: flex; flex-direction: column; gap: 8px; max-width: 640px; }
.post__credit { font-size: 18px; line-height: 1.5; }
.post__meta { font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; opacity: 0.85; }

/* Video: a poster with a play button; YouTube loads only on click */
.video {
  position: relative; display: block; width: 100%; aspect-ratio: 16 / 9; margin: 0 0 35px;
  padding: 0; border: 0; cursor: pointer; overflow: hidden; color: var(--green);
}
.video img { width: 100%; height: 100%; object-fit: cover; }
.video__play {
  position: absolute; inset: 0; margin: auto; width: 88px; height: 88px; border-radius: 50%;
  display: grid; place-items: center; border: 1px solid currentColor; background: rgba(15, 14, 8, 0.35);
  transition: box-shadow var(--t-ui) var(--ease);
}
.video__play svg { width: 28px; height: 28px; margin-left: 4px; }
.post__videos iframe { display: block; width: 100%; aspect-ratio: 16 / 9; height: auto; border: 0; margin-bottom: 35px; }
.post__images { display: grid; gap: 35px; }
.post__row { display: flex; gap: 35px; justify-content: center; }
.post__row figure { margin: 0; flex: var(--ar) 1 0; min-width: 0; }
.post__row img { width: 100%; }
/* a whole photo fits on screen: limit the row height to the viewport */
.post__row--pair { max-width: calc((calc(100 * var(--vh)) - 120px) * var(--sum) + 35px); margin-inline: auto; width: 100%; }
.post__row--single figure { flex: none; width: min(62%, calc((calc(100 * var(--vh)) - 120px) * var(--ar))); }
.post__row--single.is-left { justify-content: flex-start; padding-left: 8%; }
.post__row--single.is-right { justify-content: flex-end; padding-right: 8%; }
.post__row--stagger { align-items: flex-start; justify-content: space-between; }
/* smaller photo first, larger one lower — both still fit on screen */
.post__row--stagger figure:first-child { flex: none; width: min(38%, calc((calc(100 * var(--vh)) - 120px) * var(--ar) * 0.8)); }
.post__row--stagger figure:last-child { flex: none; width: min(50%, calc((calc(100 * var(--vh)) - 120px) * var(--ar))); margin-top: calc(12 * var(--vh)); }
.post__row--wide figure { flex: none; width: min(100%, calc((calc(100 * var(--vh)) - 120px) * var(--ar))); }
.post__next {
  display: grid; grid-template-columns: 1fr auto; align-items: end; gap: 8px 32px;
  margin-top: 120px; padding-top: 32px; border-top: 1px solid rgba(230, 228, 219, 0.2);
}
.post__next-label { grid-column: 1; font-size: 13px; letter-spacing: 0.04em; text-transform: uppercase; opacity: 0.85; }
.post__next-title { grid-column: 1; font-size: 56px; letter-spacing: -2.1px; line-height: 1; transition: color var(--t-fast); }
.post__next-img { grid-column: 2; grid-row: 1 / span 2; width: 140px; aspect-ratio: 4 / 5; overflow: hidden; }
.post__next-img img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--t-slow) var(--ease); }

/* ---------- About ---------- */
.about { width: var(--content); margin-inline: auto; display: flex; justify-content: space-between; }
.about__text { width: 50%; }
.about__intro { height: calc(100 * var(--vh)); display: flex; align-items: center; transition: opacity var(--t-ui) var(--ease); }
.about__me { height: calc(100 * var(--vh)); display: flex; flex-direction: column; justify-content: center; gap: 36px; padding-inline: 5%; }
.about__me p { font-size: 17px; line-height: 1.7; max-width: 52ch; }
.about__media { flex: 1; display: flex; justify-content: flex-end; }
.about__sticky { position: sticky; top: 0; width: 72%; height: calc(100 * var(--vh)); display: flex; align-items: center; }
.about__sticky img { width: 100%; height: 557px; object-fit: cover; opacity: 0.9; transition: opacity var(--t-ui) var(--ease); }
.is-past-intro .about__intro,
.is-past-intro .about__sticky img { opacity: 0; }
.story { min-height: calc(100 * var(--vh)); display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 50px; }
.story > * { width: var(--content); }
.story__cols { display: flex; gap: 50px; }
.story__cols p { flex: 1; font-size: 18px; line-height: 1.7; }

/* ---------- About: clients & experience ---------- */
.cv { width: var(--content); margin: 0 auto; padding: 40px 0 160px; display: grid; grid-template-columns: 1fr 1fr; gap: 50px; }
.cv__col { display: flex; flex-direction: column; gap: 36px; }
.cv__list { list-style: none; margin: 0; padding: 0; font-size: 18px; line-height: 1.7; }
.cv__list--rows li {
  display: flex; justify-content: space-between; gap: 24px;
  padding: 12px 0; border-bottom: 1px solid rgba(230, 228, 219, 0.15); line-height: 1.4;
}
.cv__list--rows li span + span { opacity: 0.7; text-align: right; white-space: nowrap; }

/* ---------- Contact ---------- */
.contact { height: calc(100 * var(--vh)); min-height: 560px; overflow: hidden; }
.contact .wrap { height: 100%; padding-top: var(--nav-h); display: flex; flex-direction: column; justify-content: space-evenly; }
.contact__row { display: flex; justify-content: space-between; align-items: center; gap: 24px; flex-wrap: wrap; }

/* ---------- Tablet ---------- */
@media (max-width: 1279.98px) {
  .t-56 { font-size: 48px; }
  .preloader__name { font-size: 80px; }
  .about__me { padding-inline: 0 5%; }
}

/* ---------- Phone ---------- */
@media (max-width: 809.98px) {
  .t-56, .t-50, .t-48 { font-size: 38px; letter-spacing: -1.4px; }
  .t-28 { font-size: 22px; }
  .btn { font-size: 16px; padding: 14px 28px; }

  .nav { justify-content: flex-start; padding: 10px; height: auto; }
  .nav__links { display: none; }
  .nav__toggle {
    display: grid; place-items: center; width: 44px; height: 44px;
    background: none; border: 0; padding: 0; cursor: pointer; position: relative; z-index: 2;
  }
  .nav__toggle span {
    position: absolute; width: 20px; height: 2px; border-radius: 10px; background: var(--beige);
    transition: transform var(--t-ui) var(--ease), background-color var(--t-fast) var(--ease);
  }
  .nav__toggle span:first-child { transform: translateY(-4px); }
  .nav__toggle span:last-child { transform: translateY(4px); }
  .nav.is-open .nav__toggle span { background: var(--bg); } /* same colour as the menu links */
  .nav.is-open .nav__toggle span:first-child { transform: rotate(45deg); }
  .nav.is-open .nav__toggle span:last-child { transform: rotate(-45deg); }
  .nav__panel {
    display: block; position: fixed; inset: 0 0 auto 0; z-index: 1; overflow: hidden;
    color: var(--bg); background: var(--brand-gradient);
    transform: translateY(-100%); visibility: hidden; will-change: transform;
    transition: transform 320ms var(--ease), visibility 0s 320ms;
  }
  .nav__inner {
    position: relative; padding: 74px 20px 0;
    transform: translateY(100%); will-change: transform;
    transition: transform 320ms var(--ease);
  }
  .nav.is-open .nav__panel { transform: none; visibility: visible; transition: transform var(--t-ui) var(--ease), visibility 0s; }
  .nav.is-open .nav__inner { transform: none; transition-duration: var(--t-ui); }
  /* the name as a signature at the bottom, like in the footer */
  .nav__name {
    margin: 48px -20px 0; padding: 0 0 14px 12px;
    font-family: var(--serif); font-size: 18.6vw; line-height: 0.8; letter-spacing: -0.01em; white-space: nowrap;
    color: var(--bg); pointer-events: none;
  }
  html.menu-open { overflow: hidden; }
  @media (max-height: 520px) { .nav__panel { max-height: calc(100 * var(--vh)); overflow-y: auto; } }
  .nav__scrim { touch-action: none; } /* older iPhones: a drag on the dimmed page doesn't scroll it */
  .nav__panel { overscroll-behavior: contain; }
  .nav__scrim { display: block; position: fixed; inset: 0; z-index: 0; background: rgba(15, 14, 8, 0.5); opacity: 0; pointer-events: none; transition: opacity 320ms var(--ease); }
  .nav.is-open .nav__scrim { opacity: 1; pointer-events: auto; transition-duration: var(--t-ui); }
  .nav__panel ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 20px; }
  .nav__panel::before {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background-image: var(--grain); mix-blend-mode: multiply; opacity: 0.5;
  }

  .nav__panel a { font-family: var(--serif); font-size: 40px; line-height: 1.1; color: var(--bg); }

  .footer__cta { order: 2; flex-direction: column; align-items: flex-start; gap: 19px; }
  .footer__cta .serif { font-size: 38px; }
  .footer__links { order: 1; }
  .footer__copy { order: 3; }
  .btn--secondary svg { opacity: 1; width: 14px; transform: none; }
  .about__intro br { display: none; }

  .preloader__name { font-size: 54px; }
  .preloader img:nth-of-type(1) { width: 140px; height: 180px; left: 6%; bottom: 14%; }
  .preloader img:nth-of-type(2) { width: 160px; height: 100px; right: 6%; top: 16%; }
  .preloader img:nth-of-type(3) { width: 120px; height: 147px; right: 8%; bottom: 6%; }


  .hero__sticky { gap: 24px; padding-bottom: 0; }
  .hero__sticky h1, .hero__sticky p { text-align: center; }
  .collage { grid-template-columns: repeat(6, minmax(0, 1fr)); column-gap: 4vw; row-gap: 14vw; }
  .collage--hero { margin-top: calc(-14 * var(--vh)); padding-bottom: 14vw; }
  .c1 { grid-column: 2 / span 5; }
  .c2 { grid-column: 4 / span 3; grid-row: 2; margin-top: 0; }
  .c3 { grid-column: 1 / span 3; grid-row: 2; margin-top: 22vw; }
  /* phone: one large photo, then a staggered pair, in turn */
  .g1 { grid-column: 2 / span 5; grid-row: 1; }
  .g2 { grid-column: 1 / span 3; grid-row: 2; margin-top: 0; }
  .g3 { grid-column: 4 / span 3; grid-row: 2; margin-top: 24vw; }
  .g4 { grid-column: 1 / span 5; grid-row: 3; margin-top: 0; }
  .g5 { grid-column: 1 / span 3; grid-row: 4; }
  .g6 { grid-column: 4 / span 3; grid-row: 4; margin-top: 24vw; }
  .g7 { grid-column: 2 / span 5; grid-row: 5; }

  .collage--gallery { margin-bottom: 60px; }

  .cta { min-height: calc(80 * var(--vh)); gap: 48px; }
  .cta__row { flex-direction: column; align-items: center; text-align: center; }
  .cta__row h2 { color: var(--green); }
  .ticker { height: calc(40 * var(--vh)); }

  .listing__head { padding-bottom: 32px; gap: 12px; }
  .filters { gap: 0 20px; }

  .post { padding: calc(var(--nav-h) + 20px) 0 60px; }
  .post__head { gap: 20px; margin-bottom: 36px; }
  .post__credit { font-size: 16px; }
  .post__images, .post__row { gap: 12px; }
  .post__row--pair { flex-direction: column; max-width: none; }
  .post__row--single figure, .post__row--wide figure { width: 100%; }
  .post__row--single.is-left, .post__row--single.is-right { padding-inline: 0; }
  .post__row--stagger figure:first-child,
  .post__row--stagger figure:last-child { width: 100%; margin-top: 0; }
  .post__next { margin-top: 64px; }
  .post__next-title { font-size: 34px; letter-spacing: -1px; }
  .post__next-img { width: 84px; }
  .filters .roll { padding: 14px 0; }

  .about { flex-direction: column-reverse; }
  .about__text { width: 100%; }
  .about__intro { height: auto; padding: 32px 0 60px; }
  .about__me { height: auto; padding: 60px 0; }
  .about__sticky { position: relative; width: 100%; height: auto; padding-top: calc(var(--nav-h) + 16px); }
  .about__sticky img { height: auto; aspect-ratio: 4 / 5; }
  .is-past-intro .about__intro,
  .is-past-intro .about__sticky img { opacity: 1; }
  .story { min-height: auto; padding: 40px 0 80px; gap: 32px; }
  .story__cols { flex-direction: column; gap: 1.2em; }
  .story__cols p { font-size: 16px; }

  .cv { grid-template-columns: 1fr; gap: 60px; padding: 20px 0 100px; }
  .cv__col { gap: 24px; }
  .cv__list { font-size: 16px; }
  .cv__list--rows li { flex-direction: column; gap: 2px; }
  .cv__list--rows li span + span { text-align: left; white-space: normal; }
  .contact { height: auto; min-height: calc(100 * var(--vh)); }
  .contact .wrap { min-height: calc(100 * var(--vh)); gap: 60px; padding-block: calc(var(--nav-h) + 40px) 60px; justify-content: center; }
}

@media (max-height: 520px) and (orientation: landscape) {
  .footer { position: relative; height: auto; padding-top: 56px; }
  .js .footer:not(.is-near) { visibility: visible; } /* in the normal flow here: nothing to show through */
  .footer__body { gap: 24px; }
  .footer-spacer { display: none; }
}

/* "Reduce motion": no movement, but fades stay (short), so changes are still smooth */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; }
  .js .collage .ph, .js main h2, .js .post__next, .card, .card__caption,
  .roll__label > span, .tlink__in span, .btn svg { transform: none !important; }
  .btn:active, .video:active, .card:active .card__img,
  .card:hover img, .ph:hover img, .post__next:hover .post__next-img img, .video:hover img { transform: none !important; }
  .preloader { display: none; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: var(--t-fast) !important; animation-delay: 0s !important; }
  .ticker { overflow-x: auto; }
  .ticker__track { animation: none !important; }
}
