/* Self-hosted UI fonts (variable woff2) — no online dependency, works in the
   offline APK. One file per family covers the full weight range. */
@font-face {
  font-family: 'Manrope';
  src: url('fonts/manrope.woff2') format('woff2');
  font-weight: 400 800; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('fonts/jetbrainsmono.woff2') format('woff2');
  font-weight: 400 700; font-style: normal; font-display: swap;
}

:root {
  --font-ui: 'Manrope', system-ui, "Segoe UI", Roboto, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, "SF Mono", Menlo, monospace;
  /* Console redesign tokens (handoff) */
  --bg: #0a0820;
  --bg2: #1a1640;
  --frame-a: #120f2c;
  --frame-b: #0d0a24;
  --card: #171234;
  --card-border: rgba(255,255,255,.07);
  --inset-bg: rgba(0,0,0,.3);
  --inset-border: #2c2552;
  --btn-border: #322a5a;
  --gold: #f5c542;
  --teal: #57b6e8;
  --green: #6ee0a0;
  --text: #e9eaf5;
  --body: #a9a7cf;
  --body2: #c9c7e6;
  --muted: #8a88b5;
  --muted2: #6a6796;
  /* per-game accent — set on .console by app.js */
  --game-accent: #57b6e8;
  /* legacy aliases used by the preserved game-stage block below */
  --accent: var(--gold);
  --accent2: var(--teal);
  --good: var(--green);
  --panel: var(--card);
  --border: var(--btn-border);
}

* { box-sizing: border-box; }

/* The `hidden` attribute must always win, even over rules like
   `.game-stage { display: flex }` below (otherwise the full-screen game
   overlay covers the launcher from page load). */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  min-height: 100%;
  background: radial-gradient(circle at 50% -10%, var(--bg2), var(--bg) 60%);
  color: var(--text);
  font-family: var(--font-ui);
}
select option { background: #0c0a22; color: var(--text); }

/* ===================== launcher console ===================== */
.console-wrap {
  min-height: 100dvh;
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  padding: 30px 18px 40px;
}
.console {
  width: min(1060px, 100%);
  background: linear-gradient(180deg, var(--frame-a), var(--frame-b));
  border: 1px solid #262048;
  border-radius: 14px;
  box-shadow: 0 30px 80px rgba(0,0,0,.55);
  overflow: hidden;
  display: flex; flex-direction: column;
}

.console-top {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 16px 26px; border-bottom: 1px solid rgba(255,255,255,.06);
}
.brand { display: flex; align-items: center; gap: 11px; }
.wordmark { font: 800 21px var(--font-ui); letter-spacing: 4px; color: var(--gold); }
.eps-pill { color: var(--teal); letter-spacing: 1px; }
.browser-pill {
  font: 600 10px var(--font-ui); letter-spacing: 1.5px; color: var(--muted);
  border: 1px solid var(--btn-border); border-radius: 5px; padding: 2px 7px;
}
.nav-top { display: flex; align-items: center; gap: 5px; }
.nav-btn {
  padding: 8px 16px; border: none; border-radius: 9px;
  font: 600 13px var(--font-ui); color: #9a98c0; background: transparent; cursor: pointer;
}
.nav-btn.active { background: rgba(245,197,66,.14); color: var(--gold); font-weight: 700; }

/* ----- game-selector bar ----- */
.game-bar { padding: 16px 26px 0; }
.game-bar-label { display: flex; align-items: center; gap: 8px; margin-bottom: 11px; }
.game-bar-label span:first-child {
  font: 700 11px var(--font-ui); letter-spacing: 1.4px; text-transform: uppercase; color: var(--muted2);
}
.hairline { flex: 1; height: 1px; background: rgba(255,255,255,.06); }
.game-tabs { display: flex; gap: 12px; }
.game-tab {
  flex: 1; text-align: left; cursor: pointer; padding: 13px 16px; border-radius: 14px;
  font-family: var(--font-ui);
  background: rgba(0,0,0,.22); border: 1.5px solid var(--inset-border);
}
.game-tab.active {
  background: rgba(245,197,66,.10);
  border: 1.5px solid var(--game-accent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--game-accent) 20%, transparent);
}
.gt-row { display: flex; align-items: baseline; gap: 8px; }
.gt-num { font: 800 18px var(--font-ui); color: var(--body2); }
.game-tab.active .gt-num { color: var(--gold); }
.gt-files { font: 600 11px var(--font-ui); color: var(--muted); }
.gt-title { font: 600 12.5px var(--font-ui); color: var(--body2); margin-top: 3px; display: block; }
.gt-status { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; font: 600 11px var(--font-ui); color: var(--muted); }
.gt-dot { width: 7px; height: 7px; border-radius: 50%; background: #5a5a8a; }
.game-tab.synced .gt-status { color: var(--green); }
.game-tab.synced .gt-dot { background: var(--green); }

/* mobile sub-bar (status pill + game switcher / global label) */
.m-subbar { display: none; }

.console-body { padding: 18px 26px 26px; }

/* cards */
.card {
  background: var(--card); border: 1px solid var(--card-border);
  border-radius: 18px; padding: 18px 20px; box-shadow: 0 10px 30px rgba(0,0,0,.3);
}
.card-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 4px; }
.card-head-right { display: flex; align-items: center; gap: 10px; }
.card-head-baseline { display: flex; align-items: baseline; gap: 12px; margin-bottom: 16px; }
.card-title { font: 700 15px var(--font-ui); color: var(--text); }
.card-title.big { font-size: 16px; }
.card-sub { font: 400 13px var(--font-ui); color: var(--muted2); }
.card-note { margin: 0 0 12px; font: 400 11.5px var(--font-ui); color: var(--muted2); line-height: 1.5; }
.card-note.status-line { margin: 10px 0 0; }

.game-badge {
  font: 700 11px var(--font-ui); color: var(--game-accent);
  background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.08);
  padding: 3px 9px; border-radius: 20px; white-space: nowrap;
}

/* hero */
.hero-card { padding: 0; overflow: hidden; }
.hero-poster { display: block; width: 100%; border: 0; padding: 0; cursor: pointer; position: relative; height: 272px; background: #08061a; }
.poster-bg { position: absolute; inset: 0; background: radial-gradient(ellipse at 50% 40%, #20407a, #0c0a22 74%); }
.poster-scan { position: absolute; inset: 0; background: repeating-linear-gradient(0deg, transparent 0 2px, rgba(0,0,0,.3) 3px, transparent 4px); }
.poster-fg { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; }
.poster-title { font: 800 46px var(--font-ui); letter-spacing: 8px; color: var(--gold); text-shadow: 0 0 30px #f5c54255; }
.poster-sub { font: 700 13px var(--font-ui); letter-spacing: 5px; color: var(--teal); }
.poster-play { margin-top: 6px; width: 62px; height: 62px; border-radius: 50%; background: rgba(245,197,66,.95); display: flex; align-items: center; justify-content: center; color: #1a1206; font-size: 23px; padding-left: 4px; box-shadow: 0 8px 28px rgba(245,197,66,.4); }
.hero-foot { padding: 20px 22px; display: flex; align-items: center; justify-content: space-between; gap: 18px; }
.hero-blurb { margin: 0; color: var(--body); font: 400 14px var(--font-ui); line-height: 1.55; max-width: 42ch; }
.hero-blurb a { color: var(--teal); text-decoration: none; cursor: pointer; }
.hero-blurb em { color: var(--text); font-style: italic; }

.play-btn {
  flex: 0 0 auto; padding: 14px 24px;
  background: linear-gradient(180deg, #f7cf54, #e8a93c); color: #1a1206;
  border: none; border-radius: 12px; font: 800 15px var(--font-ui); cursor: pointer;
  box-shadow: 0 10px 24px rgba(245,197,66,.25); white-space: nowrap;
}
.play-btn:hover:not(:disabled) { filter: brightness(1.04); }
.play-btn:disabled { opacity: .45; cursor: not-allowed; }
.play-btn.inline { padding: 12px 26px; font-size: 14px; min-width: 170px; }

/* right rail */
.rail { display: flex; flex-direction: column; gap: 18px; }

/* saved game card */
.save-size { font: 800 26px var(--font-ui); color: var(--gold); margin: 6px 0 14px; }
.save-btns { display: flex; gap: 8px; }
.save-btns .btn-2 { flex: 1; }
.empty-box { margin: 8px 0 12px; padding: 14px; border: 1px dashed var(--btn-border); border-radius: 12px; text-align: center; color: var(--muted); font: 500 12.5px var(--font-ui); line-height: 1.5; }
.empty-box code { color: var(--teal); }
.btn-2 { padding: 10px 6px; background: #221c44; color: var(--text); border: 1px solid var(--btn-border); border-radius: 10px; font: 700 12.5px var(--font-ui); cursor: pointer; }
.btn-2.full { width: 100%; }
.btn-2:hover:not(:disabled) { filter: brightness(1.15); }
.btn-2:disabled { opacity: .4; cursor: not-allowed; }
.btn-danger { flex: 0 0 auto; padding: 10px 12px; background: #3a1a2a; color: #ff9ab5; border: 1px solid #5a2a40; border-radius: 10px; font: 700 12.5px var(--font-ui); cursor: pointer; }
.btn-danger:disabled { opacity: .4; cursor: not-allowed; }
.muted-note { margin: 8px 0 0; color: var(--muted); font: 400 12.5px var(--font-ui); line-height: 1.55; }
.muted-note code { background: #0005; padding: .1em .35em; border-radius: 4px; color: var(--teal); }
.muted-note strong { color: var(--body2); }

/* switch */
.switch { position: relative; width: 42px; height: 24px; flex: 0 0 auto; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch-knob { position: absolute; inset: 0; border-radius: 20px; background: #4a4570; transition: background .15s; }
.switch-knob::after { content: ""; position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; transition: transform .15s; }
.switch input:checked + .switch-knob { background: var(--green); }
.switch input:checked + .switch-knob::after { transform: translateX(18px); }

/* sync key + devices + link */
.key-row { display: flex; align-items: center; gap: 8px; background: var(--inset-bg); border: 1px solid var(--inset-border); border-radius: 10px; padding: 8px 11px; margin-bottom: 12px; }
.key-row code { flex: 1; font: 700 13px var(--font-mono); color: var(--teal); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; letter-spacing: .04em; }
.btn-key { flex: 0 0 auto; min-width: 62px; padding: 6px 11px; border-radius: 8px; font-size: 12px; }
.device-rows { display: flex; flex-direction: column; gap: 7px; margin-bottom: 12px; }
.device-row { display: flex; align-items: center; gap: 9px; font: 600 12.5px var(--font-ui); color: var(--body2); }
.device-row .dot { width: 7px; height: 7px; border-radius: 50%; background: #5a5a8a; }
.device-row .dot.good { background: var(--green); }
.device-row .dim { color: var(--muted2); font-weight: 400; }
.link-row { display: flex; gap: 8px; margin-bottom: 10px; }
.link-row input { flex: 1; min-width: 0; padding: 8px 11px; background: var(--inset-bg); color: var(--text); border: 1px solid var(--inset-border); border-radius: 10px; font: 600 13px var(--font-mono); text-transform: uppercase; letter-spacing: .06em; }
.btn-dashed { width: 100%; padding: 9px; background: transparent; color: var(--teal); border: 1px dashed var(--btn-border); border-radius: 10px; font: 700 12.5px var(--font-ui); cursor: pointer; }
.off-note { padding: 12px; border: 1px solid var(--inset-border); border-radius: 10px; background: rgba(0,0,0,.2); color: var(--muted); font: 500 12px var(--font-ui); line-height: 1.5; }
.off-restore { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--inset-border); }
.off-restore-label { margin-bottom: 8px; color: var(--muted2); font: 500 12px var(--font-ui); line-height: 1.5; }
.off-restore .link-row { margin-bottom: 0; }
.linklike { background: none; border: none; padding: 0; cursor: pointer; color: var(--teal); text-decoration: underline; font: inherit; }

/* how to play */
.controls-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 13px 40px; margin-top: 6px; }
.ctl { display: flex; align-items: center; gap: 9px; font: 500 13.5px var(--font-ui); color: var(--body); }
.cap { display: inline-flex; align-items: center; justify-content: center; height: 24px; padding: 0 8px; background: rgba(0,0,0,.4); border: 1px solid var(--btn-border); border-bottom-width: 2px; border-radius: 6px; font: 700 12px var(--font-mono); color: var(--teal); }
.howto-note { margin: 18px 0 0; padding-top: 16px; border-top: 1px solid rgba(255,255,255,.06); color: var(--muted); font: 400 13px var(--font-ui); line-height: 1.6; }
.howto-note strong { color: var(--body2); }

/* settings */
.settings-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px 44px; margin-top: 4px; }
.set-row { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.set-label { font: 600 13.5px var(--font-ui); color: var(--body2); }
.seg { display: inline-flex; background: var(--inset-bg); border: 1px solid var(--btn-border); border-radius: 11px; padding: 3px; }
.seg button { padding: 7px 14px; border: none; border-radius: 8px; font: 600 12.5px var(--font-ui); color: #9a98c0; background: transparent; cursor: pointer; white-space: nowrap; }
.seg button.active { background: var(--gold); color: #1a1206; font-weight: 700; }
.set-row select { min-width: 210px; padding: 9px 12px; background: var(--inset-bg); color: var(--text); border: 1px solid var(--btn-border); border-radius: 11px; font: 600 12.5px var(--font-ui); cursor: pointer; }

/* ===================== modals ===================== */
.overlay { position: fixed; inset: 0; z-index: 2000; background: rgba(8,6,22,.74); display: flex; align-items: center; justify-content: center; padding: 24px; }
.modal-box { position: relative; width: 460px; max-width: 100%; background: var(--card); border: 1px solid rgba(255,255,255,.1); border-radius: 22px; box-shadow: 0 30px 90px rgba(0,0,0,.7); padding: 24px 26px; }
.modal-box.wide { width: 600px; padding: 0; }
.modal-box h3 { margin: 0 0 8px; font: 800 21px var(--font-ui); color: var(--text); }
.modal-x { position: absolute; top: 14px; right: 16px; background: none; border: none; color: var(--muted); font-size: 18px; cursor: pointer; z-index: 1; }
.modal-foot { display: flex; justify-content: flex-end; gap: 10px; }
.modal-box:not(.wide) .modal-foot { margin-top: 18px; }
.modal-box.wide .modal-foot { padding: 8px 28px 24px; }
.modal-stack { display: flex; flex-direction: column; gap: 10px; margin-top: 16px; }
.modal-stack .play-btn { width: 100%; }
.btn-ghost { padding: 12px 20px; background: transparent; color: #9a98c0; border: 1px solid var(--btn-border); border-radius: 12px; font: 700 14px var(--font-ui); cursor: pointer; }

.conflict-head { padding: 24px 28px 8px; }
.dot-badge { display: inline-flex; align-items: center; gap: 7px; margin-bottom: 10px; padding: 4px 10px; font-size: 11px; }
.dot-badge .cb-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--game-accent); }
.conflict-head h3 { margin: 0 0 8px; }
.conflict-head .muted-note { font-size: 14px; color: #9a98c0; }
.conflict-head code { font: 700 12px var(--font-mono); color: var(--teal); }
.conflict-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; padding: 18px 28px; }
.tile { position: relative; text-align: left; padding: 20px 18px; border-radius: 16px; cursor: pointer; border: 2px solid var(--btn-border); background: rgba(0,0,0,.22); display: flex; flex-direction: column; color: var(--text); }
.tile.sel { border-color: var(--gold); background: rgba(245,197,66,.08); }
.tile-badge { position: absolute; top: 14px; right: 14px; width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--muted2); }
.tile.sel .tile-badge { border: none; background: var(--gold); }
.tile.sel .tile-badge::after { content: "✓"; color: #1a1206; font: 800 12px var(--font-ui); display: flex; align-items: center; justify-content: center; height: 100%; }
.tile-ic { font-size: 24px; margin-bottom: 10px; }
.tile-title { font: 800 16px var(--font-ui); color: var(--text); }
.tile-size { margin-top: 5px; font: 600 13px var(--font-ui); color: var(--gold); }
#tile-local .tile-size { color: var(--body2); }
.tile-desc { margin-top: 8px; font: 400 12.5px var(--font-ui); color: #9a98c0; line-height: 1.45; }

/* BYO modal bits */
.dropzone { margin-top: 14px; border: 2px dashed var(--btn-border); border-radius: 12px; padding: 18px; text-align: center; cursor: pointer; transition: border-color .15s, background .15s; }
.dropzone:hover, .dropzone:focus, .dropzone.dragover { border-color: var(--gold); background: rgba(245,197,66,.06); outline: none; }
.dz-icon { font-size: 1.8rem; }
.dropzone p { margin: .3rem 0; color: var(--body); font: 400 13px var(--font-ui); }
.dz-hint { font-size: 11.5px !important; color: var(--muted); }
.dropzone code { background: #0005; padding: .1em .35em; border-radius: 4px; color: var(--teal); }
.file-status { margin-top: 12px; font: 400 12.5px var(--font-ui); background: rgba(0,0,0,.25); border: 1px solid var(--btn-border); border-radius: 8px; padding: 10px 12px; line-height: 1.5; }
.file-status .ok { color: var(--green); }
.file-status .miss { color: #ff9ab5; }
.file-status code { background: #0005; padding: .1em .35em; border-radius: 4px; color: var(--teal); }
#byo-modal .play-btn { width: 100%; margin-top: 14px; }

.legal-foot { color: var(--muted2); font: 400 11.5px var(--font-ui); text-align: center; max-width: 680px; line-height: 1.5; }
.legal-foot a { color: var(--teal); }

/* ===================== responsive view routing ===================== */
.tabs-bottom { display: none; }
.panel { display: none; }

/* ---- desktop ---- */
@media (min-width: 821px) {
  .console[data-view="play"] #panel-play { display: block; }
  .console[data-view="howto"] #panel-howto { display: block; }
  .console[data-view="settings"] #panel-settings { display: block; }
  /* the game-selector bar + its hairline only matters on Play; keep it visible
     always (selecting a tab returns to Play) */
  .console[data-view="play"] #panel-play {
    display: grid; grid-template-columns: 1.6fr 1fr; gap: 18px; align-items: start;
  }
}

/* ---- mobile ---- */
@media (max-width: 820px) {
  .console-wrap { padding: 0; gap: 0; }
  .console { width: 100%; min-height: 100dvh; border: 0; border-radius: 0; box-shadow: none; }
  .nav-top, .browser-pill, .game-bar { display: none; }
  .console-top { padding: 15px 18px 10px; }
  .wordmark { font-size: 17px; letter-spacing: 2px; }

  .m-subbar { display: block; padding: 2px 14px 10px; }
  .console-top { justify-content: space-between; }
  /* status pill rides in the top bar on mobile */
  .m-pill {
    display: inline-flex; align-items: center; gap: 5px; white-space: nowrap;
    font: 700 10px var(--font-ui); color: #9a98c0;
    background: rgba(255,255,255,.05); border: 1px solid rgba(255,255,255,.1);
    padding: 5px 9px; border-radius: 20px;
  }
  .m-pill-dot { width: 6px; height: 6px; border-radius: 50%; background: #5a5a8a; }
  .console.m-synced .m-pill { color: var(--green); background: rgba(110,224,160,.1); border-color: rgba(110,224,160,.25); }
  .console.m-synced .m-pill-dot { background: var(--green); }
  /* move the pill up into the header row */
  .console-top { position: relative; }

  .m-switch { display: flex; gap: 6px; background: var(--inset-bg); border: 1px solid var(--inset-border); border-radius: 12px; padding: 4px; }
  .m-tab { flex: 1; text-align: center; padding: 9px 4px; border: none; border-radius: 9px; font: 600 12.5px var(--font-ui); color: #9a98c0; background: transparent; cursor: pointer; }
  .m-tab.active { background: var(--gold); color: #1a1206; font-weight: 800; }
  .m-global { display: flex; align-items: center; gap: 8px; padding: 9px 12px; background: rgba(0,0,0,.2); border: 1px solid var(--inset-border); border-radius: 12px; font: 600 11.5px var(--font-ui); color: var(--muted); }
  .m-global-ic { font-size: 13px; }
  /* show switcher on game views, global label on guide/settings */
  .console[data-mview="howto"] .m-switch,
  .console[data-mview="settings"] .m-switch { display: none; }
  .console[data-mview="play"] .m-global,
  .console[data-mview="saves"] .m-global,
  .console[data-mview="sync"] .m-global { display: none; }

  .console-body { flex: 1; overflow: auto; padding: 2px 14px 84px; -webkit-overflow-scrolling: touch; display: block; }
  /* mobile shows one panel at a time, and Play splits the hero / saved / sync */
  .console[data-mview="play"] #panel-play { display: block; }
  .console[data-mview="play"] #panel-play .rail { display: none; }
  .console[data-mview="saves"] #panel-play { display: block; }
  .console[data-mview="saves"] #panel-play .hero-card,
  .console[data-mview="saves"] #panel-play #sync-card,
  .console[data-mview="saves"] #panel-play #sync-absent { display: none; }
  .console[data-mview="sync"] #panel-play { display: block; }
  .console[data-mview="sync"] #panel-play .hero-card,
  .console[data-mview="sync"] #panel-play #saved-card { display: none; }
  .console[data-mview="howto"] #panel-howto { display: block; }
  .console[data-mview="settings"] #panel-settings { display: block; }

  .hero-foot { flex-direction: column; align-items: stretch; }
  .hero-blurb { text-align: center; max-width: none; order: 2; }
  .hero-foot .play-btn { width: 100%; order: 1; white-space: normal; font-size: 14px; padding: 14px; }
  .hero-poster { height: 166px; }
  .poster-title { font-size: 32px; letter-spacing: 6px; }
  .poster-play { width: 46px; height: 46px; font-size: 17px; }
  .rail { margin-top: 0; }

  .settings-grid { grid-template-columns: 1fr; gap: 15px; }
  .pixels-row { display: none; }   /* mobile omits Pixels per the design */
  .desktop-only { display: none; }   /* desktop-only settings (e.g. Pogo on desktop Alt) */
  .set-row { gap: 10px; }
  .set-row select { min-width: 0; max-width: 170px; }
  .seg { width: 100%; }
  .seg button { flex: 1; text-align: center; padding: 8px; }
  .controls-grid { grid-template-columns: 1fr 1fr; gap: 11px 12px; }

  .modal-box.wide { width: 100%; }
  .conflict-tiles { grid-template-columns: 1fr; }

  .tabs-bottom {
    display: flex; position: sticky; bottom: 0; justify-content: space-around; align-items: center;
    padding: 9px 4px calc(14px + env(safe-area-inset-bottom));
    background: rgba(13,10,36,.97); border-top: 1px solid rgba(255,255,255,.07);
  }
  .tab-b { background: none; border: none; cursor: pointer; display: flex; flex-direction: column; align-items: center; gap: 3px; color: var(--muted2); }
  .tab-b .ic { font-size: 17px; opacity: .5; }
  .tab-b span:last-child { font: 700 9.5px var(--font-ui); }
  .tab-b.active { color: var(--gold); }
  .tab-b.active .ic { opacity: 1; }
}

/* ===================== game stage (preserved verbatim from v1.x) ===================== */
.game-stage {
  position: fixed;
  inset: 0;
  background: #000;
  z-index: 1000;
  display: flex;
}
.dos-window { flex: 1; width: 100%; height: 100%; }

/* ---- live in-game sync indicator (desktop pill + mobile dot) --------------
   One JS engine (setSyncInd) drives both nodes via [data-state]; CSS decides
   which renders per layout. States: synced/checking/uptodate/backedup/
   conflict/local/offline. `backedup` = we detected local changes AND pushed
   them to the server just now (the payoff: green ring-pulse + "Backed up"). */
.sync-ind { display: none; border: 0; background: none; }
#sync-ind-d.show { display: inline-flex; }
.game-stage.touch #sync-ind-d.show { display: none; }        /* touch uses the dot */
.game-stage.touch #sync-ind-m.show { display: inline-flex; } /* dot only in touch */

/* desktop pill: bottom-left, sitting at the foot of the js-dos sidebar column */
#sync-ind-d {
  position: absolute;
  left: 10px;
  bottom: 10px;
  z-index: 1002;
  align-items: center;
  gap: 6px;
  padding: 4px 10px 4px 8px;
  border: 1px solid #ffffff26;
  border-radius: 999px;
  background: rgba(8, 10, 20, 0.62);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
  color: #e7edf3;
  font-weight: 600;
  font-size: 11px;
  line-height: 1;
  letter-spacing: 0.02em;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  transition: background 0.2s;
}
#sync-ind-d:hover { background: rgba(8, 10, 20, 0.82); }
.si-label { white-space: nowrap; }

/* mobile dot: top-left of the controls area, right below the screen */
#sync-ind-m {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 6;
  width: 24px;
  height: 24px;
  padding: 0;
  align-items: center;
  justify-content: center;
}

/* the status dot (shared) */
.sync-ind .si-dot {
  position: relative;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  flex: 0 0 auto;
  background: #4fd777;
  color: #4fd777;                 /* currentColor drives the glow + ring */
  box-shadow: 0 0 5px currentColor;
}
#sync-ind-m .si-dot {
  width: 13px;
  height: 13px;
  box-shadow: 0 0 6px currentColor, 0 0 0 3px #0006;
}

/* ---- per-state colours ---- */
.sync-ind[data-state="synced"]   .si-dot,
.sync-ind[data-state="uptodate"] .si-dot,
.sync-ind[data-state="backedup"] .si-dot { background: #4fd777; color: #4fd777; }
.sync-ind[data-state="checking"] .si-dot,
.sync-ind[data-state="local"]    .si-dot,
.sync-ind[data-state="offline"]  .si-dot { background: #f0b849; color: #f0b849; }
.sync-ind[data-state="conflict"] .si-dot { background: #e8626a; color: #e8626a; }

/* ---- animations ---- */
/* checking: gentle pulse while a check/upload is in flight */
.sync-ind[data-state="checking"] .si-dot { animation: si-pulse 0.85s ease-in-out infinite; }
@keyframes si-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.3; } }

/* up-to-date (checked, nothing to send): one quick soft blink, NO ring —
   deliberately distinct from the payoff so "nothing changed" never looks
   like "changes were uploaded". */
.sync-ind[data-state="uptodate"] .si-dot { animation: si-blink 0.5s ease-out 1; }
@keyframes si-blink { 0% { transform: scale(1); } 45% { transform: scale(1.6); } 100% { transform: scale(1); } }

/* backed up (THE payoff): an expanding green ring-pulse (x2) around the dot */
.sync-ind[data-state="backedup"] .si-dot::after {
  content: "";
  position: absolute;
  inset: -3px;
  border-radius: 50%;
  border: 2px solid #4fd777;
  animation: si-ring 0.9s ease-out 2;
}
@keyframes si-ring { 0% { transform: scale(0.7); opacity: 0.85; } 100% { transform: scale(2.5); opacity: 0; } }

/* Touch soft-keyboard toggle — bottom-left of the controls area. Touch only.
   (Quitting is now done with the browser Back button — see history routing.) */
.kbd-btn { display: none; }
.game-stage.touch .kbd-btn {
  display: block;
  position: fixed;
  bottom: calc(2vw + env(safe-area-inset-bottom));   /* bottom-left, just right of ESC */
  left: 17vw;
  z-index: 1001;
  background: #000a;
  color: #fff;
  border: 1px solid #fff5;
  border-radius: 7px;
  padding: 0.1rem 0.4rem;
  font-size: 0.9rem;
  line-height: 1.4;
  cursor: pointer;
}
.kbd-btn.active { background: var(--accent2); color: #1a1033; }
/* Off-screen but focusable, so focusing it raises the device soft keyboard.
   font-size 16px avoids iOS zoom; transparent so it never shows a caret/text. */
.kbd-proxy {
  position: fixed;
  top: 0;                 /* keep it in view (above the keyboard) so focusing it
                             doesn't make the browser scroll the page up */
  left: 50%;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
  border: 0;
  padding: 0;
  margin: 0;
  font-size: 16px;
  color: transparent;
  background: transparent;
  caret-color: transparent;
}

/* ---- touch controls (mobile split view) ---- */
.touch-controls { display: none; }

/* Suppress native long-press behaviours on every control element so a held
   button (e.g. the pogo super-jump) is never interrupted by a callout/selection
   gesture that would cancel the touch. */
.touch-controls, .touch-controls * {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  touch-action: none;
}

/* When touch mode is active, split the stage vertically. The game pane is sized
   to the game's own aspect ratio (set inline by launch() to match renderAspect),
   so the canvas fills it with no black letterbox below; the controls take ALL
   the remaining height (taller, shifted up to meet the game). */
.game-stage.touch { flex-direction: column; }
.game-stage.touch .dos-window { flex: 0 0 auto; width: 100%; height: auto; min-height: 0; }
.game-stage.touch .touch-controls {
  flex: 1 1 auto;
  min-height: 0;
  position: relative;            /* anchor the Enter/Esc keys to the corners */
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 2vw;
  padding: 2vw 3vw calc(2vw + env(safe-area-inset-bottom));
  background: #120a26;
  border-top: 2px solid var(--border);
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

/* movement joystick (replaces the old empty-center d-pad) */
.stick {
  position: relative;
  flex: 0 0 auto;
  margin-left: 4vw;       /* nudge the joystick slightly right of the edge */
  width: min(34vw, 40vh);
  height: min(34vw, 40vh);
  border-radius: 50%;
  background: radial-gradient(circle at 50% 50%, #2a1a4a, #160d30 70%);
  border: 2px solid var(--border);
  touch-action: none;
}
.stick-knob {
  position: absolute;
  left: 50%; top: 50%;
  width: 42%; height: 42%;
  margin-left: -21%; margin-top: -21%;
  border-radius: 50%;
  background: var(--accent2);
  border: 3px solid #ffffff55;
  box-shadow: 0 2px 10px #000a;
  will-change: transform;
}

.menu-keys {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 3vmin;
}
.mbtn {
  min-width: 14vmin;
  padding: 1.6vmin 0;
  border: 1px solid var(--border);
  background: #2a1a4a;
  color: var(--text);
  border-radius: 10px;
  font-size: 1rem;
  touch-action: none;
}
.mbtn.active { background: var(--accent); color: #1a1033; }

/* In touch mode, place ESC at the top-left of the control pad and Enter at the
   bottom-right — diagonal, away from the joystick/action thumbs so they aren't
   pressed by accident. (display:contents lets each button position itself
   relative to the control pad.) */
.game-stage.touch .menu-keys { display: contents; }
.game-stage.touch .menu-keys .mbtn {
  position: absolute;
  min-width: 11vw;
  padding: 1.3vw 2.5vw;
  font-size: 0.78rem;
  opacity: 0.75;
}
.game-stage.touch .menu-keys .mbtn[data-keys="256"] {   /* ESC  -> bottom-left */
  bottom: calc(2vw + env(safe-area-inset-bottom));
  left: 3vw;
}
.game-stage.touch .menu-keys .mbtn[data-keys="257"] {   /* Enter -> bottom-right */
  bottom: calc(2vw + env(safe-area-inset-bottom));
  right: 3vw;
}

/* Y / N confirm keys — bottom-right, just left of the Enter key (both engines). */
.yn-keys { display: none; }
.game-stage.touch .yn-keys {
  display: flex;
  position: absolute;
  bottom: calc(2vw + env(safe-area-inset-bottom));
  right: 16vw;
  gap: 5px;
}
.ynbtn {
  min-width: 9vw;
  padding: 0.12rem 0.5rem;
  border: 1px solid #fff5;
  background: #000a;
  color: #fff;
  border-radius: 7px;
  font-weight: 700;
  font-size: 0.9rem;
  line-height: 1.5;
  touch-action: none;
}
.ynbtn.active { background: var(--accent); color: #1a1033; }

/* Realtime save states (DOSBox-X only): a 💾 trigger (centre-bottom) opens a
   Save/Load popup; tapping SAVE/LOAD runs it and closes the popup. */
.saveload-btn { display: none; }
.game-stage.touch.xstate .saveload-btn {
  display: block;
  position: absolute;
  bottom: calc(2vw + env(safe-area-inset-bottom));
  left: 50%;
  transform: translateX(-50%);
  z-index: 1001;
  min-width: 13vw;
  padding: 0.5vw 3vw;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  border-radius: 9px;
  font-size: 1.25rem;
  line-height: 1.3;
  touch-action: none;
}
.saveload-btn.active { filter: brightness(1.3); }

.saveload-popup { display: none; }
.game-stage.touch .saveload-popup.open {
  display: flex;
  gap: 4vw;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 13vh;
  z-index: 1100;
  padding: 3vw 4vw;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  box-shadow: 0 6px 24px #000a;
}
.statebtn {
  min-width: 26vw;
  padding: 3.5vw 0;
  border: 1px solid var(--border);
  border-radius: 10px;
  font-weight: 800;
  font-size: 1.05rem;
  touch-action: none;
}
.statebtn.save { background: #ff6b6b; color: #1a1033; }   /* save state */
.statebtn.load { background: var(--good); color: #06200f; }  /* load state */
.statebtn.active { filter: brightness(0.72); }

.actions {
  flex: 0 0 auto;
  display: grid;
  grid-template-columns: repeat(2, auto);
  gap: 3vw;              /* spread the action buttons apart (but keep them on-screen) */
  align-items: center;
}
.abtn {
  width: min(18vw, 22vh);
  height: min(18vw, 22vh);
  border-radius: 50%;
  border: 2px solid var(--border);
  font-weight: 800;
  font-size: clamp(0.7rem, 2.6vmin, 1.1rem);
  color: #1a1033;
  touch-action: none;
}
.abtn.shoot { background: #ff6b6b;        grid-column: 1; grid-row: 1; }   /* top-left */
.abtn.pogo  { background: var(--accent2); grid-column: 2; grid-row: 1; }   /* top-right */
.abtn.jump  { background: #6ee06e; grid-column: 1 / -1; grid-row: 2; justify-self: center; } /* bottom */
.abtn.active { filter: brightness(0.7); transform: scale(0.95); }

/* In touch mode, hide the js-dos sidebar (save/keyboard/fullscreen/settings)
   entirely — not needed; our own controls + browser Back cover it. */
.game-stage.touch #dos .sidebar,
.game-stage.touch #dos .sidebar-thin { display: none !important; }
.game-stage.touch #dos .left-12 { left: 0 !important; }
/* Collapse the thin left gutter js-dos reserves for the sidebar so the canvas
   isn't pushed right. */
.game-stage.touch #dos .flex-row > .w-4 { display: none !important; }
/* js-dos vertically centres the canvas via an inline `top` offset; override it
   to 0 so the game sits at the top of its pane (moved up, letterbox at bottom). */
.game-stage.touch #dos canvas { top: 0 !important; }

/* ---- visual filters (CRT / scanlines) -------------------------------------
   A WebGL canvas sized to the emulator canvas (left/top/width/height set inline
   by JS) and blended over it. See js/app.js for the dual-mode (overlay /
   sampling) implementation. */
.crt-canvas {
  display: none;
  position: absolute;
  z-index: 1002;
  pointer-events: none;
  mix-blend-mode: multiply;
}
.crt-canvas.on { display: block; }
