/* ==========================================================================
   BrightPixel — home page
   1. Tokens  2. Base  3. Shared parts  4. Sections (in page order)  5. Motion
   ========================================================================== */

/* ---------- 1. Tokens ---------- */
@font-face {
  font-family: "Outfit";
  src: url("../assets/fonts/Outfit-VariableFont.woff2") format("woff2"),
       url("../assets/fonts/Outfit-VariableFont.ttf") format("truetype");
  font-weight: 100 900;
  font-display: swap;
}

:root {
  --violet: #7C25FE;
  --pink: #F81988;
  --red: #FE4342;
  --orange: #FE8F11;
  --ink: #0F0F1A;
  --paper: #FEFDFB;
  --spectrum: linear-gradient(120deg, var(--violet), var(--pink) 40%, var(--red) 70%, var(--orange));

  --bg: var(--paper);
  --fg: var(--ink);
  --muted: rgba(15, 15, 26, .64);
  --line: rgba(15, 15, 26, .13);
  --soft: rgba(15, 15, 26, .045);
  --focus: var(--violet);

  --gutter: clamp(20px, 4vw, 64px);
  --section: clamp(96px, 14vw, 220px);
  --head-gap: clamp(20px, 2vw, 28px);   /* label to heading, everywhere */
  --ease: cubic-bezier(.2, .8, .2, 1);
  --ease-io: cubic-bezier(.7, 0, .2, 1);
  color-scheme: light;
}

/* Dark theme, and the ink sections of the light theme, share one set of tokens. */
:root[data-theme="dark"], body.is-ink {
  --bg: var(--ink);
  --fg: var(--paper);
  --muted: rgba(254, 253, 251, .68);
  --line: rgba(254, 253, 251, .16);
  --soft: rgba(254, 253, 251, .06);
  --focus: var(--orange);
}
:root[data-theme="dark"] { color-scheme: dark; }

/* ---------- 2. Base ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; background: var(--bg); }
/* Native smooth scrolling only when the scripts are not driving the scroll: it would
   otherwise make ScrollTrigger measure positions while the page is still moving. */
html:not(.js):not(.reduced) { scroll-behavior: smooth; }
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-stopped { overflow: hidden; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: "Outfit", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: clamp(1rem, .95rem + .25vw, 1.1875rem);
  font-weight: 350;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  transition: background-color .6s var(--ease), color .6s var(--ease);
  overflow-x: hidden;
}

h1, h2, h3, p, ol, ul { margin: 0; }
ol, ul { padding: 0; list-style: none; }
img, svg, canvas { display: block; max-width: 100%; }
a { color: inherit; }
button { font: inherit; color: inherit; }
address { font-style: normal; }
::selection { background: var(--pink); color: #fff; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; border-radius: 4px; }

.wrap { width: 100%; max-width: 1560px; margin-inline: auto; padding-inline: var(--gutter); }
.sr-only, .skip:not(:focus) {
  position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.skip:focus { position: fixed; top: 12px; left: 12px; z-index: 300; padding: 10px 16px; background: var(--ink); color: var(--paper); border-radius: 8px; }

/* Theme switch uses a circular reveal where the browser supports view transitions. */
::view-transition-old(root), ::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
html.theme-switching *, html.theme-switching *::before, html.theme-switching *::after { transition: none !important; }

/* ---------- 3. Shared parts ---------- */

/* Kept out of the HTML on purpose: the "@" and "." of the email address are drawn from here,
   so the address never appears whole in the page source for harvesting bots. */
.em__at::before { content: "@"; }
.em__dot::before { content: "."; }
.em i { font-style: normal; }

.eyebrow {
  display: flex; align-items: flex-start; gap: .7em; margin-block: -.25em;   /* the margin cancels the extra line height, so spacing around a one-row label is unchanged */
  font-size: .8125rem; font-weight: 500; line-height: 1.5; letter-spacing: .14em; text-transform: uppercase; color: var(--muted);
}
/* Outfit's capitals are 0.7em tall; on a 1.5 line their top edge sits 0.42em down. */
.eyebrow__px { flex: none; width: .7em; height: .7em; margin-top: .42em; border-radius: .14em; background: var(--spectrum); }

.section-head { display: grid; gap: var(--head-gap); margin-bottom: clamp(40px, 6vw, 96px); }
.section-title {
  font-size: clamp(2.5rem, 6vw, 6.25rem); font-weight: 250; line-height: 1.08; letter-spacing: -.04em; max-width: 11ch;
  text-wrap: balance;
}
.section-title--wide { max-width: 15ch; }
.word { display: inline-block; overflow: hidden; vertical-align: top; padding: 0 .1em .14em; margin: 0 -.1em -.14em; }
.word__in { display: inline-block; }

.btn {
  position: relative; display: inline-flex; align-items: center; gap: .6em; isolation: isolate; overflow: hidden;
  padding: 1.35em 2em; border: 0; border-radius: 999px; background: var(--fg); color: var(--bg);
  font-size: .8125rem; font-weight: 600; line-height: 1; letter-spacing: .05em; text-transform: uppercase; text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: color .35s var(--ease), background-color .6s var(--ease);
}
.btn::before {
  content: ""; position: absolute; inset: -1px; z-index: -1; border-radius: inherit; background: var(--spectrum);
  transform: translateY(103%); transition: transform .5s var(--ease);
}
.ico { flex: none; width: 1em; height: 1em; }
picture { display: contents; }
source { display: none; }   /* otherwise the empty <source> becomes a grid item and adds a stray 20px gap above the portrait */
.btn .ico { position: relative; top: .02em; font-size: 1.35em; margin-block: -.2em; transition: transform .35s var(--ease); }  /* centred on the capitals */
.btn:hover, .btn:focus-visible { color: #fff; }
.btn:hover::before, .btn:focus-visible::before { transform: none; }
.btn:hover .ico { transform: translate(2px, -2px); }
.btn--small { padding: 13px 1.5em; font-size: .75rem; }   /* 38px tall, the same as the theme button */
.nav__cta { text-indent: .05em; }   /* balances the letter-spacing after the last letter, so the text sits dead centre */
.btn--large { padding: 1.6em 2.4em; font-size: .875rem; }

.link {
  font-weight: 500; text-decoration: none;
  background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat;
  padding-bottom: 4px; transition: background-size .4s var(--ease);
}
.link:hover { background-size: 0 1px; background-position: 100% 100%; }

.tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 20px; }
.tags li { padding: .4em .9em; border: 1px solid var(--line); border-radius: 999px; font-size: .8125rem; color: var(--muted); }

/* The logo file has empty space around the artwork: 48 of its 390 units on the left. The negative
   margin removes exactly that, so the visible mark starts on the page margin. */
.logo { --h: 36px; height: var(--h); width: auto; margin-left: calc(var(--h) * -48 / 390); }
.logo--on-dark { display: none; }
:root[data-theme="dark"] .logo--on-light, body.is-ink .logo--on-light { display: none; }
:root[data-theme="dark"] .logo--on-dark, body.is-ink .logo--on-dark { display: block; }

/* Pointer companion: a circle that appears over links and buttons only */
.cursor { display: none; position: fixed; left: 0; top: 0; z-index: 250; pointer-events: none; mix-blend-mode: difference; opacity: 0; }
.cursor span { display: block; width: 10px; height: 10px; margin: -5px; border-radius: 50%; background: #fff; transform: scale(0); transition: transform .45s var(--ease); }
.cursor.is-link span { transform: scale(3.4); }
html.has-cursor .cursor { display: block; }

/* ---------- 4. Sections ---------- */

/* Navigation */
.nav {
  position: fixed; inset: 0 0 auto 0; z-index: 50; isolation: isolate;
  display: flex; align-items: center; gap: clamp(12px, 1.6vw, 24px); padding: 18px var(--gutter);
  transition: transform .5s var(--ease);
}
.nav::before {
  content: ""; position: absolute; inset: 0; z-index: -1; background: var(--bg); opacity: 0;
  transition: opacity .4s, background-color .6s var(--ease);
}
.nav.is-scrolled:not(.is-open)::before { opacity: .92; }
.nav--hidden { transform: translateY(-110%); }
.nav__logo { margin-right: auto; }
.nav__links { display: flex; gap: clamp(20px, 2.6vw, 44px); margin-right: clamp(8px, 2vw, 32px); }
.nav__links a { position: relative; font-size: .9375rem; font-weight: 450; text-decoration: none; padding: 6px 0; }

.theme {
  flex: none; display: grid; place-items: center; width: 38px; height: 38px; padding: 0; border: 1px solid var(--line); border-radius: 50%;
  background: none; font-size: 20px; cursor: pointer; transition: border-color .3s, transform .6s var(--ease);
}
.theme:hover { border-color: var(--fg); transform: rotate(30deg); }
.theme .ico { grid-area: 1 / 1; }
.theme__sun, :root[data-theme="dark"] .theme__moon { display: none; }
:root[data-theme="dark"] .theme__sun { display: block; }

.nav__toggle {
  display: none; align-items: center; gap: 10px; padding: .7em 1.1em; border: 1px solid var(--line); border-radius: 999px;
  background: none; font-size: .9375rem; font-weight: 500; line-height: 1; cursor: pointer;
}
.nav__toggle-icon { display: grid; grid-template-columns: repeat(2, 5px); gap: 3px; transition: transform .5s var(--ease); }
.nav__toggle-icon i { width: 5px; height: 5px; border-radius: 1px; background: currentColor; transition: background-color .4s; }
.nav.is-open .nav__toggle-icon { transform: rotate(45deg); }
.nav.is-open .nav__toggle-icon i:nth-child(1) { background: var(--violet); }
.nav.is-open .nav__toggle-icon i:nth-child(2) { background: var(--pink); }
.nav.is-open .nav__toggle-icon i:nth-child(3) { background: var(--red); }
.nav.is-open .nav__toggle-icon i:nth-child(4) { background: var(--orange); }

/* Mobile menu: a wash of colour opens from the button, the panel follows, links rise in turn */
.menu { display: none; }
@media (max-width: 860px) {
  .logo { --h: 29px; }
  .nav__links, .nav__cta { display: none; }
  .nav__toggle { display: inline-flex; }

  .menu { display: block; position: fixed; inset: 0; z-index: 40; visibility: hidden; transition: visibility 0s .9s; }
  .menu.is-open { visibility: visible; transition-delay: 0s; }
  .menu__wash, .menu__panel {
    position: absolute; inset: 0; clip-path: circle(0 at calc(100% - 64px) 40px);
    transition: clip-path .8s var(--ease-io);
  }
  .menu__wash { background: var(--spectrum); transition-delay: .12s; }
  .menu__panel { background: var(--bg); }
  .menu.is-open .menu__wash, .menu.is-open .menu__panel { clip-path: circle(150vmax at calc(100% - 64px) 40px); }
  .menu.is-open .menu__wash { transition-delay: 0s; }
  .menu.is-open .menu__panel { transition-delay: .14s; }

  .menu__inner { position: relative; height: 100%; display: flex; flex-direction: column; justify-content: space-between; padding: 104px var(--gutter) 28px; overflow-y: auto; }
  /* The line under each link fades in with that link, and fades out first when the menu closes,
     so the lines are never on screen without their links. */
  .menu__link { display: block; overflow: hidden; border-bottom: 1px solid transparent; padding: 10px 0; text-decoration: none; transition: border-color .2s; }
  .menu.is-open .menu__link { border-bottom-color: var(--line); transition: border-color .9s var(--ease) calc(.28s + var(--i) * .07s); }
  .menu__in {
    display: flex; align-items: baseline; gap: 18px; font-size: clamp(2.5rem, 12.5vw, 4.5rem); font-weight: 250; line-height: 1.08; letter-spacing: -.035em;
    transform: translateY(115%) rotate(4deg); transform-origin: left bottom; transition: transform .5s var(--ease);
  }
  .menu__in small { font-size: .75rem; font-weight: 500; letter-spacing: .12em; color: var(--muted); }
  .menu.is-open .menu__in { transform: none; transition: transform .9s var(--ease) calc(.28s + var(--i) * .07s); }
  .menu__foot {
    display: flex; align-items: center; justify-content: space-between; gap: 16px; padding-top: 28px;
    opacity: 0; transform: translateY(16px); transition: opacity .3s, transform .3s;
  }
  .menu.is-open .menu__foot { opacity: 1; transform: none; transition: opacity .7s var(--ease) .75s, transform .7s var(--ease) .75s; }
  .menu__pixels { display: grid; grid-template-columns: repeat(4, 10px); gap: 5px; }
  .menu__pixels i { height: 10px; border-radius: 2px; transform: scale(0); transition: transform .3s; }
  .menu__pixels i:nth-child(1) { background: var(--violet); --d: 0s; }
  .menu__pixels i:nth-child(2) { background: var(--pink); --d: .06s; }
  .menu__pixels i:nth-child(3) { background: var(--red); --d: .12s; }
  .menu__pixels i:nth-child(4) { background: var(--orange); --d: .18s; }
  .menu.is-open .menu__pixels i { transform: none; transition: transform .6s cubic-bezier(.3, 1.6, .5, 1) calc(.85s + var(--d)); }
}

/* Hero */
.hero { --hero-pad: clamp(24px, 4vh, 44px); position: relative; min-height: 100svh; display: flex; align-items: flex-end; padding: 120px 0 var(--hero-pad); overflow: hidden; }
/* Static poster: a still version of the pixel field. It is never shown while the animation is
   on its way (that made it flash and vanish); it appears only when the animation cannot run:
   reduced motion, no JavaScript, or no WebGL. */
.hero::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(var(--line) 1px, transparent 1.6px) 0 0 / 26px 26px;
}
.hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; background: var(--spectrum);
  -webkit-mask-image: radial-gradient(#000 9px, transparent 9.5px), radial-gradient(ellipse 46% 52% at 74% 32%, #000 20%, transparent 70%);
  mask-image: radial-gradient(#000 9px, transparent 9.5px), radial-gradient(ellipse 46% 52% at 74% 32%, #000 20%, transparent 70%);
  -webkit-mask-size: 26px 26px, 100% 100%; mask-size: 26px 26px, 100% 100%;
  -webkit-mask-composite: source-in; mask-composite: intersect;
}
html.js:not(.no-webgl) .hero::before, html.js:not(.no-webgl) .hero::after { display: none; }
.hero__canvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; display: none; }
html.webgl .hero__canvas { display: block; }
.hero__inner { position: relative; display: grid; gap: clamp(16px, 2.6vh, 32px); }
.hero__title { font-size: clamp(2.75rem, min(11.4vw, 19.5vh), 13.5rem); font-weight: 250; line-height: 1; letter-spacing: -.045em; }
.hero__title b { font-weight: 700; }
.line { display: block; overflow: hidden; padding: 0 .1em .12em; margin: 0 -.1em -.12em; }
.line__in { display: inline-block; white-space: nowrap; }
.line-row { display: flex; gap: .22em; }
.hero__dot { display: inline-block; width: .16em; height: .16em; margin-left: .05em; border-radius: .03em; background: var(--spectrum); }
.hero__bottom {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 24px 48px;
  margin-top: clamp(4px, 1.5vh, 20px); padding-top: var(--hero-pad); border-top: 1px solid var(--line);   /* same space as below the row */
}
/* Nudged up 0.025em so the capitals' top and the last baseline sit the same distance from the
   rules, plus 2px so the text block lines up optically with the button beside it. */
.hero__lead { position: relative; top: calc(-.025em - 2px); max-width: 38ch; font-size: clamp(1.0625rem, 1rem + .55vw, 1.4375rem); line-height: 1.4; color: var(--muted); }
.hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 28px; }

@media (max-width: 860px) {
  /* Phones: the hero is one screen plus the height of the "See my projects" row, so the last thing
     on the first screen is the Start a project button, with that link just below the fold. All the
     space left above the text goes to the pixel field. */
  .hero { padding-top: 104px; min-height: calc(100svh + 33px + var(--hero-pad)); }   /* leaves 30px under the button, the same as from the text above it */
  .hero__actions { gap: 34px; }   /* a little more than those 30px, so the link starts fully below the fold */
  .hero__title { font-size: min(13.4vw, 11vh); line-height: 1.04; }
  .line-row { display: block; }
  .hero__bottom { grid-template-columns: 1fr; }
  /* Stacked layout: pull the text up by the air above its capitals (0.38em), so the space from the
     rule to the capitals equals the space from the link's underline to the hero's bottom edge. */
  .hero__lead { top: 0; margin-top: -.38em; }
}

/* Marquee */
.marquee { --pad: clamp(34px, 3.6vw, 52px); overflow: hidden; border-block: 1px solid var(--line); }
.marquee__track { display: flex; width: max-content; will-change: transform; }
.marquee__group { display: flex; align-items: center; flex: none; }
/* Vertical padding is corrected for the letter shapes: 0.165em of air above the tall letters and
   0.13em below the baseline. The space above the letters and below the baseline is then equal. */
.marquee__group li { padding: calc(var(--pad) - .165em) clamp(18px, 2.4vw, 40px) calc(var(--pad) - .13em); font-size: clamp(1.75rem, 4.6vw, 4.25rem); font-weight: 250; letter-spacing: -.03em; line-height: 1; white-space: nowrap; }
.marquee__group li:nth-child(4n + 3) { font-weight: 700; }
.marquee__group .marquee__star {
  width: .62em; height: .62em; padding: 0; background: var(--spectrum);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 0C12 6.6 17.4 12 24 12C17.4 12 12 17.4 12 24C12 17.4 6.6 12 0 12C6.6 12 12 6.6 12 0Z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 0C12 6.6 17.4 12 24 12C17.4 12 12 17.4 12 24C12 17.4 6.6 12 0 12C6.6 12 12 6.6 12 0Z'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Statement */
.statement { display: grid; gap: var(--head-gap); padding-block: var(--section); }
.statement__text { max-width: 21ch; font-size: clamp(2rem, 5.6vw, 5.75rem); font-weight: 250; line-height: 1.12; letter-spacing: -.035em; }
.statement__text .sw { display: inline-block; }

/* Services */
.services { padding-bottom: calc(var(--section) * .5); }
.service {
  --t: clamp(2rem, 5vw, 4.75rem);   /* title size; the other columns align to its capitals */
  position: relative; isolation: isolate;
  display: grid; grid-template-columns: 5rem minmax(0, 1.15fr) minmax(0, 1fr) 2.5rem; gap: 24px clamp(20px, 3vw, 56px); align-items: start;
  padding: clamp(28px, 3.8vw, 64px) 0; border-top: 1px solid var(--line);
  transition: border-color .4s var(--ease), opacity .4s var(--ease);
}
.service:last-child { border-bottom: 1px solid var(--line); }
.service::before {
  content: ""; position: absolute; inset: 0 calc(var(--gutter) * -.5); z-index: -1; border-radius: 24px; background: var(--soft);
  opacity: 0; transform: scale(.985); transition: opacity .4s var(--ease), transform .5s var(--ease);
}
.service__num { padding-top: calc(var(--t) * .5675 - .515em); font-size: .875rem; font-weight: 500; line-height: 1; letter-spacing: .1em; color: var(--muted); transition: color .4s; }
.service__title { font-size: var(--t); font-weight: 250; line-height: 1.08; letter-spacing: -.035em; transition: transform .5s var(--ease); }
.service__body { padding-top: max(0px, calc(var(--t) * .225 - .455em)); color: var(--muted); max-width: 46ch; }
.service__px { justify-self: end; width: 14px; height: 14px; margin-top: calc(var(--t) * .5675 - 7px); border-radius: 3px; background: var(--accent); transition: transform .6s var(--ease); }
@media (hover: hover) and (min-width: 861px) {
  /* Wide screens only: on narrow screens the rows stay flat, with no panel behind them.
     The lines above and below the hovered row fade out (colour only, so nothing moves),
     which stops the panel sitting wider than its borders. */
  .service:hover, .service:hover + .service { border-color: transparent; }
  .service:hover::before { opacity: 1; transform: none; }
  .service:hover .service__title { transform: translateX(14px); }
  .service:hover .service__num { color: var(--accent); }
  .service:hover .service__px { transform: scale(2.6) rotate(90deg); }
  .services__list:hover .service:not(:hover) { opacity: .42; }
}
@media (max-width: 860px) {
  .service { grid-template-columns: 1fr auto; align-items: center; }
  .service__num { grid-column: 1; padding: 0; }
  .service__px { grid-column: 2; grid-row: 1; margin: 0; }
  .service__title, .service__body { grid-column: 1 / -1; }
  .service__body { padding-top: 0; }
}

/* Concept work */
.work { padding-block: clamp(72px, 10vw, 120px); }
.work__pin { position: relative; overflow-x: auto; }
.work__track { display: flex; align-items: center; gap: clamp(32px, 4.5vw, 80px); width: max-content; padding-inline: var(--gutter); }
.work__intro { flex: none; width: min(38vw, 560px); display: grid; gap: var(--head-gap); }
.work__lead { color: var(--muted); max-width: 38ch; }
.concept { flex: none; width: min(56vw, 900px, calc((100vh - 290px) * 4 / 3)); display: grid; gap: 20px; }
.concept__frame { position: relative; container-type: size; aspect-ratio: 4 / 3; overflow: hidden; border-radius: 18px; background: var(--soft); }
.concept__frame img { width: 100%; height: auto; }
.concept__hint { display: none; }

/* Desktop with a mouse: the frame shows the top of a full-page screenshot, and hovering scrolls it
   to the bottom. 100cqh is the frame's height, so the image stops exactly when its last row is in
   view. The scroll takes longer for longer pages; moving away returns to the top quickly. */
@media (hover: hover) and (min-width: 900px) {
  .concept__frame img { transition: transform 1.1s var(--ease); will-change: transform; }
  .concept:hover .concept__frame img {
    transform: translateY(calc(-100% + 100cqh));
    transition: transform calc(var(--ratio, 5) * 3s) linear;   /* one constant speed from top to bottom */
  }
  .concept__hint {
    display: block; position: absolute; right: 16px; bottom: 16px; padding: .55em 1em; border-radius: 999px;
    background: rgba(15, 15, 26, .78); color: #FEFDFB; font-size: .6875rem; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
    transition: opacity .4s var(--ease), transform .4s var(--ease);
  }
  .concept:hover .concept__hint { opacity: 0; transform: translateY(6px); }
}
/* The tag sits in the title's row and is centred on the title's capital letters (which sit 0.02em
   below the middle of a 1.2 line), so the pill and the name share one optical centre line. */
.concept__meta { --t: clamp(1.25rem, 1.8vw, 1.75rem); display: grid; grid-template-columns: auto 1fr; gap: 6px 20px; align-items: start; }
.concept__tag { align-self: center; position: relative; top: calc(var(--t) * .02 - 1px); padding: .55em .9em; border: 1px solid var(--line); border-radius: 999px; font-size: .75rem; font-weight: 500; line-height: 1; letter-spacing: .12em; text-transform: uppercase; white-space: nowrap; }
.concept__title { font-size: var(--t); font-weight: 400; line-height: 1.2; letter-spacing: -.01em; }
.concept__meta p { grid-column: 2; color: var(--muted); font-size: .9375rem; }
.work__next { flex: none; width: min(40vw, 480px); display: grid; gap: 28px; justify-items: start; padding-right: var(--gutter); }
.work__next-title { font-size: clamp(2.25rem, 4.6vw, 4.5rem); font-weight: 250; line-height: 1.08; letter-spacing: -.035em; }
.work__bar { display: none; }

@media (min-width: 900px) {
  html.js .work { padding-block: 0; }
  /* The pinned gallery is centred in a full screen, which already leaves air above the images,
     so the section before it needs only a little padding of its own. */
  html.js .services { padding-bottom: max(8px, calc(clamp(32px, 4.4vw, 64px) - 30px)); }
  html.js .work__pin { height: 100vh; display: flex; align-items: center; overflow: hidden; }
  html.js .work__bar { display: block; position: absolute; left: var(--gutter); right: var(--gutter); bottom: 36px; height: 2px; background: var(--line); }
  .work__bar span { display: block; height: 100%; background: var(--spectrum); transform: scaleX(0); transform-origin: left; }
}
@media (max-width: 899px) {
  .work__pin { overflow: visible; }
  .work__track { flex-direction: column; align-items: stretch; width: auto; gap: 56px; }
  .work__intro, .concept, .work__next { width: auto; }
  .work__next { padding-right: 0; }
}

/* Process */
.process { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: clamp(32px, 6vw, 120px); padding-block: var(--section); }
.process__aside { position: sticky; top: 120px; align-self: start; display: grid; gap: var(--head-gap); }
.process__mark { width: clamp(150px, 17vw, 260px); margin-top: clamp(24px, 4vw, 56px); overflow: visible; }
.process__mark path { will-change: transform; }
.step { --t: clamp(2rem, 4vw, 3.75rem); position: relative; display: grid; grid-template-columns: 4.5rem 1fr; gap: 12px 16px; padding: clamp(28px, 4vw, 60px) 0; border-top: 1px solid var(--line); transition: opacity .6s var(--ease); }
.step:last-child { border-bottom: 1px solid var(--line); }
.step__num { display: flex; align-items: center; gap: .7em; align-self: start; padding-top: calc(var(--t) * .5675 - .515em); font-size: .875rem; font-weight: 500; line-height: 1; letter-spacing: .1em; color: var(--muted); }
.step__num::before {
  content: ""; position: relative; top: .015em; width: .7em; height: .7em; border-radius: .14em; border: 1.5px solid var(--accent);
  background: var(--accent); transition: transform .5s var(--ease), background-color .5s;
}
html.js .step:not(.is-active) { opacity: .4; }
html.js .step:not(.is-active) .step__num::before { background: transparent; transform: scale(.8); }
.step__title { font-size: var(--t); font-weight: 250; line-height: 1.08; letter-spacing: -.035em; }
.step p { grid-column: 2; color: var(--muted); max-width: 44ch; }
@media (max-width: 860px) {
  .process { grid-template-columns: 1fr; }
  .process__aside { position: static; }
  .process__mark { width: 104px; margin-top: 16px; }
  .step { grid-template-columns: 3.75rem 1fr; }
}

/* About */
.studio { padding-bottom: var(--section); }
/* Portrait at about half its earlier width; the copy takes the space it frees. */
.studio__grid { display: grid; grid-template-columns: clamp(200px, 19vw, 300px) minmax(0, 1fr); gap: clamp(32px, 6vw, 112px); align-items: start; }
.studio__portrait { margin: 0; display: grid; gap: 20px; }
.studio__portrait img { width: 100%; height: auto; aspect-ratio: 4 / 5; object-fit: cover; object-position: 50% 100%; border-radius: 20px; background: var(--soft); }
.studio__sign { display: grid; gap: 2px; line-height: 1.4; }
.studio__sign b { font-size: 1.25rem; font-weight: 600; letter-spacing: -.01em; }
.studio__sign span { color: var(--muted); }
.studio__content { display: grid; gap: clamp(32px, 4vw, 64px); }
.studio__lead { font-size: clamp(1.375rem, 2.5vw, 2.375rem); font-weight: 300; line-height: 1.32; letter-spacing: -.02em; max-width: 22.5em; text-wrap: balance; }
.studio__points { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 clamp(24px, 3vw, 48px); }
.studio__points li { --t: clamp(1.25rem, 1.6vw, 1.5rem); position: relative; display: grid; grid-template-columns: 2rem 1fr; align-content: start; gap: 8px 0; padding: clamp(32px, 2.8vw, 44px) 0 0; border-top: 1px solid var(--line); }
/* Marker: as tall as the title's capitals (0.7em) and centred on them (0.62em down a 1.2 line). */
.studio__px { grid-row: span 2; font-size: var(--t); width: .7em; height: .7em; margin-top: .27em; border-radius: .14em; background: var(--accent); transition: transform .6s var(--ease); }
.studio__points li:hover .studio__px { transform: rotate(90deg); }
.studio__points h3 { font-size: var(--t); font-weight: 500; line-height: 1.2; letter-spacing: -.01em; }
.studio__points p { grid-column: 2; color: var(--muted); max-width: 48ch; }
/* Side by side: pull the text up by the air above its capitals (0.342em on a 1.32 line), so the
   top of the first line sits exactly level with the top of the portrait. */
@media (min-width: 861px) { .studio__lead { margin-top: -.342em; } }
/* Wide screens: the text column is as tall as the portrait column. The paragraph starts level with
   the top of the image and the three points end level with the caption under it (the small negative
   margin makes the two last baselines meet, since the two texts use different line heights). */
@media (min-width: 1101px) {
  .studio__grid { align-items: stretch; }
  .studio__content { align-content: space-between; }
  .studio__points { margin-bottom: -.075em; }
}
@media (max-width: 1100px) {
  .studio__points { grid-template-columns: 1fr; }
  .studio__points li { padding: 28px 0; }
  .studio__points li:last-child { border-bottom: 1px solid var(--line); }
}
@media (max-width: 860px) {
  .studio__grid { grid-template-columns: 1fr; }
  .studio__portrait img { width: min(50%, 200px); }
}

/* Contact + footer */
.contact { border-top: 1px solid var(--line); }
.contact__inner { display: grid; gap: var(--head-gap); justify-items: start; padding-block: var(--section) clamp(72px, 9vw, 140px); }
.contact__title { font-size: clamp(3rem, 10.5vw, 11rem); font-weight: 250; line-height: 1.08; letter-spacing: -.045em; max-width: 9ch; text-wrap: balance; }
.contact__lead { max-width: 36ch; font-size: clamp(1.125rem, 1rem + .6vw, 1.4375rem); color: var(--muted); }
.contact__email {
  --pad: calc(clamp(24px, 3vw, 48px) + 10px);
  display: flex; align-items: center; justify-content: space-between; gap: 24px; width: 100%; margin-top: clamp(16px, 3vw, 48px);
  /* The tall letters start 0.215em below the top of their line and the baseline sits 0.18em
     above its bottom; the padding cancels both, so the space from the upper rule to the top of
     the letters equals the space from the baseline to the lower rule. The arrow is centred on
     that same band. */
  padding: calc(var(--pad) - .215em) 0 calc(var(--pad) - .18em); border-block: 1px solid var(--line); text-decoration: none;
  font-size: clamp(1.5rem, 6.2vw, 6.5rem); font-weight: 250; letter-spacing: -.04em; line-height: 1.1;
}
/* The bottom padding (cancelled by the margin) lets the hover gradient cover the tail of the "g". */
.contact__email span { padding-bottom: .16em; margin-bottom: -.16em; background: var(--spectrum) 0 0 / 0 100% no-repeat; -webkit-background-clip: text; background-clip: text; transition: background-size .7s var(--ease), color .5s; overflow-wrap: anywhere; }
.contact__email .arrow { flex: none; position: relative; top: .0176em; width: .5em; height: .5em; overflow: visible; transition: transform .6s var(--ease); }
.contact__email:hover span, .contact__email:focus-visible span { background-size: 100% 100%; color: transparent; }
.contact__email:hover .arrow { transform: rotate(45deg); }
.contact__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 28px; margin-top: 8px; }
/* Narrow screens: always stacked, so the link stays under the button when its text shortens to "Copied". */
@media (max-width: 560px) { .contact__actions { flex-direction: column; align-items: flex-start; } }
.copy { padding: 0 0 4px; border: 0; background: linear-gradient(currentColor, currentColor) 0 100% / 100% 1px no-repeat; font-weight: 500; cursor: pointer; }
.copy.is-done { color: var(--orange); }

.footer {
  display: grid; grid-template-columns: 1.4fr 1fr auto; gap: 32px; align-items: start;
  padding-block: 48px var(--gutter); border-top: 1px solid var(--line); font-size: .9375rem; line-height: 1.7; color: var(--muted);
}
.footer__by { display: block; margin-top: 12px; color: var(--fg); }
.footer__nav { display: grid; justify-items: start; }
.footer a { text-decoration: none; transition: color .3s; }
.footer a:hover { color: var(--fg); }
.footer__legal { text-align: right; }
/* The wordmark is the logo's own outlines, cropped to the ink, so both edges sit exactly on the page margins. */
.footer__mark { grid-column: 1 / -1; overflow: hidden; margin-top: clamp(24px, 4vw, 64px); color: var(--fg); }
.footer__mark svg { width: 100%; height: auto; overflow: visible; }
@media (max-width: 860px) { .footer { grid-template-columns: 1fr 1fr; } .footer__legal { grid-column: 1 / -1; text-align: left; } }

/* ---------- 5. Motion: intro states and reduced motion ---------- */
html.js .hero .line__in { transform: translateY(115%); }
html.js .hero [data-intro] { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .concept:hover .concept__frame img { transform: none; }
  .concept__hint { display: none; }
  *, *::before, *::after { animation: none !important; transition-duration: .01ms !important; transition-delay: 0s !important; }
}
