/* The pages the server draws (sign-in, family board, error pages), in the game's own
   "Cartoon (night)" look: a starry purple sky with a moon, green hills along the bottom,
   chunky panels with thick ink outlines and hard drop shadows, the game's Lilita One and
   Fredoka fonts (from fonts.css on this server). Colours are the game's doodledark palette.
   Nothing here is fetched from anywhere else. */
:root {
  color-scheme: dark;
  --sky-top: #141a3e;
  --sky-mid: #33276a;
  --sky-low: #7a3576;
  --night: #1d1f4a;
  --deck: #24305e;      /* panels */
  --well: #18204a;      /* sunken fields */
  --line: #0b1026;      /* ink outlines */
  --ink: #ffffff;       /* text */
  --dim: #c9cff0;       /* quieter text */
  --coin: #ffd23f;      /* the thing to press */
  --coin-hi: #ffdf6b;
  --coin-ink: #1b2440;  /* text on yellow */
  --pink: #ef4f8f;
  --hostile: #ff4d6d;
  --alert-bg: #ffd0d6;
  --star: #ffe066;
  --moon: #fff3c4;
  --grass: #1e4636;
  --grass-back: #193b2f;
  --bush: #2f6b4f;
  --display: "Lilita One", "Arial Rounded MT Bold", "Arial Black", sans-serif;
  --body: "Fredoka", "Arial Rounded MT Bold", system-ui, sans-serif;
  /* the game's cartoon outline round lettering */
  --outline: 2px 0 0 var(--line), -2px 0 0 var(--line), 0 2px 0 var(--line), 0 -2px 0 var(--line),
    2px 2px 0 var(--line), -2px 2px 0 var(--line), 2px -2px 0 var(--line), -2px -2px 0 var(--line), 0 4px 0 var(--line);
}

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

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

body {
  margin: 0;
  min-height: 100vh;
  overflow-x: clip; /* the tilted sticker behind a card may poke past a narrow screen's edge */
  color: var(--ink);
  font: 500 18px/1.45 var(--body);
  /* stars, then the lobby's faint sun rays, then the sky */
  background:
    radial-gradient(circle at 18px 26px, var(--star) 0 1.4px, transparent 2.2px) 0 0 / 150px 130px,
    radial-gradient(circle at 70px 90px, #ffffffcc 0 1px, transparent 1.8px) 0 0 / 190px 170px,
    repeating-conic-gradient(from -90deg at 50% -10%, #ffffff0b 0deg 6deg, transparent 6deg 15deg),
    linear-gradient(var(--sky-top), var(--sky-mid) 55%, var(--sky-low));
  background-attachment: fixed;
}

/* ---------------------------------------------------------------- the scenery behind the page */
.scenery { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.moon {
  position: absolute; top: max(18px, 5vh); right: max(16px, 7vw);
  width: clamp(54px, 8vw, 92px); aspect-ratio: 1; border-radius: 50%;
  border: 4px solid var(--line);
  background:
    radial-gradient(circle at 32% 34%, #ecdca0 0 13%, transparent 14%),
    radial-gradient(circle at 64% 60%, #ecdca0 0 16%, transparent 17%),
    radial-gradient(circle at 40% 78%, #ecdca0 0 7%, transparent 8%),
    var(--moon);
  box-shadow: 0 0 0 12px #fff3c412, 0 0 70px #fff3c440;
}
.sparkles { position: absolute; inset: 0 0 25vh; width: 100%; height: 75vh; }
.sparkle { fill: var(--star); stroke: var(--line); stroke-width: 2.5; stroke-linejoin: round; }
.hills { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: clamp(150px, 30vh, 260px); }
.hills path, .hills circle { stroke: var(--line); stroke-width: 4; stroke-linejoin: round; }
.hill-back { fill: var(--grass-back); }
.hill-front { fill: var(--grass); }
.road { fill: #2b2f55; }
.road-line { fill: none; stroke: var(--coin) !important; stroke-width: 6 !important; stroke-linecap: round; }
.bush { fill: var(--bush); }

/* ---------------------------------------------------------------- layout */
.stage {
  position: relative; z-index: 1;
  min-height: 100vh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: clamp(14px, 3vh, 32px) 16px clamp(28px, 6vh, 56px);
}
.brand { width: min(440px, 100%); margin: 0 0 4px; }
.brand.small { width: min(330px, 80%); }
.title-art { display: block; width: 100%; height: auto; overflow: visible; filter: drop-shadow(0 6px 0 #2a4fae); }
.title-art text { font-family: var(--display); fill: #fff; stroke: var(--line); stroke-width: 16px; stroke-linejoin: round; paint-order: stroke fill; }
.title-small { font-size: 46px; letter-spacing: 2px; }
.title-big { font-size: 88px; }
.squiggle { fill: none; stroke-width: 7; stroke-linecap: round; stroke-linejoin: round; }
.squiggle-pink { stroke: var(--pink); }
.squiggle-gold { stroke: var(--coin); }

/* The card sits in a "spot" that also holds the robot. */
.card-spot { position: relative; width: min(27rem, 100%); }
.card-spot.wide { width: min(46rem, 100%); }

/* A chunky panel with a tilted pink sticker peeking out behind it. */
.card {
  position: relative; isolation: isolate;
  padding: 26px 24px 28px;
  background: var(--deck);
  border: 3px solid var(--line);
  border-radius: 24px;
  box-shadow: 0 8px 0 var(--line);
}
.card::before {
  content: ""; position: absolute; inset: -3px; z-index: -1;
  border: 3px solid var(--line); border-radius: 24px;
  background: var(--pink);
  transform: rotate(2.6deg) translate(6px, 4px);
}
.card::after { /* the panel's face, over the sticker */
  content: ""; position: absolute; inset: 0; z-index: -1; border-radius: 21px; background: var(--deck);
}

h1 {
  margin: 0 0 18px;
  font: 400 clamp(30px, 8vw, 38px)/1.05 var(--display);
  letter-spacing: 0.02em;
  color: #fff;
  text-shadow: var(--outline);
}

p { margin: 0 0 16px; color: var(--dim); }

/* ---------------------------------------------------------------- the sign-in form */
form { display: flex; flex-direction: column; }
label { margin: 12px 0 6px; font-weight: 600; font-size: 17px; color: var(--ink); }
form > label:first-of-type { margin-top: 0; } /* a hidden field added to the form changes nothing */

input[type="text"], input[type="password"] {
  display: block; width: 100%;
  min-height: 56px; padding: 10px 16px;
  border: 3px solid var(--line); border-radius: 16px;
  background: var(--well); color: var(--ink);
  box-shadow: inset 0 4px 0 #0b102680;
  font: 600 20px/1.2 var(--body);
  letter-spacing: 0.02em;
}
input[type="text"]:focus, input[type="password"]:focus { border-color: var(--coin); }

/* The one-time code: a text field drawn as dots until its eye is pressed. */
.masked { -webkit-text-security: disc; }

.secret { position: relative; }
.secret input { padding-right: 64px; }

.eye {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  display: grid; place-items: center;
  width: 46px; height: 46px; padding: 0;
  border: 2.5px solid var(--line); border-radius: 12px;
  background: var(--deck); color: var(--dim);
  box-shadow: 0 3px 0 var(--line);
  cursor: pointer;
}
.eye:hover { color: #fff; }
.eye:active { transform: translateY(calc(-50% + 2px)); box-shadow: 0 1px 0 var(--line); }
.eye[aria-pressed="true"] { background: var(--coin); color: var(--coin-ink); }
.eye svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.eye .eye-ball { fill: currentColor; stroke: none; }
.eye .eye-slash { display: none; stroke-width: 2.8; }
.eye[aria-pressed="true"] .eye-slash { display: inline; }

/* The words are part of the tap target: the label reaches right up to the box and is at least 44px tall. */
.check { display: flex; align-items: center; margin: 14px 0 16px; }
.check label {
  display: flex; align-items: center; min-height: 48px; margin: 0; padding: 4px 0 4px 12px;
  font-weight: 500; font-size: 16px; line-height: 1.4; color: var(--dim);
}
/* A chunky box like the game's own toggles: a yellow fill when ticked. */
.check input {
  flex: none; width: 34px; height: 34px; margin: 0;
  appearance: none; -webkit-appearance: none;
  border: 3px solid var(--line); border-radius: 9px;
  background: var(--well);
  box-shadow: inset 0 3px 0 #0b102680;
  cursor: pointer;
}
.check input:checked {
  background: var(--coin);
  box-shadow: inset 0 0 0 4px var(--well);
}
.check label { cursor: pointer; }

form > button[type="submit"] {
  min-height: 60px; padding: 8px 20px;
  border: 3px solid var(--line); border-radius: 18px;
  background: var(--coin); color: var(--coin-ink);
  box-shadow: 0 6px 0 var(--line);
  font: 400 25px/1 var(--display);
  letter-spacing: 0.03em;
  cursor: pointer;
  transition: transform 80ms ease-out, box-shadow 80ms ease-out, background-color 80ms ease-out;
}
form > button[type="submit"]:hover { background: var(--coin-hi); }
form > button[type="submit"]:active { transform: translateY(4px); box-shadow: 0 2px 0 var(--line); }

/* Something went wrong: a pale red plate, like a wrong answer's plate in the game. */
.message {
  position: relative;
  margin: 0 0 18px; padding: 12px 14px 12px 52px;
  border: 3px solid var(--line); border-radius: 16px;
  background: var(--alert-bg); color: var(--coin-ink);
  box-shadow: 0 4px 0 var(--line);
  font-weight: 600; font-size: 17px; line-height: 1.35;
}
.message::before {
  content: "!"; position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center;
  border: 2.5px solid var(--line); background: var(--hostile); color: var(--coin-ink);
  font: 400 18px/1 var(--display);
}

/* ---------------------------------------------------------------- keyboard focus, always easy to see */
input:focus-visible, button:focus-visible, a:focus-visible {
  outline: 3px solid var(--coin);
  outline-offset: 3px;
}
.check input:focus-visible { outline-offset: 2px; }

/* ---------------------------------------------------------------- the robot and its blaster */
.hero { position: absolute; display: block; overflow: visible; pointer-events: none; }
.hero-ground { fill: #0b102659; }
.toy-blaster :is(path, rect, circle) { stroke: var(--line); stroke-width: 3; stroke-linejoin: round; }
.toy-blaster .tb-w { stroke: none; }
.tb-a { fill: #3a7bef; } .tb-b { fill: #ff8a3d; } .tb-c { fill: #ffd23f; } .tb-g { fill: #9fe8ff; } .tb-w { fill: #fff; }
.bot :is(.bot-foot, .bot-outline, .bot-mouth) { stroke: #1b2440; stroke-width: 3; stroke-linejoin: round; stroke-linecap: round; }
.bot-foot { fill: #717fa2; }
.bot-body { fill: #9fb0d6; }
.bot-shade { fill: #1b2440; fill-opacity: 0.24; }
.bot-outline { fill: none; }
.bot-eye { fill: #1b2440; }
.bot-shine, .bot-mouth { fill: #fff; }
.bot-teeth { fill: none; stroke: #1b2440; stroke-width: 2; }
/* A slow idle squish, like the bosses in the game. */
.bot { transform-box: fill-box; transform-origin: 50% 100%; animation: squish 2.6s ease-in-out infinite; }
@keyframes squish { 0%, 100% { transform: scale(1, 1); } 50% { transform: scale(1.035, 0.965); } }

/* On a phone the robot stands on the card's top edge, at the right. */
.hero { right: 4px; bottom: calc(100% - 10px); width: 128px; }
.signin .card-spot { margin-top: 70px; }

/* With room to spare, it stands on the hill to the left of the card. */
@media (min-width: 900px) {
  .hero { right: calc(100% + 16px); bottom: -12px; width: 260px; }
  .signin .card-spot { margin-top: 6px; }
}

/* ---------------------------------------------------------------- links */
a { color: var(--coin); font-weight: 600; text-underline-offset: 3px; }
.actions { margin: 20px 0 0; }
.actions a {
  display: inline-flex; align-items: center; min-height: 48px; padding: 8px 18px;
  border: 3px solid var(--line); border-radius: 16px;
  background: var(--coin); color: var(--coin-ink);
  box-shadow: 0 5px 0 var(--line);
  font: 400 19px/1 var(--display); letter-spacing: 0.03em; text-decoration: none;
}
.actions a:hover { background: var(--coin-hi); }
.actions a:active { transform: translateY(3px); box-shadow: 0 2px 0 var(--line); }

/* ---------------------------------------------------------------- the family board */
.board-wrap { margin: 4px -6px 0; padding: 0 6px; overflow-x: auto; }
.board { width: 100%; border-collapse: separate; border-spacing: 0 8px; font-variant-numeric: tabular-nums; }
.board thead th {
  padding: 0 8px 2px; text-align: right; vertical-align: bottom;
  font-weight: 600; font-size: 14px; line-height: 1.2; color: var(--dim);
}
.board thead th:nth-child(-n+2) { text-align: left; }
/* Fixed columns on a wide screen, so the long headings get room; automatic on a phone. */
.board { table-layout: fixed; }
.board thead th:nth-child(1) { width: 11%; }
.board thead th:nth-child(2) { width: 25%; }
.board thead th:nth-child(n+3) { width: 16%; }
.board tbody :is(td, th) {
  padding: 8px 10px; text-align: right;
  background: var(--well); color: var(--ink);
  border-block: 3px solid var(--line);
  font-weight: 700; font-size: 19px;
}
.board tbody td:first-child { border-left: 3px solid var(--line); border-radius: 16px 0 0 16px; padding-left: 8px; }
.board tbody td:last-child { border-right: 3px solid var(--line); border-radius: 0 16px 16px 0; }
.board tbody th { text-align: left; font-weight: 600; overflow-wrap: break-word; }
.board tr.me :is(td, th) { background: var(--coin); color: var(--coin-ink); }
.medal {
  display: inline-grid; place-items: center; width: 36px; height: 36px;
  border: 3px solid var(--line); border-radius: 50%;
  background: #fff; color: var(--coin-ink);
  font: 400 18px/1 var(--display);
}
.board tbody tr:nth-child(1) .medal { background: #ffd23f; }
.board tbody tr:nth-child(2) .medal { background: #d9dee8; }
.board tbody tr:nth-child(3) .medal { background: #ff9b3d; }
.board td.place { text-align: left; width: 1%; }
.empty { padding: 14px 16px; border: 3px dashed var(--line); border-radius: 16px; background: var(--well); }

/* Short headings on a narrow screen; the full words stay for screen readers. */
@media (max-width: 640px) {
  .board .more {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
  }
  .board tbody :is(td, th) { padding: 6px 5px; font-size: 17px; }
  .board tbody td:first-child { padding-left: 5px; }
  .board tbody td:last-child { padding-right: 8px; }
  .board thead th { padding: 0 5px 2px; font-size: 13px; }
  .board { table-layout: auto; }
  .board thead th:nth-child(n) { width: auto; }
  .medal { width: 30px; height: 30px; font-size: 16px; }
}

/* ---------------------------------------------------------------- small screens */
@media (max-width: 560px) {
  .moon { display: none; } /* the title fills the top of a phone screen */
}
@media (max-width: 420px) {
  .stage { padding-inline: 14px; }
  .card { padding: 22px 16px 24px; border-radius: 20px; }
  .card::before { border-radius: 20px; transform: rotate(1.4deg) translate(3px, 3px); }
  .card::after { border-radius: 17px; }
}

/* Words read by screen readers but not drawn. */
.vh {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; }
}
