:root {
  --bg: #f4f6f9;
  --ink: #1b2430;
  --muted: #6b7786;
  --blue: #1e70d8;
  --line: #d8dde5;
  --panel: #ffffff;
}
@media (prefers-color-scheme: dark) {
  :root { --bg:#12161b; --ink:#e8edf4; --muted:#8b97a7; --line:#2a323d; --panel:#1a2029; }
}
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  display: flex; align-items: center; justify-content: center;
  padding: 24px 16px;
}
.shell { width: 100%; max-width: 1040px; }

.err { display: flex; gap: 20px; align-items: center; margin-bottom: 22px; }
.err__code {
  font: 700 46px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--blue); letter-spacing: -2px;
  padding-right: 20px; border-right: 2px solid var(--line);
}
.err__text h1 { margin: 0 0 2px; font-size: 21px; font-weight: 650; letter-spacing: -0.2px; }
.err__text p { margin: 0; color: var(--muted); font-size: 14px; }

.stage {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 10px;
  position: relative;
  box-shadow: 0 1px 2px rgba(0,0,0,.05), 0 12px 32px -18px rgba(0,0,0,.35);
}
canvas {
  display: block; width: 100%; height: auto;
  image-rendering: pixelated;
  border-radius: 8px;
  touch-action: manipulation;
}
.hint {
  position: absolute; left: 0; right: 0; bottom: 18px;
  text-align: center; color: var(--muted); font-size: 13px;
  pointer-events: none; transition: opacity .25s;
}
.hint.is-hidden { opacity: 0; }

.legend {
  margin-top: 14px; display: flex; flex-wrap: wrap; gap: 8px 22px;
  color: var(--muted); font-size: 12.5px;
}
.legend em { color: var(--blue); font-style: normal; font-weight: 600; }
kbd {
  font: 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
  border: 1px solid var(--line); border-bottom-width: 2px;
  border-radius: 4px; padding: 3px 5px; background: var(--panel); color: var(--ink);
}

@media (max-width: 560px) {
  .err { gap: 14px; }
  .err__code { font-size: 34px; padding-right: 14px; }
}

/* ------------------------------------------------------------ name gate */

/* Over the page, not inside the stage: on a phone the stage is shorter than
   the card, and an ask that hangs out of its own box reads as a second thing
   broken. The share card is laid out the same way. */
.gate {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 24px 16px;
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(3px);
  z-index: 9;
}
.gate.is-hidden { display: none; }
.gate__card {
  width: min(360px, 100%);
  max-height: 100%;
  overflow: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 22px 22px 18px;
  text-align: center;
  box-shadow: 0 18px 40px -22px rgba(0,0,0,.5);
}
.gate__label { display: block; font-size: 17px; font-weight: 650; letter-spacing: -0.2px; }
.gate__sub { margin: 4px 0 14px; color: var(--muted); font-size: 13px; }
.gate__label--sub { margin-top: 12px; font-size: 13px; font-weight: 600; color: var(--muted); }
.gate__input {
  width: 100%; padding: 9px 11px;
  font: 15px ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--ink); background: var(--bg);
  border: 1px solid var(--line); border-radius: 8px;
}
.gate__input:focus { outline: 2px solid var(--blue); outline-offset: 1px; border-color: var(--blue); }
.gate__go {
  width: 100%; margin-top: 10px; padding: 9px 12px;
  font: 600 14px/1.2 inherit; color: #fff; background: var(--blue);
  border: 0; border-radius: 8px; cursor: pointer;
}
.gate__go:hover { filter: brightness(1.07); }
/* The way out of an ask that is now optional: quiet, but not hidden. */
.gate__skip {
  width: 100%; margin-top: 6px; padding: 6px 12px;
  font: 500 12.5px/1.2 inherit; color: var(--muted);
  background: none; border: 0; border-radius: 8px; cursor: pointer;
}
.gate__skip:hover { color: var(--ink); }
.gate__skip.is-hidden { display: none; }
.gate__note { margin: 10px 0 0; min-height: 16px; color: var(--muted); font-size: 12.5px; }

.who.is-hidden { display: none; }
.who em { color: var(--blue); font-style: normal; font-weight: 600; }
.who a { color: var(--muted); margin-left: 6px; }

/* ----------------------------------------------------------- leaderboard */

.board {
  margin-top: 18px;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px 16px 12px;
}
.board__title {
  margin: 0 0 8px; font-size: 12px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .09em; color: var(--muted);
}
.board__list { margin: 0; padding: 0; list-style: none; }
.board__row {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto 62px;
  gap: 10px; align-items: baseline;
  padding: 5px 0;
  border-top: 1px solid var(--line);
}
.board__row:first-child { border-top: 0; }
.board__row.is-me { color: var(--blue); font-weight: 600; }

/* The top three carry their medal on the rank, not on the whole row: a gold
   row would out-shout the score next to it, and the board is read by score. */
.board__row.is-gold   .board__rank { color: #d4a017; }
.board__row.is-silver .board__rank { color: #9aa4b0; }
.board__row.is-bronze .board__rank { color: #b5713a; }
.board__row.is-gold   .board__rank,
.board__row.is-silver .board__rank,
.board__row.is-bronze .board__rank { font-weight: 700; }
.board__row.is-gold   { background: linear-gradient(90deg, rgba(212,160,23,.12), transparent 62%); }
.board__row.is-silver { background: linear-gradient(90deg, rgba(154,164,176,.12), transparent 62%); }
.board__row.is-bronze { background: linear-gradient(90deg, rgba(181,113,58,.12), transparent 62%); }
.board__rank, .board__score {
  font: 13px ui-monospace, SFMono-Regular, Menlo, monospace;
}
.board__rank { color: var(--muted); }
.board__row.is-me .board__rank { color: inherit; }
.board__name { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.board__org { color: var(--muted); font-size: 12.5px; font-weight: 400; }
.board__org::before { content: "· "; }
.board__row.is-me .board__org { color: inherit; opacity: .8; }
.board__tier { font-size: 12px; color: var(--muted); }
.board__score { text-align: right; }
.board__empty, .board__note { color: var(--muted); font-size: 13px; }
.board__note { margin: 8px 0 0; min-height: 17px; }

/* ------------------------------------------------------------- share card */

/* The call to action sits where the hint does — by the time a run has ended
   the hint is gone, and that strip is the one place on the stage the game
   over band does not cover. */
/* The canvas has already said the score is a best, so the button only has to
   say what it does. It is also the one piece of page chrome that sits over the
   canvas, which is white in day mode and white again under night mode's
   inverted sky — hence the filled pill rather than text in the page's ink. */
.cta {
  position: absolute; left: 0; right: 0; bottom: 14px;
  display: flex; justify-content: center;
}
.cta.is-hidden { display: none; }
.cta__go {
  padding: 7px 16px;
  font: 600 13px/1.2 inherit; color: #fff; background: var(--blue);
  border: 0; border-radius: 999px; cursor: pointer;
}
.cta__go:hover { filter: brightness(1.07); }

/* Over the page rather than inside the stage, as the name gate is: the card is
   a 1200x630 picture with text and buttons under it, which is taller than the
   stage however narrow it is made. */
.share {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 24px 16px;
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(3px);
  z-index: 10;
}
.share.is-hidden { display: none; }
.share__card {
  position: relative;
  width: min(520px, 100%);
  max-height: 100%;
  overflow: auto;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px;
  text-align: center;
  box-shadow: 0 18px 40px -22px rgba(0,0,0,.5);
}
/* It takes focus when it opens, which is what makes Escape and Tab work from
   the moment it appears — but it is a panel, not a control, so it does not
   draw a focus ring. */
.share__card:focus { outline: none; }
/* The card is drawn at 1200x630 and only ever shown scaled down, so the
   preview is the shared image itself rather than a description of it. */
.share__preview {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line); border-radius: 8px;
  background: #fff;
}
.share__text {
  margin: 12px 0 0; padding: 8px 10px;
  text-align: left; font-size: 12.5px; line-height: 1.45;
  color: var(--muted); background: var(--bg);
  border: 1px solid var(--line); border-radius: 8px;
  word-break: break-word;
}
.share__actions { display: flex; gap: 8px; margin-top: 10px; }
.share__go, .share__alt {
  flex: 1; padding: 9px 12px;
  font: 600 13px/1.2 inherit; border-radius: 8px; cursor: pointer;
}
.share__go { color: #fff; background: var(--blue); border: 0; }
.share__go:hover { filter: brightness(1.07); }
.share__go.is-hidden, .share__alt.is-hidden, .share__preview.is-hidden { display: none; }
.share__alt {
  color: var(--ink); background: var(--panel);
  border: 1px solid var(--line);
}
.share__alt:hover { border-color: var(--blue); color: var(--blue); }
/* The networks: text labels rather than borrowed logos, in one wrapping row so
   a fifth one later costs nothing. */
.share__social {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 10px;
}
.share__net {
  flex: 1 1 auto; min-width: 88px;
  padding: 8px 10px;
  font: 600 13px/1.2 inherit; text-align: center; text-decoration: none;
  color: var(--ink); background: var(--panel);
  border: 1px solid var(--line); border-radius: 8px;
  cursor: pointer;
}
.share__net:hover { border-color: var(--blue); color: var(--blue); }
.share__hint {
  margin: 8px 0 0; text-align: left;
  color: var(--muted); font-size: 12px; line-height: 1.4;
}
.share__hint em { font-style: normal; font-weight: 600; }
.share__note { margin: 8px 0 0; min-height: 16px; color: var(--muted); font-size: 12.5px; }
/* Inside the card, not hanging off its corner: the card scrolls on a short
   window, and anything outside it would be clipped away. */
.share__close {
  position: absolute; top: 9px; right: 9px;
  width: 28px; height: 28px; padding: 0;
  font: 16px/1 inherit; color: var(--muted);
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 50%; cursor: pointer;
}
.share__close:hover { color: var(--ink); }

@media (max-width: 560px) {
  .share__card { padding: 12px; }
  .share__actions { flex-wrap: wrap; }
  /* Where Web Share exists — which is most phones — it is the whole answer,
     so it gets a row of its own and the two-step fallback sits under it. */
  .share__go { flex-basis: 100%; }
  /* Four networks across a phone leave three on one row and one stranded on
     the next, so they pair off instead. */
  .share__net { flex-basis: calc(50% - 4px); }
}
