/* shaurya.fun · pixel theme. All art is original, drawn in scripts/sprites.py. */

/* Pixelify Sans (SIL Open Font License): a chunky pixel face, the bold
   instance only, used for every weight so it always looks the same. The line
   box is trimmed so capitals sit centred in buttons and tags. */
@font-face {
  font-family: "Pixelify Sans";
  src: url(/fonts/pixelify-sans-latin-700-normal.woff2) format("woff2");
  font-weight: 400 700;
  font-display: swap;
  ascent-override: 90%;
  descent-override: 22%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url(/fonts/ibm-plex-mono-latin-400-normal.woff2) format("woff2");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url(/fonts/ibm-plex-mono-latin-600-normal.woff2) format("woff2");
  font-weight: 600;
  font-display: swap;
}

/* Fallback fonts sized to match the real ones, so text does not jump or re-wrap
   when the web fonts finish loading on a slow connection. */
@font-face { font-family: "Pixel Fallback Mono"; src: local("Courier New Bold"), local("Courier New"), local("Liberation Mono"), local("DejaVu Sans Mono"), local("Menlo"), local("Consolas"), local("Roboto Mono"); font-weight: 400 700; size-adjust: 81.3%; ascent-override: 110.7%; descent-override: 27.1%; line-gap-override: 0%; }
@font-face { font-family: "Pixel Fallback Sans"; src: local("Arial Bold"), local("Arial"), local("Liberation Sans"), local("Helvetica Neue"), local("Helvetica"), local("Roboto"); font-weight: 400 700; size-adjust: 92%; ascent-override: 97.8%; descent-override: 23.9%; line-gap-override: 0%; }
@font-face { font-family: "Plex Fallback Mono"; src: local("Courier New"), local("Liberation Mono"), local("DejaVu Sans Mono"), local("Menlo"), local("Consolas"), local("Droid Sans Mono"), local("Roboto Mono"); font-weight: 400; size-adjust: 100%; ascent-override: 103%; descent-override: 28%; line-gap-override: 0%; }
@font-face { font-family: "Plex Fallback Mono"; src: local("Courier New"), local("Liberation Mono"), local("DejaVu Sans Mono"), local("Menlo"), local("Consolas"), local("Droid Sans Mono"), local("Roboto Mono"); font-weight: 600; size-adjust: 100%; ascent-override: 103%; descent-override: 28%; line-gap-override: 0%; }
@font-face { font-family: "Plex Fallback Sans"; src: local("Arial"), local("Liberation Sans"), local("Helvetica Neue"), local("Helvetica"), local("Roboto"); font-weight: 400; size-adjust: 109.8%; ascent-override: 94%; descent-override: 26%; line-gap-override: 0%; }
@font-face { font-family: "Plex Fallback Sans"; src: local("Arial"), local("Liberation Sans"), local("Helvetica Neue"), local("Helvetica"), local("Roboto"); font-weight: 600; size-adjust: 104.8%; ascent-override: 98%; descent-override: 27%; line-gap-override: 0%; }

:root {
  --sky: #9dd5f8;
  --sky-low: #cfe8fb;
  --ink: #173a8c;
  --dusk: #1a4aa8;
  --night: #0d2766;
  --deep: #0a1c4a;
  --text: #e6f2ff;
  --muted: #a3caf0;
  --pink: #8fd3ff;
  --pink-deep: #2f86e6;
  --mint: #5ef2d6;
  --yellow: #ffe066;
  --panel: #d2e8fb;
  --panel-ink: #11306f;
  --line: #5b9de6;
  --px: 3;
  /* One dither "dot" (about one sprite pixel). --dither paints 6 dot-rows of
     currentColor at 25%, 25%, 50%, 50%, 75%, 75% coverage: a pixel-art blend
     from transparent at the top to solid at the bottom. */
  --dot: 4px;
  --dither:
    linear-gradient(90deg, currentColor 0 25%, transparent 0) 0 0 / calc(4 * var(--dot)) var(--dot) repeat-x,
    linear-gradient(90deg, currentColor 0 25%, transparent 0) calc(2 * var(--dot)) var(--dot) / calc(4 * var(--dot)) var(--dot) repeat-x,
    linear-gradient(90deg, currentColor 0 50%, transparent 0) 0 calc(2 * var(--dot)) / calc(2 * var(--dot)) var(--dot) repeat-x,
    linear-gradient(90deg, currentColor 0 50%, transparent 0) var(--dot) calc(3 * var(--dot)) / calc(2 * var(--dot)) var(--dot) repeat-x,
    linear-gradient(90deg, currentColor 0 75%, transparent 0) 0 calc(4 * var(--dot)) / calc(4 * var(--dot)) var(--dot) repeat-x,
    linear-gradient(90deg, currentColor 0 75%, transparent 0) calc(2 * var(--dot)) calc(5 * var(--dot)) / calc(4 * var(--dot)) var(--dot) repeat-x;
  --pixel: "Pixelify Sans", "Pixel Fallback Sans", "Pixel Fallback Mono", sans-serif;
  --mono: "IBM Plex Mono", "Plex Fallback Mono", "Plex Fallback Sans", ui-monospace, monospace;
  --wrap: 1040px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);      /* entrances: fast start, soft landing */
  --ease-emph: cubic-bezier(0.2, 0, 0, 1);     /* things that open or swap */
  /* 2026 redesign tokens (see "Design system v3" at the end of this file) */
  --paper: #f5faff;
  --paper-2: #e4f1fd;
  --line-soft: #c8e0f5;
  --ink-soft: #2b4d98;
  --mint-soft: #c9f7ef;
  --shadow-1: 3px 3px 0 var(--ink);
  --shadow-2: 5px 5px 0 var(--ink);
  --page: 1200px;
  --gutter: clamp(16px, 4vw, 32px);
  --header-h: 64px;
  --section-y: clamp(56px, 8vw, 104px);
  color-scheme: dark;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--deep);
  color: var(--text);
  font-family: var(--mono);
  font-size: 16px;
  line-height: 1.6;
  -webkit-text-size-adjust: 100%;
}

a { color: var(--mint); text-underline-offset: 3px; }
a:hover { color: var(--yellow); }
:focus-visible { outline: 3px solid var(--yellow); outline-offset: 3px; }
/* the parts the browser draws carry the palette too */
::selection { color: var(--ink); background: var(--yellow); }
html { scrollbar-color: var(--dusk) var(--paper-2); }

.skip {
  position: absolute;
  left: 16px;
  top: -60px;
  z-index: 20;
  background: var(--yellow);
  color: var(--ink);
  padding: 8px 12px;
  font-family: var(--pixel); text-transform: uppercase;
}
.skip:focus { top: 12px; }

.sprite {
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  display: block;
  height: auto;
  pointer-events: none;
  user-select: none;
}

.wrap {
  position: relative;
  z-index: 2;
  max-width: var(--page);
  margin: 0 auto;
  padding-inline: var(--gutter);
}

/* ---------- Day scene ---------- */

.scene-day {
  position: relative;
  overflow: hidden;
  background: var(--sky);
  color: var(--ink);
  min-height: 600px;
  padding-top: 84px; /* room for the floating bar */
}

.topline {
  position: relative;
  z-index: 3;
  padding-inline: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font-family: var(--mono);
  font-weight: 600;
  font-size: 15px;
}

.hero {
  position: relative;
  z-index: 3;
  text-align: center;
  padding: 64px 16px 0;
}

.title {
  margin: 0;
  font-family: var(--pixel);
  font-weight: 700;
  font-size: clamp(44px, 9vw, 92px);
  line-height: 0.95;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink);
}

.pill {
  display: inline-block;
  margin: 22px 0 0;
  padding: 6px 18px;
  font-family: var(--pixel);
  font-size: 15px;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--panel);
  border: 3px solid var(--ink);
  box-shadow: 0 0 0 3px var(--pink) inset;
}

.cloud, .star { position: absolute; z-index: 1; }
.cloud { width: calc(20px * var(--px) * 1.6); }
img.cloud[src$="cloud-small.svg"] { width: calc(12px * var(--px) * 1.6); }
.c1 { left: 4%; top: 70px; }
.c2 { left: 28%; top: 24px; }
.c3 { right: 6%; top: 60px; }
.c4 { right: 30%; top: 150px; }
.star { width: calc(7px * var(--px) * 1.5); }
.s1 { left: 22%; top: 120px; }
.s2 { left: 31%; top: 90px; width: calc(7px * var(--px)); }

.street {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 40px;
  z-index: 2;
  height: 200px;
  max-width: 1200px;
  margin: 0 auto;
}
.street .sprite { position: absolute; bottom: 0; }
/* the street lamp: the pole is scenery; the top 20 of its 44 rows (arm and lantern) are a
   button, and the lantern swings from the hook */
.lamp-pole { left: 4%; width: calc(22px * var(--px) * 1.4); }
.lamp { position: absolute; left: 4%; bottom: calc(24px * var(--px) * 1.4); width: calc(22px * var(--px) * 1.4); aspect-ratio: 22 / 20; padding: 0; border: 0; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.lamp img { width: 100%; height: 100%; image-rendering: pixelated; }
.lamp-top { display: block; }
.lantern { position: absolute; left: 22.727%; top: 25%; width: 72.727%; height: 75%; transform-origin: 50% 0; }
.lantern > *, .lamp-on img { position: absolute; inset: 0; }
.bench { left: calc(4% + 80px); width: calc(34px * var(--px) * 1.4); }
.cat { left: calc(4% + 170px); bottom: calc(9px * var(--px) * 1.4) !important; width: calc(14px * var(--px) * 1.2); }
.b1 { left: 1%; width: calc(20px * var(--px) * 1.6); }
.b2 { right: calc(4% + 170px); width: calc(20px * var(--px) * 1.8); }
.shop { right: 4%; width: calc(52px * var(--px) * 1.15); }

.ground {
  height: 40px;
  background-color: #2f80e0;
  background-image: url(/img/bricks.png);
  background-size: 48px 24px;
  image-rendering: pixelated;
  border-top: 4px solid var(--ink);
  border-bottom: 4px solid var(--ink);
}
.scene-day .ground { position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; }

/* ---------- Bands ---------- */

.band { position: relative; overflow: hidden; padding: 72px 0; }
.band-dusk { background: var(--dusk); }
.band-night { background: var(--night); }
.band-city { background: var(--night); padding-bottom: 0; }
.band-deep { background: var(--deep); }

.pixel-h {
  margin: 0 0 20px;
  font-family: var(--pixel);
  font-weight: 700;
  font-size: clamp(24px, 3.6vw, 38px);
  line-height: 1.25;
  color: #d8f4ff;
  text-shadow: 3px 3px 0 var(--ink);
}

.body-text { max-width: 54ch; color: var(--text); margin: 0 0 12px; }

.monitor { width: calc(18px * var(--px) * 1.8); margin-top: 18px; }

.moon { position: absolute; right: 7%; top: 40px; width: calc(20px * var(--px) * 1.8); z-index: 1; }
.n1 { right: 3%; top: 120px; }
.n2 { left: 6%; top: 34px; }
.n3 { left: 52%; top: 40px; }

/* ---------- Retro window ---------- */

.window {
  position: relative;
  z-index: 2;
  max-width: 760px;
  background: var(--panel);
  color: var(--panel-ink);
  border: 3px solid var(--ink);
  box-shadow: 6px 6px 0 var(--ink);
}
.window-bar {
  display: flex;
  justify-content: space-between;
  padding: 4px 10px;
  font-family: var(--pixel);
  font-size: 13px;
  color: #fff;
  background: var(--dusk);
  border-bottom: 3px solid var(--ink);
}

.projects {
  list-style: none;
  counter-reset: proj;
  margin: 0;
  padding: 6px 18px 8px;
  max-height: 520px;
  overflow-y: auto;
  scrollbar-color: var(--line) var(--panel);
}
.projects li {
  counter-increment: proj;
  padding: 16px 0 14px 34px;
  border-bottom: 2px dashed var(--line);
  position: relative;
}
.projects li:last-child { border-bottom: 0; }
.projects li::before {
  content: counter(proj) ".";
  position: absolute;
  left: 0;
  top: 18px;
  font-family: var(--pixel); text-transform: uppercase;
  color: var(--dusk);
}

.year { margin-left: auto; font-size: 13px; color: #3561ae; }
.projects p { margin: 6px 0 0; font-size: 15px; max-width: 62ch; }

.projects .links { display: flex; gap: 16px; font-size: 14px; }
.projects a { color: var(--dusk); font-weight: 600; }
.projects a:hover { color: #1f63c9; }

.status {
  font-family: var(--pixel);
  font-size: 13px;
  padding: 1px 8px;
  border: 2px solid var(--ink);
  text-transform: uppercase;
}

/* ---------- Socials ---------- */

.social {
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  background: var(--panel);
  border: 3px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
}
.social img { width: 32px; }
/* Hover lifts only where there is a real mouse: on phones a tap would leave things stuck lifted. */
@media (hover: hover) { .social:hover { background: #fff6c2; transform: translate(-2px, -2px); box-shadow: 6px 6px 0 var(--ink); } }
.social:active { transform: translate(4px, 4px); box-shadow: 0 0 0 var(--ink); }

/* ---------- Projects (empty) ---------- */

/* ---------- Skills ---------- */

.inventory {
  list-style: none;
  margin: 0 0 72px;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  max-width: 720px;
}
.skill {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px 14px 14px;
  background: var(--panel);
  color: var(--ink);
  border: 3px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
}

.seg { width: 16px; height: 10px; background: #e9f4ff; border: 2px solid var(--ink); }
.seg.on { background: var(--mint); }
.skill:nth-child(3n/**/+2) .seg.on { background: var(--pink); }
.skill:nth-child(3n) .seg.on { background: var(--yellow); }

.city { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 24px; align-items: end; }

/* ---------- Contact ---------- */

.window-light { max-width: 820px; }
.contact {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px 20px;
  padding: 20px;
}
.field { display: flex; flex-direction: column; gap: 6px; }
.field-wide { grid-column: 1 / -1; }
.field label { font-family: var(--mono); font-size: 14px; font-weight: 600; color: var(--ink); }
.field input, .field textarea {
  font: inherit;
  font-size: 15px;
  color: var(--panel-ink);
  background: #eef6ff;
  border: 3px solid var(--ink);
  border-radius: 0;
  padding: 10px 12px;
  width: 100%;
  caret-color: var(--ink);
  color-scheme: light; /* the date icon was almost invisible on the pale field */
}
.field textarea { resize: vertical; min-height: 120px; }
.field input::placeholder, .field textarea::placeholder { color: #6f8cc2; }
.field input:focus-visible, .field textarea:focus-visible { outline-offset: 2px; }
/* Chrome focuses the parts inside a date box, so :focus-visible never matches the box */
.field input[type="date"]:focus { outline: 3px solid var(--dusk); outline-offset: 2px; }
.field input[type="date"]::-webkit-calendar-picker-indicator:focus-visible { outline: 3px solid var(--dusk); outline-offset: 2px; }
.field input[aria-invalid="true"], .field textarea[aria-invalid="true"] { border-color: #b3261e; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; }
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: var(--mono);
  font-weight: 600;
  font-size: 16px;
  line-height: 1.25;
  text-align: center;
  text-decoration: none;
  color: var(--ink);
  background: var(--yellow);
  border: 3px solid var(--ink);
  box-shadow: 4px 4px 0 var(--ink);
  padding: 10px 20px;
  cursor: pointer;
  min-height: 48px;
}
@media (hover: hover) { .btn:hover { background: #fff09a; } }
/* link-buttons keep their ink text on hover (the global link hover colour is for text links) */
a.btn:hover, a.btn:focus-visible, a.btn:active { color: var(--ink); }
.btn:active { transform: translate(4px, 4px); box-shadow: 0 0 0 var(--ink); }
.btn[disabled] { cursor: wait; opacity: 0.7; }
.form-status { margin: 0; font-size: 14px; color: var(--panel-ink); }
.form-status[data-kind="error"] { color: #b3261e; font-weight: 600; }
.form-status[data-kind="ok"] { color: #0e5e4f; font-weight: 600; }
.fine { margin: 0; font-size: 13px; color: #3561ae; }
.fine a, .window-light a { color: var(--dusk); font-weight: 600; }

/* ---------- Footer ---------- */

.footer { background: var(--deep); }
/* app pages: the other projects, one tap away */
.foot-more {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 22px 24px 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
}
.foot-more-label { font-family: var(--pixel); font-size: 13px; text-transform: uppercase; color: var(--muted); margin-right: 4px; }
.foot-more a {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 4px 10px;
  font-family: var(--pixel);
  font-size: 13px;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--text);
  border: 2px solid var(--line);
  box-shadow: 2px 2px 0 var(--ink);
}
@media (hover: hover) { .foot-more a:hover { color: var(--deep); background: var(--yellow); border-color: var(--ink); } }
.foot-row {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 18px 24px 28px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  font-size: 14px;
  color: var(--muted);
}

/* ---------- Motion ---------- */

@keyframes drift { from { transform: translateX(0); } to { transform: translateX(28px); } }
@keyframes twinkle { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }
.c1, .c3, .n1 { animation: drift 9s steps(7) infinite alternate; }
.c2, .c4, .n2, .n3 { animation: drift 12s steps(7) infinite alternate-reverse; }
.star { animation: twinkle 2.4s steps(3) infinite; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .social:hover { transform: none; }
  .cloud, .star { animation: none; }
}

/* ---------- Small screens ---------- */

@media (max-width: 760px) {
  :root { --px: 2; --dot: 3px; }
  .topline { flex-wrap: wrap; font-size: 13px; }
  .scene-day { min-height: 520px; }
  .hero { padding-top: 36px; }
  .street { height: 150px; }
  .bench, .cat, .b2, .c3, .c4, .s1 { display: none; }
  .c1 { top: 110px; }
  .c2 { top: 150px; left: auto; right: 6%; }
  .band { padding: 56px 0; }
  .wrap, .topline { padding-inline: 16px; }
  .city { grid-template-columns: 1fr; }
  .inventory { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: 16px; }
  .contact { grid-template-columns: 1fr; padding: 16px; }
  .projects li { padding-left: 28px; }
  .moon { top: 24px; }
}

/* ---------- Plain pages ---------- */

.page {
  max-width: 760px;
  margin: 0 auto;
  padding: 32px var(--gutter) 80px;
}
.page h1 { font-family: var(--pixel); font-weight: 400; font-size: clamp(28px, 4.6vw, 44px); line-height: 1.2; margin: 24px 0 10px; color: var(--ink); }
.page h2 { font-family: var(--mono); font-size: 20px; font-weight: 600; margin: 36px 0 8px; color: var(--ink); }
.page p, .page li { color: var(--ink-soft); max-width: 68ch; line-height: 1.7; }
.page .updated { color: var(--ink-soft); font-size: 14px; }
.page-top { font-family: var(--mono); font-weight: 600; font-size: 15px; }
.page-top a { display: inline-flex; align-items: center; min-height: 44px; }

/* ---------- Live sky (set by scene.js from the time in India) ---------- */

.scene-day { transition: color 0.6s; }
/* Sky bands: colours --c1..--c5 split at --t1..--t4 (4-band skies end at 100%). */
.scene-day[data-time] {
  --t4: 100%;
  --c5: transparent;
  background: linear-gradient(to bottom, var(--c1) 0 var(--t1), var(--c2) 0 var(--t2), var(--c3) 0 var(--t3), var(--c4) 0 var(--t4), var(--c5) 0);
}
.scene-day[data-time="dawn"] { --c1: #6fb0ec; --c2: #b4d9f6; --c3: #f1bfd9; --c4: #ffd9b8; --t1: 22%; --t2: 44%; --t3: 66%; }
.scene-day[data-time="day"] { --c1: #7cc4f4; --c2: #8fcdf6; --c3: #a3d6f7; --c4: #cfe8fb; --t1: 25%; --t2: 50%; --t3: 75%; }
.scene-day[data-time="sunset"] { --c1: #5b8cd0; --c2: #5aa6ea; --c3: #8fd3ff; --c4: #ffb3a1; --c5: #ffd29a; --t1: 20%; --t2: 40%; --t3: 60%; --t4: 80%; }
.scene-day[data-time="night"] {
  --c1: #061536; --c2: #0a1d48; --c3: #0f2a62; --c4: #153889; --t1: 25%; --t2: 50%; --t3: 75%;
  color: #eef6ff;
}
/* Pixel dither where one band meets the next: the lower colour creeps up in steps. */
.sky-steps { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.scene-day:not([data-time]) .sky-steps { display: none; }
.sky-steps i { position: absolute; left: 0; right: 0; height: calc(6 * var(--dot)); background: var(--dither); }
.sky-steps i:nth-child(1) { top: calc(var(--t1) - 6 * var(--dot)); color: var(--c2); }
.sky-steps i:nth-child(2) { top: calc(var(--t2) - 6 * var(--dot)); color: var(--c3); }
.sky-steps i:nth-child(3) { top: calc(var(--t3) - 6 * var(--dot)); color: var(--c4); }
.sky-steps i:nth-child(4) { top: calc(var(--t4) - 6 * var(--dot)); color: var(--c5); }
.scene-day[data-time="night"] .title { color: #eef6ff; }
.scene-day[data-time="night"] .tagline { color: #d9ecff; }
.scene-day[data-time="night"] .cloud { opacity: 0.3; }
.scene-day[data-time="sunset"] .cloud { filter: hue-rotate(-20deg) saturate(1.3); }

.sky-sun, .sky-moon { position: absolute; z-index: 1; right: 20%; top: 46px; display: none; }
.sky-sun { width: calc(24px * var(--px) * 1.4); }
.sky-moon { width: calc(20px * var(--px) * 1.5); }
.scene-day[data-time="day"] .sky-sun,
.scene-day[data-time="dawn"] .sky-sun { display: block; }
.scene-day[data-time="dawn"] .sky-sun,
.scene-day[data-time="sunset"] .sky-sun {
  /* low on the horizon, half behind the street */
  top: auto; right: auto; left: 50%; bottom: 18px;
  transform: translateX(-50%);
  width: calc(24px * var(--px) * 1.9);
}
.scene-day[data-time="sunset"] .sky-sun { display: block; filter: hue-rotate(-25deg) saturate(1.4); }
.scene-day[data-time="night"] .sky-moon { display: block; }

.night-star { display: none; }
.scene-day[data-time="night"] .night-star,
.scene-day[data-time="dawn"] .night-star { display: block; }
.scene-day[data-time="dawn"] .night-star { opacity: 0.5; }

/* ---------- Lamp, shop and neon sign ---------- */

.lamp-on { display: none; }
.scene-day[data-lamp="on"] .lamp-on { display: block; animation: lamp-hum 7s steps(1) infinite; }
.scene-day[data-lamp="on"] .lamp-off { display: none; }
@keyframes lamp-hum { 0%, 61%, 63%, 100% { opacity: 1; } 62% { opacity: 0.55; } }

.shop-night { display: none; }
.scene-day[data-time="night"] .shop-night,
.scene-day[data-time="sunset"] .shop-night { display: block; }
.scene-day[data-time="night"] .shop-day,
.scene-day[data-time="sunset"] .shop-day { display: none; }

.open-sign {
  --u: calc(var(--px) * 1.15 * 1px);
  right: calc(4% + 25.5 * var(--u));
  bottom: calc(24 * var(--u)) !important;
  width: calc(17 * var(--u));
  z-index: 3;
  animation: neon 6s steps(1) infinite;
}
.scene-day[data-time="night"] .open-sign,
.scene-day[data-time="sunset"] .open-sign { filter: drop-shadow(0 0 4px #8fd3ff) drop-shadow(0 0 10px #2f86e6); }
@keyframes neon {
  0%, 40%, 43%, 46%, 100% { opacity: 1; }
  41%, 44% { opacity: 0.25; }
}

/* ---------- Street cat ---------- */

.cat-lane {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 40px;
  z-index: 4;
  height: 0;
  max-width: 1200px;
  margin: 0 auto;
  pointer-events: none;
}
.cat-walker {
  --u: calc(var(--px) * 1.2 * 1px);
  position: absolute;
  left: 0;
  bottom: 0;
  display: block;
  pointer-events: auto;
  cursor: pointer;
  will-change: transform;
}
/* Five stacked frames; CSS shows one at a time (opacity only, so the GPU does it). */
.cat-frames { position: relative; display: block; width: calc(16 * var(--u)); height: calc(11 * var(--u)); }
.cat-img { position: absolute; left: 0; bottom: 0; width: calc(14 * var(--u)); opacity: 0; }
.cat-img.f-walk1, .cat-img.f-walk2 { width: calc(16 * var(--u)); }
.cat-img.f-sit { opacity: 1; }
.cat-walker.flip .cat-img { transform: scaleX(-1); }
@media (prefers-reduced-motion: no-preference) {
  /* sitting: one 3.4 s loop that blinks once and swishes the tail twice */
  .cat-walker:not(.walking) .f-sit { animation: cat-sit 3.4s steps(1, end) infinite; }
  .cat-walker:not(.walking) .f-tail { animation: cat-tail 3.4s steps(1, end) infinite; }
  .cat-walker:not(.walking) .f-blink { animation: cat-blink 3.4s steps(1, end) infinite; }
  /* walking: two frames alternate */
  .cat-walker.walking .f-sit { opacity: 0; }
  .cat-walker.walking .f-walk1 { animation: cat-step-a 0.34s steps(1, end) infinite; }
  .cat-walker.walking .f-walk2 { animation: cat-step-b 0.34s steps(1, end) infinite; }
}
@keyframes cat-blink { 0% { opacity: 1; } 11.76% { opacity: 0; } 100% { opacity: 0; } }
@keyframes cat-tail { 0% { opacity: 0; } 23.53% { opacity: 1; } 41.18% { opacity: 0; } 70.59% { opacity: 1; } 88.24% { opacity: 0; } 100% { opacity: 0; } }
@keyframes cat-sit { 0% { opacity: 0; } 11.76% { opacity: 1; } 23.53% { opacity: 0; } 41.18% { opacity: 1; } 70.59% { opacity: 0; } 88.24% { opacity: 1; } 100% { opacity: 1; } }
@keyframes cat-step-a { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 0; } }
@keyframes cat-step-b { 0% { opacity: 0; } 50% { opacity: 1; } 100% { opacity: 1; } }
.cat-walker:focus-visible { outline: 3px solid var(--yellow); outline-offset: 4px; }
/* invisible margin so the small cat is a 44px tap target */
.cat-walker::before { content: ""; position: absolute; inset: -8px; }
.cat-bubble {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  padding: 3px 8px;
  font-family: var(--pixel);
  font-size: 13px;
  color: var(--ink);
  background: #fff;
  border: 3px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s steps(2);
}
.cat-bubble::after {
  content: "";
  position: absolute;
  top: 100%;
  left: calc(50% - 4px);
  border: 4px solid transparent;
  border-top-color: var(--ink);
}
.cat-walker:hover .cat-bubble,
.cat-walker:focus-visible .cat-bubble,
.cat-walker.meow .cat-bubble { opacity: 1; }

/* ---------- Pixel intro ---------- */

.boot-screen { display: none; }
html.boot { overflow: hidden; }
html.boot .boot-screen {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 24px;
  background: var(--deep);
  color: var(--text);
  font-family: var(--pixel); text-transform: uppercase;
  text-align: center;
  background-image: repeating-linear-gradient(to bottom, rgba(255, 255, 255, 0.03) 0 2px, transparent 2px 4px);
}
html.boot-out .boot-screen { animation: boot-out 0.45s steps(6) forwards; }
@keyframes boot-out { to { transform: translateY(-100%); } }
.boot-title { margin: 0; font-size: clamp(34px, 8vw, 64px); font-weight: 700; color: #d8f4ff; text-shadow: 4px 4px 0 var(--dusk); }
.boot-line { margin: 0; font-size: 14px; color: var(--muted); letter-spacing: 0.08em; }
.boot-dots { animation: twinkle 0.9s steps(2) infinite; }
.boot-bar { display: flex; gap: 4px; padding: 4px; border: 3px solid var(--line); }
.boot-bar span { width: 18px; height: 16px; background: var(--deep); }
.boot-bar span.on { background: var(--mint); }
.boot-bar span.on:nth-child(3n/**/+2) { background: var(--pink); }
.boot-bar span.on:nth-child(3n) { background: var(--yellow); }
.boot-hint { margin: 6px 0 0; font-size: 13px; color: var(--muted); animation: twinkle 1.2s steps(2) infinite; }

/* hero drops in after the intro, and on every visit */
html.first .title, html.first .tagline { animation: rise-in 0.6s steps(6) both; }
.title { animation-delay: 0.08s; }
.tagline { animation-delay: 0.16s; }

html.boot .title, html.boot .tagline, html.boot .socials { animation-play-state: paused; }
@keyframes rise-in { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }

/* ---------- Hover effects ---------- */

.projects li { transition: transform 0.12s steps(2), background-color 0.12s steps(2), box-shadow 0.12s steps(2); }
.projects li:hover {
  background: #deebfc;
  transform: translate(-3px, -3px);
  box-shadow: 4px 4px 0 var(--ink);
  border-bottom-color: transparent;
}
.skill { transition: transform 0.12s steps(2), box-shadow 0.12s steps(2), background-color 0.12s steps(2); }
@media (hover: hover) { .skill:hover { transform: translate(-3px, -3px); box-shadow: 7px 7px 0 var(--ink); background: #e6f2ff; } }
.skill:hover .seg.on { animation: seg-flash 0.5s steps(2) 1; }
@keyframes seg-flash { 50% { background: #fff; } }
.btn { transition: transform 0.08s steps(1), box-shadow 0.08s steps(1); }
@media (hover: hover) { .btn:hover { transform: translate(-2px, -2px); box-shadow: 6px 6px 0 var(--ink); } }

/* pixel underline that grows in steps */
.proj-head h3 .proj-link, .projects .links a, .foot-row a {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 3px;
  transition: background-size 0.25s steps(5);
}
.proj-head h3 .proj-link:hover, .projects .links a:hover, .foot-row a:hover { background-size: 100% 3px; text-decoration: none; }
.foot-row a { text-decoration: underline; text-decoration-thickness: 1px; }
.foot-row a:hover { text-decoration: none; }

@media (prefers-reduced-motion: reduce) {
  .title, .tagline, .socials, .open-sign, .lamp-on, .boot-hint, .boot-dots { animation: none !important; }
  .projects li:hover, .skill:hover, .btn:hover { transform: none; }
}

@media (max-width: 760px) {
  .scene-day[data-time="day"] .sky-sun,
  .scene-day[data-time="night"] .sky-moon { display: none; }
  .cat-bubble { font-size: 13px; }
}
.cat-img { filter: drop-shadow(2px 0 0 var(--ink)) drop-shadow(-2px 0 0 var(--ink)) drop-shadow(0 2px 0 var(--ink)) drop-shadow(0 -2px 0 var(--ink)); }

/* ---------- Skills v2: icons, ranks, chunky bars, filters ---------- */

.inventory { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; max-width: 760px; }
.skill {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "icon text" "rank rank" "bar bar";
  align-items: center;
  column-gap: 12px;
  row-gap: 8px;
  padding: 12px 14px 14px;
}
.skill[hidden] { display: none; }

@keyframes icon-bob { to { transform: translateY(-3px); } }

.skill .seg {
  width: auto;
  height: 14px;
  border: 0;
  background: #254b80;
  box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.25);
}
.skill .seg.on {
  background: var(--mint);
  box-shadow: inset 0 3px 0 rgba(255, 255, 255, 0.55), inset 0 -3px 0 rgba(0, 0, 0, 0.2);
}
.skill:nth-child(3n/**/+2) .seg.on { background: var(--pink); }
.skill:nth-child(3n) .seg.on { background: var(--yellow); }

/* bars fill one segment at a time when they scroll into view (scene.js adds the classes) */

@keyframes seg-in { to { background: var(--seg-c, var(--mint)); box-shadow: inset 0 3px 0 rgba(255, 255, 255, 0.55), inset 0 -3px 0 rgba(0, 0, 0, 0.2); } }
.skill { --seg-c: var(--mint); }
.skill:nth-child(3n/**/+2) { --seg-c: var(--pink); }
.skill:nth-child(3n) { --seg-c: var(--yellow); }
.skill:hover .seg.on { animation: seg-flash 0.5s steps(2) 1; }

@media (max-width: 760px) {
  .inventory { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .skill { padding: 10px; column-gap: 8px; }
}
@media (max-width: 360px) {
  .inventory { grid-template-columns: 1fr; }
}

/* ---------- Header v2: top bar and clearer name ---------- */

.brand {
  font-size: 16px;
  font-weight: 700;
  color: var(--ink);
  text-decoration: none;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.brand:hover { color: var(--dusk); }
.clock {
  font-size: 13px;
  white-space: nowrap;
  color: var(--ink);
  padding: 4px 8px;
  background: #eef6ff;
  border: 2px solid var(--ink);
}

.hero { padding-top: 56px; }
.title {
  /* also capped by the screen height, so short screens still show the buttons */
  font-size: clamp(42px, min(8.4vw, 15vh), 96px);
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--ink);
  text-shadow: 3px 3px 0 var(--pink), 6px 6px 0 rgba(23, 58, 140, 0.25);
}
.title-line { display: block; }
.tagline {
  margin: 18px auto 0;
  max-width: 34ch;
  font-family: var(--mono);
  font-size: clamp(15px, 1.6vw, 18px);
  font-weight: 600;
  color: var(--ink);
}

.scene-day[data-time="night"] .title { text-shadow: 3px 3px 0 var(--pink-deep), 6px 6px 0 rgba(0, 0, 0, 0.35); }

@media (max-width: 760px) {
  .brand { font-size: 15px; }
  .clock { font-size: 13px; padding: 2px 6px; }
  .hero { padding-top: 34px; }
}
.title { letter-spacing: -0.05em; line-height: 1.15; }
/* phones held sideways: keep both title lines tight so the buttons stay on screen */
@media (max-height: 520px) { .title { line-height: 1.02; } }
.tagline { max-width: 44ch; text-wrap: balance; }

@media (max-width: 760px) {
  .scene-day { min-height: 600px; }
  .tagline { font-size: 14px; max-width: 30ch; }
}

/* ---------- Projects v2: cartridge cards ---------- */

.section-sub { margin: -6px 0 28px; max-width: 56ch; color: var(--muted); }
.proj-grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 22px;
}
.proj-card {
  --accent: var(--mint);
  display: flex;
  flex-direction: column;
  background: var(--panel);
  color: var(--panel-ink);
  border: 3px solid var(--ink);
  box-shadow: 6px 6px 0 var(--ink);
  transition: transform 0.12s steps(2), box-shadow 0.12s steps(2);
}
.accent-pink { --accent: var(--pink); }
.accent-yellow { --accent: var(--yellow); }
.proj-card:focus-within { transform: translate(-4px, -4px); box-shadow: 10px 10px 0 var(--ink); }
@media (hover: hover) { .proj-card:hover { transform: translate(-4px, -4px); box-shadow: 10px 10px 0 var(--ink); } }
.proj-cover {
  position: relative;
  display: block;
  overflow: hidden;
  border-bottom: 3px solid var(--ink);
  background: var(--accent);
  aspect-ratio: 48 / 28;
}
.proj-cover img { width: 100%; height: 100%; transition: transform 0.3s steps(3); }
@media (hover: hover) { .proj-card:hover .proj-cover img { transform: scale(1.06); } }
.proj-start {
  position: absolute;
  left: 50%;
  bottom: 12px;
  transform: translateX(-50%);
  padding: 4px 10px;
  font-family: var(--pixel); text-transform: uppercase;
  font-size: 13px;
  color: var(--ink);
  background: #fff;
  border: 3px solid var(--ink);
  box-shadow: 3px 3px 0 var(--ink);
  white-space: nowrap;
  opacity: 0;
}
.proj-card:hover .proj-start, .proj-card:focus-within .proj-start { opacity: 1; animation: blink 1s steps(2) infinite; }
@keyframes blink { 50% { opacity: 0.2; } }
.proj-body { display: flex; flex-direction: column; gap: 10px; padding: 16px 18px 18px; flex: 1; }
.proj-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.proj-top h3 { margin: 0; font-family: var(--pixel); text-transform: uppercase; font-size: 22px; line-height: 1.1; color: var(--ink); }
.proj-status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px;
  font-family: var(--pixel);
  font-size: 13px;
  text-transform: uppercase;
  color: var(--ink);
  background: #c9f7ef;
  border: 2px solid var(--ink);
  white-space: nowrap;
}

.proj-desc { margin: 0; font-size: 15px; line-height: 1.55; }

.btn-proj {
  margin-top: auto;
  align-self: flex-start;
  font-size: 13px;
  min-height: 42px;
  padding: 8px 16px;
  text-decoration: none;
  background: var(--accent);
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.btn-proj:hover { background: #fff; color: var(--ink); }

/* ---------- Skill city: one building per category ---------- */

.band-city { padding-bottom: 0; }

.band-city { overflow: hidden; }

@media (max-width: 900px) {
  .proj-grid { grid-template-columns: 1fr; }
}
/* an odd card left over at the end takes the whole row, cover beside the text */
@media (min-width: 901px) {
  .proj-card:last-child:nth-child(odd) { grid-column: 1 / -1; flex-direction: row; }
  .proj-card:last-child:nth-child(odd) .proj-cover { flex: 0 0 46%; aspect-ratio: auto; min-height: 220px; border-bottom: 0; border-right: 3px solid var(--ink); }
}

@media (prefers-reduced-motion: reduce) {
  .proj-card:hover, .bld:hover { transform: none; }
  .proj-start, .roof-antenna .bld-roof::after { animation: none !important; }
}

/* ---------- Contrast fixes ---------- */
.band-night .fine, .play-page .fine, .wx-page .fine { color: var(--muted); }
/* sign sits on the building front, so rooftop details never cover it */

.proj-cover img { object-fit: cover; }
@media (max-width: 760px) {
  .proj-cover { aspect-ratio: 48 / 22; }
  .proj-top h3 { font-size: 19px; }
  #projects .moon { width: calc(20px * var(--px) * 1.1); top: 16px; right: 4%; }
  .section-sub { padding-right: 56px; }
}

/* ---------- Skills v3: clean, no levels ---------- */
.inventory { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; max-width: 820px; margin-bottom: 40px; }
.skill {
  grid-template-columns: auto 1fr;
  grid-template-areas: "icon text";
  column-gap: 14px;
  padding: 12px 14px;
}

@media (max-width: 760px) {
  .inventory { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .skill { column-gap: 10px; padding: 10px; }
}

/* ---------- Skills: logo ticker (replaces the skill city) ---------- */
.band-city { padding-bottom: 64px; }
.ticker {
  position: relative;
  z-index: 2;
  margin-top: 8px;
  overflow: hidden;
  border-top: 3px solid var(--ink);
  border-bottom: 3px solid var(--ink);
  background: var(--dusk);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent);
}

@keyframes ticker { to { transform: translateX(calc(-50% - 7px)); } }

/* ---------- Real social logos ---------- */
.social img { width: 28px; height: 28px; image-rendering: auto; }
.social { background: #fff; }

/* ---------- Say hello v2 ---------- */

.mail-link { font-size: 17px; font-weight: 600; color: var(--ink); word-break: break-all; }
.btn-small { font-size: 14px; min-height: 44px; padding: 8px 14px; box-shadow: 3px 3px 0 var(--ink); }

.copy-buffer { position: fixed; left: -9999px; top: 0; opacity: 0; }
#contact .section-sub { color: var(--muted); }

@media (prefers-reduced-motion: reduce) {
  .ticker { -webkit-mask-image: none; mask-image: none; }
}

/* ---------- Footer v2 ---------- */

.mini-brand { display: inline-flex; align-items: center; gap: 8px; font-family: var(--pixel); text-transform: uppercase; color: var(--text); text-decoration: none; }
.mini-brand img { width: 28px; height: 28px; image-rendering: pixelated; }
.mini-brand:hover { color: var(--yellow); }
.mail-link:not([data-shown]) { font-family: var(--pixel); font-size: 14px; text-transform: uppercase; }

/* ---------- Contact v3: smooth, centred ---------- */

.contact-title {
  margin: 0;
  font-family: var(--pixel); text-transform: uppercase;
  font-size: clamp(30px, 5vw, 48px);
  line-height: 1.1;
  letter-spacing: -0.03em;
  color: #eef6ff;
}

/* ---------- Footer v3: one clean line ---------- */

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

/* ---------- Skills: the inventory itself is a React component styled with Tailwind (web/home/Skills.tsx) ---------- */
.band-city { padding-bottom: 72px; }

/* ---------- Say hello v4: back to the pixel style ---------- */
.sh-s1 { position: absolute; right: 12%; top: 60px; width: calc(7px * var(--px) * 1.4); }
.sh-s2 { position: absolute; left: 6%; top: 180px; width: calc(7px * var(--px)); }
.sh-c1 { right: 5%; top: 140px; }
.sh-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr);
  gap: 28px;
  align-items: start;
}
.sh-window { max-width: none; }
.sh-form { display: flex; flex-direction: column; gap: 16px; padding: 22px; }
.sh-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.sh-form .form-foot { display: flex; align-items: center; flex-wrap: wrap; gap: 14px; }
.sh-form .fine { color: #3561ae; }
.sh-links { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.sh-tile {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  min-height: 56px;
  padding: 8px 14px 8px 8px;
  font: inherit;
  text-align: left;
  color: var(--ink);
  text-decoration: none;
  background: transparent;
  border: 0;
  border-bottom: 2px solid var(--line-soft);
  cursor: pointer;
  transition: transform 0.12s steps(2), box-shadow 0.12s steps(2), background-color 0.12s steps(2);
}
@media (hover: hover) { .sh-tile:hover { transform: translate(-3px, -3px); box-shadow: var(--shadow-1); background: var(--paper-2); color: var(--ink); } }
.sh-tile:active { transform: none; box-shadow: none; background: var(--paper-2); }
.sh-logo { display: grid; place-items: center; width: 44px; height: 44px; background: var(--paper-2); border: 2px solid var(--ink); flex: none; }
.sh-logo img { width: 28px; height: 28px; }
.sh-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.sh-text b { font-family: var(--mono); font-size: 17px; font-weight: 600; }
.sh-text small { font-size: 13px; color: #2a519f; overflow-wrap: anywhere; }
.sh-tile.copied { background: #c9f7ef; }
.sh-tile.copied small { color: #0e5e4f; font-weight: 600; }
.copy-buffer { position: fixed; top: 0; left: -9999px; opacity: 0; }
@media (max-width: 900px) {
  .sh-grid { grid-template-columns: 1fr; }
  .sh-links { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
}
@media (max-width: 520px) {
  .sh-row { grid-template-columns: 1fr; }
  .sh-form { padding: 16px; }
  .sh-links { grid-template-columns: 1fr; }
  .sh-form .btn { width: 100%; }
}

/* ---------- Footer v4: pixel, tidy, aligned ---------- */
.px-foot { background: var(--deep); }
.pf-inner {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 22px 24px 28px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 16px;
}
.pf-brand { justify-self: start; display: inline-flex; align-items: center; gap: 12px; color: var(--text); text-decoration: none; font-family: var(--pixel); text-transform: uppercase; font-size: 16px; }
.pf-brand img { width: 36px; height: 36px; image-rendering: pixelated; }
.pf-brand:hover { color: var(--yellow); }
.pf-copy { margin: 0; text-align: center; font-size: 13px; color: var(--muted); }
.pf-copy a { color: var(--mint); }
.pf-top { justify-self: end; text-decoration: none; font-size: 13px; }
.brand { display: inline-flex; align-items: center; gap: 8px; }
.brand-logo { width: 26px; height: 26px; image-rendering: pixelated; }
@media (max-width: 760px) {
  .pf-inner { grid-template-columns: 1fr; justify-items: center; text-align: center; padding-inline: 16px; }
  .pf-brand, .pf-top { justify-self: center; }
}
@media (max-width: 760px) { .sh-s2 { display: none; } }

/* ---------- About v2: player card ---------- */
#about { padding: 88px 0 96px; }
.ab-s1 { position: absolute; right: 8%; top: 70px; width: calc(7px * var(--px) * 1.4); }
.ab-grid { display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr); gap: 44px; align-items: center; margin-top: 8px; }
.ab-card-body { padding: 22px 22px 24px; text-align: center; }
.ab-avatar {
  position: relative;
  width: 120px;
  margin: 4px auto 14px;
}
.ab-avatar img { width: 120px; height: 120px; image-rendering: pixelated; display: block; }
.ab-online {
  position: absolute;
  left: 50%;
  bottom: -12px;
  transform: translateX(-50%);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 8px;
  font-family: var(--pixel);
  font-size: 13px;
  text-transform: uppercase;
  color: var(--ink);
  background: #c9f7ef;
  border: 2px solid var(--ink);
  white-space: nowrap;
}
.ab-name { margin: 22px 0 2px; font-family: var(--pixel); text-transform: uppercase; font-size: 22px; color: var(--ink); }
.ab-class { margin: 0 0 16px; font-size: 14px; color: #2a519f; }
.ab-stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 0; }
.ab-stats div { padding: 8px 4px; background: #eef6ff; border: 2px solid var(--ink); }
.ab-stats dt { font-size: 13px; text-transform: uppercase; letter-spacing: 0.06em; color: #2a519f; }
.ab-stats dd { margin: 2px 0 0; font-family: var(--pixel); text-transform: uppercase; font-size: 16px; color: var(--ink); }
.ab-text { padding-top: 4px; }
.ab-lead { margin: 0 0 14px; font-size: clamp(19px, 2.2vw, 24px); line-height: 1.5; color: #eef6ff; font-weight: 600; }
.ab-lead mark { background: none; color: var(--yellow); }
.ab-text .body-text { max-width: 58ch; color: var(--text); margin-bottom: 22px; }

.btn-alt { background: var(--panel); }
@media (hover: hover) { .btn-alt:hover { background: #fff; } }
@media (max-width: 900px) {
  .ab-grid { grid-template-columns: 1fr; gap: 28px; }
  .ab-card { max-width: 420px; }
}

/* smoother hero and intro */
/* entrance only on the first visit (after the intro); returning visitors see it instantly */
html.first .title, html.first .tagline { animation: hero-in 0.6s var(--ease) both; }
html.first .title { animation-delay: 0.08s; }
html.first .tagline { animation-delay: 0.16s; }

@keyframes hero-in { from { opacity: 0; transform: translateY(22px) scale(0.98); } to { opacity: 1; transform: none; } }
html.first #fbar { animation: bar-in 0.6s var(--ease) both; }
@keyframes bar-in { from { opacity: 0; transform: translateY(-16px); } to { opacity: 1; transform: none; } }
html.boot #fbar { animation-play-state: paused; }
html.boot-out .boot-screen { animation: boot-fade 0.6s cubic-bezier(0.65, 0, 0.35, 1) forwards; }
@keyframes boot-fade { to { opacity: 0; transform: scale(1.04); visibility: hidden; } }

@media (prefers-reduced-motion: reduce) {
  #fbar, .title, .tagline, .socials { animation: none !important; }
}
.ab-stats dd { font-size: 13px; letter-spacing: -0.02em; }
.ab-stats dt { font-size: 13px; letter-spacing: 0.02em; white-space: nowrap; }

/* ---------- Projects shop: bigger, clickable, sign on the door ---------- */
.shop { width: calc(56px * var(--px) * 1.15); }
.open-sign {
  right: calc(4% + 8.5 * var(--u));
  bottom: calc(31 * var(--u)) !important;
  width: calc(11 * var(--u));
}
.shop-link {
  --u: calc(var(--px) * 1.15 * 1px);
  position: absolute;
  right: 4%;
  bottom: 0;
  width: calc(56 * var(--u));
  height: calc(64 * var(--u));
  pointer-events: auto;
  cursor: pointer;
}
.shop-link:focus-visible { outline: 3px solid var(--yellow); outline-offset: 4px; }
.shop-link .shop-bubble { bottom: calc(100% + 6px); }
.shop-link:hover .shop-bubble, .shop-link:focus-visible .shop-bubble { opacity: 1; }
@media (max-width: 760px) { .shop-bubble { font-size: 13px; } }

/* ---------- Now playing ---------- */
.np {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 16px;
  padding: 10px 12px;
  text-align: left;
  background: var(--ink);
  color: #eef6ff;
  border: 3px solid var(--ink);
  box-shadow: inset 0 0 0 2px #1a4aa8;
}
.np[hidden] { display: none; }
.np-art { width: 52px; height: 52px; flex: none; image-rendering: pixelated; border: 3px solid #eef6ff; background: #73aeea; }
.np-text { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.np-label { font-family: var(--pixel); font-size: 13px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--mint); }
.np-title { font-family: var(--pixel); text-transform: uppercase; font-size: 14px; color: #fff; text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.np-title:hover { color: var(--yellow); text-decoration: underline; }
.np-artist { font-size: 13px; color: #a3caf0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.np-eq { display: flex; align-items: flex-end; gap: 3px; height: 22px; flex: none; }
.np-eq i { width: 4px; height: 100%; background: var(--pink); transform-origin: bottom; animation: eq 0.9s steps(4) infinite alternate; }
.np-eq i:nth-child(1) { transform: scaleY(0.4); animation-delay: -0.2s; }
.np-eq i:nth-child(2) { transform: scaleY(0.9); animation-delay: -0.5s; background: var(--yellow); }
.np-eq i:nth-child(3) { transform: scaleY(0.6); animation-delay: -0.1s; background: var(--mint); }
.np-eq i:nth-child(4) { transform: scaleY(0.75); animation-delay: -0.7s; }
/* scaleY instead of height: runs on the graphics chip, no layout per frame */
@keyframes eq { 0% { transform: scaleY(0.2); } 100% { transform: scaleY(1); } }
@media (prefers-reduced-motion: reduce) { .np-eq i { animation: none; } }

/* ---------- Phone alignment fixes ---------- */
.ab-card, .ab-text, .np, .np-text { min-width: 0; }
.np-title, .np-artist { display: block; max-width: 100%; }
@media (max-width: 900px) {
  .ab-grid { grid-template-columns: minmax(0, 1fr); }
  .ab-card { width: 100%; }
}
/* speech bubbles: never stick out past the screen edge */
.shop-link .shop-bubble { left: auto; right: 0; transform: none; }
.shop-link .shop-bubble::after { left: auto; right: 24px; }
@media (max-width: 400px) {
  .ab-stats { gap: 6px; }
  .ab-stats dd { font-size: 13px; }

  .sh-tile { padding: 10px 12px 10px 10px; }
}
.btn-room { background: var(--mint); }
.btn-room:hover { background: #a8fbeb; }

/* =========================================================
   Clear affordances: one rule for the whole site.
   Clickable  = pixel shadow + arrow/↗ + lifts on hover + presses down on tap.
   Not clickable = flat (no lift, no arrow).
   ========================================================= */

/* hero: tell people where to start */
.btn-go { background: var(--yellow); }
.btn-go:hover { background: #fff1a6; }

/* press feedback for every clickable block (works on phones, no hover needed) */
.btn:active, .social:active, .ab-fact:active, .sh-tile:active, .proj-card:active, .rm-thing:active, .wx-result:active {
  transform: translate(3px, 3px) !important;
  box-shadow: 1px 1px 0 var(--ink) !important;
}
a:focus-visible, button:focus-visible, [role="button"]:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 3px solid var(--yellow);
  outline-offset: 3px;
}

/* the little action marker on the right of a clickable tile */
.go {
  margin-left: auto;
  flex: none;
  font-family: var(--pixel); text-transform: uppercase;
  font-size: 18px;
  line-height: 1;
  color: var(--ink);
  transition: transform 0.12s steps(2);
}
.go-tag { font-size: 13px; padding: 4px 6px; border: 2px solid var(--ink); background: var(--yellow); text-transform: uppercase; }
@media (hover: hover) { .ab-fact:hover .go, .sh-tile:hover .go:not(.go-tag) { transform: translateX(3px); } }
.sh-tile.copied .go-tag { background: var(--mint); }

/* about: fact tiles are real links now */

/* projects: the whole card opens the project, not just the button */
.proj-card { position: relative; cursor: pointer; }
.proj-card .btn-proj::after { content: ""; position: absolute; inset: 0; z-index: 1; }
.proj-card .btn-proj { position: static; }
.proj-card .proj-cover { position: relative; z-index: 0; }

/* skills: these are a display, not buttons, so they stay still */

/* hide hover-only hints on touch screens and keep tap targets big */
@media (hover: none) {
  .proj-card:hover { transform: none; box-shadow: 6px 6px 0 var(--ink); }
  .proj-card .proj-start { opacity: 1; animation: none; }
}
@media (max-width: 520px) {
}
/* the card lifts, so its button must not move (a moved button would shrink the clickable area) */
.proj-card .btn-proj:hover, .proj-card .btn-proj:active, .proj-card:hover .btn-proj { transform: none !important; }
@media (hover: hover) { .proj-card:hover .btn-proj { background: #fff; } }
.proj-card .btn-proj:active { box-shadow: 4px 4px 0 var(--ink) !important; }
/* hero: keep buttons and socials clear of the street */
.hero { padding-bottom: 130px; }
@media (max-width: 760px) {
  .hero { padding-bottom: 196px; }
}
@media (max-width: 360px) {
}
.brand-tld { color: #1f63c9; } /* pink with 4.8:1 contrast on the bar */
.brand .brand-tld { margin-left: -8px; }
@media (max-width: 380px) {
  .brand { font-size: 13px; gap: 6px; letter-spacing: 0; }
  .brand .brand-tld { margin-left: -6px; }
  .brand-logo { width: 22px; height: 22px; }
}

/* About facts are information, not buttons: flat, no lift, no press */

/* =========================================================
   Scene layout: the street is part of the page flow, under the hero.
   It is as tall as the tallest sprite (the shop), so nothing above it
   (top bar, buttons) can ever overlap the street.
   ========================================================= */
.scene-day { min-height: 0; padding-bottom: 40px; }
.scene-day > .hero { padding-bottom: 28px; }
.scene-day > .street {
  position: relative;
  bottom: auto;
  height: calc(64px * var(--px) * 1.15 + 34px); /* shop height + room for its bubble */
  margin: 0 auto;
}
/* the cat walks on the same line as the street */
.scene-day > .cat-lane { bottom: 40px; }

/* the walking cat gets its own compositor layer, so moving it never repaints the street */
.cat-walker { will-change: transform; }

/* Skills bar: on phones two copies of each row are enough for a seamless loop
   (the track still moves by exactly half its width), so the moving layer is half
   as big; and it stops moving while it is off screen. */

/* "← back" links: a finger-sized (44px) tap area without moving anything */
.back-link, .page-top a { display: inline-block; padding-block: 14px; margin-block: -14px; }

/* Skills: a Pause button for the moving rows (WCAG 2.2.2 Pause, Stop, Hide) */

 /* two bars */
 /* play */
/* very wide screens: keep the strip no wider than half a loop, so the loop never shows a gap */

/* Headings break into even lines; paragraphs avoid a single word on the last line. */
h1, h2, h3, .pixel-h { text-wrap: balance; }
p, li, dd { text-wrap: pretty; }

/* Contact form: the reason sits under the field it is about; a clear sent screen */
.field-err { margin: 0; font-size: 13px; font-weight: 600; color: #b3261e; }
.field-err[hidden] { display: none; }
.sent { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; padding: 32px 22px; text-align: center; color: var(--panel-ink); }
.sent[hidden] { display: none; }
.sent:focus { outline: none; }
.sent-badge { display: grid; place-items: center; width: 56px; height: 56px; color: var(--ink); background: var(--mint); border: 3px solid var(--ink); box-shadow: 4px 4px 0 var(--ink); }
.sent-title { margin: 6px 0 0; font-family: var(--pixel); font-size: 20px; color: var(--ink); }
.sent-text { margin: 0 0 8px; max-width: 34ch; }
@media (prefers-reduced-motion: no-preference) {
  .sent:not([hidden]) .sent-badge { animation: sent-pop 0.45s var(--ease-emph) both; }
}
@keyframes sent-pop { from { transform: scale(0.4); opacity: 0; } to { transform: none; opacity: 1; } }
.sh-form[hidden] { display: none; }

/* Phones held sideways and other very short screens: tighter hero so the buttons fit on screen */
@media (max-height: 500px) and (orientation: landscape) {
  .scene-day { padding-top: 72px; }
  .hero { padding-top: 14px; }
  .tagline { margin-top: 10px; }
}

/* Pixel hover (js/pixelfx.js): the canvas sits above the card colour and under its text */
.proj-card { --fx: var(--accent); isolation: isolate; }
.proj-card .px-fx { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }
.proj-card .proj-body { z-index: 1; } /* a flex item: stacks above the canvas without becoming a positioning box */


/* The street cat sleeps at night (eyes closed, still); scene.js keeps it from walking. */
.scene-day[data-time="night"] .cat-walker:not(.walking) .cat-img { animation: none; opacity: 0; }
.scene-day[data-time="night"] .cat-walker:not(.walking) .f-blink { opacity: 1; }

/* ==========================================================================
   Design system v3 (October 2026 redesign): a handcrafted pixel playground.
   Warm paper for reading, ink for text, and one job per accent colour:
     yellow   = the main action on a page (primary buttons)
     mint     = live, private or done (clock, "no uploads", success)
     light sky = highlight (marks, labels, the current link)
     sky blue = surfaces and secondary actions
   The pixel font is for short headlines and labels; everything people read
   for longer (paragraphs, forms, navigation, long titles) is IBM Plex Mono.
   Borders and shadows come in three steps, so not everything shouts:
     quiet  = 2px soft line, no shadow (containers)
     solid  = 3px ink line (interactive things, panels)
     raised = 3px ink line + hard shadow (the main action, the featured item)
   ========================================================================== */

/* ---------- Header (every page) ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  color: var(--ink);
  background: var(--paper);
  border-bottom: 3px solid var(--ink);
}
.site-bar {
  max-width: var(--page);
  height: var(--header-h);
  margin: 0 auto;
  padding-inline: var(--gutter);
  display: flex;
  align-items: center;
  gap: 12px;
}
.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  font-family: var(--pixel);
  font-size: 14px;
 
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.wordmark:hover { color: var(--ink); }
.wordmark img { width: 32px; height: 32px; image-rendering: pixelated; flex: none; }
.wordmark b { font-weight: inherit; color: var(--dusk); }
.site-nav { margin-left: auto; }
.site-nav ul { list-style: none; margin: 0; padding: 0; display: flex; gap: 2px; }
.site-nav a {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0 12px;
  font-family: var(--mono);
  font-weight: 600;
  font-size: 15px;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 3px solid transparent;
}
.site-nav a[aria-current] { border-bottom-color: var(--pink-deep); }
@media (hover: hover) { .site-nav a:hover { color: var(--ink); background: var(--paper-2); } }
.ist {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 2px 10px;
  font-family: var(--mono);
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--ink);
  background: var(--mint-soft);
  border: 2px solid var(--ink);
}
.menu-btn {
  display: none;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 14px;
  font-family: var(--mono);
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  background: var(--paper);
  border: 3px solid var(--ink);
  cursor: pointer;
}
@media (hover: hover) { .menu-btn:hover { background: var(--yellow); } }
.menu-btn:active { background: var(--yellow); }
a.menu-btn { text-decoration: none; }
a.menu-btn:hover { color: var(--ink); }
.burger { position: relative; display: block; width: 18px; height: 11px; }
.burger i { position: absolute; left: 0; width: 100%; height: 3px; background: currentColor; }
.burger i:first-child { top: 0; }
.burger i:last-child { bottom: 0; }
.burger.is-x i:first-child { top: 4px; transform: rotate(45deg); }
.burger.is-x i:last-child { bottom: 4px; transform: rotate(-45deg); }
@media (max-width: 899px) {
  /* phones and tablets: the name and Menu; the India clock moves to the hero and the menu */
  .site-nav { display: none; }
  .site-bar > .ist { display: none; }
  .menu-btn { display: inline-flex; margin-left: auto; }
}
@media (max-width: 420px) {
  .site-bar { gap: 8px; }
  .wordmark { font-size: 13px; gap: 8px; }
  .ist { padding: 2px 6px; font-size: 13px; }
  .menu-btn { padding: 0 10px; gap: 8px; }
}

/* jumping to a section lands below the sticky header */
#about, #projects, #skills, #contact, [id] { scroll-margin-top: calc(var(--header-h) + 16px); }

/* ---------- Menu (small screens) ---------- */
.menu {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  max-width: none;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  color: var(--ink);
  background: var(--paper);
  overflow: auto;
}
.menu[open] { display: flex; flex-direction: column; }
.menu::backdrop { background: rgba(10, 28, 74, 0.45); }
.menu > .site-bar { border-bottom: 3px solid var(--ink); flex: none; width: 100%; max-width: none; }
.menu-body { width: min(560px, 100%); margin: 0 auto; padding: 20px var(--gutter) 40px; }
.menu-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.menu-list a {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 56px;
  padding: 8px 14px;
  font-family: var(--mono);
  font-weight: 600;
  font-size: clamp(20px, 5.4vw, 26px);
  color: var(--ink);
  text-decoration: none;
  border: 3px solid transparent;
}
.menu-more a { min-height: 48px; font-size: 18px; }
.menu-num { flex: none; min-width: 2.4ch; font-size: 14px; color: var(--ink-soft); }
.menu-list a[aria-current="true"] { border-color: var(--ink); background: var(--paper-2); }
.menu-list a:focus-visible, .menu-list a:active { background: var(--yellow); border-color: var(--ink); box-shadow: var(--shadow-1); outline: none; }
@media (hover: hover) { .menu-list a:hover { background: var(--yellow); border-color: var(--ink); } }
.menu-label { margin: 24px 14px 6px; font-family: var(--pixel); font-size: 13px; color: var(--ink-soft); }
html.menu-open { overflow: hidden; }
html.menu-open body { padding-right: var(--sbw, 0px); }
@media (prefers-reduced-motion: no-preference) {
  .menu[open] { animation: menu-in 0.2s var(--ease) both; }
  .menu.closing { animation: menu-out 0.18s ease-in both; }
}
@keyframes menu-in { from { opacity: 0; transform: translateY(-12px); } to { opacity: 1; transform: none; } }
@keyframes menu-out { from { opacity: 1; } to { opacity: 0; transform: translateY(-8px); } }

/* ---------- Footer (every page) ---------- */
.site-footer { color: var(--text); background: var(--deep); }
.site-footer-inner {
  max-width: var(--page);
  margin: 0 auto;
  padding: 40px var(--gutter) 24px;
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr));
  gap: 32px;
}
.site-footer .wordmark { color: var(--text); }
.site-footer .wordmark b { color: var(--mint); }
.site-footer-about p { margin: 12px 0 0; max-width: 40ch; font-size: 14px; color: var(--muted); }
.site-footer h2 { margin: 6px 0 10px; font-family: var(--pixel); font-size: 13px; font-weight: 400; color: var(--muted); }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.site-footer nav a { display: inline-flex; align-items: center; min-height: 44px; font-size: 15px; color: var(--text); text-decoration: none; }
@media (hover: hover) { .site-footer nav a:hover { color: var(--yellow); text-decoration: underline; } }
.site-footer-row {
  max-width: var(--page);
  margin: 0 auto;
  padding: 16px var(--gutter) 28px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 20px;
  font-size: 14px;
  color: var(--muted);
  border-top: 2px solid #163b8f;
}
.site-footer-row a { display: inline-flex; align-items: center; min-height: 44px; color: var(--mint); }
@media (max-width: 720px) {
  .site-footer-inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .site-footer-about { grid-column: 1 / -1; }
}

/* ---------- Paper sections ---------- */
.paper { color: var(--ink); background: var(--paper); }
.paper-2 { color: var(--ink); background: var(--paper-2); }
.section { padding-block: var(--section-y); }
.page-wrap { max-width: var(--page); margin: 0 auto; padding-inline: var(--gutter); }
.eyebrow {
  display: inline-block;
  margin: 0 0 14px;
  padding: 4px 8px;
  font-family: var(--pixel);
  font-size: 13px;
  line-height: 1.4;
  color: var(--ink);
  background: var(--pink);
}
.h-display { margin: 0; font-family: var(--pixel); font-weight: 400; font-size: clamp(28px, 4.6vw, 52px); line-height: 1.2; }
.h-section { margin: 0; font-family: var(--pixel); font-weight: 400; font-size: clamp(22px, 3.2vw, 34px); line-height: 1.25; }
.lead { font-size: clamp(17px, 1.7vw, 20px); line-height: 1.6; }
.paper a:not(.btn):not(.card-link):not(.room-tile), .paper-2 a:not(.btn):not(.card-link) { color: var(--dusk); }
.paper a:not(.btn):not(.card-link):not(.room-tile):hover, .paper-2 a:not(.btn):not(.card-link):hover { color: var(--ink); }
/* headings focused after a jump: a quiet marker, not a control ring */
h2[tabindex="-1"]:focus { outline: none; box-shadow: inset 0 -4px 0 var(--pink); }
.paper :focus-visible, .paper-2 :focus-visible, .site-header :focus-visible, .menu :focus-visible, .ui-light :focus-visible { outline-color: var(--dusk); }
#game:focus-visible { outline-color: var(--ink); outline-offset: -6px; }
/* keyboard hints are noise on a device with no keyboard */
@media (hover: none) { .kbd-only { display: none; } }

/* ---------- Hero: introduction and street, one scene on one ground line ---------- */
.home-hero { color: var(--ink); background: var(--paper); }
.hero-stage { position: relative; overflow: hidden; }
.hero-copy { position: relative; z-index: 3; padding-top: clamp(28px, 6vw, 88px); padding-bottom: clamp(28px, 7vw, 112px); }
/* the text block spans the width; its empty part lets taps through to the street */
.hero-copy { pointer-events: none; }
.hero-copy > * { max-width: 30rem; pointer-events: auto; }
.hero-copy > .hero-title { max-width: 36rem; }
.hero-status { display: flex; align-items: center; gap: 8px; min-height: 22px; margin: 0 0 18px; font-size: 14px; font-weight: 600; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.hero-dot { width: 10px; height: 10px; flex: none; background: var(--mint); border: 2px solid var(--ink); }
.hero-hi { margin: 0 0 12px; font-family: var(--pixel); font-size: clamp(14px, 1.6vw, 18px); line-height: 1.5; color: var(--dusk); }
.hero-title { font-size: clamp(26px, 3vw, 40px); line-height: 1.25; text-wrap: balance; }
.hero-lead { margin: 18px 0 0; color: var(--ink-soft); }
.hero-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 28px; margin-top: 28px; }
.btn-raised { box-shadow: var(--shadow-2); }
.text-link { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; font-weight: 600; color: var(--dusk); text-decoration: underline; text-decoration-thickness: 2px; text-underline-offset: 5px; }
.text-link:hover { color: var(--ink); text-decoration-color: var(--pink-deep); }
/* the street: sky on the right, from the top of the hero down to the shared ground */
.hero-sky {
  --px: 2.2;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 30px;
  left: 50%;
  min-height: 0;
  padding: 0;
  z-index: 1;
}
.hero-sky .street { bottom: 0; height: 100%; max-width: none; }
.hero-sky .cat-lane { bottom: 0; max-width: none; }
.hero-ground { position: relative; z-index: 2; height: 30px; background-size: 32px 16px; border-bottom: 0; }
.hero-sky .c1 { left: 8%; top: 12%; } .hero-sky .c2 { left: 46%; top: 7%; } .hero-sky .c3 { right: 8%; top: 22%; }
.hero-sky .s1 { left: 28%; top: 26%; } .hero-sky .s2 { left: 62%; top: 15%; }
.hero-sky .sky-sun, .hero-sky .sky-moon { right: 16%; top: 10%; }
.hero-sky .lamp-pole, .hero-sky .lamp { left: 8%; }
.hero-sky .b1 { left: 2%; }
.hero-sky .bench { left: calc(8% + 70px); }
.hero-sky .b2 { right: calc(6% + 140px); }
.hero-sky .shop, .hero-sky .open-sign { right: 6%; }
.hero-sky .ns1 { left: 10%; top: 8%; } .hero-sky .ns2 { left: 30%; top: 32%; } .hero-sky .ns3 { left: 50%; top: 6%; }
.hero-sky .ns4 { left: 70%; top: 28%; } .hero-sky .ns5 { left: 88%; top: 40%; }
@media (max-width: 1100px) and (min-width: 900px) { .hero-sky { left: 54%; } .hero-sky .bench, .hero-sky .b2 { display: none; } }
/* phones and tablets: the introduction first, then a shallow street on the same ground */
@media (max-width: 899px) {
  .hero-copy > * { max-width: 36rem; }
  .hero-sky { --px: 1.6; position: relative; left: auto; bottom: auto; height: clamp(150px, 34vw, 230px); }
  .hero-sky .street, .hero-sky .cat-lane { bottom: 0; }
  .hero-sky .c3, .hero-sky .s2 { display: none; }
  .hero-sky .bench { left: calc(8% + 54px); }
}
@media (max-width: 520px) {
  .hero-sky { --px: 1.25; }
  .hero-sky .bench, .hero-sky .b2 { display: none; }
}
/* short screens: the introduction and its button fit before anything else */
@media (max-height: 560px) and (orientation: landscape) {
  .hero-copy { padding-top: 16px; padding-bottom: 20px; }
  .hero-status { margin-bottom: 10px; }
  .hero-hi { margin-bottom: 6px; }
  .hero-cta { margin-top: 16px; }
}
/* decorative motion pauses when the street is off screen or the tab is hidden */
.hero-sky.is-paused *, .hero-sky.is-paused { animation-play-state: paused !important; }

/* ---------- Diwali on the street (web/home/Diwali.tsx). Only transform and opacity move. ---------- */
.dw-sky, .dw-street { position: absolute; inset: 0; pointer-events: none; }
.dw-sky { z-index: 1; overflow: hidden; }
.dw-sky img, .dw-street img { display: block; height: auto; image-rendering: pixelated; }
.dw-shot { position: absolute; bottom: 0; animation-duration: 7s; }
.dw-s1 { left: 22%; top: 20%; } .dw-s2 { left: 62%; top: 11%; } .dw-s3 { left: 46%; top: 30%; } .dw-s4 { left: 86%; top: 34%; }
.dw-track { position: absolute; inset: 0 auto 0 0; width: 0; animation: dw-rise 7s steps(12, end) infinite; }
.dw-rocket { position: absolute; left: calc(-3.5px * var(--px)); bottom: calc(-18px * var(--px)); width: calc(7px * var(--px)); max-width: none; }
.dw-burst { position: absolute; left: 0; top: 0; width: calc(37px * var(--px) * 1.4); max-width: none; opacity: 0; transform: translate(-50%, -50%); }
.dw-f1 { animation: dw-frame-1 7s steps(1, end) infinite; }
.dw-f2 { animation: dw-frame-2 7s steps(1, end) infinite; }
.dw-f3 { animation: dw-frame-3 7s linear infinite; }
.dw-s2 *, .dw-s2 { animation-delay: 1.7s; } .dw-s3 * { animation-delay: 3.5s; } .dw-s4 * { animation-delay: 5.2s; }
@keyframes dw-rise { 0% { transform: translateY(0); opacity: 1; } 18% { transform: translateY(-100%); opacity: 1; } 18.1%, 100% { transform: translateY(-100%); opacity: 0; } }
@keyframes dw-frame-1 { 0%, 18% { opacity: 0; } 18.1%, 22% { opacity: 1; } 22.1%, 100% { opacity: 0; } }
@keyframes dw-frame-2 { 0%, 22% { opacity: 0; } 22.1%, 36% { opacity: 1; } 36.1%, 100% { opacity: 0; } }
@keyframes dw-frame-3 {
  0%, 36% { opacity: 0; transform: translate(-50%, -50%); }
  36.1% { opacity: 1; transform: translate(-50%, -50%); }
  50% { opacity: 0.5; transform: translate(-50%, -44%); }
  58%, 100% { opacity: 0; transform: translate(-50%, -40%); }
}
.dw-street { z-index: 1; }
.dw-lights { position: absolute; right: 6%; bottom: calc(54.6px * var(--px)); width: calc(56px * var(--px) * 1.15); }
.dw-lights img { width: 100%; }
.dw-bulbs { position: absolute; inset: 0; }
.dw-bulbs-a { animation: dw-twinkle 1.6s steps(1, end) infinite; }
.dw-bulbs-b { animation: dw-twinkle 1.6s steps(1, end) -0.8s infinite; }
@keyframes dw-twinkle { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0.25; } }
.dw-rangoli { position: absolute; left: 38%; bottom: 0; width: calc(31px * var(--px) * 1.4); max-width: none; }
.dw-diya { position: absolute; bottom: 0; width: calc(16px * var(--px)); }
.dw-bowl { width: 100%; position: relative; }
.dw-flame { width: 37.5%; margin: 0 auto calc(-1px * var(--px)); transform-origin: 50% 100%; animation: dw-flicker 0.9s steps(1, end) infinite; }
.dw-d2 .dw-flame { animation-delay: -0.3s; } .dw-d3 .dw-flame { animation-delay: -0.6s; } .dw-d4 .dw-flame { animation-delay: -0.15s; }
@keyframes dw-flicker { 0%, 40% { opacity: 1; transform: scaleY(1); } 41%, 70% { opacity: 0.8; transform: scaleY(0.85); } 71%, 100% { opacity: 1; transform: scaleX(0.9); } }
.dw-d1 { left: 24%; } .dw-d2 { left: 56%; } .dw-d3 { left: 64%; } .dw-d4 { right: 2%; }
.scene-day[data-time="night"] .dw-flame, .scene-day[data-time="night"] .dw-bulbs { filter: drop-shadow(0 0 3px #ffb347); }
@media (max-width: 899px) { .dw-s4, .dw-d3 { display: none; } .dw-s1 { top: 26%; } .dw-s2 { top: 22%; } .dw-s3 { top: 32%; } }
@media (max-width: 520px) { .dw-rangoli, .dw-d2 { display: none; } }
@media (prefers-reduced-motion: reduce) {
  .dw-sky .dw-track, .dw-sky .dw-f1, .dw-sky .dw-f3 { display: none; }
  .dw-f2 { animation: none; opacity: 1; }
  .dw-flame, .dw-bulbs-a, .dw-bulbs-b { animation: none; opacity: 1; }
}

/* ---------- Home: projects ---------- */
.section-tight { padding-block: clamp(40px, 6vw, 80px); }
.feature-card { position: relative; display: grid; color: var(--ink); background: #fff; border: 3px solid var(--ink); box-shadow: var(--shadow-2); }
@media (min-width: 860px) { .feature-card { grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr); } }
/* illustrative page thumbnails (not controls: no borders that look like buttons, no pointer) */
.pdf-page { position: relative; width: clamp(44px, 7vw, 76px); aspect-ratio: 3 / 4; background: #fff; border: 2px solid var(--ink); }
.pdf-page-lines { position: absolute; inset: 18% 16% auto; height: 34%; background: repeating-linear-gradient(var(--line-soft) 0 3px, transparent 3px 8px); }
.pdf-page-num { position: absolute; left: 50%; bottom: 8%; transform: translateX(-50%); font-family: var(--pixel); font-size: 10px; color: var(--ink-soft); }
.pdf-page.is-moving { transform: translateY(-16px) rotate(-6deg); background: var(--yellow); box-shadow: var(--shadow-1); }
.app-card {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 18px;
  padding: 16px;
  color: var(--ink);
  background: #fff;
  border: 2px solid var(--ink);
  box-shadow: none;
}
@media (hover: hover) { .app-card { transition: transform 0.12s steps(2), box-shadow 0.12s steps(2); } .app-card:hover { transform: translate(-2px, -2px); box-shadow: var(--shadow-1); } }
.app-card:focus-within { outline: 3px solid var(--dusk); outline-offset: 3px; }
.app-card .proj-body { padding: 4px 0; } /* the card already has its padding */
.app-visual { position: relative; z-index: 1; display: grid; place-items: center; width: clamp(96px, 14vw, 144px); aspect-ratio: 48 / 28; overflow: hidden; background: var(--accent); border: 2px solid var(--ink); }
.app-visual img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 420px) { .app-card { gap: 14px; padding: 12px; } .app-visual { width: 84px; } }
.room-tile {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: center;
  gap: 18px;
  padding: 16px 20px;
  color: var(--text);
  text-decoration: none;
  background: var(--night);
  border: 2px solid var(--ink);
}
.room-tile:hover { color: var(--yellow); }
.room-tile b { color: var(--yellow); }
.room-tile-art { display: flex; align-items: flex-end; gap: 8px; }
.room-tile-art img:first-child { width: 54px; } .room-tile-art img:last-child { width: 36px; }

/* ---------- Home: about facts (open list, no boxes) ---------- */
.about-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 24px; margin: 24px 0 0; max-width: 460px; }
.about-facts > div { display: flex; flex-direction: column; gap: 2px; padding: 10px 0; border-top: 2px solid var(--line-soft); }
.about-facts dt { font-size: 13px; color: var(--ink-soft); }
.about-facts dd { margin: 0; font-size: 17px; font-weight: 600; color: var(--ink); }

/* ---------- Pixel PDF: directory and tool pages ---------- */
.privacy-note { max-width: 62ch; font-size: 15px; color: var(--ink); }
.privacy-note summary { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; padding: 6px 12px; cursor: pointer; list-style: none; background: var(--mint-soft); border: 2px solid var(--ink); }
.privacy-note summary::-webkit-details-marker { display: none; }
.privacy-more { margin-left: 4px; font-weight: 600; color: var(--dusk); text-decoration: underline; text-underline-offset: 3px; }
.privacy-note[open] .privacy-more { text-decoration: none; }
.privacy-note p { margin: 8px 0 0; padding: 0 2px; line-height: 1.6; color: var(--ink-soft); }
.jump-link { display: inline-flex; align-items: center; min-height: 44px; padding: 0 14px; font-size: 14px; font-weight: 600; color: var(--ink); text-decoration: none; background: #fff; border: 2px solid var(--ink); }
.paper a.jump-link { color: var(--ink); }
.jump-link:hover { background: var(--yellow); }
.tool-tile { display: flex; align-items: center; gap: 14px; width: 100%; padding: 12px 14px; color: var(--ink); text-decoration: none; background: #fff; border: 2px solid var(--ink); }
.paper a.tool-tile { color: var(--ink); }
@media (hover: hover) { .tool-tile:hover { background: var(--paper-2); box-shadow: var(--shadow-1); transform: translate(-2px, -2px); } }
.tool-tile-icon { display: grid; place-items: center; width: 48px; height: 48px; flex: none; background: var(--paper-2); border: 2px solid var(--ink); }
.workspace { min-width: 0; padding: clamp(16px, 3vw, 28px); background: #fff; border: 3px solid var(--ink); }
.tool-help { font-size: 14px; color: var(--ink-soft); }
.tool-help ul { margin: 0; padding: 0; list-style: none; display: grid; gap: 10px; }
.tool-help li { position: relative; padding-left: 16px; line-height: 1.55; }
.tool-help li::before { content: ""; position: absolute; left: 0; top: 0.55em; width: 7px; height: 7px; background: var(--pink-deep); }
@media (min-width: 1200px) { .tool-help { padding-left: 20px; border-left: 2px solid var(--line-soft); } }
.more-help { margin-top: 48px; padding-top: 16px; border-top: 2px solid var(--line-soft); }
.more-help > summary { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; cursor: pointer; font-weight: 600; color: var(--dusk); }
.more-help > summary::-webkit-details-marker, .faq-q::-webkit-details-marker { display: none; }
/* a square-edged arrow, so it is clear the line opens */
.more-help > summary::before, .faq-q::before { content: ""; flex: none; width: 0; height: 0; border-left: 9px solid currentColor; border-top: 6px solid transparent; border-bottom: 6px solid transparent; }
.more-help[open] > summary::before, details[open] > .faq-q::before { transform: rotate(90deg); }
.more-help > section { margin-top: 8px; }

/* ---------- Countdown: small actions on each card ---------- */
.cd-action { display: inline-flex; align-items: center; min-height: 44px; padding: 0 12px; font: inherit; font-size: 14px; font-weight: 600; color: var(--ink); cursor: pointer; background: #fff; border: 2px solid var(--ink); }
.cd-action:hover { background: var(--yellow); }

/* ---------- Cards ---------- */
.card { position: relative; color: var(--ink); background: #fff; border: 3px solid var(--ink); }
.card-raised { box-shadow: var(--shadow-2); }
.card-link::after { content: ""; position: absolute; inset: 0; z-index: 2; }
.card-link { color: inherit; text-decoration: none; }
.card:focus-within { outline: 3px solid var(--dusk); outline-offset: 3px; }
/* keyboard focus: the whole card gets a ring and the title itself is marked */
.card-link:focus-visible { outline: none; background: var(--yellow); box-shadow: 0 0 0 3px var(--yellow); }
@media (hover: hover) {
  .card-hover { transition: transform 0.12s steps(2), box-shadow 0.12s steps(2); }
  .card-hover:hover { transform: translate(-3px, -3px); box-shadow: 8px 8px 0 var(--ink); }
}
.shot { display: block; width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; object-position: top; background: var(--paper-2); }
.chip {
  display: inline-flex;
  align-items: center;
  min-height: 26px;
  padding: 2px 8px;
  font-family: var(--mono);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  background: var(--paper-2);
  border: 2px solid var(--ink);
}
.chip-mint { background: var(--mint-soft); }
.chip-pink { background: var(--pink); }
.chip-yellow { background: var(--yellow); }

/* ==========================================================================
   Sky theme (24 Oct 2026): a bright pixel sky with fluffy clouds over the
   home page, and the introduction on a little CRT screen. Sky blues and
   white, with navy ink for text.
   ========================================================================== */

/* the sky fills the whole hero; the street on the right sees through to it */
.home-hero { background: #2b96e8; }
.home-hero[data-time] {
  --t4: 100%;
  --c5: transparent;
  background: linear-gradient(to bottom, var(--c1) 0 var(--t1), var(--c2) 0 var(--t2), var(--c3) 0 var(--t3), var(--c4) 0 var(--t4), var(--c5) 0);
}
.home-hero[data-time="day"] { --c1: #1784dd; --c2: #2b96e8; --c3: #48aaf0; --c4: #73c2f6; --t1: 22%; --t2: 44%; --t3: 68%; }
.home-hero[data-time="dawn"] { --c1: #3b86d8; --c2: #79b9ee; --c3: #f1bfd9; --c4: #ffd9b8; --t1: 24%; --t2: 48%; --t3: 72%; }
.home-hero[data-time="sunset"] { --c1: #2558b8; --c2: #4f86dc; --c3: #e9a3cf; --c4: #ffb3a1; --c5: #ffd29a; --t1: 20%; --t2: 40%; --t3: 60%; --t4: 80%; }
.home-hero[data-time="night"] { --c1: #061536; --c2: #0a1d48; --c3: #0f2a62; --c4: #153889; --t1: 25%; --t2: 50%; --t3: 75%; }
.home-hero:not([data-time]) .sky-steps { display: none; }
.home-hero .sky-steps { bottom: 30px; }
.hero-sky.scene-day, .hero-sky.scene-day[data-time] { background: none; }

/* clouds behind everything, and a bank of cloud tops along the horizon */
.hero-clouds { position: absolute; inset: 0 0 30px; z-index: 0; overflow: hidden; pointer-events: none; }
.hc { position: absolute; height: auto; image-rendering: pixelated; }
.hc1 { left: 2%; top: 7%; width: 176px; }
.hc2 { left: 36%; top: 5%; width: 80px; }
.hc3 { left: 24%; bottom: 30%; width: 224px; }
.hc4 { left: 6%; bottom: 22%; width: 96px; }
.hero-bank { position: absolute; left: 0; right: 0; bottom: 0; height: 48px; background: url(/img/cloud-bank.png) repeat-x left bottom / 256px 48px; image-rendering: pixelated; }
.home-hero[data-time="night"] .hc, .home-hero[data-time="night"] .hero-bank { opacity: 0.22; }
.home-hero[data-time="sunset"] .hc, .home-hero[data-time="sunset"] .hero-bank { opacity: 0.85; }

/* the CRT: a slate bezel around a pale screen with pixel-rounded corners */
.hero-copy { padding-top: clamp(24px, 4vw, 56px); padding-bottom: clamp(56px, 7vw, 96px); }
.hero-copy > .crt { max-width: 34rem; }
.crt {
  position: relative;
  padding: clamp(10px, 1.4vw, 16px);
  background: #2c3a5e;
  border: 3px solid var(--ink);
  box-shadow: var(--shadow-2), inset 0 0 0 3px #4b5d8c;
}
.crt-screen {
  --n: 4px; /* one step of the screen's rounded corner */
  position: relative;
  overflow: hidden;
  padding: clamp(20px, 3vw, 32px) clamp(18px, 3vw, 32px) clamp(52px, 6vw, 64px);
  background: linear-gradient(to bottom, #f3f9ff 0 30%, #e6f3fe 0 62%, #d3eafc 0);
  clip-path: polygon(0 calc(3 * var(--n)), var(--n) calc(3 * var(--n)), var(--n) calc(2 * var(--n)), calc(2 * var(--n)) calc(2 * var(--n)), calc(2 * var(--n)) var(--n), calc(3 * var(--n)) var(--n), calc(3 * var(--n)) 0,
    calc(100% - 3 * var(--n)) 0, calc(100% - 3 * var(--n)) var(--n), calc(100% - 2 * var(--n)) var(--n), calc(100% - 2 * var(--n)) calc(2 * var(--n)), calc(100% - var(--n)) calc(2 * var(--n)), calc(100% - var(--n)) calc(3 * var(--n)), 100% calc(3 * var(--n)),
    100% calc(100% - 3 * var(--n)), calc(100% - var(--n)) calc(100% - 3 * var(--n)), calc(100% - var(--n)) calc(100% - 2 * var(--n)), calc(100% - 2 * var(--n)) calc(100% - 2 * var(--n)), calc(100% - 2 * var(--n)) calc(100% - var(--n)), calc(100% - 3 * var(--n)) calc(100% - var(--n)), calc(100% - 3 * var(--n)) 100%,
    calc(3 * var(--n)) 100%, calc(3 * var(--n)) calc(100% - var(--n)), calc(2 * var(--n)) calc(100% - var(--n)), calc(2 * var(--n)) calc(100% - 2 * var(--n)), var(--n) calc(100% - 2 * var(--n)), var(--n) calc(100% - 3 * var(--n)), 0 calc(100% - 3 * var(--n)));
}
/* faint scanlines (still, no flicker) and cloud tops along the bottom of the screen */
.crt-screen::before { content: ""; position: absolute; inset: 0; z-index: 0; pointer-events: none; background: repeating-linear-gradient(to bottom, rgba(23, 58, 140, 0.045) 0 2px, transparent 2px 4px); }
.crt-screen::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; z-index: 0; height: 36px; pointer-events: none; background: url(/img/cloud-bank.png) repeat-x left bottom / 192px 36px; image-rendering: pixelated; }
.crt-screen > * { position: relative; z-index: 1; }
.crt .hero-status { margin-bottom: 14px; }
.crt .hero-title {
  font-size: clamp(32px, 4vw, 50px);
  line-height: 1.08;
  color: var(--ink);
  /* a white pixel outline around the letters, like a game title screen */
  text-shadow: 3px 0 #fff, -3px 0 #fff, 0 3px #fff, 0 -3px #fff, 3px 3px #fff, -3px -3px #fff, 3px -3px #fff, -3px 3px #fff, 5px 6px 0 rgba(23, 58, 140, 0.22);
}
.crt .hero-hi { font-size: clamp(16px, 1.8vw, 20px); color: var(--dusk); }
.crt .hero-lead { color: var(--ink-soft); }
.crt .btn { background: #fff; }
@media (hover: hover) { .crt .btn:hover { background: #e3f1fd; } }
@media (max-width: 899px) {
  .hero-copy > .crt { max-width: none; }
  .hero-copy { padding-bottom: 20px; }
  .hc3, .hc4 { display: none; }
}
/* the sparkles belong to the night and dawn skies, not to a bright blue day */
.home-hero[data-time="day"] .star:not(.night-star), .home-hero[data-time="sunset"] .star:not(.night-star) { display: none; }
/* phones held sideways: a compact screen, so the buttons stay on the first screen */
@media (max-height: 560px) and (orientation: landscape) {
  .hero-copy { padding-top: 10px; padding-bottom: 16px; }
  .crt { padding: 6px; }
  .crt-screen { padding: 12px 16px 14px; }
  .crt-screen::after, .crt .hero-status, .crt .hero-lead { display: none; }
  .crt .hero-hi { font-size: 15px; margin-bottom: 4px; }
  .crt .hero-title { font-size: 26px; }
  .crt .hero-cta { margin-top: 12px; }
}

/* ---------- Home motion (web/home/pageEffects.ts, web/lib/tier.ts) ----------
   Scroll effects use the browser's own scroll timeline: no script runs on
   scroll or while idle, and browsers without it simply show the still page.
   Everything here only moves transform/opacity, stops for reduced motion,
   and is switched off on slow devices (<html data-tier="low">). */

/* the sun (or moon) has a ring of pixel text around it: two halves of one
   tilted ring, the back half behind the sun and the front half in front */
.sky-orbit { position: absolute; right: 16%; top: 10%; width: calc(24px * var(--px) * 1.4); aspect-ratio: 1; pointer-events: none; display: none; }
.hero-sky[data-time] .sky-orbit { display: block; }
.orbit-half { position: absolute; left: 50%; top: 50%; width: 230%; aspect-ratio: 1; transform: translate(-50%, -50%) scaleY(0.42); }
.orbit-back { z-index: 0; clip-path: inset(0 0 50% 0); opacity: 0.6; }
.orbit-front { z-index: 2; clip-path: inset(50% 0 0 0); }
.orbit-ring { display: block; width: 100%; height: 100%; overflow: visible; }
.orbit-text { font-family: var(--pixel); font-size: 11px; letter-spacing: 0.5px; fill: #fff; stroke: var(--ink); stroke-width: 2.4px; stroke-linejoin: miter; paint-order: stroke; }
@media (prefers-reduced-motion: no-preference) {
  .orbit-ring { animation: orbit-spin 48s linear infinite; }
}
@keyframes orbit-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@media (max-width: 760px) { .hero-sky[data-time] .sky-orbit { display: none; } }

/* section headings rise in line by line, in six hard pixel steps */
.h-section .hw { display: inline-block; overflow: clip; vertical-align: bottom; padding-bottom: 0.14em; margin-bottom: -0.14em; }
.h-section .hw > span { display: inline-block; transition: transform 0.5s steps(6, end); }
.h-section.hr-wait .hw > span { transform: translateY(160%); }

/* where one section meets the next, the lower colour creeps up in dither steps */
#about, #contact { position: relative; }
#about::before, #contact::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: calc(-6 * var(--dot));
  height: calc(6 * var(--dot));
  background: var(--dither);
  pointer-events: none;
}
#about::before { color: var(--paper-2); }
#contact::before { color: var(--paper); }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    /* scrolling down dives into the CRT: it zooms toward you in pixel steps
       and blinks out, and the street behind it steps closer */
    .home-hero { view-timeline: --hero block; }
    .hero-copy > .crt { transform-origin: 50% 55%; animation: crt-dive steps(8, end) both; animation-timeline: --hero; animation-range: exit 0% exit 85%; }
    .hero-sky { transform-origin: 50% 100%; animation: street-near steps(6, end) both; animation-timeline: --hero; animation-range: exit 0% exit 85%; }
    #about::before, #contact::before { animation: dither-rise steps(3, end) both; animation-timeline: view(); animation-range: entry 0% cover 30%; }
  }
}
@keyframes crt-dive { 0% { transform: none; opacity: 1; } 25% { opacity: 1; } 70% { opacity: 0; } 100% { transform: scale(1.8); opacity: 0; } }
@keyframes street-near { from { transform: none; } to { transform: scale(1.12); } }
@keyframes dither-rise { from { transform: translateY(100%); } to { transform: none; } }

/* slow devices: the sky holds still and the scroll effects stay off */
:root[data-tier="low"] .hero-sky .cloud,
:root[data-tier="low"] .hero-sky .star,
:root[data-tier="low"] .orbit-ring,
:root[data-tier="low"] .hero-copy > .crt,
:root[data-tier="low"] .hero-sky,
:root[data-tier="low"] #about::before,
:root[data-tier="low"] #contact::before { animation: none; }
