:root {
  --ink: #181616;
  --grey: #535353;
  --blue: #0761c1;
  --paper: #ebeae6;
  --mono: "IBM Plex Mono", ui-monospace, monospace;
}

@font-face {
  font-family: "CS Sargent Pixel";
  src: url(fonts/CSSargentPixel-Regular.woff2) format("woff2");
  font-display: block;
}

* { box-sizing: border-box; margin: 0; }

body {
  min-height: 100svh;
  background: var(--paper);
  color: var(--ink);
  font: 300 20px/1 var(--mono);
}

/* Paper: one screen of texture pinned behind the page. On body itself, "cover" stretched it over the whole scroll height */
body::before { content: ""; position: fixed; inset: -3vmax; z-index: -1; background: url(img/paper-folded.webp) center / cover; }  /* folded poster scan with faint grid creases; img/paper.webp is the plain sheet it replaced */
/* After Effects hold keyframes: the sheet jumps between 8 positions and stays put in between. A transform, so the page never repaints.
   One hold = --hold; how far it moves = the numbers in the keyframes */
@media (prefers-reduced-motion: no-preference) { body::before { animation: paper-hold calc(8 * var(--hold, .5s)) step-end infinite; } }
@keyframes paper-hold {
  0% { translate: 0 0; }
  12.5% { translate: -.8vmax .5vmax; }
  25% { translate: .5vmax -1vmax; }
  37.5% { translate: 1.1vmax .7vmax; }
  50% { translate: -.4vmax 1.3vmax; }
  62.5% { translate: -1.3vmax -.4vmax; }
  75% { translate: .7vmax -1.4vmax; }
  87.5% { translate: -1vmax 1.1vmax; }
}

a { color: inherit; text-decoration: none; }

/* Pixel cursor (made with proj/cursors.py): dithered arrow, filled blue over links and buttons */
html { cursor: url(img/cursor.png) 1 1, auto; }
a, button { cursor: url(img/cursor-link.png) 1 1, pointer; }

/* Stage: a 1920x1080 artboard scaled to fit the window.
   Place things with Photoshop pixel coords: style="--x:175; --y:157; --w:1104" */
.stage {
  position: relative;
  width: min(100%, 100svh * 16 / 9);
  aspect-ratio: 16 / 9;
  margin-inline: auto;
  container-type: inline-size;
  overflow: hidden;
  --u: calc(100cqw / 1920);
}
.stage > * {
  position: absolute;
  left: calc(var(--x) * var(--u));
  top: calc(var(--y) * var(--u));
  width: calc(var(--w, auto) * var(--u));
}
.stage img { display: block; height: auto; }

/* Nav pills: dashed inner frame always, solid outer ring on hover/current
   (the ring is the hidden "Rectangle 2 copy 3" layer in the PSD) */
.nav { display: flex; gap: calc(22.4 * var(--u)); }
.pill {
  position: relative;
  display: grid;
  place-items: center;
  height: calc(35 * var(--u));
  padding-inline: calc(7.5 * var(--u));
  font-size: calc(19.3 * var(--u));
  border: max(1px, calc(2 * var(--u))) solid transparent;
  border-radius: calc(16.5 * var(--u));
}
.pill:hover { border-color: var(--ink); }
.pill span {
  display: grid;
  place-items: center;
  width: calc(var(--pw) * var(--u));
  height: calc(23 * var(--u));
  padding-inline: calc(24 * var(--u));
  border: 1px dashed var(--ink);
  border-radius: 99px;
}
/* Wordmark: live CS Sargent Pixel filled with the PSD's own texture stack (img/ink-*.jpg,
   rendered at 2x; crop origin --ix/--iy in Photoshop px).
   No z-index on .wordmark itself, so CARSON can sit under the gargoyle and BECKER over it. */
.wordmark { inset: 0; width: 100%; height: 100%; font: inherit; pointer-events: none; }
.wordmark > span {
  position: absolute;
  left: calc(var(--x) * var(--u));
  top: calc(var(--y) * var(--u));
  font: calc(var(--fs) * var(--u)) / 1 "CS Sargent Pixel", serif;
  letter-spacing: calc(var(--k, 0) * var(--u));
  white-space: nowrap;
  padding-right: .15em;  /* room for glyphs that overhang their box (the N), else background-clip:text cuts them */
  color: var(--blue);
  background: var(--ink) calc((var(--ix) - var(--x)) * var(--u)) calc((var(--iy) - var(--y)) * var(--u)) / calc(1150 * var(--u)) auto no-repeat;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.wordmark i { font-style: normal; letter-spacing: calc(var(--k, 0) * var(--u)); }
.carson { z-index: 1; --ink: url(img/ink-carson.jpg); --ix: 88; --iy: 138; }
.becker { z-index: 3; --ink: url(img/ink-becker.jpg); --ix: 88; --iy: 347.8; }
.gargoyle { z-index: 2; }
iframe.gargoyle { aspect-ratio: 1026 / 1023; border: 0; background: url(img/hero-poster.webp) 0 0 / 100% 100%; }  /* live 3D statue from lab/gargoyle.html, over a still of it until the first frame is drawn */
iframe.gargoyle.drawn { background: none; }

/* Float: &float=2.4 in the iframe URL, done inside the shader. Don't move the iframe with CSS: a tilt or sub-pixel slide resamples the halftone into moving stripes */
.lede, .blurb, .dots { z-index: 4; }

.lede { font-size: calc(30 * var(--u)); line-height: calc(32 * var(--u)); }
.prose, .blurb, .tile .r { text-transform: lowercase; }
.blurb { width: 64ch; font-size: calc(20 * var(--u)); line-height: calc(20 * var(--u)); }

/* Glitch: put class="glitch" (slice near the start) or "glitch-end" (slice near the end) on any heading.
   Filters live in the <svg class="fx"> at the bottom of each page.
   ponytail: the push is a fraction of the heading's width, so it reads right on 1-3 word headings;
   on a long sentence the slice moves further. Wrap just the words you want glitched if that happens. */
.glitch { filter: url(#glitch); }
.glitch-end { filter: url(#glitch-end); }
.glitch, .glitch-end { width: fit-content; }
.fx { position: absolute; width: 0; height: 0; }

/* Inner pages: normal flow, same nav, pills and title texture as the hero */
.page { --u: 1px; max-width: 1570px; padding: 95px clamp(16px, 9vw, 175px) 96px; }
.title {
  margin: 48px 0 40px;
  font: clamp(88px, 15vw, 280px) / 1 "CS Sargent Pixel", serif;
  color: var(--blue);
  background: url(img/ink-becker.jpg) center / cover;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.prose { max-width: 60ch; font-size: 20px; line-height: 1.35; }
.prose p + p, .prose ul { margin-top: 1.2em; }
.prose ul { padding: 0; list-style: none; }
.prose a { text-decoration: underline; text-underline-offset: 3px; }
.prose a:hover { color: var(--blue); }
.headline { color: var(--grey); }
.reel { width: 100%; max-width: min(1280px, (100svh - 510px) * 16 / 9); aspect-ratio: 16 / 9; border: 0; display: block; background: var(--ink); }

/* Work grid: 1-bit dither by default, colour on hover/focus */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); gap: 40px 32px; padding: 0; list-style: none; }
.tile { display: block; }
.thumb { position: relative; display: grid; place-items: center; aspect-ratio: 16 / 10; overflow: hidden; outline: 1px dashed var(--ink); outline-offset: 4px; }
.thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.thumb .d { image-rendering: pixelated; }
.thumb .c { opacity: 0; transition: opacity .24s steps(3); }
.tile:hover .c, .tile:focus-visible .c { opacity: 1; }
.thumb b { font: 96px / 1 "CS Sargent Pixel", serif; color: var(--blue); }
.tile .t { display: block; margin-top: 16px; font-size: 18px; }
.tile .r { display: block; margin-top: 4px; font-size: 14px; color: var(--grey); }
.tile:hover .t { color: var(--blue); }

.sr-only, .index .tags { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

/* Landing sections under the hero. .below is the container so --u matches the artboard;
   inside, plain flow at PSD px. Left edge 108 = the hero's type column. */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
.below { width: min(100%, 100svh * 16 / 9); margin-inline: auto; container-type: inline-size; --u: calc(100cqw / 1920); }
.sheet { position: relative; padding: calc(124 * var(--u)) calc(108 * var(--u)) 0; }
.kicker { margin-bottom: calc(26 * var(--u)); font-size: calc(30 * var(--u)); }
#reel { padding-block: calc(78 * var(--u)) calc(132 * var(--u)); }
#reel .kicker { text-align: center; }
#about { padding-top: calc(188 * var(--u)); }
#about .kicker { margin-bottom: calc(54 * var(--u)); color: var(--blue); }

.reel-frame { display: block; position: relative; aspect-ratio: 16 / 9; overflow: hidden; border: calc(2 * var(--u)) solid var(--blue); outline: calc(2 * var(--u)) dotted var(--blue); outline-offset: calc(6 * var(--u)); }
.reel-frame:focus-visible { outline-style: solid; }
.reel-frame img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.reel-frame video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; }
.reel-frame.live video { opacity: 1; }
/* player chrome like YouTube's: white icons bottom right (speaker, full screen), the YouTube link top right */
.reel-ui { position: absolute; right: calc(12 * var(--u)); bottom: calc(12 * var(--u)); display: flex; gap: calc(4 * var(--u)); }
.reel-ui button { width: calc(54 * var(--u)); height: calc(54 * var(--u)); padding: calc(8 * var(--u)); border: 0; background: none; color: #fff; opacity: .9; filter: drop-shadow(0 0 calc(3 * var(--u)) rgba(0, 0, 0, .7)); }
.reel-ui button:hover { opacity: 1; }
.reel-ui svg { display: block; width: 100%; height: 100%; fill: currentColor; }
.reel-ui .on, .reel-frame.loud .off { display: none; }
.reel-frame.loud .on { display: block; }
.reel-yt { position: absolute; top: calc(14 * var(--u)); right: calc(18 * var(--u)); color: #fff; font-size: calc(17 * var(--u)); text-decoration: none; text-shadow: 0 0 calc(4 * var(--u)) rgba(0, 0, 0, .8); opacity: .9; }
.reel-yt:hover { opacity: 1; text-decoration: underline; }

.index { width: calc(850 * var(--u)); padding: 0; list-style: none; border-bottom: 1px dashed var(--ink); }
.index a { display: grid; grid-template-columns: calc(110 * var(--u)) 1fr; align-items: baseline; padding: calc(26 * var(--u)) 0 calc(18 * var(--u)); border-top: 1px dashed var(--ink); color: var(--grey); transition: color .1s; }
.index a:hover, .index a:focus-visible, .index a.on { color: var(--blue); }
.index b { font-weight: inherit; font-size: calc(20 * var(--u)); }
.index .name { font: calc(94 * var(--u)) / 1 "CS Sargent Pixel", serif; width: fit-content; padding-right: .15em; transform-origin: left center; transition: scale .18s; }
.index a:hover .name, .index a:focus-visible .name, .index a.on .name { scale: 1.05; }
.links a:hover { color: var(--blue); }

/* Work card, right of the list */
.peek { position: absolute; left: calc(1012 * var(--u)); width: calc(800 * var(--u)); aspect-ratio: 16 / 10; overflow: hidden; pointer-events: none; opacity: 0; }
.peek.on { opacity: 1; pointer-events: auto; }
.peek img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Cord from the title to the card, in #work's own coordinates (script in index.html). Shows with the card */
.cord { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; visibility: hidden; stroke-width: max(1.5px, calc(2 * var(--u))); stroke-linecap: round; stroke-dasharray: 0 calc(5 * var(--u)); }  /* dots, like the reel's frame */
.peek.on + .cord { visibility: visible; }
/* Info pill at the cursor. vw, not --u: it's outside the .below container, like the figure */
.tip { position: fixed; left: 0; top: 0; z-index: 6; padding: .45em 1em; border-radius: 99px; background: var(--blue); color: var(--paper); font-size: min(1.04vw, 1.85svh); white-space: nowrap; pointer-events: none; opacity: 0; }
.tip.on { opacity: 1; transition: translate .18s ease-out; }

.bio { max-width: calc(1240 * var(--u)); font-size: calc(30 * var(--u)); line-height: 1.35; }  /* one body size across the page: lede, bio, kickers, links */

.end { padding-block: calc(150 * var(--u)) calc(115 * var(--u)); overflow: hidden; }  /* clips the figure's frame where it runs past the page bottom */  /* top padding makes room for the taller footer figure */
/* Footer figure, like the mask in the hero: says hi from the bottom right, its feet on the page's end */
.end-fig { position: absolute; right: calc(30 * var(--u)); bottom: calc(-280 * var(--u)); width: calc(1040 * var(--u)); aspect-ratio: 1; border: 0; }  /* the viewer frames the figure with air under it; pushed down so the base sits on the page's bottom edge */
.hi, .links { position: relative; }
.hi {
  display: inline-block; padding-right: .15em; transform-origin: left center; transition: scale .18s;
  font: calc(318 * var(--u)) / 1 "CS Sargent Pixel", serif;
  color: var(--blue);
  background: url(img/ink-becker.jpg) 0 0 / calc(1150 * var(--u)) auto;
  -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
}
.hi:hover { scale: 1.03; }
.end-dots { position: relative; display: block; width: calc(211 * var(--u)); margin-top: calc(28 * var(--u)); }  /* the barcode, at the PSD's size, same gap as the dots under the lede */
.about-dots { display: block; width: calc(247 * var(--u)); margin: calc(-14 * var(--u)) 0 calc(44 * var(--u)); }  /* the hero's dots mirrored, between the kicker and the bio */
.links { margin-top: calc(24 * var(--u)); padding: 0; list-style: none; font-size: calc(30 * var(--u)); line-height: 1.5; }

/* Phones: drop the artboard, stack it */
@media (max-aspect-ratio: 1 / 1) and (max-width: 900px) {
  .stage {
    width: 100%;
    aspect-ratio: auto;
    container-type: normal;
    padding: 24px 16px 0;
    display: flex;
    flex-direction: column;
    gap: 20px;
    --u: 1.6px;
  }
  .stage > * { position: relative; left: 0; top: 0; width: auto; }
  .wordmark { margin-top: 12px; --u: calc((100vw - 32px) / 1170); }
  .wordmark > span { position: relative; display: block; left: 0; top: 0; }
  .gargoyle { width: 115%; margin: 0 -16px 0 auto; }
  .dots, .about-dots { width: 160px; }
  .end-dots { width: 137px; }
  .lede br { display: none; }
  .lede { font-size: 22px; line-height: 1.1; }
  .blurb { font-size: 14px; line-height: 1.15; max-width: 40ch; width: auto; }
  .pill { height: 40px; font-size: 16px; }
  .nav { flex-wrap: wrap; gap: 8px; }
  .pill { padding-inline: 3px; }
  .pill span { width: auto; height: 28px; padding-inline: 12px; }
  .reel-ui button { width: 36px; height: 36px; padding: 4px; }
  .reel-yt { font-size: 13px; }
  .page { padding-top: 24px; }
  .prose { font-size: 16px; }
  .peek, .cord, .tip, .end-fig { display: none; }
  .below { --u: .5px; }
  .sheet, #reel, #about, .end { padding: 72px 16px 0; }
  .end { padding-bottom: 48px; }
  .kicker, .index b, .index .tags { font-size: 14px; }
  .index { width: auto; }
  .index a { grid-template-columns: 32px 1fr; row-gap: 6px; padding: 16px 0 12px; }
  .index .name { font-size: 44px; }
  .index .tags { position: static; grid-column: 2; width: auto; height: auto; clip-path: none; }
  .bio, .kicker { font-size: 22px; }  /* same as .lede on phones */
  .hi { font-size: 104px; background-size: 600px auto; }
  .links { font-size: 22px; }
}
