/* ==========================================================================
   SITE MENU
   Built from the Figma file "the-site-menu" (frames "Main", "Menu Selector"
   and "Main Projects", 402 × 874). Like the Assumption Machine, each screen is drawn at its Figma
   size and scaled to fit the phone, so all positions are Figma coordinates.
   ========================================================================== */

/* Paper Mono, Medium and Bold (the two weights the design uses) */
@font-face { font-family: "Paper Mono"; font-weight: 500; font-display: swap;
  src: url("assets/fonts/PaperMono-Medium.woff2") format("woff2"); }
@font-face { font-family: "Paper Mono"; font-weight: 700; font-display: swap;
  src: url("assets/fonts/PaperMono-Bold.woff2") format("woff2"); }

:root {
  --sage: #aab69b;      /* text, frames */
  --cream: #f4fad2;     /* corner marks */
  --violet: #8870ff;    /* buttons */
  --black: #000;
  --mono: "Paper Mono", ui-monospace, Menlo, monospace;
  color-scheme: dark;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; background: var(--black); }
body { overflow: hidden; font-family: var(--mono); font-weight: 500; color: var(--sage); }
button, a { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; text-decoration: none; -webkit-tap-highlight-color: transparent; }
button:focus, a:focus { outline: none; }
.kb button:focus-visible, .kb a:focus-visible { outline: 2px solid var(--violet); outline-offset: 3px; }

/* Fixed frame the size of the window; the 402 × 874 screen is scaled inside. */
.viewport { position: fixed; inset: 0; overflow: hidden; background: var(--black); }
.screen {
  position: absolute; left: 0; top: 0;
  width: 402px; height: 874px;
  overflow: hidden;
  background: var(--black);
  transform-origin: 0 0;
  opacity: 0; visibility: hidden;
  transition: opacity 600ms ease, visibility 0s linear 600ms;   /* Figma: dissolve 600ms */
}
.screen.on { opacity: 1; visibility: visible; transition: opacity 600ms ease, visibility 0s; }
/* Arriving straight at the Menu Selector / Main Projects (e.g. from a
   project's EXIT): Main stays hidden and the screen dissolves in from black */
[data-open] #main { opacity: 0; visibility: hidden; }
[data-open="menu"] #menu, [data-open="projects"] #projects { opacity: 0; visibility: visible; }
.instant .screen { transition: none !important; }
/* Opening a project page: the whole site fades to black first (200ms) */
.viewport { transition: opacity 200ms ease; }
/* Coming back from a project page: the screen dissolves in faster (300ms) */
.quick .screen, .quick .screen.on { transition-duration: 300ms; }
.viewport.leaving { opacity: 0; }
.viewport.instant { transition: none !important; }
.screen img, .screen video { display: block; max-width: none; }

.abs { position: absolute; }
.mid { transform: translateY(-50%); }
.missing { visibility: hidden !important; }

/* ---------- Shared frame ---------- */
.dash {
  left: 24px; top: 56px; width: 354px; height: 778px;
  opacity: .5;
  /* 16-on / 16-off dashed border, as in Figma */
  background:
    repeating-linear-gradient(90deg, var(--sage) 0 16px, transparent 16px 32px) top / 100% 1px no-repeat,
    repeating-linear-gradient(90deg, var(--sage) 0 16px, transparent 16px 32px) bottom / 100% 1px no-repeat,
    repeating-linear-gradient(180deg, var(--sage) 0 16px, transparent 16px 32px) left / 1px 100% no-repeat,
    repeating-linear-gradient(180deg, var(--sage) 0 16px, transparent 16px 32px) right / 1px 100% no-repeat;
}
.dash-line { left: 24px; width: 354px; height: 1px; opacity: .5;
  background: repeating-linear-gradient(90deg, var(--sage) 0 16px, transparent 16px 32px); }
.corner { width: 16px; height: 16px; border-color: var(--cream); border-style: solid; border-width: 0; }
.corner.tl { border-top-width: 1px; border-left-width: 1px; }
.corner.tr { border-top-width: 1px; border-right-width: 1px; }
.corner.bl { border-bottom-width: 1px; border-left-width: 1px; }
.corner.br { border-bottom-width: 1px; border-right-width: 1px; }

.ver  { left: 24px;  top: 42px; font-size: 16px; line-height: normal; white-space: nowrap; }
.date { right: 23px; top: 42px; font-size: 16px; line-height: normal; white-space: nowrap; text-align: right; }

/* Bubble video seen through three windows across the top */
.bubble { top: 58px; height: 88px; overflow: hidden;
  -webkit-mask: var(--bars) no-repeat 0 0 / 100% 100%; mask: var(--bars) no-repeat 0 0 / 100% 100%; }
/* bubble.mp4 is pre-cropped to the band that shows through the windows */
.bubble video { position: absolute; top: 0; width: 350px; height: 88px; object-fit: fill; }
.bubble.main { left: 27px; width: 349px;
  --bars: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='349' height='88'%3E%3Cg fill='white'%3E%3Crect width='115' height='88'/%3E%3Crect x='117' width='115' height='88'/%3E%3Crect x='234' width='115' height='88'/%3E%3C/g%3E%3C/svg%3E"); }
.bubble.main video { left: -1px; }
.bubble.menu { left: 26px; width: 350px;
  --bars: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='350' height='88'%3E%3Cg fill='white'%3E%3Crect width='116' height='88'/%3E%3Crect x='117' width='116' height='88'/%3E%3Crect x='234' width='116' height='88'/%3E%3C/g%3E%3C/svg%3E"); }
.bubble.menu video { left: 0; }

/* ==========================================================================
   MAIN
   ========================================================================== */
.grid-lines { left: 25px; top: 148px; width: 352px; height: 685px; opacity: .5; pointer-events: none; }
.grid-lines i { position: absolute; background: var(--sage); }

/* PORTFOLIO: each letter sweeps through its own cell (Figma "word cut":
   2s linear sweep, then 1s offstage, repeating). Positions are set by menu.js. */
.word { left: 27px; top: 148px; width: 348px; height: 579px; visibility: hidden; }
.word.ready { visibility: visible; }
.cell { position: absolute; width: 116px; height: 193px; overflow: hidden; }
.glyph {
  position: absolute; left: 0; top: 0; width: 116px; height: 193px; overflow: visible;
  transform: translate(var(--fx), var(--fy));            /* rests offstage */
  animation: sweep 3s linear infinite;
}
.glyph text { font-family: var(--mono); font-weight: 500; font-size: 269.92px; fill: var(--sage); }
@keyframes sweep {
  0%      { transform: translate(var(--fx), var(--fy)); }
  66.667% { transform: translate(var(--tx), var(--ty)); }
  100%    { transform: translate(var(--tx), var(--ty)); }
}

/* Profile picture window (PFPPixel_3, pre-cropped to the window).
   The video is drawn onto the canvas: some phones misplace a <video> on a
   scaled page, a canvas always stays in its box. */
.pfp { left: 27px; top: 729px; width: 114px; height: 102px; overflow: hidden; background: url("assets/media/pfp-poster.jpg?v=20261025a") 0 0 / 100% 100%; }
.pfp canvas { position: absolute; left: 0; top: 0; width: 114px; height: 102px; }
.pfp video { position: absolute; left: 0; top: 0; width: 1px; height: 1px; opacity: 0; pointer-events: none; }

.intro { left: 143px; top: 728px; width: 116px; font-size: 10px; line-height: normal; white-space: pre-wrap; }

/* COME: the violet fill fades out and back in over 2s */
.come { left: 261px; top: 729px; width: 115px; height: 102.5px; }
.come .fill { position: absolute; inset: 0; background: var(--violet); animation: come-pulse 2s infinite; }
/* come-art.png is the Figma artwork with the word COME, rendered at 3x */
.come img { position: absolute; left: 0; top: 0; width: 115px; height: 102.5px; }
@keyframes come-pulse {
  0%   { opacity: 1; animation-timing-function: ease-out; }
  50%  { opacity: 0; animation-timing-function: ease-in; }
  100% { opacity: 1; }
}

/* ==========================================================================
   MENU SELECTOR and MAIN PROJECTS (same header)
   ========================================================================== */
.portfolio { left: 30px; top: 74px; font-size: 26px; line-height: normal; white-space: nowrap; z-index: 2; }

/* Loading bars: fill one by one every 0.3s, then Back lights up, then repeat */
.load { left: 32px; top: 63px; width: 338px; height: 76px; }
.load i { position: absolute; width: 16px; border: 1px solid var(--sage); transition: background 300ms linear; }
.load i.short { top: 27px; height: 49px; }
.load i.tall { top: 0; height: 76px; }
.load i.lit { background: var(--sage); }
.load.reset i { transition: none; }
.back {
  left: 296px; top: 63px; width: 74px; height: 76px;
  border: 1px solid var(--sage);
  font-weight: 700; font-size: 16px;
  transition: background 300ms linear;
}
.back span { position: absolute; left: 17px; top: 32px; line-height: 11px; }
.back.lit { background: var(--violet); }
.load.reset ~ .back { transition: none; }

.section-label { left: 31px; top: 161.5px; width: 340px; font-size: 16px; line-height: normal; white-space: pre; }

.preview { left: 36px; top: 179px; width: 332px; height: 422px; overflow: hidden; }
/* --planet-shift moves the planet right inside its window */
.preview { --planet-shift: 0px; }
.preview video { position: relative; left: var(--planet-shift); width: 100%; height: 100%; object-fit: cover; }
.star { width: 1px; height: 1px; background: var(--sage); }

/* Carousel ("Menu Frame" in Figma). The canvas covers the part of the
   frame above the black panel, so circles disappear behind it. */
.carousel { left: 32px; top: 175px; width: 338px; height: 430px; overflow: hidden; pointer-events: none; }
.carousel canvas { position: absolute; left: 0; top: 0; width: 338px; height: 430px; }
.carousel video { position: absolute; left: 0; top: 0; width: 1px; height: 1px; opacity: 0; }
.tri { left: 189px; top: 602px; width: 23px; height: 23px; }

/* Project title: long titles scroll right to left (Figma: 2.5s linear loop),
   short ones sit in the middle. Changing project crossfades the title. */
.title { left: 32px; top: 619px; width: 338px; height: 42px; overflow: hidden; font-size: 26px; transition: opacity 250ms ease; }
.title.fade { opacity: 0; }
.title .track { position: absolute; left: -4px; top: 12px; display: flex; gap: 44px; white-space: nowrap; line-height: 19px; }
.title .track.scroll { animation: title-scroll 2.5s linear infinite; }
.title .track span { width: 347px; flex: none; }
.title .track.still span { text-align: center; }
@keyframes title-scroll { to { transform: translateX(-391px); } }

.arrow { width: 54px; height: 54px; }
.arrow svg { display: block; width: 54px; height: 54px; }
.prev { left: 254px; top: 710px; }
.next { left: 316px; top: 710px; }
.arrow[aria-disabled="true"] { cursor: default; }
.select { left: 254px; top: 772px; width: 116px; height: 54px; background: var(--violet); font-weight: 700; font-size: 16px;
  display: flex; align-items: center; justify-content: center; }
.select span { line-height: 11px; }
.arrow:active, .select:active, .come:active, .back:active { filter: brightness(1.25); }

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

@media (prefers-reduced-motion: reduce) {
  .glyph, .come .fill, .title .track { animation: none; }
  .glyph { transform: none; }
}
