/* ═══════════════════════════════════════════════════════════════════
   GaY sCaN 2000 — the geocities build.

   Maximalist on purpose: tiled starfield, WordArt bevels, outset
   borders, marquees, blink, a visitor counter, Comic Sans. The joke is
   that a page this deranged is still the one telling you the truth.

   Rule followed throughout: it should look like 1999 by *committing*,
   not by being sloppy. Alignment, rhythm and tap targets are all still
   deliberate underneath the chrome.
   ═══════════════════════════════════════════════════════════════════ */

:root {
  --void:   #1B0033;
  --void-2: #33006B;
  --lime:   #33FF66;
  --magenta:#FF33CC;
  --cyan:   #33FFFF;
  --yellow: #FFFF33;
  --hot:    #FF0066;

  --face:   #C0C0C0;   /* the one true Windows grey */
  --hi:     #FFFFFF;
  --lo:     #808080;
  --dk:     #404040;

  --comic: 'Comic Sans MS', 'Chalkboard SE', 'Comic Neue', 'Marker Felt', cursive;
  --impact: 'Anton', Impact, 'Haettenschweiler', sans-serif;
  --court: 'Courier New', Courier, monospace;

  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  height: 100%;
  overflow: hidden;
  /* Base wash lives here, NOT on .stars — .stars translates by a whole
     tile every cycle and would drag its own gradient edge into view. */
  background: linear-gradient(160deg, var(--void) 0%, var(--void-2) 55%, #4B0082 100%);
  background-attachment: fixed;
  color: #fff;
  font-family: var(--comic);
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
}
body { overscroll-behavior: none; user-select: none; }

/* Tiled starfield, drifting forever, exactly as god intended. */
.stars {
  position: fixed;
  inset: -60px;
  background:
    radial-gradient(1.6px 1.6px at 24px 32px, #fff, transparent),
    radial-gradient(1.4px 1.4px at 88px 12px, var(--cyan), transparent),
    radial-gradient(1.8px 1.8px at 140px 76px, #fff, transparent),
    radial-gradient(1.3px 1.3px at 52px 118px, var(--magenta), transparent),
    radial-gradient(1.5px 1.5px at 176px 148px, #fff, transparent);
  background-size: 200px 180px;
  background-repeat: repeat;
  animation: drift 9s linear infinite;
  z-index: 0;
}
@keyframes drift { to { transform: translate(-200px, -180px); } }

.site { position: fixed; inset: 0; z-index: 1; }

.screen { position: absolute; inset: 0; display: none; flex-direction: column; }
.screen.is-active { display: flex; }
[hidden] { display: none !important; }

.page {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 14px 12px calc(var(--safe-b) + 18px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 15px;
  text-align: center;
}

/* ── marquee ─────────────────────────────────────────────────────── */

.marquee {
  flex: none;
  overflow: hidden;
  white-space: nowrap;
  background: #000;
  border-bottom: 3px ridge var(--lime);
  padding: 5px 0;
  padding-top: calc(var(--safe-t) + 5px);
  font-family: var(--court);
  font-size: 13px;
  font-weight: 700;
  color: var(--lime);
}
.marquee-track {
  display: inline-block;
  padding-left: 100%;
  animation: marquee 18s linear infinite;
}
@keyframes marquee { to { transform: translateX(-100%); } }

/* ── WordArt ─────────────────────────────────────────────────────── */
/*
   Real WordArt is a bevelled face over an offset dark extrusion. Two
   stacked copies of the text: the shadow layer sits behind and down-
   right, the face layer carries the rainbow. Text-shadow alone can't do
   it — a gradient-filled glyph has no shadow to offset.
*/
.wordart {
  position: relative;
  display: inline-block;
  /* Both layers MUST break identically. The shadow layer is absolutely
     positioned, so left to itself it wraps at its own width and the two
     copies desynchronise — which renders as a doubled, offset word. */
  white-space: nowrap;
  font-family: var(--impact);
  font-size: clamp(2.6rem, 15vw, 4.2rem);
  line-height: 1;
  letter-spacing: .02em;
  text-transform: uppercase;
  margin-top: 4px;
}
.wordart-sm { font-size: clamp(2.1rem, 12vw, 3.2rem); }

.wordart-shadow {
  position: absolute;
  left: 3px; top: 4px;
  color: #000;
  -webkit-text-fill-color: #000;
  z-index: 0;
}
.wordart-face { position: relative; z-index: 1; }
/* The bevel: a bright top-left edge and a dark bottom-right one. */
.wordart .rainbow {
  filter:
    drop-shadow(-1px -1px 0 rgba(255,255,255,.85))
    drop-shadow(2px 2px 0 rgba(0,0,0,.85))
    drop-shadow(0 0 10px rgba(255,51,204,.55));
}

.tag {
  font-size: 16px;
  line-height: 1.45;
  color: var(--cyan);
  font-weight: 700;
}
.tag-sub { color: var(--yellow); font-size: 14px; }

/* Sits directly above the button so the instruction and its target are
   one object, not two things the eye has to connect. */
.tap-hint {
  font-family: var(--court);
  font-size: 15px;
  font-weight: 700;
  letter-spacing: .08em;
  color: var(--yellow);
  text-shadow: 0 0 10px rgba(255,255,51,.6);
  margin-bottom: -4px;
}

.head2 {
  font-family: var(--impact);
  font-size: clamp(1.5rem, 7.5vw, 2rem);
  letter-spacing: .04em;
  color: var(--yellow);
  text-shadow: 2px 2px 0 #000, 0 0 12px rgba(255,255,51,.5);
  text-transform: uppercase;
}

.blink { animation: blink 1s steps(1) infinite; }
@keyframes blink { 0%,50% { opacity: 1 } 51%,100% { opacity: 0 } }

/* ── under construction ──────────────────────────────────────────── */

.construction {
  width: 100%;
  font-family: var(--court);
  font-weight: 700;
  font-size: 13px;
  color: #000;
  padding: 6px 8px;
  letter-spacing: .06em;
  /* The hazard barber-pole, animated. */
  background: repeating-linear-gradient(
    45deg, #FFD700 0 12px, #000 12px 24px);
  background-size: 34px 34px;
  animation: barber 1.1s linear infinite;
  border-top: 2px solid #000;
  border-bottom: 2px solid #000;
  text-shadow: 0 0 4px #FFD700, 0 0 4px #FFD700, 0 0 4px #FFD700;
}
@keyframes barber { to { background-position: 34px 0; } }
.cone { font-size: 15px; }

/* ── beveled panels ──────────────────────────────────────────────── */

.panel {
  width: 100%;
  background: rgba(0,0,0,.55);
  border: 3px outset var(--magenta);
  padding: 10px 12px;
}
.panel-head {
  font-family: var(--court);
  font-weight: 700;
  color: var(--magenta);
  font-size: 13px;
  letter-spacing: .08em;
  margin-bottom: 6px;
}
.steps {
  text-align: left;
  padding-left: 22px;
  font-size: 15px;
  line-height: 1.75;
  color: #fff;
}
.steps b { color: var(--yellow); }

/* ── Windows buttons ─────────────────────────────────────────────── */

.win-btn {
  width: 100%;
  font-family: var(--comic);
  font-size: 17px;
  font-weight: 700;
  color: #000;
  background: var(--face);
  border: none;
  box-shadow:
    inset 2px 2px 0 var(--hi),
    inset -2px -2px 0 var(--dk),
    inset 4px 4px 0 rgba(255,255,255,.4),
    inset -4px -4px 0 var(--lo);
  padding: 13px 14px;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
}
.win-btn:active {
  box-shadow:
    inset -2px -2px 0 var(--hi),
    inset 2px 2px 0 var(--dk),
    inset -4px -4px 0 rgba(255,255,255,.4),
    inset 4px 4px 0 var(--lo);
  padding: 14px 13px 12px 15px;
}
.win-btn small { font-size: 12px; font-weight: 400; }

.win-btn-big {
  font-size: 25px;
  padding: 26px 16px;
  animation: throb 1.3s ease-in-out infinite;
}
.win-btn-big small { font-size: 15px; }
@keyframes throb {
  0%,100% { transform: scale(1); }
  50%     { transform: scale(1.035); }
}

/* ── visitor counter ─────────────────────────────────────────────── */

.counter-box { display: flex; flex-direction: column; align-items: center; gap: 5px; }
.counter-label {
  font-family: var(--court);
  font-size: 11px;
  letter-spacing: .14em;
  color: var(--cyan);
}
.odometer {
  display: flex;
  gap: 2px;
  background: #000;
  border: 2px inset var(--lo);
  padding: 4px;
}
.odometer.ticked {
  animation: odo-tick .9s ease-out;
}
@keyframes odo-tick {
  0%   { box-shadow: 0 0 0 0 rgba(51,255,102,.9); }
  100% { box-shadow: 0 0 16px 5px rgba(51,255,102,0); }
}

.odometer i {
  font-family: var(--court);
  font-style: normal;
  font-weight: 700;
  font-size: 21px;
  color: var(--lime);
  background: #0A0A0A;
  width: 17px;
  text-align: center;
  text-shadow: 0 0 6px var(--lime);
}

.page-foot {
  width: 100%;
  margin-top: auto;          /* claim whatever vertical space is spare */
  padding-top: 22px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

/* The checkout screen otherwise sits doing nothing while the user works
   out that they're meant to double-tap. A feed of other people getting
   results makes the machine look busy. */
[data-screen="pay"] .ticker { margin-top: auto; }
[data-screen="pay"] .page-foot { margin-top: 0; padding-top: 14px; }

.ticker {
  width: 100%;
  background: rgba(0,0,0,.6);
  border: 3px ridge var(--lime);
  padding: 7px 9px 8px;
}
[data-screen="pay"] .footer .blink { animation: none; }
[data-screen="pay"] .ticker-head .blink {
  animation: soft-pulse 2.2s ease-in-out infinite;
}
@keyframes soft-pulse { 0%,100% { opacity: .45 } 50% { opacity: 1 } }

.ticker-head {
  font-family: var(--court);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  color: var(--lime);
  margin-bottom: 5px;
}
.ticker-list { display: flex; flex-direction: column; }

.tick-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 3px 1px;
  font-size: 14px;
  border-bottom: 1px dotted rgba(51,255,102,.25);
  /* Each arrival slides down from nothing, so the feed reads as live
     rather than as a list that was always sitting there. */
  animation: tick-in .35s ease both;
}
.tick-row:last-child { border-bottom: none; }
@keyframes tick-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
.tick-name {
  color: #fff;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tick-pct {
  font-family: var(--court);
  font-weight: 700;
  color: var(--yellow);
  flex: none;
}
.tick-row.is-zero .tick-name,
.tick-row.is-zero .tick-pct { color: rgba(255,255,255,.35); }

.dashes {
  width: 100%;
  border: none;
  border-top: 3px dashed var(--cyan);
  opacity: .8;
}

.footer {
  font-size: 12px;
  line-height: 1.7;
  color: var(--cyan);
}
.footer .blink { color: var(--yellow); font-weight: 700; }

/* ── checkout ────────────────────────────────────────────────────── */

.receipt { width: 100%; font-size: 15px; border-collapse: collapse; }
.receipt td { padding: 4px 2px; text-align: left; }
.receipt td:last-child { text-align: right; font-family: var(--court); font-weight: 700; }
.receipt .tot td {
  border-top: 2px dashed var(--magenta);
  padding-top: 7px;
  color: var(--yellow);
  font-weight: 700;
}

.secure { font-size: 13px; color: var(--lime); }
.lock { font-size: 15px; }

.applepay {
  width: 100%;
  height: 70px;
  background: #000;
  border: 3px outset var(--lo);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  cursor: pointer;
  font-family: -apple-system, 'SF Pro Text', system-ui, sans-serif;
  font-size: 27px;
  font-weight: 500;
  /* This is the only thing on the page anyone has to do, so it gets the
     strongest motion. A glow pulse rather than a blink — a control that
     disappears every half second is genuinely harder to tap. */
  animation: pay-pulse 1.4s ease-in-out infinite;
}
@keyframes pay-pulse {
  0%, 100% { transform: scale(1);     box-shadow: 0 0 0 0 rgba(51,255,102,.5); }
  50%      { transform: scale(1.025); box-shadow: 0 0 22px 7px rgba(51,255,102,.45); }
}
.applepay:active { border-style: inset; animation: none; transform: scale(.99); }
.applepay-mark {
  width: 25px; height: 30px;
  background: #fff;
  -webkit-mask: var(--apple-mark) center/contain no-repeat;
  mask: var(--apple-mark) center/contain no-repeat;
}
:root {
  --apple-mark: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 170 210'><path fill='black' d='M140 111c0-25 20-37 21-38-11-17-29-19-36-19-15-2-30 9-38 9s-20-9-33-8c-17 0-32 10-41 25-17 30-4 75 13 100 8 12 18 26 31 25 12 0 17-8 32-8s19 8 33 8c13 0 22-12 30-24 9-14 13-27 13-28-1 0-25-10-25-42zM116 34c7-8 11-19 10-30-10 0-22 6-29 15-6 7-12 19-10 30 11 1 22-5 29-15z'/></svg>");
}

.hint { font-size: 13px; color: var(--yellow); }
#pay-hint {
  font-size: 15px;
  font-weight: 700;
  animation: blink 1s steps(1) infinite;
}
.working { font-family: var(--court); font-weight: 700; color: var(--lime); font-size: 15px; }
.done { font-family: var(--impact); font-size: 22px; color: var(--lime); text-shadow: 2px 2px 0 #000; }

/* ── progress bars ───────────────────────────────────────────────── */

.bar {
  width: 100%;
  height: 22px;
  background: #000;
  border: 2px inset var(--lo);
  padding: 2px;
}
.bar-big { height: 46px; padding: 3px; }
.bar-fill {
  height: 100%;
  width: 0;
  /* Classic segmented Win95 progress blocks. */
  background:
    repeating-linear-gradient(90deg, var(--lime) 0 9px, #000 9px 12px);
  transition: width .12s linear;
}

/* ── the TV ──────────────────────────────────────────────────────── */

/* The viewfinder takes whatever space is left. This screen has an actual
   job — see yourself, follow the guidance, hold still — and it's also the
   frame that gets captured for the reveal, so a bigger preview helps both.
   A fixed 3:4 box left ~240px of dead purple underneath it. */
.tv {
  position: relative;
  width: 100%;
  flex: 1 1 auto;
  min-height: 0;
  background: #000;
  border: 5px outset var(--cyan);
  overflow: hidden;
}
.tv video {
  width: 100%; height: 100%;
  object-fit: cover;
  transform: scaleX(-1);
  filter: saturate(1.5) contrast(1.15);
}
.tv-scan {
  position: absolute; inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(180deg, rgba(0,0,0,.35) 0 2px, transparent 2px 4px);
}
.tv-corner {
  position: absolute;
  width: 22px; height: 22px;
  border: 4px solid var(--yellow);
  animation: blink 1s steps(1) infinite;
}
.tv-tl { top: 6px; left: 6px; border-right: none; border-bottom: none; }
.tv-tr { top: 6px; right: 6px; border-left: none; border-bottom: none; }
.tv-bl { bottom: 6px; left: 6px; border-right: none; border-top: none; }
.tv-br { bottom: 6px; right: 6px; border-left: none; border-top: none; }

[data-screen="scan"] .page { overflow: hidden; }
.readout {
  width: 100%;
  flex: none;
  font-family: var(--court);
  font-weight: 700;
  font-size: 16px;
  color: #000;
  background: var(--lime);
  border: 3px outset var(--lime);
  padding: 9px 8px;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.readout.warn { background: var(--yellow); }
.readout.good { background: var(--cyan); }

/* This screen had ~200px of dead space under it. Everything gets more
   room: the content spreads down the page rather than piling at the top. */
[data-screen="analysis"] .page { justify-content: space-evenly; gap: 10px; }

.thumb {
  width: min(56vw, 210px);
  border: 5px ridge var(--magenta);
  filter: saturate(1.3);
}

/* The running commentary is the most interesting thing here, so it gets
   the biggest jump. min-height stops the layout twitching as the lines
   change length. */
.task {
  font-family: var(--court);
  font-weight: 700;
  color: var(--cyan);
  font-size: 20px;
  line-height: 1.35;
  min-height: 2.7em;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 4px;
  text-shadow: 0 0 12px rgba(51,255,255,.45);
}

.bigpct {
  font-family: var(--impact);
  font-size: 5rem;
  color: var(--lime);
  text-shadow: 3px 3px 0 #000, 0 0 22px rgba(51,255,102,.65);
  line-height: 1;
}

/* ── result ──────────────────────────────────────────────────────── */

.screen-result { background: #000; justify-content: space-between; overflow: hidden; }
.result-photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.result-flash {
  position: absolute; inset: 0;
  background: #fff;
  animation: flash .3s steps(1) infinite;
  pointer-events: none;
}
@keyframes flash {
  0%,44%   { opacity: 0 }
  45%,57%  { opacity: .88 }
  58%,100% { opacity: 0 }
}

.sparkles { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.sparkles i {
  position: absolute;
  font-style: normal;
  font-size: 22px;
  animation: sparkle 1.4s ease-in-out infinite;
}
@keyframes sparkle {
  0%,100% { opacity: 0; transform: scale(.4) rotate(0deg); }
  50%     { opacity: 1; transform: scale(1.15) rotate(180deg); }
}

.result-top {
  position: relative;
  padding: calc(var(--safe-t) + 24px) 14px 0;
  text-align: center;
  width: 100%;
}
.verdict {
  font-family: var(--impact);
  font-size: clamp(5.5rem, 33vw, 12rem);
  line-height: .86;
  letter-spacing: .01em;
  animation: verdict-bounce .26s ease-in-out infinite alternate;
}
@keyframes verdict-bounce {
  from { transform: scale(1) rotate(-1.5deg); }
  to   { transform: scale(1.09) rotate(1.5deg); }
}
.verdict-sub {
  position: relative;
  margin: 12px auto 0;
  max-width: 28ch;
  font-size: 15px;
  font-weight: 700;
  color: var(--yellow);
  text-shadow: 2px 2px 0 #000, 0 0 10px rgba(0,0,0,.95);
}

/* A full-width banner bolted across the bottom of the page, like every
   other piece of furniture on a 1999 homepage. Deliberately NOT floating
   over the photo — the face is the punchline and the placard was sitting
   right on it. */
.result-scrim {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 46%;
  background: linear-gradient(180deg, transparent, rgba(27,0,51,.72) 55%, rgba(27,0,51,.9));
  pointer-events: none;
}

.result-foot { position: relative; width: 100%; }

/* In layout from the start but invisible, so the buttons never jump. */
.award {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 1.2s ease, transform 1.2s ease;
  background: #000;
  border-top: 4px ridge var(--lime);
  border-bottom: 4px ridge var(--lime);
  padding: 7px 12px;
  margin-bottom: 12px;
  text-align: center;
}
.award.show { opacity: 1; transform: none; }
.award-label {
  font-family: var(--court);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  color: var(--cyan);
}
.award-value {
  font-family: var(--impact);
  font-size: clamp(1.5rem, 8vw, 2.2rem);
  letter-spacing: .02em;
  color: var(--yellow);
  text-shadow: 2px 2px 0 #000, 0 0 14px rgba(255,255,51,.65);
  margin-top: 2px;
  word-break: break-word;
}

/* Share and re-scan split one row; the leaderboard keeps a full-width
   row of its own because it's the onward journey, not a side action. */
/* One button by default. Four stacked buttons plus a banner was eating
   the middle of the screen, and the middle of the screen is the face —
   which is the entire payoff of this page. */
.win-btn-menu { font-size: 19px; padding: 13px 12px; }

/* Leads the stack on the leaderboard: it's the way back to everything
   else, so it should read as the primary move rather than a footnote. */
.win-btn-back { font-size: 17px; padding: 10px 12px; }
.win-btn-back small { font-size: 11px; color: #333; }

/* ── the board gets the rest ─────────────────────────────────────────
   The leaderboard is the entire point of this screen, so everything
   around it is trimmed and .board-frame (flex: 1) absorbs the slack. */
[data-screen="board"] .page { gap: clamp(6px, 1.2vh, 12px); }
[data-screen="board"] .wordart-sm { font-size: clamp(1.5rem, 8vw, 2.3rem); margin-top: 2px; }
[data-screen="board"] .board-status { font-size: 12px; }
[data-screen="board"] .result-actions { gap: 7px; }
[data-screen="board"] .btn-row .win-btn { font-size: 15px; padding: 10px 6px; }
[data-screen="board"] .board { font-size: 16px; }
[data-screen="board"] .board td { padding: 7px 8px; }
.win-btn-menu small { font-size: 11px; }

/* Two buttons need to pull the eye: the one that opens the menu, and the
   one inside it we actually want tapped.

   Done with an animated OUTLINE, not a pseudo-element. A ::after at
   z-index:-1 paints *above* its parent's background rather than behind it
   — CSS paints negative-z descendants after the element's own background —
   so the gradient filled the buttons instead of ringing them. Outline also
   stays clear of the Win95 bevel, which already owns box-shadow. */
.win-btn-glow,
.win-btn-wall {
  position: relative;
  outline: 3px solid #E40303;
  outline-offset: 2px;
  animation: glow-hue 2.4s steps(1) infinite;
}
@keyframes glow-hue {
  0%   { outline-color: #E40303; }
  17%  { outline-color: #FF8C00; }
  34%  { outline-color: #FFED00; }
  50%  { outline-color: #008026; }
  67%  { outline-color: #004DFF; }
  84%  { outline-color: #750787; }
  100% { outline-color: #E40303; }
}

/* The wall button is the one we most want tapped, so it also breathes. */
.win-btn-wall {
  animation: glow-hue 2.4s steps(1) infinite,
             wall-throb 1.8s ease-in-out infinite;
}
@keyframes wall-throb {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.02); }
}
.win-btn-wall:active { animation: none; }

.wall-new {
  position: absolute;
  top: -9px; right: -6px;
  z-index: 1;
  font-family: var(--court);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .06em;
  color: #000;
  background: var(--yellow);
  border: 2px solid #000;
  padding: 1px 5px;
  transform: rotate(7deg);
}

.menu-panel {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-bottom: 7px;
  animation: menu-open .22s ease both;
}
.menu-panel .win-btn { font-size: 16px; padding: 10px 10px; }

/* With six options the stack ran past the bottom of the window. The
   banner has already been read by the time anyone opens the menu, so it
   stands down and gives its ~85px back. */
.result-foot.menu-open .award { display: none; }

/* Open, the button is a plain "close" — it should stop competing with
   the options it just revealed. No ring, no throb, just a darker key. */
.win-btn-menu.is-open {
  animation: none;
  outline: none;
  background: #9A9A9A;
}
@keyframes menu-open {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.btn-row { display: flex; gap: 9px; }
.btn-row > * { flex: 1 1 0; min-width: 0; }
.btn-row .win-btn { font-size: 16px; padding: 11px 8px; }
.btn-row .win-btn small { font-size: 11px; }

.result-actions {
  position: relative;
  width: 100%;
  padding: 0 12px calc(var(--safe-b) + 16px);
  display: flex;
  flex-direction: column;
  gap: 9px;
}
.screen-result .result-actions {
  opacity: 0;
  transform: translateY(14px);
  pointer-events: none;
  transition: opacity .6s ease, transform .6s ease;
}
.screen-result .result-actions.show { opacity: 1; transform: none; pointer-events: auto; }

/* ── leaderboard table ───────────────────────────────────────────── */

.board-status { font-family: var(--court); font-size: 13px; color: var(--cyan); min-height: 1.3em; }
.board-status.locked { color: var(--lime); font-weight: 700; }

.board-frame {
  width: 100%;
  flex: 1;
  min-height: 0;
  /* Scrollable, not clipped. The bottom of this board is where all the
     0% screen names live, and they are the best part of the list — with
     overflow:hidden they were rendered and then made unreachable. The
     mask stays as a "there's more down there" affordance. */
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  border: 4px ridge var(--cyan);
  background: rgba(0,0,0,.6);
  -webkit-mask-image: linear-gradient(180deg, #000 0 88%, transparent 100%);
  mask-image: linear-gradient(180deg, #000 0 88%, transparent 100%);
}
.board { width: 100%; border-collapse: collapse; font-size: 15px; }
.board td { padding: 6px 8px; text-align: left; }
.board tr:nth-child(odd) { background: rgba(255,255,255,.05); }

/* Appears only once the board has settled — see main.js. Kept in the
   layout the whole time so the rows don't shift underneath it. */
.board .board-header {
  opacity: 0;
  transition: opacity .55s ease;
}
.board.settled .board-header { opacity: 1; }
.board .board-header td {
  background: #000;
  border-bottom: 2px solid var(--cyan);
  padding-top: 8px;
  padding-bottom: 6px;
  font-family: var(--court);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  color: var(--cyan);
  text-transform: uppercase;
  vertical-align: bottom;
  line-height: 1.25;
}
.board .board-header .r-pct { color: var(--yellow); }
.board .r-rank { width: 2.4rem; color: var(--cyan); font-family: var(--court); font-size: 13px; }
.board .r-pct { text-align: right; font-family: var(--court); font-weight: 700; color: var(--yellow); }
.board .zero .r-name, .board .zero .r-pct { color: rgba(255,255,255,.35); }

.board .you td {
  background: var(--hot);
  color: #fff;
  font-weight: 700;
  font-size: 16px;
}
.board .you .r-rank, .board .you .r-pct { color: #fff; }
.board .you.first td { animation: you-pop .5s ease both; }
@keyframes you-pop {
  0%   { background: #fff; transform: scale(1.04); }
  100% { background: var(--hot); transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .stars, .marquee-track, .construction, .win-btn-big, .verdict,
  .result-flash, .sparkles i, .blink, .tv-corner { animation: none !important; }
  .result-flash { opacity: 0; }
}

/* ═══════════════════════════════════════════════════════════════════
   GaY sCaN 2001 — what the Y2K build becomes with more nerve.

   Everything above is inherited. What follows is the upgrade, and the
   thinking behind each piece:

   · WINDOW CHROME. The original was a web page pretending to be 1999.
     Wrapping it in a Windows-98 application window makes it a *program*,
     which is a much bigger leap in period-feel than any amount of extra
     WordArt. It also gives somewhere honest to hang the music toggle.

   · A DIAL-UP SCREEN. The original went straight from paying to
     scanning. Making you wait through a 56k handshake — synthesised, no
     sample — adds a whole comedic beat in dead time the app already had.

   · A POPUP AD. Non-negotiable for the era, and it makes the checkout
     screen feel like somewhere hostile rather than somewhere designed.

   · A CURSOR TRAIL. The single most geocities thing that exists.
   ═══════════════════════════════════════════════════════════════════ */

.win98 {
  position: fixed;
  inset: 0;
  display: flex;
  flex-direction: column;
  z-index: 1;
  /* Transparent on purpose — a solid fill here covers the starfield the
     whole design is built on. The frame is the border; the chrome
     elements below bring their own backgrounds. */
  background: none;
  border: 3px solid var(--face);
  box-shadow: inset 1px 1px 0 var(--hi), inset -1px -1px 0 var(--dk);
}

.titlebar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 3px 4px;
  padding-top: calc(var(--safe-t) + 3px);
  background: linear-gradient(90deg, #000082, #1084D0);
  color: #fff;
  font-family: var(--court);
  font-size: 13px;
  font-weight: 700;
}
.titlebar-icon { font-size: 13px; }
.titlebar-text { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.titlebar-btns { display: flex; gap: 3px; }
.tb-btn {
  width: 22px; height: 20px;
  background: var(--face);
  border: none;
  box-shadow: inset 1px 1px 0 var(--hi), inset -1px -1px 0 var(--dk);
  color: #000;
  font-family: var(--court);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}
.tb-btn:active { box-shadow: inset -1px -1px 0 var(--hi), inset 1px 1px 0 var(--dk); }
.tb-close { color: #000; }

.menubar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 3px 8px;
  background: var(--face);
  border-bottom: 1px solid var(--lo);
  font-family: var(--court);
  font-size: 12px;
  color: #000;
}
.menubar-toggle {
  margin-left: auto;
  cursor: pointer;
  padding: 1px 5px;
  border: 1px solid transparent;
}
.menubar-toggle.on {
  background: #000082;
  color: #fff;
  border-color: #000082;
}

/* ── fitting the home screen ─────────────────────────────────────
   The window chrome eats ~52px that the plain Y2K build doesn't spend,
   which pushed the footer just below the fold on an iPhone. Rather than
   pick a breakpoint and hope, the vertical rhythm scales with viewport
   height: roomy on a big screen, tight on a small one, and everything
   visible on load either way.

   Overflow is deliberately left scrollable as a safety valve — on a very
   short screen scrolling is bad, but clipping the button is worse. */
/* NOTE ON THE UNITS: vh is the *viewport*, which does not subtract the
   notch or the home indicator. On a real iPhone those cost ~93px that
   this simulator reports as 0, which is why a layout that measured as
   "exactly fits" still scrolled on device. Everything below is sized to
   fit WITH those insets present, so it fits without them too. */
/* Spacing by GROUP rather than one uniform gap. Things that belong
   together sit close; the seams between groups get the air. Reading top
   to bottom the page is really four blocks:
       who this is        wordart + tagline
       the warning        construction bar
       what happens       how-it-works panel
       what u do          tap hint + button   (one unit — the hint points
                                               at the button, so a gap
                                               between them reads as two
                                               separate things)
   and then the footer, which margin-top:auto pins to the bottom. */
[data-screen="home"] .page {
  gap: 0;                                    /* every gap set explicitly below */
  padding-top: 8px;
  padding-bottom: calc(var(--safe-b) + 8px);
}
[data-screen="home"] .tag          { margin-top: clamp(3px, .7vh, 7px); }
[data-screen="home"] .construction { margin-top: clamp(8px, 1.9vh, 20px); }
[data-screen="home"] .panel        { margin-top: clamp(8px, 1.9vh, 20px); }
[data-screen="home"] .tap-hint     { margin-top: clamp(9px, 2.1vh, 22px); }
[data-screen="home"] .win-btn-big  { margin-top: clamp(2px, .5vh, 5px); }
[data-screen="home"] .wordart { margin-top: 0; font-size: clamp(1.75rem, 9.5vw, 2.9rem); }
[data-screen="home"] .tag { font-size: clamp(13px, 1.7vh, 15px); line-height: 1.3; }
[data-screen="home"] .construction { padding: clamp(3px, .6vh, 5px) 8px; font-size: 12px; }
[data-screen="home"] .panel { padding: clamp(6px, 1vh, 9px) 11px; }
[data-screen="home"] .panel-head { margin-bottom: 4px; }
[data-screen="home"] .steps { font-size: clamp(13px, 1.7vh, 15px); line-height: clamp(1.35, 2.1vh, 1.6); padding-left: 20px; }
[data-screen="home"] .tap-hint { font-size: clamp(12px, 1.6vh, 14px); margin-bottom: -2px; }
[data-screen="home"] .win-btn-big { padding: clamp(11px, 2.2vh, 20px) 14px; font-size: clamp(19px, 2.6vh, 24px); }
[data-screen="home"] .win-btn-big small { font-size: clamp(12px, 1.6vh, 14px); }
[data-screen="home"] .page-foot { padding-top: clamp(5px, 1.1vh, 14px); gap: clamp(5px, 1vh, 10px); }
[data-screen="home"] .odometer { padding: 3px; }
[data-screen="home"] .odometer i { font-size: clamp(15px, 2.2vh, 19px); width: clamp(13px, 1.9vh, 16px); }
[data-screen="home"] .footer { font-size: clamp(10px, 1.3vh, 12px); line-height: 1.45; }
[data-screen="home"] .counter-label { font-size: clamp(9px, 1.2vh, 11px); }
[data-screen="home"] .dashes { border-top-width: 2px; }

/* The app's own screens now live inside the window, not the viewport. */
.win98 .site { position: relative; flex: 1; min-height: 0; inset: auto; }
.win98 .screen { position: absolute; inset: 0; }

/* ── dial-up ─────────────────────────────────────────────────────── */

/* The dial-up screen had everything piled at the top with dead purple
   underneath. Spread it down the page instead. */
/* Checkout, sized to fit WITH the notch and home indicator — see the
   note on the home screen for why vh alone isn't enough. The Apple Pay
   button keeps its size; everything around it gives way instead, since
   it's the only thing on this screen anyone has to hit. */
[data-screen="pay"] .page { gap: clamp(5px, 1.1vh, 13px); padding-top: 8px; }
[data-screen="pay"] .head2 { font-size: clamp(1.3rem, 6vw, 1.7rem); }
[data-screen="pay"] .panel { padding: clamp(6px, 1vh, 9px) 11px; }
[data-screen="pay"] .receipt { font-size: clamp(13px, 1.8vh, 15px); }
[data-screen="pay"] .receipt td { padding: 3px 2px; }
[data-screen="pay"] .secure { font-size: clamp(11px, 1.5vh, 13px); }
[data-screen="pay"] .ticker { padding: 5px 8px 6px; }
[data-screen="pay"] .ticker-head { font-size: 10px; margin-bottom: 3px; }
[data-screen="pay"] .tick-row { padding: 2px 1px; font-size: clamp(12px, 1.7vh, 14px); }
[data-screen="pay"] .page-foot { padding-top: clamp(5px, 1vh, 12px); gap: clamp(5px, 1vh, 10px); }
[data-screen="pay"] .footer { font-size: clamp(10px, 1.3vh, 12px); line-height: 1.45; }

[data-screen="dial"] .page { justify-content: space-evenly; gap: clamp(8px, 1.6vh, 16px); }

.dial-panel { display: flex; flex-direction: column; gap: 12px; }
.dial-panel .dial-row { font-size: clamp(13px, 1.9vh, 15px); }
.dial-panel .bar { height: clamp(22px, 3.4vh, 32px); }

.tip-panel { border-color: var(--cyan); }
.tip-panel .panel-head { color: var(--cyan); }
.tip {
  font-size: clamp(14px, 2vh, 16px);
  line-height: 1.45;
  color: #fff;
  min-height: 3em;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.tip b { color: var(--yellow); }
.tip.tip-in { animation: tip-fade .45s ease both; }
@keyframes tip-fade {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: none; }
}
.dial-rows { display: flex; flex-direction: column; gap: 6px; }
.dial-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-family: var(--court);
  font-size: 13px;
}
.dial-row span { color: var(--cyan); }
.dial-row b { color: var(--lime); font-weight: 700; text-align: right; }

/* ── popup ad ────────────────────────────────────────────────────── */

.popup-veil {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: grid;
  place-items: center;
  padding: 20px;
  background: rgba(0,0,0,.45);
}
.popup {
  width: 100%;
  max-width: 330px;
  background: var(--face);
  padding: 3px;
  box-shadow: inset 2px 2px 0 var(--hi), inset -2px -2px 0 var(--dk), 6px 6px 0 rgba(0,0,0,.5);
  animation: popup-in .18s ease both;
}
@keyframes popup-in {
  from { opacity: 0; transform: scale(.9) }
  to   { opacity: 1; transform: none }
}
.titlebar-popup { padding-top: 3px; }
.popup-body {
  padding: 14px 12px 12px;
  text-align: center;
  color: #000;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.popup-shout {
  font-family: var(--impact);
  font-size: 21px;
  color: #C00000;
  letter-spacing: .02em;
}
.popup-line { font-size: 15px; line-height: 1.35; }
.popup-line b { color: #0000C0; }
.popup-small { font-size: 13px; }
.popup-ok { margin-top: 2px; }
.popup-tiny { font-size: 10px; color: #555; }

/* ── cursor trail ────────────────────────────────────────────────── */

.trail {
  position: fixed;
  z-index: 150;
  pointer-events: none;
  font-size: 15px;
  animation: trail-out .85s ease-out forwards;
}
@keyframes trail-out {
  from { opacity: 1; transform: translate(-50%, -50%) scale(1) rotate(0deg); }
  to   { opacity: 0; transform: translate(-50%, 22px) scale(.4) rotate(140deg); }
}

@media (prefers-reduced-motion: reduce) {
  .trail { display: none; }
  .popup { animation: none; }
}

@media (max-height: 700px) {
  .menubar { display: none; }
}
