/* JNY shell — phone-first. Tablet & desktop tweaks at the bottom. */

* { box-sizing: border-box; }

/* ─── Theme tokens — three modes for varying light conditions ──────────────
   DARK:    indoor/evening default. Low-fatigue.
   OUTDOOR: bright-sun, glare-resistant. Near-white text on near-black bg,
            saturated high-chroma accents, heavier type weight, thicker
            scrollbars + focus rings. Built for a grandparent on a park bench
            in July noon.
   LIGHT:   full-sun alternative. Dark text on bright bg — sometimes reads
            better than dark-mode+glare since bright screens at max nit
            beat reflected skylight. User picks.

   Toggle cycles dark → outdoor → light and sets data-theme on <html>.
   prefers-contrast: more auto-upgrades dark → outdoor. prefers-color-scheme:
   light auto-picks light when the OS says so (user can still override). */

:root, html[data-theme="dark"] {
  --bg:             #070812;
  --surface:        #0f1226;
  --surface-2:      #171a33;
  --text:           #e9eaf2;
  --text-dim:       #a7a9bd;
  --border:         rgba(255,255,255,0.08);
  --accent:         #8c8ff0;
  --accent-strong:  #a7aaff;
  --danger:         #ff6b7a;
  --success:        #4ad29a;
  --focus-ring:     0 0 0 2px rgba(167, 170, 255, 0.5);
  --jny-scroll-thumb:       rgba(180, 170, 220, 0.28);
  --jny-scroll-thumb-hover: rgba(200, 190, 240, 0.52);
  --jny-scroll-thumb-active:rgba(220, 210, 250, 0.75);
  --jny-scroll-track:       transparent;
}

html[data-theme="outdoor"] {
  /* WCAG AAA-target contrast. Pure white on pure black. Wider borders,
     thicker focus, heavier scrollbars. No subtle grays that wash to white
     under direct sunlight. */
  --bg:             #000000;
  --surface:        #0b0b14;
  --surface-2:      #151525;
  --text:           #ffffff;
  --text-dim:       #e0e2ef;
  --border:         rgba(255,255,255,0.24);
  --accent:         #b9bcff;     /* brighter — survives glare */
  --accent-strong:  #d8dbff;
  --danger:         #ff9ea6;
  --success:        #7fffbd;
  --focus-ring:     0 0 0 3px #ffffff, 0 0 0 6px #000000;
  --jny-scroll-thumb:       rgba(255,255,255,0.6);
  --jny-scroll-thumb-hover: rgba(255,255,255,0.85);
  --jny-scroll-thumb-active:#ffffff;
  --jny-scroll-track:       rgba(255,255,255,0.1);
}

html[data-theme="light"] {
  /* Full-sun mode. Dark text, bright bg. Max-nit screen beats reflected
     skylight — the opposite choice from dark mode for the same problem. */
  --bg:             #fafbff;
  --surface:        #ffffff;
  --surface-2:      #eef0f8;
  --text:           #0b0c1a;
  --text-dim:       #3a3d55;
  --border:         rgba(0,0,0,0.14);
  --accent:         #3a3dd6;
  --accent-strong:  #1e21b0;
  --danger:         #c0312c;
  --success:        #1f7a4e;
  --focus-ring:     0 0 0 3px #000000, 0 0 0 6px #ffffff;
  --jny-scroll-thumb:       rgba(30, 32, 80, 0.38);
  --jny-scroll-thumb-hover: rgba(30, 32, 80, 0.62);
  --jny-scroll-thumb-active:rgba(30, 32, 80, 0.85);
  --jny-scroll-track:       rgba(0,0,0,0.04);
}

/* Auto-upgrade dark → outdoor when the OS asks for high contrast. User's
   explicit toggle still wins (because they'd have set data-theme). */
@media (prefers-contrast: more) {
  :root:not([data-theme]) {
    --bg:             #000000;
    --surface:        #0b0b14;
    --surface-2:      #151525;
    --text:           #ffffff;
    --text-dim:       #e0e2ef;
    --border:         rgba(255,255,255,0.24);
    --accent:         #b9bcff;
    --accent-strong:  #d8dbff;
    --danger:         #ff9ea6;
    --success:        #7fffbd;
    --focus-ring:     0 0 0 3px #ffffff, 0 0 0 6px #000000;
    --jny-scroll-thumb:       rgba(255,255,255,0.6);
    --jny-scroll-thumb-hover: rgba(255,255,255,0.85);
    --jny-scroll-thumb-active:#ffffff;
    --jny-scroll-track:       rgba(255,255,255,0.1);
  }
}

/* ─── Scrollbars (use the tokens above) ───────────────────────────────────── */
html { scrollbar-width: thin; scrollbar-color: var(--jny-scroll-thumb) var(--jny-scroll-track); }
*::-webkit-scrollbar        { width: 8px; height: 8px; }
*::-webkit-scrollbar-track  { background: var(--jny-scroll-track); }
*::-webkit-scrollbar-thumb  {
  background: var(--jny-scroll-thumb);
  border-radius: 8px;
  border: 2px solid transparent;      /* visual breathing room inside the 8px lane */
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover  { background: var(--jny-scroll-thumb-hover); background-clip: padding-box; }
*::-webkit-scrollbar-thumb:active { background: var(--jny-scroll-thumb-active); background-clip: padding-box; }
*::-webkit-scrollbar-corner { background: transparent; }
/* Don't draw a scrollbar lane just for overflow-x on mobile — looks noisy. */
@media (pointer: coarse) {
  *::-webkit-scrollbar        { width: 3px; height: 3px; }
  *::-webkit-scrollbar-thumb  { border: 0; background-clip: border-box; }
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  overflow-x: hidden;
  overscroll-behavior: contain;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--bg);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

/* App frame: phone-width on all viewports. Web = phone-in-a-window, not expanded desktop. */
body {
  display: flex;
  align-items: stretch;
  justify-content: center;
}

.shell {
  display: grid;
  grid-template-rows: auto 1fr auto auto;
  width: 100%;
  max-width: 420px;      /* phone baseline */
  /* Use svh (small viewport height) so our layout fits WITH Safari's URL bar
     visible. dvh shrinks/grows as the bar appears, causing jumpy content.
     On keyboard-open, --jny-kbd-h is set by wireKeyboardLayout() so the
     shell shrinks enough to keep the compose bar above the keyboard. */
  height: calc(100svh - var(--jny-kbd-h, 0px));
  max-height: calc(100svh - var(--jny-kbd-h, 0px));
  background: var(--surface);
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
  box-shadow: 0 0 48px rgba(0,0,0,.5);
  overflow-x: hidden;    /* prevent any child from forcing horizontal scroll */
  transition: height 180ms ease-out, max-height 180ms ease-out;
}
/* When the keyboard is open, suppress the status strip animation noise
   and lock the comm panel to max, so typing surface is always visible. */
body.kbd-open .status-strip { position: relative; }

/* Grid-item min-width gotcha: grid children default to min-width:auto,
   which lets content expand tracks and push past the shell. Force 0. */
.shell > * { min-width: 0; }

/* iOS Safari (not standalone) — Safari's URL bar + bottom-controls bar aren't
   captured by safe-area insets. Give ourselves explicit breathing room. */
body.is-ios.mode-browser .shell {
  padding-top: max(env(safe-area-inset-top), 12px);
  /* Safari's bottom URL/tab bar can be up to 50px; if safe-area is 0, use a
     comfortable fallback so our comm-icons don't sit under it. */
  padding-bottom: max(env(safe-area-inset-bottom), 20px);
}
/* In standalone (installed PWA) on iOS, safe-area-inset-bottom captures the
   home indicator; no fallback needed. */
body.mode-standalone .shell {
  height: 100dvh;
  max-height: 100dvh;
}

/* ─── Theme toggle — cycles dark ☾ / outdoor ◉ / light ☀ ─── */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  margin-left: 8px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface-2);
  color: var(--text);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: background 120ms, border-color 120ms, transform 120ms;
  -webkit-tap-highlight-color: transparent;
}
.theme-toggle:hover { border-color: var(--accent); }
.theme-toggle:active { transform: scale(0.94); }
.theme-toggle:focus-visible { outline: none; box-shadow: var(--focus-ring); }
html[data-theme="dark"]    .theme-toggle::after { content: "☾"; }   /* moon */
html[data-theme="outdoor"] .theme-toggle::after { content: "◉"; }   /* high-contrast dot */
html[data-theme="light"]   .theme-toggle::after { content: "☀"; }  /* sun */
/* When no theme explicitly set: show the dark moon (matches root defaults). */
html:not([data-theme])     .theme-toggle::after { content: "☾"; }

/* ─── Force-refresh button — always visible, always works ─── */
/* Persistent escape hatch: if the user thinks the app is stuck on an old
   version (no update pill shown, but something feels wrong), one tap here
   unregisters service workers, deletes all caches, and reloads with a
   cache-bust query. Distinct from the update pill which only shows when
   a NEW SW is waiting. */
.force-refresh {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  margin-left: 6px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 14px;
  background: var(--surface-2);
  color: var(--text);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: background 120ms, border-color 120ms, transform 120ms;
  -webkit-tap-highlight-color: transparent;
  flex: 0 0 auto;
}
.force-refresh:hover { border-color: var(--accent); }
.force-refresh:active { transform: rotate(180deg); }
.force-refresh:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.force-refresh.is-working { animation: jny-refresh-spin 0.8s linear infinite; pointer-events: none; }
@keyframes jny-refresh-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
.theme-toggle              { color: transparent; }   /* hide the fallback glyph */
.theme-toggle::after       { color: var(--text); }

/* ─── Status strip ─── */
.status-strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 14px;
  background: #1a1f3a;
  font-size: 12px;
  letter-spacing: 0.02em;
  border-bottom: 1px solid #252b4a;
}
.identity { font-weight: 600; opacity: .85; min-width: 0; max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.circle { opacity: .85; color: #c9cce8; min-width: 0; max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.circle:hover { color: #ffffff; }

/* Circle picker dropdown */
/* Device settings overlay */
.device-settings {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,.6);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 200;
  padding: 20px;
}
.ds-card {
  width: 100%;
  max-width: 420px;
  background: #1a1f3a;
  border: 1px solid #2d3463;
  border-radius: 14px;
  padding: 20px;
  color: #e9eaf2;
}
.ds-card h2 { margin: 0 0 6px; font-size: 18px; }
.ds-card h3.ds-section { margin: 20px 0 6px; font-size: 13px; opacity: .7; text-transform: uppercase; letter-spacing: .08em; }
.ds-label { display: block; margin: 12px 0 6px; font-size: 12px; opacity: .7; }
.ds-card input[type="text"] {
  width: 100%;
  padding: 10px 12px;
  background: #14172b;
  border: 1px solid #2d3463;
  border-radius: 8px;
  color: #e9eaf2;
  font-size: 14px;
  font-family: inherit;
  outline: none;
}
.ds-card input[type="text"]:focus { border-color: #5062c7; }
.ds-row { display: flex; gap: 8px; margin-top: 10px; }
.ds-row-wrap { flex-wrap: wrap; }
.ds-row-right { justify-content: flex-end; margin-top: 16px; }
.ds-btn {
  padding: 8px 14px;
  background: #5062c7;
  color: #fff;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  font-size: 13px;
  font-family: inherit;
}
.ds-btn:hover { background: #6172d9; }
.ds-btn-ghost { background: transparent; color: #9aa0c0; border: 1px solid #2d3463; }
.ds-btn-ghost:hover { color: #c9cce8; background: rgba(80,98,199,.1); }

/* Identity menu (click on name in status strip) */
.identity-menu {
  position: fixed;
  top: max(44px, calc(env(safe-area-inset-top) + 8px));
  left: 10px;
  right: auto;
  background: #1a1f3a;
  border: 1px solid #2d3463;
  border-radius: 12px;
  box-shadow: 0 12px 40px rgba(0,0,0,.5);
  z-index: 100;
  min-width: 260px;
  max-width: min(90vw, 360px);
  padding: 8px;
  color: #e9eaf2;
  font-size: 14px;
}
.im-header {
  padding: 10px 10px 12px;
  border-bottom: 1px solid #2d3463;
  margin-bottom: 6px;
}
.im-name { font-weight: 600; font-size: 15px; }
.im-device { font-size: 12px; opacity: .65; margin-top: 2px; }
.im-section-label {
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  opacity: .45;
  padding: 8px 10px 4px;
}
.im-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 10px 12px;
  background: transparent;
  border: 0;
  border-radius: 6px;
  color: #e9eaf2;
  cursor: pointer;
  font-size: 14px;
  text-align: left;
  font-family: inherit;
}
.im-item:hover { background: #262b55; }
.im-item span:first-child { font-size: 16px; line-height: 1; }
.im-signout { color: #d87b7b; }
.im-signout:hover { background: rgba(216,123,123,0.1); }
.im-muted { opacity: .55; font-size: 11px; }
.im-device-list { padding: 4px 0; }
.im-device-row {
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 13px;
}
.im-device-row.is-this { background: rgba(80,98,199,0.15); }
.im-device-name { }

.circle-menu {
  position: fixed;
  top: 44px;
  left: 50%;
  transform: translateX(-50%);
  background: #1a1f3a;
  border: 1px solid #2d3463;
  border-radius: 10px;
  box-shadow: 0 12px 40px rgba(0,0,0,.5);
  z-index: 99;
  min-width: 220px;
  padding: 6px;
}
.circle-opt {
  display: flex;
  justify-content: space-between;
  align-items: center;
  width: 100%;
  padding: 10px 12px;
  background: transparent;
  border: 0;
  border-radius: 6px;
  color: #e9eaf2;
  cursor: pointer;
  font-size: 14px;
  text-align: left;
}
.circle-opt:hover { background: #262b55; }
.circle-opt.is-active { background: rgba(80,98,199,.2); color: #ffffff; }
.co-room { font-size: 12px; opacity: .6; }
.conn {
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11px;
  background: #2a2a2a;
  color: #aaa;
}
.conn[data-state="online"]  { background: #1d3a2a; color: #7bd89a; }
.conn[data-state="offline"] { background: #3a1d1d; color: #d87b7b; }
.conn[data-state="pending"] { background: #2a2a3a; color: #9aa0c0; }

/* ─── Stage (L2/L3 swap area) ─── */
.stage {
  overflow-y: auto;
  padding: 16px;
  background: #14172b;
}
.stage .loading { opacity: .6; text-align: center; padding: 48px 0; }
.stage h1 { margin: 0 0 12px; font-size: 20px; }
.stage h2 { margin: 0 0 8px; font-size: 16px; }
.stage p  { margin: 0 0 12px; opacity: .8; line-height: 1.4; }

.stage .card {
  background: #1f2345;
  border: 1px solid #2d3463;
  border-radius: 12px;
  padding: 14px;
  margin-bottom: 12px;
  display: flex;
  gap: 12px;
  align-items: center;
}
.stage .card-art {
  width: 60px; height: 60px;
  border-radius: 10px;
  background: linear-gradient(135deg, #3c4a8a, #5062c7);
  display: flex; align-items: center; justify-content: center;
  font-size: 28px;
  flex-shrink: 0;
}
.stage .card-meta { flex: 1; min-width: 0; }
.stage .card-meta h2 { margin: 0 0 2px; font-size: 15px; }
.stage .card-meta p  { margin: 0; font-size: 13px; opacity: .65; }
.stage button.card.game-card {
  width: 100%;
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
}
.stage button.card.game-card:hover {
  background: #262b55;
  border-color: #3c4a8a;
}

/* Tic-Tac-Toe */
.game-back {
  background: transparent;
  color: #9aa0c0;
  border: 0;
  font-size: 13px;
  padding: 4px 0 10px;
  cursor: pointer;
}
.game-back:hover { color: #c9cce8; }
.game-title { font-size: 18px; margin: 0 0 6px; }
.game-status { font-size: 13px; opacity: .7; margin-bottom: 12px; }
.ttt-board {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
  max-width: 280px;
}
.ttt-cell {
  aspect-ratio: 1 / 1;
  background: #1f2345;
  border: 1px solid #2d3463;
  border-radius: 10px;
  color: #e9eaf2;
  font-size: 40px;
  font-weight: 700;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}
.ttt-cell:hover:not(:disabled) { background: #262b55; }
.ttt-cell:disabled { cursor: default; }
.ttt-cell.is-win { background: #3a4e2a; border-color: #7bd89a; color: #7bd89a; }
.game-reset {
  margin-top: 14px;
  padding: 8px 16px;
  background: #5062c7;
  color: #fff;
  border: 0;
  border-radius: 8px;
  cursor: pointer;
  font-size: 14px;
}
.game-reset:hover { background: #6172d9; }

/* ─── Flip bar ─── */
.flip-bar {
  display: flex;
  background: #1a1f3a;
  border-top: 1px solid #252b4a;
  border-bottom: 1px solid #252b4a;
}
.flip-btn {
  flex: 1;
  padding: 10px 8px;
  background: transparent;
  border: 0;
  color: #9aa0c0;
  font-size: 13px;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  cursor: pointer;
  transition: color 120ms ease, background 120ms ease;
}
.flip-btn .flip-icon { font-size: 20px; line-height: 1; }
.flip-btn:hover { color: #c9cce8; }
.flip-btn.is-active {
  color: #ffffff;
  background: linear-gradient(180deg, rgba(80,98,199,.15), rgba(80,98,199,.0));
  box-shadow: inset 0 2px 0 #5062c7;
}

/* ─── Comm bar (bottom, fixed) ─── */
.comm-bar {
  height: 38vh;
  min-height: 260px;
  max-height: 50vh;
  border-top: 1px solid #252b4a;
  background: #0c0f1e;
}
.comm-bar iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* ─── In-app Jitsi call overlay (Phase C tier-2) ─── */
.jny-call-overlay {
  position: fixed;
  inset: 0;
  z-index: 11000;                /* above login overlay (9999) and popovers (10000) */
  background: #0a0d1a;
  color: #eaecff;
  display: flex;
  flex-direction: column;
}
.jny-call-overlay[hidden] { display: none !important; }
.jny-call-header {
  display: flex;
  align-items: center;
  padding: 10px 14px;
  background: #14172b;
  border-bottom: 1px solid #2d3463;
  padding-top: max(10px, env(safe-area-inset-top));
  flex: 0 0 auto;
}
.jny-call-title {
  flex: 1;
  font-weight: 600;
  font-size: 15px;
  color: #c9cce8;
}
.jny-call-hangup {
  padding: 8px 14px;
  border: 0;
  border-radius: 8px;
  background: #c53030;
  color: #fff;
  font-weight: 600;
  cursor: pointer;
  font-size: 13px;
}
.jny-call-hangup:hover { filter: brightness(1.1); }
.jny-call-frame {
  flex: 1 1 auto;
  min-height: 0;
  background: #000;
  position: relative;
}
/* The iframe Jitsi injects fills the frame box */
.jny-call-frame iframe {
  width: 100% !important;
  height: 100% !important;
  border: 0 !important;
}
.jny-call-status {
  padding: 10px 14px;
  background: #3a1d1d;
  color: #ffb4b4;
  font-size: 13px;
  flex: 0 0 auto;
}

/* ─── Login overlay ─── */
.jny-login {
  position: fixed;
  inset: 0;
  background: #070812;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 9999;
  padding: 24px;
}
.jny-login-card {
  width: 100%;
  max-width: 360px;
  background: #1a1f3a;
  border: 1px solid #2d3463;
  border-radius: 16px;
  padding: 28px 24px;
  color: #e9eaf2;
  box-shadow: 0 20px 60px rgba(0,0,0,.6);
}
.jny-login-card h1 {
  margin: 0 0 2px;
  font-size: 32px;
  letter-spacing: 0.04em;
  display: flex;
  align-items: center;
  gap: 6px;
}
.j-wordmark {
  background: linear-gradient(135deg, #c9cce8, #5062c7);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-weight: 700;
}
.j-mark {
  font-size: 24px;
  color: #ffd166;
  margin-left: 2px;
  text-shadow: 0 0 8px rgba(255, 209, 102, .3);
}
.jny-login-card .j-tag {
  margin: 0 0 16px;
  font-size: 11px;
  opacity: .55;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.jny-login-card p { margin: 0 0 18px; opacity: .7; font-size: 14px; }
.jny-login-card input {
  display: block;
  width: 100%;
  padding: 12px 14px;
  margin-bottom: 10px;
  background: #14172b;
  border: 1px solid #2d3463;
  border-radius: 10px;
  color: #e9eaf2;
  font-size: 15px;
  font-family: inherit;
  outline: none;
}
.jny-login-card input:focus { border-color: #5062c7; }
.jny-login-card button {
  display: block;
  width: 100%;
  padding: 12px;
  margin-top: 6px;
  background: linear-gradient(135deg, #5062c7, #3c4a8a);
  color: #ffffff;
  border: 0;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
}
.jny-login-card button:hover { filter: brightness(1.1); }
/* Primary OIDC button (anchor tag) — matches the gradient button style */
.jny-login-card .kc-btn {
  display: block;
  width: 100%;
  padding: 14px 12px;
  margin-top: 6px;
  background: linear-gradient(135deg, #5062c7, #3c4a8a);
  color: #ffffff !important;
  border: 0;
  border-radius: 10px;
  font-size: 16px;
  font-weight: 600;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  box-sizing: border-box;
  transition: filter 120ms, transform 120ms;
  -webkit-tap-highlight-color: transparent;
}
.jny-login-card .kc-btn:hover { filter: brightness(1.1); }
.jny-login-card .kc-btn:active { transform: scale(0.98); }
.jny-login-card .kc-btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.pw-wrap {
  position: relative;
  margin-bottom: 10px;
}
.pw-wrap input {
  padding-right: 44px !important;
  margin-bottom: 0 !important;
}
.pw-toggle {
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: 0;
  color: #9aa0c0;
  font-size: 18px;
  padding: 6px 8px;
  margin: 0 !important;
  width: auto !important;
  cursor: pointer;
}

.jny-login-err {
  margin: 10px 0 0;
  padding: 8px 10px;
  background: #3a1d1d;
  color: #ffb4b4;
  border-radius: 8px;
  font-size: 13px;
}
.jny-login-msg {
  margin: 10px 0 0;
  padding: 8px 10px;
  background: #1d3a2a;
  color: #7bd89a;
  border-radius: 8px;
  font-size: 13px;
}
.magic-btn {
  display: block;
  width: 100%;
  padding: 10px !important;
  margin-top: 8px !important;
  background: transparent !important;
  color: #9aa0c0 !important;
  border: 1px solid #2d3463 !important;
  font-size: 13px !important;
}
.magic-btn:hover { color: #c9cce8 !important; border-color: #3c4a8a !important; }

.jny-login-footer {
  margin: 16px 0 0;
  text-align: center;
  font-size: 13px;
  color: #9aa0c0;
}
.jny-login-footer a {
  color: #c9cce8;
  text-decoration: none;
  border-bottom: 1px dotted #3c4a8a;
  padding-bottom: 1px;
}
.jny-login-footer a:hover { color: #ffffff; border-bottom-color: #5062c7; }

/* iOS "Add to Home Screen" hint */
.ios-install-hint {
  position: fixed;
  bottom: max(20px, env(safe-area-inset-bottom));
  left: 20px;
  right: 20px;
  background: #1a1f3a;
  color: #e9eaf2;
  border: 1px solid #2d3463;
  border-radius: 12px;
  padding: 14px 16px;
  font-size: 13px;
  z-index: 100;
  box-shadow: 0 8px 24px rgba(0,0,0,.5);
}
.ios-install-hint button {
  background: #5062c7;
  color: #fff;
  border: 0;
  border-radius: 6px;
  padding: 6px 12px;
  font-size: 12px;
  margin-left: 8px;
  cursor: pointer;
}
body.mode-standalone .ios-install-hint { display: none; }

/* Tablet — keep phone width, just a touch more comfort */
@media (min-width: 768px) {
  .shell { max-width: 480px; }
  .stage h1 { font-size: 22px; }
}

/* Landscape layout: two-column (stage | comm) for any landscape-oriented
   device wide enough to make sense — covers phone landscape, tablet
   landscape (iPad, Android tablets), and small desktop windows.
   Portrait on any size stays single-column phone-width. */
@media (orientation: landscape) and (min-width: 720px) {
  .shell {
    max-width: min(1200px, 100vw);
    width: 100%;
    max-height: 100dvh;
    grid-template-columns: 1fr minmax(320px, 420px);
    grid-template-rows: auto 1fr auto;
    grid-template-areas:
      "status status"
      "stage  comm"
      "flip   comm";
    box-shadow: 0 0 48px rgba(0,0,0,.5);
  }
  .status-strip { grid-area: status; }
  .stage { grid-area: stage; }
  .flip-bar { grid-area: flip; }
  .comm-bar {
    grid-area: comm;
    max-height: none !important;
    border-top: 0;
    border-left: 1px solid var(--border);
  }
}

/* Phone landscape (short, not wide enough for side-by-side comm):
   single-column, comm stays at the bottom, shell fills viewport. */
@media (orientation: landscape) and (max-width: 719px) and (max-height: 520px) {
  .shell {
    max-width: none;
    width: 100%;
    max-height: 100dvh;
    box-shadow: none;
  }
}

/* Utility: a surface can opt OUT of phone-width lock and fill the viewport
   (e.g., a game or video that wants landscape). Add class `.landscape-free`
   to <body> while that surface is active, remove when done. */
body.landscape-free .shell {
  max-width: none;
  width: 100%;
  box-shadow: none;
}

/* ─── Partial-render modes (via ?part= query param) ─── */
/* Shell applies a data-part attribute based on URL; CSS below shows only that region. */

body[data-part="comm"] .status-strip,
body[data-part="comm"] .stage,
body[data-part="comm"] .flip-bar { display: none; }
body[data-part="comm"] .shell { grid-template-rows: 1fr; max-width: none; box-shadow: none; }
body[data-part="comm"] .comm-bar { height: 100dvh; max-height: none; min-height: 0; }

body[data-part="stage"] .status-strip,
body[data-part="stage"] .flip-bar,
body[data-part="stage"] .comm-bar { display: none; }
body[data-part="stage"] .shell { grid-template-rows: 1fr; max-width: none; box-shadow: none; }

body[data-part="flip"] .status-strip,
body[data-part="flip"] .comm-bar { display: none; }
body[data-part="flip"] .shell { grid-template-rows: 1fr auto; max-width: none; box-shadow: none; }

/* Update-available pill — lives inside the status strip next to the conn
   chip, never escapes the phone-width shell. Tap to open a small popover
   anchored to the pill with Update / Later. */
.jny-update-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin: 0 6px;
  padding: 0;
  border: 1px solid var(--accent);
  border-radius: 11px;
  background: var(--accent);
  color: #fff;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  animation: jny-update-pulse 1.8s ease-in-out infinite;
  -webkit-tap-highlight-color: transparent;
  flex: 0 0 auto;
}
.jny-update-pill:focus-visible { outline: none; box-shadow: var(--focus-ring); }
html[data-theme="light"] .jny-update-pill { color: #fff; }
@keyframes jny-update-pulse {
  0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(140, 143, 240, 0); }
  50%      { transform: scale(1.08); box-shadow: 0 0 0 4px rgba(140, 143, 240, 0.22); }
}
@media (prefers-reduced-motion: reduce) {
  .jny-update-pill { animation: none; }
}

.jny-update-pop {
  position: fixed;
  z-index: 10000;
  width: 220px;
  padding: 12px 14px;
  background: var(--surface-2);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 10px 28px rgba(0,0,0,.45);
  font-size: 14px;
}
.jny-update-pop-msg   { margin-bottom: 10px; line-height: 1.35; }
.jny-update-pop-actions { display: flex; justify-content: flex-end; gap: 8px; }
.jny-update-pop button {
  border: none;
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}
.jny-update-later { background: transparent; color: var(--text-dim); }
.jny-update-now   { background: var(--accent); color: #fff; }
html[data-theme="light"] .jny-update-now { background: var(--accent-strong); }

/* Global incognito/private-window banner — one warning across all L3s. */
.jny-incog-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9999;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: max(10px, env(safe-area-inset-top)) 14px 10px;
  background: #3a2a12;
  color: #ffe8c7;
  border-bottom: 1px solid #6a4a1e;
  font-size: 13px;
  line-height: 1.35;
}
.jny-incog-banner button {
  margin-left: auto;
  background: transparent;
  border: none;
  color: #ffe8c7;
  font-size: 18px;
  cursor: pointer;
  padding: 0 4px;
}
