@font-face {
  font-family: "Anybody";
  src: url("/fonts/anybody.woff2") format("woff2");
  font-weight: 100 900;
  font-stretch: 50% 150%;
  font-display: block;
}

@property --a {
  syntax: "<angle>";
  inherits: true;
  initial-value: 0deg;
}

* { box-sizing: border-box; margin: 0; touch-action: none; }

html, body {
  height: 100%;
  overflow: hidden;
  touch-action: none;
  background: #0b0b0b;
}

body {
  font-family: "Anybody", Impact, "Arial Black", sans-serif;
  font-weight: 900;
  -webkit-font-smoothing: antialiased;
  user-select: none;
  -webkit-user-select: none;
  cursor: pointer;
}

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

/* ---------- shared: scene, word, letters ---------- */

.scene {
  position: fixed;
  inset: 0;
  display: none;
  place-items: center;
  overflow: hidden;
  background: var(--bg);
  color: var(--fg);
}
.scene.on { display: grid; }

/* main.js sets the font size of .fitbox so the word fills the screen */
.fitbox {
  position: relative;
  /* The capitals sit high in their 0.8em line. This centres the ink on screen. */
  top: 0.056em;
  display: inline-block;
  font-size: 100px;
}

.word {
  display: flex;
  align-items: center;
  line-height: 0.8;
  white-space: nowrap;
}
.pair { display: flex; }
.l { display: block; position: relative; }

/* One line on wide screens, ME / LK / ER on tall ones */
@media (max-aspect-ratio: 4/5) {
  .word { flex-direction: column; }
}

/* ---------- 1. wave: the width axis rolls through the letters ---------- */

.s-wave { --bg: #0b0b0b; --fg: #f3efe4; }
.s-wave .l {
  animation: wave 1.3s ease-in-out infinite alternate;
  animation-delay: calc(var(--i) * -2.6s / 6);
}
@media (max-aspect-ratio: 4/5) {
  .s-wave .l { animation-delay: calc((var(--c) / 2 + var(--r) / 3) * -2.6s); }
}
@keyframes wave {
  from { font-variation-settings: "wght" 900, "wdth" 50; }
  to   { font-variation-settings: "wght" 900, "wdth" 150; }
}

/* ---------- 2. glitch ---------- */

.s-glitch { --bg: #07020f; --fg: #ffffff; }
.s-glitch .fitbox { animation: jolt 3.1s steps(1) infinite; }
.s-glitch .l::before,
.s-glitch .l::after {
  content: attr(data-c);
  position: absolute;
  inset: 0;
  mix-blend-mode: screen;
}
.s-glitch .l::before {
  color: #00f0ff;
  animation: split-a 2.1s steps(1) infinite;
  animation-delay: calc(var(--i) * -0.37s);
}
.s-glitch .l::after {
  color: #ff0055;
  animation: split-b 1.7s steps(1) infinite;
  animation-delay: calc(var(--i) * -0.23s);
}
.s-glitch::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: repeating-linear-gradient(to bottom, transparent 0 3px, rgb(0 0 0 / 0.22) 3px 4px);
  animation: scan 0.5s linear infinite;
}
.s-glitch::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 14vh;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(to bottom, transparent, rgb(0 240 255 / 0.12), transparent);
  animation: tear 2.3s linear infinite;
}
@keyframes split-a {
  0%   { transform: translate(-0.025em, 0);      clip-path: inset(0 0 0 0); }
  11%  { transform: translate(-0.07em, 0.01em);  clip-path: inset(12% 0 55% 0); }
  17%  { transform: translate(-0.02em, 0);       clip-path: inset(0 0 0 0); }
  38%  { transform: translate(0.06em, -0.01em);  clip-path: inset(60% 0 8% 0); }
  44%  { transform: translate(-0.03em, 0);       clip-path: inset(0 0 0 0); }
  63%  { transform: translate(-0.12em, 0);       clip-path: inset(35% 0 40% 0); }
  69%  { transform: translate(-0.02em, 0.012em); clip-path: inset(0 0 0 0); }
  86%  { transform: translate(0.04em, 0);        clip-path: inset(78% 0 2% 0); }
  92%  { transform: translate(-0.025em, 0);      clip-path: inset(0 0 0 0); }
}
@keyframes split-b {
  0%   { transform: translate(0.025em, 0);       clip-path: inset(0 0 0 0); }
  14%  { transform: translate(0.09em, 0);        clip-path: inset(48% 0 22% 0); }
  21%  { transform: translate(0.02em, -0.01em);  clip-path: inset(0 0 0 0); }
  47%  { transform: translate(-0.05em, 0.01em);  clip-path: inset(5% 0 70% 0); }
  53%  { transform: translate(0.03em, 0);        clip-path: inset(0 0 0 0); }
  74%  { transform: translate(0.14em, 0);        clip-path: inset(66% 0 14% 0); }
  80%  { transform: translate(0.025em, 0.01em);  clip-path: inset(0 0 0 0); }
}
@keyframes jolt {
  0%, 100% { transform: none; }
  23% { transform: translateX(-1.2%) skewX(-6deg); }
  25% { transform: translateX(0.8%) skewX(3deg); }
  27% { transform: none; }
  61% { transform: translateY(-1.5%) scaleY(1.04); }
  63% { transform: translateX(1.5%) skewX(9deg); }
  65% { transform: none; }
  88% { transform: translateX(-0.6%); }
  90% { transform: none; }
}
@keyframes scan { to { transform: translateY(4px); } }
@keyframes tear {
  from { transform: translateY(-20vh); }
  to   { transform: translateY(110vh); }
}

/* ---------- 3. rows: outlined rows scroll behind the word ---------- */

.s-rows { --bg: #ff3b0a; --fg: #fff4e2; --ink: #170600; }
.rows {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.row {
  display: flex;
  width: max-content;
  font-size: 15.5vh;
  line-height: 0.84;
  font-stretch: 50%;
  color: transparent;
  -webkit-text-stroke: 1.5px var(--ink);
  animation: slide var(--t) linear infinite;
}
.row:nth-child(even) { animation-direction: reverse; }
.row span { padding-right: 0.16em; }
@keyframes slide { to { transform: translateX(-50%); } }

.s-rows .word {
  text-shadow:
    0.012em 0.012em 0 var(--ink), 0.024em 0.024em 0 var(--ink),
    0.036em 0.036em 0 var(--ink), 0.048em 0.048em 0 var(--ink),
    0.06em 0.06em 0 var(--ink), 0.072em 0.072em 0 var(--ink);
  -webkit-text-stroke: 0.012em var(--ink);
  paint-order: stroke fill;
}
.s-rows .l {
  animation: bob 0.9s ease-in-out infinite alternate;
  animation-delay: calc(var(--i) * -0.3s);
}
@keyframes bob {
  from { transform: translateY(-0.035em); }
  to   { transform: translateY(0.035em); }
}

/* ---------- 4. slices: the word is cut into strips that slide ---------- */

.s-slice { --bg: #1a22ff; --fg: #e6ff3a; }
.s-slice .fitbox { font-stretch: 125%; }
.ghost { visibility: hidden; }
.slice {
  position: absolute;
  inset: 0;
  clip-path: inset(
    calc(var(--n) * 100% / var(--of) - 0.5px) -30%
    calc((var(--of) - 1 - var(--n)) * 100% / var(--of) - 0.5px) -30%
  );
  animation: shear 1.5s ease-in-out infinite alternate;
  animation-delay: calc(var(--n) * -3s / var(--of));
}
@keyframes shear {
  from { transform: translateX(-3%); }
  to   { transform: translateX(3%); }
}

/* ---------- 5. pop: a stacked shadow orbits the letters ---------- */

.s-pop { --bg: #f3eee2; --fg: #121212; }
.s-pop .fitbox { animation: orbit 3.2s linear infinite; }
.s-pop .l {
  animation: wobble 1.4s ease-in-out infinite alternate;
  animation-delay: calc(var(--i) * -0.47s);
}
@keyframes orbit { to { --a: 360deg; } }
@keyframes wobble {
  from { transform: rotate(-5deg) translateY(-0.02em); }
  to   { transform: rotate(5deg) translateY(0.02em); }
}

/* ---------- 6. eq: the letters pump like level meters ---------- */

.s-eq { --bg: #c8ff2e; --fg: #0b0b0b; }
.s-eq .fitbox { font-stretch: 75%; }
.s-eq .l {
  transform-origin: 50% 90%;
  animation: pump 0.62s cubic-bezier(.5, 0, .5, 1) infinite alternate;
  animation-delay: calc(var(--i) * -0.41s);
}
@keyframes pump {
  from { transform: scaleY(0.3); }
  to   { transform: scaleY(1); }
}

/* ---------- 7. tunnel: outlines fly out of the word ---------- */

.s-tunnel { --bg: #14002b; --fg: #ffffff; --line: #ff4df0; }
.echo {
  position: absolute;
  inset: 0;
  color: transparent;
  -webkit-text-stroke: 0.008em var(--line);
  animation: zoom 4.2s linear infinite;
  animation-delay: calc(var(--n) * -4.2s / var(--of));
}
.s-tunnel .echo ~ .word:not(.echo) {
  position: relative;
  animation: throb 0.6s ease-in-out infinite alternate;
}
@keyframes zoom {
  from { transform: scale(1); opacity: 1; }
  70%  { opacity: 0.9; }
  to   { transform: scale(4.5); opacity: 0; }
}
@keyframes throb {
  from { transform: scale(0.97); }
  to   { transform: scale(1.02); }
}

/* ---------- 8. hazard: stripes run through the letters ---------- */

.s-hazard { --bg: #ffd400; --fg: #0b0b0b; }
.s-hazard .l {
  color: transparent;
  background: linear-gradient(-45deg, var(--fg) 25%, transparent 25% 50%, var(--fg) 50% 75%, transparent 75%);
  background-size: 0.2em 0.2em;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-stroke: 0.022em var(--fg);
  animation: stripes 0.7s linear infinite;
}
.s-hazard .l:nth-child(even) { animation-direction: reverse; }
.s-hazard .fitbox { animation: sway 2.4s ease-in-out infinite alternate; }
@keyframes stripes { to { background-position: 0.2em 0; } }
@keyframes sway {
  from { transform: skewX(-7deg); }
  to   { transform: skewX(7deg); }
}
@media (max-aspect-ratio: 4/5) {
  /* A tall block leans much further at the same angle, so lean less. */
  .s-hazard .fitbox { animation-name: sway-tall; }
}
@keyframes sway-tall {
  from { transform: skewX(-2.5deg); }
  to   { transform: skewX(2.5deg); }
}

/* ---------- 9. flip: the letters turn over one after another ---------- */

.s-flip { --bg: #ff4fa3; --fg: #1b0030; }
.s-flip .l {
  animation: flip 1.8s cubic-bezier(.6, 0, .2, 1) infinite;
  animation-delay: calc(var(--i) * -0.3s);
}
@keyframes flip {
  0%, 35% { transform: perspective(5em) rotateX(0); color: var(--fg); }
  67%     { color: #fff7d6; }
  100%    { transform: perspective(5em) rotateX(360deg); color: var(--fg); }
}

/* ---------- 10. reel: every letter rolls like a slot machine ---------- */

.s-reel { --bg: #00b3a4; --fg: #0b0b0b; }
.s-reel .l {
  height: 0.8em;
  overflow: hidden;
}
.reel {
  display: block;
  animation: roll 2.4s cubic-bezier(.7, 0, .2, 1) infinite;
  animation-delay: calc(var(--i) * -0.4s);
}
.s-reel .pair .l:nth-child(even) .reel { animation-direction: reverse; }
.reel b {
  display: block;
  position: relative;
  top: 0.066em;
  height: 0.8em;
  font-weight: inherit;
}
.reel b:nth-child(2) {
  color: transparent;
  -webkit-text-stroke: 0.02em var(--fg);
}
@keyframes roll {
  0%        { transform: translateY(0); }
  45%, 50%  { transform: translateY(-33.333%); }
  95%, 100% { transform: translateY(-66.667%); }
}

/* ---------- the transition bars ---------- */

#wipe {
  position: fixed;
  inset: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  pointer-events: none;
}
#wipe.v { flex-direction: row; }
#wipe i {
  flex: 1;
  margin: -0.5px;
  transform: scale(0);
}

#stage.cut .scene.on { animation: cut 0.5s steps(1); }
@keyframes cut {
  0%  { transform: translateX(-2%) skewX(-4deg); filter: invert(1); }
  12% { transform: translateX(3%); filter: none; }
  24% { transform: translateY(-2%) scaleY(1.05); }
  36% { transform: translateX(-1%) skewX(6deg); filter: hue-rotate(90deg); }
  48% { transform: none; filter: none; }
}

/* ---------- the project list, laid over a blurred and dimmed loop ---------- */
/* Quiet type on purpose: one plain sans (Inter), tight and large for the names. */

@font-face {
  font-family: "Inter";
  src: url("/fonts/inter.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}

#menu {
  --pad: max(7vw, 24px);
  position: fixed;
  inset: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* --n is the number of projects, set in main.js, so any count fits the screen. */
  gap: min(7vh, calc(16vh / var(--n, 2)));
  padding: 12vh var(--pad);
  font-family: "Inter", system-ui, sans-serif;
  font-weight: 400;
  color: #f3efe4;
  background: rgb(8 8 8 / 0.8);
  -webkit-backdrop-filter: blur(28px) saturate(1.3);
  backdrop-filter: blur(28px) saturate(1.3);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.35s ease, visibility 0s 0.35s;
}
body.open #menu {
  opacity: 1;
  visibility: visible;
  transition: opacity 0.35s ease;
}

.menu-top,
.menu-bottom {
  position: absolute;
  left: var(--pad);
  right: var(--pad);
  display: flex;
  justify-content: space-between;
}
.menu-top { top: max(24px, env(safe-area-inset-top)); }
.menu-bottom { bottom: max(26px, env(safe-area-inset-bottom)); }

.menu-top,
.meta {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.5;
}

#menu .proj {
  display: block;
  width: fit-content;
  max-width: 100%;
  color: inherit;
  text-decoration: none;
  opacity: 0;
  transform: translateY(1.2em);
  transition: opacity 0.2s ease, transform 0.2s ease;
}
body.open #menu .proj {
  opacity: 1;
  transform: none;
  transition: opacity 0.5s ease, transform 0.6s cubic-bezier(.2, .8, .2, 1);
  transition-delay: calc(var(--k, 0) * 0.08s + 0.08s);
}
#menu .proj:nth-of-type(2) { --k: 1; }
#menu .proj:nth-of-type(3) { --k: 2; }
#menu .proj:nth-of-type(4) { --k: 3; }
#menu .proj:nth-of-type(5) { --k: 4; }
#menu .proj:nth-of-type(6) { --k: 5; }

.meta, .name { display: block; }
.meta b { margin-right: 1.4em; font-weight: 500; }
.name {
  margin: 0.12em 0 0 -0.05em;
  font-size: min(11.5vw, 21vh, calc(44vh / var(--n, 2)));
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.05em;
  white-space: nowrap;
  position: relative;
  transition: color 0.3s ease;
}
.c {
  display: inline-block;
  position: relative;
  white-space: pre;
}

#menu .proj:focus-visible { outline: none; }

.menu-bottom a {
  color: inherit;
  text-decoration: none;
  font-size: clamp(17px, 1.6vw, 24px);
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1;
  padding: 0.5em 0;
  margin: -0.5em 0;
  transition: color 0.3s ease;
}
.menu-bottom a:hover,
.menu-bottom a:focus-visible,
.menu-bottom a:active { color: #d6ff5c; outline: none; }

/* ---------- a hovered project link takes on the style playing behind it ---------- */

/* wave */
body[data-style="wave"] #menu .proj:is(:hover, :focus-visible, :active) .c {
  animation: h-wave 0.7s ease-in-out infinite alternate;
  animation-delay: calc(var(--i) * -0.2s);
}
@keyframes h-wave {
  from { font-weight: 200; }
  to   { font-weight: 900; }
}

/* rows */
body[data-style="rows"] #menu .proj:is(:hover, :focus-visible, :active) .name {
  color: #fff4e2;
  text-shadow:
    0.012em 0.012em 0 #ff3b0a, 0.024em 0.024em 0 #ff3b0a, 0.036em 0.036em 0 #ff3b0a,
    0.048em 0.048em 0 #ff3b0a, 0.06em 0.06em 0 #ff3b0a, 0.072em 0.072em 0 #ff3b0a;
}
body[data-style="rows"] #menu .proj:is(:hover, :focus-visible, :active) .c {
  animation: bob 0.5s ease-in-out infinite alternate;
  animation-delay: calc(var(--i) * -0.17s);
}

/* glitch */
body[data-style="glitch"] #menu .proj:is(:hover, :focus-visible, :active) .name { color: #fff; animation: jolt 3.1s steps(1) infinite; }
body[data-style="glitch"] #menu .proj:is(:hover, :focus-visible, :active) .c::before,
body[data-style="glitch"] #menu .proj:is(:hover, :focus-visible, :active) .c::after {
  content: attr(data-c);
  position: absolute;
  inset: 0;
  mix-blend-mode: screen;
}
body[data-style="glitch"] #menu .proj:is(:hover, :focus-visible, :active) .c::before {
  color: #00f0ff;
  animation: split-a 2.1s steps(1) infinite;
  animation-delay: calc(var(--i) * -0.37s);
}
body[data-style="glitch"] #menu .proj:is(:hover, :focus-visible, :active) .c::after {
  color: #ff0055;
  animation: split-b 1.7s steps(1) infinite;
  animation-delay: calc(var(--i) * -0.23s);
}

/* eq */
body[data-style="eq"] #menu .proj:is(:hover, :focus-visible, :active) .name { color: #c8ff2e; }
body[data-style="eq"] #menu .proj:is(:hover, :focus-visible, :active) .c {
  transform-origin: 50% 82%;
  animation: pump 0.62s cubic-bezier(.5, 0, .5, 1) infinite alternate;
  animation-delay: calc(var(--i) * -0.41s);
}

/* slice: three bands of the name slide against each other */
body[data-style="slice"] #menu .proj:is(:hover, :focus-visible, :active) .name { color: #e6ff3a; }
body[data-style="slice"] #menu .proj:is(:hover, :focus-visible, :active) .name::before,
body[data-style="slice"] #menu .proj:is(:hover, :focus-visible, :active) .name::after {
  content: attr(data-text);
  position: absolute;
  left: 0;
  top: 0;
}
body[data-style="slice"] #menu .proj:is(:hover, :focus-visible, :active) .name::before {
  clip-path: inset(0 -1em 62% -1em);
  animation: h-shear 0.9s ease-in-out infinite alternate;
}
body[data-style="slice"] #menu .proj:is(:hover, :focus-visible, :active) .c {
  clip-path: inset(38% -1em 38% -1em);
  animation: h-shear 0.9s ease-in-out -0.6s infinite alternate;
}
body[data-style="slice"] #menu .proj:is(:hover, :focus-visible, :active) .name::after {
  clip-path: inset(62% -1em 0 -1em);
  animation: h-shear 0.9s ease-in-out -1.2s infinite alternate;
}
@keyframes h-shear {
  from { transform: translateX(-0.07em); }
  to   { transform: translateX(0.07em); }
}

/* tunnel */
body[data-style="tunnel"] #menu .proj:is(:hover, :focus-visible, :active) .name { color: #fff; }
body[data-style="tunnel"] #menu .proj:is(:hover, :focus-visible, :active) .name::before,
body[data-style="tunnel"] #menu .proj:is(:hover, :focus-visible, :active) .name::after {
  content: attr(data-text);
  position: absolute;
  left: 0;
  top: 0;
  color: transparent;
  -webkit-text-stroke: 0.012em #ff4df0;
  animation: h-zoom 1.4s linear infinite;
}
body[data-style="tunnel"] #menu .proj:is(:hover, :focus-visible, :active) .name::after { animation-delay: -0.7s; }
@keyframes h-zoom {
  from { transform: scale(1); opacity: 1; }
  to   { transform: scale(1.7); opacity: 0; }
}

/* pop */
body[data-style="pop"] #menu .proj:is(:hover, :focus-visible, :active) .name {
  animation: orbit 3.2s linear infinite;
  text-shadow:
    calc(cos(var(--a)) * 0.012em) calc(sin(var(--a)) * 0.012em) 0 #ff2d2d,
    calc(cos(var(--a)) * 0.024em) calc(sin(var(--a)) * 0.024em) 0 #ff2d2d,
    calc(cos(var(--a)) * 0.036em) calc(sin(var(--a)) * 0.036em) 0 #ff2d2d,
    calc(cos(var(--a)) * 0.048em) calc(sin(var(--a)) * 0.048em) 0 #2b4bff,
    calc(cos(var(--a)) * 0.06em) calc(sin(var(--a)) * 0.06em) 0 #2b4bff,
    calc(cos(var(--a)) * 0.072em) calc(sin(var(--a)) * 0.072em) 0 #2b4bff,
    calc(cos(var(--a)) * 0.084em) calc(sin(var(--a)) * 0.084em) 0 #ffc400,
    calc(cos(var(--a)) * 0.096em) calc(sin(var(--a)) * 0.096em) 0 #ffc400,
    calc(cos(var(--a)) * 0.108em) calc(sin(var(--a)) * 0.108em) 0 #ffc400;
}
body[data-style="pop"] #menu .proj:is(:hover, :focus-visible, :active) .c {
  animation: wobble 1.4s ease-in-out infinite alternate;
  animation-delay: calc(var(--i) * -0.47s);
}

/* hazard */
body[data-style="hazard"] #menu .proj:is(:hover, :focus-visible, :active) .name { animation: sway-tall 1.2s ease-in-out infinite alternate; }
body[data-style="hazard"] #menu .proj:is(:hover, :focus-visible, :active) .c {
  color: transparent;
  background: linear-gradient(-45deg, #ffd400 25%, transparent 25% 50%, #ffd400 50% 75%, transparent 75%);
  background-size: 0.2em 0.2em;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-stroke: 0.02em #ffd400;
  animation: stripes 0.7s linear infinite;
}

/* flip */
body[data-style="flip"] #menu .proj:is(:hover, :focus-visible, :active) .name { --fg: #ff4fa3; }
body[data-style="flip"] #menu .proj:is(:hover, :focus-visible, :active) .c {
  animation: flip 1.8s cubic-bezier(.6, 0, .2, 1) infinite;
  animation-delay: calc(var(--i) * -0.3s);
}

/* reel */
body[data-style="reel"] #menu .proj:is(:hover, :focus-visible, :active) .name { color: #19d6c5; }
body[data-style="reel"] #menu .proj:is(:hover, :focus-visible, :active) .c {
  animation: h-roll 1.2s cubic-bezier(.7, 0, .2, 1) infinite;
  animation-delay: calc(var(--i) * -0.2s);
}
@keyframes h-roll {
  0%, 20%   { transform: translateY(0); opacity: 1; }
  55%       { transform: translateY(-0.8em); opacity: 0; }
  56%       { transform: translateY(0.8em); opacity: 0; }
  90%, 100% { transform: translateY(0); opacity: 1; }
}

@media (max-aspect-ratio: 4/5) {
  .name { font-size: min(16vw, 13vh, calc(46vh / var(--n, 2))); }
}
