/* ==========================================================================
   impizulu.com: an amber-phosphor CRT, one screen, mobile first.

   THE PIXEL GRID
   --------------
   Everything on this page is drawn on one grid whose unit is --px, "one CRT
   pixel". The grid is real, not decorative: VT323 is an outline font, but its
   stems land on whole pixels at particular sizes, so --fs is always chosen to
   put the stem at exactly 1 --px.

       --px   --fs    VT323 stem   icon (16px source)   heading (2x --fs)
       1px    20px    1px          16px  (1:1)          40px, 2px stem
       2px    24px    2px          32px  (2:1)          48px, 4px stem

   Measured, not assumed: rendering VT323 'H' and counting the run gives a 2px
   stem for 22-28px and 1px below 20px. The heading is exactly 2x the body
   size, which is a real terminal's double-height line, so its stem is exactly
   2 --px and stays on grid.

   Borders are 1 --px, gaps are multiples of --px, and the logos are 16x16
   rasters scaled by an integer factor, so every edge on the page falls on the
   same grid. Change --px and --fs together or the grid breaks.

   COLOUR
   ------
   A P3 amber phosphor: one hue at three levels, all measured against the lit
   screen (#100D07). The only colour that breaks the phosphor is the logos.
   ========================================================================== */

@font-face {
  font-family: "VT323";
  src: url("/fonts/vt323-regular.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}

:root {
  /* --- the grid (change --px and --fs together) --- */
  --px:   2px;         /* one CRT pixel                                 */
  --fs:   24px;        /* VT323 stem == 1 --px at this size             */
  --icon: 32px;        /* the 16px source raster, scaled 2x             */

  /* --- phosphor --- */
  --bg:     #0A0A08;   /* the dead screen                               */
  --screen: #100D07;   /* the lit screen                                */
  --fg:     #FFB000;   /* P3 amber             10.6:1 on --screen     */
  --bright: #FFD08A;   /* highlight            13.5:1                 */
  --dim:    #C08A0A;   /* secondary             6.4:1                 */
  --rule:   #7A5A0A;   /* borders (non-text)    3.0:1                 */

  --term: "VT323", ui-monospace, "Courier New", monospace;
}

/* Short screens step the whole grid down one notch, together, so the stem,
   the icon pixels and the borders stay in agreement. */
@media (max-height: 700px) {
  :root { --px: 1px; --fs: 20px; --icon: 16px; }
}

*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  min-height: 100svh;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--term);
  font-size: var(--fs);
  line-height: 1.25;
  -webkit-font-smoothing: none;
}

/* ---------- the cabinet ------------------------------------------------- */

.crt {
  position: relative;
  min-height: 100svh;
  display: grid;
  align-content: center;
  padding: max(calc(var(--px) * 5), env(safe-area-inset-top))
           max(calc(var(--px) * 5), env(safe-area-inset-right))
           max(calc(var(--px) * 5), env(safe-area-inset-bottom))
           max(calc(var(--px) * 5), env(safe-area-inset-left));
}

.screen {
  width: 100%;
  max-width: 30rem;
  margin-inline: auto;
  background: var(--screen);
  border: var(--px) solid var(--rule);
  box-shadow: 0 0 0 var(--px) #000, 0 0 30px rgba(255, 176, 0, 0.07);
}

/* Scanlines sit above everything and take no clicks. The period is 2 --px, so
   the lines land on the grid rather than shimmering across it. */
.scan {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 3;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0)    0,
    rgba(0, 0, 0, 0)    var(--px),
    rgba(0, 0, 0, 0.20) var(--px),
    rgba(0, 0, 0, 0.20) calc(var(--px) * 2)
  );
}

/* ---------- title bar --------------------------------------------------- */

.bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: calc(var(--px) * 3);
  padding: 0 calc(var(--px) * 3);
  border-bottom: var(--px) solid var(--rule);
  background: #17110A;
}

.bar-title {
  font-size: 0.75em;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--dim);
}

.bar-dots { display: flex; gap: var(--px); }
.bar-dots i {
  width: calc(var(--px) * 4);
  height: calc(var(--px) * 4);
  background: var(--rule);
}

/* ---------- screen body ------------------------------------------------- */

.body {
  display: grid;
  gap: calc(var(--px) * 3);
  padding: calc(var(--px) * 5);
}

.line { margin: 0; color: var(--dim); }
.ps1  { color: var(--dim); opacity: 0.85; }   /* 4.9:1 composited */
.cmd  { color: var(--bright); }

/* Double-height, exactly 2x the body size, a real terminal's DECDHL line. */
.name {
  margin: 0;
  font-size: calc(var(--fs) * 2);
  font-weight: 400;
  line-height: 1.1;
  color: var(--bright);
  text-shadow: 0 0 calc(var(--px) * 6) rgba(255, 176, 0, 0.45);
}

.bio { margin: 0; color: var(--fg); }
.hi  { color: var(--bright); }

/* ---------- link tiles -------------------------------------------------- */

.tiles {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: calc(var(--px) * 2);
}

.wide { grid-column: 1 / -1; }

.tiles a {
  display: grid;
  grid-template-columns: var(--icon) 1fr;
  align-items: center;
  gap: 0 calc(var(--px) * 3);
  min-height: 44px;                        /* touch target floor */
  height: 100%;
  padding: calc(var(--px) * 2) calc(var(--px) * 3);
  border: var(--px) solid var(--rule);
  color: var(--fg);
  text-decoration: none;
  cursor: pointer;
  transition: background-color 120ms steps(2), border-color 120ms steps(2);
}

/* Real brand marks, deliberately low-resolution: a 16x16 raster scaled by a
   whole number, so one source pixel is always exactly one square block. */
.tiles img {
  grid-row: 1 / 3;
  width: var(--icon);
  height: var(--icon);
  image-rendering: pixelated;
}

.tiles .t { color: var(--bright); line-height: 1.1; }
.tiles .h {
  font-size: 0.85em;
  color: var(--dim);
  line-height: 1.1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tiles a:hover  { background: #241A08; border-color: var(--fg); }
.tiles a:active { background: #2E2109; }

.tiles a:focus-visible,
.skip:focus-visible {
  outline: calc(var(--px) * 2) solid var(--bright);
  outline-offset: var(--px);
}

/* ---------- caret ------------------------------------------------------- */

.caret {
  display: inline-block;
  width: 0.55em;
  height: 1em;
  margin-left: 0.3em;
  vertical-align: -0.14em;
  background: var(--fg);
  box-shadow: 0 0 calc(var(--px) * 4) rgba(255, 176, 0, 0.6);
  animation: blink 1.1s steps(1, end) infinite;
}

@keyframes blink { 0%, 52% { opacity: 1; } 53%, 100% { opacity: 0; } }

/* ---------- utilities --------------------------------------------------- */

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip {
  position: absolute;
  left: calc(var(--px) * 4); top: -5rem;
  z-index: 4;
  padding: calc(var(--px) * 2) calc(var(--px) * 4);
  background: var(--fg);
  color: #000;
  text-decoration: none;
  transition: top 140ms ease;
}
.skip:focus { top: calc(var(--px) * 4); }

/* ---------- boot sequence (enhancement only) ---------------------------- */

.js-boot .body > * {
  opacity: 0;
  animation: on 1ms steps(1, end) forwards;   /* snaps on, like a scanout */
}
.js-boot .body > *:nth-child(1) { animation-delay:  60ms; }
.js-boot .body > *:nth-child(2) { animation-delay: 150ms; }
.js-boot .body > *:nth-child(3) { animation-delay: 240ms; }
.js-boot .body > *:nth-child(4) { animation-delay: 320ms; }
.js-boot .body > *:nth-child(5) { animation-delay: 390ms; }
.js-boot .body > *:nth-child(6) { animation-delay: 460ms; }
.js-boot .body > *:nth-child(7) { animation-delay: 530ms; }
.js-boot .body > *:nth-child(8) { animation-delay: 600ms; }

@keyframes on { to { opacity: 1; } }

/* ---------- respect the user -------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
  .caret { opacity: 1; }
}

/* Scanlines and glow are atmosphere, not information, the first thing to go
   when someone has asked for maximum legibility. */
@media (prefers-contrast: more) {
  :root { --fg: #FFC44D; --dim: #E0A81A; --rule: #A87B10; }
  .scan { display: none; }
  .name { text-shadow: none; }
  .caret { box-shadow: none; }
}
