/*
  Every page is exactly one screen and fills the window at any size or shape.

  `--u` is one unit of the original 1024 × 576 design, scaled so the whole
  design always fits on screen. Positions below are copied straight from the
  design file. Backgrounds (static, records, black) run past the design to
  the window's edges, so there's never an empty band.

  Phones and tall windows switch to a narrower virtual page so text stays
  readable (see the bottom of this file).
*/

:root {
  color-scheme: dark;
  --ink: #fff;
  --link: #4c8bf5;
  --chip: rgba(255, 255, 255, 0.68);
  --serif: "Petrona", Georgia, serif;
  --hand: "Schoolbell", "Comic Sans MS", cursive;
}

* { box-sizing: border-box; }

html { background: #000; }

body {
  margin: 0;
  background: #000;
  color: var(--ink);
  font-family: var(--serif);
  -webkit-font-smoothing: antialiased;
}

img { display: block; max-width: none; }

::selection { background: var(--link); color: #fff; }

a:focus-visible {
  outline: 2px solid var(--link);
  outline-offset: 3px;
}

.slide {
  --u: calc(min(100cqw, 177.778cqh) / 1024);
  position: relative;
  width: 100%;
  height: 100vh;
  height: 100dvh;
  container-type: size;
  overflow: hidden;
}

/* =========================================================
   Home · TV
   ========================================================= */

/* the TV takes everything left of the nav column, so it stretches with the window */
.tv {
  --t: calc(min(100cqw / 787.7, 100cqh / 575.7)); /* one design unit, measured against the TV */
  position: absolute;
  left: 0;
  top: 0;
  width: calc(100% - 236.3 * var(--u));
  height: 100%;
  container-type: size;
  isolation: isolate;
}

.tv__static {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
}

/* CRT glass: faint scanlines and darker corners */
.tv::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    repeating-linear-gradient(to bottom, rgba(10, 6, 30, 0.14) 0 1px, transparent 1px 3px),
    radial-gradient(ellipse 72% 68% at 48% 50%, transparent 55%, rgba(14, 10, 32, 0.55) 100%);
}

/* The bezel photo as a 9-slice frame: corners stay put, edges stretch.
   At the design's proportions it lines up exactly with the original photo. */
.tv__frame {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  border-style: solid;
  border-color: transparent;
  border-width:
    calc(50.6 * var(--t))
    calc(100.9 * var(--t))
    calc(63.2 * var(--t))
    calc(82 * var(--t));
  border-image: url("assets/tv-frame.webp") 80 160 100 130 / 1 / 0 stretch;
}

/* the cursive signature, white straight on the static, like a channel logo in the corner */
.tv__name {
  position: absolute;
  z-index: 3;
  left: calc(44 * var(--t));
  top: calc(30 * var(--t));
  width: calc(204 * var(--t));
  margin: 0;
}

.tv__name img {
  width: 100%;
  height: auto;
  /* thicken the pen strokes slightly, then a soft dark edge so they read against the bright static */
  filter:
    drop-shadow(0 0 0.3px #fff)
    drop-shadow(0 0 1.5px rgba(16, 10, 36, 0.9))
    drop-shadow(0 1px 3px rgba(16, 10, 36, 0.7));
}

/* the intro stays where it sits in the design, relative to the screen's middle */
.tv__intro {
  --px: calc(100cqw / 608.7); /* measured against the intro itself */
  position: absolute;
  z-index: 3;
  width: calc(608.7 * var(--t));
  left: calc(49.4% - 304.35 * var(--t));
  top: calc(52.6% - 167.2 * var(--t));
  container-type: inline-size;
}

.tv__intro .pixel-art { width: 100%; height: auto; }

.pixel-text--center {
  left: 0;
  right: 0;
  top: 0;
  text-align: center;
}

/* nav, anchored to the top-right corner */
.nav {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 5;
}

.nav__row {
  position: absolute;
  top: calc(25.5 * var(--u));
  right: calc(22 * var(--u));
  display: flex;
  gap: calc(20.2 * var(--u));
  white-space: nowrap;
}

.nav__link {
  color: var(--ink);
  font-size: calc(27.08 * var(--u));
  line-height: 1;
  text-decoration: none;
  text-underline-offset: 0.18em;
  text-decoration-thickness: 0.06em;
}

.nav__link:hover { text-decoration: underline; }

/* Cool Projects: the right-hand column, which starts at x = 748 in the design.
   Positions inside are measured from that edge. */
.projects {
  position: absolute;
  top: 0;
  right: 0;
  width: calc(276 * var(--u));
  height: 100%;
  z-index: 4;
  pointer-events: none; /* the column box itself mustn't catch clicks meant for the nav */
}

.projects > * { pointer-events: auto; }

.projects__title {
  position: absolute;
  left: calc(45.29 * var(--u));
  top: calc(103.4 * var(--u));
  width: calc(175.87 * var(--u));
  margin: 0;
  background: var(--chip);
}

.projects__title img { width: 100%; height: auto; }

/* The Deskpad + Developings block, nudged left and scaled up a touch as one piece
   (around its top-left corner) from where it sits in the design. */
.projects__list {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  transform-origin: calc(57 * var(--u)) calc(159 * var(--u));
  transform: translateX(calc(-16 * var(--u))) scale(1.08);
  pointer-events: none;
}

.project > * { pointer-events: auto; }

.project > * { position: absolute; margin: 0; }

.project__logo { height: auto; }

.project__name {
  color: var(--link);
  font-size: calc(20.5 * var(--u));
  line-height: 1;
  white-space: nowrap;
  text-decoration-thickness: calc(1.71 * var(--u));
  text-underline-offset: calc(1.14 * var(--u));
}

.project__name:hover { color: #7aa9ff; }

/* tenure badge: a pushpin holding a curved label; inner positions are % of the badge */
.project__time { display: block; }
.project__time img { position: absolute; height: auto; }
.project__tenure { left: 0; bottom: 0; width: 100%; z-index: 1; }
.project__pin { z-index: 2; } /* the pin sits in front of the label it's holding */

.project--deskpad .project__time    { aspect-ratio: 35.5 / 24.44; }
.project--deskpad .project__pin     { left: 36.45%; top: 0; width: 40.1%; }
.project--developings .project__time { aspect-ratio: 31 / 23.89; }
.project--developings .project__pin   { left: 38.45%; top: 0; width: 45.97%; }

.project__desc {
  font-weight: 700;
  font-size: calc(13.65 * var(--u));
  line-height: calc(18.765 * var(--u));
  white-space: nowrap;
}

.project--deskpad .project__logo { left: calc(64.86 * var(--u));  top: calc(159.45 * var(--u)); width: calc(25.35 * var(--u)); }
.project--deskpad .project__name { left: calc(101.68 * var(--u)); top: calc(164.51 * var(--u)); }
.project--deskpad .project__time { left: calc(192 * var(--u));    top: calc(160.16 * var(--u)); width: calc(35.5 * var(--u)); }
.project--deskpad .project__desc { left: calc(87.25 * var(--u));  top: calc(201.41 * var(--u)); }

.project--developings .project__logo { left: calc(57.33 * var(--u));  top: calc(273.14 * var(--u)); width: calc(40.25 * var(--u)); }
.project--developings .project__name { left: calc(101.69 * var(--u)); top: calc(279.03 * var(--u)); }
.project--developings .project__time { left: calc(224.8 * var(--u));  top: calc(274.71 * var(--u)); width: calc(31 * var(--u)); }
.project--developings .project__desc { left: calc(87.25 * var(--u));  top: calc(320.91 * var(--u)); }

/* "+ hopefully more to come :)" — Dot Mincho at 9 units a character */
.projects__more {
  --px: calc(100cqw / 567); /* 21-unit pixel grid → 9 units, measured against this line itself */
  position: absolute;
  left: calc(19.4 * var(--u));
  top: calc(496.1 * var(--u));
  width: calc(243 * var(--u));
  margin: 0;
  container-type: inline-size;
}

.projects__more .pixel-art { width: 100%; height: auto; }
.projects__more .pixel-text { left: 0; top: calc(4.8 * var(--px)); }

/* =========================================================
   Selectable pixel text
   Dot Mincho 16 has no web version, so the visible letters are the shapes
   exported from Canva. The real text sits on top, invisible. Every
   character is forced onto the font's 21-unit grid (whatever monospace
   font the browser picks), so highlighting lines up with the letters.
   ========================================================= */

.pixel-text {
  position: absolute;
  margin: 0;
  color: transparent;
  font-family: ui-monospace, Menlo, Consolas, "Courier New", monospace;
  font-size: calc(34 * var(--px));
  letter-spacing: calc(21 * var(--px) - 1ch);
  line-height: calc(58.47 * var(--px));
  white-space: nowrap;
  translate: 0 calc(-6.6 * var(--px)); /* centers the highlight on the letters, which sit high in each line */
}

.pixel-text::selection {
  color: transparent;
  background: rgba(76, 139, 245, 0.45);
}

/* =========================================================
   Blog
   ========================================================= */

/* the records photo covers the whole window, whatever its shape */
.blog__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: left top;
}

.blog__title {
  position: absolute;
  left: calc(144.2 * var(--u));
  top: calc(14.72 * var(--u));
  width: calc(363.7 * var(--u));
  margin: 0;
}

.blog__title img { width: 100%; height: auto; }

.blog__sections {
  position: absolute;
  left: calc(135.63 * var(--u));
  top: calc(195.03 * var(--u));
  margin: 0;
  font-size: calc(31.07 * var(--u));
  line-height: 1;
  white-space: nowrap;
}

.posts {
  --px: var(--u);
  margin: 0;
  padding: 0;
  list-style: none;
}

.posts__bg {
  position: absolute;
  left: calc(25.785 * var(--u));
  top: calc(257.41 * var(--u));
  width: calc(692.66 * var(--u));
  height: auto;
}

/* each line is one 58.47-unit text line; its letter shapes sit on its part of the highlight */
.post {
  position: absolute;
  left: calc(25.785 * var(--u));
  height: calc(58.47 * var(--u));
}

.post .pixel-art {
  position: absolute;
  left: 0;
  top: var(--art-dy, 0);
  width: 100%;
  height: auto;
}

.post .pixel-text { left: 0; top: 0; }

.post--1 { top: calc(257.41 * var(--u));  width: calc(650.68 * var(--u)); }
.post--2 { top: calc(315.875 * var(--u)); width: calc(692.66 * var(--u)); }
.post--3 { top: calc(374.35 * var(--u));  width: calc(503.75 * var(--u)); --art-dy: calc(-16.49 * var(--u)); }

/* =========================================================
   Reach. Me.
   ========================================================= */

/* hands and words pinned to the top corners */
.hand {
  position: absolute;
  top: 0;
  height: auto;
}

.hand--l { left: 0;  width: calc(152.93 * var(--u)); }
.hand--r { right: 0; width: calc(151.8 * var(--u)); }

.reach__title {
  margin: 0;
  font: 400 calc(43.3 * var(--u)) / 1 var(--hand);
}

.reach__word {
  position: absolute;
  top: calc(61.6 * var(--u));
}

.reach__word--l { left: calc(160.5 * var(--u)); }
.reach__word--r { right: calc(155 * var(--u)); }

/* contact details stay centered in the window */
.contact {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(50% - 66.6 * var(--u));
  margin: 0;
  padding: 0;
  list-style: none;
  font-size: calc(27 * var(--u));
  line-height: 1;
}

.contact li {
  position: absolute;
  left: 0;
  right: 0;
  text-align: center;
}

.contact li:nth-child(1) { top: 0; }
.contact li:nth-child(2) { top: calc(74.9 * var(--u)); }
.contact li:nth-child(3) { top: calc(149.9 * var(--u)); }

.contact__form {
  color: var(--link);
  text-decoration-thickness: calc(2.3 * var(--u));
  text-underline-offset: calc(2 * var(--u));
}

.contact__form:hover { color: #7aa9ff; }

/* sketch and credit pinned to the bottom-right corner */
.sketch {
  position: absolute;
  right: calc(57 * var(--u));
  bottom: calc(31 * var(--u));
  width: calc(89.5 * var(--u));
  height: auto;
}

.credit {
  position: absolute;
  right: calc(8.4 * var(--u));
  bottom: calc(10.4 * var(--u));
  margin: 0;
  font: italic 400 calc(20 * var(--u)) / 1 var(--serif);
  white-space: nowrap;
}

/* =========================================================
   Way home: the "ag" monogram, placed within each page's layout
   ========================================================= */

/* bottom-left corner of the page; since every page fills the window, it never floats off the design */
.home {
  position: absolute;
  z-index: 10;
  left: calc(24 * var(--u));
  bottom: calc(22 * var(--u));
  width: max(52px, calc(78 * var(--u)));
  isolation: isolate;
}

/* a soft dark pool behind it so it stands out over the records photo
   (invisible on black) */
.home::before {
  content: "";
  position: absolute;
  inset: -40%;
  z-index: -1;
  background: radial-gradient(closest-side, rgba(0, 0, 0, 0.78), rgba(0, 0, 0, 0.55) 55%, transparent);
  pointer-events: none;
}

.home img {
  width: 100%;
  height: auto;
  /* the first three shadows thicken the thin pen strokes; the last adds a crisp dark edge */
  filter:
    drop-shadow(0 0 0.5px #fff)
    drop-shadow(0 0 0.5px #fff)
    drop-shadow(0 0 0.5px #fff)
    drop-shadow(0 1px 2px rgba(0, 0, 0, 0.9));
}

/* =========================================================
   Phones and tall windows
   ========================================================= */

@media (max-width: 640px), (max-aspect-ratio: 4/5) {
  /* nav becomes a bar across the top; the TV fills the rest of the screen */
  .slide--tv {
    display: flex;
    flex-direction: column;
  }

  .nav {
    position: static;
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 14px 16px;
  }

  .nav__row {
    position: static;
    gap: 18px;
  }

  .nav__link { font-size: 19px; }

  /* Cool Projects stacks under the TV */
  .projects {
    position: static;
    width: auto;
    height: auto;
    display: grid;
    gap: 14px;
    padding: 16px 16px 20px;
  }

  .projects__title {
    position: static;
    width: 128px;
  }

  .projects__list {
    position: static;
    transform: none;
    display: grid;
    gap: 14px;
  }

  .project {
    display: grid;
    grid-template-columns: 40px auto 1fr;
    column-gap: 10px;
    row-gap: 3px;
    align-items: baseline;
  }

  .project > * { position: static; }

  .project__logo {
    grid-row: 1 / span 2;
    align-self: center;
    justify-self: center;
  }

  .project--deskpad .project__logo { width: 26px; }
  .project--developings .project__logo { width: 40px; }

  .project__name { font-size: 20px; text-decoration-thickness: 1.5px; text-underline-offset: 2px; }

  .project > .project__time {
    position: relative;
    left: auto;
    top: auto;
    align-self: end;
    width: 34px;
  }

  .project__desc {
    grid-column: 2 / span 2;
    font-size: 14px;
    line-height: 1.3;
    white-space: normal;
  }

  .project__desc br { display: none; }

  .projects__more {
    position: relative; /* keeps the invisible text on top of its own line */
    left: 0;
    top: 0;
    width: 200px;
  }

  .tv {
    --t: calc(min(100cqw / 690, 100cqh / 575.7)); /* intro a little bigger, so the pixel text stays legible */
    position: relative;
    flex: 1;
    width: 100%;
    height: auto;
  }

  /* a narrower virtual page, so the post lines fill the phone's width */
  .slide--blog { --u: calc(min(100cqw, 123.33cqh) / 740); }
  .blog__bg { object-position: 52% top; } /* keeps the pale record label out from behind the white text */
  .blog__sections { text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7); }

  .slide--reach { --u: calc(min(100cqw, 104.17cqh) / 600); }
  .credit { font-size: max(12px, calc(20 * var(--u))); }
}
