/* Values come from the Figma frame (1920 wide). Type and spacing scale with the viewport and stop at the Figma size. */
:root {
  --red: #d00606;
  --red-portfolio: #cd2713;
  --red-icon: #f9321f;
  --red-button: #e42a17; /* Figma #f9321f, darkened so white 20px text passes 4.5:1 */
  --orange-text: #ff9950; /* Figma #ff5e00, lightened so 14px text passes 4.5:1 on the footer */
  --ink: #010101;
  --paper: #fdfdfc;
  --line: #ccc;
  --hint: #737373; /* Figma #808080, darkened to 4.6:1 */
  --footer: #434343;
  --footer-ink: #bebebe;

  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", Inter, "Segoe UI", Roboto, sans-serif;
  --mono: "Space Mono", ui-monospace, monospace;
  --display: Michroma, var(--sans);

  --fs-hero: clamp(36px, calc(3.468 * var(--vw)), 66.588px);
  --fs-hero-2: clamp(28px, calc(2.872 * var(--vw)), 55.143px);
  --fs-hero-3: clamp(18px, calc(1.7075 * var(--vw)), 32.784px);
  --fs-h2: clamp(32px, calc(2.5 * var(--vw)), 48px);
  --fs-h2-cta: clamp(40px, calc(3.333 * var(--vw)), 64px);
  --fs-stat: clamp(36px, calc(2.917 * var(--vw)), 56px);
  --fs-body: clamp(16px, calc(1.0417 * var(--vw)), 20px);
  --fs-title: clamp(15px, calc(1.0417 * var(--vw)), 20px); /* Figma 24, trimmed so every title fits two lines in a narrowed card */
  --ease-smooth: cubic-bezier(0.65, 0, 0.35, 1); /* even in and out: the value card hover, which read as a bounce with --ease */
  --fs-input: clamp(18px, calc(1.25 * var(--vw)), 24px);
  --fs-label: clamp(13px, calc(0.8333 * var(--vw)), 16px);
  --fs-btn: clamp(15px, calc(1.0417 * var(--vw)), 20px);

  --pad: clamp(16px, calc(2.0833 * var(--vw)), 40px);
  --sec-y: clamp(64px, calc(5.2083 * var(--vw)), 100px);
  --wide: calc(var(--x0) + var(--pad));

  /* --u is one Figma pixel, --vw one percent of the Figma width. Phones use real vw;
     desktop fits the 1920x1080 frame inside the viewport (see below). */
  --u: 1px;
  --vw: 1vw;
  --x0: 0px;
  --y0: 0px;

  --plus-s: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 6'%3E%3Cpath d='M3 0v6M0 3h6' stroke='%23000'/%3E%3C/svg%3E");
  --plus-l: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 0v16M0 8h16' stroke='%23000' stroke-width='2'/%3E%3C/svg%3E");
  --ease: cubic-bezier(0.2, 0, 0, 1);
}

@media (min-width: 1024px) {
  :root {
    /* scale by whichever runs out first, width or height, so each section fits one screen */
    --u: calc(min(100vw / var(--z), 1920px, 177.78svh / var(--z)) / 1920);
    --vw: calc(19.2 * var(--u));
    --x0: calc((100vw / var(--z) - 1920 * var(--u)) / 2);
    --y0: calc((100svh / var(--z) - 1080 * var(--u)) / 2);
  }
}

/* Past 1920 the frame stops growing, so big screens (2K, 4K) zoom the whole page instead:
   type, icons and fixed gaps all grow together. Zoom also multiplies vw/svh, hence the / var(--z) above. */
:root { --z: 1; }
html { zoom: var(--z); }
@media (min-width: 2160px) { :root { --z: 1.125; } }
@media (min-width: 2400px) { :root { --z: 1.25; } }
@media (min-width: 2560px) { :root { --z: 1.3333; } }
@media (min-width: 2880px) { :root { --z: 1.5; } }
@media (min-width: 3840px) { :root { --z: 2; } }

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  font-family: var(--sans);
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg { display: block; max-width: 100%; }
h1, h2, h3, p, ol, ul { margin: 0; }
ol, ul { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button, input, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }

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

/* [ bracketed ] labels, the recurring motif of the design */
.br::before { content: "["; content: "[" / ""; margin-inline-end: 2px; }
.br::after { content: "]"; content: "]" / ""; margin-inline-start: 2px; }

/* + marks on the corners of a box, as four real elements so each one can turn on its own centre.
   --m sets their size, --mark their color, --plus their stroke weight. */
.corners { position: absolute; inset: calc(var(--m, 6px) / -2); pointer-events: none; }
.corners i {
  position: absolute;
  width: var(--m, 6px);
  height: var(--m, 6px);
  background: var(--mark, #fff);
  -webkit-mask: var(--plus, var(--plus-s)) center / 100% no-repeat;
  mask: var(--plus, var(--plus-s)) center / 100% no-repeat;
  transition: rotate 250ms var(--ease);
}
.corners i:nth-child(1) { top: 0; left: 0; }
.corners i:nth-child(2) { top: 0; right: 0; }
.corners i:nth-child(3) { bottom: 0; left: 0; }
.corners i:nth-child(4) { bottom: 0; right: 0; }
.br::before, .br::after { display: inline-block; transition: translate 250ms var(--ease); }

/* Hover or keyboard focus: marks turn a quarter, brackets step apart */
@media (hover: hover) {
  :is(.btn, a.social[href], .lang summary, .pf-btn, .pd-close, .pd-frame):is(:hover, :focus-visible) .corners i { rotate: 90deg; }
  :is(.btn, .lang summary):is(:hover, :focus-visible) .br::before,
  :is(#site-nav a, .menu-btn, .nav-close button, .pd-actions .br):is(:hover, :focus-visible)::before { translate: -4px 0; }
  :is(.btn, .lang summary):is(:hover, :focus-visible) .br::after,
  :is(#site-nav a, .menu-btn, .nav-close button, .pd-actions .br):is(:hover, :focus-visible)::after { translate: 4px 0; }
}

.btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 16px 24px;
  font-size: var(--fs-btn);
  line-height: 1.5;
  text-transform: uppercase;
  white-space: nowrap;
  border: 0;
  isolation: isolate;
  transition: scale 150ms var(--ease);
}
.btn:active { scale: 0.96; }
/* Every button: the hover fill opens from the centre out to both sides. --btn-fill sets its colour. */
:where(.btn, a.social[href], .pf-btn, .lang summary, .pd-close) { isolation: isolate; --btn-fill: rgb(255 255 255 / 0.1); } /* :where keeps this default below each button's own --btn-fill */
:is(.btn, a.social[href], .pf-btn, .lang summary, .pd-close)::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--btn-fill);
  transform: scaleX(0);
  transition: transform 250ms var(--ease-smooth);
}
:is(.btn, a.social[href], .pf-btn, .lang summary, .pd-close):is(:hover, :focus-visible)::before { transform: none; }
/* text buttons: the letters open up a little, less than the brackets (the script holds the button's width) */
.btn .br { letter-spacing: 0; transition: letter-spacing 250ms var(--ease-smooth); }
.btn:is(:hover, :focus-visible) .br { letter-spacing: 0.06em; }
.btn .br, .btn .br svg { display: inline-flex; align-items: center; }
.f-menu a { letter-spacing: 0; transition: letter-spacing 250ms var(--ease-smooth), color 150ms; }
@media (hover: hover) {
  .f-menu a:hover { letter-spacing: 0.06em; } /* navbar links keep only the bracket spread */
}
.f-menu a { justify-content: flex-end; } /* right-aligned column: extra letter room grows to the left */
.btn .br svg { margin-inline-start: 2px; }
.btn-light { background: #fff; color: var(--red); }
.btn-light { --btn-fill: #fbe9e7; }
.btn-ghost { background: rgb(255 255 255 / 0.1); color: #fff; }

.social {
  position: relative;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  background: rgb(255 255 255 / 0.1);
}
.social[aria-disabled] { cursor: not-allowed; }

/* ---------- Hero ---------- */
/* hero, value and portfolio are each at least one screen tall; phones grow past it when content is longer */
.hero, .value, .portfolio { min-height: calc(100svh / var(--z)); }
.hero {
  position: relative;
  overflow: clip; /* not hidden: a hidden box can still be scrolled sideways by focus or find-in-page */
  isolation: isolate;
  color: #fff;
  padding: 96px var(--pad) 64px;
  background:
    radial-gradient(farthest-corner at 50% 50%, rgb(251 117 8 / 0.05), rgb(168 52 6 / 0.65)),
    radial-gradient(circle at 50% 97%, #f24523, rgb(242 69 35 / 0) 70%),
    var(--red);
}

.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: var(--pad) calc(var(--x0) + var(--pad));
  color: #fff;
  transition: translate 300ms var(--ease-smooth), color 200ms;
}
/* after scrolling: hidden while going down, back as soon as you scroll up; no bar behind it */
.site-header.is-hidden:not(:focus-within) { translate: 0 -100%; }
/* over a light section the whole header turns dark */
.site-header .brand img { transition: filter 200ms; }
.site-header.is-dark { color: var(--ink); --mark: var(--ink); }
.site-header.is-dark .brand img { filter: brightness(0); }
.site-header.is-dark .lang summary { --btn-fill: rgb(1 1 1 / 0.08); }
.brand { display: flex; align-items: center; gap: calc(33 * var(--u)); }
.brand img { width: clamp(112px, calc(9.479 * var(--vw)), 182px); height: auto; }
.tagline {
  display: none;
  font-family: var(--display);
  font-size: clamp(11px, calc(0.8333 * var(--vw)), 16px);
  line-height: 1.331;
  white-space: nowrap;
}
.header-right { display: flex; align-items: center; gap: clamp(12px, calc(1.667 * var(--vw)), 32px); }
.header-right a, .header-right button, .lang summary {
  font-size: var(--fs-label);
  line-height: 1.5;
  text-transform: uppercase;
  white-space: nowrap;
}
.menu-btn { background: none; border: 0; padding: 10px 0; min-height: 44px; }

/* mobile menu: a native popover, full screen */
#site-nav:popover-open {
  position: fixed;
  inset: 0;
  width: auto;
  height: auto;
  margin: 0;
  border: 0;
  padding: 96px var(--pad) 40px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--red);
  color: #fff;
}
#site-nav:popover-open a { display: block; padding: 8px 0; font-size: 32px; line-height: 1.5; }
.nav-close { position: absolute; top: var(--pad); right: var(--pad); }
.nav-close button { background: none; border: 0; padding: 10px 0; min-height: 44px; }

.lang { position: relative; }
.lang summary {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 10px 12px;
  list-style: none;
  cursor: pointer;
}
.lang summary::-webkit-details-marker { display: none; }
.lang summary .br { display: flex; align-items: center; gap: 4px; }
.lang summary .br::before, .lang summary .br::after { margin: 0; }
.lang img { width: 16px; height: 16px; margin-inline-start: 2px; }
.chev { transition: rotate 150ms var(--ease); margin-inline-end: 2px; }
.lang[open] .chev { rotate: 180deg; }
.lang-menu {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  min-width: 220px;
  padding: 8px 0;
  background: #fff;
  color: var(--ink);
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.18);
  font-size: 16px;
  line-height: 1.5;
}
.lang-menu span { display: block; padding: 10px 16px; }
.lang-menu [aria-current] { font-weight: 600; }
.lang-menu [aria-disabled] { color: var(--hint); }
.lang-menu small { display: block; font-size: 13px; }

.social-rail { display: none; }

.art {
  position: relative;
  container-type: inline-size;
  width: min(80vw, 450px); /* phones/tablets; desktop sets its own width */
  aspect-ratio: 685.583 / 896.214;
  margin-inline: auto;
  --a: calc(100cqw / 685.583);
}
.art > *, .art-logo > *, .art-logo-in > * { position: absolute; max-width: none; }
.art-cut {
  left: calc(-548.88 * var(--a));
  top: calc(-91.59 * var(--a));
  width: calc(2327.36 * var(--a));
  height: calc(1079.31 * var(--a));
}
/* same photo as .art-cut, padded 800/1000/600/400 source px so it still covers when the section is taller or wider than 16:9 */
.art-bg {
  left: calc(-1352.11 * var(--a));
  top: calc(-694.01 * var(--a));
  width: calc(4134.64 * var(--a));
  height: calc(2083.38 * var(--a));
}
.art-bg, .art-vignette { display: none; }
.art-vignette {
  left: calc(-1717.58 * var(--a));
  top: calc(-2051.89 * var(--a));
  width: calc(5000 * var(--a));
  height: calc(5000 * var(--a));
  background: radial-gradient(circle calc(1413 * var(--a)), rgb(251 117 8 / 0.05), rgb(168 52 6 / 0.65));
}

/* Entry: the "0" (and the copies that sit on it) is revealed by a window rising from its base.
   The window slides up while its content slides down by the same amount, so the logo itself stays put.
   Transforms only: animating clip-path repainted the masked photos every frame and stuttered. */
.art-logo, .art-logo-in { inset: 0; will-change: transform; animation: 700ms cubic-bezier(0.65, 0, 0.35, 1) 100ms backwards; }
.art-logo { overflow: clip; animation-name: logo-window; }
.art-logo-in { animation-name: logo-content; }
@keyframes logo-window { from { transform: translateY(92.64%); } }
@keyframes logo-content { from { transform: translateY(-92.64%); } }
.art-zero {
  left: calc(96.56 * var(--a));
  top: calc(82.3 * var(--a));
  width: calc(561.641 * var(--a));
  height: calc(747.937 * var(--a));
}
.art-mask {
  left: calc(47.5 * var(--a));
  top: calc(-7.22 * var(--a));
  width: calc(657.706 * var(--a));
  height: calc(945.774 * var(--a));
  overflow: hidden;
}
.art-mask img { position: absolute; left: -77.39%; top: 0; width: 254.79%; height: 100%; max-width: none; }
.art-mask-front {
  -webkit-mask: url(assets/hero-mask3.svg) calc(42.333 * var(--a)) calc(53.69 * var(--a)) / calc(614.857 * var(--a)) calc(849.751 * var(--a)) no-repeat;
  mask: url(assets/hero-mask3.svg) calc(42.333 * var(--a)) calc(53.69 * var(--a)) / calc(614.857 * var(--a)) calc(849.751 * var(--a)) no-repeat;
}
.art-mask-holes {
  -webkit-mask: url(assets/hero-mask5.svg) calc(197.936 * var(--a)) calc(238.892 * var(--a)) / calc(263.886 * var(--a)) calc(449.396 * var(--a)) no-repeat;
  mask: url(assets/hero-mask5.svg) calc(197.936 * var(--a)) calc(238.892 * var(--a)) / calc(263.886 * var(--a)) calc(449.396 * var(--a)) no-repeat;
}

.hero-copy { position: relative; z-index: 1; margin-top: 32px; }
.hero h1 { font-size: var(--fs-hero); font-weight: 700; line-height: 1.193; }
.hero-lede { margin-top: 6px; font-size: var(--fs-hero-2); font-weight: 300; line-height: 1.324; }
.hero-sub { margin-top: clamp(24px, calc(3.385 * var(--vw)), 65px); font-size: var(--fs-hero-3); font-weight: 300; line-height: 1.398; }
.hero-actions { display: flex; flex-wrap: wrap; gap: clamp(16px, calc(1.25 * var(--vw)), 24px); margin-top: clamp(24px, calc(1.406 * var(--vw)), 27px); }

.stats { display: flex; align-items: flex-start; margin-top: clamp(40px, calc(5.938 * var(--vw)), 114px); }
.bars { display: flex; align-items: flex-end; gap: 7px; height: 40px; margin: 12px clamp(20px, calc(3.02 * var(--vw)), 58px) 0 0; }
.bars i { width: 8px; background: #fff; }
.bars i:nth-child(1) { height: 26.667px; }
.bars i:nth-child(2) { height: 40px; }
.bars i:nth-child(3) { height: 36.078px; }
.stats-list { display: flex; }
.stats-list li {
  display: grid;
  gap: 2px;
  width: clamp(88px, calc(8.229 * var(--vw)), 158px);
  font-size: var(--fs-label);
  line-height: 1.5;
  text-transform: uppercase;
}
.stats-list strong { font-size: var(--fs-stat); line-height: 1.143; font-variant-numeric: tabular-nums; }

@media (max-width: 1023px) {
  /* the "0" sits right of the art box's centre (its left edge is the figure's coat), so nudge it back to the middle */
  .art { translate: -5% 0; }
}
@media (max-width: 767px) {
  .hero br { display: none; }
}
@media (max-width: 1279px) {
  .value h2 br { display: none; }
}

@media (min-width: 1024px) {
  .tagline { display: block; }
  .menu-btn, .nav-close { display: none; }
  #site-nav {
    position: static;
    inset: auto;
    width: auto;
    height: auto;
    margin: 0;
    border: 0;
    padding: 0;
    overflow: visible;
    background: none;
    color: inherit;
    display: flex;
    gap: clamp(20px, calc(1.667 * var(--vw)), 32px);
  }

  .hero {
    padding: calc(var(--y0) + 186 * var(--u)) var(--pad) calc(64 * var(--u)) calc(var(--x0) + 1034 * var(--u));
  }
  .social-rail {
    position: absolute;
    z-index: 2;
    left: calc(var(--x0) + var(--pad));
    top: 50%;
    translate: 0 -50%;
    display: grid;
    gap: 32px;
  }
  .art {
    position: absolute;
    left: calc(var(--x0) + 177.58 * var(--u));
    top: calc(var(--y0) + 91.89 * var(--u));
    width: calc(685.583 * var(--u));
    margin: 0;
  }
  .art-bg, .art-vignette { display: block; }
  /* Figma box is 669 wide; browsers render SF a hair wider, so give the lines room */
  .hero-copy { width: max(calc(720 * var(--u)), 400px); margin-top: 0; }
}

/* ---------- Value ---------- */
.value {
  position: relative;
  overflow: clip;
  background: var(--ink);
  color: #fff;
  padding: var(--sec-y) var(--wide);
}
.value-zero {
  position: absolute;
  top: 0;
  right: -45%;
  width: 90%;
  max-width: none;
  height: auto;
  pointer-events: none;
}
.value-head, .values { position: relative; }
.value-head { display: grid; gap: 32px; }
.value h2 {
  font-size: var(--fs-h2);
  font-weight: 400;
  line-height: 1.333;
  letter-spacing: -0.02em;
  text-transform: capitalize;
}
/* SF at its Text optical size, which is how Figma sets these 20px paragraphs */
.value-text, .contact-intro p { font-variation-settings: "opsz" 17; }
.value-text { display: grid; gap: clamp(24px, calc(2.083 * var(--vw)), 40px); font-size: var(--fs-body); line-height: 1.6; text-wrap: pretty; }

.values {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-top: 56px;
}
.values li {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 240px;
  padding: clamp(16px, calc(1.25 * var(--vw)), 24px);
  color: rgb(255 255 255 / 0.7);
  --m: 12px;
  --plus: var(--plus-l);
  transition: color 200ms;
}
/* Figma card 01 is the hover state. Its fill rises from the bottom like a mask, quickly. */
.values li::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgb(255 255 255 / 0.1);
  transform: scaleY(0);
  transform-origin: 50% 100%;
  transition: transform 250ms var(--ease-smooth);
}
.values .icon { flex: 1; display: grid; place-items: center; margin-bottom: 8px; }
.values .ico { width: calc(var(--w) * var(--u)); height: auto; overflow: visible; transition: scale 250ms var(--ease-smooth); }
.values .art { opacity: 0.6; }
/* hover draws the icon (script in index.html): each line of the white .ink copy is hidden behind a dash as long as
   itself (--len) and the dash slides in along the line's own direction; dots pop. Leaving rewinds it quickly. */
.values .ink .ln { stroke-dasharray: var(--len) var(--len); stroke-dashoffset: var(--len); transition: stroke-dashoffset 200ms var(--ease-smooth); }
.values .ink [data-pop] { scale: 0; transform-box: fill-box; transform-origin: center; transition: scale 150ms var(--ease-smooth); }
.values .corners i, .pf-frame .corners i { opacity: 0; rotate: -90deg; transition: opacity 200ms var(--ease-smooth), rotate 250ms var(--ease-smooth); }
.values .num { display: flex; font-size: var(--fs-label); line-height: 1.5; }
.values .num::before, .values .num::after { margin: 0; }
/* Figma centres the digits in a 24px box, which reads as padding inside the brackets */
.values .num { gap: 5.5px; }
.values h3 { font-size: var(--fs-title); font-weight: 500; line-height: 1.333; text-transform: capitalize; }

@media (hover: hover) {
  .values li:hover { color: #fff; }
  .values li:hover::before { transform: none; }
  .values li:hover .ico { scale: 1.45; } /* grows with the card, close to Figma's larger active icon */
  .values li:hover .ink .ln { stroke-dashoffset: 0; transition: stroke-dashoffset var(--dur) var(--ease-smooth) var(--delay); }
  .values li:hover .ink [data-pop] { scale: 1; transition: scale 200ms var(--ease) var(--delay); }
  .values li:hover .ico:not(:has(.ink)) .art { opacity: 1; } /* no script: just turn white */
  .values li:hover .corners i { opacity: 1; rotate: 0deg; }
}

@media (min-width: 768px) {
  .values { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

@media (min-width: 1024px) {
  /* content height, not one screen: 100 above and below, 128 between the title row and the cards */
  .value { display: flex; flex-direction: column; gap: calc(128 * var(--u)); min-height: 0; padding-block: calc(100 * var(--u)); }
  .value-zero { top: var(--y0); left: calc(var(--x0) + 1356 * var(--u)); right: auto; width: calc(822 * var(--u)); }
  .values { margin-top: 0; }
}

@media (min-width: 768px) {
  .value-text { grid-template-columns: 1fr 1fr; }
}

@media (min-width: 1280px) {
  /* Figma: 595 + 188 gap; the heading renders a few px wider here, so borrow from the gap */
  .value-head { grid-template-columns: 640fr 1057fr; column-gap: clamp(24px, calc(7.448 * var(--vw)), 143px); }
  .values { display: flex; gap: clamp(12px, calc(1.25 * var(--vw)), 24px); }
  .values li { flex: 1 1 0; min-width: 0; min-height: 0; height: calc(434 * var(--u)); gap: 8px; }
  /* hover widens the card to Figma's 360 and the others give up the space */
  .values li { transition: color 200ms var(--ease-smooth), flex-grow 250ms var(--ease-smooth), flex-basis 250ms var(--ease-smooth); }
  @media (hover: hover) {
    .values li:hover { flex: 0 0 calc(360 * var(--u)); }
  }
  /* titles are broken into two lines by hand and never re-wrap while the cards resize */
  /* exact scale and a fixed optical size, so the lines shrink in proportion on smaller screens (SF widens its small sizes) */
  .values h3 { white-space: nowrap; font-size: calc(20 * var(--u)); font-variation-settings: "opsz" 20; }
}

/* ---------- Portfolio ---------- */
.portfolio {
  background: var(--red-portfolio);
  color: #fff;
  padding: var(--sec-y) var(--wide);
}
.pf-head { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: 16px; }
.portfolio h2 { font-size: var(--fs-h2); font-weight: 400; line-height: 1.333; letter-spacing: -0.02em; text-transform: capitalize; }
.pf-nav { display: flex; align-items: center; gap: 24px; font-family: var(--mono); }
/* Figma 5:479: 56px square, 10% white, + marks on the corners */
.pf-btn {
  position: relative;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  border: 0;
  background: rgb(255 255 255 / 0.1);
  color: #fff;
  transition: scale 150ms var(--ease);
}
.pf-btn:active { scale: 0.96; }
.pf-btn svg { position: relative; }
.pf-timer { position: absolute; inset: 0; background: rgb(255 255 255 / 0.2); transform: scaleX(0); transform-origin: 0 50%; }
.pf-next.run .pf-timer { animation: pf-timer 5s linear forwards; } /* showcase pace: long enough to read a card */
.pf-nav.paused .pf-timer { animation-play-state: paused; }
@keyframes pf-timer { to { transform: scaleX(1); } }

/* the viewport clips the sliding row; its padding keeps the corner marks inside the clip */
.pf-viewport { overflow: clip; margin: 24px calc(-1 * var(--pad)) 0; padding: 8px var(--pad); touch-action: pan-y; }
.pf-track {
  --gap: 16px;
  display: flex;
  gap: var(--gap);
  transition: transform 600ms var(--ease-smooth);
}
.pf-card { flex: 0 0 var(--card); min-width: 0; }
/* the script puts the last card in front; this pulls it out of view to the left, so the left edge has a neighbour too */
.pf-track { --card: 100%; width: 100%; margin-left: calc(-1 * (var(--card) + var(--gap))); } /* explicit width: a negative margin would otherwise widen it */
/* one screen tall at every size: title and arrows on top, the carousel at the bottom */
.portfolio { display: flex; flex-direction: column; justify-content: space-between; gap: 32px; } /* min-height 100svh is set with the hero */
@media (max-width: 1023px) {
  .pf-head { flex-wrap: nowrap; align-items: center; }
  .pf-nav { gap: 12px; flex-shrink: 0; }
  /* one card, centred; the gap is wider than the side padding so the neighbours stay out of view */
  .pf-viewport { margin: 0 calc(-1 * var(--pad)); padding: 8px var(--pad); }
  .pf-track { --gap: calc(2 * var(--pad)); }
}
.pf-frame {
  position: relative;
  isolation: isolate;
  container-type: inline-size;
  aspect-ratio: 586.67 / 640;
  --m: 16px;
  --plus: var(--plus-l);
}
/* hover fill rises from the bottom, same as the value cards */
.pf-frame::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: rgb(255 255 255 / 0.1);
  transform: scaleY(0);
  transform-origin: 50% 100%;
  transition: transform 250ms var(--ease-smooth);
}
.pf-num {
  position: absolute;
  inset: -3.41cqw 0 auto;
  text-align: center;
  font-size: 38.18cqw;
  font-weight: 700;
  line-height: 1.143;
  color: rgb(255 255 255 / 0.2);
  transform: translateY(7.84cqw) scale(0.643);
  transform-origin: 50% 0;
  transition: transform 250ms var(--ease-smooth), color 200ms var(--ease-smooth);
}
.pf-frame img {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 73.13cqw;
  height: auto;
  translate: -50% -50%;
  scale: 0.853;
  filter: drop-shadow(1.5px 3px 6px rgb(0 0 0 / 0.12));
  transition: scale 250ms var(--ease-smooth);
}
@media (hover: hover) {
  .pf-card:hover .pf-frame::before { transform: none; }
  .pf-card:hover .corners i { opacity: 1; rotate: 0deg; }
  .pf-card:hover .pf-num { transform: none; color: #fff; }
  .pf-card:hover .pf-frame img { scale: 1; }
  .pf-card:hover .pf-tags .br::before { translate: -4px 0; }
  .pf-card:hover .pf-tags .br::after { translate: 4px 0; }
}

.pf-card { position: relative; cursor: pointer; }
/* the whole card is the button; it sits on top so a click anywhere opens the details */
.pf-open { position: absolute; inset: 0; z-index: 1; border: 0; background: none; cursor: pointer; }
.pf-meta { display: grid; gap: 8px; margin-top: 24px; }
.pf-meta h3 { font-size: var(--fs-body); font-weight: 400; line-height: 1.6; }
.pf-tags .br { display: inline-block; } /* lets the scramble hold each tag's width */
.pf-tags { display: flex; flex-wrap: wrap; gap: 16px; font-family: var(--mono); font-size: var(--fs-label); line-height: 1.5; text-transform: uppercase; }

@media (min-width: 1024px) {
  .portfolio { justify-content: flex-start; gap: calc(128 * var(--u)); min-height: 0; padding-block: calc(100 * var(--u)); } /* same rhythm as the value section */
  .pf-viewport { margin: -8px; padding: 8px; }
  .pf-track { --gap: clamp(24px, calc(2.083 * var(--vw)), 40px); }
  .pf-track { --card: calc((100% - 2 * var(--gap)) / 3); }
}

/* ---------- Project details dialog ---------- */
html:has(.pd[open]) { overflow: hidden; }
.pd {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  border: 0;
  padding: clamp(16px, calc(2.083 * var(--vw)), 40px) var(--wide);
  background: none;
  color: #fff;
  overflow: auto;
}
.pd[open] { display: flex; flex-direction: column; gap: clamp(24px, calc(2.2 * var(--vw)), 42px); }
.pd::backdrop { background: rgb(1 1 1 / 0.92); } /* Figma 50%; darker so the page behind doesn't read through the title */
.pd-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.pd-head > div:first-child { flex: 1; min-width: 0; }
/* one row always, also while the letters are scrambling; a name too long for a phone ends in … */
.pd-title { font-size: 16px; font-weight: 400; line-height: 24px; text-transform: uppercase; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pd-tags { display: flex; gap: 16px; margin-top: 8px; font-size: 12px; line-height: 18px; text-transform: uppercase; }
.pd-tags .br, .pf-tags .br { white-space: nowrap; }
.pd-tags .br { display: inline-block; }
.pd-actions { display: flex; align-items: center; gap: 16px; }
.pd-actions .br {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  min-width: 44px;
  min-height: 44px;
  border: 0;
  background: none;
  font-size: 16px;
  line-height: 24px;
}
.pd-actions .br::before, .pd-actions .br::after { margin: 0; }
.pd-close {
  position: relative;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-inline-start: 8px;
  border: 0;
  background: rgb(255 255 255 / 0.15);
  color: #fff;
}
/* Figma: 588 | 282 282 columns, the big spread spans both rows */
.pd-gallery { display: grid; grid-template-columns: 2fr 1fr 1fr; grid-template-rows: 1fr 1fr; gap: 24px; flex: 1; min-height: 0; }
.pd-a { grid-row: 1 / 3; }
.pd-b { grid-column: 2 / 4; }
.pd-frame { position: relative; display: grid; place-items: center; min-height: 0; margin: 0; background: #e2e2e2; --m: 16px; --plus: var(--plus-l); }
.pd-frame img { width: 92%; height: 92%; object-fit: contain; }
.pd-a img { width: 96%; }
.pd-frame .corners i { transition: rotate 250ms var(--ease-smooth); }
.pd-frame img { transition: scale 300ms var(--ease-smooth); }
@media (hover: hover) {
  .pd-frame:hover img { scale: 1.05; }
}

@media (max-width: 767px) {
  .pd-gallery { grid-template-columns: 1fr 1fr; grid-template-rows: none; flex: none; }
  .pd-a, .pd-b { grid-row: auto; grid-column: 1 / -1; }
  .pd-a { aspect-ratio: 588 / 640; }
  .pd-b { aspect-ratio: 588 / 308; }
  .pd-c, .pd-d { aspect-ratio: 282 / 308; }
}

/* opening: backdrop fades, header rises, each spread is revealed by a mask rising from its base */
@media (prefers-reduced-motion: no-preference) {
  .pd[open]::backdrop { animation: fade 250ms var(--ease-smooth); }
  .pd.play .pd-head { animation: rise 500ms var(--ease) backwards; }
  .pd.play .pd-frame { animation: pd-in 600ms var(--ease-smooth) calc(80ms + var(--k) * 70ms) backwards; }
  .pd.closing, .pd.closing::backdrop { animation: fade 200ms var(--ease-smooth) reverse forwards; }
}
@keyframes fade { from { opacity: 0; } }
@keyframes pd-in { from { clip-path: inset(100% 0 0 0); } }

/* ---------- Contact ---------- */
.contact { background: var(--paper); padding: var(--sec-y) var(--pad); }
.contact-intro { display: flex; flex-direction: column; min-width: 0; } /* the one-line title overflows into the gap instead of widening the column */
.contact h2 { font-size: var(--fs-h2-cta); font-weight: 400; line-height: 1.125; letter-spacing: -0.02em; white-space: nowrap; } /* one line; on desktop it may run into the column gap */
.contact-intro p { max-width: 430px; margin-top: 40px; font-size: var(--fs-body); line-height: 1.6; text-wrap: pretty; }
.contact-social { display: flex; gap: 32px; margin-top: 48px; padding-left: 3px; }
.contact-social .social { background: none; color: var(--red-icon); --mark: var(--red-icon); }
.contact-social .social { --btn-fill: rgb(249 50 31 / 0.08); }

.form { display: grid; gap: 40px; margin-top: 64px; }
.field label { display: block; font-size: var(--fs-body); font-weight: 500; line-height: 1.5; }
.field input, .field textarea {
  display: block;
  width: 100%;
  padding: 16px 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  border-radius: 0;
  font-size: var(--fs-input);
  line-height: 1.667;
  /* two underlines drawn over the border: grey on hover, black (or red when invalid) on focus, both fill left to right */
  --fill: var(--ink);
  background:
    linear-gradient(var(--fill), var(--fill)) 0 100% / 0 2px no-repeat,
    linear-gradient(#8c8c8c, #8c8c8c) 0 100% / 0 1px no-repeat;
  background-origin: border-box;
  transition: background-size 350ms var(--ease-smooth);
}
.field textarea { height: 140px; resize: vertical; }
.field ::placeholder { color: var(--hint); opacity: 1; transition: color 200ms; }
.field input:hover, .field textarea:hover { background-size: 0 2px, 100% 1px; }
.field input:hover::placeholder, .field textarea:hover::placeholder { color: #595959; }
/* focus ring replaced by the black underline filling in, which reads as the field's own edge */
.field input:focus, .field textarea:focus { outline: none; background-size: 100% 2px, 100% 1px; }
.field :user-invalid { --fill: var(--red-button); background-size: 100% 2px, 100% 1px; }
.field-error { display: none; margin-top: 8px; font-size: 14px; line-height: 1.4; color: #b3200f; }
.field:has(:user-invalid) .field-error { display: block; }
.btn-cta { justify-self: start; background: var(--red-button); color: #fff; font-family: var(--mono); --mark: var(--red-button); }
.btn-cta { --btn-fill: #c92212; }
.form-status { font-size: 16px; line-height: 1.5; }
.form-status:empty { display: none; }


@media (min-width: 1024px) {
  .contact {
    display: grid;
    grid-template-columns: 430fr 587fr;
    column-gap: clamp(40px, calc(10.26 * var(--vw)), 197px);
    padding-inline: max(var(--pad), calc(6 * var(--vw)));
  }
  .contact-social { margin-top: auto; padding-top: 48px; }
  .form { margin-top: 0; }
  .form-status { grid-column: 1 / -1; }
  /* the copy spans exactly the one-line title: the intro sizes to the title, and the copy adds no width of its own */
  .contact-intro { width: fit-content; }
  .contact-intro p { max-width: none; contain: inline-size; }
}

/* phones: title, copy and social icons stacked on top, the form below; fields a touch roomier */
@media (max-width: 767px) {
  .contact { min-height: 100svh; display: flex; flex-direction: column; justify-content: center; padding-block: 48px; }
  .contact h2 { font-size: min(36px, 10.5vw); } /* still one line on 320-wide phones */
  .contact-intro p { max-width: none; margin-top: 16px; font-size: 15px; line-height: 1.55; }
  .contact-social { gap: 16px; margin-top: 20px; padding-left: 3px; } /* room so neighbouring + marks do not touch */
  .contact-social .social { width: 48px; height: 48px; }
  .form { gap: 24px; margin-top: 36px; }
  .field label { font-size: 16px; line-height: 1.5; }
  .field input, .field textarea { padding: 12px 0; font-size: 18px; line-height: 1.5; }
  .field textarea { height: 104px; }
}

/* ---------- Footer ---------- */
.site-footer {
  display: grid;
  gap: 40px;
  /* side margin as on nine0.co.id: 110 of 1440 on phones, 66 of 1440 from 768 up, always of the real viewport width */
  padding: 34px calc(7.639vw / var(--z)) 32px;
  background: var(--footer);
  color: var(--footer-ink);
}
.f-logos { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 24px 40px; }
.f-logos img { height: auto; }
.f-logos img:nth-child(3) { margin-bottom: 19px; }
address {
  margin-top: 34px;
  font-style: normal;
  font-family: "Pathway Extreme", var(--sans);
  font-size: 12px;
  line-height: 16px;
}
address p + p { margin-top: 16px; }
address a:hover { text-decoration: underline; }

.f-right { display: flex; flex-direction: column; justify-content: space-between; gap: 40px; }
.f-menu { font-family: var(--display); font-size: 14px; line-height: 30px; text-transform: uppercase; }
.f-menu a { display: inline-flex; align-items: center; gap: 8px; }
.f-menu a:hover { color: #fff; }
.f-top { color: var(--orange-text); }
.f-top::before { content: ""; width: 13px; height: 11.25px; background: currentColor; clip-path: polygon(50% 0, 100% 100%, 0 100%); }
.f-design { display: flex; align-items: flex-start; gap: 12px; font-family: var(--display); font-size: 9px; line-height: 1; }
.f-copy { margin-top: 15px; font-family: Inter, var(--sans); font-size: 12px; line-height: 25px; }

@media (min-width: 768px) {
  .site-footer { grid-template-columns: 1fr auto; padding-inline: calc(4.5833vw / var(--z)); }
  .f-right, .f-menu { align-items: flex-end; text-align: right; }
  .f-menu { display: flex; flex-direction: column; }
  .f-design { justify-content: flex-end; }
}
/* phones: everything centred, in the order logos, menu, address, credit; the three logos share one row */
@media (max-width: 767px) {
  .site-footer { justify-items: center; text-align: center; gap: 48px; }
  .f-left, .f-right { display: contents; }
  .f-logos { order: 1; flex-wrap: nowrap; justify-content: center; gap: 24px; }
  .f-logos img:nth-child(1) { width: 96px; }
  .f-logos img:nth-child(2) { width: 76px; }
  .f-logos img:nth-child(3) { width: 96px; margin-bottom: 14px; }
  .f-menu { order: 2; display: flex; flex-direction: column; align-items: center; }
  address { order: 3; margin-top: 0; }
  .f-credit { order: 4; display: grid; justify-items: center; }
  .f-design { flex-direction: column; align-items: center; gap: 10px; }
  .f-copy { line-height: 1.5; }
}
@media (min-width: 768px) {
  .m-only { display: none; }
}

/* ---------- First-seen motion ---------- */
/* .js is set in <head> only when the animations will run, so nothing stays hidden without them */
.js .rv:not(.in) { opacity: 0; }
.rv.in { animation: rise 700ms var(--ease) var(--d, 0ms) backwards; }
@keyframes rise { from { opacity: 0; translate: 0 24px; } }
#site-nav a { display: inline-block; } /* lets the letter scramble hold the link's width */

/* justified as in Figma, never hyphenated (client request). The script sets each line as a .jl block
   after choosing even line breaks, so every line but the last is stretched to the full width. */
.value-text, .contact-intro p { text-align: justify; hyphens: none; text-wrap: wrap; }
.jl { display: block; text-align-last: justify; }
.jl:last-child { text-align-last: auto; }
@media (min-width: 1440px) {
  .contact { padding-inline: calc(var(--x0) + 353 * var(--u)); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .art-logo, .art-logo-in { animation: none; }
  *, *::before, *::after { transition-duration: 0s !important; }
}
