/* game-kit shared shell styles — neutral, readable on any dark game background.
   Tint the share hover per game by setting --gamekit-accent on the share container. */
.gamekit-nav { position: fixed; top: 8px; left: 10px; z-index: 80; display: flex; gap: 8px; }
.gamekit-back { font: 600 12px/1 ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace; letter-spacing: 1px;
  color: #fff; text-decoration: none; background: rgba(6, 10, 16, 0.92); border: 1px solid rgba(159, 232, 255, 0.22);
  border-radius: 6px; padding: 7px 11px; cursor: pointer; display: inline-flex; align-items: center; justify-content: center;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
  -webkit-user-drag: none; user-select: none; -webkit-user-select: none; touch-action: manipulation;
  transition: border-color .12s, color .12s, box-shadow .12s; }
.gamekit-back:hover { border-color: #9fe8ff; color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 0 0 1px rgba(159, 232, 255, 0.5), 0 0 16px -3px rgba(159, 232, 255, 0.7); }
/* home button: a home glyph + "Komyo" (no forward chevron — it goes UP to the site, not forward) */
.gamekit-home .gamekit-home-ico { width: 15px; height: 15px; flex: none; display: block; }
.gamekit-home .gamekit-home-label { margin-left: 6px; }
/* The left nav collapses to just the home glyph ONLY when it would actually overlap the right
   sound/pause cluster — game-kit.js measures the two and toggles .gamekit-nav-tight (no hardcoded
   breakpoint, so portrait phones with room keep the full "Komyo" label). */
.gamekit-nav-tight .gamekit-home-label { display: none; }
.gamekit-nav-tight .gamekit-back { padding: 6px 8px; font-size: 11px; letter-spacing: .5px; }

/* top-right sound menu (+ optional reset-scores) */
.gamekit-audio { position: fixed; top: 8px; right: 10px; z-index: 80; display: flex; flex-direction: row; align-items: flex-start; gap: 6px; }
.gamekit-au-btn { font-size: 14px; line-height: 0; width: 38px; height: 34px; cursor: pointer; color: #fff;
  background: rgba(6, 10, 16, 0.92); border: 1px solid rgba(159, 232, 255, 0.22); border-radius: 6px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08); display: inline-flex; align-items: center; justify-content: center;
  transition: border-color .12s, box-shadow .12s; }
.gamekit-au-btn:hover { border-color: #9fe8ff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 0 0 1px rgba(159, 232, 255, 0.5), 0 0 16px -3px rgba(159, 232, 255, 0.7); }
.gamekit-au-panel { display: none; position: absolute; top: 42px; right: 0; flex-direction: column; gap: 10px; min-width: 178px; padding: 12px;
  background: rgba(8, 12, 20, 0.92); border: 1px solid rgba(255, 255, 255, 0.22); border-radius: 10px;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); }
.gamekit-au-panel.open { display: flex; }
.gamekit-au-row { display: flex; align-items: center; gap: 10px; }
.gamekit-au-toggle { font-size: 15px; line-height: 0; width: 30px; height: 30px; cursor: pointer; flex: 0 0 auto; color: #fff;
  background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 7px; display: inline-flex; align-items: center; justify-content: center; }
.gamekit-au-toggle:hover { border-color: #9fe8ff; }
.gamekit-au-slider { flex: 1; min-width: 92px; accent-color: #9fe8ff; cursor: pointer; }
.gamekit-au-pausebtn { font-size: 13px; color: #9fe8ff; }
/* ☰ menu panel: version/update status + refresh + embed + reset */
.gamekit-au-morebtn { font-size: 15px; }
.gamekit-more-panel { min-width: 224px; gap: 8px; }
.gamekit-more-ver { font: 500 11px/1.5 ui-monospace, "SFMono-Regular", Menlo, monospace; color: #cfe3f5;
  white-space: nowrap; padding-bottom: 6px; border-bottom: 1px solid rgba(255, 255, 255, 0.14); }
.gamekit-more-item { font: 600 12px/1 system-ui, sans-serif; letter-spacing: .5px; text-align: left; color: #fff; cursor: pointer;
  background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.2); border-radius: 8px; padding: 10px 12px; }
.gamekit-more-item:hover { border-color: #9fe8ff; }
.gamekit-more-item:disabled { opacity: .6; cursor: default; }

/* ---- language picker: current-flag trigger + themed grid overlay ---- */
.gk-langflag { display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: 1.8em; vertical-align: -0.3em; }
.gk-langflag svg { display: block; width: 100%; height: auto; border-radius: 3px; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.28); }
.gamekit-langbtn { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.gamekit-more-lang { width: 100%; justify-content: flex-start; }
.gamekit-more-lang .gk-lang-lbl { font: inherit; }

.gamekit-langmenu { position: fixed; inset: 0; z-index: 9300; display: flex; align-items: center; justify-content: center; padding: 18px;
  background: var(--gkm-overlay, rgba(5, 8, 13, 0.72)); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.gamekit-langmenu .gklang-box { position: relative; width: min(360px, 100%); box-sizing: border-box;
  background: var(--gkm-bg, rgba(16, 22, 34, 0.98)); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.18));
  border-radius: var(--gkm-radius, 16px); padding: 24px 22px; box-shadow: var(--gkm-shadow, 0 20px 60px rgba(0, 0, 0, 0.6));
  color: var(--gkm-text, #eef2f8); font-family: var(--gkm-font, ui-monospace, "SFMono-Regular", Menlo, monospace); }
.gamekit-langmenu h3 { margin: 0 0 16px; font-size: 17px; letter-spacing: 2px; text-align: center;
  color: var(--gkm-title, var(--gkm-text, #eaf3ff)); text-shadow: var(--gkm-glow, none); }
.gamekit-langmenu .gklang-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
.gamekit-langmenu .gklang-cell { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 7px; padding: 13px 6px; border-radius: 12px;
  cursor: pointer; background: rgba(255, 255, 255, 0.05); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16));
  color: var(--gkm-text, #eef2f8); font-family: inherit; transition: border-color .12s, background .12s; }
.gamekit-langmenu .gklang-cell:hover { border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-langmenu .gklang-cell.selected { border-color: var(--gkm-accent, #9fe8ff); background: var(--gkm-accent-soft, rgba(159, 232, 255, 0.16)); box-shadow: var(--gkm-glow, none); }
.gamekit-langmenu .gklang-flag { width: 46px; line-height: 0; }
.gamekit-langmenu .gklang-flag svg { display: block; width: 100%; height: auto; border-radius: 4px; box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.28); }
.gamekit-langmenu .gklang-name { font-size: 11px; letter-spacing: .5px; }
/* not-yet-translated languages: dimmed, desaturated flag, non-interactive, "soon" pill */
.gamekit-langmenu .gklang-cell.soon { cursor: not-allowed; opacity: .5; }
.gamekit-langmenu .gklang-cell.soon:hover { border-color: var(--gkm-border, rgba(255, 255, 255, 0.16)); }
.gamekit-langmenu .gklang-cell.soon .gklang-flag svg { filter: grayscale(1); }
.gamekit-langmenu .gklang-soon { font-size: 8.5px; letter-spacing: 1px; text-transform: uppercase; font-weight: 700;
  padding: 1px 6px; border-radius: 999px; background: rgba(255, 255, 255, 0.12); color: var(--gkm-text, #eef2f8); opacity: .85; }
.gamekit-langmenu .gklang-x { position: absolute; top: -13px; right: -13px; z-index: 6; width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; padding: 0; cursor: pointer; font-size: 14px; line-height: 1;
  color: #cdd8e8; background: rgba(18, 24, 38, 0.92); border: 1px solid rgba(255, 255, 255, 0.18); box-shadow: 0 3px 12px rgba(0, 0, 0, 0.5); }
.gamekit-langmenu .gklang-x:hover { color: #fff; border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-more-danger { color: #ffb4b4; border-color: rgba(255, 120, 120, 0.4); }
.gamekit-more-danger:hover { color: #fff; background: rgba(255, 90, 90, 0.25); border-color: #ff8a8a; }

/* an open kit overlay owns the scroll — the page behind must not move (overlay panes scroll themselves) */
body:has(.gamekit-menu, .gamekit-confirm, .gamekit-lock, .gamekit-embed, .gamekit-controls, .gamekit-challenges, .gamekit-pause.show, .gkm-picker-modal, .gamekit-langmenu) { overflow: hidden; }
.gamekit-menu .gkm-scroll, .gamekit-menu .gkm-rail, .gamekit-challenges, .gamekit-embed-box, .gamekit-controls, .gkm-picker-list { overscroll-behavior: contain; }

/* universal pause overlay */
.gamekit-pause { position: fixed; inset: 0; z-index: 8500; display: none; align-items: center; justify-content: center;
  background: rgba(6, 9, 15, 0.30); }
.gamekit-pause.show { display: flex; }
.gamekit-pause-box { display: flex; flex-direction: column; align-items: center; gap: 12px; color: #eaf2fb;
  font: 600 19px system-ui, sans-serif; letter-spacing: 2px; }
.gamekit-pause-ico { font-size: 46px; }
.gamekit-pause-resume { font: 600 14px system-ui, sans-serif; letter-spacing: 1px; color: #06121a; background: #9fe8ff;
  border: none; border-radius: 9px; padding: 10px 24px; cursor: pointer; }
.gamekit-pause-resume:hover { background: #c2f0ff; }
/* the shared in-play pause veil — shown under ANY pausing panel/modal (sound, ☰, side stack,
   controls…): light dim + a quiet PAUSED splash; pointer-events none so click-outside-to-close
   still reaches whatever is open */
.gamekit-pauseveil { position: fixed; inset: 0; z-index: 30; display: none; align-items: center; justify-content: center;
  background: rgba(6, 9, 15, 0.30); pointer-events: none; }
.gamekit-pauseveil.show { display: flex; }
.gamekit-pauseveil .gkpv { display: flex; flex-direction: column; align-items: center; gap: 10px;
  color: rgba(234, 242, 251, 0.75); font: 600 19px system-ui, sans-serif; letter-spacing: 2px; }
.gamekit-pauseveil .gkpv-ico { font-size: 46px; }
/* pause MENUS use the same light dim (the frozen game is the backdrop — keep it readable);
   start/end menus keep their theme overlay + per-game art */
.gamekit-menu.gamekit-menu-pause { background: rgba(6, 9, 15, 0.35); -webkit-backdrop-filter: none; backdrop-filter: none; }
/* standard center-top HUD — clears the left nav and the right sound menu; wraps when busy */
.gamekit-hud { position: fixed; top: 8px; left: 50%; transform: translateX(-50%); z-index: 5;
  display: flex; gap: 20px; flex-wrap: wrap; justify-content: center; align-items: center;
  /* width:max-content sizes the pill to its ONE-ROW content (then wraps only if that exceeds
     max-width). Without it, a position:fixed flex-wrap box shrink-to-fits by wrapping early — so a
     4-stat pill needlessly went 2 rows at 50% width. Hugs low-stat pills; no forced stretch. */
  width: max-content; max-width: calc(100vw - 240px); padding: 6px 16px; border-radius: 10px;
  background: rgba(8, 12, 20, 0.6); border: 1px solid rgba(255, 255, 255, 0.16);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
  font: 600 13px/1.1 ui-monospace, "SFMono-Regular", Menlo, monospace; letter-spacing: 1px; color: #fff; pointer-events: none; text-align: center; }
.gamekit-hud .lbl { display: block; font-size: 9px; letter-spacing: 1.5px; opacity: 1; color: #c9d6e8; margin-bottom: 2px; }
/* Overlap fix that does NOT waste vertical space (dropping the pill on a short landscape screen +
   reserving 92px squeezes the board — the earlier mistake):
   - PORTRAIT (tall, narrow): nav + HUD + cluster can't share the top row, so drop the HUD below the
     nav. Plenty of height. hudTop() returns 92 here.
   - LANDSCAPE (short, height is precious): KEEP the HUD on the top row and instead reserve the side
     clusters (~214px each) in its max-width so it never overlaps them; shrink it a touch on short
     screens. hudTop() stays 48 so the board keeps its height. */
@media (orientation: portrait) {
  /* FILL the width and spread the stats so many-stat HUDs (range/frog/etc.) use the horizontal space
     and wrap less vertically — instead of a narrow, tall pill floating with wasted sides. Compact so a
     row fits inside the 92px reserve (top 48 + ~40px pill) and clears the board top. */
  /* Hug content (centered) up to a wide cap: many-stat HUDs (range/frog/aim) get enough width to
     avoid tall wrapping; few-stat HUDs (breakout/2048/glow) stay compact instead of stretched. */
  .gamekit-hud { top: 48px; max-width: 92vw;
    gap: 4px 16px; padding: 4px 14px; font-size: 11.5px; }
  .gamekit-hud .lbl { margin-bottom: 1px; }
}
@media (orientation: landscape) {
  /* Reserve the side clusters (nav left + pause/controls/sound/fullscreen/menu right). The HUD is
     centered, so its border-box must clear a FULL cluster — 380 left the widest pills (busy stat sets +
     6-figure scores, e.g. asteroids) clipping the cluster. 410 guarantees clearance for any content at
     any score; wide pills wrap to a 2nd row instead of spilling. Harmless on desktop (the cap is huge). */
  .gamekit-hud { max-width: calc(100vw - 410px); }
}
@media (orientation: landscape) and (max-height: 560px) {
  .gamekit-hud { gap: 6px 12px; padding: 4px 10px; font-size: 11px; }
  .gamekit-audio { gap: 4px; }
  .gamekit-au-btn { width: 32px; height: 30px; }
}
/* Narrow (portrait phone): the whole top row must fit — the left nav can't hide (no hamburger) and the
   right cluster keeps ALL its buttons, so shrink both. Combined with the measured label-collapse
   (.gamekit-nav-tight), this keeps the row from overlapping down to ~320px wide. */
@media (max-width: 560px) {
  .gamekit-nav { left: 6px; gap: 6px; }
  .gamekit-audio { right: 6px; gap: 4px; }
  .gamekit-au-btn { width: 34px; height: 32px; }
  .gamekit-back { padding: 6px 9px; }
}
@media (max-width: 400px) {
  /* the common Android width is 360px — force-collapse the brand label here (don't rely on the JS
     measurement firing in time on mobile load) and shrink further so the row fits down to ~320px. */
  .gamekit-home-label { display: none; }
  .gamekit-back { padding: 6px 8px; font-size: 11px; letter-spacing: .5px; }
  .gamekit-audio { gap: 3px; }
  .gamekit-au-btn { width: 30px; height: 30px; font-size: 12px; }
}
/* Large displays (2.5K/4K desktop): bump the kit chrome a notch so it doesn't read tiny. A full
   10-foot / TV experience (bigger focus targets, D-pad focus nav, safe-area margins) is a future
   a11y initiative — this is just a proportional nudge. */
@media (min-width: 1900px) and (min-height: 1000px) {
  .gamekit-au-btn { width: 46px; height: 42px; font-size: 17px; }
  .gamekit-hud { font-size: 16px; }
  .gamekit-back { font-size: 15px; padding: 8px 14px; }
  .gamekit-home-label { font-size: 15px; }
}

/* in-page confirm dialog (reset scores / leave-run) — themed via the same --gkm-* vars as the menu,
   so a game's confirm matches its menu; neutral kit palette when no theme is passed */
.gamekit-confirm { position: fixed; inset: 0; z-index: 9600; display: flex; align-items: center; justify-content: center;
  background: var(--gkm-overlay, rgba(5, 8, 13, 0.66)); }
.gamekit-confirm-box { background: var(--gkm-bg, rgba(16, 22, 34, 0.98)); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.2));
  border-radius: var(--gkm-radius, 14px); padding: 20px 22px;
  max-width: min(340px, calc(100vw - 32px)); text-align: center; box-shadow: var(--gkm-shadow, 0 20px 60px rgba(0, 0, 0, 0.6));
  color: var(--gkm-text, #eef2f8); font-family: var(--gkm-font, ui-monospace, "SFMono-Regular", Menlo, monospace); }
.gamekit-confirm-box p { margin: 0 0 16px; font-size: 14px; line-height: 1.5; }
.gamekit-confirm-btns { display: flex; gap: 10px; justify-content: center; }
.gamekit-confirm-btns button { font: 600 12px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: 1px; cursor: pointer; padding: 9px 16px; border-radius: 9px;
  border: 1px solid rgba(255, 255, 255, 0.25); background: rgba(255, 255, 255, 0.06); color: var(--gkm-text, #eef2f8); }
.gamekit-confirm-btns button:hover { border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-cf-yes { background: rgba(255, 90, 90, 0.2) !important; border-color: #ff8a8a !important; color: #fff !important; }
/* hold-to-confirm: a red fill sweeps the button while held (--gk-hold set by the kit) */
.gamekit-cf-yes.gkm-cf-hold { background-image: linear-gradient(90deg, rgba(255, 90, 90, 0.75), rgba(255, 90, 90, 0.75)) !important;
  background-size: var(--gk-hold, 0%) 100% !important; background-repeat: no-repeat !important; touch-action: none; }
.gamekit-confirm-btns button.gkm-cf-focus { outline: 2px solid var(--gkm-accent, #9fe8ff); outline-offset: 2px; }
.gamekit-confirm-btns button.gamekit-cf-yes.gkm-cf-focus { outline-color: #ff8a8a; } /* destructive button: red focus ring, never the theme accent */
/* parental-lock PIN pad — same theming contract as the confirm dialog */
.gamekit-lock { position: fixed; inset: 0; z-index: 9600; display: flex; align-items: center; justify-content: center;
  background: var(--gkm-overlay, rgba(5, 8, 13, 0.66)); }
.gamekit-lock-box { position: relative; background: var(--gkm-bg, rgba(16, 22, 34, 0.98)); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.2));
  border-radius: var(--gkm-radius, 14px); padding: 16px 20px;
  width: min(300px, calc(100vw - 32px)); max-height: calc(100vh - 24px); overflow: auto; text-align: center;
  box-shadow: var(--gkm-shadow, 0 20px 60px rgba(0, 0, 0, 0.6));
  color: var(--gkm-text, #eef2f8); font-family: var(--gkm-font, ui-monospace, "SFMono-Regular", Menlo, monospace); }
.gamekit-lock-box h3 { margin: 0 0 6px; font-size: 15px; }
/* always rendered (even empty) with a reserved height — every pad variant (enter / choose /
   repeat) keeps its numpad at the SAME position, so rapid re-typing never mis-hits a moved key */
.gamekit-lock-hint { margin: 0 0 4px; font-size: 11.5px; line-height: 1.4; opacity: 0.8; min-height: 32px; }
.gamekit-lock-dots { display: flex; gap: 12px; justify-content: center; margin: 8px 0 4px; }
.gamekit-lock-dot { width: 13px; height: 13px; border-radius: 50%; border: 2px solid var(--gkm-accent, #9fe8ff); opacity: 0.45; }
.gamekit-lock-dot.on { background: var(--gkm-accent, #9fe8ff); opacity: 1; }
.gamekit-lock-status { min-height: 16px; font-size: 11.5px; margin: 2px 0 4px; opacity: 0.9; }
.gamekit-lock-status.err { color: #ff8a8a; }
.gamekit-lock-pad { display: grid; grid-template-columns: repeat(3, minmax(56px, 64px)); gap: 8px; justify-content: center; margin: 4px 0 10px; }
.gamekit-lock-pad button { font: 600 17px/1 var(--gkm-font, ui-monospace, monospace); padding: 11px 0; border-radius: 10px; cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.25); background: rgba(255, 255, 255, 0.06); color: var(--gkm-text, #eef2f8); touch-action: manipulation; }
.gamekit-lock-pad button:hover { border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-lock-pad button:disabled { opacity: 0.35; cursor: default; }
.gamekit-lock-shake { animation: gk-lock-shake 0.3s; }
@keyframes gk-lock-shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }
.gamekit-lock-row { display: flex; gap: 14px; justify-content: center; }
.gamekit-lock-cancel, .gamekit-lock-forgot { font: 600 11px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: 0.5px; cursor: pointer;
  padding: 7px 10px; border: 0; background: none; color: var(--gkm-text, #eef2f8); opacity: 0.75; text-decoration: underline; }
.gamekit-lock-cancel:hover, .gamekit-lock-forgot:hover { opacity: 1; }
/* "Forgot PIN?" tip — a floating bubble over the pad (toggled by the link; typing dismisses it),
   so the modal itself never grows to fit help text */
.gamekit-lock-tip { position: absolute; left: 12px; right: 12px; bottom: 52px; z-index: 2; text-align: left;
  background: rgba(8, 13, 22, 0.98); border: 1px solid rgba(255, 255, 255, 0.22); border-radius: 10px; padding: 10px 12px;
  font-size: 11px; line-height: 1.45; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55); }
.gamekit-lock-tip p { margin: 0 0 8px; }
.gamekit-lock-supportbtn { display: block; margin: 0 auto; font: 600 11px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: 0.5px; cursor: pointer;
  padding: 8px 12px; border-radius: 9px; border: 1px solid rgba(255, 255, 255, 0.25); background: rgba(255, 255, 255, 0.06); color: var(--gkm-text, #eef2f8); }
.gamekit-lock-supportbtn:hover { border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-sharemenu { width: min(320px, calc(100vw - 32px)); }
.gamekit-sm-preview { display: block; width: 100%; max-height: 45vh; object-fit: contain; border-radius: 10px; margin: 0 0 14px;
  border: 1px solid rgba(255, 255, 255, 0.14); background: #0a121d; }
.gamekit-sm-btns { display: flex; flex-direction: column; gap: 9px; }
.gamekit-sm-btns button { font: 600 13px/1 ui-monospace, monospace; letter-spacing: 0.5px; cursor: pointer; padding: 12px 14px; border-radius: 9px;
  border: 1px solid rgba(255, 255, 255, 0.25); background: rgba(255, 255, 255, 0.06); color: #eef2f8; }
.gamekit-sm-btns button:hover { border-color: #9fe8ff; }
.gamekit-sm-x { opacity: 0.7; }

/* shared menu engine (gamekit.menu.show) — ONE structure, per-game look via --gkm-* custom props.
   A game themes these in its own CSS (e.g. `.gamekit-menu{--gkm-accent:#ff7ab6;--gkm-glow:...}`) or
   passes a `theme` to menu.show(); everything below falls back to the neutral kit palette. */
.gamekit-menu { position: fixed; inset: 0; z-index: 60; display: flex; align-items: center; justify-content: center; padding: 60px 16px 24px;
  background: var(--gkm-overlay, rgba(6, 9, 15, 0.82)); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.gamekit-menu .gkm-box { width: min(420px, 100%); max-height: calc(100vh - 84px); display: flex; flex-direction: column; overflow: hidden; box-sizing: border-box;
  background: var(--gkm-bg, rgba(14, 20, 32, 0.96)); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16));
  border-radius: var(--gkm-radius, 16px); padding: 24px 22px; box-shadow: var(--gkm-shadow, 0 20px 60px rgba(0, 0, 0, 0.6));
  color: var(--gkm-text, #eaf2fb); text-align: center; font-family: var(--gkm-font, ui-monospace, "SFMono-Regular", Menlo, monospace);
  --gamekit-accent: var(--gkm-accent, #9fe8ff); }
/* the content between the title and the actions scrolls — so the title + the big Play stay pinned/visible */
.gamekit-menu .gkm-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; display: flex; flex-direction: column; }
/* Short screens (landscape phones): tighten the section spacing. (The old always-on inset
   "scroll cue" shadow was removed — menus no longer scroll, so it only showed as a weird dark band,
   glaring on light themes like Meadow Flyer's Day.) */
@media (max-height: 560px) {
  .gamekit-menu .gkm-sec { margin: 12px 0 6px; }
}
.gamekit-menu .gkm-title { flex: 0 0 auto; }
.gamekit-menu .gkm-title { margin: 0 0 14px; font-size: 26px; letter-spacing: 2px; font-weight: 800; text-wrap: balance;
  color: var(--gkm-title, var(--gkm-text, #eaf2fb)); text-shadow: var(--gkm-glow, none); }
.gamekit-menu .gkm-sec { display: flex; align-items: center; justify-content: center; gap: 12px; margin: 20px 0 10px;
  font-size: 11px; font-weight: 700; letter-spacing: 2.5px; opacity: .9; color: var(--gkm-title, var(--gkm-text, #eaf3ff)); }
.gamekit-menu .gkm-sec::before, .gamekit-menu .gkm-sec::after { content: ""; flex: 1; max-width: 64px; height: 1px; background: var(--gkm-accent, #9fe8ff); opacity: .45; }
.gamekit-menu .gkm-row { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.gamekit-menu .gkm-choice { flex: 1 1 auto; min-width: 96px; cursor: pointer; padding: 10px 12px; border-radius: 10px;
  font: 600 13px/1.2 var(--gkm-font, ui-monospace, monospace); letter-spacing: 1px; color: var(--gkm-text, #eaf2fb);
  background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.2); transition: border-color .12s, background .12s, box-shadow .12s; }
.gamekit-menu .gkm-choice .gkm-desc { display: block; margin-top: 4px; font-size: 10px; letter-spacing: .5px; opacity: .6; font-weight: 400; }
.gamekit-menu .gkm-choice.gkm-on { background: var(--gkm-accent-soft, rgba(159, 232, 255, 0.16)); border-color: var(--gkm-accent, #9fe8ff);
  color: var(--gkm-text, #fff); box-shadow: var(--gkm-glow, none); }
.gamekit-menu .gkm-choice:hover { border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-choice.gkm-focus, .gamekit-menu .gkm-action.gkm-focus { outline: 2px solid var(--gkm-accent, #9fe8ff); outline-offset: 2px; }
.gamekit-menu .gkm-hint { margin: 14px 0 0; font-size: 11px; line-height: 1.5; opacity: .7; }
/* actions stack full-width (mobile-first) — the primary Play reads big and is always easy to hit */
.gamekit-menu .gkm-actions { flex: 0 0 auto; display: flex; flex-direction: column; gap: 10px; margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.12)); }
.gamekit-menu .gkm-action { width: 100%; cursor: pointer; padding: 13px 22px; border-radius: 11px; font: 700 14px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: 1px;
  color: var(--gkm-text, #eaf2fb); background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.25); transition: border-color .12s, background .12s, filter .12s; }
.gamekit-menu .gkm-action:hover { border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-action.gkm-disabled { opacity: 0.38; cursor: not-allowed; }
.gamekit-menu .gkm-action.gkm-disabled:hover { border-color: rgba(255, 255, 255, 0.25); }
.gamekit-menu .gkm-action.primary { padding: 16px; font-size: 17px; letter-spacing: 2px; color: var(--gkm-on-accent, #06121a); background: var(--gkm-accent, #9fe8ff); border-color: var(--gkm-accent, #9fe8ff); box-shadow: var(--gkm-glow, none); }
.gamekit-menu .gkm-action.primary:hover { filter: brightness(1.1); }
.gamekit-menu .gkm-action.danger { color: #ffb4b4; border-color: rgba(255, 120, 120, 0.5); background: rgba(255, 90, 90, 0.12); }
.gamekit-menu .gkm-action.danger:hover { color: #fff; background: rgba(255, 90, 90, 0.25); border-color: #ff8a8a; }
.gamekit-menu .gkm-score { font-size: 40px; font-weight: 800; letter-spacing: 1px; margin: 6px 0; color: var(--gkm-title, var(--gkm-text, #eaf2fb)); text-shadow: var(--gkm-glow, none); }
.gamekit-menu .gkm-best { margin: 0 0 6px; font-size: 12px; opacity: .85; }
/* Short screens: gently tighten ONLY the end-screen text/actions so the stats fit without scrolling.
   The share-card image keeps its natural size (in the 2-col split it has its own column; it only
   competes vertically in the single-column case, where the box's own scroll is the last resort). */
@media (max-height: 560px) {
  .gamekit-menu .gkm-score { font-size: 30px; margin: 2px 0; }
  .gamekit-menu .gkm-actions { gap: 7px; margin-top: 8px; padding-top: 8px; }
  .gamekit-menu .gkm-action.primary { padding: 12px; }
}
.gamekit-menu .gkm-best .gkm-new { color: var(--gkm-new, #ffd86b); opacity: 1; }
/* The live pulse: fires mid-run the moment you pass your old best. Sits above the HUD but below the
   menu layer (z 60), never takes pointer events, and is gone in 1.7s — it must not become something
   you wait out. Centred high so it does not cover the middle of the play area. */
.gamekit-bestpulse { position: fixed; left: 50%; top: 22%; transform: translate(-50%, -50%); z-index: 55;
  pointer-events: none; font: 800 clamp(20px, 6vw, 34px)/1 var(--gkm-font, ui-monospace, "SFMono-Regular", Menlo, monospace);
  letter-spacing: 2px; white-space: nowrap; color: var(--gkm-new, #ffd86b);
  text-shadow: 0 0 12px rgba(255, 216, 107, .85), 0 0 34px rgba(255, 216, 107, .45), 0 2px 6px rgba(0, 0, 0, .7);
  animation: gkm-bestpulse 1700ms ease-out both; }
@keyframes gkm-bestpulse {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.55); }
  12%  { opacity: 1; transform: translate(-50%, -50%) scale(1.22); }
  26%  { transform: translate(-50%, -50%) scale(1); }
  72%  { opacity: 1; transform: translate(-50%, -62%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -86%) scale(.96); }
}
@media (prefers-reduced-motion: reduce) {
  .gamekit-bestpulse { animation: gkm-bestpulse-fade 1700ms linear both; }
  @keyframes gkm-bestpulse-fade { 0%, 80% { opacity: 1; } 100% { opacity: 0; } }
}
/* New-best celebration. The burst is position:absolute inside .gkm-box and pointer-events:none, so it
   adds NO height — the menu-fit budget at 360×640 / 640×360 has none to give — and never blocks a tap
   on "Play again" underneath it. .gkm-box is overflow:hidden, which also clips the confetti to the card. */
.gamekit-menu .gkm-burst { position: absolute; left: 0; top: 0; pointer-events: none; z-index: 3; }
.gamekit-menu .gkm-best .gkm-new.gkm-new-pop { display: inline-block; animation: gkm-newpop 620ms cubic-bezier(.2, 1.5, .4, 1) both;
  text-shadow: 0 0 10px var(--gkm-new, #ffd86b); }
@keyframes gkm-newpop {
  0%   { transform: scale(.6) rotate(-4deg); opacity: 0; }
  45%  { transform: scale(1.35) rotate(2deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) { .gamekit-menu .gkm-best .gkm-new.gkm-new-pop { animation: none; } }
.gamekit-menu .gkm-line { margin: 2px 0; font-size: 12px; opacity: .7; }
/* a description line right after a group's button row (e.g. Meadow Flyer's Day/Night) needs breathing room */
.gamekit-menu .gkm-row + .gkm-line { margin-top: 14px; }
.gamekit-menu .gkm-goodrun { margin: 6px 0 2px; font: 700 12px/1.3 var(--gkm-font, ui-monospace, monospace); letter-spacing: .5px; color: var(--gkm-accent, #9fe8ff); text-shadow: var(--gkm-glow, none); }
/* an achievement receipt is the same shape, in the trophy colour (it paid trophies, not a bonus) */
.gamekit-menu .gkm-achline { color: var(--gkm-new, #ffd166); margin: 3px 0 0; }
.gamekit-menu .gkm-share-host { margin-top: 16px; }
/* a menu with mode cards / a shop / a grid gets a wider box (so the Drydock + level-up picker
   aren't a cramped 2-column column on desktop) + a slightly larger start title */
.gamekit-menu.gkm-wide .gkm-box, .gamekit-menu.gkm-split .gkm-box { width: min(640px, 100%); }
.gamekit-menu-start .gkm-title { font-size: 30px; letter-spacing: 5px; }

/* landscape phones: split menu — the big list (mode cards / thumbnail grid / shop) scrolls on the
   LEFT, and the title + simple selectors/toggles/hint (moved into .gkm-rail by the kit) + actions
   stack in a RIGHT rail, so nothing hides below the fold. Portrait + desktop keep the stacked
   layout (the kit moves the rail content back). */
@media (orientation: landscape) and (max-height: 560px) {
  .gamekit-menu { padding: 32px 12px 6px; }
  .gamekit-menu.gkm-split .gkm-box { width: min(740px, 100%); display: grid;
    grid-template-columns: 1fr minmax(190px, 230px); grid-template-rows: auto 1fr auto;
    grid-template-areas: "big title" "big rail" "big actions"; column-gap: 16px; row-gap: 8px;
    padding: 12px 18px; text-align: left; }
  .gamekit-menu.gkm-split .gkm-title { grid-area: title; margin: 0; font-size: 18px; letter-spacing: 2px; text-align: left; }
  .gamekit-menu.gkm-split .gkm-scroll { grid-area: big; min-height: 0; overflow-x: hidden;
    border-right: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.12)); padding-right: 14px; }
  /* overflow-y:auto silently flips overflow-x from visible→auto, so a vertical scrollbar (or any
     1px graze) spawned a horizontal one — clamp x and let children shrink instead */
  .gamekit-menu.gkm-split .gkm-rail { grid-area: rail; min-height: 0; overflow-y: auto; overflow-x: hidden;
    display: flex; flex-direction: column; gap: 6px; }
  .gamekit-menu.gkm-split .gkm-rail > * { min-width: 0; max-width: 100%; flex-shrink: 0; }
  .gamekit-menu.gkm-split .gkm-actions { grid-area: actions; align-self: end; margin: 0; padding: 0; border-top: none; gap: 7px; }
  /* Landscape phones stack the actions in a short column, so every px of button chrome comes
     straight out of the rail beside it — a second action used to push the rail into scrolling.
     Compact them here (this block only; portrait and desktop keep the full-size buttons). */
  .gamekit-menu.gkm-split .gkm-action { padding: 9px 14px; font-size: 12.5px; letter-spacing: 0.6px; }
  .gamekit-menu.gkm-split .gkm-action.primary { padding: 11px 14px; font-size: 14.5px; letter-spacing: 1.2px; }
  .gamekit-menu.gkm-split .gkm-sec { margin: 0 0 8px; }
  .gamekit-menu.gkm-split .gkm-rail .gkm-sec { margin: 0; }
  .gamekit-menu.gkm-split .gkm-hint { margin: 0; text-align: left; }
  .gamekit-menu.gkm-split .gkm-checkrow { text-align: left; }
  /* compact cards: small preview, drop the sentence AND the chips (the hint carries them) so the
     card list column never scrolls — a card is just preview + name + best on one line (~50px). */
  .gamekit-menu.gkm-split .gkm-cards { gap: 7px; }
  .gamekit-menu.gkm-split .gkm-card { grid-template-columns: 40px 1fr; gap: 10px; padding: 5px 10px; align-items: center; }
  .gamekit-menu.gkm-split .gkm-card-pv { width: 40px; height: 40px; }
  .gamekit-menu.gkm-split .gkm-card-nm { font-size: 12.5px; }
  .gamekit-menu.gkm-split .gkm-card-body { gap: 2px; }
  .gamekit-menu.gkm-split .gkm-card-desc { display: none; }
  .gamekit-menu.gkm-split .gkm-card-mech { display: none; }
  /* Drydock shop (default, many items): natural rows in the LEFT pane, which scrolls when they
     overflow — the old height:100%/1fr rows crushed a long upgrade list into unreadable slivers */
  .gamekit-menu.gkm-split .gkm-shop { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); grid-auto-rows: max-content; margin: 0; }
  /* the level-up picker (cols:3, only a few choices) still fills the pane, no scroll */
  .gamekit-menu.gkm-split .gkm-shop-c3 { grid-template-columns: repeat(3, 1fr); grid-auto-rows: 1fr; height: 100%; align-content: stretch; }
  .gamekit-menu.gkm-split .gkm-shop-c3 .gkm-shop-desc { display: none; } /* rail focdesc carries it */
  .gamekit-menu.gkm-split .gkm-shop-c2 { grid-template-columns: repeat(2, 1fr); }
  /* thumbnail grid auto-fits the pane width (more flyers → more columns, not more scrolling) */
  /* level-select grids: auto-fill lands on 3 columns in the ~317px landscape pane, which adds a
     4th row and overflows. 4 fixed columns fit — both puzzle games needed this identical
     override locally, so it lives here. */
  .gamekit-menu.gkm-split .gkm-grid { grid-template-columns: repeat(4, 1fr); gap: 6px; margin: 0; }
  .gamekit-menu.gkm-split .gkm-gcell { padding: 7px 4px 6px; }
  .gamekit-menu.gkm-split .gkm-gcv { width: 36px; height: auto; }
  .gamekit-menu.gkm-split .gkm-gnm { font-size: 11px; }
  .gamekit-menu.gkm-split .gkm-gsub { font-size: 9.5px; }
  /* rail widgets shrink to rail scale: slim toggle pill, one-line choice rows, tighter slider */
  .gamekit-menu.gkm-split .gkm-checkrow { margin-top: 0; justify-content: flex-start; }
  .gamekit-menu.gkm-split .gkm-check { gap: 8px; padding: 7px 10px; }
  .gamekit-menu.gkm-split .gkm-check-box { width: 16px; height: 16px; }
  .gamekit-menu.gkm-split .gkm-check-box::after { font-size: 11px; }
  .gamekit-menu.gkm-split .gkm-check-txt { font-size: 11.5px; letter-spacing: .5px; }
  .gamekit-menu.gkm-split .gkm-check-txt .cap { font-size: 10.5px; }
  .gamekit-menu.gkm-split .gkm-rail .gkm-row { flex-wrap: nowrap; gap: 6px; }
  .gamekit-menu.gkm-split .gkm-rail .gkm-choice { flex: 1 1 0; min-width: 0; padding: 8px 4px; font-size: 11.5px; letter-spacing: .5px; }
  .gamekit-menu.gkm-split .gkm-rail .gkm-slider { margin: 0; }
  .gamekit-menu.gkm-split .gkm-rail .gkm-sl-hit { padding: 12px 10px 2px; }
  .gamekit-menu.gkm-split .gkm-rail .gkm-sl-thumb { width: 18px; height: 18px; margin: -9px 0 0 -9px; }
  .gamekit-menu.gkm-split .gkm-rail .gkm-sl-tick { width: 7px; height: 7px; margin: -3.5px 0 0 -3.5px; }
  .gamekit-menu.gkm-split .gkm-rail .gkm-sl-label { padding: 5px 2px; font-size: 11px; }
  /* end-screen split: the score card fills the left pane; score + good-run read rail-scale.
     The end rail is a RESULT column (verdict + number + stat lines), not a controls list —
     centered like the portrait end screen; start-menu rails stay left-aligned for scanning */
  .gamekit-menu.gkm-split .gkm-share-host { margin: 0; }
  .gamekit-menu.gkm-split .gkm-rail .gkm-score { font-size: 26px; margin: 0; }
  .gamekit-menu.gkm-split .gkm-rail .gkm-goodrun { margin: 0; font-size: 11px; }
  .gamekit-menu-end.gkm-split .gkm-title, .gamekit-menu-end.gkm-split .gkm-rail { text-align: center; }
}
/* Plain (non-split) menus — mode/difficulty button-row start menus like sudoku / tower-defense — in
   short landscape: the 420px box forces the 4-button DIFFICULTY row to wrap and pushes content below
   a 360px-tall fold. Widen the box to use the landscape width (rows become single-line) and compact
   the vertical rhythm so title + all groups + actions fit without scrolling. (Card/shop/grid menus
   use the .gkm-split two-column layout above instead.) */
@media (orientation: landscape) and (max-height: 560px) {
  .gamekit-menu:not(.gkm-split) .gkm-box { width: min(600px, 100%); max-height: calc(100vh - 48px); padding: 10px 20px; }
  .gamekit-menu:not(.gkm-split) .gkm-title,
  .gamekit-menu-start:not(.gkm-split) .gkm-title { font-size: 19px; letter-spacing: 3px; margin-bottom: 6px; }
  .gamekit-menu:not(.gkm-split) .gkm-sec { margin: 6px 0 4px; }
  .gamekit-menu:not(.gkm-split) .gkm-choice { padding: 6px 12px; }
  .gamekit-menu:not(.gkm-split) .gkm-hint { margin-top: 8px; }
  .gamekit-menu:not(.gkm-split) .gkm-actions { margin-top: 8px; padding-top: 8px; gap: 7px; }
  .gamekit-menu:not(.gkm-split) .gkm-action.primary { padding: 11px; font-size: 15px; }
  /* split rail: let a many-button group WRAP to readable ~2-per-row cells instead of squeezing all
     into slivers (critter-match's Solo/2P/3P/4P/Speedrun broke mid-word in a nowrap rail). */
  .gamekit-menu.gkm-split .gkm-rail .gkm-row { flex-wrap: wrap; }
  .gamekit-menu.gkm-split .gkm-rail .gkm-choice { flex: 1 1 72px; min-width: 72px; }
}

/* ---- mode cards (style:'cards') — preview left, text column right ---- */
.gamekit-menu .gkm-cards { display: flex; flex-direction: column; gap: 10px; text-align: left; }
.gamekit-menu .gkm-card { position: relative; display: grid; grid-template-columns: 92px 1fr; gap: 15px; align-items: center; cursor: pointer;
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16)); border-radius: 14px;
  padding: 11px 14px; transition: border-color .15s, box-shadow .15s, transform .12s; }
.gamekit-menu .gkm-card:hover { border-color: var(--gkm-accent, #9fe8ff); transform: translateY(-1px); }
.gamekit-menu .gkm-card.gkm-on { border-color: var(--gkm-accent, #9fe8ff); box-shadow: 0 0 0 1px var(--gkm-accent, #9fe8ff), var(--gkm-glow, 0 0 26px rgba(159, 232, 255, .26)); }
.gamekit-menu .gkm-card.gkm-focus { outline: 2px solid var(--gkm-accent, #9fe8ff); outline-offset: 2px; }
.gamekit-menu .gkm-card.gkm-locked { opacity: 0.55; cursor: default; }
.gamekit-menu .gkm-card.gkm-locked:hover { border-color: var(--gkm-border, rgba(255, 255, 255, 0.16)); transform: none; }
.gamekit-menu .gkm-card-rm { position: absolute; top: 7px; right: 7px; width: 32px; height: 32px; border-radius: 8px; cursor: pointer;
  font: 14px/1 system-ui, sans-serif; color: #ffb4b4; border: 1px solid rgba(255, 120, 120, 0.4); background: rgba(255, 90, 90, 0.1); }
.gamekit-menu .gkm-card-rm:hover { background: rgba(255, 90, 90, 0.28); }
.gamekit-menu .gkm-card-pv { width: 92px; height: 92px; border-radius: 11px; background: rgba(0, 0, 0, .35); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.14)); display: block; }
.gamekit-menu .gkm-card.gkm-on .gkm-card-pv { box-shadow: inset 0 0 0 1px var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-card-body { min-width: 0; display: flex; flex-direction: column; gap: 7px; }
.gamekit-menu .gkm-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; }
.gamekit-menu .gkm-card-nm { font: 700 18px/1.2 var(--gkm-font, ui-monospace, monospace); letter-spacing: 1px;
  color: var(--gkm-title, var(--gkm-text, #eaf3ff)); display: flex; align-items: center; gap: 9px; transition: color .15s; }
.gamekit-menu .gkm-card.gkm-on .gkm-card-nm { color: var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-tag { font: 700 9px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: 1.5px; padding: 3px 7px; border-radius: 5px;
  color: var(--gkm-accent, #9fe8ff); background: rgba(255, 255, 255, 0.06); border: 1px solid var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-card-best { font: 12px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: .5px; white-space: nowrap; flex: 0 0 auto;
  color: var(--gkm-best, var(--gkm-new, #ffd166)); font-variant-numeric: tabular-nums; }
.gamekit-menu .gkm-card-best .l { color: #93a3b8; font-size: 9px; letter-spacing: 1.5px; margin-right: 6px; }
.gamekit-menu .gkm-card-desc { color: #93a5bd; font: 13.5px/1.5 var(--gkm-font-body, system-ui, sans-serif); }
.gamekit-menu .gkm-card-mech { display: flex; flex-wrap: wrap; gap: 6px; }

/* ---- multi-column cards (group `cols: 2|3`) — halves the height a card group needs.
   Below 420px wide it stays a single column: side-by-side previews get too small, and a
   portrait phone has the height to spare. Everything here is scoped to the opted-in group. */
@media (min-width: 420px) {
  .gamekit-menu .gkm-cards-multi { flex-direction: row; flex-wrap: wrap; }
  .gamekit-menu .gkm-cards-multi > * { flex: 1 1 calc(100% / var(--gkm-cols, 2) - 6px); min-width: 0; }
  /* a half-width head can't fit a mode name AND a 5-digit record on one line (measured: 169px
     of content in 155px) — stack the record so its block is only as wide as the number, and let
     a long name ellipsize rather than push the record out of the card */
  .gamekit-menu .gkm-cards-multi .gkm-card-head { gap: 8px; min-width: 0; align-items: baseline; }
  .gamekit-menu .gkm-cards-multi .gkm-card-nm { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .gamekit-menu .gkm-cards-multi .gkm-card-best { display: flex; flex-direction: column; align-items: flex-end;
    flex: 0 0 auto; white-space: nowrap; font-size: 11px; line-height: 1.15; text-align: right; }
  .gamekit-menu .gkm-cards-multi .gkm-card-best .l { margin: 0; font-size: 8.5px; letter-spacing: 1px; opacity: .55; }
}
/* between the split breakpoint and a tall desktop there's a band (~560–780px high) with no split
   layout and not much height — borrow the split layout's compact card so the CARDS survive */
@media (min-width: 420px) and (max-height: 780px) {
  .gamekit-menu:not(.gkm-split) .gkm-cards-multi { gap: 6px; }
  .gamekit-menu:not(.gkm-split) .gkm-cards-multi .gkm-card { grid-template-columns: 46px 1fr; gap: 9px; padding: 5px 9px; }
  .gamekit-menu:not(.gkm-split) .gkm-cards-multi .gkm-card-pv { width: 46px; height: 46px; }
  .gamekit-menu:not(.gkm-split) .gkm-cards-multi .gkm-card-desc,
  .gamekit-menu:not(.gkm-split) .gkm-cards-multi .gkm-card-mech { display: none; }
}
/* in the split (landscape) layout the head is only ~83px wide — a 5-digit record takes 43 of them
   and a mode name needs 60, so they cannot share a line at all: one each */
@media (max-height: 430px) {
  .gamekit-menu.gkm-split .gkm-cards-multi .gkm-card-head { flex-direction: column; align-items: flex-start; gap: 1px; }
  .gamekit-menu.gkm-split .gkm-cards-multi .gkm-card-best { flex-direction: row; align-items: baseline; gap: 4px;
    text-align: left; font-size: 10px; }
  .gamekit-menu.gkm-split .gkm-cards-multi .gkm-card-nm { font-size: 12px; }
}
.gamekit-menu .gkm-card-mech span { font: 10px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: .4px; color: #9fb2c9;
  background: rgba(255, 255, 255, 0.05); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16)); border-radius: 999px; padding: 3px 9px; }
.gamekit-menu .gkm-card-mech span.hot { color: var(--gkm-new, #ffd166); border-color: rgba(255, 209, 102, .4); background: rgba(255, 209, 102, .08); }
/* Narrow portrait phones: compact the whole menu (title, sections, buttons, actions) so a dense
   menu — 3 option groups + a hint — fits one screen without scrolling. */
@media (max-width: 560px) {
  .gamekit-menu .gkm-box { padding: 14px 18px; }
  .gamekit-menu .gkm-title, .gamekit-menu-start .gkm-title { font-size: 21px; letter-spacing: 3px; margin-bottom: 6px; }
  .gamekit-menu .gkm-sec { margin: 6px 0 4px; }
  .gamekit-menu .gkm-choice { padding: 8px 12px; }
  .gamekit-menu .gkm-hint { margin-top: 7px; }
  .gamekit-menu .gkm-actions { margin-top: 9px; padding-top: 9px; gap: 7px; }
  /* keep Play + secondary actions proportional to the mode/difficulty buttons (not chunky blocks) */
  .gamekit-menu .gkm-action { padding: 10px 18px; font-size: 13px; }
  .gamekit-menu .gkm-action.primary { padding: 11px; font-size: 15px; }
}

/* ---- per-game backdrop art behind a frosted box (cfg.backdrop) ---- */
/* backdrop stays opaque (so the live game canvas never bleeds through); the kit dims it with a
   baked-in scrim in paintBackdrop so it reads as a background rather than a vivid full-opacity scene */
.gamekit-menu .gkm-backdrop { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.gamekit-menu .gkm-box { position: relative; z-index: 1; -webkit-backdrop-filter: blur(9px) saturate(1.08); backdrop-filter: blur(9px) saturate(1.08); }
/* contrast scrim: a tint behind the box CONTENT (above the frosted glass, below text) so any
   backdrop is legible by construction. --gkm-scrim defaults dark (light text); light-text-on-dark
   menus keep it; a light-box menu (e.g. Meadow day, dark text) sets --gkm-scrim to a light tint. */
.gamekit-menu .gkm-box::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; background: var(--gkm-scrim, rgba(8, 12, 20, 0.32)); }
.gamekit-menu .gkm-scroll { overflow-x: hidden; }
/* Room for the selected-chip ring below (`.gkm-choice.gkm-on::after` sits at inset -4px, and an
   absolutely-positioned descendant DOES count toward an ancestor scroller's scrollHeight). Without
   it every menu whose last row holds a selected chip reads as "scrolls +3px" — which games had been
   working around by trimming their own content. Bottom only: scrollHeight never grows upward.
   Scoped with :has() to panes that actually hold chips — card panes highlight with a box-shadow (no
   abspos ring) and 4px there is pure cost that tipped three card menus over the gate. */
.gamekit-menu .gkm-scroll:has(.gkm-choice), .gamekit-menu .gkm-rail:has(.gkm-choice) { padding-bottom: 4px; }

/* selector-button highlight: an outer ring deliberately CUT with a vertical line on both sides
   (clip-path), identical on every button; keyboard focus is a clean inset ring (never clipped) */
.gamekit-menu .gkm-choice { position: relative; }
.gamekit-menu .gkm-choice.gkm-on { box-shadow: none; }
.gamekit-menu .gkm-choice.gkm-focus { outline: none; box-shadow: inset 0 0 0 2px var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-choice.gkm-on::after { content: ""; position: absolute; inset: -4px; border: 1.6px solid var(--gkm-accent, #9fe8ff);
  border-radius: 13px; pointer-events: none; -webkit-clip-path: inset(0 6px); clip-path: inset(0 6px); }
/* a danger action (Quit) focuses in its own red, not the theme accent — avoids e.g. purple-ring-on-red */
.gamekit-menu .gkm-action.danger.gkm-focus { outline-color: #ff8a8a; }

/* ---- segmented slider (style:'slider') — Snake speed, Keep Defender difficulty ---- */
.gamekit-menu .gkm-slider { margin: 4px 2px 2px; }
.gamekit-menu .gkm-sl-hit { padding: 16px 12px 4px; cursor: pointer; touch-action: none; }
.gamekit-menu .gkm-sl-track { position: relative; height: 6px; border-radius: 3px; background: rgba(255, 255, 255, 0.16); }
.gamekit-menu .gkm-sl-fill { position: absolute; left: 0; top: 0; height: 100%; border-radius: 3px; background: var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-sl-tick { position: absolute; top: 50%; width: 9px; height: 9px; margin: -4.5px 0 0 -4.5px; border-radius: 50%; background: rgba(255, 255, 255, 0.32); }
.gamekit-menu .gkm-sl-thumb { position: absolute; top: 50%; width: 26px; height: 26px; margin: -13px 0 0 -13px; border-radius: 50%;
  background: var(--gkm-accent, #9fe8ff); box-shadow: var(--gkm-glow, 0 0 12px rgba(159, 232, 255, .5)); }
.gamekit-menu .gkm-sl-labels { display: flex; justify-content: space-between; margin: 2px 0 0; }
.gamekit-menu .gkm-sl-label { flex: 1; text-align: center; padding: 7px 2px; cursor: pointer; color: #93a5bd;
  font: 600 12.5px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: .5px; }
.gamekit-menu .gkm-sl-label:first-child { text-align: left; } .gamekit-menu .gkm-sl-label:last-child { text-align: right; }
.gamekit-menu .gkm-sl-label.gkm-on { color: var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-sl-label.gkm-focus { color: var(--gkm-text, #eaf3ff); text-decoration: underline; text-underline-offset: 3px; }

/* ---- thumbnail grid (style:'grid') — Meadow Flyer flyer picker ---- */
.gamekit-menu .gkm-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 4px 0 14px; }
.gamekit-menu .gkm-gcell { position: relative; display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 9px 6px 8px; border-radius: 12px; cursor: pointer;
  background: rgba(255, 255, 255, 0.05); border: 1.5px solid var(--gkm-border, rgba(255, 255, 255, 0.14)); transition: border-color .14s, box-shadow .14s; }
.gamekit-menu .gkm-gcell.gkm-on { border-color: var(--gkm-accent, #9fe8ff); background: rgba(255, 255, 255, 0.1); box-shadow: none; }
.gamekit-menu .gkm-gcell.gkm-focus { outline: none; box-shadow: inset 0 0 0 2px var(--gkm-accent, #9fe8ff); }
/* same symmetric cut-highlight ring as the selector buttons (cut on both sides) */
.gamekit-menu .gkm-gcell.gkm-on::after { content: ""; position: absolute; inset: -4px; border: 1.6px solid var(--gkm-accent, #9fe8ff);
  border-radius: 15px; pointer-events: none; -webkit-clip-path: inset(0 6px); clip-path: inset(0 6px); }
.gamekit-menu .gkm-gcell.gkm-locked { opacity: 0.55; cursor: default; }
.gamekit-menu .gkm-gcv { display: block; }
.gamekit-menu .gkm-gnm { font: 600 12px/1 var(--gkm-font-body, system-ui, sans-serif); color: var(--gkm-text, #eaf3ff); }
.gamekit-menu .gkm-gsub { font: 600 10.5px/1 var(--gkm-font-body, system-ui, sans-serif); color: var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-gcell.gkm-locked .gkm-gsub { color: #93a5bd; }

/* ---- action grid (style:'shop') — Asteroids+ level-up picker + between-wave shop ---- */
.gamekit-menu .gkm-banner { margin: 2px 0 4px; font: 800 22px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: 2px;
  color: var(--gkm-new, #ffd166); text-shadow: var(--gkm-glow, none); }
.gamekit-menu .gkm-shop { display: grid; grid-template-columns: repeat(auto-fill, minmax(178px, 1fr)); gap: 8px; margin: 6px 0 12px; text-align: left; }
.gamekit-menu .gkm-shopcard { position: relative; display: flex; flex-direction: column; gap: 5px; cursor: pointer; padding: 11px 13px; border-radius: 12px;
  background: rgba(255, 255, 255, 0.05); border: 1.5px solid var(--gkm-border, rgba(255, 255, 255, 0.14)); transition: border-color .14s, box-shadow .14s, transform .1s; }
.gamekit-menu .gkm-shopcard:hover { border-color: var(--gkm-accent, #9fe8ff); transform: translateY(-1px); }
.gamekit-menu .gkm-shopcard.gkm-focus { outline: none; box-shadow: inset 0 0 0 2px var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-shopcard.gkm-disabled { opacity: 0.42; cursor: not-allowed; }
.gamekit-menu .gkm-shopcard.gkm-disabled:hover { border-color: var(--gkm-border, rgba(255, 255, 255, 0.14)); transform: none; }
.gamekit-menu .gkm-shop-nm { font: 700 14px/1.15 var(--gkm-font, ui-monospace, monospace); letter-spacing: .6px; color: var(--gkm-text, #eaf3ff); }
.gamekit-menu .gkm-shop-desc { font: 11px/1.4 var(--gkm-font-body, system-ui, sans-serif); color: #93a5bd; }
.gamekit-menu .gkm-shop-sub { margin-top: auto; font: 700 11.5px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: .5px;
  color: var(--gkm-accent, #9fe8ff); font-variant-numeric: tabular-nums; }
.gamekit-menu .gkm-shop-sub .cost { color: var(--gkm-new, #ffd166); } .gamekit-menu .gkm-shop-sub .max { color: #6b7a90; }
/* optional per-choice icon (canvas painter) — quick scan without reading */
.gamekit-menu .gkm-shopcard.gkm-has-ic { display: grid; grid-template-columns: 26px 1fr; gap: 4px 10px; align-items: center; }
.gamekit-menu .gkm-shop-ic { grid-row: 1 / span 3; width: 26px; height: 26px; display: block; }
/* cols:3 — the exactly-3 picker shape: 3 across (desktop + landscape), stacked in portrait */
.gamekit-menu .gkm-shop-c3 { grid-template-columns: repeat(3, 1fr); }
/* cols:2 — the exactly-2 grid shape (e.g. a 4-item shop as 2×2 instead of 3+1) */
.gamekit-menu .gkm-shop-c2 { grid-template-columns: repeat(2, 1fr); }
.gamekit-menu .gkm-shop-c3 .gkm-shopcard.gkm-has-ic { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 7px; padding: 14px 10px; }
.gamekit-menu .gkm-shop-c3 .gkm-shop-ic { width: 34px; height: 34px; }
/* focused-choice desc line + BUY/TAKE button — small screens only (desktop cards show their desc) */
.gamekit-menu .gkm-focdesc { display: none; margin: 2px 0 4px; min-height: 1.4em; font: 11px/1.4 var(--gkm-font, ui-monospace, monospace); color: #93a5bd; }
.gamekit-menu .gkm-focdesc b { color: var(--gkm-title, #eaf3ff); font-weight: 700; }
.gamekit-menu .gkm-buybtn { display: none; color: var(--gkm-on-accent, #06121a); background: var(--gkm-new, #ffd166); border-color: var(--gkm-new, #ffd166); font-weight: 800; }
.gamekit-menu .gkm-buybtn:disabled { opacity: .5; cursor: default; }
@media (max-width: 560px), (max-height: 560px) {
  .gamekit-menu .gkm-shopcard { padding: 8px 10px; }
  .gamekit-menu .gkm-shop:not(.gkm-shop-c3) .gkm-shop-desc { display: none; } /* the focdesc line carries it */
  .gamekit-menu .gkm-focdesc { display: block; }
  .gamekit-menu .gkm-buybtn { display: block; }
}
@media (max-width: 560px) { .gamekit-menu .gkm-shop { grid-template-columns: 1fr 1fr; } .gamekit-menu .gkm-shop-c3 { grid-template-columns: 1fr; } }
@media (max-width: 380px) { .gamekit-menu .gkm-shop { grid-template-columns: 1fr; } }

/* ---- map-picker (style:'popup') — Keep Defender ---- */
.gamekit-menu .gkm-picker { width: 100%; display: flex; align-items: center; gap: 10px; text-align: left; cursor: pointer;
  padding: 10px 12px; border-radius: 12px; background: rgba(255, 255, 255, 0.06); border: 1.5px solid var(--gkm-border, rgba(255, 255, 255, 0.2));
  color: var(--gkm-text, #eaf3ff); font: 600 15px/1.2 var(--gkm-font-body, system-ui, sans-serif); }
.gamekit-menu .gkm-picker:hover { border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-picker.gkm-focus { outline: none; box-shadow: inset 0 0 0 2px var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-picker .gkm-picker-cv { border-radius: 6px; flex: 0 0 auto; }
.gamekit-menu .gkm-picker-nm { flex: 1; } .gamekit-menu .gkm-picker-sub { font: 600 11px/1 system-ui; color: #8ea3bd; } .gamekit-menu .gkm-picker-chev { color: var(--gkm-accent, #9fe8ff); }
.gkm-picker-modal { position: fixed; inset: 0; z-index: 9300; display: flex; align-items: center; justify-content: center; padding: 70px 16px 20px;
  background: rgba(4, 7, 12, 0.72); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px); }
.gkm-picker-panel { width: min(580px, 100%); max-height: 100%; display: flex; flex-direction: column; overflow: hidden; border-radius: 16px;
  background: var(--gkm-bg, rgba(14, 20, 32, 0.98)); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.2)); color: var(--gkm-text, #eaf2fb);
  font-family: var(--gkm-font, ui-monospace, monospace); }
.gkm-picker-head { display: flex; align-items: center; justify-content: space-between; padding: 13px 16px; border-bottom: 1px solid rgba(255, 255, 255, 0.12); }
.gkm-picker-head h3 { margin: 0; font: 800 15px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: 1px; color: var(--gkm-title, var(--gkm-text, #eaf3ff)); }
.gkm-picker-x { background: none; border: none; color: #9fb2c8; font-size: 20px; cursor: pointer; line-height: 1; }
.gkm-picker-body { display: grid; grid-template-columns: 1fr 1.2fr; min-height: 0; overflow: hidden; }
.gkm-picker-list { display: flex; flex-direction: column; padding: 7px; gap: 3px; overflow-y: auto; border-right: 1px solid rgba(255, 255, 255, 0.1); }
.gkm-picker-item { display: flex; align-items: center; gap: 9px; padding: 8px; border-radius: 9px; cursor: pointer; font: 600 13.5px/1.1 var(--gkm-font-body, system-ui, sans-serif); color: var(--gkm-text, #eaf3ff); }
.gkm-picker-item:hover, .gkm-picker-item.gkm-hot { background: rgba(255, 255, 255, 0.09); }
.gkm-picker-item.gkm-on { background: var(--gkm-accent-soft, rgba(159, 232, 255, 0.16)); color: var(--gkm-accent, #9fe8ff); box-shadow: inset 0 0 0 1px var(--gkm-accent, #9fe8ff); }
.gkm-picker-item .gkm-picker-cv { border-radius: 5px; flex: 0 0 auto; }
.gkm-picker-desc { padding: 16px; overflow-y: auto; display: flex; flex-direction: column; justify-content: center; text-align: center; }
.gkm-picker-desc canvas { border-radius: 10px; margin: 0 auto 12px; box-shadow: 0 3px 14px rgba(0, 0, 0, .4); max-width: 100%; }
.gkm-picker-desc h4 { margin: 0 0 6px; font: 700 16px/1.1 var(--gkm-font, ui-monospace, monospace); color: var(--gkm-accent, #9fe8ff); }
.gkm-picker-desc p { margin: 0 0 10px; font: 400 13px/1.5 var(--gkm-font-body, system-ui, sans-serif); color: #b8c6db; }
.gkm-picker-best { font: 600 11px/1 var(--gkm-font, ui-monospace, monospace); color: #8ea3bd; letter-spacing: .05em; }
/* phones: stack the map list above its description instead of squeezing two columns (canvas would overflow) */
@media (max-width: 560px) {
  .gkm-picker-body { grid-template-columns: 1fr; }
  .gkm-picker-list { border-right: none; border-bottom: 1px solid rgba(255, 255, 255, 0.1); max-height: 38vh; }
}

/* ---- boolean checkbox (toggles) ---- */
.gamekit-menu .gkm-checkrow { display: flex; justify-content: center; margin-top: 16px; }
/* Exactly two toggles pair into one row wherever there is width for it — a whole row of height back,
   which is what lets four mode cards AND the toggles fit a 640×360 landscape phone. Grid (not measured
   margins) means a label that wraps in cs/uk/pl grows its own cell instead of overlapping its
   neighbour. Below 420px they stack again: two half-width rows there clip their labels. */
.gamekit-menu .gkm-checks { display: contents; }
@media (min-width: 420px) {
  .gamekit-menu .gkm-checks-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0 8px;
    align-items: start; margin-top: 16px; }
  .gamekit-menu .gkm-checks-pair .gkm-checkrow { margin-top: 0; }
  .gamekit-menu .gkm-checks-pair .gkm-checkrow:first-child { justify-content: flex-end; }
  .gamekit-menu .gkm-checks-pair .gkm-checkrow:last-child { justify-content: flex-start; }
}
.gamekit-menu .gkm-check { display: inline-flex; align-items: center; gap: 11px; cursor: pointer; -webkit-user-select: none; user-select: none;
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16)); border-radius: 11px; padding: 10px 16px;
  transition: border-color .14s, box-shadow .14s; }
.gamekit-menu .gkm-check:hover { border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-check.gkm-on { border-color: var(--gkm-accent, #9fe8ff); box-shadow: var(--gkm-glow, 0 0 18px rgba(159, 232, 255, .22)); }
.gamekit-menu .gkm-check.gkm-focus { outline: 2px solid var(--gkm-accent, #9fe8ff); outline-offset: 2px; }
.gamekit-menu .gkm-check-box { width: 20px; height: 20px; border-radius: 6px; flex: 0 0 auto; display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--gkm-border, rgba(255, 255, 255, 0.3)); transition: background .14s, border-color .14s; }
.gamekit-menu .gkm-check.gkm-on .gkm-check-box { background: var(--gkm-accent, #9fe8ff); border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-menu .gkm-check-box::after { content: "✓"; color: var(--gkm-on-accent, #06121a); font: 900 13px/1 system-ui, sans-serif; opacity: 0; transform: scale(.5); transition: opacity .12s, transform .12s; }
.gamekit-menu .gkm-check.gkm-on .gkm-check-box::after { opacity: 1; transform: scale(1); }
.gamekit-menu .gkm-check-txt { font: 700 14px/1.2 var(--gkm-font, ui-monospace, monospace); letter-spacing: 1px; color: var(--gkm-text, #eaf3ff); }
.gamekit-menu .gkm-check-txt .cap { font-weight: 400; letter-spacing: .3px; color: #93a5bd; font-size: 12px; }
/* a toggle that doesn't apply in the current mode — grayed, keeps its checked state, not clickable */
.gamekit-menu .gkm-check.gkm-disabled { opacity: 0.4; cursor: not-allowed; }
.gamekit-menu .gkm-check.gkm-disabled:hover { border-color: var(--gkm-border, rgba(255, 255, 255, 0.16)); box-shadow: none; }
/* a choice-row group that doesn't apply in the current mode (e.g. difficulty in a no-fail zen mode) —
   grayed + not clickable, keeps its selected pill; same semantics as the disabled toggle above */
.gamekit-menu .gkm-choice.gkm-disabled { opacity: 0.4; cursor: not-allowed; }
.gamekit-menu .gkm-choice.gkm-disabled:hover { border-color: var(--gkm-border, rgba(255, 255, 255, 0.14)); }

/* controls board (🎮 top-bar button → modal) */
.gamekit-au-ctlbtn { font-size: 15px; }
.gamekit-controls { position: fixed; inset: 0; z-index: 9200; display: flex; align-items: center; justify-content: center; padding: 18px;
  background: var(--gkm-overlay, rgba(6, 9, 15, 0.82)); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.gamekit-controls .gkctl-box { position: relative; width: min(380px, 100%); overflow: visible; box-sizing: border-box;
  background: var(--gkm-bg, rgba(14, 20, 32, 0.97)); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16)); border-radius: 16px; padding: 22px 22px 20px;
  box-shadow: var(--gkm-shadow, 0 20px 60px rgba(0, 0, 0, 0.6)); color: var(--gkm-text, #eaf2fb); font-family: var(--gkm-font, ui-monospace, monospace); }
.gamekit-controls .gkctl-scroll { max-height: calc(100vh - 80px); overflow-y: auto; overscroll-behavior: contain; }
.gamekit-controls h3 { margin: 0 0 14px; font-size: 18px; letter-spacing: 2px; color: var(--gkm-title, var(--gkm-text, #eaf3ff)); text-shadow: var(--gkm-glow, none); }
.gamekit-controls .gkctl-sec { font-size: 10px; letter-spacing: 2px; color: #6b7a90; text-transform: uppercase; margin: 14px 0 7px; }
.gamekit-controls .gkctl-sec:first-of-type { margin-top: 0; }
.gamekit-controls .gkctl-row { display: flex; align-items: center; gap: 12px; padding: 5px 0; }
.gamekit-controls .gkctl-keys { flex: 0 0 auto; min-width: 96px; font-size: 12px; letter-spacing: .5px; color: var(--gkm-accent, #9fe8ff);
  background: rgba(255, 255, 255, 0.05); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.18)); border-radius: 7px; padding: 6px 9px; text-align: center; }
.gamekit-controls .gkctl-act { color: #aebccd; font: 13px/1.4 var(--gkm-font-body, system-ui, sans-serif); }
.gamekit-controls .gkctl-note { margin: 14px 0 0; font-size: 12px; color: #6b7a90; line-height: 1.5; }
.gamekit-controls .gkctl-x { position: absolute; top: 12px; right: 14px; background: none; border: none; color: #9fb2c8; font-size: 17px; line-height: 1; cursor: pointer; padding: 2px; }
.gamekit-controls .gkctl-x:hover { color: var(--gkm-text, #fff); }

/* about / how-to modal (the game's crawlable #gk-about section lifted into a box) */
.gamekit-about .gkctl-box { width: min(440px, 100%); }
.gk-about-body { font: 13px/1.55 var(--gkm-font-body, system-ui, sans-serif); color: #aebccd; padding-right: 4px; }
.gk-about-body h1 { margin: 0 0 4px; font-size: 19px; letter-spacing: 2px; font-family: var(--gkm-font, ui-monospace, monospace); color: var(--gkm-title, var(--gkm-text, #eaf3ff)); text-shadow: var(--gkm-glow, none); }
.gk-about-body h2 { margin: 16px 0 6px; font-size: 10px; letter-spacing: 2px; text-transform: uppercase; font-family: var(--gkm-font, ui-monospace, monospace); color: #6b7a90; }
.gk-about-body p { margin: 6px 0; }
.gk-about-body strong { color: var(--gkm-text, #eaf2fb); }
.gk-about-body a { color: var(--gkm-accent, #9fe8ff); text-decoration: none; }
.gk-about-body a:hover { text-decoration: underline; }

/* the in-game top bar carries NO notification dots — every dot lives on the side stack (.has-dot) */
.gamekit-au-chbtn { font-size: 15px; position: relative; }


.gamekit-challenges { position: fixed; inset: 0; z-index: 9200; display: flex; align-items: center; justify-content: center; padding: 18px;
  background: var(--gkm-overlay, rgba(6, 9, 15, 0.82)); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.gamekit-challenges .gkch-box { position: relative; width: min(400px, 100%); overflow: visible; box-sizing: border-box;
  background: var(--gkm-bg, rgba(14, 20, 32, 0.97)); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16)); border-radius: 16px; padding: 22px;
  box-shadow: var(--gkm-shadow, 0 20px 60px rgba(0, 0, 0, 0.6)); color: var(--gkm-text, #eaf2fb); font-family: var(--gkm-font, ui-monospace, monospace); }
.gamekit-challenges .gkch-scroll { max-height: calc(100vh - 80px); overflow-y: auto; overscroll-behavior: contain; }
.gamekit-challenges h3 { margin: 0 0 14px; font-size: 18px; letter-spacing: 1px; color: var(--gkm-title, var(--gkm-text, #eaf3ff)); text-shadow: var(--gkm-glow, none); }
.gamekit-challenges .gkch-card { background: rgba(255, 255, 255, 0.04); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.14)); border-radius: 12px; padding: 12px 14px; margin-bottom: 10px; text-align: left; }
.gamekit-challenges .gkch-card.mine { border-color: var(--gkm-accent, #9fe8ff); box-shadow: 0 0 0 1px var(--gkm-accent, #9fe8ff), var(--gkm-glow, none); }
.gamekit-challenges .gkch-card.done { opacity: 0.85; }
.gamekit-challenges .gkch-k { font-size: 9px; letter-spacing: 2px; text-transform: uppercase; color: #6b7a90; display: flex; align-items: baseline; gap: 6px; }
.gamekit-challenges .gkch-reset { margin-left: auto; letter-spacing: 0.5px; text-transform: none; opacity: 0.8; white-space: nowrap; }
.gamekit-challenges .gkch-card.mine .gkch-k b { color: var(--gkm-accent, #9fe8ff); }
.gamekit-challenges .gkch-t { font-size: 14px; margin: 5px 0 9px; color: var(--gkm-text, #eaf3ff); font-family: var(--gkm-font-body, system-ui, sans-serif); }
.gamekit-challenges .gkch-bar { height: 7px; border-radius: 99px; background: rgba(255, 255, 255, 0.08); overflow: hidden; }
.gamekit-challenges .gkch-bar span { display: block; height: 100%; border-radius: 99px; background: var(--gkm-accent, #9fe8ff); }
.gamekit-challenges .gkch-card.done .gkch-bar span { background: var(--gkm-new, #7fe0a0); }
.gamekit-challenges .gkch-p { font-size: 11px; margin-top: 6px; color: #9fb2c9; font-variant-numeric: tabular-nums; }
.gamekit-challenges .gkch-goodbar { font-size: 11.5px; margin: 0 0 12px; text-align: center; color: var(--gkm-accent, #9fe8ff); }
.gamekit-challenges .gkch-empty { color: #8294ac; font-size: 13px; padding: 8px 0; }
.gamekit-challenges .gkch-note { margin: 12px 0 0; font-size: 11px; color: #6b7a90; line-height: 1.5; }
.gamekit-challenges .gkch-x { position: absolute; top: -13px; right: -13px; z-index: 6; width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; padding: 0; cursor: pointer; font-size: 14px; line-height: 1;
  color: #cdd8e8; background: rgba(18, 24, 38, 0.92); border: 1px solid rgba(255, 255, 255, 0.18); box-shadow: 0 3px 12px rgba(0, 0, 0, 0.5); }
.gamekit-challenges .gkch-x:hover { color: #fff; border-color: var(--gkm-accent, #9fe8ff); }

@media (max-width: 560px) {
  /* COMPACT single-row cards: small square preview + name/best on one line, no blurb — so 3–4 mode
     cards fit one screen without scrolling. Full-width, so text never cramps/wraps (a 2-up grid
     would). Rich cards stay on roomier screens; picker (style:'picker') is the rare-overflow fallback. */
  .gamekit-menu .gkm-cards { gap: 7px; }
  .gamekit-menu .gkm-card { grid-template-columns: 36px 1fr; gap: 11px; padding: 7px 11px; align-items: center; }
  .gamekit-menu .gkm-card-pv { width: 36px; height: 36px; align-self: center; }
  .gamekit-menu .gkm-card-body { gap: 2px; }
  .gamekit-menu .gkm-card-head { flex-wrap: wrap; }
  .gamekit-menu .gkm-card-desc { display: none; }
  .gamekit-menu .gkm-card-mech { display: none; }
}

.gamekit-share { display: flex; gap: 9px; justify-content: center; align-items: center; flex-wrap: wrap; --gamekit-accent: #9fe8ff; }
/* visual props are !important so a game's broad `#overlay button {…}` rule can't clobber these icon
   buttons (that was collapsing the copy <button>'s icon to zero width). */
.gamekit-share .sbtn { appearance: none !important; -webkit-appearance: none !important; font: inherit !important; margin: 0 !important;
  line-height: 0 !important; display: inline-flex !important; align-items: center !important; justify-content: center !important;
  width: 38px !important; height: 38px !important; padding: 0 !important; cursor: pointer !important;
  color: #eaf2fb !important; background: rgba(8, 12, 20, 0.55) !important; border: 1px solid rgba(255, 255, 255, 0.35) !important;
  border-radius: 9px !important; box-shadow: none !important; text-decoration: none !important; transition: color .12s, border-color .12s, background .12s; }
.gamekit-share .sbtn svg { width: 18px !important; height: 18px !important; fill: currentColor !important; display: block !important; }
.gamekit-share .sbtn:hover { color: #fff !important; border-color: var(--gamekit-accent) !important; background: rgba(8, 12, 20, 0.8) !important; }
.gamekit-share .sbtn.ok { color: #7fe0a0 !important; border-color: #7fe0a0 !important; }
.gamekit-share .sbtn[data-act="discord"]:hover { color: #fff !important; border-color: #5865F2 !important; background: #5865F2 !important; }
/* score-card-first share (end screen): the branded card renders inline (the shareable artifact) above
   ONE Share button that opens the image menu (native w/ image+link · copy image · download). Themed by
   the menu's --gkm-accent so the button matches the game. */
.gamekit-share-card { flex-direction: column !important; gap: 12px !important; }
.gamekit-share-card .gkshare-card { display: block; width: 100%; max-width: 340px; border-radius: 12px;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.22); cursor: pointer; }
.gamekit-share .gkshare-btn { appearance: none; -webkit-appearance: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  font: 700 14px/1 ui-monospace, monospace; letter-spacing: 0.5px; padding: 12px 24px; border-radius: 11px;
  color: #06131f; background: var(--gkm-accent, #9fe8ff); border: 1px solid var(--gkm-accent, #9fe8ff);
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2); transition: filter .12s, transform .06s; }
.gamekit-share .gkshare-btn:hover { filter: brightness(1.08); }
.gamekit-share .gkshare-btn:active { transform: translateY(1px); }
.gamekit-share .gkshare-btn svg { width: 17px; height: 17px; fill: currentColor; display: block; }

/* "Tap to play" splash — one gesture up front so audio can start (browsers block autoplay until a tap).
   Shown once per game load; the tap is the unlock. */
.gamekit-tap { position: fixed; inset: 0; z-index: 9999; display: flex; align-items: center; justify-content: center;
  background: rgba(6, 9, 14, 0.82); -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  cursor: pointer; transition: opacity .28s ease; }
.gamekit-tap.gk-hide { opacity: 0; pointer-events: none; }
.gamekit-tap-inner { display: flex; flex-direction: column; align-items: center; gap: 13px; text-align: center;
  color: #fff; font: 700 15px/1.2 ui-monospace, "SFMono-Regular", Menlo, monospace; letter-spacing: 3px; }
.gamekit-tap-play { width: 66px; height: 66px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, 0.55);
  display: flex; align-items: center; justify-content: center; font-size: 26px; padding-left: 4px;
  box-shadow: 0 0 26px -6px rgba(159, 232, 255, 0.6); animation: gkTapPulse 1.8s ease-in-out infinite; }
.gamekit-tap-inner small { font-size: 11px; letter-spacing: 1.5px; color: rgba(255, 255, 255, 0.55); font-weight: 400; }
@keyframes gkTapPulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }
@media (prefers-reduced-motion: reduce) { .gamekit-tap { transition: none; } .gamekit-tap-play { animation: none; } }

.gamekit-share .sbtn:disabled { opacity: 0.55 !important; cursor: default !important; }

/* "rotate your phone" overlay (gamekit.layout.requireOrientation) — for games locked to one orientation */
/* while the rotate-lock splash is up, the left nav rides above it — quitting must not require rotating */
body.gk-rotate-lock .gamekit-nav { z-index: 9100; }
.gamekit-rotate { position: fixed; inset: 0; z-index: 9000; display: none; align-items: center; justify-content: center;
  background: rgba(6, 9, 15, 0.96); color: #eaf2fb; text-align: center; padding: 24px; }
.gamekit-rotate.show { display: flex; }
.gamekit-rotate-box { font-size: 17px; line-height: 1.5; max-width: 280px; }
.gamekit-rotate-ico { font-size: 46px; margin-bottom: 10px; animation: gamekit-rot 1.6s ease-in-out infinite; }
@keyframes gamekit-rot { 0%,100% { transform: rotate(-12deg); } 50% { transform: rotate(78deg); } }
@media (prefers-reduced-motion: reduce) { .gamekit-rotate-ico { animation: none; } }

/* embed modal (iframe snippet) */
.gamekit-embed { position: fixed; inset: 0; z-index: 9100; display: flex; align-items: center; justify-content: center;
  background: rgba(5, 8, 13, 0.7); padding: 18px; }
.gamekit-embed-box { position: relative; width: min(520px, 100%); background: #0f1622; color: #eaf2fb;
  border: 1px solid rgba(255, 255, 255, 0.14); border-radius: 14px; padding: 22px; box-shadow: 0 18px 50px rgba(0, 0, 0, 0.55);
  font: 14px/1.5 system-ui, sans-serif; }
.gamekit-embed-box h3 { margin: 0 0 8px; font-size: 18px; }
.gamekit-embed-box p { margin: 0 0 14px; color: #9fb2c8; }
.gamekit-embed-sel { width: 100%; margin-bottom: 10px; padding: 9px 10px; border-radius: 9px; background: #0a121d;
  color: #eaf2fb; border: 1px solid rgba(255, 255, 255, 0.2); font: inherit; }
.gamekit-embed-code { width: 100%; box-sizing: border-box; resize: vertical; padding: 11px; border-radius: 9px;
  background: #0a121d; color: #9fe8ff; border: 1px solid rgba(255, 255, 255, 0.18); font: 12px/1.5 ui-monospace, monospace; }
.gamekit-embed-copy { margin-top: 12px; padding: 10px 16px; border-radius: 9px; cursor: pointer; font: 600 13px system-ui, sans-serif;
  color: #06121a; background: #9fe8ff; border: none; }
.gamekit-embed-x { position: absolute; top: -13px; right: -13px; z-index: 6; width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; padding: 0; cursor: pointer; font-size: 14px; line-height: 1;
  color: #cdd8e8; background: rgba(18, 24, 38, 0.92); border: 1px solid rgba(255, 255, 255, 0.18); box-shadow: 0 3px 12px rgba(0, 0, 0, 0.5); }
.gamekit-embed-x:hover { color: #fff; border-color: var(--gkm-accent, #9fe8ff); }

/* bottom-left build stamp (short commit SHA from version.js) — debug aid, deliberately faint +
   non-interactive; z below every kit overlay (menu 60, modals 9000+) so it never paints over them */
#gamekitVersion { position: fixed; left: 8px; bottom: 7px; z-index: 50; pointer-events: none; user-select: none;
  font: 11px/1 ui-monospace, "SFMono-Regular", Menlo, monospace; letter-spacing: 0.4px; color: #cdd8e8; opacity: 0.5; }
/* dev FPS meter (?fps=1) — bottom-right, above everything, non-interactive */
#gamekitFps { position: fixed; right: 8px; bottom: 7px; z-index: 2147483000; pointer-events: none; user-select: none;
  font: 700 12px/1 ui-monospace, "SFMono-Regular", Menlo, monospace; letter-spacing: 0.4px; color: #9fe8ff;
  background: rgba(0, 0, 0, 0.55); padding: 4px 8px; border-radius: 6px; }

/* ---- challenges panel: trophy pills + good-run bonus line ---- */
/* two matched muted-gold pills — kept in lockstep with the catalogue drawer's .cpills (index.html) */
.gamekit-challenges .gkch-pills { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; justify-content: center; margin: 0 0 8px; }
.gamekit-challenges .gkch-pill { display: inline-flex; align-items: center; gap: 6px; font: 700 12px/1 var(--gkm-font, ui-monospace, monospace);
  letter-spacing: 0.5px; color: #e8c069; background: rgba(255, 206, 92, 0.10);
  border: 1px solid rgba(255, 206, 92, 0.34); border-radius: 999px; padding: 6px 13px; }
.gamekit-challenges .gkch-pill.gkch-shop { cursor: pointer; }
.gamekit-challenges .gkch-pill.gkch-shop:hover { border-color: #ffce5c; background: rgba(255, 206, 92, 0.16); color: #ffce5c; }
/* ---- good-run bonus widget (gamekit.goodRunBonusHtml — challenges drawer + in-game panel):
   ONE compact centered row — label · bolt pips (light up as earned) · the numbers ---- */
.gk-grb { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 4px 10px; margin: 4px 0 10px; }
.gk-grb-head { font: 700 10.5px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: 1.4px; text-transform: uppercase; color: #8fa2ba; }
.gk-grb-pips { display: inline-flex; gap: 6px; }
.gk-grb-pip { width: 22px; height: 22px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; font-size: 12px;
  background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.12); filter: grayscale(1); opacity: 0.35; }
.gk-grb-pip.on { filter: none; opacity: 1; color: #ffce5c; background: rgba(255, 206, 92, 0.14);
  border-color: rgba(255, 206, 92, 0.6); box-shadow: 0 0 10px rgba(255, 206, 92, 0.35); }
.gk-grb-sub { font-size: 11px; color: #9fb2c9; }

/* ---- Cosmetics store modal (kit-owned, gamekit.shopPanel) ---- */
body:has(.gamekit-shoppanel) { overflow: hidden; }
.gamekit-shoppanel { position: fixed; inset: 0; z-index: 9300; display: flex; align-items: center; justify-content: center; padding: 16px;
  background: var(--gkm-overlay, rgba(6, 9, 15, 0.82)); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); overscroll-behavior: contain; }
/* FIXED height, not content height: the modal used to jump on every tab switch (the Titles ladder and
   the Achievements mock are shorter than the cosmetics grid). The shop's scroll pane and the two panes
   flex-grow into the slack, so one size holds all three tabs. */
.gamekit-shoppanel .gksp-box { position: relative; display: flex; flex-direction: column; width: min(720px, 100%); height: min(780px, calc(100vh - 32px)); max-height: calc(100vh - 32px); box-sizing: border-box;
  background: var(--gkm-bg, rgba(14, 20, 32, 0.97)); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16)); border-radius: 16px; padding: 20px 22px 16px;
  box-shadow: var(--gkm-shadow, 0 20px 60px rgba(0, 0, 0, 0.6)); color: var(--gkm-text, #eaf2fb); font-family: var(--gkm-font, ui-monospace, monospace); }
.gamekit-shoppanel .gksp-x { position: absolute; top: -13px; right: -13px; z-index: 6; width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; padding: 0; cursor: pointer; font-size: 14px; line-height: 1;
  color: #cdd8e8; background: rgba(18, 24, 38, 0.92); border: 1px solid rgba(255, 255, 255, 0.18); box-shadow: 0 3px 12px rgba(0, 0, 0, 0.5); }
.gamekit-shoppanel .gksp-x:hover { color: #fff; border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-shoppanel .gksp-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding-right: 40px; }
.gamekit-shoppanel .gksp-title { font-size: 18px; font-weight: 800; letter-spacing: 2px; color: var(--gkm-title, #eaf3ff); text-shadow: var(--gkm-glow, none); }
.gamekit-shoppanel .gksp-bal { font-size: 14px; font-weight: 700; color: var(--gkm-new, #ffd166); white-space: nowrap; }
.gamekit-shoppanel .gksp-barrow { display: flex; align-items: center; gap: 10px; margin: 10px 0 4px; }
.gamekit-shoppanel .gksp-bar { flex: 1; height: 8px; border-radius: 99px; background: rgba(255, 255, 255, 0.09); overflow: hidden; }
.gamekit-shoppanel .gksp-bar i { display: block; height: 100%; border-radius: 99px; background: linear-gradient(90deg, #ffd166, #ff9a5c); }
.gamekit-shoppanel .gksp-bartxt { font-size: 10.5px; font-weight: 700; color: #8294ac; white-space: nowrap; }
.gamekit-shoppanel .gksp-focdesc { min-height: 1.5em; margin: 6px 0 4px; font-size: 11px; line-height: 1.45; color: #93a5bd; }
.gamekit-shoppanel .gksp-focdesc b { color: var(--gkm-title, #eaf3ff); }
.gamekit-shoppanel .gksp-price, .gamekit-menu .gkm-focdesc .gkm-price { color: var(--gkm-new, #ffd166); font-weight: 700; white-space: nowrap; }
.gamekit-shoppanel .gksp-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; margin: 2px -6px 10px; padding: 0 6px; }
/* the BUY button belongs to the Shop tab; syncFocus() owns its inline display (hidden with nothing
   focused), so it is hidden HERE by class rather than by setTab clobbering that inline value */
.gamekit-shoppanel.gksp-tab-ach .gksp-buy,
.gamekit-shoppanel.gksp-tab-titles .gksp-buy { display: none; }
.gamekit-shoppanel .gksp-game { display: flex; align-items: baseline; gap: 10px; margin: 16px 0 8px; }
.gamekit-shoppanel .gksp-gt { font-size: 12.5px; font-weight: 700; letter-spacing: 1px; color: var(--acc, #eaf3ff); white-space: nowrap; }
.gamekit-shoppanel .gksp-gp { font-size: 10px; font-weight: 600; color: #6b7a90; }
.gamekit-shoppanel .gksp-gline { flex: 1; height: 1px; background: var(--gkm-border, rgba(255, 255, 255, 0.14)); }
.gamekit-shoppanel .gksp-set { font-size: 10px; letter-spacing: 1.5px; text-transform: uppercase; color: #8294ac; margin: 8px 0 6px; }
.gamekit-shoppanel .gksp-note { text-transform: none; letter-spacing: 0.4px; color: #6b7a90; }
/* controls row: search + game filter (full store) or "All games →" (scoped) */
.gamekit-shoppanel .gksp-ctrls { display: flex; gap: 8px; margin: 10px 0 2px; }
.gamekit-shoppanel .gksp-search { flex: 1; min-width: 0; font: 12px var(--gkm-font, ui-monospace, monospace); color: var(--gkm-text, #eaf2fb);
  background: rgba(255, 255, 255, 0.05); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16)); border-radius: 9px; padding: 8px 11px; }
.gamekit-shoppanel .gksp-search::placeholder { color: #6b7a90; }
.gamekit-shoppanel .gksp-filter { display: flex; align-items: center; justify-content: space-between; gap: 6px; font: 12px var(--gkm-font, ui-monospace, monospace); color: var(--gkm-text, #eaf2fb);
  background: rgba(255, 255, 255, 0.05); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16)); border-radius: 9px; padding: 8px 10px; max-width: 42%; cursor: pointer; text-align: left; }
.gamekit-shoppanel .gksp-filter:hover { border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-shoppanel .gksp-filter-lbl { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gamekit-shoppanel .gksp-filter-caret { flex: 0 0 auto; opacity: 0.7; }
/* themed game-filter overlay (replaces the native <select>) — mirrors the language menu */
.gamekit-shopfilter-menu { position: fixed; inset: 0; z-index: 9400; display: flex; align-items: center; justify-content: center; padding: 18px;
  background: var(--gkm-overlay, rgba(5, 8, 13, 0.72)); -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.gamekit-shopfilter-menu .gkspf-box { width: min(320px, 100%); box-sizing: border-box; max-height: 70vh; overflow: auto; display: flex; flex-direction: column; gap: 6px;
  background: var(--gkm-bg, rgba(16, 22, 34, 0.98)); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.18));
  border-radius: var(--gkm-radius, 16px); padding: 12px; box-shadow: var(--gkm-shadow, 0 20px 60px rgba(0, 0, 0, 0.6));
  color: var(--gkm-text, #eef2f8); font-family: var(--gkm-font, ui-monospace, "SFMono-Regular", Menlo, monospace); }
.gamekit-shopfilter-menu .gkspf-opt { text-align: left; font: 12px var(--gkm-font, ui-monospace, monospace); color: var(--gkm-text, #eaf2fb);
  background: rgba(255, 255, 255, 0.05); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16)); border-radius: 9px; padding: 10px 12px; cursor: pointer;
  transition: border-color .12s, background .12s; }
.gamekit-shopfilter-menu .gkspf-opt:hover { border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-shopfilter-menu .gkspf-opt.selected { border-color: var(--gkm-accent, #9fe8ff); background: var(--gkm-accent-soft, rgba(159, 232, 255, 0.16)); }
.gamekit-shoppanel .gksp-allgames { font: 700 12px var(--gkm-font, ui-monospace, monospace); color: var(--gkm-accent, #9fe8ff);
  background: rgba(255, 255, 255, 0.05); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16)); border-radius: 9px; padding: 8px 12px; cursor: pointer; white-space: nowrap; }
.gamekit-shoppanel .gksp-allgames:hover { border-color: var(--gkm-accent, #9fe8ff); }
/* tiles: a compact row — icon left, name + status stacked right; auto-fill fits 4–5 across */
.gamekit-shoppanel .gksp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 6px; }
.gamekit-shoppanel .gksp-cell { position: relative; display: flex; align-items: center; gap: 7px; padding: 6px 8px; border-radius: 9px; cursor: pointer;
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.14)); }
.gamekit-shoppanel .gksp-cell:hover { border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-shoppanel .gksp-cell.gksp-focus { box-shadow: inset 0 0 0 2px var(--gkm-accent, #9fe8ff); }
.gamekit-shoppanel .gksp-cell.gksp-owned { border-color: rgba(127, 224, 160, 0.5); }
.gamekit-shoppanel .gksp-cell.gksp-sel { border-color: var(--gkm-accent, #9fe8ff); box-shadow: inset 0 0 0 1px var(--gkm-accent, #9fe8ff); }
.gamekit-shoppanel .gksp-cell.gksp-dim { opacity: 0.5; }
.gamekit-shoppanel .gksp-sw { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 8px; border: 1px solid rgba(255, 255, 255, 0.18); }
.gamekit-shoppanel .gksp-txt { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* `overflow-wrap: anywhere` broke mid-WORD, so a 9-letter skin name rendered as "Blueprin" + a
   lone "t" on the next line. Wrap at spaces only; a single word that still doesn't fit shrinks
   one step and then ellipsises — an orphaned letter reads as a rendering bug, an ellipsis doesn't. */
.gamekit-shoppanel .gksp-nm { font-size: 12px; font-weight: 700; letter-spacing: 0.2px; color: #eaf3ff;
  line-height: 1.15; overflow-wrap: normal; word-break: keep-all; hyphens: none;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden;
  text-overflow: ellipsis; }
/* names longer than ~8 characters get the smaller step so they still fit the cell on one line */
.gamekit-shoppanel .gksp-nm.gksp-long { font-size: 10.5px; letter-spacing: 0; }
.gamekit-shoppanel .gksp-sub { font-size: 10.5px; font-weight: 700; letter-spacing: 0.4px; color: #93a5bd; }
.gamekit-shoppanel .gksp-sub .gksp-on { color: var(--gkm-accent, #9fe8ff); }
.gamekit-shoppanel .gksp-empty { color: #8294ac; font-size: 12.5px; padding: 18px 4px; text-align: center; }
/* CRT cell: the whole swatch is an animated colour-cycling tile; a ▾ caret opens the colour dropdown */
.gamekit-shoppanel .gksp-crt-cell { position: relative; }
.gamekit-shoppanel .gk-crt-sw { position: relative; overflow: hidden; background: #0c1f12; animation: gkCrtSwCycle 4.4s linear infinite; }
.gamekit-shoppanel .gk-crt-sw::after { content: ''; position: absolute; inset: 0; background: repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0.4) 0 1px, transparent 1px 3px); }
@keyframes gkCrtSwCycle {
  0%, 100% { background: #0c1f12; box-shadow: inset 0 0 0 1px #46e0a0, inset 0 0 14px -2px #46e0a0; }
  25% { background: #1f180c; box-shadow: inset 0 0 0 1px #ffb454, inset 0 0 14px -2px #ffb454; }
  50% { background: #0c1a1f; box-shadow: inset 0 0 0 1px #5cc8ff, inset 0 0 14px -2px #5cc8ff; }
  75% { background: #1a1c20; box-shadow: inset 0 0 0 1px #eaf3ff, inset 0 0 14px -2px #eaf3ff; }
}
@media (prefers-reduced-motion: reduce) { .gamekit-shoppanel .gk-crt-sw { animation: none; } }
.gamekit-shoppanel .gksp-crt-caret { margin-left: auto; flex: 0 0 auto; width: 24px; height: 24px; border-radius: 7px; cursor: pointer;
  display: flex; align-items: center; justify-content: center; font-size: 12px; line-height: 1;
  color: var(--gkm-text, #eaf2fb); background: rgba(255, 255, 255, 0.06); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.16)); }
.gamekit-shoppanel .gksp-crt-caret:hover { border-color: var(--gkm-accent, #9fe8ff); }
/* The ▶ lives ON THE SWATCH, as a play badge over the artwork — not in the text column. Two earlier
   attempts put it in that column: in flow it ate 24px and clipped names to "Rea… Pul…", and floated
   into the corner with reserved padding it still collided, because the column is ~45px and "Default"
   is one ~46px unbreakable word (reserving space cannot stop an overflow, and letting it break gave
   "Defau/lt"). Over the swatch there is nothing to contend with: the label gets the full column and
   fits on one line in every locale. */
.gamekit-shoppanel .gksp-cell.gksp-has-pv .gksp-pv { position: absolute; left: 28px; bottom: 8px;
  width: 20px; height: 20px; border-radius: 6px; font-size: 9px; margin: 0;
  background: rgba(6, 10, 18, 0.82); backdrop-filter: blur(2px); }
.gamekit-shoppanel .gksp-pv { color: var(--gkm-accent, #9fe8ff); font-size: 11px; }
/* anchored CRT colour dropdown (fixed-positioned near the caret; lives at body level, so unscoped) */
.gksp-crt-dd { display: flex; flex-direction: column; gap: 3px; min-width: 152px; padding: 6px;
  background: var(--gkm-bg, rgba(16, 22, 34, 0.98)); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.18));
  border-radius: 12px; box-shadow: var(--gkm-shadow, 0 16px 40px rgba(0, 0, 0, 0.6)); font-family: var(--gkm-font, ui-monospace, monospace); }
.gksp-crt-opt { display: flex; align-items: center; gap: 8px; text-align: left; background: none; border: 1px solid transparent; border-radius: 8px;
  padding: 8px 11px; cursor: pointer; color: var(--gkm-text, #eaf2fb); font: inherit; font-size: 13px; font-weight: 600; }
.gksp-crt-opt:hover { background: rgba(255, 255, 255, 0.06); }
.gksp-crt-opt.on { color: var(--gkm-accent, #9fe8ff); border-color: rgba(159, 232, 255, 0.4); background: rgba(159, 232, 255, 0.10); }
.gksp-crt-dot { width: 11px; height: 11px; border-radius: 3px; flex: 0 0 auto; box-shadow: 0 0 6px currentColor; }
.gksp-crt-dot[data-c="green"] { background: #46e0a0; color: #46e0a0; }
.gksp-crt-dot[data-c="amber"] { background: #ffb454; color: #ffb454; }
.gksp-crt-dot[data-c="cyan"] { background: #5cc8ff; color: #5cc8ff; }
.gksp-crt-dot[data-c="mono"] { background: #eaf3ff; color: #eaf3ff; }
/* ---- Collection tabs: Shop · Achievements · Titles -------------------------------------------
   One modal for everything you collect. Titles used to be a second dialog behind a hint row under
   the grid; the tab row replaces that row, so it costs no extra height in the tight viewports. */
.gamekit-shoppanel .gksp-tabs { display: flex; gap: 6px; margin: 10px 0 0; }
/* equal thirds — three peers, so they get equal width at every size */
.gamekit-shoppanel .gksp-tab { position: relative; flex: 1 1 0; min-width: 0; display: flex; align-items: center; justify-content: center; gap: 6px;
  font: 700 11px var(--gkm-font, ui-monospace, monospace); letter-spacing: 0.5px;
  color: #93a5bd; background: rgba(255, 255, 255, 0.04); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.14));
  border-radius: 9px; padding: 8px 7px; cursor: pointer; white-space: nowrap; }
.gamekit-shoppanel .gksp-tabi { flex: none; }
.gamekit-shoppanel .gksp-tabl { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.gamekit-shoppanel .gksp-tab:hover { color: var(--gkm-text, #eaf2fb); border-color: var(--gkm-accent, #9fe8ff); }
.gamekit-shoppanel .gksp-tab.on { color: var(--gkm-title, #eaf3ff); background: var(--gkm-accent-soft, rgba(159, 232, 255, 0.14));
  border-color: var(--gkm-accent, #9fe8ff); box-shadow: inset 0 -2px 0 var(--gkm-accent, #9fe8ff); }
/* the same dot the side-stack buttons use — it points at WHICH tab the Collection dot meant. Only the
   Achievements tab has one: a fresh title already dots the Profile button, and the Shop has no news. */
.gamekit-shoppanel .gksp-tab.has-dot::after { content: ""; position: absolute; top: -3px; right: -3px;
  width: 9px; height: 9px; border-radius: 50%; background: #ffd166; box-shadow: 0 0 6px 1px rgba(255, 209, 102, 0.9); }
/* A 360px box gives each equal third ~86px. "Achievements" cannot fit that WITH an emoji, so the emoji
   is what goes — the word is the part that has to survive. */
@media (max-width: 430px) {
  .gamekit-shoppanel .gksp-tab { font-size: 10px; padding: 8px 4px; letter-spacing: 0; gap: 0; }
  .gamekit-shoppanel .gksp-tabi { display: none; }
}
.gamekit-shoppanel .gksp-pane { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; margin: 10px -6px 0; padding: 0 6px; }
/* Titles pane: a flex column so the ladder (min-height:100%) stretches its rows over the full box */
.gamekit-shoppanel .gksp-titles { flex-direction: column; }
.gamekit-shoppanel .gksp-titles .gksp-panesub { flex: 0 0 auto; }
.gamekit-shoppanel .gksp-titles .tl-list { flex: 1 1 auto; }
.gamekit-shoppanel .gksp-panesub { margin: 0 0 10px; font-size: 11px; line-height: 1.5; color: #93a5bd; }
.gamekit-shoppanel .gksp-panesub b { color: var(--gkm-title, #eaf3ff); }
/* Achievements: bigger tiles than the cosmetics grid, because a row carries a name, a goal AND a
   progress bar, not just a swatch. Locked rows stay readable (the hint IS the driver) — they are
   dimmed, never hidden. A `run:`-shaped goal has no bar (see achievements.js): it shows ✓ / — . */
.gamekit-shoppanel .gksp-ach { position: relative; }
.gamekit-shoppanel .gksp-achgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: 9px; }
.gamekit-shoppanel .gksp-achcell { display: flex; align-items: center; gap: 12px; padding: 13px; border-radius: 13px;
  background: rgba(255, 255, 255, 0.04); border: 1px solid var(--gkm-border, rgba(255, 255, 255, 0.14)); opacity: 0.62; }
.gamekit-shoppanel .gksp-achcell.done { opacity: 1; border-color: var(--gkm-new, #ffd166); background: rgba(255, 209, 102, 0.07); }
.gamekit-shoppanel .gksp-achicon { font-size: 30px; line-height: 1; flex: none; filter: grayscale(1); opacity: 0.7; }
.gamekit-shoppanel .gksp-achcell.done .gksp-achicon { filter: none; opacity: 1; }
.gamekit-shoppanel .gksp-achtxt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
/* names WRAP to two lines rather than ellipsizing: a truncated badge name is unreadable, and the
   longest translations (it/pl run to ~24 chars) don't fit one 360px-wide line. */
.gamekit-shoppanel .gksp-achnm { font: 700 12.5px var(--gkm-font, ui-monospace, monospace); color: var(--gkm-title, #eaf3ff);
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.gamekit-shoppanel .gksp-achds { font-size: 10.5px; line-height: 1.4; color: #93a5bd; }
.gamekit-shoppanel .gksp-achbar { position: relative; height: 5px; border-radius: 3px; overflow: hidden;
  background: rgba(255, 255, 255, 0.10); margin-top: 2px; }
.gamekit-shoppanel .gksp-achbar i { position: absolute; inset: 0 auto 0 0; border-radius: 3px; background: var(--gkm-accent, #9fe8ff); }
.gamekit-shoppanel .gksp-achcell.done .gksp-achbar i { background: var(--gkm-new, #ffd166); }
.gamekit-shoppanel .gksp-achprog { font: 700 9.5px var(--gkm-font, ui-monospace, monospace); letter-spacing: 0.4px; color: #7f92ab; }
.gamekit-shoppanel .gksp-achpts { flex: none; align-self: flex-start; font-size: 12px; font-weight: 700;
  color: var(--gkm-new, #ffd166); white-space: nowrap; }
.gamekit-shoppanel .gksp-achcell.done .gksp-achpts { color: #7dd8a6; }
.gamekit-shoppanel .gksp-achempty { padding: 22px 8px; text-align: center; font-size: 11px; color: #93a5bd; }
/* A row the notification dot was about: the chip + glow the challenges drawer uses for a NEW rotation,
   so the dot that led you here lands on something. The wall also sorts these first and scrolls to the
   first one. Chip text comes from i18n via data-new. */
.gamekit-shoppanel .gksp-achcell.gksp-achnew { border-color: #ffd166; animation: gkspAchNew 1.8s ease-in-out 2; }
.gamekit-shoppanel .gksp-achcell.gksp-achnew::after { content: attr(data-new); position: absolute; top: -8px; right: 10px; z-index: 2;
  padding: 3px 8px; border-radius: 999px; background: #ffd166; color: #1a1405;
  font: 800 9.5px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: 1px;
  box-shadow: 0 0 12px rgba(255, 209, 102, 0.8); animation: gkspAchNewIn .5s ease; }
.gamekit-shoppanel .gksp-achcell { position: relative; }   /* the chip anchors to the row */
@keyframes gkspAchNew { 0%, 100% { box-shadow: none; } 50% { box-shadow: 0 0 0 1px #ffd166, 0 0 18px rgba(255, 209, 102, 0.55); } }
@keyframes gkspAchNewIn { 0% { opacity: 0; transform: translateY(4px) scale(.8); } 100% { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  .gamekit-shoppanel .gksp-achcell.gksp-achnew, .gamekit-shoppanel .gksp-achcell.gksp-achnew::after { animation: none; }
}
.gamekit-shoppanel .gksp-buy { margin-top: 10px; font: 800 12.5px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: 1px; border-radius: 10px; padding: 12px 16px;
  border: none; cursor: pointer; color: var(--gk-shop-ink, #0a1420); background: var(--gkm-new, #ffd166); box-shadow: 0 0 14px rgba(255, 209, 102, 0.35); }
.gamekit-shoppanel .gksp-buy:disabled { opacity: 0.5; cursor: default; box-shadow: none; }
.gamekit-shoppanel .gksp-buy.gksp-buy-equip { color: var(--gkm-text, #eaf2fb); background: rgba(255, 255, 255, 0.08); box-shadow: none; border: 1px solid var(--gkm-accent, #9fe8ff); }
/* welcome gift row (one-time, removed after claiming) */
.gamekit-shoppanel .gksp-gift { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 8px 0 0; padding: 9px 12px;
  border: 1px dashed rgba(255, 206, 92, 0.65); border-radius: 10px; background: rgba(255, 206, 92, 0.08); }
.gamekit-shoppanel .gksp-gift-t { font-size: 12.5px; color: var(--gkm-text, #eaf2fb); }
.gamekit-shoppanel .gksp-gift-btn { font: 800 11.5px/1 var(--gkm-font, ui-monospace, monospace); letter-spacing: 1px; white-space: nowrap; cursor: pointer;
  color: #1a1408; background: var(--gkm-new, #ffd166); border: 0; border-radius: 8px; padding: 9px 12px; }
.gamekit-shoppanel .gksp-gift-btn:hover { filter: brightness(1.1); }
.gamekit-shoppanel .gksp-gift.claimed { justify-content: center; border-style: solid; }
/* free-play footer toggle (a settings row, deliberately NOT a shop card) + its header badge */
.gamekit-shoppanel .gksp-fp { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 10px; padding: 9px 2px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.08); }
.gamekit-shoppanel .gksp-fp-l { font-size: 12px; font-weight: 700; color: var(--gkm-text, #eaf2fb); }
.gamekit-shoppanel .gksp-fp-s { font-size: 10.5px; color: #8294ac; margin-top: 2px; }
.gamekit-shoppanel .gksp-fp-toggle { position: relative; flex: 0 0 auto; width: 44px; height: 24px; border-radius: 999px; cursor: pointer; padding: 0;
  background: rgba(255, 255, 255, 0.10); border: 1px solid rgba(255, 255, 255, 0.22); transition: background 0.15s, border-color 0.15s; }
.gamekit-shoppanel .gksp-fp-toggle::after { content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%;
  background: #cdd8e8; transition: left 0.15s, background 0.15s; }
.gamekit-shoppanel .gksp-fp-toggle.on { background: rgba(255, 206, 92, 0.30); border-color: #ffce5c; }
.gamekit-shoppanel .gksp-fp-toggle.on::after { left: 22px; background: #ffce5c; }
.gamekit-shoppanel .gksp-strike { text-decoration: line-through; opacity: 0.65; }
@media (max-width: 420px) { .gamekit-shoppanel .gksp-grid { grid-template-columns: repeat(2, 1fr); } }
/* compact progress donut (conic-gradient, no SVG so it's headless-safe) — hidden except in the
   short-height landscape layout below, where the linear bar is hidden and this takes its place */
.gamekit-shoppanel .gksp-ringwrap { display: none; position: relative; width: 88px; height: 88px; margin: 2px auto 0; }
.gamekit-shoppanel .gksp-ring { width: 100%; height: 100%; border-radius: 50%;
  /* the gold ramp spans the FILLED arc (not a fixed 40% stop — a small pct stayed all-pale) */
  background: conic-gradient(#ffe6a3, #ffc24d calc(var(--pct, 0) * 0.45%), #ff9f45 calc(var(--pct, 0) * 1%), rgba(255, 255, 255, 0.13) 0);
  -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 10px), #000 calc(100% - 9px));
          mask: radial-gradient(farthest-side, #0000 calc(100% - 10px), #000 calc(100% - 9px)); }
.gamekit-shoppanel .gksp-ringlabel { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; }
.gamekit-shoppanel .gksp-ringlabel b { font: 800 17px/1 var(--gkm-font, ui-monospace, monospace); color: var(--gkm-new, #ffce5c); }
.gamekit-shoppanel .gksp-ringlabel span { font: 600 9px/1.3 var(--gkm-font, ui-monospace, monospace); color: #93a5bd; margin-top: 2px; }
/* short-height landscape: the stacked search + progress + titles-note starved the item grid. Give
   the grid the full-height left column; the right rail stacks search + filter + a compact progress
   RING, with See titles pinned to the bottom. (same breakpoint the main menu uses for its split) */
@media (orientation: landscape) and (max-height: 560px) {
  .gamekit-shoppanel { padding: 8px; }
  .gamekit-shoppanel .gksp-box {
    height: calc(100vh - 16px); max-height: calc(100vh - 16px); padding: 10px 16px 12px;
    display: grid; column-gap: 16px; row-gap: 5px;
    grid-template-columns: 1fr 150px;
    /* header spans the full width (no gap under it); the ring row is the only flexible one, so it
       absorbs slack AND shrinks first — the fixed rail items (search/desc/buy/titles) always fit */
    grid-template-rows: auto auto auto auto minmax(0, 1fr) auto auto auto;
    grid-template-areas:
      "head    head"
      "gift    gift"
      "tabs    tabs"
      "scroll  ctrls"
      "scroll  ring"
      "scroll  focdesc"
      "scroll  buy"
      "scroll  fp";
  }
  /* compact tabs here: the rail's flexible row is the progress donut, so every pixel this row takes
     comes straight out of the donut */
  .gamekit-shoppanel .gksp-tabs { grid-area: tabs; margin: 4px 0 0; gap: 5px; }
  .gamekit-shoppanel .gksp-tab { padding: 5px 4px; font-size: 10px; letter-spacing: 0; }
  /* the two non-shop tabs hide every rail item, so the two-column grid has nothing left to align —
     drop back to a plain column and let the pane take the height the grid was reserving */
  .gamekit-shoppanel.gksp-tab-ach .gksp-box,
  .gamekit-shoppanel.gksp-tab-titles .gksp-box { display: flex; flex-direction: column; }
  .gamekit-shoppanel.gksp-tab-ach .gksp-pane,
  .gamekit-shoppanel.gksp-tab-titles .gksp-pane { flex: 1; }
  .gamekit-shoppanel .gksp-gift { grid-area: gift; margin: 0; padding: 6px 10px; }
  .gamekit-shoppanel .gksp-fp { grid-area: fp; margin: 0; padding-top: 6px; }
  .gamekit-shoppanel .gksp-head { grid-area: head; }
  .gamekit-shoppanel .gksp-scroll { grid-area: scroll; min-height: 0; margin: 2px -6px 0; }
  /* search + games selector at the TOP of the rail; donut centered in the middle; See titles at the bottom */
  .gamekit-shoppanel .gksp-ctrls { grid-area: ctrls; flex-direction: column; margin: 0; }
  .gamekit-shoppanel .gksp-filter { max-width: none; }
  .gamekit-shoppanel .gksp-barrow { grid-area: ring; min-height: 0; margin: 0; display: flex; align-items: center; justify-content: center; overflow: hidden; }
  /* overflow:hidden on both: when the flexible ring row collapses (very short viewports), the
     absolutely-positioned % label must vanish with it, not paint over the rail buttons above */
  .gamekit-shoppanel .gksp-ringwrap { display: block; width: auto; height: min(100%, 118px); aspect-ratio: 1; margin: 0 auto; overflow: hidden; }
  /* the free-play explainer is a paragraph — in the 150px rail it wraps to ~10 lines and starves
     the ring row to nothing; the short label + toggle carry the feature here */
  .gamekit-shoppanel .gksp-fp-s { display: none; }
  .gamekit-shoppanel .gksp-ring { -webkit-mask: radial-gradient(farthest-side, #0000 calc(100% - 11px), #000 calc(100% - 10px));
          mask: radial-gradient(farthest-side, #0000 calc(100% - 11px), #000 calc(100% - 10px)); }
  .gamekit-shoppanel .gksp-ringlabel b { font-size: 24px; }
  .gamekit-shoppanel .gksp-ringlabel span { font-size: 11px; }
  .gamekit-shoppanel .gksp-focdesc { grid-area: focdesc; margin: 2px 0; }
  /* idle (nothing focused) the desc row must not reserve height — it pushed the donut off-center */
  .gamekit-shoppanel .gksp-focdesc:empty { min-height: 0; margin: 0; }
  .gamekit-shoppanel .gksp-buy { grid-area: buy; margin: 0; padding: 10px 14px; }
  .gamekit-shoppanel .gksp-barrow .gksp-bar,
  .gamekit-shoppanel .gksp-barrow .gksp-bartxt { display: none; } /* linear bar → ring */
  .gamekit-shoppanel .gksp-grid { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); } /* more per row in the wider grid */
}
/* Phone-in-landscape (360px tall): after head + gift + tabs + search + desc + BUY + free-play there is
   no room left for a donut at all — it collapsed to ~20px, which reads as a smudge. Below this height
   the numeric readout carries the progress instead; the donut returns as soon as there's room for it. */
@media (orientation: landscape) and (max-height: 420px) {
  /* the Titles explainer wraps to three lines here and leaves ~2 ladder rows visible; the rows say
     "Wear" / "✓ Worn" / "N 🏆" themselves, so the paragraph is the thing that goes */
  .gamekit-shoppanel .gksp-panesub { display: none; }
  .gamekit-shoppanel .gksp-ringwrap { display: none; }
  .gamekit-shoppanel .gksp-barrow { min-height: 0; }
  .gamekit-shoppanel .gksp-barrow .gksp-bartxt { display: block; width: 100%; text-align: center; }
}

/* site-wide cursor-trail overlay (Neon Comet / Rainbow Trail skins) */
.gamekit-cursor-trail { position: fixed; inset: 0; z-index: 999999; pointer-events: none; }
/* Terminal cursor skin: a blinking phosphor block following the pointer (colour set inline by the kit) */
.gamekit-term-cursor { position: fixed; left: 0; top: 0; inset: auto; margin: 0; border: 0; padding: 0; overflow: visible;
  z-index: 2147483600; pointer-events: none; width: 9px; height: 16px;
  background: #33ff88; box-shadow: 0 0 8px #33ff88; animation: gkTermBlink 1.15s steps(1) infinite; }
.gamekit-term-cursor::backdrop { display: none; background: none; }
/* always visible: the "blink" is just a short dip to 50% opacity, never fully off */
@keyframes gkTermBlink { 0%, 80% { opacity: 1; } 80.01%, 100% { opacity: 0.5; } }
@media (prefers-reduced-motion: reduce) { .gamekit-term-cursor { animation: none; opacity: 1; } }

/* ---- CRT display mode (site-wide, unlockable — gamekit.crt) ----
   the whole page is monochrome-tinted via a root filter; a fixed overlay adds scanlines + vignette.
   green is the default; amber/cyan/mono are the other unlocked colours. */
:root.gk-crt { --gk-crt-filter: grayscale(1) brightness(1.05) sepia(0.85) saturate(2.4) hue-rotate(78deg); filter: var(--gk-crt-filter); }
:root.gk-crt[data-crt-color="amber"] { --gk-crt-filter: grayscale(1) brightness(1.05) sepia(0.95) saturate(1.8) hue-rotate(-14deg); }
:root.gk-crt[data-crt-color="cyan"] { --gk-crt-filter: grayscale(1) brightness(1.05) sepia(0.7) saturate(2.1) hue-rotate(142deg); }
:root.gk-crt[data-crt-color="mono"] { --gk-crt-filter: grayscale(1) brightness(1.08) contrast(1.06); }
/* native <dialog> modals paint in the browser top layer, which the root filter can't reach — tint them
   directly (the var inherits down the DOM). Kit overlays are plain divs, so they're already covered. */
:root.gk-crt dialog[open] { filter: var(--gk-crt-filter); }
.gamekit-crt-overlay { position: fixed; inset: 0; z-index: 2147483000; pointer-events: none;
  background: repeating-linear-gradient(to bottom, rgba(0, 0, 0, 0.22) 0, rgba(0, 0, 0, 0.22) 1px, transparent 1px, transparent 3px);
  mix-blend-mode: multiply; }
.gamekit-crt-overlay::after { content: ''; position: absolute; inset: 0;
  background: radial-gradient(125% 125% at 50% 50%, transparent 58%, rgba(0, 0, 0, 0.4) 100%); }
:root:not(.gk-crt) .gamekit-crt-overlay { display: none; }
/* locked ☰ row (feature not yet unlocked) — dimmed, points to the shop */
.gamekit-more-item.gamekit-more-locked { opacity: 0.55; }
.gamekit-more-lock { margin-left: 4px; opacity: 0.8; }
/* ☰ CRT dropdown: the row + an inline themed option list */
.gamekit-more-crt { display: flex; flex-direction: column; }
.gamekit-more-crt .gamekit-more-item { display: flex; align-items: center; gap: 6px; width: 100%; box-sizing: border-box; }
.gamekit-more-caret { margin-left: auto; opacity: 0.6; }
.gamekit-more-sub { display: flex; flex-direction: column; gap: 2px; padding: 3px 0 6px 22px; }
.gamekit-more-sub[hidden] { display: none; }
.gamekit-more-subitem { display: flex; align-items: center; gap: 8px; text-align: left; background: none; border: 1px solid transparent; border-radius: 8px; padding: 7px 10px;
  cursor: pointer; color: var(--gkm-text, #eaf2fb); font: inherit; font-size: 13px; }
.gamekit-more-subitem:hover { background: rgba(255, 255, 255, 0.06); }
.gamekit-more-subitem.on { color: var(--gkm-new, #ffce5c); border-color: rgba(255, 206, 92, 0.4); background: rgba(255, 206, 92, 0.10); }
/* animated CRT indicator — cycles the available phosphor colours to hint what's on offer */
.gk-crt-ico { display: inline-block; width: 12px; height: 12px; border-radius: 3px; flex: 0 0 auto;
  background: #46e0a0; box-shadow: 0 0 7px #46e0a0; animation: gkCrtCycle 4.4s linear infinite; }
@keyframes gkCrtCycle {
  0%, 100% { background: #46e0a0; box-shadow: 0 0 7px #46e0a0; }
  25% { background: #ffb454; box-shadow: 0 0 7px #ffb454; }
  50% { background: #5cc8ff; box-shadow: 0 0 7px #5cc8ff; }
  75% { background: #eaf3ff; box-shadow: 0 0 7px #eaf3ff; }
}
@media (prefers-reduced-motion: reduce) { .gk-crt-ico { animation: none; } }

/* themed scrollbars inside every kit overlay — match the box's accent, never the OS default.
   scrollbar-color inherits, so setting it on the overlay root cascades to all scrollable descendants. */
.gamekit-shoppanel, .gamekit-menu, .gamekit-challenges, .gamekit-controls, .gamekit-embed, .gkm-picker-modal {
  scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--gkm-accent, #9fe8ff) 45%, transparent) transparent; }
.gamekit-shoppanel ::-webkit-scrollbar, .gamekit-menu ::-webkit-scrollbar, .gamekit-challenges ::-webkit-scrollbar,
.gamekit-controls ::-webkit-scrollbar, .gamekit-embed ::-webkit-scrollbar, .gkm-picker-modal ::-webkit-scrollbar { width: 9px; height: 9px; }
.gamekit-shoppanel ::-webkit-scrollbar-track, .gamekit-menu ::-webkit-scrollbar-track, .gamekit-challenges ::-webkit-scrollbar-track,
.gamekit-controls ::-webkit-scrollbar-track, .gamekit-embed ::-webkit-scrollbar-track, .gkm-picker-modal ::-webkit-scrollbar-track { background: transparent; }
.gamekit-shoppanel ::-webkit-scrollbar-thumb, .gamekit-menu ::-webkit-scrollbar-thumb, .gamekit-challenges ::-webkit-scrollbar-thumb,
.gamekit-controls ::-webkit-scrollbar-thumb, .gamekit-embed ::-webkit-scrollbar-thumb, .gkm-picker-modal ::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--gkm-accent, #9fe8ff) 42%, transparent); border-radius: 99px; border: 2px solid transparent; background-clip: padding-box; }
.gamekit-shoppanel ::-webkit-scrollbar-thumb:hover, .gamekit-menu ::-webkit-scrollbar-thumb:hover, .gamekit-challenges ::-webkit-scrollbar-thumb:hover,
.gamekit-controls ::-webkit-scrollbar-thumb:hover, .gamekit-embed ::-webkit-scrollbar-thumb:hover, .gkm-picker-modal ::-webkit-scrollbar-thumb:hover {
  background: var(--gkm-accent, #9fe8ff); }


/* ==================================================================================
   SIDE STACK + PROFILE MODAL + TITLES LADDER — kit-owned, ported 1:1 from the catalogue.
   The catalogue mounts these via gamekit.sideStack(); games get them from nav(). The
   :root palette below mirrors the catalogue's — the catalogue re-declares the same
   values, so both render identically; game pages inherit these defaults. */
:root {
  --bg:#0b0f17; --surface:#161c28; --surface-2:#1e2738; --border:#2a3446;
  --text:#eef2f8; --muted:#aab6c8; --faint:#7d8aa0;
  --mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  --sans: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

/* dialog frames for the two kit-owned dialogs (the catalogue styles its other modals itself) */
#profileModal, #titlesModal { border:1px solid var(--border); background:var(--surface); color:var(--text); border-radius:16px; padding:0; width:min(440px,92vw); box-shadow:0 20px 60px rgba(0,0,0,0.6); font-family:var(--sans); }
#profileModal::backdrop, #titlesModal::backdrop { background:rgba(5,8,13,0.66); }
#profileModal { width:min(760px,95vw); overflow:visible; }
#titlesModal { overflow:visible; }
#profileModal .about, #titlesModal .about { padding:18px 20px 20px; display:flex; flex-direction:column; gap:12px; max-height:90vh; overflow-y:auto; }
#profileModal .about.profile { padding-left:4px; padding-right:4px; } /* .pf-scroll owns 16px of the h-inset so its clip leaves room for the title-reveal glow */
#titlesModal .cl-head { display:flex; align-items:center; justify-content:space-between; gap:12px; }
#titlesModal .cl-head h3 { margin:0; font-size:17px; }
.about.profile { max-height:88vh; display:flex; flex-direction:column; overflow:hidden; position:relative; padding:20px; }
.pf-x { position:absolute; top:-13px; right:-13px; z-index:20; width:34px; height:34px; border-radius:50%; background:var(--surface); border:1px solid var(--border); color:var(--muted); font-size:15px; line-height:1; display:flex; align-items:center; justify-content:center; box-shadow:0 4px 14px rgba(0,0,0,0.45); cursor:pointer; }
.pf-x:hover { color:#fff; border-color:#9fe8ff; }
/* narrow portrait OR very short landscape: tuck the corner ✕ inside — the protruding badge
   otherwise pokes into the OS status bar / screen edge on a tall modal (profile + titles) */
@media (max-width:560px), (max-height:359px) { .pf-x { top:6px; right:6px; } }
#profileBody { display:flex; flex-direction:column; min-height:0; flex:1 1 auto; overflow:hidden; }
/* the scroll region is the innermost clipper (overflow-y:auto clips BOTH axes), so the reveal's
   chip + glow need room INSIDE it — pad it 22/16 and pull the same 16 off .about.profile below so
   content stays at 20px from the modal edge */
.pf-scroll { flex:1 1 auto; min-height:0; overflow-y:auto; padding:22px 16px 0; }

  /* side stack (Profile / Challenges / Collection). Two modes, decided by measuring the gutter
     beside .wrap: inline (fits) → a plain fixed column at right:13px; tucked (doesn't fit) → the
     whole column hides off the right edge behind a ‹‹ pull-tab (its clip window's width toggles
     0 ↔ the panel's measured width — at 0 the panel is invisible by construction). */
  /* ONE look at every width: the stack is always the edge drawer (boxed panel + ‹‹/» tab, flush
     against the screen edge). The measured gutter only decides the DEFAULT state — shown when
     there's room beside .wrap, hidden when there isn't — and the tab toggles it either way. */
  .side-stack { position:fixed; top:50%; transform:translateY(-50%); right:0; z-index:40; display:flex; align-items:center; transition:opacity .25s; }
  /* live gameplay: the tucked ‹‹ tab fades so it can't hide game elements under it — full again on hover/expand */
  .side-stack.gameplay-dim { opacity:.3; }
  .side-stack.gameplay-dim:hover, .side-stack.gameplay-dim:focus-within { opacity:1; }
  .side-tab { flex:0 0 auto; width:22px; height:74px; display:flex; align-items:center; justify-content:center;
    background:rgba(6,10,16,0.92); border:1px solid rgba(159,232,255,0.22); border-right:none; border-radius:10px 0 0 10px;
    color:var(--muted); font-size:14px; cursor:pointer; padding:0; box-shadow:-4px 0 14px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,0.08);
    transition:color .12s, border-color .12s, box-shadow .12s; }
  .side-tab:hover { border-color:#9fe8ff; color:#9fe8ff;
    box-shadow:-4px 0 14px rgba(0,0,0,.35), 0 0 0 1px rgba(159,232,255,0.5), 0 0 16px -3px rgba(159,232,255,0.7); }
  .side-stack.shown .side-tab { color:#9fe8ff; }
  /* notification dots: any stack button can carry one; while the drawer is HIDDEN the tab mirrors
     "something inside has a dot" so it's never invisible exactly when it matters */
  .side-btn { position:relative; }
  .side-btn.has-dot::after { content:""; position:absolute; top:-3px; right:-3px; width:9px; height:9px;
    border-radius:50%; background:#ffd166; box-shadow:0 0 6px 1px rgba(255,209,102,0.9); }
  .side-tab { position:relative; }
  .side-tab.has-dot::after { content:""; position:absolute; top:7px; left:50%; transform:translateX(-50%);
    width:8px; height:8px; border-radius:50%; background:#ffd166; box-shadow:0 0 6px 1px rgba(255,209,102,0.9); }
  /* inside the drawer, the NEW rotation gets a chip + a couple of glow pulses, so the dot that led
     you here actually points at something (chip text comes from i18n via data-new) */
  .ch-new { position:relative; }
  .ch-new::after { content:attr(data-new); position:absolute; top:-9px; right:10px; z-index:2; padding:3px 8px;
    border-radius:999px; background:#ffd166; color:#1a1405; font:800 10px/1 var(--mono, monospace); letter-spacing:1px;
    box-shadow:0 0 12px rgba(255,209,102,0.8); animation:chNewIn .5s ease; }
  .ch-new > * { animation:chNewGlow 1.8s ease-in-out 2; border-radius:12px; }
  @keyframes chNewGlow { 0%,100% { box-shadow:none; } 50% { box-shadow:0 0 0 1px #ffd166, 0 0 16px rgba(255,209,102,.55); } }
  @keyframes chNewIn { 0% { opacity:0; transform:translateY(4px) scale(.8); } 100% { opacity:1; transform:none; } }
  @media (prefers-reduced-motion: reduce){ .ch-new::after, .ch-new > * { animation:none; } }
  .side-clip { overflow:hidden; width:0; transition:width .22s ease; }
  .side-stack.shown .side-clip { box-shadow:-4px 0 14px rgba(0,0,0,.35); border-radius:14px 0 0 14px; }
  /* padding also gives the buttons' hover lift/glow headroom against the overflow clip */
  .side-panel { display:flex; flex-direction:column; gap:8px; max-height:calc(100vh - 80px); overflow-y:auto;
    padding:10px; width:max-content; background:var(--surface); border:1px solid var(--border);
    border-right:none; border-radius:14px 0 0 14px; }
  .side-btn { width:130px; height:112px; flex:0 0 auto; display:flex; flex-direction:column; align-items:center;
    justify-content:center; gap:8px; border-radius:16px; border:1px solid var(--border); background:var(--surface-2);
    color:var(--text); cursor:pointer; box-shadow:0 4px 14px rgba(0,0,0,.42); transition:border-color .12s, transform .12s; font:inherit; padding:0; }
  .side-btn:hover { border-color:#9fe8ff; transform:translateY(-1px);
    box-shadow:0 4px 14px rgba(0,0,0,.42), 0 0 0 1px rgba(159,232,255,0.5), 0 0 16px -3px rgba(159,232,255,0.7); }
  .side-btn .ico { font-size:44px; line-height:1; }
  .side-btn .lbl { font-family:var(--mono); font-size:12px; letter-spacing:1px; text-transform:uppercase; color:var(--muted); white-space:normal; padding:0 4px; }
  .side-btn .side-sub { font-family:var(--mono); font-size:11px; color:var(--muted); opacity:.8; max-width:120px;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; padding:0 4px; }
  .side-btn .side-sub:empty { display:none; }
  .side-chal { background:linear-gradient(160deg, rgba(255,206,92,.16), var(--surface-2)); }
  .side-cos { background:linear-gradient(160deg, rgba(185,140,255,.18), var(--surface-2)); }
  .side-profile { background:linear-gradient(160deg, var(--ttbg, rgba(120,130,143,.18)), var(--surface-2)); }
  /* lightweight echo of the profile title box: a tier-scaled glow on the worn emoji + a one-shot
     pulse when a new title lights the dot. CSS-only on purpose — no particle canvas / holo sweep
     (rAF-heavy, and this button is on screen the whole session). Premium tiers (3+) only. */
  .side-profile .ico { filter:var(--ttglow, none); transition:filter .3s ease; }
  .side-profile[data-tt="3"] { --ttglow:drop-shadow(0 0 5px rgba(211,222,237,.6)); }
  .side-profile[data-tt="4"] { --ttglow:drop-shadow(0 0 6px rgba(185,140,255,.7)); }
  .side-profile[data-tt="5"] { --ttglow:drop-shadow(0 0 7px rgba(159,232,255,.8)); }
  .side-profile[data-tt="6"] { --ttglow:drop-shadow(0 0 8px rgba(127,232,208,.85)); }
  .side-profile[data-tt="7"] { --ttglow:drop-shadow(0 0 9px rgba(255,138,209,.9)); }
  .side-profile[data-tt="8"] { --ttglow:drop-shadow(0 0 11px rgba(255,215,106,1)); }
  @keyframes ttPulse { 0% { transform:none; } 30% { transform:translateY(-1px) scale(1.05); box-shadow:0 4px 14px rgba(0,0,0,.42), 0 0 0 3px rgba(255,209,102,.55), 0 0 22px rgba(255,209,102,.5); } 100% { transform:none; } }
  .side-profile.tt-pulse { animation:ttPulse .9s ease-out; }
  @media (prefers-reduced-motion: reduce){ .side-profile.tt-pulse { animation:none; } }
/* on game pages the kit menu overlay sits at z 60 — lift the stack above it there so it stays
   clickable on menu screens (the catalogue has no .gamekit-menu, so this never fires at home) */
body:has(.gamekit-menu) .side-stack { z-index:70; }
  /* short landscape: compact cards so the opened drawer fits the viewport instead of spilling
     under the nav cluster and past the bottom edge */
  @media (orientation: landscape) and (max-height: 560px) {
    .side-panel { gap:6px; padding:8px; max-height:calc(100vh - 24px); }
    .side-btn { width:104px; height:64px; gap:3px; border-radius:12px; }
    .side-btn .ico { font-size:24px; }
    .side-btn .lbl { font-size:9.5px; letter-spacing:.5px; }
    .side-btn .side-sub { display:none; }
  }

  .profile .pf-name { color:var(--muted); font-size:14px; margin:-4px 0 2px; }
  /* identity row: name (left) + genre · since (right), reusing the modal header line */
  #pfTitle { display:flex; align-items:baseline; flex:1; min-width:0; gap:8px 14px; flex-wrap:wrap; }
  #pfTitle .pf-meta { margin-left:auto; font-family:inherit; font-weight:400; font-size:12px; letter-spacing:0; color:var(--faint); white-space:nowrap; }
  /* the four core counts — a clean centered strip with dividers (understated, not title-flashy) */
  .pf-stats { display:flex; justify-content:center; flex-wrap:wrap; margin:2px 0 4px; border:1px solid var(--border); border-radius:12px; background:linear-gradient(180deg,rgba(255,255,255,0.02),transparent),var(--surface); overflow:hidden; }
  .pf-stat { flex:1 1 0; min-width:64px; display:flex; flex-direction:column; align-items:center; gap:1px; padding:7px 8px; text-align:center; }
  .pf-stat + .pf-stat { border-left:1px solid var(--border); }
  .pf-stat b { font-size:19px; color:var(--text); font-variant-numeric:tabular-nums; line-height:1.1; }
  .pf-stat span { font-size:10px; letter-spacing:.07em; text-transform:uppercase; color:var(--faint); }
  /* collection progress bar (below the stats) — tap to open the Cosmetics store */
  .pf-collect { display:block; width:100%; margin:8px 0 4px; padding:10px 13px; border:1px solid var(--border); border-radius:12px; background:var(--surface); cursor:pointer; text-align:left; color:var(--muted); }
  .pf-collect:hover { border-color:#ffce5c; }
  /* the achievements track, until the feature lands: same row, visibly not started */
  .pf-soon { opacity:.62; }
  .pf-soon .pf-collect-n { color:var(--muted); font-weight:600; }
  .pf-collect-top { display:flex; justify-content:space-between; align-items:center; gap:10px; font-family:var(--mono); font-size:11px; letter-spacing:.5px; }
  .pf-collect-n { color:#e8c069; font-weight:700; font-variant-numeric:tabular-nums; }
  /* min-height (not just height) so the bar keeps its size in the share snapshot, which strips
     width/height; the gold fill is a background gradient set inline per render */
  .pf-collect-bar { display:block; width:100%; height:10px; min-height:10px; margin-top:8px; border-radius:99px; background:rgba(255,255,255,0.09); overflow:hidden; }
  /* "Title · see ladder ›" link inside the profile title box — a clear accent link (the faint
     label colour washed out against high-tier title glows) */
  .pf-title-link { background:none; border:none; padding:0; font:inherit; letter-spacing:inherit; cursor:pointer;
    color:#bfe6ff; text-decoration:underline; text-underline-offset:2px; text-decoration-color:rgba(159,232,255,0.45); }
  .pf-title-link:hover { color:#ffce5c; text-decoration-color:#ffce5c; }
  /* per-card column labels so the value column reads as "best" and the mode column is named */
  .pf-rhead { display:grid; grid-template-columns:1fr auto; gap:12px; font-size:9.5px; letter-spacing:.09em; text-transform:uppercase; color:var(--faint); padding-bottom:5px; margin-bottom:2px; border-bottom:1px solid var(--border); }
  .pf-rhead span:last-child { text-align:right; }
  .pf-sec { font-size:11px; letter-spacing:.08em; text-transform:uppercase; color:var(--faint); margin:16px 0 8px; border-top:1px solid var(--border); padding-top:14px; }
  /* one unified per-game block (most-played first): header = title + total plays, then each mode's best.
     Tint matches the catalogue tiles (accent radial from the top) so a game reads the same everywhere. */
  .pf-tinted { border:1px solid color-mix(in srgb, var(--acc,#9fe8ff) 28%, var(--border)); background:radial-gradient(120% 130% at 50% 0%, color-mix(in srgb, var(--acc,#9fe8ff) 20%, var(--surface)), var(--surface) 70%); }
  .pf-games { display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:10px; align-items:stretch; }
  .pf-game { border-radius:12px; padding:12px 14px; }
  .pf-gh { display:flex; align-items:baseline; justify-content:space-between; gap:10px; margin-bottom:9px; }
  .pf-gt { font-size:14.5px; font-weight:600; color:var(--text); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .pf-gp { flex:0 0 auto; font-size:12px; color:var(--faint); font-variant-numeric:tabular-nums; }
  .pf-gp b { color:var(--text); font-weight:700; font-size:15px; }
  .pf-rows { display:flex; flex-direction:column; gap:3px; }
  .pf-row { display:grid; grid-template-columns:1fr auto; align-items:baseline; gap:12px; font-size:14px; }
  .pf-row .pr-mode { color:var(--muted); min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .pf-row .pr-mode .pr-x { color:var(--faint); font-size:12px; margin-left:5px; }
  .pf-row .pr-val { color:var(--text); font-weight:600; font-variant-numeric:tabular-nums; white-space:nowrap; text-align:right; }
  .pf-empty { color:var(--muted); font-size:15px; line-height:1.6; }
  /* pinned to the bottom of the panel (outside the scroll area) so it's always reachable */
  .pf-share { flex:0 0 auto; margin:0 -4px -20px; padding:13px 20px 20px; border-top:1px solid var(--border); background:var(--surface); } /* -4px = the reduced .about.profile h-padding, so the footer still full-bleeds to the modal edge */
  .pf-share button { width:100%; padding:11px; border-radius:10px; border:1px solid var(--border); background:var(--surface); color:var(--text); font-weight:600; cursor:pointer; }
  .pf-share button:hover { border-color:#9fe8ff; }
  /* ---- earned title (lifetime challenge points) — escalating shine, tier 0→8 ---- */
  .pf-titlebar { position:relative; overflow:hidden; display:flex; align-items:center; gap:12px; padding:13px 16px; margin-bottom:12px; border:1px solid var(--border); border-radius:13px; background:linear-gradient(180deg,rgba(255,255,255,0.02),transparent),var(--surface); }
  .pf-tb-emoji { font-size:22px; flex:0 0 auto; position:relative; z-index:2; }
  .pf-tb-main { position:relative; z-index:2; flex:1 1 auto; min-width:0; display:flex; flex-direction:column; gap:3px; }
  .pf-tb-label { display:inline-flex; align-items:center; gap:5px; font-size:9px; letter-spacing:.16em; text-transform:uppercase; color:var(--faint); white-space:nowrap; }
  .pf-title { position:relative; font-size:clamp(15px,4.4vw,19px); line-height:1.15; }
  .pf-tb-name { position:relative; z-index:2; font-size:13px; color:var(--muted); display:flex; align-items:center; gap:6px; min-width:0; }
  /* right column: challenge points (emphasised) + good runs + since date */
  .pf-tb-meta { flex:0 0 auto; position:relative; z-index:2; display:flex; flex-direction:column; align-items:flex-end; gap:8px; text-align:right; }
  .pf-tb-pts { font-family:var(--mono); font-size:16px; font-weight:700; color:var(--text); font-variant-numeric:tabular-nums; white-space:nowrap; line-height:1.2; }
  .pf-tb-pts span { display:block; font-size:8.5px; font-weight:400; letter-spacing:1px; color:var(--faint); margin-top:2px; }
  .pf-tb-mini { font-size:12px; color:var(--muted); white-space:nowrap; }
  .pf-tb-mini b { color:var(--text); font-variant-numeric:tabular-nums; }
  button.pf-tb-cos { background:none; border:none; padding:0; font:inherit; font-size:12px; cursor:pointer; text-align:right; }
  button.pf-tb-cos:hover b { color:#ffce5c; }
  /* Narrow: the two side-by-side columns don't fit — the title link ran under the trophy count
     (already 34px over in English, worse in every longer language). Drop the meta column to its
     own full-width row and lay it out horizontally; the stat labels shed letter-spacing so a long
     single word ("ROZGRYWEK") stops being clipped — an unbreakable word can't wrap. */
  @media (max-width: 560px) {
    .pf-titlebar:not(.pf-compact) { flex-wrap:wrap; }
    .pf-titlebar:not(.pf-compact) .pf-tb-main { flex:1 1 60%; }
    .pf-titlebar:not(.pf-compact) .pf-tb-meta { flex:1 1 100%; flex-direction:row; flex-wrap:wrap; align-items:baseline;
      justify-content:flex-start; gap:6px 14px; text-align:left; margin-top:9px; padding-top:9px; border-top:1px solid var(--border); }
    .pf-titlebar:not(.pf-compact) .pf-tb-pts { font-size:15px; }
    .pf-titlebar:not(.pf-compact) .pf-tb-pts span { display:inline; margin:0 0 0 5px; }
    .pf-stat { padding:7px 4px; min-width:0; }
    .pf-stat span { font-size:9px; letter-spacing:0; }
  }
  .pf-pfx { position:absolute; inset:0; width:100%; height:100%; pointer-events:none; z-index:1; }
  /* soft glow behind the title — a blurred rounded block so it covers a wrapped 2-line title
     (an ellipse only lit the middle line); the per-glyph text-shadow/drop-shadow handles the rest */
  .pf-halo { position:absolute; inset:-6px -14px; z-index:0; border-radius:14px; filter:blur(15px); opacity:0; pointer-events:none; }
  .pf-sh { position:relative; z-index:1; display:inline-block; max-width:100%; font-family:var(--mono); font-weight:700; letter-spacing:.5px; }
  .pf-t0 .pf-sh { color:#78828f; }
  .pf-t1 .pf-sh { color:#c3ccd8; }
  .pf-t2 .pf-sh { color:#d0954f; text-shadow:0 0 7px rgba(208,149,79,.4); }
  .pf-t3 .pf-sh { background-image:linear-gradient(180deg,#7f8b9c,#d7e0ec 42%,#fff 50%,#c2cddb 58%,#74808f); -webkit-background-clip:text; background-clip:text; color:transparent; filter:drop-shadow(0 0 6px rgba(211,222,237,.5)); }
  .pf-t4 .pf-sh { color:#c39cff; text-shadow:0 0 12px rgba(160,110,255,.85),0 0 26px rgba(160,110,255,.45); }
  .pf-t5 .pf-sh,.pf-t6 .pf-sh,.pf-t7 .pf-sh,.pf-t8 .pf-sh { color:transparent; -webkit-background-clip:text; background-clip:text; }
  .pf-t5 .pf-sh { background-image:linear-gradient(90deg,#b98cff,#9fe8ff); filter:drop-shadow(0 0 9px rgba(159,180,255,.6)); }
  .pf-t6 .pf-sh { background-image:linear-gradient(100deg,#6fe0cf,#9fe8ff 40%,#fff 50%,#9fe8ff 60%,#6fe0cf); background-size:250% 100%; filter:drop-shadow(0 0 10px rgba(159,232,255,.65)); animation:pftSweep 3.4s linear infinite; }
  .pf-t7 .pf-sh { background-image:linear-gradient(90deg,#ff8ad1,#b98cff,#9fe8ff,#7fffc4,#ff8ad1); background-size:300% 100%; animation:pftHolo 5s linear infinite,pftPulse 2.4s ease-in-out infinite; }
  .pf-t8 .pf-sh { background-image:linear-gradient(90deg,#ffd76a,#fff3c0,#ff9ad1,#9fe8ff,#ffd76a); background-size:300% 100%; animation:pftHolo 4s linear infinite,pftPulseGold 2s ease-in-out infinite; }
  .pf-t3 .pf-halo { opacity:1; background:rgba(211,222,237,.22); }
  .pf-t4 .pf-halo { opacity:1; background:rgba(160,110,255,.32); animation:pftBreathe 3.4s ease-in-out infinite; }
  .pf-t5 .pf-halo { opacity:1; background:rgba(159,180,255,.34); animation:pftBreathe 3.2s ease-in-out infinite; }
  .pf-t6 .pf-halo { opacity:1; background:rgba(159,232,255,.38); animation:pftBreathe 3s ease-in-out infinite; }
  .pf-t7 .pf-halo { opacity:1; background:rgba(185,140,255,.4); animation:pftBreathe 2.6s ease-in-out infinite; }
  .pf-t8 .pf-halo { opacity:1; background:rgba(255,215,106,.42); animation:pftBreathe 2.2s ease-in-out infinite; }
  .pf-gl::after { content:attr(data-text); position:absolute; inset:0; width:100%; white-space:normal; z-index:2; pointer-events:none; background-image:linear-gradient(115deg,transparent 42%,rgba(255,255,255,.95) 50%,transparent 58%); background-size:220% 100%; -webkit-background-clip:text; background-clip:text; color:transparent; -webkit-text-fill-color:transparent; animation:pftGlint 3.8s ease-in-out infinite; }
  .pf-t0 .pf-gl::after, .pf-t1 .pf-gl::after, .pf-t2 .pf-gl::after { display:none; } /* rare shine starts at Knight */
  .pf-t3 .pf-gl::after { background-image:linear-gradient(115deg,transparent 45%,#fff 50%,transparent 55%); animation-duration:3.1s; }
  .pf-t6 .pf-gl::after { animation-duration:3.2s; }
  .pf-t7 .pf-gl::after { animation-duration:2.6s; }
  .pf-t8 .pf-gl::after { background-image:linear-gradient(115deg,transparent 40%,rgba(255,247,208,1) 50%,transparent 60%); animation-duration:2.1s; }
  @keyframes pftSweep { to { background-position:-166.667% 0; } } /* one exact tile at size 250% (see badgeShine note) — was 1.5 tiles, jumping each wrap */
  @keyframes pftHolo { to { background-position:300% 0; } }
  @keyframes pftPulse { 0%,100%{ filter:drop-shadow(0 0 7px rgba(185,140,255,.55)); } 50%{ filter:drop-shadow(0 0 16px rgba(159,232,255,.95)); } }
  @keyframes pftPulseGold { 0%,100%{ filter:drop-shadow(0 0 9px rgba(255,215,106,.6)); } 50%{ filter:drop-shadow(0 0 20px rgba(255,215,106,1)); } }
  @keyframes pftBreathe { 0%,100%{ transform:scale(.92); opacity:.7; } 50%{ transform:scale(1.08); opacity:1; } }
  @keyframes pftGlint { 0%{ background-position:180% 0; } 42%,100%{ background-position:-90% 0; } }
  /* titles ladder modal — every rank prerendered with its tier shine, points only */
  /* clickable display name (rename) with an instant tooltip */
  .pf-name-btn { position:relative; background:none; border:none; padding:0; cursor:pointer; color:inherit; font:inherit; display:inline-flex; align-items:center; text-align:left; }
  .pf-name-btn:hover .pf-sh, .pf-name-btn:focus-visible .pf-sh { text-decoration:underline dotted; text-underline-offset:3px; }
  .pf-tt { position:absolute; bottom:calc(100% + 7px); left:0; z-index:4; background:#0c111c; border:1px solid var(--border); color:var(--muted); font:600 10.5px var(--mono); letter-spacing:.4px; padding:5px 9px; border-radius:7px; white-space:nowrap; opacity:0; pointer-events:none; transition:opacity .1s; }
  .pf-name-btn:hover .pf-tt, .pf-name-btn:focus-visible .pf-tt { opacity:1; }
  .pf-pen { width:12px; height:12px; margin-left:6px; flex:0 0 auto; fill:var(--faint); }
  .pf-name-btn:hover .pf-pen, .pf-name-btn:focus-visible .pf-pen { fill:#9fe8ff; }
  .about.titles { max-height:88vh; overflow-y:auto; }
  .tl-sub { color:var(--muted); font-size:13.5px; margin:0 0 4px; }
  /* The ladder FILLS its box: 9 rows share whatever height the pane has, so a tall modal has no dead
     space under the last rank. Rows shrink to --tl-min and the pane scrolls from there (they are the
     same rows in the profile dialog, which sizes itself, and in the Collection modal's Titles tab). */
  .tl-list { display:flex; flex-direction:column; gap:6px; --tl-min:46px; }
  .tl-row { position:relative; overflow:hidden; display:flex; align-items:center; gap:10px; padding:9px 12px; border:1px solid var(--border); border-radius:11px; background:var(--surface);
    flex:1 1 auto; min-height:var(--tl-min); }
  @media (max-height: 520px) { .tl-list { --tl-min:38px; } }
  .tl-row .pf-title { font-size:15px; min-width:0; }
  .tl-emoji { font-size:17px; flex:0 0 auto; }
  .tl-pts { margin-left:auto; flex:0 0 auto; font-family:var(--mono); font-size:12px; color:var(--faint); font-variant-numeric:tabular-nums; white-space:nowrap; }
  .tl-cur { border-color:#9fe8ff; }
  .tl-cur .tl-pts { color:var(--text); }
  /* unlocked ranks are tap-to-equip; the worn one is highlighted, locked ones dimmed */
  .tl-unlocked { cursor:pointer; }
  .tl-unlocked:hover { border-color:#9fe8ff; }
  .tl-unlocked:not(.tl-cur):hover .tl-pts { color:#9fe8ff; }
  .tl-locked { opacity:0.62; }
  .tl-worn { color:#7fe0a0; font-weight:700; }
  @media (prefers-reduced-motion: reduce) { .pf-sh, .pf-halo, .pf-gl::after { animation:none !important; } .pf-halo { opacity:.8; } }

  /* one-shot "★ NEW TITLE" reveal on the profile modal's titlebar (the side-stack dot leads here) */
  .pf-titlebar.pf-reveal { animation:idReveal 1.4s cubic-bezier(.2,1.2,.4,1); border-color:#ffd166; overflow:visible; }
  .pf-titlebar.pf-reveal::after { content:"★ NEW TITLE"; position:absolute; top:-9px; right:10px; z-index:2; padding:3px 8px; border-radius:999px;
    background:#ffd166; color:#1a1405; font:800 10px/1 var(--mono, monospace); letter-spacing:1px;
    box-shadow:0 0 12px rgba(255,209,102,0.8); animation:idChip 2.4s ease forwards; }
  @keyframes idReveal { 0% { transform:scale(.94); filter:brightness(1.7) drop-shadow(0 0 18px rgba(255,209,102,.9)); }
    45% { transform:scale(1.03); } 100% { transform:scale(1); filter:none; } }
  @keyframes idChip { 0% { opacity:0; transform:translateY(4px); } 12%,80% { opacity:1; transform:translateY(0); } 100% { opacity:0; } }
  @media (prefers-reduced-motion: reduce){ .pf-titlebar.pf-reveal { animation:none; } .pf-titlebar.pf-reveal::after { animation:none; } }

/* ---- shared hint affordance (gamekit.hintButton) — one bottom-centre button + a toast that is
   laid out ABOVE it, so the text can never sit under the tap target. Games reserve `reserve` px
   of bottom band via layout.archetype so the board never grows under it. ---- */
.gamekit-hintwrap { position: fixed; left: 50%; bottom: 8px; transform: translateX(-50%); z-index: 6;
  display: flex; flex-direction: column; align-items: center; gap: 6px; pointer-events: none; max-width: min(94vw, 560px); }
.gamekit-hintbtn { pointer-events: auto; font: 700 12px/1 ui-monospace, "SFMono-Regular", Menlo, monospace;
  letter-spacing: 1.5px; color: var(--gkm-text, #eef2f8); background: rgba(8, 12, 20, 0.72);
  border: 1px solid var(--gkm-accent, #9fe8ff); border-radius: 999px; padding: 9px 18px; cursor: pointer;
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.gamekit-hintbtn:hover { background: rgba(16, 24, 38, 0.86); }
.gamekit-hinttip { display: none; pointer-events: none; text-align: center;
  font: 600 12px/1.45 ui-monospace, "SFMono-Regular", Menlo, monospace; color: #eef2f8;
  background: rgba(8, 12, 20, 0.88); border: 1px solid rgba(255, 255, 255, 0.22); border-radius: 10px;
  padding: 8px 12px; max-width: 100%; }
.gamekit-hinttip.show { display: block; }
/* Toast opens DOWNWARD (gamekit.hintButton({tipBelow:true})): the tip leaves the flow and hangs
   under the button, so the wrap itself stays exactly the height of the button (it fits the reserved
   band) and the text covers whatever the game keeps below it — its own control strip — instead of
   the play area above. DOM order is untouched (tip first, button last). */
.gamekit-hintwrap.gk-hint-tipdown .gamekit-hinttip { position: absolute; top: calc(100% + 6px);
  left: 50%; transform: translateX(-50%); width: min(94vw, 460px); max-width: 94vw; }
.gamekit-hintwrap.gk-hint-side.gk-hint-tipdown .gamekit-hinttip,
.gamekit-hintwrap.gk-hint-side-r.gk-hint-tipdown .gamekit-hinttip { width: 100%; left: 0; transform: none; }
/* tap the text to dismiss it — the point of tipBelow is that it may sit over the game's own keys */
.gamekit-hinttip.show { pointer-events: auto; cursor: pointer; }
/* Landscape dock (gamekit.hintButton().dock('left')): a left-edge rail instead of a bottom strip —
   a short screen cannot spare 46px of height for a button, but it has width to burn. Vertically
   centred so it clears the top nav; the toast stacks under the button inside the rail. */
.gamekit-hintwrap.gk-hint-side { left: 6px; right: auto; bottom: auto; top: 50%;
  transform: translateY(-50%); align-items: stretch; width: 134px; max-width: 134px; }
.gamekit-hintwrap.gk-hint-side .gamekit-hintbtn { width: 100%; padding: 8px 6px; }
.gamekit-hintwrap.gk-hint-side .gamekit-hinttip { text-align: left; font-size: 10.5px; line-height: 1.4; padding: 7px 9px; }
/* right rail, anchored under the HUD — for a game whose own control strip owns the bottom of that
   column in landscape (Sudoku's number pad docks bottom-right) */
.gamekit-hintwrap.gk-hint-side-r { left: auto; right: 6px; bottom: auto; top: 58px; transform: none;
  align-items: stretch; width: 158px; max-width: 158px; }
.gamekit-hintwrap.gk-hint-side-r .gamekit-hintbtn { width: 100%; padding: 8px 6px; }
.gamekit-hintwrap.gk-hint-side-r .gamekit-hinttip { text-align: left; font-size: 10.5px; line-height: 1.4; padding: 7px 9px; }
@media (max-height: 420px) {   /* landscape phones: keep it tight so the board keeps its height */
  .gamekit-hintwrap { bottom: 4px; }
  .gamekit-hintbtn { padding: 6px 14px; font-size: 11px; }
  .gamekit-hinttip { font-size: 11px; padding: 6px 10px; }
}
