/* ── Glox Design System ─────────────────────────────────────── */
@import url('https://fonts.googleapis.com/css2?family=Baloo+2:wght@800&family=Space+Grotesk:wght@500;600&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@400;500&display=swap');
@font-face { font-family: 'NineCircles'; src: url('/fonts/NineCirclesReg.otf') format('opentype'), url('/fonts/NineCirclesReg.ttf') format('truetype'); font-display: swap; }
@font-face { font-family: 'NineCirclesBook'; src: url('/fonts/nine-circles.book.otf') format('opentype'), url('/fonts/nine-circles.book.ttf') format('truetype'); font-display: swap; }

:root {
  /* Scratch day — playful light, Scratch purple + orange on ice blue */
  --ink: #E8EEFA;
  --panel: #FFFFFF;
  --panel-raised: #E2E9FA;
  --line: #C9D5F0;
  --text-primary: #2E2A4B;
  --text-secondary: #5C5878;
  --text-tertiary: #9C97B8;
  --signal: #7300FF;
  --signal-hover: #5D00E9;
  --signal-tint: rgba(115, 0, 255, 0.12);
  --ember: #FF8C1A;
  --ember-deep: #B25E00;
  --success: #14965F;
  --danger: #E0442E;
  --radius-sm: 6px;
  --radius-lg: 12px;
  --font-head: 'Space Grotesk', sans-serif;
  --font-body: 'Inter', sans-serif;
  --font-mono: 'JetBrains Mono', monospace;
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.25rem;
  --text-xl: 1.625rem;
  --text-2xl: 2rem;
  --on-signal: #fff;
}

/* ── Dark theme ──────────────────────────────────────────────
   Palette: #141414 surfaces, #66A8A0 signal. Applied via
   <html data-theme="dark">, set by the head boot snippet on every app
   page (localStorage['glox_theme']: dark / light / unset = system).
   Precedence is pack > accent > dark > light: packs and the accent
   picker write inline vars, which beat this block automatically. */
:root[data-theme="dark"] {
  color-scheme: dark;
  --ink: #B0C4DE;
  --panel: #222222;
  --panel-raised: #343434;
  --line: #343434;
  --text-primary: #FFFFFF;
  --text-secondary: #A6A6A6;
  --text-tertiary: #808080;
  --signal: #66A8A0;
  --signal-hover: #50928A;
  --signal-tint: rgba(102, 168, 160, 0.14);
  --success: #3ECF8E;
  --on-signal: #141414;
}
/* Dark mode: badge/icon glyphs go white (tinted backgrounds stay, so the
   accent still reads). Light mode keeps the signal-colored glyphs. */
:root[data-theme="dark"] .avatar,
:root[data-theme="dark"] .server-icon,
:root[data-theme="dark"] .conv-ava,
:root[data-theme="dark"] .game-creator-avatar,
:root[data-theme="dark"] .author-avatar,
:root[data-theme="dark"] .empty-icon-circle,
:root[data-theme="dark"] .pack-tags span,
:root[data-theme="dark"] .pack-install.installed,
:root[data-theme="dark"] .game-actions .ga-primary,
:root[data-theme="dark"] .msg-ava {
  color: var(--text-primary);
}
/* Dark mode readability on the lightsteelblue page: text inputs keep a
   dark surface so white text still reads. */
:root[data-theme="dark"] .field input,
:root[data-theme="dark"] .invite-code { background: #222222; }
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* Author display values beat the `hidden` attribute, so hidden elements
   with a CSS display (flex bar, topbar, badge) would never hide.
   This guard makes hidden mean hidden everywhere. */
[hidden] { display: none !important; }
html, body { height: 100%; }

body {
  font-family: var(--font-body);
  background: var(--ink);
  color: var(--text-primary);
  overflow: hidden;
  display: flex;
  height: 100%;
  -webkit-font-smoothing: antialiased;
}

/* ── Sidebar ─────────────────────────────────────────────── */
/* Fixed 60px icon rail, always collapsed. It fills the full height with
   no gaps and no rounded corners; labels appear as hover tooltips
   (#railTip, positioned from sidebar.js) instead of an expanding card. */
.sidebar {
  width: 60px;
  background: transparent;
  flex-shrink: 0;
  height: 100%;
  position: relative;
  z-index: 0;
}

/* Rail brand: the plain Baloo 2 wordmark — same logo the sign-in page uses. */
.rail-brand {
  position: relative;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 8px;
  flex-shrink: 0;
}
.rail-word {
  font: 800 15px/1 'Baloo 2', var(--font-head), sans-serif;
  letter-spacing: -0.01em;
  color: var(--text-primary);
  white-space: nowrap;
}

/* Rail card: flush full-height rectangle, icon column only. */
.sidebar-nav-card {
  background: var(--panel);
  border: none;
  border-right: 1px solid var(--line);
  border-radius: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overflow-x: hidden;
  min-height: 0;
  height: 100%;
  width: 100%;
  padding: 12px 0;
}
/* Rail is always collapsed: labels hidden, icons centered. Names appear
   as tooltips (#railTip) on hover/focus instead of an expanding card. */
.sidebar .nav-section-label { display: block; height: 1px; background: var(--line); margin: 10px 16px 8px; padding: 0; font-size: 0; line-height: 0; overflow: hidden; border: none; }

/* Floating user bar: bottom-left of the main panel. */
#accountRow {
  position: fixed;
  left: 76px;
  bottom: 16px;
  z-index: 900;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--panel-raised);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 6px 8px 6px 6px;
}
#accountRow .avatar { width: 40px; height: 40px; font-size: 1rem; }
.ava-wrap { position: relative; width: 40px; height: 40px; flex-shrink: 0; }
#sbDot {
  position: absolute; right: -1px; bottom: -1px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--text-tertiary); border: 2px solid var(--panel-raised);
}
#sbDot.on { background: var(--success); }
#accountRow .account-name {
  max-width: 120px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
#accountRow .iconbtn {
  width: 32px; height: 32px; border-radius: var(--radius-sm);
  border: none; background: transparent; color: var(--text-secondary);
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  flex-shrink: 0; padding: 0;
}
#accountRow .iconbtn:hover { color: var(--signal); background: var(--signal-tint); }
#accountRow .iconbtn svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 1.5; fill: none; stroke-linecap: round; stroke-linejoin: round; }
#logoutBtn { display: none; }

/* Servers stay visible as icons */
.sidebar #serversSection { opacity: 1; pointer-events: auto; }
.sidebar .sidebar-item { justify-content: center; align-items: center; padding: 8px 0; border-left-width: 2px; gap: 0; width: 100%; }
.sidebar .sidebar-item span { opacity: 0; max-width: 0; overflow: hidden; pointer-events: none; }
.sidebar #serverList > div { display: none; }
.sidebar #serverList .sidebar-item span:first-child { opacity: 1; max-width: none; }

/* Hover tooltip: dark pill with the item name, positioned from sidebar.js
   as position:fixed so rail scrolling never clips it. */
#railTip {
  display: none;
  position: fixed;
  z-index: 9999;
  pointer-events: none;
  background: #212121;
  color: #fff;
  border: 1px solid var(--line);
  font-size: 0.75rem;
  font-weight: 600;
  font-family: var(--font-body);
  padding: 6px 12px;
  border-radius: 8px;
  white-space: nowrap;
}

.nav-section-label {
  font-size: 0.75rem;
  color: var(--text-tertiary);
  padding: 0 20px;
  margin-bottom: 6px;
}

.sidebar-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 20px;
  font-size: 0.9375rem;
  color: var(--text-secondary);
  text-decoration: none;
  border-left: 2px solid transparent;
  cursor: pointer;
  transition: background 0.1s, color 0.1s;
}

.sidebar-item:hover {
  background: var(--panel-raised);
  color: var(--text-primary);
}

.sidebar-item.active {
  border-left-color: var(--signal);
  background: var(--signal-tint);
  color: var(--text-primary);
}

.sidebar-item svg {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  stroke: currentColor;
  stroke-width: 1.5;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.sidebar-spacer { flex: 1; }

.mode-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.875rem;
  color: var(--text-secondary);
  min-height: 20px;
}

.switch {
  width: 34px;
  height: 20px;
  border-radius: 999px;
  background: var(--panel-raised);
  border: 1px solid var(--line);
  position: relative;
  cursor: pointer;
  transition: background 0.2s;
}

.switch.on {
  background: var(--signal);
  border-color: var(--signal);
}

.switch::after {
  content: "";
  position: absolute;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--text-secondary);
  top: 2px;
  left: 3px;
  transition: transform 0.2s, background 0.2s;
}

.switch.on::after {
  transform: translateX(14px);
  background: #fff;
}

.account-row {
  display: flex;
  align-items: center;
  gap: 10px;
  position: relative;
  min-height: 32px;
}

.avatar {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--signal-tint);
  color: var(--signal);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.8rem;
  flex-shrink: 0;
}

.account-name {
  font-size: 0.875rem;
  color: var(--text-primary);
  line-height: 1.2;
}

.account-status {
  font-size: 0.75rem;
  color: var(--text-secondary);
}

/* ── Layout helper ───────────────────────────────────────── */
.app-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  min-width: 0;
}

/* ── Page panel ──────────────────────────────────────────────
   Every main surface is an isolated rounded rectangle floating on the
   page background: 16px margins, 16px radius (explicit exception to the
   12px container rule), hairline border, clipped corners. Add this class
   to a page root alongside its layout class; interiors are untouched. */
.page-panel {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  overflow: hidden;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 16px;
  margin: 16px;
}

/* ── Topbar ──────────────────────────────────────────────── */
.topbar {
  padding: 18px 28px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--panel);
  flex-shrink: 0;
}

.topbar h1 {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.25rem;
  margin: 0;
}

/* ── Buttons ─────────────────────────────────────────────── */
.btn {
  font-family: var(--font-head);
  font-weight: 500;
  font-size: 0.9375rem;
  border-radius: var(--radius-sm);
  padding: 10px 16px;
  border: 1px solid transparent;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}

.btn-primary {
  background: var(--signal);
  color: var(--on-signal, #fff);
}

.btn-primary:hover { background: var(--signal-hover); }

.btn-secondary {
  background: transparent;
  border-color: var(--line);
  color: var(--text-primary);
}

.btn-secondary:hover { background: var(--panel-raised); }

.btn-ember {
  background: var(--ember);
  color: #2E2A4B;
}

.btn-ember:hover { filter: brightness(1.06); }

.btn:disabled { opacity: 0.6; cursor: default; }

.btn-ghost {
  background: transparent;
  border-color: var(--line);
  color: var(--text-primary);
}

.btn-ghost:hover { background: var(--panel-raised); }

.btn-danger {
  background: transparent;
  border-color: var(--line);
  color: var(--danger);
}

.btn-danger:hover { border-color: var(--danger); }

/* ── Cards ─────────────────────────────────────────────── */
.card {
  background: var(--panel-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 24px;
}

/* ── Form fields ───────────────────────────────────────── */
.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 14px;
}

.field label {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-secondary);
}

.field input {
  background: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  padding: 10px 12px;
  color: var(--text-primary);
  font-size: var(--text-sm);
  font-family: inherit;
  outline: none;
}

.field input:focus { border-color: var(--signal); }
.field input[readonly] { opacity: 0.6; }

/* ── Status messages ───────────────────────────────────── */
.status-msg {
  font-size: var(--text-sm);
  margin-top: 10px;
  display: none;
}

.status-msg.ok { color: var(--success); display: block; }
.status-msg.err { color: var(--danger); display: block; }

/* ── Page title ────────────────────────────────────────── */
.page-title {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: var(--text-lg);
  margin-bottom: 20px;
}

/* ── Empty states ────────────────────────────────────────── */
.empty-wrap {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.empty-card {
  text-align: center;
  max-width: 320px;
  position: relative;
  z-index: 1;
}

.empty-icon-circle {
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--signal-tint);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 18px;
  color: var(--signal);
}

.empty-icon-circle svg {
  width: 24px;
  height: 24px;
  stroke: currentColor;
  stroke-width: 1.5;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.empty-card h2 {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 1.125rem;
  margin: 0 0 8px;
}

.empty-card p {
  font-size: 0.875rem;
  color: var(--text-secondary);
  line-height: 1.5;
  margin: 0 0 22px;
}

.empty-card .btn { width: auto; padding: 10px 20px; }

/* ── Catalog pattern ─────────────────────────────────────────
   Shared by the browse surfaces (games, servers, themes): hero banner,
   section header with sort, and the cards below. Page-specific accents
   stay in each page's own <style>. */
.hero {
  position: relative; overflow: hidden; border-radius: var(--radius-lg);
  border: 1px solid var(--line); margin-bottom: 4px; padding: 34px 30px;
  background:
    radial-gradient(420px 220px at 85% 15%, color-mix(in srgb, var(--signal) 30%, transparent), transparent 70%),
    radial-gradient(380px 220px at 65% 95%, color-mix(in srgb, var(--ember) 22%, transparent), transparent 70%),
    var(--panel-raised);
  background-size: cover; background-position: center;
}
.hero h1 { font-family: var(--font-head); font-weight: 700; font-size: 1.9rem; margin: 0 0 8px; }
.hero p { color: var(--text-secondary); font-size: 0.9rem; margin: 0 0 18px; max-width: 46em; }
.hero-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.hero.has-art h1 { color: #fff; }
.hero.has-art p { color: rgba(255, 255, 255, 0.82); }
.sec-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 18px 0 0; }
.sec-head h2 { font-family: var(--font-head); font-weight: 600; font-size: 1.15rem; margin: 0; }
.sortsel {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--radius-sm); color: var(--text-primary);
  font-size: 0.8rem; font-family: inherit; padding: 7px 10px;
  outline: none; cursor: pointer;
}

/* ── Skeletons ───────────────────────────────────────────────
   Loading placeholders: shimmering blocks in the shape of the content
   they stand in for. Pages render these in the initial HTML and replace
   them on first data load. Motion-guarded like everything else. */
.sk { position: relative; overflow: hidden; background: var(--panel-raised); }
.sk::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(46, 42, 75, 0.08), transparent);
  animation: skshim 1.3s infinite;
}
:root[data-theme="dark"] .sk::after {
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.07), transparent);
}
@keyframes skshim { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
@media (prefers-reduced-motion: reduce) { .sk::after { animation: none; } }

/* ── Theme packs ───────────────────────────────────────────── */
#packBg {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
}
#packBg img, #packBg video, #packBg canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
html[data-pack-bg] { background: var(--ink); }
html[data-pack-bg] body { background: transparent; }
/* Layouts go transparent so pack art shows through; cards stay solid. */
html[data-pack-bg] nav.sidebar + .games-layout,
html[data-pack-bg] nav.sidebar + .chat-layout,
html[data-pack-bg] nav.sidebar + .lobbies-layout,
html[data-pack-bg] nav.sidebar + .profile-layout,
html[data-pack-bg] nav.sidebar + .servers-layout,
html[data-pack-bg] nav.sidebar + .game-layout,
html[data-pack-bg] nav.sidebar + .themes-layout,
html[data-pack-bg] nav.sidebar + .music-layout,
html[data-pack-bg] nav.sidebar + .auth-layout { background: transparent; }
html[data-pack-bg] .topbar {
  background: color-mix(in srgb, var(--panel) 78%, transparent);
  backdrop-filter: blur(6px);
}
html[data-pack-bg] .empty-card h2,
html[data-pack-bg] .empty-card p,
html[data-pack-bg] .topbar h1 { text-shadow: 0 1px 14px rgba(0, 0, 0, 0.55); }
/* Pack sidebar background: art fills the card under a dark scrim so labels
   and icons stay readable in both collapsed and expanded states. */
nav.sidebar.has-rail-bg .sidebar-nav-card {
  background-image: linear-gradient(rgba(8, 6, 24, 0.74), rgba(8, 6, 24, 0.74)), var(--rail-bg);
  background-size: cover, cover;
  background-position: center top, center top;
  border-color: rgba(255, 255, 255, 0.14);
}
/* Neon icon set: glow instead of redrawn shapes. */
nav.sidebar.pack-icons-neon .sidebar-item svg {
  filter: drop-shadow(0 0 5px var(--signal)) saturate(1.4);
}
nav.sidebar.pack-icons-neon .sidebar-item.active svg {
  filter: drop-shadow(0 0 7px var(--signal)) saturate(1.6);
}
/* Motion presets. */
html[data-motion="off"] *, html[data-motion="off"] *::before, html[data-motion="off"] *::after {
  animation-duration: 0.001s !important;
  transition-duration: 0.001s !important;
}
html[data-motion="playful"] .game-card, html[data-motion="playful"] .pack-card {
  transition: transform 0.18s ease, border-color 0.15s;
}
html[data-motion="playful"] .game-card:hover, html[data-motion="playful"] .pack-card:hover {
  transform: translateY(-3px);
}
