/* Block Party — game styles on top of lib/gk-base.css.
   The kit's primitives (.btn, .screen, .modal, .toast, profile roster) are
   re-themed through the --gk-* custom properties rather than forked.

   Everything below is built from the token block at the top: colour, surfaces,
   space, radius, depth, motion and type. A one-off pixel value in a rule
   further down is a bug in this file, not a decision — the whole point of the
   tokens is that two panels on two different screens cannot drift apart. */

:root {
  /* ---- gamekit overrides -----------------------------------------------
     green, blue and danger used to be overridden here because gk-base's own
     button colours carried white lettering at 2.22:1 / 3.01:1 / 3.69:1.
     gamekit 1.9.2 fixed that in the kit and ships the very values this file
     was using, so the overrides are gone: the kit is the one place those
     numbers live now.

     Grey stays. The kit's #616675 is a neutral grey (5.72:1 on white); this
     one is the same grey pulled toward the app's purple, and measures
     6.56:1, so it clears the bar and belongs to Block Party's look. */
  --gk-grey:   #5d5a78;  --gk-grey-sh:   #3f3d55;
  /* Accent buttons carry ink, not white — 1.80:1 against white on this
     amber, 8.98:1 against the ink below. The kit now does this by default
     (--gk-btn-ink); these two are Block Party's own amber and purple. */
  --gk-accent: #ffb13b;  --gk-accent-sh: #c77e1a;
  --gk-ink:    #241748;
  --gk-card:   #fdf7ff;

  /* ---- colour ---------------------------------------------------------- */
  --bp-night:  #241847;      /* the app's ground colour */
  --bp-deep:   #1b1136;      /* behind the HUD, under the board */
  --bp-room:   #543ba0;      /* the mid purple the splash is built on */
  --bp-lilac:  #7a5fd0;
  --bp-ink:    #241748;      /* text on light surfaces */
  --bp-bone:   #f6f0ff;      /* text on dark surfaces */
  --bp-bone-2: rgba(246,240,255,.78);
  --bp-bone-3: rgba(246,240,255,.55);
  --bp-gold:   #ffc44d;
  --bp-gold-hi:#ffdb92;
  --bp-mint:   #2ed9c3;
  --bp-pink:   #ff5c8a;
  /* On the white results sheet. The old #8a76c9 measured 3.81:1 — just inside
     the bar for the 20px bold line it sat on, but one size change away from
     failing. This measures 5.67:1 and is safe at any size. */
  --bp-plum:   #6a55ad;

  /* ---- surfaces -------------------------------------------------------- */
  --bp-s1:   rgba(255,255,255,.075);
  --bp-s2:   rgba(255,255,255,.13);
  --bp-s3:   rgba(255,255,255,.20);
  --bp-line: rgba(255,255,255,.13);

  /* ---- space ----------------------------------------------------------- */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-5: 22px; --sp-6: 30px;

  /* ---- radius ---------------------------------------------------------- */
  --r-1: 9px; --r-2: 13px; --r-3: 17px; --r-4: 22px; --r-pill: 999px;

  /* ---- depth ----------------------------------------------------------- */
  --sh-1: 0 2px 7px rgba(10,4,30,.30);
  --sh-2: 0 7px 20px rgba(10,4,30,.36);
  --sh-3: 0 18px 44px rgba(10,4,30,.55);
  --sh-in: inset 0 1px 0 rgba(255,255,255,.11);

  /* ---- motion ---------------------------------------------------------- */
  --t-fast: 110ms; --t-mid: 210ms; --t-slow: 420ms;
  --ease:     cubic-bezier(.22,.68,.36,1);
  --ease-pop: cubic-bezier(.34,1.5,.64,1);

  /* ---- type ------------------------------------------------------------ */
  --fs-hero: clamp(38px, 12vw, 62px);
  --fs-title: 26px;
  --fs-h2: 21px;
  --fs-body: 14px;
  --fs-small: 12.5px;
}

/* Paint the ROOT, not just body: with viewport-fit=cover iOS extends the visual
   viewport past height:100% in standalone, and a body-only background leaves a
   pale strip behind the home indicator. */
html, body {
  margin: 0; height: 100%; overflow: hidden;
  color: var(--bp-bone);
  font-family: 'Baloo 2', 'Comic Sans MS', system-ui, -apple-system, sans-serif;
  user-select: none; -webkit-user-select: none; touch-action: none;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: none;
  background: var(--bp-night);
}
.screen.opaque {
  background:
    radial-gradient(120% 78% at 50% -12%, var(--bp-lilac) 0%, transparent 62%),
    radial-gradient(90% 60% at 92% 104%, #3d2a75 0%, transparent 64%),
    linear-gradient(180deg, var(--bp-room) 0%, var(--bp-night) 78%);
  background-color: var(--bp-night);   /* AFTER the shorthand, or it is a no-op */
}

/* -------------------------------- typography ------------------------------ */
h1.title { font-weight: 800; letter-spacing: .4px; }

/* --------------------------------- buttons -------------------------------- */
/* One button system, five states. gk-base supplies the fill and the 3D lip;
   everything that makes it feel touchable is here. */
.btn {
  font-family: inherit; font-weight: 800; letter-spacing: .2px;
  border-radius: var(--r-3);
  transition: transform var(--t-fast) var(--ease),
              box-shadow var(--t-fast) var(--ease),
              filter var(--t-fast) var(--ease);
}
/* Hover only where there is a real pointer — a phone that emulates it leaves
   the button stuck in its hover state after a tap, which looks like a bug. */
@media (hover: hover) and (pointer: fine) {
  .btn:hover:not(:disabled) { transform: translateY(-1px); filter: brightness(1.08); }
  .iconbtn:hover:not(:disabled) { filter: brightness(1.06); }
  .profile-card:hover { background: var(--bp-s2); }
}
.btn:active:not(:disabled) { transform: translateY(4px); box-shadow: 0 2px 0 rgba(0,0,0,.34); }
.btn:disabled { filter: grayscale(.55) brightness(.82); }
.btn:focus-visible, .iconbtn:focus-visible, .profile-card:focus-visible,
.avatar-choice:focus-visible, .pin-key:focus-visible {
  outline: 3px solid var(--bp-gold); outline-offset: 3px;
}
/* 44px minimum: the hands using this are four and seven years old. gk-base's
   .iconbtn is 46px at coarse pointers but only 40 on a desktop pointer. */
.iconbtn { min-width: 44px; min-height: 44px; border-radius: var(--r-2);
           transition: filter var(--t-fast) var(--ease), transform var(--t-fast) var(--ease); }
.iconbtn:active { transform: scale(.94); }

/* --------------------------------- splash --------------------------------- */
/* The title screen's own little party, painted by Render.paintHero with the
   same block painter the game uses — so the first thing you see is literally
   the thing you are about to play with, not a row of platform emoji that came
   out square on one device and rounded on another. */
.hero-wrap { width: min(320px, 84vw); height: min(132px, 22vh); margin: var(--sp-1) 0 var(--sp-2); }
#hero { width: 100%; height: 100%; display: block; }
.logo {
  font-size: var(--fs-hero); line-height: .96; font-weight: 800;
  color: var(--bp-gold);
  text-shadow: 0 4px 0 #a6701a, 0 8px 0 rgba(12,4,34,.45);
  margin: 0 0 var(--sp-1); letter-spacing: 1px;
}
.logo span { display: block; color: var(--bp-mint); text-shadow: 0 4px 0 #17836f, 0 8px 0 rgba(12,4,34,.45); }
.subtitle { color: var(--bp-bone); font-size: 16.5px; margin: 0 0 var(--sp-3); }
.sync-line { opacity: .62; font-size: 13px; margin-top: var(--sp-3); }

/* ------------------------------- game screen ------------------------------ */
/* No `display` here: gk-base already does .screen{display:none} +
   .screen.active{display:flex}, and an ID selector outranks both — setting it
   would pin this screen visible forever, on top of everything else. */
#screen-game { padding: 0; touch-action: none; overflow: hidden; }
#screen-game .topbar {
  padding-top: calc(10px + env(safe-area-inset-top));
  max-width: 620px;                 /* a HUD stretched across a monitor reads as a web page */
  background: linear-gradient(180deg, rgba(21,12,44,.55), rgba(21,12,44,0));
  z-index: 2;
}
.hud-score {
  flex: 1; text-align: center;
  font-weight: 800; font-size: 30px; line-height: 1.05;
  font-variant-numeric: tabular-nums;    /* so the number stops jittering as it changes */
  text-shadow: 0 3px 0 rgba(12,4,34,.35);
}
#hud-score { display: inline-block; }    /* transform does nothing on an inline element */
#hud-score.pop { animation: numPop 300ms var(--ease-pop); }
@keyframes numPop {
  0% { transform: scale(1); } 42% { transform: scale(1.22); } 100% { transform: scale(1); }
}
.hud-best {
  display: block; margin-top: -2px;
  font-size: var(--fs-body); font-weight: 700; color: var(--bp-bone-2);
  font-variant-numeric: tabular-nums;
}
#stage { flex: 1; width: 100%; position: relative; --safe-b: env(safe-area-inset-bottom, 0px); }
/* canvas is a replaced element: inset:0 alone does NOT stretch it — without an
   explicit CSS size it displays at its attribute size (W×dpr, so 2-3× too big
   on retina screens). */
#cv { position: absolute; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; }

/* ------------------------- roster + leaderboard --------------------------- */
/* Both are lists sitting on the game's purple, and gk-base gives them white
   cards — the one place the app visibly stopped looking like itself. The light
   SHEETS (name, PIN) stay light on purpose: those match the results sheet. */
.profile-card, .lb-row {
  background: var(--bp-s1); color: var(--bp-bone);
  border: 1px solid var(--bp-line);
  border-radius: var(--r-4);
  box-shadow: var(--sh-1);
  transition: transform var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.profile-card:active { transform: scale(.985); }
/* Two 44px touch targets on the right leave column 2 about 158px on a 375px
   phone, and the meta line wrapped its last number onto a line of its own. */
.profile-card .pmeta {
  color: var(--bp-bone-2); opacity: 1;
  font-size: var(--fs-small); white-space: nowrap;
}
.profile-card .ppin, .profile-card .pdelete { color: var(--bp-bone-2); }
.profile-card.add .pname { color: var(--bp-gold-hi); }
.lb-row { border-radius: var(--r-3); }
.lb-row.me { outline: 3px solid var(--bp-gold); outline-offset: 1px; }
.lb-rank { color: var(--bp-gold-hi); }
.lb-stat { color: var(--bp-bone-2); opacity: 1; }
.lb-empty { color: var(--bp-bone-2); }

/* --------------------------------- sheets --------------------------------- */
.sheet {
  background: var(--gk-card); color: var(--bp-ink);
  border-radius: var(--r-4); box-shadow: var(--sh-3);
  animation: sheetIn var(--t-mid) var(--ease-pop) both;
}
@keyframes sheetIn {
  from { opacity: 0; transform: translateY(14px) scale(.96); }
  to   { opacity: 1; transform: none; }
}

/* ---------------------------- the results sheet --------------------------- */
.res-art { width: min(200px, 58vw); height: min(104px, 17vh); margin: 0 auto var(--sp-1); }
#res-art { width: 100%; height: 100%; display: block; }
#over-title { font-size: var(--fs-title); color: var(--bp-plum); margin: 0 0 2px; }
.over-score {
  font-size: 46px; font-weight: 800; line-height: 1;
  color: var(--bp-ink); margin: 0;
  font-variant-numeric: tabular-nums;
}
.over-score.count { animation: scorePop 460ms var(--ease-pop) both; }
@keyframes scorePop {
  0% { opacity: 0; transform: scale(.6); } 100% { opacity: 1; transform: none; }
}
.over-msg {
  font-size: 16px; font-weight: 700; margin: var(--sp-1) 0 var(--sp-3);
  color: var(--bp-plum);
}
.over-msg b { color: var(--bp-ink); }

/* ---------------------------------- toast --------------------------------- */
/* gk-base pins the toast 24px from the bottom with no width cap, so a combo
   message wrapped into the home-indicator area on a phone. */
.toast {
  bottom: calc(var(--sp-5) + env(safe-area-inset-bottom));
  max-width: min(86vw, 340px); text-align: center; line-height: 1.3;
  background: rgba(26,15,52,.93); border: 1px solid var(--bp-line);
  border-radius: var(--r-3); box-shadow: var(--sh-2);
  font-family: inherit;
  transition: opacity var(--t-mid) var(--ease), transform var(--t-mid) var(--ease);
  transform: translateX(-50%) translateY(10px);
}
.toast.show { transform: translateX(-50%) translateY(0); }

/* -------------------------------- responsive ------------------------------ */
/* A phone held on its side, and the little iPhones: the hero and the title have
   to give up their room first, because the buttons cannot. */
@media (max-height: 620px) {
  .hero-wrap { height: min(96px, 17vh); }
  .logo { font-size: clamp(30px, 8.5vh, 46px); }
  .subtitle { font-size: 14.5px; margin-bottom: var(--sp-2); }
  .res-art { height: min(78px, 13vh); }
  .over-score { font-size: 36px; }
}
@media (orientation: landscape) and (max-height: 460px) {
  .hero-wrap { display: none; }
  .splash-inner { gap: 2px; padding: var(--sp-3); }
  .btn { padding: 12px 20px; font-size: 17px; margin: 5px 0; }
}
/* Tablets and desktops: a little more air, and bigger type where it reads as
   restraint rather than as a zoomed-in phone. */
@media (min-width: 700px) {
  :root { --fs-body: 15px; --fs-small: 13px; }
  .hero-wrap { width: 360px; height: 150px; }
  .hud-score { font-size: 34px; }
}

/* ----------------------------- reduced motion ----------------------------- */
/* Everything on the canvas is gated on Art.motion in js/art.js; this is the
   same promise for the DOM. Focus rings and colour state changes stay — they
   are information, not decoration. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
}
