/* Layout: the 1024-unit Figma grid, scaled to the window. One unit (--u) = 1/1024 of the page width,
   so every position and size below is the number from the layout. Under 900px the phone layout takes over. */
:root {
  --bg: #ffffff;
  --fg: #000000;
  --fg-50: rgb(0 0 0 / .5);
  --fg-30: rgb(0 0 0 / .3);
  --on-blend: #ffffff; /* phone menu: white in "difference" mode reads black on white and inverts over pictures */
  --font: "Roboto Flex", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --ease: cubic-bezier(.2, .75, .2, 1);
  color-scheme: light;
}
html { background: var(--bg); }
body {
  margin: 0;
  max-width: 2200px;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font);
  font-variation-settings: "opsz" 14;
  font-optical-sizing: none;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  container-type: inline-size;
}
.page { --u: calc(100cqw / 1024); --cu: var(--u); }
a { color: inherit; text-decoration: none; }
a:focus-visible { outline: 1px solid var(--fg); outline-offset: 3px; }
h1, h2, p, ul { margin: 0; padding: 0; font: inherit; }
ul { list-style: none; }
img, video { display: block; }

/* ---- type ---- */
.caps { font-weight: 500; font-size: max(calc(10 * var(--u)), 10px); line-height: 1.2; letter-spacing: .15em; text-transform: uppercase; }
.txt  { font-weight: 400; font-size: max(calc(14 * var(--tu, var(--u))), 13px); line-height: calc(16 / 14); letter-spacing: -.03em; }
.cap  { font-weight: 400; font-size: max(calc(10 * var(--u)), 10px); line-height: 1.2; letter-spacing: -.03em; }
.title { font-weight: 500; font-size: calc(24 * var(--u)); line-height: calc(28 / 24); letter-spacing: .15em; text-transform: uppercase; }
.o50 { color: var(--fg-50); }
.o30 { color: var(--fg-30); }

/* ---- navigation: fixed slots at 20 / 92 / 163 ---- */
.nav { display: grid; grid-template-columns: calc(72 * var(--u)) calc(71 * var(--u)) auto; justify-content: start; }
.nav a, .social a { transition: opacity .2s; }
.nav a:hover, .social a:hover { opacity: .4; }
.social { display: flex; flex-direction: column; gap: calc(1 * var(--u)); }

/* ---- pages with the sticky left column (works, about, archive) ---- */
.with-side { display: grid; grid-template-columns: minmax(0, 1fr); }
.with-side > * { grid-area: 1 / 1; min-width: 0; }
.side {
  position: sticky; top: 0; z-index: 1; align-self: start;
  box-sizing: border-box; width: calc(215 * var(--u)); height: 100vh; height: 100dvh;
  padding: calc(13 * var(--u)) 0 calc(13 * var(--u)) calc(20 * var(--u));
  display: flex; flex-direction: column;
  /* long text shrinks with the window height so it never runs under the links */
  --tu: min(var(--u), calc(100vh / 602));
}
.side .intro { margin-top: calc(15 * var(--tu)); margin-left: calc(-1 * var(--u)); }
.side .social { margin-top: auto; }
.about { margin-left: calc(-1 * var(--u)); }
.about section { margin-top: calc(33 * var(--tu)); }
.about h2 { margin-bottom: calc(16 * var(--tu)); }

/* works: two columns, 482 + 267 units */
.works {
  display: grid; grid-template-columns: calc(482 * var(--u)) calc(267 * var(--u)); column-gap: calc(20 * var(--u));
  padding: calc(44 * var(--u)) calc(20 * var(--u)) calc(13 * var(--u)) calc(235 * var(--u));
  align-items: start;
}
.col { display: flex; flex-direction: column; gap: calc(7 * var(--u)); min-width: 0; }
.card { display: flex; flex-direction: column; }
.pic { position: relative; display: block; overflow: hidden; margin-bottom: calc(7 * var(--u)); }
.pic > img:first-child { width: 100%; height: 100%; transition: opacity .2s; }
.card:not(.tilt):hover .pic > img:first-child { opacity: .82; }
/* Solville cover: the bottle is a separate layer and leans a little under the cursor */
.float { position: absolute; height: auto; max-width: none; transform-origin: 50% 64%; transition: rotate .8s var(--ease); }
@media (hover: hover) { .card:hover .float { rotate: 8deg; } }
@media (hover: none)  { .card.on .float { rotate: 8deg; } }

/* ---- project pages ---- */
.project > .nav { padding: calc(13 * var(--u)) calc(20 * var(--u)) 0; }
.head {
  box-sizing: border-box; min-height: calc(269 * var(--u));
  padding: 0 calc(20 * var(--u)) calc(28 * var(--u));
  display: flex; flex-direction: column;
}
.head .title { margin-top: calc(14 * var(--u)); margin-left: calc(-1 * var(--u)); }
.head .desc { margin-top: auto; padding-top: calc(24 * var(--u)); max-width: 62ch; }

/* ---- collage canvas: every piece sits at its coordinates from the layout ---- */
.canvas { position: relative; overflow: clip; height: calc(var(--H) * var(--cu)); }
.canvas > * {
  position: absolute; max-width: none; object-fit: cover;
  left: calc(var(--x) * var(--cu));
  top: calc(var(--y) * var(--cu));
  width: calc(var(--w) * var(--cu));
  height: calc(var(--h) * var(--cu));
}

/* ---- archive: a piece is invisible until the cursor finds it, then grows out of transparency ---- */
.pop { opacity: 0; scale: .86; transition: opacity .5s ease, scale .75s var(--ease); }
@media (hover: hover) and (min-width: 900px) {
  .pop:hover { opacity: 1; scale: 1; z-index: 99; }
}
@media (hover: none) and (min-width: 900px) {
  /* tablet: a tap shows a piece */
  .pop.on, html:not(.js) .pop { opacity: 1; scale: 1; }
}

/* archive on a wide screen: exactly one screen tall, pieces placed by fractions of the free area */
@media (min-width: 900px) {
  .p-archive .canvas { height: 100vh; height: 100dvh; --au: min(var(--u), calc(100vh / 602)); }
  .p-archive .canvas > * {
    width: calc(var(--w) * var(--au));
    height: calc(var(--h) * var(--au));
    left: calc(228 * var(--u) + var(--fx) * (100cqw - 244 * var(--u) - var(--bw) * var(--au)) + (var(--bw) - var(--w)) * var(--au) / 2);
    top: calc(14 * var(--au) + var(--fy) * (100vh - 28 * var(--au) - var(--bh) * var(--au)) + (var(--bh) - var(--h)) * var(--au) / 2);
  }
  .pop.on { opacity: 1; scale: 1; z-index: 99; }
}

/* ---- found objects (map zine): they hover in place, turn as the page scrolls, and spin once when touched ---- */
.obj {
  rotate: calc(var(--sr, 0) * 1deg);
  animation: drift var(--d, 8s) ease-in-out var(--dl, 0s) infinite alternate;
}
.obj.spin { animation: drift var(--d, 8s) ease-in-out var(--dl, 0s) infinite alternate, spin 1.4s var(--ease); }
@keyframes drift {
  from { translate: calc(-3 * var(--cu)) calc(-9 * var(--cu)); }
  to   { translate: calc(3 * var(--cu)) calc(9 * var(--cu)); }
}
@keyframes spin {
  0%   { transform: rotate(0deg) scale(1); }
  45%  { transform: rotate(215deg) scale(1.28); }
  100% { transform: rotate(360deg) scale(1); }
}

/* ---- phone and narrow windows ---- */
@media (max-width: 899px) {
  .page { --g: 16px; }
  .caps { font-size: 11px; }
  .txt { font-size: 15px; line-height: 1.25; }
  .cap { font-size: 12px; }
  br.soft { display: none; }

  /* menu stays on screen and inverts over whatever scrolls under it */
  .nav {
    position: sticky; top: env(safe-area-inset-top, 0px); z-index: 5;
    display: flex; gap: 22px; padding: 14px var(--g);
    mix-blend-mode: difference; color: var(--on-blend);
  }
  .nav a:hover { opacity: 1; }
  .project > .nav { padding: 14px var(--g); }

  .with-side { display: flex; flex-direction: column; }
  .side { display: contents; }
  /* opening line set large, as a statement */
  .intro { font-size: clamp(23px, 6.7cqw, 32px); line-height: 1.08; letter-spacing: -.035em; text-wrap: balance; }
  .side .intro { margin: 26px var(--g) 46px; max-width: 15em; }
  .about { margin: 0 var(--g) 40px; }
  .about .intro { margin: 26px 0 0; }
  .about section { margin-top: 34px; }
  .about h2 { margin-bottom: 14px; }
  .side .social { order: 3; flex-direction: row; gap: 22px; margin: 0; padding: 56px var(--g) 28px; }

  /* works: wide covers run edge to edge of the column, upright ones step right and left */
  .works { display: flex; flex-direction: column; gap: 54px; padding: 0 var(--g); }
  .col { display: contents; }
  .card { width: var(--mw); margin-left: var(--ml); }
  .pic { margin-bottom: 9px; }

  .head { min-height: 0; padding: 22px var(--g) 30px; }
  .title { font-size: clamp(26px, 8cqw, 36px); line-height: 1.04; letter-spacing: .12em; }
  .head .title { margin: 0 0 12px; }
  .head .desc { margin-top: 44px; padding-top: 0; font-size: 16px; }

  .canvas { --cu: calc(100cqw / var(--mcw)); height: calc(var(--mH) * var(--cu)); }
  .canvas > * {
    left: calc(var(--mx) * var(--cu));
    top: calc(var(--my) * var(--cu));
    width: calc(var(--mw) * var(--cu));
    height: calc(var(--mh) * var(--cu));
  }

  /* pieces rise into place the first time they are scrolled to */
  .js .rv { opacity: 0; scale: .95; translate: 0 20px; transition: opacity .8s ease var(--rd, 0s), scale .9s var(--ease) var(--rd, 0s), translate .9s var(--ease) var(--rd, 0s); }
  .js .rv.in { opacity: 1; scale: 1; translate: 0 0; }
}
/* archive on a phone: one screen, no scrolling; the pieces flicker in turn, each in its own spot */
@media (max-width: 899px) {
  .p-archive { height: 100vh; height: 100dvh; box-sizing: border-box; }
  .p-archive .about { margin-bottom: 8px; }
  .p-archive .side .social { padding-top: 12px; }
  .p-archive .canvas {
    flex: 1 1 0; min-height: 0; height: auto; margin: 0 var(--g);
    container-type: size;
    --au: min(calc(100cqw / 450), calc(100cqh / 400));
  }
  .p-archive .canvas > * {
    width: calc(var(--w) * var(--au));
    height: calc(var(--h) * var(--au));
    left: calc(var(--fx) * (100cqw - var(--bw) * var(--au)) + (var(--bw) - var(--w)) * var(--au) / 2);
    top: calc(var(--fy) * (100cqh - var(--bh) * var(--au)) + (var(--bh) - var(--h)) * var(--au) / 2);
  }
  /* quick flicker: every piece gets about half a second, one after another, in a loop */
  .p-archive .pop {
    transition: none;
    animation: turn calc(var(--n) * var(--beat)) calc(var(--i) * var(--beat)) infinite both;
    --beat: .5s;
  }
}
/* one piece's share of the loop is 1/13: in, hold, out, then wait for the others */
@keyframes turn {
  0%    { opacity: 0; scale: .84; animation-timing-function: cubic-bezier(.2, .75, .2, 1); }
  2.4%  { opacity: 1; scale: 1; }
  7.4%  { opacity: 1; scale: 1; animation-timing-function: ease-in; }
  9.6%  { opacity: 0; scale: .95; }
  100%  { opacity: 0; scale: .84; }
}
@media (prefers-reduced-motion: reduce) {
  .p-archive .pop { animation: none; opacity: 1; scale: 1; }
  .nav a, .social a, .pic > img, .float, .pop, .js .rv, .obj { transition: none; }
  .obj { animation: none; }
  .js .rv { translate: none; scale: none; }
}
