/* Urooj Khan portfolio
   Palette: cutting-mat green, white board, process black, with process magenta (cut)
   and cyan (crease) kept for dieline lines only. One type family, Archivo, used at
   three widths: expanded for display, normal for reading, condensed for spec text. */

@font-face {
  font-family: "Archivo";
  src: url("../fonts/archivo-variable.woff2") format("woff2");
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-display: swap;
}

@property --line {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

/* Values main.js sets on the one element that reads them (see startStory).
   Not inherited, so changing one restyles that element alone instead of
   everything inside it. The initial values match the resting box. */
@property --rx { syntax: "<angle>"; inherits: false; initial-value: -16deg; }
@property --ry { syntax: "<angle>"; inherits: false; initial-value: -34deg; }
@property --rz { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@property --zoom { syntax: "<number>"; inherits: false; initial-value: 1; }
@property --drop { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --dark { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --shadow { syntax: "<number>"; inherits: false; initial-value: 1; }
@property --spread { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --plates-on { syntax: "<number>"; inherits: false; initial-value: 0; }
@property --ink-on { syntax: "<number>"; inherits: false; initial-value: 1; }

:root {
  --mat: #2f5d46;
  --mat-line: rgb(222 238 205 / 0.11);
  --mat-line-major: rgb(222 238 205 / 0.22);
  --board: #eff1ee;
  --white: #ffffff;
  --ink: #231f20;
  --muted: #535b57;
  --kraft: #b48a5a;
  --kraft-light: #e9dbc6;
  --ease: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-out: cubic-bezier(0.2, 0.7, 0.2, 1);
  --gutter: clamp(1rem, 4vw, 3.5rem);
  --max: 86rem;
  --edge: max(var(--gutter), calc((100% - var(--max)) / 2));
  --gap: clamp(1rem, 3vw, 2.5rem);
}

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

html {
  -webkit-text-size-adjust: 100%;
}

/* Anchor jumps stop below the header, which stays on screen. This is
   scroll-margin on the targets, not scroll-padding on html: with
   scroll-padding, Chromium treats the sticky header's own links as covered
   and scrolls the page on every Tab. */
[id] {
  scroll-margin-top: 5rem;
}

body {
  margin: 0;
  background: var(--board);
  color: var(--ink);
  font-family: "Archivo", system-ui, sans-serif;
  font-size: 1.0625rem;
  font-weight: 400;
  font-stretch: 100%;
  line-height: 1.6;
  font-kerning: normal;
}

@media (min-width: 900px) {
  body {
    font-size: 1.125rem;
  }
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

a {
  color: inherit;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}

a:hover {
  text-decoration-thickness: 2px;
}

:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}

h1,
h2,
h3,
h4,
p,
figure,
dl,
dd {
  margin: 0;
}

p + p {
  margin-top: 1em;
}

h1,
h2,
h3,
h4 {
  font-weight: 700;
  line-height: 1.05;
  text-wrap: balance;
}

button {
  font: inherit;
  color: inherit;
}

.skip {
  position: absolute;
  left: var(--gutter);
  top: -5rem;
  z-index: 30;
  padding: 0.5rem 1rem;
  background: var(--ink);
  color: var(--board);
}

.skip:focus {
  top: 1rem;
}

/* Display type: expanded and heavy, like a carton's brand panel. */
.cap-name,
.cap-title,
.work-head :is(h1, h2),
.about > :is(h1, h2),
.experience > h1,
.contact h2,
.case-heading h1,
.next-title,
.missing-main h1 {
  font-stretch: 125%;
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 0.9;
}

/* Cutting mat: 1-unit grid with a heavier line every five, as on a self-healing mat. */
.mat {
  background-color: var(--mat);
  background-image:
    linear-gradient(var(--mat-line-major) 1px, transparent 1px),
    linear-gradient(90deg, var(--mat-line-major) 1px, transparent 1px),
    linear-gradient(var(--mat-line) 1px, transparent 1px),
    linear-gradient(90deg, var(--mat-line) 1px, transparent 1px);
  background-size: 10rem 10rem, 10rem 10rem, 2rem 2rem, 2rem 2rem;
  color: var(--board);
}

/* ------------------------------------------------------------------ header and footer */

/* The header stays on screen everywhere. Over the cutting mat (the home
   story, the 404 page) it floats with no background; elsewhere it has a
   frosted board background so the page reads through it. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem 1.5rem;
  padding: 1.25rem var(--edge);
  background: rgb(239 241 238 / 0.94);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}

.site-header.on-mat {
  color: var(--board);
  background: rgb(47 93 70 / 0.94);
}

/* Over the home story the header floats, with no background. */
.home .site-header.on-mat {
  position: fixed;
  inset: 0 0 auto;
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.home .site-header {
  justify-content: flex-end;
}

.home .wordmark {
  display: none;
}

.wordmark {
  font-stretch: 125%;
  font-weight: 800;
  text-decoration: none;
}

.site-header nav {
  display: flex;
  gap: 1.5rem;
}

.site-header nav a {
  font-weight: 500;
  text-decoration: none;
}

@media (max-width: 480px) {
  .site-header nav {
    gap: 1rem;
  }
}

/* On phones the header is two rows. The name row scrolls away and the
   links row stays, so the pinned part is short. */
@media (max-width: 600px) {
  .site-header {
    top: -2.2rem;
    row-gap: 0.5rem;
    padding-block: 0.5rem 0.6rem;
  }

  .wordmark {
    flex-basis: 100%;
    line-height: 1.7rem;
  }

  .site-header nav {
    line-height: 1.7rem;
  }

  /* Tabbing to the name brings its row back into view. */
  .site-header:focus-within {
    top: 0;
  }
}

.site-header {
  view-transition-name: site-header;
}

.site-header nav a:hover,
.site-header nav a.here {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.3em;
}

.site-footer {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 2rem var(--edge);
  font-size: 0.875rem;
  font-stretch: 87.5%;
}

/* ------------------------------------------------------------------ the scroll story
   The home page opens on a pinned scene. As the page scrolls the box spins,
   unfolds into its dieline, splits into CMYK plates, lands back in register,
   then folds up and opens. main.js turns the scroll position into the CSS
   variables the scene reads. Without JavaScript .story-on is never set: the
   box sits still and the captions read as a list. */

.story {
  position: relative;
}

.story-pin {
  position: relative;
  display: grid;
  gap: 2rem;
  padding: 5.5rem var(--edge) 4rem;
  overflow: hidden;
}

.story-night {
  position: absolute;
  inset: 0;
  background: #1b1d1c;
  opacity: var(--dark, 0);
  pointer-events: none;
  /* Its own layer, so fading it does not repaint the cutting mat behind it. */
  will-change: opacity;
}

.story-steps {
  display: none;
}

.story-scene {
  position: relative;
  height: min(70vh, 40rem);
}

.story-captions {
  position: relative;
  display: grid;
  gap: 2.5rem;
  max-width: 34rem;
}

.cap-name {
  font-size: clamp(3.5rem, 8.5vw, 8.5rem);
  line-height: 0.84;
}

.cap-title {
  font-size: clamp(2.25rem, 4.4vw, 4.25rem);
  text-wrap: balance;
}

.cap-text {
  max-width: 30ch;
  margin-top: 1.25rem;
  font-size: clamp(1.125rem, 1.5vw, 1.375rem);
  line-height: 1.45;
}

.cap-link {
  display: inline-block;
  margin-top: 1.5rem;
  padding: 0.65em 1.25em;
  border: 1.5px solid currentColor;
  border-radius: 999px;
  font-weight: 600;
  text-decoration: none;
}

.cap-link:hover {
  background: var(--board);
  color: var(--mat);
}

.story-hint {
  display: none;
}

/* Pinned and scroll-driven. On phones the screen grows when the browser's
   toolbars slide away, so the pin is as tall as the screen without them
   (lvh). Everything inside is laid out in the part that is always visible
   (lvh minus --toolbar, which is the height of the toolbars), so nothing sits
   under the toolbars and no page background shows below the pin. */
.story-on .story {
  height: 650vh;
}

.story-on .story-pin {
  --toolbar: 0px;
  position: sticky;
  top: 0;
  display: block;
  height: 100vh;
  height: 100lvh;
  padding: 0;
}

@supports (height: 1lvh) {
  .story-on .story-pin {
    --toolbar: calc(100lvh - 100svh);
  }
}

.story-on .story-steps {
  position: absolute;
  left: var(--edge);
  top: 4.75rem;
  z-index: 2;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: 0.9375rem;
  font-stretch: 87.5%;
}

.story-steps li {
  opacity: 0.6;
}

.story-steps li[aria-current] {
  opacity: 1;
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.35em;
}

.story-on .story-scene {
  position: absolute;
  top: 0;
  right: 0;
  bottom: var(--toolbar);
  width: 62%;
  height: auto;
  /* Vertical swipes scroll and pinches zoom; sideways drags turn the box.
     Dragging doesn't select the text on the box. */
  touch-action: pan-y pinch-zoom;
  -webkit-user-select: none;
  user-select: none;
  cursor: grab;
}

.story-on .story-scene:active {
  cursor: grabbing;
}

.story-on .story-captions {
  position: absolute;
  left: var(--edge);
  bottom: calc(var(--toolbar) + 9vh);
  display: block;
  width: min(34%, 30rem);
  height: 60vh;
}

.story-on .cap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  opacity: 0;
}

.story-on .cap:first-child {
  opacity: 1;
}

.story-on .story-hint {
  position: absolute;
  right: var(--edge);
  bottom: calc(var(--toolbar) + 2rem);
  display: block;
  margin: 0;
  font-size: 0.9375rem;
  font-stretch: 87.5%;
}

/* Phones and portrait tablets: box on top, captions underneath. */
@media (max-width: 760px), (orientation: portrait) and (max-width: 1100px) {
  .story-on .story-steps {
    gap: 0.5rem 0.9rem;
    font-size: 0.875rem;
  }

  .story-on .story-scene {
    top: 6.5rem;
    bottom: calc(var(--toolbar) + (100% - var(--toolbar)) * 0.4);
    width: 100%;
  }

  .story-on .story-captions {
    left: var(--edge);
    right: var(--edge);
    bottom: calc(var(--toolbar) + 4vh);
    width: auto;
    height: calc((100% - var(--toolbar)) * 0.38);
  }

  .cap-name {
    font-size: clamp(3rem, 16vw, 5rem);
  }

  .cap-title {
    font-size: clamp(1.875rem, 9vw, 2.75rem);
  }

  .story-on .story-hint {
    display: none;
  }
}

/* Short phones: tighter captions so the longest one and its button fit
   under the box. */
@media (max-width: 760px) and (max-height: 740px) {
  .cap-title {
    font-size: clamp(1.625rem, 7.5vw, 2.25rem);
  }

  .cap-text {
    margin-top: 0.75rem;
    font-size: 1rem;
    line-height: 1.4;
  }

  .cap-link {
    margin-top: 0.9rem;
    padding: 0.5em 1.1em;
  }
}

/* Short landscape screens (phones on their side, zoomed-in laptops): box on
   the right, captions on the left, both fitted to the height. */
@media (max-height: 560px) and (orientation: landscape) {
  .story-on .story-steps {
    top: 3.75rem;
  }

  .story-on .story-scene {
    top: 0;
    bottom: var(--toolbar);
    width: 60%;
  }

  .story-on .story-captions {
    left: var(--edge);
    right: auto;
    top: 6rem;
    bottom: calc(var(--toolbar) + 1.25rem);
    width: 38%;
    height: auto;
  }

  .cap-name {
    font-size: clamp(2.25rem, 13vh, 4.5rem);
  }

  .cap-title {
    font-size: clamp(1.5rem, 8vh, 2.75rem);
  }

  .cap-text {
    margin-top: 0.6rem;
    font-size: 1rem;
    line-height: 1.35;
  }

  .cap-link {
    margin-top: 0.75rem;
  }

  .story-on .story-hint {
    display: none;
  }
}

/* Where the scroll hasn't reached yet: the folded box at rest. main.js
   overwrites these on the element as the page scrolls. */
.scene {
  --night: #1b1d1c;
  --f-tuck: 1;
  --f-lid: 1;
  --f-dust: 1;
  --f-glue: 1;
  --f-sidel: 1;
  --f-back: 1;
  --f-sider: 1;
  --flat: 0;
  --line: 0;
  --rx: -16deg;
  --ry: -34deg;
  --rz: 0deg;
  --zoom: 1;
  --drop: 0;
  --spread: 0;
  --plates-on: 0;
  --ink-on: 1;
  --shadow: 1;
  --lid-open: 0;
  --rise: 0;
  --covers-on: 0;
  position: relative;
  width: 100%;
  height: 100%;
  container-type: size;
  overflow: hidden;
}

.scene-stage {
  --u: 1.62cqmin;
  --s-flat: 0.62;
  --w: calc(var(--u) * 20);
  --d: calc(var(--u) * 12);
  --h: calc(var(--u) * 28);
  --g: calc(var(--u) * 3);
  --t: calc(var(--u) * 4);
  --df: calc(var(--u) * 6.5);
  --flat-x: calc(-1 * (var(--w) / 2 + var(--d) + var(--g) / 2));
  --rule: calc(1.5px / var(--s-flat));
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  perspective: calc(var(--u) * 240);
}

/* Browsers without container units (Safari before 16) size the box by the
   screen instead; it comes out within a few percent of the same size. */
@supports not (width: 1cqmin) {
  .scene-stage {
    --u: 1.62vmin;
  }
}

.scene-shadow {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--u) * 29);
  height: calc(var(--u) * 5.6);
  translate: -46% calc(var(--u) * 14);
  background: radial-gradient(closest-side, rgb(0 0 0 / 0.42), transparent);
  opacity: var(--shadow);
}

.spin {
  width: var(--w);
  height: var(--h);
  transform-style: preserve-3d;
  transform: translateY(calc(var(--u) * var(--drop))) scale(var(--zoom)) rotateX(var(--rx)) rotateY(var(--ry)) rotateZ(var(--rz));
}

.carton {
  position: relative;
  width: var(--w);
  height: var(--h);
  transform-style: preserve-3d;
  transform-origin: calc(var(--w) / 2) calc(var(--h) / 2);
  transform:
    translateX(calc(var(--flat-x) * var(--s-flat) * var(--flat)))
    scale(calc(1 - (1 - var(--s-flat)) * var(--flat)))
    translateZ(calc(var(--d) / 2 * (1 - var(--flat))));
}

/* ---- panels: each one hangs off the panel it folds from */

.pnl {
  position: absolute;
  transform-style: preserve-3d;
}

.face {
  --cut: rgb(236 0 140 / var(--line));
  --crease: rgb(0 174 239 / var(--line));
  position: absolute;
  inset: 0;
  border: var(--rule) solid transparent;
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.face.out {
  background: var(--white);
}

.face.in {
  inset: 1px;
  background: var(--kraft);
  transform: rotateY(180deg);
}

.side-r > .face.out::after,
.side-l > .face.out::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgb(35 31 32 / 0.13);
  opacity: calc(1 - var(--flat));
}

.dust > .face.out,
.glue > .face.out,
.tuck > .face.out {
  transform: translateZ(-1px);
}

.dust > .face.in,
.glue > .face.in,
.tuck > .face.in {
  transform: translateZ(-1px) rotateY(180deg);
}

.front { left: 0; top: 0; width: var(--w); height: var(--h); }
.side-r, .side-l { left: 100%; top: 0; width: var(--d); height: var(--h); transform-origin: left center; }
.back { left: 100%; top: 0; width: var(--w); height: var(--h); transform-origin: left center; }
.glue { left: 100%; top: 0; width: var(--g); height: var(--h); transform-origin: left center; }
.lid-t, .tuck-t, .dust-t { left: 0; bottom: 100%; transform-origin: center bottom; }
.lid-b, .tuck-b, .dust-b { left: 0; top: 100%; transform-origin: center top; }
.lid { width: var(--w); height: var(--d); }
.tuck { width: var(--w); height: var(--t); }
.dust { width: var(--d); height: var(--df); }

.side-r { transform: rotateY(calc(90deg * var(--f-sider))); }
.back { transform: rotateY(calc(90deg * var(--f-back))); }
.side-l { transform: rotateY(calc(90deg * var(--f-sidel))); }
.glue { transform: rotateY(calc(90deg * var(--f-glue))); }
.dust-t { transform: rotateX(calc(90deg * var(--f-dust))); }
.dust-b { transform: rotateX(calc(-90deg * var(--f-dust))); }
.lid-t { transform: rotateX(calc(90deg * var(--f-lid) - 125deg * var(--lid-open))); }
.lid-b { transform: rotateX(calc(-90deg * var(--f-lid))); }
.tuck-t { transform: rotateX(calc(90deg * var(--f-tuck) * (1 - var(--lid-open)))); }
.tuck-b { transform: rotateX(calc(-90deg * var(--f-tuck))); }

/* Dieline: solid magenta where the board is cut, dashed cyan where it folds. */
.front > .face.out { border-left-color: var(--cut); border-bottom-color: var(--cut); }
.side-r > .face.out, .side-l > .face.out { border-left: var(--rule) dashed var(--crease); }
.back > .face.out { border-left: var(--rule) dashed var(--crease); border-top-color: var(--cut); }
.glue > .face.out { border-color: var(--cut); border-left: var(--rule) dashed var(--crease); border-radius: 0 calc(var(--u) * 2.5) calc(var(--u) * 2.5) 0; }
.lid-t > .face.out { border-bottom: var(--rule) dashed var(--crease); border-left-color: var(--cut); border-right-color: var(--cut); }
.lid-b > .face.out { border-top: var(--rule) dashed var(--crease); border-left-color: var(--cut); border-right-color: var(--cut); }
.tuck-t > .face.out { border-color: var(--cut); border-bottom: var(--rule) dashed var(--crease); border-radius: calc(var(--u) * 3) calc(var(--u) * 3) 0 0; }
.tuck-b > .face.out { border-color: var(--cut); border-top: var(--rule) dashed var(--crease); border-radius: 0 0 calc(var(--u) * 3) calc(var(--u) * 3); }
.dust-t > .face.out { border-color: var(--cut); border-bottom: var(--rule) dashed var(--crease); border-radius: calc(var(--u) * 1) calc(var(--u) * 5) 0 0; }
.dust-b > .face.out { border-color: var(--cut); border-top: var(--rule) dashed var(--crease); border-radius: 0 0 calc(var(--u) * 5) calc(var(--u) * 1); }

/* ---- the print on the panels */

.art {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: calc(var(--u) * 1.4);
  color: var(--ink);
  line-height: 1.15;
  overflow: hidden;
  opacity: var(--ink-on);
}

.c-name { margin: 0; font-size: calc(var(--u) * 3.1); font-stretch: 125%; font-weight: 800; line-height: 0.9; letter-spacing: -0.01em; }
.c-role { margin: calc(var(--u) * 1.1) 0 0; font-size: calc(var(--u) * 1.45); font-stretch: 87.5%; white-space: pre-line; }
.c-net { margin: auto calc(var(--u) * -1.4) calc(var(--u) * -1.4); height: 36%; box-sizing: border-box; display: flex; align-items: flex-end; padding: calc(var(--u) * 1.4); background: var(--mat); color: var(--board); font-size: calc(var(--u) * 1.3); font-stretch: 87.5%; font-weight: 600; }
.c-head { margin: 0; font-size: calc(var(--u) * 1.45); font-stretch: 87.5%; font-weight: 700; }
.c-fine { margin: calc(var(--u) * 0.6) 0 0; font-size: calc(var(--u) * 1.1); font-stretch: 75%; line-height: 1.3; }
.back-art .c-fine { font-size: calc(var(--u) * 1.35); font-stretch: 87.5%; }
.c-bar { margin-top: auto; display: grid; grid-template-columns: repeat(8, 1fr); height: calc(var(--u) * 1.4); }
.c-bar i:nth-child(1) { background: #00aeef; }
.c-bar i:nth-child(2) { background: #ec008c; }
.c-bar i:nth-child(3) { background: #fff200; }
.c-bar i:nth-child(4) { background: #231f20; }
.c-bar i:nth-child(5) { background: #80d6f7; }
.c-bar i:nth-child(6) { background: #f580c5; }
.c-bar i:nth-child(7) { background: #fff880; }
.c-bar i:nth-child(8) { background: #918f90; }
.c-reg { position: relative; display: block; width: calc(var(--u) * 2.6); aspect-ratio: 1; border: 1px solid var(--ink); border-radius: 50%; }
.c-reg::before, .c-reg::after { content: ""; position: absolute; background: var(--ink); }
.c-reg::before { left: -25%; right: -25%; top: 50%; height: 1px; }
.c-reg::after { top: -25%; bottom: -25%; left: 50%; width: 1px; }
.side-l .art { justify-content: space-between; }

/* ---- CMYK plates: four inked copies of the dieline that lift off the sheet */

.plates {
  position: absolute;
  left: 50%;
  top: 50%;
  width: calc(var(--u) * 67);
  height: calc(var(--u) * 60);
  margin: calc(var(--u) * -30) 0 0 calc(var(--u) * -33.5);
  transform-style: preserve-3d;
  transform: scale3d(var(--s-flat), var(--s-flat), var(--s-flat));
  pointer-events: none;
}

.plate {
  position: absolute;
  inset: 0;
  opacity: var(--plates-on);
  transform: translateZ(calc(var(--u) * 12 * var(--spread) * var(--i) + 2px));
}

.plate-y { --i: 1; --c: #fff200; }
.plate-m { --i: 2; --c: #ec008c; }
.plate-c { --i: 3; --c: #00aeef; }
.plate-k { --i: 4; --c: #eff1ee; }

.plate i {
  position: absolute;
  display: block;
  background: radial-gradient(circle, var(--c) 0 34%, transparent 37%) 0 0 / calc(var(--u) * 1.1) calc(var(--u) * 1.1);
  box-shadow: 0 0 0 calc(var(--u) * 0.15) var(--c);
}

.plate .solid {
  background: var(--c);
  box-shadow: none;
}

/* The dieline's footprint, in units of --u (the net is 67 wide, 60 tall). */
.p-tuckt { left: 0; top: 0; width: calc(var(--u) * 20); height: calc(var(--u) * 4); border-radius: calc(var(--u) * 3) calc(var(--u) * 3) 0 0; }
.p-lidt { left: 0; top: calc(var(--u) * 4); width: calc(var(--u) * 20); height: calc(var(--u) * 12); }
.p-dust1, .p-dust2 { top: calc(var(--u) * 9.5); width: calc(var(--u) * 12); height: calc(var(--u) * 6.5); border-radius: calc(var(--u) * 1) calc(var(--u) * 5) 0 0; }
.p-dust3, .p-dust4 { top: calc(var(--u) * 44); width: calc(var(--u) * 12); height: calc(var(--u) * 6.5); border-radius: 0 0 calc(var(--u) * 5) calc(var(--u) * 1); }
.p-dust1, .p-dust3 { left: calc(var(--u) * 20); }
.p-dust2, .p-dust4 { left: calc(var(--u) * 52); }
.p-body { left: 0; top: calc(var(--u) * 16); width: calc(var(--u) * 64); height: calc(var(--u) * 28); }
.p-glue { left: calc(var(--u) * 64); top: calc(var(--u) * 16); width: calc(var(--u) * 3); height: calc(var(--u) * 28); border-radius: 0 calc(var(--u) * 2.5) calc(var(--u) * 2.5) 0; }
.p-lidb { left: calc(var(--u) * 32); top: calc(var(--u) * 44); width: calc(var(--u) * 20); height: calc(var(--u) * 12); }
.p-tuckb { left: calc(var(--u) * 32); top: calc(var(--u) * 56); width: calc(var(--u) * 20); height: calc(var(--u) * 4); border-radius: 0 0 calc(var(--u) * 3) calc(var(--u) * 3); }
.p-band { left: calc(var(--u) * 0.4); top: calc(var(--u) * 33.9); width: calc(var(--u) * 19.2); height: calc(var(--u) * 9.7); opacity: 0.85; }
.p-swatch { top: calc(var(--u) * 41.2); width: calc(var(--u) * 2.15); height: calc(var(--u) * 1.4); }
.p-line { height: calc(var(--u) * 0.55); }
.p-word { position: absolute; left: calc(var(--u) * 1.4); top: calc(var(--u) * 17.2); margin: 0; font-size: calc(var(--u) * 3.1); font-stretch: 125%; font-weight: 800; letter-spacing: -0.01em; color: var(--c); }
.p-label { position: absolute; left: calc(var(--u) * 69); top: calc(var(--u) * 15.4); margin: 0; display: flex; align-items: center; gap: calc(var(--u) * 0.8); font-size: max(calc(var(--u) * 2), 15px); color: #eff1ee; white-space: nowrap; }
.p-label::before { content: ""; width: calc(var(--u) * 2); height: calc(var(--u) * 2); background: var(--c); }

/* ---- project covers that rise out of the opened box */

.covers {
  position: absolute;
  inset: 0;
  transform-style: preserve-3d;
  transform: translateZ(calc(var(--d) / -2));
}

.cover {
  position: absolute;
  left: 50%;
  bottom: calc(var(--u) * 3);
  width: calc(var(--u) * 12);
  aspect-ratio: 3 / 4;
  margin: 0 0 0 calc(var(--u) * -6);
  transform-origin: 50% 100%;
  transform:
    translateX(calc(var(--u) * var(--dx) * var(--rise)))
    translateY(calc(var(--u) * -21 * var(--rise)))
    rotateZ(calc(var(--rot) * 1deg * var(--rise)))
    translateZ(calc(var(--u) * 0.3 * var(--k)));
  opacity: var(--covers-on);
  box-shadow: 0 calc(var(--u) * 0.8) calc(var(--u) * 2) rgb(0 0 0 / 0.35);
}

/* Fan positions: sideways shift, tilt and stacking order of each cover. */
.cover-1 { --dx: -15; --rot: -22; --k: 1; }
.cover-2 { --dx: 15; --rot: 22; --k: 2; }
.cover-3 { --dx: -7.5; --rot: -11; --k: 3; }
.cover-4 { --dx: 7.5; --rot: 11; --k: 4; }
.cover-5 { --dx: 0; --rot: 0; --k: 5; }

.cover img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ------------------------------------------------------------------ work */

.work,
.about {
  padding: clamp(4rem, 9vw, 8rem) var(--edge);
}

/* About sits on light kraft, the colour of the inside of the box, so it
   reads as its own section next to the work on board. */
.about {
  background: var(--kraft-light);
}

.work-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: end;
  gap: 1.5rem;
  margin-bottom: clamp(2.5rem, 6vw, 5rem);
}

.work-head :is(h1, h2),
.about > :is(h1, h2),
.experience > h1,
.contact h2 {
  font-size: clamp(3rem, 8vw, 6.75rem);
}

:is(.work, .about, .experience).page-top {
  padding-top: clamp(1.5rem, 4vw, 3rem);
}

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.filters button {
  padding: 0.45em 1em;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  background: transparent;
  font-size: 1rem;
  font-weight: 600;
  font-stretch: 87.5%;
  cursor: pointer;
}

.filters button[aria-pressed="true"] {
  background: var(--ink);
  color: var(--board);
}

.filters button span {
  margin-left: 0.2em;
  font-weight: 400;
}

.cards {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  column-gap: var(--gap);
  row-gap: clamp(3rem, 7vw, 6rem);
  align-items: start;
}

.card {
  grid-column: span 12;
}

@media (min-width: 640px) {
  .card {
    grid-column: span 6;
  }
}

/* Large and small covers alternate sides, so the page reads like a spread, not a catalogue. */
@media (min-width: 1000px) {
  .card:nth-child(4n + 1 of .card:not([hidden])) {
    grid-column: 1 / span 7;
  }

  .card:nth-child(4n + 2 of .card:not([hidden])) {
    grid-column: 9 / span 4;
    margin-top: clamp(6rem, 16vw, 16rem);
  }

  .card:nth-child(4n + 3 of .card:not([hidden])) {
    grid-column: 2 / span 4;
  }

  .card:nth-child(4n + 4 of .card:not([hidden])) {
    grid-column: 7 / span 6;
    margin-top: clamp(4rem, 9vw, 9rem);
  }
}

.card a {
  display: block;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}

.card-img {
  --tx: 0deg;
  --ty: 0deg;
  position: relative;
  display: block;
  aspect-ratio: 3 / 4;
  background: #e1e4e0;
  transform: perspective(1100px) rotateX(var(--tx)) rotateY(var(--ty)) translateY(var(--lift, 0px)) scale(var(--press, 1));
  transition: transform 0.45s var(--ease-out), box-shadow 0.45s var(--ease-out);
}

/* The die-cut line: two corner brackets that grow into a full magenta outline. */
.card-img::before,
.card-img::after {
  content: "";
  position: absolute;
  width: 0;
  height: 0;
  border: 2px solid transparent;
  pointer-events: none;
  transition: width 0s 0.2s, height 0s 0.2s, border-color 0.2s;
}

.card-img::before {
  top: -10px;
  left: -10px;
}

.card-img::after {
  right: -10px;
  bottom: -10px;
}

@media (hover: hover) {
  .card a:hover .card-img {
    --lift: -6px;
    box-shadow: 0 30px 36px -26px rgb(35 31 32 / 0.5);
  }

  .card a:hover .card-img::before,
  .card a:hover .card-img::after {
    width: calc(100% + 20px);
    height: calc(100% + 20px);
  }

  .card a:hover .card-img::before {
    border-top-color: #ec008c;
    border-right-color: #ec008c;
    transition: border-color 0s, width 0.18s ease-out, height 0.18s ease-out 0.18s;
  }

  .card a:hover .card-img::after {
    border-bottom-color: #ec008c;
    border-left-color: #ec008c;
    transition: border-color 0s 0.36s, width 0.18s ease-out 0.36s, height 0.18s ease-out 0.54s;
  }
}

.card a:active .card-img {
  --press: 0.965;
  transition-duration: 0.12s;
}

.card-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.card-title {
  display: block;
  margin-top: 1.1rem;
  font-size: clamp(1.3125rem, 1.9vw, 1.75rem);
  font-stretch: 112%;
  font-weight: 700;
  line-height: 1.1;
}

.card-summary {
  display: block;
  max-width: 42ch;
  margin-top: 0.4rem;
  color: var(--muted);
}

.card-meta {
  display: block;
  margin-top: 0.5rem;
  font-size: 0.875rem;
  font-stretch: 87.5%;
  font-weight: 600;
}

.card a:hover .card-title,
.card a:focus-visible .card-title {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.15em;
}

/* ------------------------------------------------------------------ about */

.about > :is(h1, h2) {
  margin-bottom: clamp(2.5rem, 6vw, 5rem);
}

.about-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(2.5rem, 5vw, 4.5rem) var(--gap);
}

.portrait {
  grid-column: 1 / span 4;
}

.portrait img {
  width: 100%;
  max-width: 22rem;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 50%;
}

.bio {
  grid-column: 6 / span 7;
  max-width: 36em;
  font-size: clamp(1.125rem, 1.6vw, 1.3125rem);
  line-height: 1.5;
}

.tools {
  grid-column: 1 / span 7;
}

.highlights {
  grid-column: 9 / span 4;
}

.about :is(.tools, .highlights) h2 {
  margin-bottom: 1rem;
  font-size: 1.5rem;
  font-stretch: 112%;
}

.tools dl div,
.highlights li {
  padding: 0.85rem 0;
  border-top: 1px dashed rgb(35 31 32 / 0.35);
}

.tools dl div {
  display: grid;
  grid-template-columns: 10.5rem minmax(0, 1fr);
  gap: 0.25rem 1rem;
}

@media (max-width: 560px) {
  .tools dl div {
    grid-template-columns: minmax(0, 1fr);
  }
}

.tools dt {
  font-weight: 700;
  font-stretch: 87.5%;
}

.highlights ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

@media (max-width: 860px) {
  .portrait,
  .bio,
  .tools,
  .highlights {
    grid-column: 1 / -1;
  }

  .portrait img {
    max-width: 16rem;
  }
}

/* ------------------------------------------------------------------ experience */

.experience {
  padding: clamp(4rem, 9vw, 8rem) var(--edge);
}

.experience > h1 {
  margin-bottom: clamp(2.5rem, 6vw, 5rem);
}

.timeline {
  list-style: none;
  margin: 0;
  padding: 0;
}

.entry {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 0.5rem var(--gap);
  padding: 1.25rem 0 2.25rem;
  border-top: 1px dashed rgb(35 31 32 / 0.35);
}

.entry-dates {
  grid-column: 1 / span 3;
  font-weight: 600;
  font-stretch: 87.5%;
  font-variant-numeric: tabular-nums;
}

.entry-body {
  grid-column: 4 / span 8;
  max-width: 40em;
}

.entry-title {
  font-size: clamp(1.3125rem, 2vw, 1.75rem);
  font-stretch: 112%;
  font-weight: 700;
  line-height: 1.15;
}

.entry-org {
  margin-top: 0.3rem;
  color: var(--muted);
}

.entry-points {
  margin: 1rem 0 0;
  padding-left: 1.1em;
  list-style-type: "–  ";
}

.entry-points li + li {
  margin-top: 0.5em;
}

.education-title {
  margin: clamp(2.5rem, 5vw, 4rem) 0 1rem;
  font-size: 1.5rem;
  font-stretch: 112%;
}

@media (max-width: 860px) {
  .entry-dates,
  .entry-body {
    grid-column: 1 / -1;
  }
}

/* ------------------------------------------------------------------ contact */

.contact {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(2.5rem, 5vw, 4rem) var(--gap);
  align-items: center;
  padding: clamp(4rem, 10vw, 9rem) var(--edge);
}

.contact-intro {
  grid-column: 1 / span 6;
}

.contact-body {
  max-width: 28rem;
  margin-top: clamp(1.25rem, 3vw, 2rem);
  font-size: clamp(1.125rem, 1.6vw, 1.3125rem);
  line-height: 1.5;
}

/* The label: white stock, heavy rules, dashed field lines, a barcode. */
.label {
  grid-column: 8 / span 5;
  width: 100%;
  max-width: 34rem;
  padding: clamp(1.25rem, 3vw, 2rem);
  border-radius: 0.5rem;
  background: var(--white);
  color: var(--ink);
  box-shadow: 0 1.5rem 3rem -1.25rem rgb(0 0 0 / 0.5);
}

.label-head,
.label-foot span,
.label-row dt {
  font-size: 0.8125rem;
  font-weight: 700;
  font-stretch: 87.5%;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.label-head {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin: 0;
  padding-bottom: 0.75rem;
  border-bottom: 3px solid var(--ink);
}

.label-name {
  margin: 1.25rem 0 0.75rem;
  font-size: clamp(2rem, 4vw, 2.75rem);
  font-stretch: 125%;
  font-weight: 800;
  line-height: 0.95;
}

.label-rows {
  margin: 0;
}

.label-row {
  display: grid;
  grid-template-columns: 6.5rem minmax(0, 1fr);
  gap: 0.25rem 1rem;
  align-items: baseline;
  padding: 0.85rem 0;
  border-top: 1px dashed rgb(35 31 32 / 0.4);
}

.label-row dt {
  color: var(--muted);
}

.label-row dd {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.75rem;
  margin: 0;
  font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.label-row a {
  text-decoration-thickness: 1.5px;
  text-underline-offset: 0.2em;
}

.copy {
  padding: 0.2em 0.8em;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  background: transparent;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
}

.copy:hover {
  background: var(--ink);
  color: var(--white);
}

.label-foot {
  display: flex;
  justify-content: space-between;
  align-items: end;
  gap: 1rem;
  margin-top: 0.5rem;
  padding-top: 1rem;
  border-top: 3px solid var(--ink);
}

.label-code {
  width: min(60%, 15rem);
  height: 2.75rem;
  fill: var(--ink);
}

.label-head {
  flex-wrap: wrap;
  row-gap: 0.25rem;
}

.label-foot span {
  text-align: right;
  white-space: nowrap;
}

@media (max-width: 900px) {
  .contact-intro,
  .label {
    grid-column: 1 / -1;
  }
}

@media (max-width: 420px) {
  .label-row {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ------------------------------------------------------------------ project page */

.case-hero {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--gap);
  align-items: end;
  padding: clamp(1.5rem, 4vw, 3rem) var(--edge) 0;
}

.case-heading {
  grid-column: 1 / span 7;
}

.case-heading h1 {
  font-size: clamp(2.75rem, 6.6vw, 6.25rem);
  overflow-wrap: break-word;
  hyphens: auto;
}

.case-summary {
  max-width: 32ch;
  margin-top: 1.5rem;
  font-size: clamp(1.1875rem, 1.7vw, 1.3125rem);
  line-height: 1.45;
}

.spec {
  margin-top: clamp(2rem, 4vw, 3rem);
}

.spec div {
  border-top: 1px dashed rgb(35 31 32 / 0.35);
}

.spec div {
  display: grid;
  grid-template-columns: 6rem minmax(0, 1fr);
  gap: 1rem;
  padding: 0.7rem 0;
  font-size: 1rem;
}

.spec dt {
  font-weight: 700;
  font-stretch: 87.5%;
}

.case-cover {
  grid-column: 8 / span 5;
}

.case-cover img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
}

/* The brief and the answer: numbered white panels, side by side on wide
   screens and equal in height, like two job tickets. */
.case-brief {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 24rem), 1fr));
  gap: var(--gap);
  margin: clamp(3rem, 7vw, 6rem) var(--edge) 0;
}

/* A single section (no separate solution) keeps a readable width. */
.case-brief:has(> .case-section:only-child) {
  grid-template-columns: minmax(0, 44rem);
}

.case-section {
  padding: clamp(1.25rem, 3vw, 2.25rem);
  border-radius: 0.5rem;
  background: var(--white);
  box-shadow: 0 1rem 2.5rem -1.5rem rgb(35 31 32 / 0.3);
}

.case-section h2 {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
  padding-bottom: 0.85rem;
  border-bottom: 3px solid var(--ink);
  font-size: clamp(1.375rem, 2vw, 1.625rem);
  font-stretch: 112%;
}

.case-num {
  font-size: 0.8125rem;
  font-weight: 700;
  font-stretch: 87.5%;
  letter-spacing: 0.08em;
  color: var(--muted);
}

.case-text {
  max-width: 62ch;
}

@media (max-width: 860px) {
  .case-heading,
  .case-cover {
    grid-column: 1 / -1;
  }
}

.video {
  margin: clamp(3rem, 7vw, 6rem) var(--edge) 0;
  aspect-ratio: 16 / 9;
  background: var(--ink);
}

.video :is(iframe, video) {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.gallery {
  display: grid;
  gap: clamp(1rem, 2.5vw, 2rem);
  padding: clamp(3rem, 7vw, 6rem) var(--edge) 0;
}

.row.pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1rem, 2.5vw, 2rem);
  align-items: start;
}

.shot {
  width: 100%;
  max-width: var(--nw);
  margin-inline: auto;
}

.row.single .shot {
  width: min(100%, 60%);
}

.row.tall .shot {
  width: min(100%, 34rem);
}

.shot a {
  display: block;
  cursor: zoom-in;
}

.shot img {
  width: 100%;
}

@media (max-width: 640px) {
  .row.pair {
    grid-template-columns: 1fr;
  }

  .row.single .shot {
    width: 100%;
  }
}

.case-link {
  padding: clamp(2.5rem, 5vw, 4rem) var(--edge) 0;
}

.button {
  display: inline-block;
  padding: 0.7em 1.3em;
  border: 1.5px solid var(--ink);
  border-radius: 999px;
  background: var(--ink);
  color: var(--board);
  font-weight: 600;
  text-decoration: none;
}

.button:hover {
  border-color: var(--mat);
  background: var(--mat);
}

.button.ghost {
  background: transparent;
  color: var(--ink);
}

.button.ghost:hover {
  color: var(--board);
}

.teaser-links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}

.next + .contact {
  border-top: 1px dashed rgb(239 241 238 / 0.35);
}

.next {
  margin-top: clamp(4rem, 9vw, 8rem);
}

.next a {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: 0.75rem var(--gap);
  padding: clamp(3rem, 7vw, 6rem) var(--edge);
  text-decoration: none;
}

.next-label {
  font-weight: 600;
}

.next-title {
  grid-column: 1;
  font-size: clamp(2.25rem, 6vw, 5.5rem);
}

.next-img {
  grid-column: 2;
  grid-row: 1 / span 2;
  width: clamp(6.5rem, 17vw, 15rem);
}

.next a:hover .next-title,
.next a:focus-visible .next-title {
  text-decoration: underline;
  text-decoration-thickness: 3px;
  text-underline-offset: 0.12em;
}

/* ------------------------------------------------------------------ lightbox */

.lightbox {
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: var(--ink);
  color: var(--board);
  opacity: 0;
  transition: opacity 0.25s var(--ease-out), display 0.25s allow-discrete, overlay 0.25s allow-discrete;
}

.lightbox[open] {
  opacity: 1;
}

@starting-style {
  .lightbox[open] {
    opacity: 0;
  }
}

.lightbox::backdrop {
  background: transparent;
}

.lightbox figure {
  display: grid;
  place-items: center;
  height: 100%;
  padding: 4.5rem clamp(1rem, 6vw, 6rem) 5rem;
}

.lightbox img {
  max-height: calc(100vh - 10rem);
  max-height: calc(100svh - 10rem);
  width: auto;
  object-fit: contain;
}

.lightbox figcaption {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  bottom: 1.5rem;
  font-size: 0.9375rem;
  text-align: center;
}

.lb-bar {
  position: absolute;
  inset: 1rem var(--gutter) auto;
  display: flex;
  gap: 0.5rem;
}

.lb-close {
  margin-left: auto;
}

.lightbox button {
  padding: 0.5em 1em;
  border: 1.5px solid currentColor;
  border-radius: 999px;
  background: transparent;
  font-weight: 600;
  font-stretch: 87.5%;
  cursor: pointer;
}

/* ------------------------------------------------------------------ 404 */

.missing-main {
  min-height: calc(100vh - 4.5rem);
  min-height: calc(100svh - 4.5rem);
  display: grid;
  align-content: center;
  gap: 1.5rem;
  padding: 3rem var(--edge) 6rem;
}

.missing-main h1 {
  font-size: clamp(3rem, 9vw, 8rem);
}

/* ------------------------------------------------------------------ motion */

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }

  @view-transition {
    navigation: auto;
  }

  ::view-transition-group(*) {
    animation-duration: 0.5s;
    animation-timing-function: var(--ease-out);
  }
}

/* With reduced motion, page changes and filtering crossfade instead of
   sliding. Hover effects and the scroll story stay: they only move when the
   visitor does. */
@media (prefers-reduced-motion: reduce) {
  @view-transition {
    navigation: auto;
  }

  ::view-transition-group(*) {
    animation: none;
  }

  ::view-transition-old(*),
  ::view-transition-new(*) {
    animation-duration: 0.2s;
  }
}
