/* =============================================================
   ★ MY WEBSITE ★  styles.css
   Plain CSS. Edit, save, refresh. No build step.

   The values you will most likely want to change are all in the
   first blocks below:
     1. ANIMATION SPEEDS
     2. SIZES
     3. PASTEL THEME COLORS, RED THEME COLORS, MATRIX THEME COLORS

   Extra matrix-only styling (code rain, glow, terminal title) lives
   in its own MATRIX THEME section near the bottom.
   ============================================================= */


/* =========================
   ANIMATION SPEEDS
   (bigger number = slower)
   ========================= */
:root {
  --hero-spin-speed: 9s;        /* one slow idle coin-spin of the hero image     */
  --hero-burst-duration: 1.8s;  /* the fast coin-spin when the theme changes     */
  --rainbow-speed: 5s;          /* how fast the rainbow slides through the title */
  --letter-wave-speed: 1.8s;    /* one bounce of each title letter               */
  --marquee-speed: 18s;         /* time for ONE copy of the edge text to scroll  */
  --background-speed: 30s;      /* the slow color wash behind everything         */
  --matrix-rain-speed: 60ms;    /* pause between steps of the falling code rain  */
}


/* =========================
   SIZES
   ========================= */
:root {
  --column-width: 580px;                           /* max width of the center column */
  --edge-size: 22px;                               /* thickness of the scrolling edges */
  --edge-font-size: 0.75rem;
  --gutter: clamp(8px, 2.6vw, 22px);               /* space between edges and content */
  --stack-gap: clamp(8px, 1.6vh, 20px);            /* space between the big pieces */
  --title-size: clamp(1.9rem, 8.4vw, 3rem);
  --hero-size: clamp(120px, 33vw, 210px);
  --coin-tilt: 9deg;                               /* lean of the spinning coin towards you */
  --coin-thickness: calc(var(--hero-size) * 0.06);
  --coin-perspective: 700px;                       /* smaller = more dramatic 3D */
  --heading-size: clamp(0.95rem, 0.9rem + 0.4vw, 1.15rem);
  --body-size: clamp(0.94rem, 0.88rem + 0.3vw, 1.05rem);

  /* iPhone notch / home-bar safe areas (0 on everything else) */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
}


/* =========================
   PASTEL THEME COLORS
   (the default theme)
   ========================= */
:root,
html[data-theme="pastel"] {
  /* the six candy colors */
  --pink: #ffc7dc;
  --peach: #ffd1ae;
  --yellow: #fff0ae;
  --mint: #bff1d5;
  --blue: #bcdcff;
  --lavender: #d9c5ff;

  /* page */
  --bg: #fff8f2;
  --text: #2a2233;
  --link: #0000ee;
  --link-visited: #551a8b;
  --focus: #e0007a;
  --selection: #ffc7dc;
  --selection-text: #2a2233;
  --wash: linear-gradient(120deg, var(--pink), var(--peach), var(--yellow), var(--mint), var(--blue), var(--lavender), var(--pink));
  --pattern: radial-gradient(circle, rgba(255, 255, 255, 0.85) 2px, transparent 2.6px);
  --pattern-size: 22px 22px;

  /* title */
  --title-font: "Arial Black", "Arial Bold", Gadget, Impact, sans-serif;
  --title-gradient: linear-gradient(90deg, var(--pink), var(--peach), var(--yellow), var(--mint), var(--blue), var(--lavender), var(--pink));
  --title-gradient-size: 8em;   /* width of one full rainbow */
  --title-stroke: #4b2a63;
  --title-stroke-width: 1.5px;
  --title-shadow: #4b2a63;
  --title-filter: drop-shadow(3px 3px 0 #4b2a63);

  /* hero coin */
  --coin-rim: #434343;
  --coin-shadow: rgba(75, 42, 99, 0.35);

  /* content boxes */
  --font-body: Georgia, "Times New Roman", Times, serif;
  --font-heading: Verdana, Geneva, Tahoma, sans-serif;
  --font-mono: "Courier New", Courier, monospace;
  --panel: rgba(255, 255, 255, 0.88);
  --box-border-style: dashed;
  --box-shadow: rgba(75, 42, 99, 0.25);
  --heading-bg: transparent;
  --deco: "★";          /* before each section heading */
  --deco-after: "★";    /* after each section heading */

  /* theme button */
  --switch-bg: linear-gradient(#fff, #f1e8ff);
  --switch-text: #2a2233;
  --switch-bevel: #d9c5ff;
  --switch-shadow: #4b2a63;
  --switch-dot: #ff8fbf;

  /* footer bits */
  --stripe-a: var(--pink);
  --stripe-b: var(--mint);
  --counter-bg: #2a2233;
  --counter-text: #7dffb0;
  --status-bg: #ece4f7;
  --status-line: #b7a6cf;

  /* scrolling edges */
  --edge-text: #3b2350;
  --edge-line: #4b2a63;
  --corner-bg: #fff0ae;
  --corner-text: #4b2a63;
}


/* =========================
   RED THEME COLORS
   (turned on by the switch: <html data-theme="red">)
   ========================= */
html[data-theme="red"] {
  --bg: #000;
  --text: #fff;
  --red: #ff1a1a;
  --link: #ff6b6b;
  --link-visited: #ff9d9d;
  --focus: #fff;
  --selection: #ff1a1a;
  --selection-text: #fff;
  --wash: radial-gradient(ellipse at center, #3d0000 0%, #120000 45%, #000 75%);
  --pattern: conic-gradient(rgba(255, 0, 0, 0.13) 25%, transparent 0 50%, rgba(255, 0, 0, 0.13) 0 75%, transparent 0);
  --pattern-size: 28px 28px;

  --title-font: "Times New Roman", Times, Georgia, serif;
  --title-gradient: linear-gradient(90deg, #ff1a1a 0%, #fff 18%, #ff1a1a 34%, #000 50%, #ff1a1a 66%, #fff 82%, #ff1a1a 100%);
  --title-stroke: #fff;
  --title-stroke-width: 1.5px;
  --title-shadow: #ff0000;
  --title-filter: drop-shadow(3px 3px 0 #ff0000);

  --coin-rim: #8a0000;
  --coin-shadow: rgba(255, 0, 0, 0.45);

  --font-body: "Courier New", Courier, monospace;
  --font-heading: Impact, "Arial Black", "Arial Bold", sans-serif;
  --panel: rgba(0, 0, 0, 0.88);
  --box-border-style: solid;
  --box-shadow: #ff0000;
  --heading-bg: #c00000;
  --deco: "✖";
  --deco-after: "✖";

  --switch-bg: linear-gradient(#222, #000);
  --switch-text: #fff;
  --switch-bevel: #ff1a1a;
  --switch-shadow: #ff0000;
  --switch-dot: #ff1a1a;

  --stripe-a: #ff1a1a;
  --stripe-b: #000;
  --counter-bg: #000;
  --counter-text: #ff3333;
  --status-bg: #111;
  --status-line: #ff1a1a;

  --edge-text: #000;
  --edge-line: #fff;
  --corner-bg: #fff;
  --corner-text: #c00000;
}


/* =========================
   MATRIX THEME COLORS
   (black + terminal green: <html data-theme="matrix">)
   ========================= */
html[data-theme="matrix"] {
  /* the greens */
  --bright: #39ff14;    /* headings, highlights */
  --border: #1ca63a;    /* box borders, lines   */
  --dim: #0d5f21;       /* shadows, stripes     */

  --bg: #000;
  --text: #8cff8c;
  --link: #39ff14;
  --link-visited: #b5ffb0;
  --focus: #b5ffb0;
  --selection: #39ff14;
  --selection-text: #000;
  --wash: radial-gradient(ellipse at center, #001f08 0%, #000 70%);
  --pattern: none;
  --pattern-size: auto;

  --title-font: "Courier New", Courier, "Lucida Console", monospace;
  --title-gradient: linear-gradient(90deg, #063d12, #39ff14, #b5ffb0, #39ff14, #063d12);
  --title-stroke: #39ff14;
  --title-stroke-width: 0.6px;
  --title-shadow: #0d5f21;
  --title-filter: drop-shadow(0 0 3px rgba(57, 255, 20, 0.55));

  --coin-rim: #0d5f21;
  --coin-shadow: rgba(57, 255, 20, 0.35);

  --font-body: "Courier New", Courier, "Lucida Console", monospace;
  --font-heading: "Courier New", Courier, "Lucida Console", monospace;
  --panel: rgba(0, 0, 0, 0.72);
  --box-border-style: solid;
  --box-shadow: #0d5f21;
  --heading-bg: transparent;
  --deco: ">";
  --deco-after: "_";

  --switch-bg: #000;
  --switch-text: #39ff14;
  --switch-bevel: #1ca63a;
  --switch-shadow: #0d5f21;
  --switch-dot: #39ff14;

  --stripe-a: #0d5f21;
  --stripe-b: #000;
  --counter-bg: #000;
  --counter-text: #39ff14;
  --status-bg: rgba(0, 0, 0, 0.8);
  --status-line: #1ca63a;

  --edge-text: #39ff14;
  --edge-line: #1ca63a;
  --corner-bg: #000;
  --corner-text: #39ff14;

  /* code rain colors (read by script.js) */
  --rain-color: #22c94a;
  --rain-head-color: #d4ffd0;
}


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

html {
  background: var(--bg);
  color: var(--text);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  /* keep content clear of the scrolling edges and the iPhone notch */
  padding:
    calc(var(--safe-top) + var(--edge-size) + var(--gutter))
    calc(var(--safe-right) + var(--edge-size) + var(--gutter))
    calc(var(--safe-bottom) + var(--edge-size) + var(--gutter))
    calc(var(--safe-left) + var(--edge-size) + var(--gutter));
  font-family: var(--font-body);
  font-size: var(--body-size);
  line-height: 1.4;
  transition: color 0.4s ease;
}

/* the polka-dot / checkerboard tiles + slow color wash behind everything */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  background-image: var(--pattern), var(--wash);
  background-size: var(--pattern-size), 400% 400%;
  animation: wash-drift var(--background-speed) ease-in-out infinite alternate;
  opacity: 0.75;
}

::selection {
  background: var(--selection);
  color: var(--selection-text);
}

a {
  color: var(--link);
}

a:visited {
  color: var(--link-visited);
}

:focus-visible {
  outline: 3px dashed var(--focus);
  outline-offset: 4px;
}

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


/* =============================================================
   LAYOUT  (one narrow centered column)
   ============================================================= */
.page {
  position: relative;
  width: min(100%, var(--column-width));
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--stack-gap);
  text-align: center;
}

.masthead {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--stack-gap);
  width: 100%;
}


/* =============================================================
   ANIMATED RAINBOW TITLE
   script.js wraps every letter in <span class="letter">.
   Without JavaScript the plain title below still shows.
   ============================================================= */
.rainbow-title {
  margin: 0;
  font-family: var(--title-font);
  font-size: var(--title-size);
  font-weight: 900;
  line-height: 1.1;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  /* no-JavaScript fallback look */
  color: var(--title-stroke);
  text-shadow: 3px 3px 0 var(--title-shadow);
}

.title-letters {
  display: block;
  padding: 0.12em 0 0.06em;
  filter: var(--title-filter);
}

.title-word {
  display: inline-block;
  white-space: nowrap;
}

.letter {
  display: inline-block;
  padding: 0 0.015em;
  color: transparent;
  text-shadow: none;
  /* the rainbow: one wide gradient, each letter shows a different slice of it */
  background-image: var(--title-gradient);
  background-size: var(--title-gradient-size) 100%;
  background-repeat: repeat-x;
  background-position: calc(var(--i) * -0.7em) 0;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-stroke: var(--title-stroke-width) var(--title-stroke);
  animation:
    letter-wave var(--letter-wave-speed) ease-in-out infinite,
    rainbow-slide var(--rainbow-speed) linear infinite;
  /* each letter starts a little later than the one before = a wave */
  animation-delay: calc((var(--i) * 0.06 - 50) * var(--letter-wave-speed)), 0s;
}

@keyframes letter-wave {
  0%, 100% { transform: translateY(0) rotate(0deg) scale(1); }
  25%      { transform: translateY(-0.16em) rotate(-6deg) scale(1.08); }
  50%      { transform: translateY(0) rotate(0deg) scale(1); }
  75%      { transform: translateY(0.05em) rotate(5deg) scale(0.96); }
}

@keyframes rainbow-slide {
  from { background-position: calc(var(--i) * -0.7em) 0; }
  to   { background-position: calc(var(--i) * -0.7em + var(--title-gradient-size)) 0; }
}


/* =============================================================
   SPINNING HERO COIN
   The picture spins like a coin standing on a table.
     .hero        = sets up the 3D view + the shadow on the "table"
     .hero-tilt   = leans the coin slightly towards you
     .hero-spin   = the slow forever spin (CSS, below)
     .hero-burst  = the fast spin on theme change (script.js)
   script.js also adds a back face and a thin rim so the coin has
   some thickness. The pictures swap while the coin is edge-on.
   ============================================================= */
.hero {
  position: relative;
  width: var(--hero-size);
  height: var(--hero-size);
  flex: none;
  perspective: var(--coin-perspective);
}

/* soft shadow on the tabletop */
.hero::after {
  content: "";
  position: absolute;
  left: 12%;
  right: 12%;
  bottom: -9%;
  height: 12%;
  z-index: -1;
  background: radial-gradient(closest-side, var(--coin-shadow), transparent);
  pointer-events: none;
}

.hero-tilt,
.hero-spin,
.hero-burst {
  position: relative;
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
}

.hero-tilt {
  transform: rotateX(var(--coin-tilt));
}

.hero-spin {
  animation: coin-spin var(--hero-spin-speed) linear infinite;
}

.hero-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
}

/* front and back faces (added by script.js) sit on either side of the rim */
.hero-img-front,
.hero-img-back {
  -webkit-backface-visibility: hidden;
  backface-visibility: hidden;
}

.hero-img-front { transform: translateZ(calc(var(--coin-thickness) / 2)); }
.hero-img-back  { transform: rotateY(180deg) translateZ(calc(var(--coin-thickness) / 2)); }

/* show the picture that belongs to the current theme */
html[data-theme="pastel"] .hero-img[data-theme-image="pastel"],
html[data-theme="red"] .hero-img[data-theme-image="red"],
html[data-theme="matrix"] .hero-img[data-theme-image="matrix"] {
  opacity: 1;
}

/* the coin's edge: a stack of thin discs between the two faces */
.coin-rim {
  position: absolute;
  inset: 1%;
  background: var(--coin-rim);
  transform: translateZ(calc((var(--k) - 0.5) * (var(--coin-thickness) - 1px)));
  /* change color halfway through the burst, while the coin is edge-on */
  transition: background-color 0.05s linear calc(var(--hero-burst-duration) * 0.5);
}

@keyframes coin-spin {
  from { transform: rotateY(0deg); }
  to   { transform: rotateY(360deg); }
}

/* =========================
   HERO HEART MASK
   Cuts every picture face and every rim disc into the same heart,
   so the coin is a heart-shaped token from every angle, edge-on too.
   To reshape it, edit the path (drawn in a 100 x 100 box).
   The mask goes on the faces, not on .hero-tilt/-spin/-burst:
   a mask on those would flatten the 3D and break the spin.
   ========================= */
.hero {
  --heart-mask: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><path d='M50 94 C50 94 4 64 4 33 C4 17 16 6 30 6 C39 6 46 11 50 19 C54 11 61 6 70 6 C84 6 96 17 96 33 C96 64 50 94 50 94 Z'/></svg>");
}

.hero-img,
.coin-rim {
  -webkit-mask: var(--heart-mask) center / 100% 100% no-repeat;
  mask: var(--heart-mask) center / 100% 100% no-repeat;
}

/* fill the whole heart, even behind pictures with see-through corners;
   like the rim, it changes color while the coin is edge-on */
.hero-img {
  background: var(--coin-rim);
  transition: background-color 0.05s linear calc(var(--hero-burst-duration) * 0.5);
}


/* =============================================================
   THEME BUTTON  (a tiny beveled button: MODE: PASTEL ▪▫▫)
   Each press moves to the next theme.
   ============================================================= */
.theme-switch {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.45em;
  min-height: 26px;
  padding: 3px 8px;
  font: bold 11px/1 var(--font-mono);
  letter-spacing: 0.08em;
  color: var(--switch-text);
  background: var(--switch-bg);
  border: 2px outset var(--switch-bevel);
  border-radius: 0;
  box-shadow: 2px 2px 0 var(--switch-shadow);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* invisible padding so the small button is still easy to tap (about 44px tall) */
.theme-switch::before {
  content: "";
  position: absolute;
  inset: -11px -10px;
}

.theme-switch:active {
  border-style: inset;
  transform: translate(1px, 1px);
  box-shadow: 1px 1px 0 var(--switch-shadow);
}

/* the button only works with JavaScript, so hide it without */
html:not(.js) .theme-switch {
  display: none;
}

.switch-label {
  opacity: 0.8;
}

.switch-name {
  min-width: 7ch;     /* stops the button changing width between themes */
  text-align: left;
}

/* one little square per theme; the current one is filled in */
.switch-dots {
  display: inline-flex;
  gap: 2px;
}

.switch-dots i {
  width: 6px;
  height: 6px;
  border: 1px solid currentColor;
}

.switch-dots i.is-on {
  background: var(--switch-dot);
  border-color: var(--switch-dot);
}


/* =============================================================
   THE FOUR CONTENT BOXES
   ============================================================= */
.sections {
  display: grid;
  gap: var(--stack-gap);
  width: 100%;
}

.box {
  --box-border: #ff8fbf;
  --heading: #c2185b;
  padding: clamp(7px, 1.2vh, 14px) clamp(10px, 3vw, 18px);
  background: var(--panel);
  border: 3px var(--box-border-style) var(--box-border);
  box-shadow: 4px 4px 0 var(--box-shadow);
  transition: background-color 0.4s ease, border-color 0.4s ease;
}

/* each pastel box gets its own rainbow color */
.box:nth-child(2) { --box-border: #ffab6e; --heading: #a14300; }
.box:nth-child(3) { --box-border: #5fd39a; --heading: #047857; }
.box:nth-child(4) { --box-border: #8fb8ff; --heading: #1d4ed8; }

html[data-theme="red"] .box {
  --box-border: var(--red);
  --heading: #fff;
}

.box h2 {
  display: inline-block;
  margin: 0 0 0.2em;
  padding: 0.05em 0.4em;
  font-family: var(--font-heading);
  font-size: var(--heading-size);
  font-weight: bold;
  line-height: 1.2;
  letter-spacing: 0.06em;
  color: var(--heading);
  background: var(--heading-bg);
}

html[data-theme="red"] .box h2 {
  font-weight: normal;   /* Impact is already bold */
  letter-spacing: 0.1em;
}

/* "\00a0" is a non-breaking space, so a star never ends up alone on a line */
.box h2::before { content: var(--deco) "\00a0"; }
.box h2::after  { content: "\00a0" var(--deco-after); }

.box p {
  margin: 0;
}


/* =============================================================
   FOOTER BITS
   ============================================================= */
.footer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 100%;
  font-size: 0.875rem;
}

.footer p {
  margin: 0;
}

.construction {
  width: 100%;
  padding: 4px;
  background: repeating-linear-gradient(45deg, var(--stripe-a) 0 10px, var(--stripe-b) 10px 20px);
  background-size: 28.28px 28.28px;   /* one tile = two stripes, so it repeats seamlessly */
  animation: stripes-slide 4s linear infinite;
}

.construction span {
  display: inline-block;
  padding: 2px 8px;
  font: bold 0.8rem/1.3 var(--font-mono);
  letter-spacing: 0.05em;
  background: var(--panel);
}

.counter {
  font-family: var(--font-mono);
}

.counter-digits {
  display: inline-flex;
  gap: 2px;
  vertical-align: middle;
}

.counter-digits span {
  min-width: 1.15em;
  padding: 1px 2px;
  font: bold 1rem/1.2 var(--font-mono);
  color: var(--counter-text);
  background: var(--counter-bg);
  border: 2px inset var(--status-line);
}

.footer-links {
  font-family: var(--font-heading);
  font-weight: bold;
}

.footer-links a {
  display: inline-block;
  padding: 6px 4px;   /* bigger tap target */
}

.ascii {
  display: inline-block;
  margin: 0;
  font: 0.85rem/1.15 var(--font-mono);
  text-align: left;
}

.status-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 3px;
  width: 100%;
  padding: 3px;
  font: 0.75rem/1.3 var(--font-mono);
  background: var(--status-bg);
  border: 2px outset var(--status-line);
}

.status-bar span {
  padding: 1px 6px;
  border: 1px inset var(--status-line);
}

@keyframes stripes-slide {
  to { background-position: -28.28px 0; }
}


/* =============================================================
   SCROLLING EDGES
   Top and bottom are normal horizontal strips. The left and right
   strips are the same thing turned on their side with a transform,
   so all four share one marquee animation.
   ============================================================= */
.edge {
  position: fixed;
  z-index: 20;
  height: var(--edge-size);
  display: flex;
  align-items: center;
  overflow: hidden;
  pointer-events: none;
  font: bold var(--edge-font-size)/1 var(--font-mono);
  letter-spacing: 0.08em;
  white-space: nowrap;
  color: var(--edge-text);
  background: var(--edge-bg);
  border-bottom: 2px dotted var(--edge-line);   /* the side facing the content */
}

.edge-top {
  --edge-bg: var(--pink);
  top: var(--safe-top);
  left: calc(var(--safe-left) + var(--edge-size));
  right: calc(var(--safe-right) + var(--edge-size));
}

.edge-bottom {
  --edge-bg: var(--blue);
  bottom: var(--safe-bottom);
  left: calc(var(--safe-left) + var(--edge-size));
  right: calc(var(--safe-right) + var(--edge-size));
  border-bottom: 0;
  border-top: 2px dotted var(--edge-line);
}

.edge-left,
.edge-right {
  top: calc(var(--safe-top) + var(--edge-size));
  /* the strip's length = screen height minus the top and bottom strips */
  width: calc(100vh - var(--safe-top) - var(--safe-bottom) - 2 * var(--edge-size));
  width: calc(100dvh - var(--safe-top) - var(--safe-bottom) - 2 * var(--edge-size));
}

.edge-left {
  --edge-bg: var(--lavender);
  left: var(--safe-left);
  transform-origin: top left;
  transform: rotate(-90deg) translateX(-100%);   /* reads bottom to top */
}

.edge-right {
  --edge-bg: var(--mint);
  right: var(--safe-right);
  transform-origin: top right;
  transform: rotate(90deg) translateX(100%);     /* reads top to bottom */
}

html[data-theme="red"] .edge-top,
html[data-theme="red"] .edge-bottom {
  --edge-bg: var(--red);
}

html[data-theme="red"] .edge-left,
html[data-theme="red"] .edge-right {
  --edge-bg: #000;
  --edge-text: var(--red);
}

.edge-corner {
  position: fixed;
  z-index: 21;
  width: var(--edge-size);
  height: var(--edge-size);
  display: grid;
  place-items: center;
  pointer-events: none;
  font-size: 0.8rem;
  line-height: 1;
  color: var(--corner-text);
  background: var(--corner-bg);
  border: 2px dotted var(--edge-line);
}

.corner-tl { top: var(--safe-top); left: var(--safe-left); }
.corner-tr { top: var(--safe-top); right: var(--safe-right); }
.corner-br { bottom: var(--safe-bottom); right: var(--safe-right); }
.corner-bl { bottom: var(--safe-bottom); left: var(--safe-left); }

/* script.js fills each track with two identical halves, then slides
   the whole track left by exactly one half, forever = no visible jump */
.marquee-track {
  display: flex;
  flex: none;
  width: max-content;
  padding-left: 0.5em;
}

.marquee-track.is-ready {
  padding-left: 0;
  /* --reps is set by script.js: more copies = longer trip, same speed */
  animation: marquee-scroll calc(var(--marquee-speed) * var(--reps, 1)) linear infinite;
}

.edge-bottom .marquee-track {
  animation-direction: reverse;
}

.marquee-phrase {
  padding-right: 1.5em;
}

@keyframes marquee-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@keyframes wash-drift {
  from { background-position: 0 0, 0% 50%; }
  to   { background-position: 0 0, 100% 50%; }
}


/* =============================================================
   MATRIX THEME
   Everything that only happens in <html data-theme="matrix">.
   (Its colors are up top in MATRIX THEME COLORS.)
   ============================================================= */

/* the falling code canvas, behind everything, never clickable */
.code-rain {
  display: none;
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: #000;
  opacity: 0.6;
}

html[data-theme="matrix"] .code-rain {
  display: block;
}

/* faint CRT scanlines over the rain */
html[data-theme="matrix"] body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: repeating-linear-gradient(0deg, rgba(0, 0, 0, 0.35) 0 1px, transparent 1px 3px);
}

html[data-theme="matrix"] body::before {
  opacity: 1;
}

/* calmer letter wave + a blinking cursor after the title */
html[data-theme="matrix"] .letter {
  animation-name: letter-wave-terminal, rainbow-slide;
}

html[data-theme="matrix"] .title-letters::after {
  content: "_";
  color: var(--bright);
  animation: cursor-blink 1.1s steps(1) infinite;
}

@keyframes letter-wave-terminal {
  0%, 100% { transform: translateY(0); }
  25%      { transform: translateY(-0.06em) scale(1.03); }
  75%      { transform: translateY(0.02em); }
}

@keyframes cursor-blink {
  50% { opacity: 0; }
}

html[data-theme="matrix"] .box {
  --box-border: var(--border);
  --heading: var(--bright);
  border-width: 2px;
}

html[data-theme="matrix"] .box h2 {
  text-shadow: 0 0 4px rgba(57, 255, 20, 0.5);
}

html[data-theme="matrix"] .edge {
  --edge-bg: rgba(0, 12, 3, 0.92);
  text-shadow: 0 0 3px rgba(57, 255, 20, 0.6);
}

html[data-theme="matrix"] .edge-left,
html[data-theme="matrix"] .edge-right {
  --edge-bg: rgba(0, 0, 0, 0.92);
  --edge-text: var(--text);
}

html[data-theme="matrix"] .theme-switch {
  border-style: solid;
}


/* =============================================================
   BIGGER SCREENS  (same layout, just a little roomier)
   ============================================================= */
@media (min-width: 700px) {
  :root {
    --edge-size: 26px;
    --edge-font-size: 0.85rem;
    --hero-size: clamp(150px, 20vh, 220px);
  }

  .theme-switch {
    font-size: 12px;
  }
}

/* short screens (landscape phones): shrink the picture, not the text */
@media (max-height: 560px) {
  :root {
    --hero-size: clamp(90px, 24vh, 130px);
  }
}


/* =============================================================
   REDUCED MOTION
   If the visitor's device asks for less motion, everything holds
   still. The theme switch still works, with a gentle crossfade.
   ============================================================= */
@media (prefers-reduced-motion: reduce) {
  body::before,
  .hero-spin,
  .letter,
  html[data-theme="matrix"] .letter,
  html[data-theme="matrix"] .title-letters::after,
  .marquee-track.is-ready,
  .construction {
    animation: none;
  }

  /* no coin spin: the pictures simply crossfade */
  .hero-img {
    transition: opacity 0.4s ease, background-color 0.4s ease;
  }

  .coin-rim {
    transition: none;
  }
}
