
/* Invert fullscreen icon in dark mode */
[data-theme="dark"] .fullscreen-toggle img,
[data-theme="dark"] .header-overlay-btn img[src*="fullscreen"],
[data-theme="dark"] .floating-titlebar-btn img[alt*="fullscreen"],
[data-theme="dark"] .floating-titlebar-btn img[src*="fullscreen"],
[data-theme="dark"] .react-gametab-landscape-ls-rail .react-gametab-toolbar-btn img[alt*="fullscreen"],
[data-theme="dark"] .react-gametab-landscape-ls-rail .react-gametab-toolbar-btn img[src*="fullscreen"],
[data-theme="dark"] .react-gametab-landscape-ls-overlay-toolbar .react-gametab-toolbar-btn img[alt*="fullscreen"],
[data-theme="dark"] .react-gametab-landscape-ls-overlay-toolbar .react-gametab-toolbar-btn img[src*="fullscreen"] {
  filter: invert(1) brightness(1.2) contrast(1.1);
}
:root {
  color-scheme: light;
  
  /* Expose safe-area-inset values as custom properties for JS access */
  --sal: env(safe-area-inset-left, 0px);
  --sar: env(safe-area-inset-right, 0px);
  --sat: env(safe-area-inset-top, 0px);
  --sab: env(safe-area-inset-bottom, 0px);
  
  /* Light Theme - Lobby Colors */
  --primary-start: #2d9da8;
  --primary-end: #1e7a85;
  --primary-color: #2d9da8;
  --primary-hover: #1e7a85;
  --selection-border-blue: #4a7bd9;
  --app-hover-fill: rgba(90, 125, 140, 0.08);
  --secondary-bg: #f5f5f5;
  --text-primary: #333;
  --text-secondary: #555;
  --text-light: #666;
  --bg-white: #ffffff;
  --border-color: #e0e0e0;
  --select-highlight-bg: #e6f0ff;
  --shadow-color: rgba(0, 0, 0, 0.1);
  --shadow-hover: rgba(45, 157, 168, 0.4);
  
  /* Success/Error colors */
  --success-color: #4caf50;
  --success-hover: #45a049;
  --danger-color: #f44336;
  --danger-hover: #da190b;
  
  /* Modern Backgammon Board Colors - Light Theme */
  --board-border: #c4a17c;          /* Light brown border */
  --board-surface: #c4d4c0;         /* Muted sage green recessed areas */
  --board-point-light: #ff9966;     /* Light orange points */
  --board-point-dark: #fff8e7;      /* Cream points */
  --board-home: #c4d4c0;            /* Muted sage green home areas */
  --checker-black: #7a3a2a;         /* Red/brown resin checkers */
  --checker-white: #e8e5e3;         /* White marble checkers */
  --checker-black-accent: #4a2218;  /* Darker resin tones */
  --checker-white-accent: #c5c3c1;  /* Gray marble veins */
  --board-text: #333;               /* Dark text for light theme */
  --board-button: #c4a17c;          /* Light brown button */
  --board-button-hover: #b08960;    /* Darker brown on hover */
}

[data-theme="dark"] {
  color-scheme: dark;
  
  /* Dark Theme - Lobby Colors */
  --primary-start: #2d9da8;
  --primary-end: #1e7a85;
  --primary-color: #2d9da8;
  --primary-hover: #3db4c0;
  --selection-border-blue: #4a7bd9;
  --app-hover-fill: rgba(138, 164, 176, 0.18);
  --secondary-bg: #2a2a2a;
  --text-primary: #e0e0e0;
  --text-secondary: #b0b0b0;
  --text-light: #888;
  --bg-white: #1a1a1a;
  --border-color: #404040;
  --select-highlight-bg: #2b3a44;
  --shadow-color: rgba(0, 0, 0, 0.5);
  --shadow-hover: rgba(45, 157, 168, 0.6);
  
  /* Success/Error colors (slightly adjusted for dark theme) */
  --success-color: #66bb6a;
  --success-hover: #5cb85c;
  --danger-color: #ef5350;
  --danger-hover: #e53935;
  
  /* Modern Backgammon Board Colors - Dark Theme */
  --board-border: #5d4a3a;          /* Dark brown border */
  --board-surface: #2d5c3f;         /* Dark green recessed areas */
  --board-point-light: #ff9966;     /* Light orange points (same) */
  --board-point-dark: #fff8e7;      /* Cream points (same) */
  --board-home: #2d5c3f;            /* Dark green home areas */
  --checker-black: #7a3a2a;         /* Red/brown resin (same) */
  --checker-white: #e8e5e3;         /* White marble (same) */
  --checker-black-accent: #4a2218;  /* Darker resin tones */
  --checker-white-accent: #c5c3c1;  /* Gray marble veins */
  --board-text: #ffffff;            /* White text for dark theme */
  --board-button: #5d4a3a;          /* Dark brown button */
  --board-button-hover: #7d6a5a;    /* Lighter brown on hover */
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

button {
  -webkit-touch-callout: none;
  user-select: none;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
  background: linear-gradient(135deg, var(--primary-start) 0%, var(--primary-end) 100%);
  height: 100vh;
  height: 100dvh;
  width: 100%;
  overflow: hidden;
  color: var(--text-primary);
  /* Fix for iOS Safari address bar resizing */
  min-height: -webkit-fill-available;
}

#root {
  height: 100vh;
  height: 100dvh;
  width: 100%;
  overflow: hidden;
  /* Fix for iOS Safari address bar resizing */
  min-height: -webkit-fill-available;
}

h1, h2, h3, h4, h5, h6 {
  color: var(--text-primary);
}

.container {
  max-width: 1200px;
  margin: 0 auto;
  padding: 20px;
}

/* Login and Auth Screens */
.auth-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
  /* Changed: clear of the status bar and the home indicator where the page fills the screen (the
     apps, the iOS home-screen web app); env() is 0 in a browser tab. The height media queries
     below set the same with smaller spacing. */
  padding: calc(20px + env(safe-area-inset-top, 0px)) 20px calc(20px + env(safe-area-inset-bottom, 0px));
}

.auth-box {
  background: var(--bg-white);
  border-radius: 12px;
  padding: 40px;
  box-shadow: 0 10px 40px var(--shadow-color);
  max-width: 450px;
  width: 100%;
  max-height: calc(100vh - 40px);
  overflow-y: auto;
}

.logo {
  width: 80px;
  height: 80px;
  margin: 0 auto 20px;
  display: block;
  border-radius: 50%;
}

.auth-box h1 {
  text-align: center;
  color: var(--text-primary);
  margin-bottom: 30px;
  font-size: 28px;
}

.form-group {
  margin-bottom: 20px;
}

.form-group label {
  display: block;
  margin-bottom: 8px;
  color: var(--text-secondary);
  font-weight: 500;
}

.form-group input,
.form-group select,
.form-group textarea {
  width: 100%;
  padding: 12px;
  border: 2px solid var(--border-color);
  border-radius: 6px;
  font-size: 16px;
  transition: border-color 0.3s;
  background: var(--bg-white);
  color: var(--text-primary);
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
  outline: none;
  border-color: var(--primary-color);
}

.form-group textarea {
  resize: vertical;
  min-height: 80px;
}

.btn {
  border: none;
  border-radius: 6px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.3s;
  padding: 10px 16px;
  font-size: 14px;
  width: auto;
  margin: 0;
}

/* Form buttons - full width */
form .btn,
.btn[type="submit"] {
  width: 100%;
  padding: 14px;
  font-size: 16px;
  margin-bottom: 10px;
}

.btn-primary {
  background: linear-gradient(135deg, var(--primary-start) 0%, var(--primary-end) 100%);
  color: white;
}

.btn-primary:hover:not(:disabled) {
  box-shadow: 0 5px 15px var(--shadow-hover);
}

.btn-primary:disabled {
  background: var(--border-color);
  color: var(--text-light);
  cursor: not-allowed;
  opacity: 0.6;
}

.btn-secondary {
  background: var(--secondary-bg);
  color: var(--text-primary);
}

.btn-secondary:hover:not(:disabled) {
  background: var(--border-color);
}

.btn-secondary:disabled {
  background: #f5f5f5;
  color: #bbb;
  cursor: not-allowed;
  opacity: 0.5;
}

.btn-success {
  background: var(--success-color);
  color: white;
}

.btn-success:hover:not(:disabled) {
  background: var(--success-hover);
  box-shadow: 0 5px 15px rgba(76, 175, 80, 0.4);
}

.btn-success:disabled {
  background: #a5d6a7;
  color: #fff;
  cursor: not-allowed;
  opacity: 0.6;
}

.btn-info {
  background: var(--primary-color);
  color: white;
}

.btn-info:hover:not(:disabled) {
  background: var(--primary-hover);
  box-shadow: 0 5px 15px var(--shadow-hover);
}

.btn-info:disabled {
  background: var(--border-color);
  color: var(--text-light);
  cursor: not-allowed;
  opacity: 0.6;
}

.btn-danger {
  background: var(--danger-color);
  color: white;
}

.btn-danger:hover:not(:disabled) {
  background: var(--danger-hover);
  box-shadow: 0 5px 15px rgba(244, 67, 54, 0.4);
}

.btn-danger:disabled {
  background: #ef9a9a;
  color: #fff;
  cursor: not-allowed;
  opacity: 0.6;
}

.btn-google {
  background: var(--bg-white);
  border: 2px solid var(--border-color);
  color: var(--text-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}

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

.link-button {
  background: none;
  border: none;
  color: var(--primary-color);
  cursor: pointer;
  font-size: 14px;
  text-decoration: underline;
  padding: 5px;
}

.error-message {
  background: #fee;
  color: #c33;
  padding: 12px;
  border-radius: 6px;
  margin-bottom: 20px;
  text-align: center;
}

/* Main Lobby */
.lobby-container {
  --lobby-safe-top: 0px;
  --lobby-safe-right: 0px;
  --lobby-safe-bottom: 0px;
  --lobby-safe-left: 0px;
  background: transparent;
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: auto;
  position: relative;
  box-sizing: border-box;
  padding-top: var(--lobby-safe-top);
  padding-right: var(--lobby-safe-right);
  padding-bottom: var(--lobby-safe-bottom);
  padding-left: var(--lobby-safe-left);
}

/* In non-fullscreen iPhone landscape, reserve the camera/notch side once at
   app-shell level so all regular tabs/overlays inherit the same inset. */
.lobby-container.smartphone-landscape:not(.fullscreen) {
  --lobby-safe-left: env(safe-area-inset-left, 0px);
}

/* In fullscreen, keep content away from notch/camera/rounded corners */
.lobby-container.fullscreen {
  --lobby-safe-top: env(safe-area-inset-top, 0px);
  --lobby-safe-right: env(safe-area-inset-right, 0px);
  --lobby-safe-bottom: env(safe-area-inset-bottom, 0px);
  --lobby-safe-left: env(safe-area-inset-left, 0px);
}

.lobby-container.smartphone-portrait.fullscreen {
  background: #000;
}

.lobby-container.smartphone-landscape.fullscreen {
  background: #000;
}

.lobby-header {
  background: linear-gradient(135deg, var(--primary-start) 0%, var(--primary-end) 100%);
  color: white;
  padding: clamp(2px, calc(var(--header-live-height, 42px) * 0.11), 20px) clamp(4px, calc(var(--header-live-height, 42px) * 0.16), 20px);
  min-height: clamp(39px, 5vh, 60px);
  --header-live-height: 39px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
  box-sizing: border-box;
  flex-shrink: 0;
}

.lobby-container.smartphone .lobby-header {
  min-height: 39px;
  max-height: 39px;
  --header-live-height: 39px;
}

.lobby-container.smartphone .lobby-header h1 {
  font-size: 16px;
}

.lobby-header h1 {
  /* The header's white, not the global heading colour (h1-h6 use
     --text-primary, which is dark in the light theme: a dark title on the
     header's coloured bar) */
  color: inherit;
  font-size: clamp(14.52px, 1.65vw, 20px);
  display: flex;
  align-items: center;
  gap: clamp(4px, calc(var(--header-live-height, 42px) * 0.24), 15px);
  min-width: 0; /* allow h1 to shrink so user-info buttons remain visible */
  /* visible (not hidden) so the Menu button's overlay badge isn't clipped at
     the top; the .app-name child handles its own ellipsis truncation. */
  overflow: visible;
}

.lobby-header .header-menu-button {
  margin-right: clamp(2px, calc(var(--header-live-height, 42px) * 0.12), 10px);
}

.lobby-header .header-menu-button {
  gap: clamp(2px, calc(var(--header-live-height, 42px) * 0.12), 8px);
  line-height: 1;
}

.lobby-header .header-menu-button .menu-button-text {
  font-size: clamp(11px, 0.95vw, 17px);
  display: inline-flex;
  align-items: center;
  line-height: 1;
}

.lobby-header .header-menu-button .menu-button-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: clamp(16px, calc(var(--header-live-height, 42px) * 0.38), 26px);
  height: clamp(16px, calc(var(--header-live-height, 42px) * 0.38), 26px);
  line-height: 1;
}

.lobby-header h1 .app-name {
  font-size: inherit;
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.lobby-header h1 .titlebar-dynamic-status {
  flex-shrink: 0;
  white-space: nowrap;
  overflow: visible;
  font-size: inherit;
}

.lobby-header h1 .titlebar-dynamic-status,
.floating-titlebar-name .titlebar-dynamic-status {
  font-family: inherit;
  font-weight: inherit;
  line-height: inherit;
  opacity: 0.88;
}

.titlebar-dynamic-status.titlebar-dynamic-status-impersonated {
  color: #ff6b6b;
  opacity: 1;
}

.titlebar-dynamic-close {
  appearance: none;
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: #c83a3a;
  color: #fff;
  font-size: clamp(12px, 1vw, 16px);
  line-height: 1;
  min-width: clamp(20px, calc(var(--header-live-height, 42px) * 0.56), 28px);
  height: clamp(20px, calc(var(--header-live-height, 42px) * 0.56), 28px);
  padding: 0 6px;
  cursor: pointer;
  flex: 0 0 auto;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 6px;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.22);
}

.titlebar-dynamic-close:hover:not(:disabled) {
  color: #fff;
  background: #df4a4a;
  border-color: rgba(255, 255, 255, 0.3);
}

.titlebar-dynamic-close:disabled,
.titlebar-dynamic-close.closing {
  opacity: 0.45;
  cursor: default;
}

/* Truncate long usernames with ellipsis rather than pushing controls off-screen */
.lobby-header h1 > span:not(.app-name) {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

.lobby-header .logo {
  width: clamp(16px, calc(var(--header-live-height, 42px) * 0.80), 50px);
  height: clamp(16px, calc(var(--header-live-height, 42px) * 0.80), 50px);
  margin: 0;
  flex-shrink: 0;
}

.user-info {
  display: flex;
  align-items: center;
  gap: clamp(4px, 1vw, 15px);
  flex-shrink: 0;
}

.user-info span {
  white-space: nowrap;
}

.user-profile-link {
  display: flex;
  align-items: center;
  gap: clamp(4px, 0.8vw, 10px);
  cursor: pointer;
  min-width: 0;
}

.user-profile-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: clamp(90px, 20vw, 260px);
}

.lobby-header .app-name,
.user-profile-name,
.tab-dropdown-label {
  font-size: clamp(14px, 1.2vw, 21px);
}

.user-avatar {
  width: clamp(26px, calc(var(--header-live-height, 42px) * 0.62), 46px);
  height: clamp(26px, calc(var(--header-live-height, 42px) * 0.62), 46px);
  border-radius: 50%;
  background: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  font-size: clamp(10px, 0.85vw, 16px);
  color: var(--primary-color);
  flex-shrink: 0;
}

.user-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}

@media (max-width: 560px) {
  .lobby-container .lobby-header .header-menu-button .menu-button-text {
    display: none;
  }

  .lobby-container .user-profile-name {
    display: none;
  }

  .lobby-container .user-profile-link {
    gap: 0;
  }
}

@media (max-width: 300px) {
  .lobby-container .lobby-header h1 .user-avatar {
    display: none;
  }
}

@media (max-width: 200px) {
  .lobby-container .lobby-header h1 span {
    display: none;
  }
}

.tabs {
  display: none !important;
  background: var(--secondary-bg);
  border-bottom: 2px solid var(--border-color);
  overflow: hidden;
  position: relative;
}

.tab {
  padding: 15px 30px;
  background: none;
  border: none;
  cursor: pointer;
  font-size: 16px;
  font-weight: 500;
  color: var(--text-light);
  border-bottom: 3px solid transparent;
  transition: all 0.3s;
  white-space: nowrap;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Compact tab size */
.tabs[data-tab-size="compact"] .tab {
  padding: 12px 20px;
  font-size: 15px;
  gap: 6px;
}

/* Minimal tab size */
.tabs[data-tab-size="minimal"] .tab {
  padding: 10px 15px;
  font-size: 14px;
  gap: 5px;
}

.tab-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}

.close-tab-btn {
  flex-shrink: 0;
  padding: 0 6px;
  font-size: 14px;
  cursor: pointer;
  color: var(--text-light);
}

.close-tab-btn:hover {
  color: var(--text-primary);
}

.close-tab-btn.closing {
  opacity: 0.4;
  cursor: default;
  pointer-events: none;
}

.tab:hover {
  background: var(--border-color);
}

.tab.active {
  color: var(--primary-color);
  border-bottom-color: var(--primary-color);
  background: var(--bg-white);
}

.tab-dropdown {
  position: relative;
  flex-shrink: 0;
}

.tab-more {
  position: relative;
}

.tab-dropdown-menu {
  position: absolute;
  top: 100%;
  right: 0;
  background: var(--bg-white);
  border: 1px solid var(--border-color);
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  min-width: 200px;
  max-width: 280px;
  width: max-content;
  max-height: 400px;
  overflow-y: auto;
  margin-top: 2px;
}

/* Menu dropdown styles */
.btn-small.menu-button {
  font-size: clamp(12px, calc(var(--header-live-height, 42px) * 0.33), 23px);
  padding: clamp(2px, calc(var(--header-live-height, 42px) * 0.08), 11px) clamp(4px, calc(var(--header-live-height, 42px) * 0.26), 16px);
  min-width: clamp(32px, calc(var(--header-live-height, 42px) * 0.80), 60px);
  height: clamp(26px, calc(var(--header-live-height, 42px) * 0.62), 46px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.menu-dropdown {
  background: var(--bg-white);
  border: 1px solid var(--border-color);
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  overflow: hidden;
  min-width: 130px;
  width: max-content;
  max-width: calc(100vw - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px) - 8px);
  max-height: var(--menu-max-height, 90vh);
  overflow-y: auto;
}

@media (min-width: 850px) {
  .menu-dropdown {
    min-width: 200px;
  }
}

.menu-item {
  display: block;
  width: 100%;
  padding: var(--menu-item-pad-y, 12px) 20px;
  background: none;
  border: none;
  cursor: pointer;
  font-size: 16px;
  color: var(--text-primary);
  text-align: left;
  white-space: nowrap;
  transition: background 0.2s;
}

.menu-item:last-child {
  border-bottom: none;
}

.menu-item-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  height: 16px;
  margin-left: 8px;
  padding: 0 4px;
  border-radius: 999px;
  background: #c62828;
  color: #fff;
  font-size: 10px;
  line-height: 1;
  font-weight: 700;
  vertical-align: middle;
}

.menu-item:hover {
  background: var(--secondary-bg);
}

/* An area entry (Play, Observe) while the area is empty */
.menu-item:disabled {
  cursor: default;
  color: var(--text-secondary);
  opacity: 0.6;
}

.menu-item:disabled:hover {
  background: none;
}

/* Compact menu items on small screens */
@media (max-width: 849px) {
  .menu-item {
    padding-left: 10px;
    padding-right: 10px;
    font-size: 13px;
  }
}

/* On mobile/touch devices, maintain minimum 16px font size to prevent zoom */
@media (hover: none) and (pointer: coarse) {
  .menu-item {
    font-size: 16px !important;
  }

  /* Enforce a 12pt readability floor on mobile UI text.
     Board point numbering is exempted and remains canvas-driven. */
  :where(
    body,
    button,
    input,
    select,
    textarea,
    option,
    label,
    p,
    a,
    li,
    dt,
    dd,
    td,
    th,
    caption,
    figcaption,
    legend,
    summary,
    span,
    small,
    strong,
    em,
    code,
    pre,
    kbd,
    samp,
    blockquote,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6
  ):not(.react-gametab-toolbar-icon):not(.menu-button-icon):not(.tab-icon):not(.board-point-number) {
    font-size: max(12pt, 1em);
  }
}

/* Enforce the same mobile floor for app-declared mobile layouts, regardless
   of device pointer reporting in embedded/webview contexts. */
:is(.lobby-container.smartphone, .react-gametab-root.is-mobile)
  :where(
    button,
    input,
    select,
    textarea,
    option,
    label,
    p,
    a,
    li,
    dt,
    dd,
    td,
    th,
    caption,
    figcaption,
    legend,
    summary,
    span,
    small,
    strong,
    em,
    code,
    pre,
    kbd,
    samp,
    blockquote,
    h1,
    h2,
    h3,
    h4,
    h5,
    h6
  ):not(.react-gametab-toolbar-icon):not(.menu-button-icon):not(.tab-icon):not(.board-point-number) {
  font-size: max(12pt, 1em);
}

:is(.lobby-container.smartphone, .react-gametab-root.is-mobile) {
  font-size: max(12pt, 1em);
}

:is(.lobby-container.smartphone, .react-gametab-root.is-mobile) .analysis-panel {
  font-size: inherit;
}

.menu-divider {
  height: 1px;
  background: var(--border-color);
  margin: var(--menu-divider-margin, 4px) 0;
}

/* Added: a heading over menu entries (Play over its areas Human, Bot, Chouette; MainLobby
   navMenuItems type 'heading'): not selectable, so in the secondary text colour; the entries
   under it (.menu-item-sub) are indented */
.menu-heading {
  padding: 10px 20px 4px;
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: default;
  user-select: none;
}

.menu-item.menu-item-sub {
  padding-left: 36px;
}

.tab-dropdown-label {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Added: the row of the left nav (MainLobby sideNavShown) and the tab content */
.lobby-body {
  flex: 1;
  display: flex;
  min-height: 0;
}

.tab-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  position: relative;
}

/* The menu as a nav fixed on the left (enough room for it: MainLobby SIDE_NAV_MIN_*), with a
   « to collapse it into the Menu button */
.lobby-side-nav {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  /* Changed: a fixed width (was min-width 160px, else its content's), so the title bar's slot
     above it (.lobby-header-nav-slot) has the same width and the divider lines up */
  width: var(--side-nav-width);
  box-sizing: border-box;
  padding: 8px 0;
  border-right: 1px solid var(--border-color);
  background: var(--bg-white);
  overflow-y: auto;
}

.lobby-side-nav .menu-divider {
  margin: 6px 0;
}

/* The width of the pinned menu and of the title bar's slot above it */
.lobby-container {
  --side-nav-width: 180px;
}

/* While the menu is pinned the title bar continues its column: no padding on the left, top and
   bottom, so the slot reaches the header's left edge and full height; the title starts right of
   the slot's divider line, which continues the nav's */
.lobby-header.has-side-nav {
  padding-left: 0;
  padding-top: 0;
  padding-bottom: 0;
}

.lobby-header.has-side-nav h1 {
  align-self: stretch;
}

/* Changed: « and "Menu" at the left, where » and the Menu button are while the menu is
   collapsed: the header's left padding (which has-side-nav removes) and the h1's gap */
.lobby-header-nav-slot {
  flex: 0 0 auto;
  width: var(--side-nav-width);
  box-sizing: border-box;
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: clamp(4px, calc(var(--header-live-height, 42px) * 0.24), 15px);
  padding-left: clamp(4px, calc(var(--header-live-height, 42px) * 0.16), 20px);
  padding-right: 8px;
  border-right: 1px solid var(--border-color);
}

/* "Menu" in the slot: plain text. Changed: in the Menu button's size (.menu-button-text), not the
   title's (the h1's), so it does not compete with the area's name right of the divider */
.lobby-header-nav-label {
  white-space: nowrap;
  font-size: clamp(11px, 0.95vw, 17px);
}

/* The collapse («) in the title bar's slot and the expand (») left of the Menu button, in the
   header's colours */
.lobby-side-nav-collapse {
  padding: 2px 8px;
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: 6px;
  background: none;
  color: inherit;
  font-size: 16px;
  line-height: 1.2;
  cursor: pointer;
}

.lobby-side-nav-collapse:hover {
  background: rgba(255, 255, 255, 0.15);
}

.tab-content > div:not([id^="game-root-"]):not(.react-gametab-shell):not(.lobby-floating-titlebar):not(.lobby-overlay-layer) {
  flex: 1;
  overflow: auto;
  min-height: 0;
}

.tab-content > [id^="game-root-"] {
  overflow: auto;
}

.tab-content > div:not([id^="game-root-"]):not(.react-gametab-shell):not(.lobby-floating-titlebar):not(.lobby-overlay-layer) {
  padding: 30px;
}

.tab-content > div.tutorial-tab-root:not([id^="game-root-"]):not(.lobby-floating-titlebar):not(.lobby-overlay-layer) {
  padding: 0;
}

/* Explore and Setup are laid out like a game tab, to the edges of the page */
.tab-content > div.position-page:not([id^="game-root-"]):not(.lobby-floating-titlebar):not(.lobby-overlay-layer) {
  padding: 0;
  overflow: hidden;
}

/* Added: the Play page's tabs reach the page's edges; its content below them has the page's
   padding (.play-tab-body) */
.tab-content > div.play-tab:not([id^="game-root-"]):not(.lobby-floating-titlebar):not(.lobby-overlay-layer) {
  padding: 0;
}

.lobby-overlay-layer {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  background: rgba(0, 0, 0, 0.08);
}

.lobby-overlay-layer.is-keyboard-visible {
  background: var(--bg-color);
}

.tab-content.overlay-keyboard-visible > *:not(.lobby-overlay-layer) {
  display: none !important;
}

.lobby-overlay-panel {
  height: 70%;
  background: var(--bg-white);
  border-bottom: 2px solid var(--border-color);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
  display: flex;
  flex-direction: column;
}

.lobby-overlay-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border-color);
  background: var(--secondary-bg);
}

.lobby-overlay-title {
  font-weight: 700;
  color: var(--text-primary);
}

.lobby-overlay-close {
  border: none;
  background: transparent;
  color: var(--text-primary);
  font-size: 22px;
  cursor: pointer;
  line-height: 1;
}

.lobby-overlay-content {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.tutorial-tab-root ul {
  padding-left: 1.5em;
  margin: 0.5em 0;
}

[id^="game-root-"] {
  flex: 1;
  overflow: hidden;
  min-height: 0;
  padding: 0;
  margin: 0;
  border: none;
  position: relative;
}

/* Floating lobby title bar for landscape game tabs */
.lobby-floating-titlebar {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 2px;
  background: linear-gradient(135deg, var(--primary-start) 0%, var(--primary-end) 100%);
  padding: 0 4px;
  overflow: hidden;
}

/*
 * When the mobile soft keyboard is open we constrain the app root to the
 * visualViewport height. The floating title bar and corner menu button are
 * position:fixed and anchored to the layout viewport, so without hiding they
 * remain visible above the constrained root and clutter the chat area.
 * Match the portrait keyboard-mode behavior: show only the chat/setup panel.
 */
.lobby-container.mobile-keyboard-active .lobby-floating-titlebar,
.lobby-container.mobile-keyboard-active .floating-corner-menu-btn {
  display: none;
}

/* In fullscreen, add right padding to keep icons away from the notch/cutout
   and the device's rounded display corners. */
.lobby-floating-titlebar.fullscreen {
  padding-right: max(env(safe-area-inset-right, 40px), 40px);
}

/* Changed: wraps when the area's close (and "Back to game") and the right
   actions (avatar, fullscreen) do not fit in one line. wrap-reverse stacks the
   lines upwards, so the right actions, last in the DOM, are the top line and
   the close goes into the line below them, at the left. Its cross-start is
   the bottom of a line, so align-items flex-end keeps the items top aligned.
   The bar has only a min-height in LS (MainLobby) so the second line takes
   room instead of overflowing above the bar. */
.lobby-floating-titlebar.is-landscape-ls {
  display: flex;
  flex-wrap: wrap-reverse;
  align-items: flex-end;
  align-content: flex-end;
  justify-content: space-between;
  gap: 6px;
  background: transparent;
  padding: 0;
  overflow: visible;
  pointer-events: none;
}

.lobby-container.fullscreen .lobby-floating-titlebar.is-landscape-ls.fullscreen {
  padding-right: max(env(safe-area-inset-right, 0px), 24px);
}

.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-right-actions {
  position: relative;
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 6px;
  pointer-events: auto;
  z-index: 29;
}

/* The game's area and its close (MainLobby: "Play ×"), first in the landscape
   LS title bar. Styled like the regular title bar's white bold title and red
   close (titlebar-dynamic-close), without a background of its own. */
.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-area {
  position: relative;
  z-index: 29;
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 26px;
  padding: 0 4px 0 8px;
  box-sizing: border-box;
  /* Changed: the theme's text colour, it was white: the LS bar is transparent, so the page shows
     behind the area's name (the close has its own colours) */
  color: var(--text-primary);
  flex-shrink: 0;
}

/* Play mode: only the close, left aligned with the panel switcher below and
   the same size as its buttons (.react-gametab-landscape-ls-mode-rail, radius
   10px), so the column lines up. The size is the rail buttons' measured one
   (--ls-rail-btn-px, GameTab lsModeRailButtonPx): it depends on the device
   and the panel font scale. 34px is the rail's own size, before the first
   measurement. */
.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-area.is-play-mode {
  padding-left: 0;
  height: var(--ls-rail-btn-px, 34px);
}

.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-area.is-play-mode .titlebar-dynamic-close {
  width: var(--ls-rail-btn-px, 34px);
  min-width: var(--ls-rail-btn-px, 34px);
  height: var(--ls-rail-btn-px, 34px);
  padding: 0;
  border-radius: 10px;
  font-size: 16px;
}

.floating-titlebar-area-name {
  font-size: 10pt;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
}

.floating-titlebar-area .titlebar-dynamic-close {
  min-width: 20px;
  height: 20px;
  font-size: 12px;
}

/* Added: the apps' ← in front of the area (MainLobby appBackShown), in the area's text colour */
.floating-titlebar-area .floating-titlebar-back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: none;
  color: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.floating-titlebar-area .floating-titlebar-back:active {
  background: var(--app-hover-fill);
}

.floating-titlebar-area .floating-titlebar-back .header-control-icon {
  width: 20px;
  height: 20px;
}

/* "Back to game" (MainLobby) in the landscape LS title bar, which has no
   corner button any more; like the header's button */
.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-back-to-game {
  position: relative;
  z-index: 29;
  pointer-events: auto;
  flex-shrink: 0;
  height: 24px;
  padding: 0 8px;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  background: linear-gradient(135deg, var(--primary-start) 0%, var(--primary-end) 100%);
  color: #fff;
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
}

.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-btn {
  display: flex;
  margin: 0;
  width: 26px !important;
  height: 26px !important;
  border-radius: 10px;
  pointer-events: auto;
  opacity: 1;
  border: 1px solid rgba(23, 34, 46, 0.22);
  color: #16202b;
  background: rgba(255, 255, 255, 0.94);
}

.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-right-actions .floating-titlebar-btn {
  margin: 0;
}

.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-btn:hover:not(:disabled) {
  background: rgba(255, 255, 255, 0.99);
}

/* The floating title bar's notification menu button (MainLobby floatingNotificationItems): a
   bell with the header's count badge; in the primary colour while it holds "Back to game", and
   pulsing while a match search runs */
.floating-notification-btn {
  position: relative;
  align-items: center;
  justify-content: center;
}

.floating-notification-icon {
  width: 70%;
  height: 70%;
  display: block;
}

.lobby-floating-titlebar .floating-notification-btn.is-back-to-game {
  background: linear-gradient(135deg, var(--primary-start) 0%, var(--primary-end) 100%);
  border-color: transparent;
  color: #fff;
}

.floating-notification-btn.is-searching {
  animation: play-tab-choice-pulse 3s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
  .floating-notification-btn.is-searching {
    animation: none;
  }
}

.floating-titlebar-name {
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  min-width: 0;
  margin-right: 6px;
  color: #fff;
  font-size: 10pt;
  font-weight: 700;
  line-height: 1;
  overflow: hidden;
  text-overflow: ellipsis;
}

.floating-titlebar-base-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.floating-titlebar-name .titlebar-dynamic-status {
  flex-shrink: 0;
  white-space: nowrap;
}

.floating-titlebar-btn {
  border: none;
  background: transparent;
  color: white;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.85;
  flex-shrink: 0;
  position: relative;
}

.app-tooltip {
  position: fixed;
  padding: 4px 8px;
  background: rgba(20, 25, 32, 0.92);
  color: #fff;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.2;
  max-width: 300px;
  white-space: normal;
  border-radius: 4px;
  pointer-events: none;
  z-index: 1000;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.25);
}

.app-tooltip-target {
  display: inline-flex;
}

.floating-titlebar-btn:hover {
  opacity: 1;
  background: rgba(255, 255, 255, 0.15);
}

.floating-titlebar-btn:disabled,
.floating-titlebar-btn.closing {
  opacity: 0.45;
  cursor: default;
  pointer-events: none;
}

.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-btn:disabled,
.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-btn.closing {
  opacity: 0.42;
}

.floating-titlebar-btn img {
  filter: brightness(0) invert(1);
}

.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-btn img {
  filter: none;
}

/* Account avatar sits in the landscape-LS right actions (left of fullscreen).
   Fill the 26px rounded button and drop the avatar's own chrome. */
.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-avatar-btn {
  padding: 0;
  overflow: hidden;
}

.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-avatar-btn .user-avatar {
  width: 100%;
  height: 100%;
  border-radius: inherit;
  background: #fff;
  font-size: 12px;
  color: var(--primary-color);
}

.lobby-floating-titlebar.is-landscape-ls .floating-titlebar-avatar-btn .user-avatar img {
  border-radius: inherit;
}

.floating-corner-menu-btn {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 4px);
  left: calc(env(safe-area-inset-left, 0px) + 4px);
  z-index: 50;
  border: none;
  background: linear-gradient(135deg, var(--primary-start) 0%, var(--primary-end) 100%);
  color: white;
  border-radius: 6px;
  min-width: 30px;
  height: 30px;
  font-size: 20px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}

.floating-corner-menu-btn.is-expanded {
  gap: 6px;
  padding: 0 10px;
  width: auto;
  min-width: 78px;
  font-size: 14px;
}

.floating-corner-menu-btn.is-landscape-ls {
  border: 1px solid rgba(23, 34, 46, 0.22);
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.94) 0%, rgba(247, 250, 253, 0.94) 100%);
  color: #16202b;
  border-radius: 10px;
  min-width: 34px;
  width: 34px;
  height: 34px;
  padding: 0;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16);
}

[data-theme="dark"] .lobby-floating-titlebar.is-landscape-ls .floating-titlebar-btn {
  border-color: rgba(255, 255, 255, 0.16);
  color: #fff;
  background: rgba(22, 28, 36, 0.34);
}

[data-theme="dark"] .lobby-floating-titlebar.is-landscape-ls .floating-titlebar-btn:hover:not(:disabled) {
  background: rgba(22, 28, 36, 0.52);
}

[data-theme="dark"] .lobby-floating-titlebar.is-landscape-ls .floating-titlebar-btn img {
  filter: brightness(0) invert(1);
}

/* The account avatar is a real photo, not a monochrome icon -- never invert it. */
[data-theme="dark"] .lobby-floating-titlebar.is-landscape-ls .floating-titlebar-avatar-btn img {
  filter: none;
}

[data-theme="dark"] .floating-corner-menu-btn.is-landscape-ls {
  border: 1px solid rgba(255, 255, 255, 0.32);
  background: linear-gradient(135deg, rgba(21, 29, 40, 0.92) 0%, rgba(27, 37, 52, 0.92) 100%);
  color: #fff;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.24);
}

.floating-corner-menu-btn.is-expanded.is-landscape-ls {
  width: 78px;
  height: 34px;
}

.floating-corner-menu-btn.is-expanded .menu-button-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
}

.floating-corner-menu-btn.is-expanded .menu-button-text {
  display: inline-flex;
  align-items: center;
  line-height: 1;
  font-weight: 600;
}

/* Lists */
.list-item {
  background: var(--bg-white);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 15px;
  transition: all 0.3s;
}

.list-item:hover {
  box-shadow: 0 4px 12px var(--shadow-color);
  transform: translateY(-2px);
}

.profile-summary-card:hover {
  transform: none;
}

/* Player list items - compact horizontal layout */
.player-list-item {
  background: var(--bg-white);
  border: 1px solid var(--border-color);
  border-radius: 6px;
  padding: 6px 12px;
  margin-bottom: 4px;
  transition: all 0.3s;
}

.player-list-item:hover {
  box-shadow: 0 4px 12px var(--shadow-color);
  transform: translateY(-2px);
}

.react-gametab-toolbar-icon-with-badge {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.react-gametab-toolbar-icon-with-badge .react-gametab-toolbar-badge {
  position: absolute;
  top: -8px;
  right: -6px;
  pointer-events: none;
}

.list-item h3 {
  color: var(--text-primary);
  margin-bottom: 10px;
  font-size: 18px;
}

.list-item p {
  color: var(--text-secondary);
  margin-bottom: 5px;
  font-size: 14px;
}

.badge {
  display: inline-block;
  padding: 4px 12px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: 600;
  margin-right: 8px;
  margin-top: 8px;
}

.badge-public {
  background: #e3f2fd;
  color: #1976d2;
}

.badge-private {
  background: #fce4ec;
  color: #c2185b;
}

.badge-active {
  background: #e8f5e9;
  color: #388e3c;
}

.badge-scheduled {
  background: #fff3e0;
  color: #f57c00;
}

/* Added: an online player in a game (Players tab, lobby availability.go) */
.player-busy-note {
  margin-left: 6px;
  font-size: 11px;
  color: var(--text-secondary);
}

.badge-online {
  background: #4caf50;
  color: white;
}

/* Player Cards */
.player-card {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 1;
}

.player-photo {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--secondary-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  font-weight: bold;
  color: var(--text-secondary);
  flex-shrink: 0;
  overflow: hidden;
}

.player-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.player-info {
  flex: 1;
  min-width: 0;
}

.player-name {
  font-weight: 600;
  color: var(--text-primary);
  font-size: 14px;
  margin-bottom: 1px;
  line-height: 1.2;
}

.player-details {
  color: var(--text-secondary);
  font-size: 12px;
  margin-top: 1px;
  line-height: 1.2;
}

.rating-stars {
  color: #ffa000;
  font-size: 11px;
  margin-top: 0;
}

/* Buttons in lists */
.action-buttons {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}

.btn-small {
  padding: 4px 8px;
  font-size: 12px;
  width: auto;
  margin: 0;
  white-space: nowrap;
  line-height: 1.2;
}

.btn-session {
  padding: 4px 8px;
  font-size: 12px;
  width: auto;
  margin: 0;
  white-space: nowrap;
  line-height: 1.2;
}

/* Modal */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal {
  background: var(--bg-white);
  border-radius: 12px;
  padding: 30px;
  max-width: 600px;
  width: 90%;
  max-height: 90vh;
  overflow-y: auto;
}

.modal-small {
  max-width: 400px;
}

.modal h2 {
  margin-bottom: 20px;
  color: var(--text-primary);
}

.modal-actions {
  display: flex;
  gap: 10px;
  margin-top: 20px;
}

/* Empty State */
.empty-state {
  text-align: center;
  padding: 60px 20px;
  color: var(--text-light);
}

.empty-state-icon {
  font-size: 64px;
  margin-bottom: 20px;
}

.empty-state p {
  font-size: 18px;
  margin-bottom: 20px;
}

/* Loading */
.loading {
  text-align: center;
  padding: 40px;
  color: #999;
  font-size: 18px;
}

/* Rating Display */
.rating-detail {
  background: var(--secondary-bg);
  padding: 15px;
  border-radius: 5px;
  margin-bottom: 15px;
  border: 1px solid var(--border-color);
}

.rating-category {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
  font-size: 14px;
}

/* Detail text used in session cards, rating UI, etc. */
.detail-text {
  font-size: 13px;
}

.rating-response {
  background: #e3f2fd;
  padding: 15px;
  border-radius: 6px;
  margin-top: 10px;
  font-style: italic;
}

/* Smartphone scrollable tab bar */
.lobby-container.smartphone .tabs {
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none; /* Firefox */
}
.lobby-container.smartphone .tabs::-webkit-scrollbar {
  display: none; /* Chrome/Safari */
}

/* Responsive */
@media (max-width: 768px) {
  .tabs {
    justify-content: flex-start;
  }

  /* Default tab sizing on mobile - will be overridden by data-tab-size if set */
  .tabs:not([data-tab-size]) .tab {
    padding: 12px 20px;
    font-size: 14px;
  }

  /* Removed: a 15px page padding up to 768px wide. Its selector was invalid (":div:not"), so it
     never applied; a phone's page padding is in the "Phones and small windows: lobby pages without a
     frame"
     block at the end of this file. */

  .auth-box {
    padding: 30px 20px;
  }

  .modal {
    padding: 20px;
  }
}

/* Vertical space optimization for Create Account form */
/* Medium spacing: 850-1050px height */
@media (max-height: 1050px) {
  .auth-container {
    align-items: flex-start;
    /* Changed: with the safe areas, as the rule without this query */
    padding: calc(10px + env(safe-area-inset-top, 0px)) 10px calc(10px + env(safe-area-inset-bottom, 0px));
  }

  .auth-box {
    padding: 25px;
    margin: 10px 0;
  }

  .auth-box h1 {
    margin-bottom: 20px;
    font-size: 24px;
  }

  .logo {
    width: 60px;
    height: 60px;
    margin: 0 auto 15px;
  }

  .form-group {
    margin-bottom: 15px;
  }

  .form-group label {
    margin-bottom: 5px;
  }

  .form-group input,
  .form-group select,
  .form-group textarea {
    padding: 10px;
  }
}

/* Compact spacing: below 850px height */
@media (max-height: 850px) {
  .auth-container {
    /* Changed: with the safe areas, as the rule without this query */
    padding: calc(5px + env(safe-area-inset-top, 0px)) 5px calc(5px + env(safe-area-inset-bottom, 0px));
  }

  .auth-box {
    padding: 15px;
    margin: 5px 0;
  }

  .auth-box h1 {
    margin-bottom: 10px;
    font-size: 18px;
  }

  .logo {
    width: 40px;
    height: 40px;
    margin: 0 auto 8px;
  }

  .form-group {
    margin-bottom: 8px;
  }

  .form-group label {
    margin-bottom: 3px;
    font-size: 13px;
  }

  .form-group input,
  .form-group select,
  .form-group textarea {
    padding: 6px;
    font-size: 13px;
  }

  .auth-container .btn {
    padding: 8px 16px;
    font-size: 13px;
    margin-top: 5px;
  }

  /* My Chouettes Tab - responsive buttons */
  .action-buttons {
    flex-wrap: wrap;
    gap: 4px;
  }

  .action-buttons .btn-small {
    padding: 4px 8px;
    font-size: 10px;
  }

  /* Chouette header - stack vertically on mobile */
  .chouette-header {
    flex-direction: column;
    align-items: stretch !important;
  }

  .chouette-header h2 {
    margin-bottom: 10px !important;
  }

  .chouette-header .btn {
    width: 100%;
    font-size: 14px;
  }
}

/* Very compact spacing: below 700px height */
@media (max-height: 700px) {
  .auth-box .logo {
    width: 30px;
    height: 30px;
    margin: 0 auto 5px;
  }

  .auth-box .step-indicator {
    display: none;
  }
  
  .auth-box {
    padding: 10px 15px;
    margin: 0;
  }
  
  .auth-box h1 {
    margin-bottom: 5px;
    margin-top: 0;
    font-size: 16px;
  }

  .form-group {
    margin-bottom: 6px;
  }
}

/* Theme toggle and fullscreen toggle buttons - specific override for icon buttons */
.btn-small.theme-toggle,
.btn-small.fullscreen-toggle {
  padding: clamp(1px, calc(var(--header-live-height, 42px) * 0.06), 4px) clamp(2px, calc(var(--header-live-height, 42px) * 0.12), 8px);
  font-size: clamp(12px, 1.1vw, 18px);
  min-width: clamp(24px, calc(var(--header-live-height, 42px) * 0.62), 40px);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Keep all header control buttons at exactly the same height in mobile/compact states. */
.lobby-header .btn-small.menu-button,
.lobby-header .btn-small.search-toggle,
.lobby-header .btn-small.challenges-toggle,
.lobby-header .btn-small.players-toggle,
.lobby-header .btn-small.messages-toggle,
.lobby-header .btn-small.fullscreen-toggle {
  height: clamp(26px, calc(var(--header-live-height, 42px) * 0.62), 46px);
  min-height: clamp(26px, calc(var(--header-live-height, 42px) * 0.62), 46px);
  box-sizing: border-box;
}

/* Keep the header icon controls visually consistent (they used to match the
   removed "My games" pill) */
.lobby-header .header-menu-button,
.icon-buttons-container .btn-small.search-toggle,
.icon-buttons-container .btn-small.challenges-toggle,
.icon-buttons-container .btn-small.players-toggle,
.icon-buttons-container .btn-small.messages-toggle,
.icon-buttons-container .btn-small.fullscreen-toggle {
  border: 1px solid rgba(255, 255, 255, 0.28);
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.22) 0%, rgba(255, 255, 255, 0.10) 100%);
  color: #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
}

.lobby-header .header-menu-button:hover,
.icon-buttons-container .btn-small.players-toggle:hover,
.icon-buttons-container .btn-small.messages-toggle:hover,
.icon-buttons-container .btn-small.fullscreen-toggle:hover {
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.28) 0%, rgba(255, 255, 255, 0.14) 100%);
}

.icon-buttons-container .btn-small.players-toggle.is-active,
.icon-buttons-container .btn-small.messages-toggle.is-active,
.floating-titlebar-btn.is-active {
  opacity: 1;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.34) 0%, rgba(255, 255, 255, 0.18) 100%);
  border-color: var(--selection-border-blue, #4a7bd9);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.32), 0 1px 4px rgba(0, 0, 0, 0.2);
}

.icon-buttons-container .btn-small.players-toggle.is-active:hover,
.icon-buttons-container .btn-small.messages-toggle.is-active:hover,
.floating-titlebar-btn.is-active:hover {
  border-color: var(--selection-border-blue, #4a7bd9);
}

/* Keep header icon buttons visually consistent with the menu icon */
.btn-small.search-toggle,
.btn-small.challenges-toggle,
.btn-small.players-toggle,
.btn-small.messages-toggle {
  padding: clamp(2px, calc(var(--header-live-height, 42px) * 0.08), 11px) clamp(4px, calc(var(--header-live-height, 42px) * 0.26), 16px);
  min-width: clamp(32px, calc(var(--header-live-height, 42px) * 0.80), 60px);
  height: clamp(26px, calc(var(--header-live-height, 42px) * 0.62), 46px);
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

.header-control-icon {
  display: block;
  width: clamp(14px, calc(var(--header-live-height, 42px) * 0.33), 24px);
  height: clamp(14px, calc(var(--header-live-height, 42px) * 0.33), 24px);
  margin: 0 auto;
}

.header-overlay-btn {
  position: relative;
}

.header-overlay-badge {
  position: absolute;
  top: -5px;
  right: -5px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: 999px;
  background: #c62828;
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.85);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  line-height: 1;
  font-weight: 700;
  pointer-events: none;
}

.menu-button-icon .header-control-icon {
  width: 100%;
  height: 100%;
}

/* Make theme toggle icon larger to match fullscreen icon size */
.btn-small.theme-toggle {
  font-size: clamp(16px, calc(var(--header-live-height, 42px) * 0.38), 26px);
}

/* Container for icon buttons in vertical layout */
.icon-buttons-container {
  display: flex;
  gap: clamp(2px, calc(var(--header-live-height, 42px) * 0.16), 8px);
}

/* Smooth transitions for theme changes - applied to specific elements only */
body,
.lobby-container,
.tab-button,
.btn,
.modal-content,
.session-card,
input,
textarea,
select,
.tab-content {
  transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}

/* Modal Content */
.modal-content {
  background: var(--bg-white);
  border-radius: 12px;
  max-width: 700px;
  width: 90%;
  max-height: 90vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 24px;
  border-bottom: 1px solid var(--border-color);
  background: var(--bg-white);
  flex-shrink: 0;
}

.modal-header h2 {
  margin: 0;
  color: var(--text-primary);
  font-size: 18px;
}

.close-button {
  background: none;
  border: none;
  font-size: 32px;
  color: var(--text-secondary);
  cursor: pointer;
  padding: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

.close-button:hover {
  color: var(--text-primary);
}

/* Tabs */
.tabs {
  display: flex;
  border-bottom: 1px solid var(--border-color);
  background: var(--secondary-bg);
}

/* Tab Content - for modals and other contexts */
.modal .tab-content {
  padding: 30px;
  overflow-y: auto;
  flex: 1;
}

/* Main lobby tab content should not have padding */
.lobby-container .tab-content {
  padding: 0;
  background: var(--bg-white);
}

.settings-section {
  display: flex;
  flex-direction: column;
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.form-group label {
  font-weight: 500;
  color: var(--text-primary);
  font-size: 14px;
}

.form-group input[type="number"],
.form-group input[type="text"],
.form-group input[type="date"],
.form-group input[type="time"],
.form-group select {
  padding: 10px 12px;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  font-size: 14px;
  background: var(--bg-white);
  color: var(--text-primary);
}

/* Date/time picker dropdown styling in dark mode */
[data-theme="dark"] input[type="date"]::-webkit-datetime-edit,
[data-theme="dark"] input[type="time"]::-webkit-datetime-edit {
  color: var(--text-primary);
}

[data-theme="dark"] input[type="date"]::-webkit-datetime-edit-fields-wrapper,
[data-theme="dark"] input[type="time"]::-webkit-datetime-edit-fields-wrapper {
  background: var(--bg-white);
}

.form-group input:focus,
.form-group select:focus {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-color) 10%, transparent); /* Changed: was a fixed teal tint; follows the game tab accent */
}

.form-group.checkbox {
  flex-direction: row;
  align-items: center;
  gap: 10px;
}

.form-group.checkbox label {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  font-weight: normal;
}

.form-group.checkbox input[type="checkbox"] {
  width: 18px;
  height: 18px;
  cursor: pointer;
}

.help-text {
  color: var(--text-light);
  font-size: 12px;
  margin-top: 4px;
  display: block;
}

.session-details-box {
  padding: 10px;
  background: var(--secondary-bg);
  border: 1px solid var(--border-color);
  border-radius: 4px;
  font-size: 14px;
}

.session-details-box p {
  margin: 6px 0;
}

/* Modal Footer */
.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 16px 24px;
  border-top: 1px solid var(--border-color);
  background: var(--bg-white);
  flex-shrink: 0;
}

.modal-footer .primary-button,
.modal-footer .secondary-button,
.modal-footer .btn {
  padding: 8px 20px;
}

/* Modal Body */
.modal-body {
  padding: 20px 24px;
  flex: 1 1 auto;
  overflow-y: auto;
}

.primary-button,
.secondary-button {
  padding: 10px 20px;
  border-radius: 6px;
  border: none;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  transition: all 0.2s;
}

.primary-button {
  background: var(--primary-color);
  color: white;
}

.primary-button:hover:not(:disabled) {
  background: var(--primary-hover);
}

/* Added: there was no disabled look, so a disabled button looked enabled. As .btn-primary:disabled. */
.primary-button:disabled {
  background: var(--border-color);
  color: var(--text-light);
  cursor: not-allowed;
  opacity: 0.6;
}

.secondary-button {
  background: var(--border-color);
  color: var(--text-primary);
}

.secondary-button:hover {
  background: var(--text-light);
  color: white;
}

/* EditChouetteModal - Compact Form Styles */
.edit-chouette-label {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  color: var(--text-primary);
  font-weight: 500;
}

.edit-chouette-input {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--bg-white);
  color: var(--text-primary);
}

.edit-chouette-input:focus {
  outline: none;
  border-color: var(--primary-color);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-color) 10%, transparent); /* Changed: was a fixed teal tint; follows the game tab accent */
}

.edit-chouette-checkbox-label {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-bottom: 0;
  cursor: pointer;
  color: var(--text-primary);
}

.edit-chouette-section-header {
  padding-bottom: 4px;
  font-weight: 600;
  border-bottom: 2px solid var(--border-color);
  color: var(--primary-color);
}

.edit-chouette-help-icon {
  display: inline-flex;
  align-items: center;
  margin-left: 6px;
  cursor: help;
  font-size: 12px;
  color: #666;
  position: relative;
  flex-shrink: 0;
  z-index: 1;
}

[data-theme="dark"] .edit-chouette-help-icon {
  color: #999;
}

.edit-chouette-tooltip {
  position: absolute;
  top: -5px;
  background-color: #333;
  color: #fff;
  padding: 8px 12px;
  border-radius: 4px;
  font-size: 12px;
  z-index: 1000;
  box-shadow: 0 2px 8px rgba(0,0,0,0.2);
  pointer-events: none;
  line-height: 1.4;
}

.edit-chouette-tooltip ul {
  margin: 4px 0 0 0;
  padding-left: 18px;
}

/* During measurement phase, don't wrap */
.edit-chouette-tooltip.measuring {
  white-space: nowrap;
}

/* After positioning, allow wrapping with max-width */
.edit-chouette-tooltip.positioned {
  white-space: normal;
  max-width: 300px;
  word-wrap: break-word;
}

.edit-chouette-tooltip.tooltip-left {
  right: 20px;
}

.edit-chouette-tooltip.tooltip-right {
  left: 20px;
}

.edit-chouette-tooltip.tooltip-center {
  left: 50%;
  transform: translateX(-50%);
}

/* Mobile Responsiveness */
@media (max-width: 768px) {
  .modal-content {
    width: 95%;
    max-height: 95vh;
  }

  .modal-header {
    padding: 15px 20px;
  }

  .modal-header h2 {
    font-size: 18px;
  }

  .modal .tab-content {
    padding: 20px;
  }
  
  .lobby-container .tab-content {
    padding: 0;
  }

  /* Reduce gap in header to make room for menu button - only on mobile */
  .lobby-container.smartphone .lobby-header h1 {
    gap: 8px;
    font-size: 18px;
  }
  
  .lobby-container.smartphone .lobby-header .logo {
    width: 35px;
    height: 35px;
  }
  
  .lobby-container.smartphone .user-avatar {
    width: clamp(26px, calc(var(--header-live-height, 42px) * 0.62), 46px) !important;
    height: clamp(26px, calc(var(--header-live-height, 42px) * 0.62), 46px) !important;
    font-size: clamp(12px, 3.2vw, 14px) !important;
  }

  /* Keep menu button visible in portrait by prioritizing controls over labels */
  .lobby-container.smartphone-portrait .lobby-header {
    padding-left: 6px;
    padding-right: 6px;
  }

  .lobby-container.smartphone-portrait .lobby-header h1 {
    gap: 6px;
    min-width: 0;
  }

  .lobby-container.smartphone-portrait .user-info {
    gap: 6px;
    min-width: 0;
  }

  .lobby-container.smartphone-portrait .lobby-header .header-menu-button {
    flex-shrink: 0;
  }

  /* Default tab sizing on mobile - will be overridden by data-tab-size if set */
  .tabs:not([data-tab-size]) .tab {
    padding: 12px 15px;
    font-size: 13px;
    white-space: nowrap;
  }
}

/* Keep horizontal header in mobile landscape; only compact controls when width is tight */
@media (max-width: 780px) and (orientation: landscape) {
  .lobby-container.smartphone-landscape .lobby-header {
    padding-top: 2px;
    padding-bottom: 2px;
    padding-left: 6px;
    padding-right: 6px;
  }

  .lobby-container.smartphone-landscape .lobby-header h1 {
    gap: 6px;
    font-size: clamp(12px, 2vw, 16px);
  }

  .lobby-container.smartphone-landscape .lobby-header .logo {
    width: 18px;
    height: 18px;
  }

  .lobby-container.smartphone-landscape .user-info {
    gap: 6px;
  }

  .lobby-container.smartphone-landscape .btn-small.menu-button,
  .lobby-container.smartphone-landscape .btn-small.search-toggle,
  .lobby-container.smartphone-landscape .btn-small.challenges-toggle,
  .lobby-container.smartphone-landscape .btn-small.players-toggle,
  .lobby-container.smartphone-landscape .btn-small.messages-toggle,
  .lobby-container.smartphone-landscape .btn-small.fullscreen-toggle {
    height: 26px;
    padding-top: 2px;
    padding-bottom: 2px;
  }

  .lobby-container.smartphone-landscape .menu-button-text,
  .lobby-container.smartphone-landscape .user-profile-name {
    display: none;
  }

  .lobby-container.smartphone-landscape .user-avatar {
    width: 26px !important;
    height: 26px !important;
    font-size: clamp(10px, 1.8vw, 12px) !important;
  }
}

/* Very limited header space: hide text labels but keep icon buttons */
@media (max-width: 460px) {
  .lobby-container.smartphone-portrait .menu-button-text,
  .lobby-container.smartphone-portrait .user-profile-name {
    display: none;
  }

  .lobby-container.smartphone-portrait .user-profile-link {
    gap: 0;
  }
}

/* Reduce tab height for small screens or smartphone landscape */
@media (max-height: 700px) {
  .lobby-container .tabs .tab {
    padding-top: 2px;
    padding-bottom: 2px;
  }
}

/* Smartphone landscape mode - applied via class */
.lobby-container.smartphone-landscape .tabs .tab {
  padding-top: 2px;
  padding-bottom: 2px;
}

/* Session Cards */
.session-card {
  margin-top: 10px;
  padding-top: 8px;
  border-top: 1px solid var(--border-color);
}

/* Visibility Badges */
.visibility-badge {
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 14px;
  font-weight: 500;
}

.visibility-badge.public {
  background-color: #d4edda;
  color: #155724;
}

.visibility-badge.friends {
  background-color: #d1ecf1;
  color: #0c5460;
}

.visibility-badge.private {
  background-color: #f8d7da;
  color: #721c24;
}

[data-theme="dark"] .visibility-badge.public {
  background-color: #1a3a1a;
  color: #66bb6a;
}

[data-theme="dark"] .visibility-badge.friends {
  background-color: #1a3a4a;
  color: #64b5f6;
}

[data-theme="dark"] .visibility-badge.private {
  background-color: #4a1a1a;
  color: #ef5350;
}

/* Collapsible Section Headers - Shared by SessionsTab and MyChouettesTab */
.section-header {
  cursor: pointer;
  padding: 15px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.section-header h3 {
  margin: 0;
}

.section-header .collapse-icon {
  font-size: 20px;
}

.section-group {
  margin-bottom: 30px;
}

.section-header.success {
  background-color: #d4edda;
  border: 1px solid #c3e6cb;
  color: #28a745;
}

.section-header.info {
  background-color: #d1ecf1;
  border: 1px solid #bee5eb;
  color: #0c5460;
}

.section-header.challenge {
  background-color: #e7f3ff;
  border: 1px solid #b3d9ff;
  color: #0056b3;
}

.section-header.warning {
  background-color: #fff3cd;
  border: 1px solid #ffeaa7;
  color: #856404;
}

.section-header.danger {
  background-color: #f8d7da;
  border: 1px solid #f5c6cb;
  color: #721c24;
}

.section-header.secondary {
  background-color: #e2e3e5;
  border: 1px solid #d6d8db;
  color: #6c757d;
}

[data-theme="dark"] .section-header.success {
  background-color: #1a3a1a;
  border-color: #2d5a2d;
  color: #66bb6a;
}

[data-theme="dark"] .section-header.info {
  background-color: #1a3a4a;
  border-color: #2d5a7a;
  color: #4fc3f7;
}

[data-theme="dark"] .section-header.challenge {
  background-color: #1a2a4a;
  border-color: #2d4a8a;
  color: #64b5f6;
}

[data-theme="dark"] .section-header.warning {
  background-color: #4a3a1a;
  border-color: #6a5a2a;
  color: #ffd54f;
}

[data-theme="dark"] .section-header.danger {
  background-color: #4a1a1a;
  border-color: #6a2a2a;
  color: #ef5350;
}

[data-theme="dark"] .section-header.secondary {
  background-color: #2a2a2a;
  border-color: #4a4a4a;
  color: #9e9e9e;
}

/* Content area for collapsible sections */
.section-content {
  padding: 10px;
  border-radius: 4px;
}

.section-content.info {
  background: #f0f8ff;
  border: 1px solid #bee5eb;
}

[data-theme="dark"] .section-content.info {
  background: #1a2a3a;
  border-color: #2d4a6a;
}

/* ========================================
   Sessions Tab - Two-Table Layout
   ======================================== */

/* Sessions tab parent wrapper is styled inline with display:flex in MainLobby.jsx */

.sessions-tab-container {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow: auto;
  gap: 12px;
}

/* Panel (each table) */
.st-panel {
  border: 1px solid var(--border-color);
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg-white);
}

.st-panel-top {
  flex: 1 1 0;
  min-height: 142px;
  border: none;
  border-radius: 0;
  background: transparent;
  overflow: visible;
}

.st-panel-bottom {
  flex: 3 1 0;
  min-height: 240px;
}

/* Panel header / title bar */
.st-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 14px;
  background: var(--secondary-bg);
  border-bottom: 1px solid var(--border-color);
  flex-shrink: 0;
  gap: 10px;
  flex-wrap: wrap;
}

.st-panel-title {
  font-weight: 600;
  font-size: 15px;
  color: var(--text-primary);
  white-space: nowrap;
}

.st-panel-header-actions {
  display: flex;
  gap: 8px;
  flex-wrap: nowrap;
  min-width: 0;
}

.st-panel-header-actions > .btn {
  flex-shrink: 1;
  min-width: 0;
}

.st-lobby-top {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 0;
}

.st-lobby-hero-copy {
  padding: 0;
}

.st-lobby-heading {
  margin: 0;
  font-size: 27px;
  line-height: 1.1;
  color: var(--text-primary);
}

.st-lobby-subtitle {
  margin: 10px 0 0;
  max-width: 36rem;
  font-size: 17px;
  line-height: 1.5;
  color: var(--text-secondary);
}

.st-lobby-section-heading {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: #22a8c7;
  font-size: 15px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.st-lobby-section-heading-games {
  color: #22a8c7;
}

.st-lobby-section-icon {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.st-lobby-section-icon svg {
  width: 24px;
  height: 24px;
}

.st-lobby-actions-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 14px;
  align-items: stretch;
}

.st-action-card {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 260px;
  padding: 22px 18px 18px;
  border-radius: 18px;
  border: 1px solid rgba(56, 72, 84, 0.14);
  box-shadow: 0 10px 24px rgba(35, 52, 63, 0.06);
}

.st-action-card-primary {
  background:
    radial-gradient(circle at 20% 12%, rgba(83, 218, 247, 0.24), transparent 52%),
    linear-gradient(180deg, rgba(232, 248, 253, 0.98), rgba(217, 240, 250, 0.98));
}

.st-action-card-success {
  background:
    radial-gradient(circle at 20% 12%, rgba(156, 224, 125, 0.24), transparent 52%),
    linear-gradient(180deg, rgba(236, 249, 235, 0.98), rgba(221, 241, 218, 0.98));
}

.st-action-card-neutral {
  background:
    radial-gradient(circle at 20% 12%, rgba(199, 143, 245, 0.23), transparent 54%),
    linear-gradient(180deg, rgba(244, 238, 252, 0.98), rgba(233, 223, 247, 0.98));
}

.st-action-card-topline {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.st-action-card-headline {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
  flex: 1;
}

.st-action-card-icon {
  width: 72px;
  height: 72px;
  border-radius: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: #36515d;
  box-shadow: none;
  flex: 0 0 auto;
  margin: 0;
}

.st-action-card-icon svg {
  width: 70px;
  height: 70px;
  display: block;
}

.st-action-card-body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
  align-items: flex-start;
  text-align: left;
}

.st-action-card-headline h3 {
  margin: 0;
  font-size: 23px;
  line-height: 1.1;
  color: var(--text-primary);
}

.st-action-card-body p {
  margin: 0;
  max-width: none;
  font-size: 15px;
  line-height: 1.45;
  color: #42545f;
}

.st-action-card-button {
  align-self: center;
  width: min(100%, 224px);
  min-height: 46px;
  padding: 12px 18px;
  border-radius: 10px;
  font-size: 17px;
  font-weight: 700;
  line-height: 1;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
}

.st-action-card-button-row {
  display: none;
}

.st-action-card-button-row-bot {
  display: none;
}

.st-action-card-button-inline {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
}

.st-hero-button-label-compact {
  display: none;
}

.st-action-card-menu-trigger {
  white-space: nowrap;
}

.st-action-card-icon-trigger {
  width: 56px;
  min-height: 28px;
  padding: 0;
  border-radius: 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
}

.st-action-card-icon-trigger svg {
  width: 24px;
  height: 24px;
}

.st-my-games-section {
  border: 1px solid var(--border-color);
  border-radius: 8px;
  background: var(--bg-white);
  box-shadow: none;
  overflow: hidden;
}

.st-my-games-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border-color);
  background: var(--secondary-bg);
}

.st-my-games-header .st-lobby-section-heading {
  min-width: 0;
  flex: 1 1 auto;
}

.st-bottom-mode-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0 10px;
  border-bottom: none;
  background: transparent;
}

.st-panel-title-caps {
  font-size: 15px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #22a8c7;
}

.st-bottom-list-title {
  width: 100%;
  margin: 0 0 2px;
}

.st-my-games-caption {
  margin-top: 4px;
  font-size: 13px;
  color: var(--text-secondary);
}

.st-my-games-link {
  border: none;
  background: transparent;
  padding: 0 10px 0 0;
  color: #36515d;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  flex: 0 0 auto;
}

.st-my-games-link:hover {
  color: #24353d;
  text-decoration: underline;
}

.st-empty-inline {
  padding: 18px;
}

.st-table-preview .st-cell-name,
.st-table-preview .st-cell-info,
.st-table-preview .st-cell-actions {
  background: transparent;
}

.st-table-preview .st-row:hover > .st-cell-name,
.st-table-preview .st-row:hover > .st-cell-info,
.st-table-preview .st-row:hover > .st-cell-actions {
  background: var(--app-hover-fill);
}

[data-theme="dark"] .st-action-card-primary {
  background: linear-gradient(180deg, rgba(77, 68, 45, 0.42), rgba(56, 49, 33, 0.52));
}

[data-theme="dark"] .st-action-card-success {
  background: linear-gradient(180deg, rgba(38, 66, 58, 0.56), rgba(26, 46, 40, 0.62));
}

[data-theme="dark"] .st-action-card-neutral {
  background: linear-gradient(180deg, rgba(52, 61, 67, 0.74), rgba(34, 41, 45, 0.82));
}

[data-theme="dark"] .st-action-card,
[data-theme="dark"] .st-my-games-section {
  border-color: rgba(120, 156, 171, 0.18);
  box-shadow: none;
}

[data-theme="dark"] .st-action-card-body p,
[data-theme="dark"] .st-bottom-section-title {
  color: var(--text-secondary);
}

[data-theme="dark"] .st-action-card-icon {
  background: rgba(255, 255, 255, 0.06);
  color: #dce8ed;
  box-shadow: inset 0 0 0 1px rgba(220, 232, 237, 0.1);
}

[data-theme="dark"] .st-my-games-header,
[data-theme="dark"] .st-my-games-header,
[data-theme="dark"] .st-bottom-mode-header {
  background: rgba(255, 255, 255, 0.04);
  color: var(--text-secondary);
}

[data-theme="dark"] .st-lobby-section-heading,
[data-theme="dark"] .st-panel-title-caps,
[data-theme="dark"] .st-my-games-link {
  color: #4bc6e0;
}

[data-theme="dark"] .st-my-games-link {
  color: #dce8ed;
}

[data-theme="dark"] .st-my-games-link:hover {
  color: #ffffff;
}

@media (max-width: 1180px) {
  .st-lobby-actions-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
  }

  .st-action-card {
    min-height: 0;
    padding: 16px;
  }

  .st-action-card-icon {
    width: 60px;
    height: 60px;
  }

  .st-action-card-icon svg {
    width: 58px;
    height: 58px;
  }

  .st-action-card-headline h3 {
    font-size: 19px;
  }
}

@media (max-width: 980px) {
  .st-action-card-topline {
    align-items: flex-start;
  }

  .st-action-card-headline {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 6px;
  }

  .st-action-card-headline h3 {
    text-align: center;
  }

  .st-action-card-body p {
    display: none;
  }

  .st-action-card-success .st-action-card-topline {
    flex-wrap: wrap;
    align-items: flex-start;
  }


  .st-action-card-success .st-action-card-headline {
    min-width: 0;
    flex: 1 1 100%;
  }

  .st-action-card-success .st-action-card-headline h3 {
    font-size: clamp(16px, 4.1vw, 19px);
    line-height: 1.12;
    display: block;
    overflow: visible;
    white-space: normal;
  }
}

/* Vertical compaction: progressively remove lobby elements by height */
@media (max-height: 840px) {
  .st-lobby-subtitle {
    display: none;
  }

  .st-lobby-section-heading .st-lobby-section-icon {
    display: none;
  }

  .st-lobby-section-heading > span:not(.st-lobby-section-icon) {
    display: none;
  }

  .st-action-card-headline h3 {
    display: none;
  }

  .st-hero-button-label-default {
    display: none;
  }

  .st-hero-button-label-compact {
    display: inline;
  }
}

/* Hide "Play now" earlier on narrow portrait phones so bottom table content stays visible. */
@media (max-width: 520px) and (orientation: portrait) {
  .st-lobby-top > .st-lobby-section-heading {
    display: none;
  }

  .st-action-card {
    padding: 12px 10px;
    gap: 8px;
  }

  .st-action-card-icon {
    width: 52px;
    height: 52px;
  }

  .st-action-card-icon svg {
    width: 50px;
    height: 50px;
  }
}

@media (max-height: 600px) {
  .st-lobby-top {
    gap: 0;
  }

  .st-lobby-hero-copy {
    display: none;
  }

  .st-lobby-top > .st-lobby-section-heading {
    display: none;
  }

  .st-lobby-actions-grid {
    gap: 8px;
  }

  .st-action-card,
  .st-action-card-primary,
  .st-action-card-success,
  .st-action-card-neutral {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    min-height: 0;
    padding: 6px 10px;
    gap: 0;
  }

  .st-action-card-icon,
  .st-action-card-headline,
  .st-action-card-headline h3,
  .st-action-card-body,
  .st-action-card-body p,
  .st-action-card-topline {
    display: none;
  }

  .st-action-card-button {
    min-height: 34px;
    padding: 8px 10px;
    font-size: 14px;
    width: 100%;
  }

  .st-action-card-button-inline {
    width: auto;
  }

  .st-hero-button-label-default {
    display: none !important;
  }

  .st-hero-button-label-compact {
    display: inline !important;
  }

  .st-action-card-button-row-bot {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
  }

  .st-action-card-success > .st-action-card-button,
  .st-action-card-success > .st-action-card-button.st-action-card-button-legacy {
    display: none !important;
  }




  .st-action-card-button-row-bot {
    margin-top: 0;
  }
}

/* Landscape phones/tablets with limited height should use the tight button-only hero layout */
@media (max-width: 980px) and (orientation: landscape) and (max-height: 760px) {
  .st-lobby-top {
    gap: 0;
  }

  .st-lobby-hero-copy,
  .st-lobby-top > .st-lobby-section-heading {
    display: none;
  }

  .st-lobby-actions-grid {
    gap: 8px;
  }

  .st-action-card,
  .st-action-card-primary,
  .st-action-card-success,
  .st-action-card-neutral {
    background: transparent !important;
    border: none !important;
    box-shadow: none !important;
    min-height: 0;
    padding: 6px 10px;
    gap: 0;
  }

  .st-action-card-icon,
  .st-action-card-headline,
  .st-action-card-headline h3,
  .st-action-card-body,
  .st-action-card-body p,
  .st-action-card-topline {
    display: none;
  }

  .st-action-card-button {
    min-height: 34px;
    padding: 8px 10px;
    font-size: 14px;
    width: 100%;
  }

  .st-action-card-button-inline {
    width: auto;
  }

  .st-hero-button-label-default {
    display: none !important;
  }

  .st-hero-button-label-compact {
    display: inline !important;
  }

  .st-action-card-button-row-bot {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    margin-top: 0;
  }

  .st-action-card-success > .st-action-card-button,
  .st-action-card-success > .st-action-card-button.st-action-card-button-legacy {
    display: none !important;
  }



}

@media (max-width: 780px) {
  .st-lobby-top {
    gap: 14px;
  }

  .st-lobby-heading {
    font-size: 22px;
  }

  .st-lobby-actions-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .st-bottom-mode-header {
    align-items: flex-start;
    flex-direction: column;
  }
}

/* In tight landscape space, keep hero cards horizontal by dropping card descriptions */
@media (max-width: 980px) and (orientation: landscape) and (min-height: 601px) {
  .st-lobby-actions-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
  }

  .st-action-card {
    min-height: 0;
    padding: 12px 10px;
    gap: 8px;
  }

  .st-action-card-headline {
    gap: 8px;
  }

  .st-action-card-icon {
    width: 42px;
    height: 42px;
  }

  .st-action-card-icon svg {
    width: 40px;
    height: 40px;
  }

  .st-action-card-headline h3 {
    font-size: 15px;
  }

  .st-action-card-body p {
    display: none;
  }

  .st-action-card-button {
    width: 100%;
    min-height: 34px;
    padding: 8px 10px;
    font-size: 14px;
  }

  .st-action-card-icon-trigger {
    width: 36px;
    min-height: 26px;
  }
}









/* Filter row inside bottom panel header */
.st-filter-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.st-filter-sep {
  width: 1px;
  height: 24px;
  background: var(--border-color);
  flex-shrink: 0;
}

.st-filter-label {
  font-size: 13px;
  color: var(--text-secondary);
  white-space: nowrap;
  font-weight: 500;
}

.st-filter-select {
  padding: 4px 8px;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--bg-white);
  color: var(--text-primary);
  font-size: 13px;
  cursor: pointer;
}

/* Added: the Review page's title filter, a text field in the filter row */
.st-filter-title {
  width: 180px;
  cursor: text;
}

.st-filter-select-narrow {
  width: 90px;
}

/* Toggle buttons (pressed/depressed) */
.st-toggle-btn {
  padding: 5px 12px;
  font-size: 13px;
  font-weight: 500;
  border: 1px solid var(--border-color);
  background: var(--bg-white);
  color: var(--text-primary);
  transition: all 0.15s ease;
  cursor: pointer;
}

/* Segmented toggle (Current / Past) */
.st-seg-toggle {
  display: inline-flex;
}

.st-seg-toggle .st-seg-left {
  border-radius: 6px 0 0 6px;
  border-right: none;
}

.st-seg-toggle .st-seg-right {
  border-radius: 0 6px 6px 0;
}

.st-toggle-btn:hover {
  background: var(--secondary-bg);
}

.st-toggle-btn.st-toggle-active {
  background: #5a7d8c;
  color: white;
  border-color: var(--selection-border-blue, #4a7bd9);
}

.st-toggle-btn.st-toggle-active:hover {
  background: #4a6b78;
  border-color: var(--selection-border-blue, #4a7bd9);
}

.st-toggle-sm {
  padding: 3px 10px;
  font-size: 12px;
}

.st-panel-bottom > .st-panel-header {
  flex-direction: column;
  align-items: flex-start;
}

.st-panel-bottom > .st-panel-header > .st-panel-title {
  font-size: 13px;
  color: var(--text-secondary);
  font-weight: 500;
}

.st-bottom-mode-header {
  width: 100%;
}

/* Panel body (scrollable) */
.st-panel-body {
  flex: 1;
  overflow-y: auto;
  min-height: 0;
}

/* Empty state inside a panel */
.st-empty {
  padding: 24px;
  text-align: center;
  color: var(--text-light);
  font-size: 14px;
}

/* Session list (CSS Grid for aligned columns with progressive hiding) */
.st-table {
  display: grid;
  grid-template-columns: minmax(30px, auto) minmax(0, 1fr) auto;
  width: 100%;
}

.st-row {
  display: contents;
}

/* Apply row border and hover via cells */
.st-row > .st-cell-name,
.st-row > .st-cell-info,
.st-row > .st-cell-actions {
  border-bottom: 1px solid var(--border-color);
  transition: background 0.15s;
}

.st-row:last-child > .st-cell-name,
.st-row:last-child > .st-cell-info,
.st-row:last-child > .st-cell-actions {
  border-bottom: none;
}

.st-row:hover > .st-cell-name,
.st-row:hover > .st-cell-info,
.st-row:hover > .st-cell-actions {
  background: var(--app-hover-fill);
}

/* Name cell: auto-width based on widest name, truncates when space is tight */
.st-cell-name {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 500;
  font-size: 14px;
  color: var(--text-primary);
  padding: 8px 12px;
  display: flex;
  align-items: center;
  cursor: default;
}

/* Info cell: fills remaining space, clips from right */
.st-cell-info {
  overflow: hidden;
  padding: 8px 12px;
  display: flex;
  align-items: center;
}

.st-info-tags {
  display: flex;
  gap: 8px;
  align-items: center;
  overflow: hidden;
  white-space: nowrap;
}

.st-info-tag {
  flex-shrink: 0;
  font-size: 13px;
  line-height: 1;
  color: var(--text-secondary);
  cursor: pointer;
  pointer-events: auto;
  display: flex;
  align-items: center;
}

.st-info-icon {
  width: 14px;
  height: 14px;
  vertical-align: middle;
  margin-right: 2px;
}

/* Actions cell: auto-width, right-aligned, won't shrink */
.st-cell-actions {
  white-space: nowrap;
  text-align: right;
  padding: 8px 12px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.st-cell-actions .btn {
  margin-left: 6px;
}

.st-row-title {
  margin-right: 6px;
}

/* Badges */
.st-badge-private,
.st-badge-friends {
  font-size: 12px;
  margin-left: 4px;
  vertical-align: middle;
}

/* Invite badge with accept/decline icons */
.st-invite-badge {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin-left: 6px;
  font-size: 12px;
  vertical-align: middle;
  overflow: visible;
}

.st-invite-icon:disabled {
  cursor: not-allowed;
  opacity: 0.4;
}

.st-invite-icon-accept,
.st-invite-icon-decline {
  font-size: 13px;
  width: 22px;
  height: 22px;
}
.st-invite-icon-accept {
  background-color: var(--success-color);
  color: #fff;
}
.st-invite-icon-decline {
  background-color: var(--danger-color);
  color: #fff;
}

/* Session row button */
.btn-session-row {
  padding: 4px 12px;
  font-size: 13px;
  min-width: 0;
}

/* Last active indicator in session rows */
.st-last-active {
  font-size: 11px;
  font-weight: 400;
  margin-left: 6px;
  white-space: nowrap;
}

.st-last-active-now {
  color: var(--success-color);
}

.st-last-active-recent {
  color: var(--text-light);
}

.st-last-active-inactive {
  color: var(--danger-color);
  opacity: 0.8;
}

/* Bottom table row animations */
@keyframes st-row-slide-out {
  from { opacity: 1; max-height: 50px; transform: translateX(0); }
  to   { opacity: 0; max-height: 0; transform: translateX(-30px); }
}

@keyframes st-row-slide-in {
  from { opacity: 0; max-height: 0; transform: translateX(30px); }
  to   { opacity: 1; max-height: 50px; transform: translateX(0); }
}

.st-row-removing > * {
  animation: st-row-slide-out 0.35s ease-in forwards;
  overflow: hidden;
}

.st-row-adding > * {
  animation: st-row-slide-in 0.35s ease-out forwards;
  overflow: hidden;
}

/* Responsive: stack filter rows on narrow screens */
@media (max-width: 600px) {
  .st-panel-header {
    padding: 8px 10px;
  }
  
  .st-filter-row {
    gap: 6px;
  }
  
  .st-toggle-btn {
    padding: 4px 8px;
    font-size: 12px;
  }
  
  .st-filter-select {
    font-size: 12px;
    padding: 3px 6px;
  }
  
  .btn-session-row {
    padding: 3px 8px;
    font-size: 12px;
  }
  
  .st-cell-name,
  .st-cell-info,
  .st-cell-actions {
    padding: 6px 8px;
    font-size: 13px;
  }
}

/* Dark mode overrides for new sessions tab elements */
[data-theme="dark"] .st-panel {
  border-color: var(--border-color);
}

[data-theme="dark"] .st-panel-header {
  background: var(--secondary-bg);
  border-bottom-color: var(--border-color);
}

[data-theme="dark"] .st-filter-select {
  background: var(--bg-white);
  border-color: var(--border-color);
  color: var(--text-primary);
}

[data-theme="dark"] .st-toggle-btn {
  background: var(--bg-white);
  color: var(--text-primary);
  border-color: var(--border-color);
}

[data-theme="dark"] .st-toggle-btn:hover {
  background: #333;
}

[data-theme="dark"] .st-toggle-btn.st-toggle-active {
  background: #5a7d8c;
  color: white;
  border-color: #5a7d8c;
}

[data-theme="dark"] .st-row:hover > .st-cell-name,
[data-theme="dark"] .st-row:hover > .st-cell-info,
[data-theme="dark"] .st-row:hover > .st-cell-actions {
  background: #2a2a2a;
}

/* Inline alert/banner boxes */
.alert-box {
  margin-top: 10px;
  padding: 10px;
  border-radius: 4px;
}

.alert-box.success {
  background: #d4edda;
  border: 1px solid #c3e6cb;
}

.alert-box.danger {
  background: #f8d7da;
  border: 1px solid #f5c6cb;
}

.alert-box.info {
  background: #d1ecf1;
  border: 1px solid #bee5eb;
}

[data-theme="dark"] .alert-box.success {
  background: #1a3a1a;
  border-color: #2d5a2d;
}

[data-theme="dark"] .alert-box.danger {
  background: #4a1a1a;
  border-color: #6a2a2a;
}

[data-theme="dark"] .alert-box.info {
  background: #1a3a4a;
  border-color: #2d5a7a;
}

/* Contextual text colors with dark mode support */
.text-success { color: #155724; }
.text-warning { color: #856404; }
.text-danger { color: #721c24; }
.text-info { color: #0c5460; }
.text-muted { color: var(--text-light); }

[data-theme="dark"] .text-success { color: #66bb6a; }
[data-theme="dark"] .text-warning { color: #ffd54f; }
[data-theme="dark"] .text-danger { color: #ef5350; }
[data-theme="dark"] .text-info { color: #4fc3f7; }

/* Small inline action buttons (accept/decline/cancel in lists) */
.btn-inline-success {
  font-size: 11px;
  padding: 2px 6px;
  margin-left: 3px;
  background-color: var(--success-color);
  color: #fff;
  border: none;
  border-radius: 3px;
  cursor: pointer;
}

.btn-inline-danger {
  font-size: 11px;
  padding: 2px 6px;
  margin-left: 3px;
  background-color: var(--danger-color);
  color: #fff;
  border: none;
  border-radius: 3px;
  cursor: pointer;
}

.btn-inline-success:disabled,
.btn-inline-danger:disabled {
  cursor: not-allowed;
  opacity: 0.5;
}

/* Badge for unread counts */
.badge-count {
  background-color: var(--success-color);
  color: #fff;
  border-radius: 10px;
  padding: 2px 8px;
  font-size: 12px;
  font-weight: bold;
}

/* Tab badge (sup element) */
.tab-badge {
  margin-left: 5px;
  color: var(--success-color);
  font-weight: bold;
  font-size: 0.8em;
}

/* Form validation colors */
.text-field-success { color: var(--success-color); }
.text-field-error { color: var(--danger-color); display: block; margin-top: 4px; }

/* Step indicator */
.step-indicator {
  margin-bottom: 20px;
  padding: 10px;
  background: var(--secondary-bg);
  border-radius: 6px;
  font-size: 13px;
  color: var(--text-light);
}

/* Hint/helper text */
.hint-text {
  font-size: 12px;
  color: var(--text-light);
  margin-top: 5px;
}

/* Divider line */
.divider-line {
  flex: 1;
  height: 1px;
  background: var(--border-color);
}

/* Tab badge sup */
.tab sup {
  margin-left: 5px;
  color: var(--success-color);
  font-weight: bold;
  font-size: 0.8em;
}

/* Selectable item rows (modals with checkboxes) */
.selectable-item {
  display: flex;
  align-items: center;
  padding: 8px;
  cursor: pointer;
  border-radius: 4px;
}

.selectable-item input[type="checkbox"] {
  margin-right: 8px;
}

/* Checkbox list layout */
.checkbox-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.avatar-field-button {
  width: 100%;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 8px 10px;
  background: var(--bg-white);
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}

.profile-inline-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.profile-inline-actions .avatar-field-button {
  flex: 1;
  min-width: 210px;
}

.btn-inline-form {
  width: auto !important;
  margin-bottom: 0 !important;
  padding: 10px 14px !important;
  font-size: 14px !important;
}

.avatar-field-preview {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--secondary-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: bold;
  color: var(--text-secondary);
  flex-shrink: 0;
}

.avatar-field-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar-field-text {
  color: var(--text-primary);
  text-align: left;
}

.avatar-selector-modal .modal-body {
  padding: 0;
}

.avatar-selector-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 10px;
  padding: 10px;
}

.avatar-selector-item {
  border: 1px solid var(--border-color);
  border-radius: 10px;
  background: var(--bg-white);
  padding: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  cursor: pointer;
}

.avatar-selector-item.is-selected {
  border-color: var(--primary-color);
  box-shadow: 0 0 0 1px var(--primary-color);
}

.avatar-selector-thumb {
  width: 74px;
  height: 74px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--secondary-bg);
}

.avatar-selector-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.avatar-selector-key {
  max-width: 100%;
  font-size: 12px;
  color: var(--text-secondary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.image-crop-modal .modal-body {
  padding-top: 10px;
  overflow: hidden;
}

.image-crop-stage {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: 100%;
}

.image-crop-viewport {
  position: relative;
  width: var(--crop-viewport-size, min(560px, calc(100vw - 80px)));
  height: var(--crop-viewport-size, min(560px, calc(100vw - 80px)));
  max-width: 100%;
  overflow: hidden;
  border-radius: 12px;
  border: 1px solid var(--border-color);
  background: #111;
  touch-action: none;
  user-select: none;
}

.image-crop-image {
  position: absolute;
  top: 50%;
  left: 50%;
  transform-origin: center center;
  pointer-events: none;
  max-width: none;
}

.image-crop-mask {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.image-crop-loading {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.65);
  color: #fff;
  font-weight: 600;
  font-size: 16px;
  letter-spacing: 0.2px;
  z-index: 3;
}

.image-crop-mask::before {
  content: '';
  position: absolute;
  width: 300px;
  height: 300px;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.35);
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.95);
}

.image-crop-controls {
  width: min(100%, var(--crop-viewport-size, 360px));
  display: grid;
  grid-template-columns: 48px 1fr auto;
  align-items: center;
  gap: 8px;
}

.image-crop-controls input[type="range"] {
  width: 100%;
}

/* Checkbox row */
.checkbox-row {
  display: flex;
  align-items: center;
}

/* Pagination */
.pagination-bar {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 15px;
  margin-top: 15px;
  padding: 10px;
}

.pagination-btn {
  padding: 5px 10px;
}

.pagination-info {
  font-size: 14px;
  color: var(--text-light);
}

/* Standard textarea */
.textarea-standard {
  width: 100%;
  padding: 10px;
  font-size: 14px;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  resize: vertical;
  font-family: inherit;
  background-color: var(--bg-white);
  color: var(--text-primary);
}

/* Compact select for modals */
.form-select-compact {
  width: 100%;
  padding: 6px 10px;
}

/* Detail field groups (expanded player cards) */
.detail-field-group {
  margin-bottom: 6px;
}

.detail-label {
  color: var(--text-secondary);
  font-size: 11px;
  text-transform: uppercase;
}

.detail-value {
  color: var(--text-primary);
  margin-top: 2px;
}

/* Review/response quote blocks */
.review-quote {
  margin-top: 10px;
  padding: 10px;
  background-color: var(--bg-white);
  border-left: 3px solid var(--border-color);
  font-size: 14px;
}

.review-quote.italic {
  font-style: italic;
}

/* Chouette section header */
.chouette-section-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 15px;
  cursor: pointer;
  align-items: center;
  padding: 10px;
  background: var(--secondary-bg);
  border-radius: 4px;
}

.chouette-section-header h2 {
  margin: 0;
}

/* Link colors */
.link-accent {
  color: var(--primary-color);
  text-decoration: underline;
}

/* Connection status banner */
.connection-banner {
  position: fixed;
  top: 60px;
  left: 50%;
  transform: translateX(-50%);
  background-color: #f0ad4e;
  color: #333;
  padding: 12px 24px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  z-index: 10001;
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 14px;
  font-weight: 500;
}

.connection-banner .retry-btn {
  background-color: var(--bg-white);
  color: var(--text-primary);
  border: none;
  padding: 6px 12px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 13px;
  font-weight: 600;
  transition: background-color 0.2s;
}

.connection-banner .retry-btn:hover {
  background-color: var(--secondary-bg);
}

/* Unobtrusive first-attempt indicator: small, muted, no button, no shadow.
   Shown between the initial grace period and the first failed reconnect
   attempt so users get a subtle hint without the alarming yellow banner. */
.connection-banner--soft {
  background-color: rgba(0, 0, 0, 0.55);
  color: #f0f0f0;
  padding: 4px 10px;
  border-radius: 4px;
  box-shadow: none;
  font-size: 12px;
  font-weight: 400;
  opacity: 0.85;
}

/* Fullscreen re-entry prompt shown briefly (3 s) on Android when a
   rotate-to-landscape auto-enter of fullscreen was refused by the browser
   because the orientation-change event doesn't count as a user gesture.
   Two independent fixed-position siblings: a transparent full-viewport
   catcher (lower z-index) so tapping anywhere grants user activation, and
   a small visible banner at the top of the viewport (higher z-index) to
   tell the user what to do. Both share the same click handler. */
.fullscreen-prompt-catcher {
  position: fixed;
  inset: 0;
  z-index: 10002;
  background: transparent;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

.fullscreen-prompt-banner {
  position: fixed;
  top: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10003;
  background-color: rgba(0, 0, 0, 0.85);
  color: #fff;
  padding: 14px 22px;
  border-radius: 10px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.45);
  font-size: 16px;
  font-weight: 600;
  text-align: center;
  max-width: min(80vw, 480px);
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* Error form message */
.form-error {
  background-color: #fee;
  border: 1px solid #fcc;
  padding: 10px;
  margin-bottom: 15px;
  border-radius: 4px;
  color: #c00;
}

[data-theme="dark"] .form-error {
  background-color: #4a1a1a;
  border-color: #6a2a2a;
  color: #ef5350;
}

/* Player ratings modal */
.rating-card {
  margin-bottom: 15px;
  padding: 15px;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--bg-white);
}

.rating-review {
  margin-top: 10px;
  padding: 10px;
  background: var(--secondary-bg);
  border-radius: 4px;
}

.rating-response {
  margin-top: 10px;
  padding: 10px;
  background: var(--secondary-bg);
  border-radius: 4px;
  border-left: 3px solid var(--primary-color);
}

.ratings-container {
  flex: 1;
  padding: 15px;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  background: var(--secondary-bg);
  box-shadow: 0 2px 4px var(--shadow-color);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.ratings-summary {
  margin-bottom: 20px;
  padding: 15px;
  background: var(--bg-white);
  border-radius: 4px;
  border: 1px solid var(--border-color);
}

.ratings-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid var(--border-color);
}

.ratings-header button {
  background: none;
  border: none;
  font-size: 28px;
  cursor: pointer;
  line-height: 1;
  color: var(--text-light);
}

/* Selected item highlight */
.item-selected {
  background-color: color-mix(in srgb, var(--primary-color) 15%, transparent); /* Changed: was a fixed teal tint; follows the game tab accent */
}

[data-theme="dark"] .item-selected {
  background-color: color-mix(in srgb, var(--primary-color) 25%, transparent); /* Changed: was a fixed teal tint; follows the game tab accent */
}

/* Messages Tab */
/* The frame around the conversation list and the conversation (was inline in MessagesTab) */
.messages-frame {
  display: flex;
  gap: 0;
  flex: 1 1 auto;
  min-height: 0;
  border: 1px solid var(--border-color);
}

.conversation-list {
  flex: 0 0 280px;
  border-right: 1px solid var(--border-color);
  display: flex;
  flex-direction: column;
  background-color: var(--bg-white);
}

/* On narrower screens, make conversations column about 1/4 of messages column width */
@media (max-width: 900px) {
  .conversation-list {
    flex: 0 0 25%;
    min-width: 100px;
  }
}

.conversation-list-header {
  padding: 15px;
  border-bottom: 1px solid var(--border-color);
  font-weight: bold;
  background-color: var(--secondary-bg);
  font-size: clamp(12px, 1.5vw, 16px);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.conversation-item {
  padding: 15px;
  cursor: pointer;
  border-bottom: 1px solid var(--border-color);
  background-color: var(--bg-white);
  transition: background-color 0.2s;
  overflow: hidden;
}

.conversation-username {
  font-size: clamp(12px, 1.4vw, 16px);
}

.conversation-meta {
  font-size: clamp(10px, 1.1vw, 12px);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.conversation-item:hover {
  background-color: var(--secondary-bg);
}

.conversation-item.selected {
  background-color: var(--secondary-bg);
}

.message-view {
  flex: 1;
  display: flex;
  flex-direction: column;
  background-color: var(--bg-white);
}

.message-view-header {
  padding: 15px;
  border-bottom: 1px solid var(--border-color);
  font-weight: bold;
  background-color: var(--secondary-bg);
  font-size: clamp(12px, 1.5vw, 16px);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.message-bubble {
  max-width: 70%;
  padding: 10px 15px;
  border-radius: 10px;
}

.message-bubble.from-me {
  background-color: #007bff;
  color: white;
}

.message-bubble.from-other {
  background-color: var(--secondary-bg);
  color: var(--text-primary);
}

[data-theme="dark"] .message-bubble.from-other {
  background-color: #3a3a3a;
}

.message-input-area {
  padding: 15px;
  border-top: 1px solid var(--border-color);
  background-color: var(--secondary-bg);
}

/* Error Overlays */
.error-toast {
  position: fixed;
  bottom: 20px;
  left: 20px;
  padding: 15px 20px;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
  z-index: 1000;
  animation: slideIn 0.3s ease-out;
}

.error-toast.error {
  background-color: #f8d7da;
  color: #721c24;
  border: 1px solid #f5c6cb;
}

.error-toast.success {
  background-color: #d4edda;
  color: #155724;
  border: 1px solid #c3e6cb;
}

/* Lobby-level stacking overlays */
.lobby-overlay-stack {
  position: fixed;
  bottom: 20px;
  left: 20px;
  z-index: 10000;
  pointer-events: none;
  display: flex;
  flex-direction: column-reverse;
  gap: 8px;
}

.lobby-overlay {
  padding: 14px 32px;
  border-radius: 8px;
  font-size: 15px;
  max-width: 500px;
  text-align: left;
  word-wrap: break-word;
  overflow-wrap: break-word;
  white-space: normal;
  pointer-events: auto;
  animation: overlaySlideUp 0.3s ease-out;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.lobby-overlay-error {
  background: #dc3545;
  color: white;
}

.lobby-overlay-success {
  background: #28a745;
  color: white;
}

@keyframes overlaySlideUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.error-overlay-center {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: #dc3545;
  color: white;
  padding: 20px 40px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  z-index: 10000;
  font-size: 16px;
  max-width: 500px;
  text-align: center;
}

/* Dark mode variants */
[data-theme="dark"] .error-toast.error {
  background-color: #5a1a1a;
  color: #f8d7da;
  border: 1px solid #8b2e2e;
}

[data-theme="dark"] .error-toast.success {
  background-color: #1e4620;
  color: #d4edda;
  border: 1px solid #2d6930;
}

[data-theme="dark"] .error-overlay-center {
  background: #a82a2a;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6);
}

[data-theme="dark"] .lobby-overlay-error {
  background: #a82a2a;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6);
}

[data-theme="dark"] .lobby-overlay-success {
  background: #1e6e28;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6);
}

/* Session hover bubble */
.st-bubble {
  position: fixed;
  z-index: 2000;
  background: var(--bg-white);
  color: var(--text-primary);
  border: 1px solid var(--border-color);
  border-radius: 8px;
  padding: 12px 16px;
  box-shadow: 0 4px 16px var(--shadow-color);
  max-width: 420px;
  min-width: 200px;
  pointer-events: none;
  font-size: 13px;
  line-height: 1.5;
}

.st-bubble-line {
  white-space: normal;
  word-wrap: break-word;
}

.st-bubble-title {
  font-weight: 700;
  font-size: 14px;
  margin-bottom: 4px;
  border-bottom: 1px solid var(--border-color);
  padding-bottom: 4px;
}

.st-bubble-line + .st-bubble-line {
  margin-top: 2px;
}

[data-theme="dark"] .st-bubble {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
}

@media (max-width: 768px) {
  .st-bubble {
    font-size: 15px;
  }
  .st-bubble-title {
    font-size: 16px;
  }
}

@keyframes slideIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* === Structured game log (Phase 1) === */
.gamelog-preview {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-top: 6px;
  font-size: 13px;
}
.gamelog-preview.empty .gamelog-empty {
  color: var(--text-light);
  font-style: italic;
}
.recent-chats {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: 6px;
  font-size: 13px;
  max-height: 160px;
  overflow-y: auto;
}
.recent-chats.empty .recent-chats-empty {
  color: var(--text-light);
  font-style: italic;
}
.recent-chats-row {
  display: block;
  padding: 2px 6px;
  line-height: 1.3;
  word-break: break-word;
}
.recent-chats-line {
  display: block;
  padding-left: 20px;
  text-indent: -20px;
  overflow-wrap: anywhere;
}
.recent-chats-row.is-error .recent-chats-line {
  color: #c62828;
}
.gamelog-row {
  display: grid;
  grid-template-columns: 2ch minmax(0, max-content);
  column-gap: 8px;
  align-items: baseline;
  padding: 3px 6px;
  border-radius: 4px;
  background: var(--secondary-bg);
  color: var(--text-primary);
  font-style: normal;
}
.gamelog-row.is-empty {
  min-height: 26px;
  background: transparent;
  border: 1px dashed var(--border-color);
}
.gamelog-row.is-box {
  border-left: 4px solid var(--checker-black, #333);
}
.gamelog-row.is-captain {
  border-left: 4px solid var(--checker-white, #eee);
}
.gamelog-row-number {
  flex: 0 0 auto;
  color: var(--text-light);
  font-variant-numeric: tabular-nums;
}
.gamelog-row-number.is-placeholder {
  visibility: hidden;
}
.gamelog-row-main {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}
.gamelog-flag {
  position: absolute;
  top: -5px;
  right: -4px;
  z-index: 1;
  font-size: 0.72em;
  line-height: 1;
  opacity: 0.78;
  user-select: none;
  pointer-events: none;
  background: transparent;
}
.gamelog-actor {
  position: relative;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
}
.gamelog-actor-cube {
  --gamelog-cube-face: #fff;
  --gamelog-cube-ink: #111;
  color: var(--gamelog-cube-ink);
  background: transparent !important;
  border-radius: 2px;
  overflow: hidden;
}
.gamelog-actor-cube.sev-warning {
  --gamelog-cube-face: greenyellow;
  --gamelog-cube-ink: #111;
}
.gamelog-actor-cube.sev-error {
  --gamelog-cube-face: yellow;
  --gamelog-cube-ink: #111;
}
.gamelog-actor-cube.sev-blunder {
  --gamelog-cube-face: red;
  --gamelog-cube-ink: #fff;
}
.gamelog-preview, .gamelog-review {
  container-type: inline-size;
  max-width: 100%;
}
.gamelog-dice {
  flex: 0 0 auto;
  color: var(--text-primary);
  font-style: normal;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}
.gamelog-move {
  flex: 1 1 auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px;
  white-space: nowrap;
  color: var(--text-primary);
  font-style: normal;
}

.react-gametab-root.is-mobile.layout-landscape .gamelog-move {
  font-family: inherit;
}

.react-gametab-root.is-mobile.layout-landscape .analysis-move-cell,
.react-gametab-root.is-mobile.layout-landscape .analysis-probs-cell {
  font-family: inherit;
}
.gamelog-move.gamelog-move-notation {
  display: inline-grid;
  grid-template-columns: 2ch 1ch minmax(0, 1fr);
  align-items: baseline;
}
.gamelog-move-dice {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.gamelog-move-colon {
  text-align: center;
}
.gamelog-move-body {
  min-width: 0;
}
.react-gametab-root .gamelog-move.warning {
  background: greenyellow;
  color: #111;
}
.react-gametab-root .gamelog-move.error {
  background: yellow;
  color: #111;
}
.react-gametab-root .gamelog-move.blunder {
  background: red;
  color: #fff;
  font-weight: 700;
}
.gamelog-cubes { display: inline-flex; gap: 4px; }
.gamelog-cube {
  padding: 1px 5px;
  border-radius: 3px;
  background: var(--bg-white);
  border: 1px solid var(--border-color);
  font-size: 11px;
}
.gamelog-cube.warning { border-color: #b8860b; color: #b8860b; }
.gamelog-cube.error   { border-color: #c0392b; color: #c0392b; }
.gamelog-cube.blunder { border-color: #8e1b1b; color: #fff; font-weight: 700; }

.gamelog-review { display: flex; flex-direction: column; gap: 10px; }
.gamelog-review-panel,
.gamelog-review-scroll {
  width: 100%;
  min-width: 0;
  align-items: stretch;
}
.gamelog-review-panel {
  display: inline-flex;
  flex-direction: column;
  flex: 0 0 auto;
  max-width: 100%;
  overflow: hidden;
  max-height: 100%;
}
.gamelog-review-scroll {
  display: none;
}
.gamelog-review-scroll > .gamelog-game {
  width: 100%;
}
.gamelog-toolbar { display: flex; align-items: center; gap: 8px; }
.gamelog-toolbar-main {
  flex: 1 1 auto;
  min-width: 0;
}
.gamelog-toolbar-main.gamelog-toolbar-main-nav {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}
.gamelog-nav-btn,
.gamelog-game-pill {
  border: 1px solid var(--border-color);
  background: var(--secondary-bg);
  color: var(--text-primary);
  border-radius: 6px;
  height: 24px;
  line-height: 22px;
  padding: 0 8px;
  font: inherit;
  font-size: 11px;
  cursor: pointer;
  user-select: none;
}
.gamelog-nav-btn {
  width: 24px;
  height: 22px;
  line-height: 20px;
  text-align: center;
  padding: 0;
  font-size: 10px;
}
.gamelog-game-pill {
  min-width: 82px;
  text-align: center;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.gamelog-nav-btn:hover:not(:disabled),
.gamelog-game-pill:hover {
  background: var(--app-hover-fill);
}
.gamelog-nav-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.gamelog-toolbar-main .gamelog-select {
  width: 100%;
}
.gamelog-toolbar-right {
  margin-left: auto;
  flex: 0 0 auto;
}
.gamelog-label {
  font-size: 12px;
  color: var(--text-light);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.gamelog-select {
  flex: 1 1 auto;
  padding: 4px 6px;
  border-radius: 6px;
  border: 1px solid var(--border-color);
  background: var(--bg-white);
  color: var(--text-primary);
  font-size: 13px;
}
.gamelog-game-header {
  margin-top: 6px;
  font-weight: 600;
  color: var(--text-primary);
  border-bottom: 1px solid var(--border-color);
  padding-bottom: 3px;
}
.gamelog-turns { display: flex; flex-direction: column; gap: 3px; margin-top: 4px; }
.gamelog-starting-score {
  color: var(--text-light);
  font-size: 12px;
  font-style: italic;
  padding: 1px 0 3px;
}
/* Heads each run of rows in a filtered view with the game they came from.
   Borrows the type of .gamelog-starting-score above, since that is already how
   this log announces a game, and adds the gap that separates one game's errors
   from the next. */
.gamelog-match-game-header {
  margin-top: 14px;
}
.gamelog-match-game-header.is-first {
  margin-top: 0;
}
.gamelog-player-legend-row {
  display: inline-flex;
  align-items: center;
  gap: 16px;
  padding: 1px 0 3px;
  color: var(--text-primary);
}
.gamelog-review-panel.is-one-column-mode .gamelog-player-legend-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}
.gamelog-review-panel.is-one-column-mode .gamelog-player-legend {
  /* Keep legend checker aligned with the checker column used by move rows:
     row padding (6px) + turn-number column (2ch) + column gap (8px). */
  padding-left: calc(6px + 2ch + 8px);
}
.gamelog-player-legend {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 20px;
  white-space: nowrap;
  padding: 3px 6px;
  border-radius: 4px;
  background: var(--secondary-bg);
  color: var(--text-primary);
}
.gamelog-player-legend .gamelog-actor-checker {
  flex: 0 0 auto;
}
.gamelog-player-legend.is-box {
  border-left: 4px solid var(--checker-black, #333);
}
.gamelog-player-legend.is-captain {
  border-left: 4px solid var(--checker-white, #eee);
}
.gamelog-player-legend.is-empty {
  visibility: hidden;
}
.gamelog-player-legend-name {
  font-size: 12px;
  line-height: 1.2;
}
.gamelog-grid-player-row {
  display: contents;
}
.gamelog-grid-num-empty {
  visibility: hidden;
}
.gamelog-grid-player-row .gamelog-grid-cell {
  align-self: center;
}
.gamelog-review-panel .gamelog-turns:not(.is-two-column) {
  width: var(--gamelog-single-width, max-content);
}
.gamelog-turns.is-two-column {
  flex: 0 0 auto;
  width: max-content;
  max-width: none;
}
.gamelog-turns-grid {
  display: grid;
  grid-template-columns:
    var(--gamelog-two-col-num-width, max-content)
    var(--gamelog-two-col-left-width, max-content)
    var(--gamelog-two-col-right-width, max-content);
  column-gap: 8px;
  row-gap: 3px;
  flex: 0 0 auto;
  width: max-content;
}
.gamelog-grid-row {
  display: contents;
}
.gamelog-grid-num {
  min-width: 2ch;
  align-self: baseline;
  color: var(--text-light);
  font-variant-numeric: tabular-nums;
}
.gamelog-grid-cell {
  min-width: max-content;
}
.gamelog-grid-cell .gamelog-row {
  width: max-content;
  grid-template-columns: minmax(0, max-content);
}
.gamelog-empty { color: var(--text-light); font-style: italic; }

.gamelog-review-panel.is-empty-log.is-one-column-mode {
  min-width: 250px;
}

.gamelog-review-panel.is-empty-log.is-two-column-mode {
  min-width: 450px;
}

/* === Review-mode side pane: the moves box becomes a tall, scrollable
   panel that contains the game selector + full log. The analysis box
   below it uses the same styling as in play mode. === */
.react-gametab-side-scroll.is-review {
  overflow: hidden;
}
.react-gametab-info-box.react-gametab-review-panel {
  flex: 1 1 0;
  min-height: 40%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.react-gametab-side-scroll.is-review .react-gametab-info-box.react-gametab-analysis-panel {
  max-height: 60%;
}
.gamelog-review-panel {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  position: relative;
}
.gamelog-review-scroll {
  flex: 1 1 auto;
  display: block;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  min-height: 0;
  overflow-y: auto;
  overflow-x: auto;
  container-type: inline-size;
}
.gamelog-review-panel .gamelog-toolbar {
  flex: 0 0 auto;
}

.gamelog-game-picker-backdrop {
  position: fixed;
  inset: 0;
  z-index: 11000;
  background: rgba(0, 0, 0, 0.18);
}

.gamelog-game-picker {
  position: fixed;
  border: 1px solid var(--border-color);
  background: var(--bg-white);
  border-radius: 8px;
  padding: 8px;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.18);
  width: fit-content;
  max-width: calc(100vw - 24px);
  max-height: calc(100vh - 24px);
  overflow: auto;
}

.gamelog-game-picker-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}

.gamelog-game-picker-title {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary);
}

.gamelog-game-picker-close {
  width: 24px;
  height: 24px;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--secondary-bg);
  color: var(--text-primary);
  font: inherit;
  font-size: 14px;
  line-height: 22px;
  padding: 0;
  cursor: pointer;
}

.gamelog-game-picker-close:hover {
  background: var(--bg-white);
}

.gamelog-game-picker-grid {
  display: grid;
  gap: 6px;
}

/* The two match-wide views head the picker. They are not games, so they get
   their own row across the full width rather than a cell in the game grid --
   which also gives the longer labels room the fixed game cells do not have. */
.gamelog-game-picker-views {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 6px;
  margin-bottom: 10px;
}

.gamelog-game-picker-btn.is-view {
  width: auto;
}

.gamelog-game-picker-btn {
  width: var(--gamelog-picker-cell-width, 92px);
  height: 30px;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--secondary-bg);
  color: var(--text-primary);
  font: inherit;
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  white-space: nowrap;
}

.gamelog-game-picker-btn:hover {
  background: var(--app-hover-fill);
}

.gamelog-game-picker-btn.is-active {
  background: var(--primary-color);
  border-color: var(--selection-border-blue, #4a7bd9);
  color: #fff;
}

.gamelog-game-picker-btn.is-active:hover,
.gamelog-game-picker-btn.is-active:focus-visible {
  border-color: var(--selection-border-blue, #4a7bd9);
}

/* === Chat-mode side pane: chat panel takes full height with a sticky
   reply input at the bottom. === */
.react-gametab-side-scroll.is-chat {
  overflow: hidden;
}
.react-gametab-info-box.react-gametab-full-chats {
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
  container-type: inline-size;
}
.react-gametab-side-scroll.is-chat .react-gametab-info-box.react-gametab-full-chats {
  flex: 1 1 0;
}
.react-gametab-full-chats-list {
  position: relative;
  flex: 1 1 0;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior-y: contain;
  -webkit-overflow-scrolling: touch;
}
.react-gametab-full-chats-list .recent-chats {
  display: block;
  flex: none;
  max-height: none;
  overflow: visible;
  margin-top: 0;
}
.react-gametab-full-chats-form {
  display: flex;
  gap: 6px;
  margin-top: 6px;
  flex: 0 0 auto;
}
.react-gametab-full-chats-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 6px 8px;
  font: inherit;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--bg-white);
  color: var(--text-primary);
}
.react-gametab-full-chats-input::placeholder {
  color: var(--text-light);
}
.react-gametab-full-chats-send {
  flex: 0 0 auto;
  padding: 6px 12px;
  font: inherit;
  border: 1px solid var(--border-color);
  border-radius: 4px;
  background: var(--secondary-bg);
  color: var(--text-primary);
  cursor: pointer;
}
.react-gametab-full-chats-send:hover:not(:disabled) {
  background: var(--primary-color);
  color: #fff;
  border-color: var(--primary-color);
}
.react-gametab-full-chats-send:disabled {
  opacity: 0.5;
  cursor: default;
}

@container (max-width: 249px) {
  .react-gametab-full-chats-form {
    flex-wrap: wrap;
  }

  .react-gametab-full-chats-input {
    flex: 1 1 100%;
  }

  .react-gametab-full-chats-send {
    margin-left: auto;
  }
}

/* === Info-mode scoreboard panel === */
.react-gametab-side-scroll.is-info {
  overflow: hidden;
}
.react-gametab-info-box.react-gametab-scoreboard-panel {
  flex: 1 1 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.react-gametab-info-box.react-gametab-scoreboard-panel.react-gametab-setup-position-panel {
  overflow-y: auto;
}
.sb-scroll {
  flex: 1 1 0;
  min-height: 0;
  overflow: auto;
  margin-top: 6px;
}
.sb-table {
  width: max-content;
  min-width: min(100%, clamp(420px, 62%, 560px));
  border-collapse: separate;
  border-spacing: 0 4px;
  font-size: 13px;
  color: var(--text-primary);
}
.sb-table caption {
  caption-side: top;
  text-align: left;
  color: var(--text-light);
  font-size: 12px;
  padding: 0 0 6px;
}
.sb-table thead th {
  position: sticky;
  top: 0;
  background: var(--bg-white);
  color: var(--text-light);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-align: left;
  padding: 0 8px 4px;
  border-bottom: 1px solid var(--border-color);
  white-space: nowrap;
}
.sb-table thead th:first-child,
.sb-table tbody td:first-child {
  padding-left: 0;
}
.sb-table tbody td {
  background: var(--secondary-bg);
  padding: 4px 8px;
  vertical-align: middle;
  white-space: nowrap;
  line-height: 1.3;
}
.sb-table tbody td:first-child {
  border-top-left-radius: 4px;
  border-bottom-left-radius: 4px;
}
.sb-table tbody td:last-child {
  border-top-right-radius: 4px;
  border-bottom-right-radius: 4px;
}

.sb-table tbody tr.admin-reorder-row td {
  cursor: move;
  transition: background 120ms ease, border-color 120ms ease;
}

.sb-table tbody tr.admin-reorder-row:hover td {
  background: rgba(74, 123, 217, 0.1);
}

.sb-table tbody tr.admin-reorder-row.is-selected td {
  background: rgba(74, 123, 217, 0.18);
  border-top: 1px solid var(--primary-color, #4a7bd9);
  border-bottom: 1px solid var(--primary-color, #4a7bd9);
}

.sb-table tbody tr.admin-reorder-row.is-selected td:first-child {
  border-left: 1px solid var(--primary-color, #4a7bd9);
}

.sb-table tbody tr.admin-reorder-row.is-selected td:last-child {
  border-right: 1px solid var(--primary-color, #4a7bd9);
}

.sb-table tbody tr.sb-selectable-row td {
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}

.sb-table tbody tr.sb-selectable-row:hover td {
  background: rgba(74, 123, 217, 0.1);
}

.sb-table tbody tr.sb-selectable-row.is-selected td {
  background: rgba(74, 123, 217, 0.18);
  border-top: 1px solid var(--primary-color, #4a7bd9);
  border-bottom: 1px solid var(--primary-color, #4a7bd9);
}

.sb-table tbody tr.sb-selectable-row.is-selected td:first-child {
  border-left: 1px solid var(--primary-color, #4a7bd9);
}

.sb-table tbody tr.sb-selectable-row.is-selected td:last-child {
  border-right: 1px solid var(--primary-color, #4a7bd9);
}

.sb-cell-num {
  text-align: right;
  font-size: 12.5px;
  font-variant-numeric: tabular-nums;
}
.sb-head-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.sb-cell-ico {
  display: inline-block;
  margin-right: 4px;
  color: var(--text-secondary);
}
.sb-cell-name {
  font-weight: 600;
  padding-left: 4px !important;
}
.sb-head-avatar,
.sb-cell-avatar {
  width: 26px;
  min-width: 26px;
  max-width: 26px;
  text-align: center;
}
.sb-cell-avatar {
  padding-right: 2px !important;
}
.sb-avatar-button {
  border: none;
  background: transparent;
  padding: 0;
  margin: 0;
  cursor: pointer;
  line-height: 0;
}
.sb-cell-action {
  width: 20px;
  min-width: 20px;
  max-width: 20px;
  padding-left: 2px !important;
  padding-right: 2px !important;
}
.sb-avatar-chip {
  width: clamp(18px, calc(1em + 8px), 24px);
  height: clamp(18px, calc(1em + 8px), 24px);
  border-radius: 50%;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: white;
  color: var(--primary-color);
  font-size: 10px;
  font-weight: bold;
  line-height: 1;
}
.sb-avatar-chip img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.sb-avatar-fallback {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.sb-user-with-avatar {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.sb-cell-state {
  color: var(--text-secondary);
}
.sb-cell-role.sb-new-captain {
  color: var(--primary-color);
  font-weight: 600;
}
.sb-cell-cube {
  font-size: 12px;
  color: var(--text-secondary);
}
.sb-cell-deleg {
  color: var(--text-secondary);
  font-size: 12px;
}
.sb-cell-last {
  color: var(--text-light);
  font-size: 12px;
}
.sb-empty {
  color: var(--text-light);
  font-style: italic;
  margin-top: 8px;
}

.react-gametab-impersonation-note {
  margin-top: 6px;
  margin-bottom: 4px;
  color: #d63031;
  font-size: 13px;
  font-weight: 600;
}

/* === Game log clickable rows / selection === */
.gamelog-row.move-clickable,
.gamelog-cube.clickable {
  cursor: pointer;
}
.gamelog-row.move-clickable:hover {
  background: var(--app-hover-fill);
  outline: 1px solid var(--border-color);
}
.gamelog-cube.clickable:hover {
  background: var(--secondary-bg);
}
.gamelog-row.is-selected-move,
.gamelog-cube.is-selected {
  background: rgba(74, 123, 217, 0.18);
  outline: 1px solid var(--selection-border-blue, #4a7bd9);
}

.gamelog-row.is-selected-move:hover,
.gamelog-cube.is-selected:hover {
  outline: 1px solid var(--selection-border-blue, #4a7bd9);
}

/* === Analysis panel === */
.analysis-panel {
  margin-top: 0;
  padding: 0;
  border: none;
  background: transparent;
  font-size: 13px;
  color: var(--text-primary);
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.analysis-panel-body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;
  overflow-x: auto;
  overflow-y: auto;
}
.analysis-panel.with-log .analysis-panel-body {
  overflow: hidden;
}
.analysis-panel.with-log {
  min-height: 0;
}
.analysis-panel.idle {
  color: var(--text-light);
}
.analysis-panel-compound {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  flex: 1 1 auto;
}
.analysis-panel-log {
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1 1 auto;
  overflow: hidden;
  /* Changed: no border / padding below: they separated the log from the
     summary under it, which moved below the board (GameTab boardSummary) */
}
.analysis-panel.with-log-split .analysis-panel-compound {
  gap: 0;
  display: grid;
  grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);
}
.analysis-panel.with-log-split .analysis-panel-log {
  flex: 0 0 auto;
  height: 100%;
  min-height: 0;
  padding-bottom: 4px;
}
.analysis-panel-log-split {
  border-bottom: 1px solid var(--border-color);
}
.analysis-panel-split-analysis {
  flex: 0 0 auto;
  height: 100%;
  min-height: 0;
  overflow: auto;
  padding-top: 6px;
}
.analysis-summary-move-link {
  appearance: none;
  border: 1px solid var(--border-color);
  background: var(--bg-white);
  color: var(--text-secondary, var(--text-primary));
  cursor: pointer;
  padding: 1px 4px;
  font: inherit;
  text-decoration: none;
  border-radius: 3px;
}

/* The info panel's played-move link sits inside the row's .gamelog-move,
   whose error class (warning/error/blunder) sets the background and colour:
   let those show through. Hover/focus/selected rules are more specific. */
.gamelog-move .analysis-summary-move-link {
  background: transparent;
  color: inherit;
}

/* Selected move matches the active Moves/Cube button: blue fill, white text. */
.analysis-summary-move-link.is-selected {
  background: var(--gametab-accent, #3a7bd5);
  border-color: var(--selection-border-blue, #4a7bd9);
  color: #fff;
}

.analysis-summary-move-link:hover:not(.is-selected) {
  background: var(--app-hover-fill);
  border-color: var(--border-color);
  color: inherit;
}

.analysis-summary-move-link.is-selected:hover {
  background: var(--gametab-accent, #3a7bd5);
  border-color: var(--selection-border-blue, #4a7bd9);
  color: #fff;
}

.analysis-summary-move-link:focus-visible:not(.is-selected) {
  background: var(--app-hover-fill);
  border-color: var(--border-color);
  color: inherit;
  outline: none;
}

.analysis-summary-move-link.is-selected:focus-visible {
  background: var(--gametab-accent, #3a7bd5);
  border-color: var(--selection-border-blue, #4a7bd9);
  color: #fff;
}

.analysis-panel-toprow {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  margin-bottom: 4px;
}
.analysis-panel-toprow.is-compact {
  margin-bottom: 0;
  gap: 0;
}
.analysis-panel-toprow.is-compact .analysis-panel-switcher-wrap {
  min-height: 0;
  height: 0;
  overflow: hidden;
}
.analysis-panel-switcher-wrap {
  margin-left: 0;
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
  min-height: 26px;
  display: flex;
  align-items: center;
}
.analysis-panel-switcher-placeholder {
  display: inline-block;
  width: 96px;
  height: 26px;
  visibility: hidden;
}
.analysis-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  border-bottom: 1px solid var(--border-color);
  padding-bottom: 4px;
  font-size: 12px;
  color: var(--text-light);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.analysis-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.analysis-status {
  padding: 8px 10px;
  border-radius: 6px;
  background: var(--secondary-bg);
  border-left: 3px solid var(--text-light);
}
.analysis-status.status-pending { border-left-color: #b8860b; }
.analysis-status.status-hidden  { border-left-color: #888; }
.analysis-status.status-unavailable { border-left-color: #c0392b; }
.analysis-status-label { font-weight: 600; }
.analysis-status-reason { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
.analysis-empty { color: var(--text-light); font-style: italic; }
.analysis-empty.analysis-empty-action {
  font-style: normal;
}
.analysis-show-button {
  appearance: none;
  border: 1px solid var(--border-color);
  background: var(--bg-white);
  color: var(--text-primary);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 12px;
  cursor: pointer;
}
.analysis-show-button:hover {
  background: var(--secondary-bg);
}
.analysis-move-note {
  padding: 6px 4px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--text-primary);
}
.analysis-luck-label {
  padding: 4px 4px 2px;
  font-weight: 600;
  font-size: 12px;
}
.analysis-luck-label.luck-very-lucky,
.analysis-luck-label.luck-lucky {
  color: #1a8c3a;
}
.analysis-luck-label.luck-unlucky,
.analysis-luck-label.luck-very-unlucky {
  color: #c0392b;
}

.react-gametab-analysis-embedded-log {
  display: flex;
  flex-direction: column;
  min-height: 0;
  height: 100%;
}

.react-gametab-analysis-embedded-log .gamelog-review-panel {
  min-height: 0;
  flex: 1 1 auto;
  overflow-y: auto;
}

.analysis-move-table {
  width: max-content;
  max-width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 12px;
  table-layout: auto;
}
.analysis-move-table th,
.analysis-move-table td {
  padding: 3px 4px;
  border-bottom: 1px solid var(--border-color);
  text-align: left;
  vertical-align: top;
}
.analysis-move-table .analysis-num-col,
.analysis-move-table .analysis-num-cell {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.analysis-move-table td:first-child {
  white-space: nowrap;
}
.analysis-move-table th {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-light);
  border-bottom-width: 2px;
  white-space: nowrap;
}
.analysis-move-cell {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  white-space: nowrap;
}
.analysis-move-notation {
  display: inline-block;
  padding: 1px 6px;
  border-radius: 4px;
  line-height: 1.35;
}
.react-gametab-root .analysis-move-notation.warning {
  background: greenyellow;
  color: #111;
}
.react-gametab-root .analysis-move-notation.error {
  background: yellow;
  color: #111;
}
.react-gametab-root .analysis-move-notation.blunder {
  background: red;
  color: #fff;
  font-weight: 700;
}
.analysis-move-table tr.analysis-probs-row > td {
  border-bottom: 1px solid var(--border-color);
  padding-top: 0;
  padding-bottom: 4px;
}
.analysis-move-table tr:not(.analysis-probs-row) > td {
  border-bottom: none;
  padding-bottom: 1px;
}
.analysis-probs-cell {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  line-height: 1.3;
  color: var(--text-secondary);
}
.analysis-probs-inner {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  white-space: nowrap;
}
.analysis-probs-win span + span,
.analysis-probs-loss span + span { margin-left: 4px; }
.analysis-probs-win  { text-align: left; }
.analysis-probs-loss { text-align: right; }
.analysis-move-table tr.is-played { font-weight: 600; }
.analysis-move-table tr[role='button'] { cursor: pointer; }
.analysis-move-table tr[role='button']:hover > td { background: var(--app-hover-fill); }
.analysis-move-table tr.is-selected > td {
  background: rgba(74, 123, 217, 0.18);
  box-shadow:
    inset 0 1px 0 var(--primary-color, #4a7bd9),
    inset 0 -1px 0 var(--primary-color, #4a7bd9);
}
.analysis-move-table tr.is-selected > td:first-child {
  box-shadow:
    inset 1px 0 0 var(--primary-color, #4a7bd9),
    inset 0 1px 0 var(--primary-color, #4a7bd9),
    inset 0 -1px 0 var(--primary-color, #4a7bd9);
}
.analysis-move-table tr.is-selected > td:last-child {
  box-shadow:
    inset -1px 0 0 var(--primary-color, #4a7bd9),
    inset 0 1px 0 var(--primary-color, #4a7bd9),
    inset 0 -1px 0 var(--primary-color, #4a7bd9);
}
/* When a data row is followed by a visible probs row, treat them as one
   box: drop the inner edges so the blue outline forms a single frame. */
.analysis-move-table tr.is-selected:not(.analysis-probs-row):has(+ tr.analysis-probs-row.is-selected:not([style*="display: none"])) > td {
  box-shadow: inset 0 1px 0 var(--primary-color, #4a7bd9);
}
.analysis-move-table tr.is-selected:not(.analysis-probs-row):has(+ tr.analysis-probs-row.is-selected:not([style*="display: none"])) > td:first-child {
  box-shadow:
    inset 1px 0 0 var(--primary-color, #4a7bd9),
    inset 0 1px 0 var(--primary-color, #4a7bd9);
}
.analysis-move-table tr.is-selected:not(.analysis-probs-row):has(+ tr.analysis-probs-row.is-selected:not([style*="display: none"])) > td:last-child {
  box-shadow:
    inset -1px 0 0 var(--primary-color, #4a7bd9),
    inset 0 1px 0 var(--primary-color, #4a7bd9);
}
.analysis-move-table tr.analysis-probs-row.is-selected > td {
  box-shadow: inset 0 -1px 0 var(--primary-color, #4a7bd9);
}
.analysis-move-table tr.analysis-probs-row.is-selected > td:first-child {
  box-shadow:
    inset 1px 0 0 var(--primary-color, #4a7bd9),
    inset 0 -1px 0 var(--primary-color, #4a7bd9);
}
.analysis-move-table tr.analysis-probs-row.is-selected > td:last-child {
  box-shadow:
    inset -1px 0 0 var(--primary-color, #4a7bd9),
    inset 0 -1px 0 var(--primary-color, #4a7bd9);
}
.analysis-move-table tr[role='button']:focus { outline: none; }

.analysis-cube { display: flex; flex-direction: column; gap: 6px; }
.analysis-cube-row {
  display: flex;
  justify-content: flex-start;
  gap: 8px;
}
.analysis-cube-row-cube-switcher {
  align-items: flex-start;
}
.analysis-cube-row-inline {
  justify-content: flex-start;
  align-items: baseline;
  gap: 6px;
}
.analysis-cube-variants {
  display: inline-flex;
  gap: 6px;
  flex-wrap: wrap;
  justify-content: flex-start;
}
.analysis-cube-variant-btn {
  border: 1px solid var(--border-color);
  background: var(--panel-bg);
  color: var(--text-primary);
  border-radius: 999px;
  padding: 2px 8px;
  font-size: 12px;
  cursor: pointer;
}
.analysis-cube-variant-btn.is-active {
  border-color: var(--primary-color, #4a7bd9);
  box-shadow: inset 0 0 0 1px var(--primary-color, #4a7bd9);
}
.analysis-cube-row.warning .analysis-value { color: #b8860b; }
.analysis-cube-row.error   .analysis-value { color: #c0392b; }
.analysis-cube-row.blunder .analysis-value { color: #8e1b1b; font-weight: 700; }
.analysis-cube-summary,
.analysis-variant-header {
  display: inline-flex;
  align-self: flex-start;
  width: auto;
  max-width: 100%;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px;
  padding: 6px 8px;
  border-radius: 6px;
  background: var(--secondary-bg);
}
.analysis-cube-summary.warning {
  background: greenyellow;
  color: #111;
  font-weight: 700;
}
.analysis-cube-summary.error {
  background: yellow;
  color: #111;
  font-weight: 700;
}
.analysis-cube-summary.blunder {
  background: red;
  color: #fff;
  font-weight: 700;
}
.analysis-cube-section {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.analysis-cube-tables {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: flex-start;
  gap: 10px;
}
.analysis-cube-spacer {
  flex: 1 1 0;
  min-width: 0;
  max-width: 50px;
}
.analysis-cube-section-primary {
  flex: 0 1 auto;
  min-width: 0;
}
.analysis-cube-section-secondary {
  flex: 0 1 auto;
  min-width: 220px;
}
.analysis-cube-table {
  width: max-content;
  min-width: 0;
  border-collapse: collapse;
  font-size: 12px;
}
.analysis-cube-table th,
.analysis-cube-table td {
  padding: 4px 6px;
  border-bottom: 1px solid var(--border-color);
}
.analysis-cube-table .analysis-num-col,
.analysis-cube-table .analysis-num-cell {
  text-align: right;
  font-variant-numeric: tabular-nums;
}
.analysis-cube-table th {
  text-align: left;
  color: var(--text-light);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  font-size: 10px;
}
.analysis-cube-table .analysis-num-cell {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.analysis-cube-table tr.is-chosen td {
  background: rgba(74, 123, 217, 0.12);
}
.analysis-cube-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 8px;
  padding: 6px;
  background: var(--secondary-bg);
  border-radius: 6px;
}
.analysis-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--text-light);
}
.analysis-value {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  color: var(--text-primary);
}

/* Download button in the session-row name cell. Scoped to .st-cell-name so it
   outranks .btn-session-row, which is defined later in this file and would
   otherwise reimpose its horizontal padding and push the icon off centre. */
.st-cell-name .st-row-download {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  min-width: 26px;
  height: 22px;
  padding: 0;
  margin-right: 8px;
  line-height: 1;
  border: 1px solid var(--border-color);
}

/* Added: Explore position view, the viewer's matches played from the position
   (Explore2PositionView, below the match context; same look as that table) */
/* Match contexts and Play from Position sessions (ExplorePositionView): rows
   of two lines, the title (ellipsis when too long, full in the tooltip) and
   the other values in smaller muted text, the buttons at the end of the row,
   always in view. The detail line is a smaller div: the phones' 12pt floor
   (above) lists elements such as span, li and td but not div, so it stays
   smaller on purpose; keep its text out of spans. */
.explore-match-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.explore-match-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border-bottom: 1px solid var(--border-color);
}
.explore-match-list .explore-match-row.is-selected {
  background: var(--select-highlight-bg);
}
/* Match contexts: a tap selects the row */
.explore-match-row.is-selectable {
  cursor: pointer;
}
.explore-match-main {
  flex: 1 1 auto;
  min-width: 0;
}
/* The row's size: 16px on phones by the floor (li), the panel's 13px elsewhere */
.explore-match-title {
  font-size: inherit;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.explore-match-meta {
  margin-top: 2px;
  /* A step below the title: about 13.6px on phones, 12px in a desktop panel */
  font-size: max(12px, 0.85em);
  /* Fixed, not normal: with normal, a glyph of another font (the flag from
     the Mac's emoji font) made the line taller than the others */
  line-height: 1.2;
  color: var(--text-light);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The flag of a flagged context: the emoji font's glyph sits low against
   the text, so it goes up a little */
.explore-match-flag {
  display: inline-block;
  position: relative;
  top: -0.1em;
}
.explore-match-actions {
  flex: 0 0 auto;
  display: flex;
  gap: 6px;
}
.explore-match-actions button {
  font-size: 12px;
  padding: 2px 10px;
  cursor: pointer;
}
.explore-match-actions button:disabled {
  cursor: not-allowed;
}
/* Rows still to come (PlaceholderMatchRow, the collapsed line): grey bars in
   place of the text. Each bar is followed by a no-break space, which gives its
   line a real line of text: alone, the bar sets the line's height (the strut
   does not apply here), and the row came out 9px lower than a real one. */
.explore-skeleton {
  display: inline-block;
  height: 0.8em;
  width: 8em;
  border-radius: 4px;
  background: var(--border-color);
  vertical-align: middle;
}
.explore-skeleton.is-title {
  width: 60%;
}
.explore-skeleton.is-meta {
  width: 80%;
}
/* The row that will be selected: its highlight shows it, no bars (on request).
   The bars stay in the layout (visibility), so the row keeps its height. */
.explore-match-row.is-placeholder.is-selected .explore-skeleton {
  visibility: hidden;
}
.explore-play-sessions {
  margin-bottom: 16px;
}
.explore-play-sessions-title {
  font-size: 12px;
  font-weight: bold;
  color: var(--text-light);
  margin-bottom: 6px;
}

/* Setup area (SetupTab.jsx): a bar with the panel switch and New Position
   above Explore's position view */
.setup-tab {
  height: 100%;
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--bg-white);
  color: var(--text-primary);
}

.setup-tab-view {
  flex: 1;
  min-height: 0;
}

/* Explore and Setup: the position workspace (PositionWorkspace.jsx). Its layout
   is the game tab's (gametab.css); these are only the contents of its slots. */
.explore-tab {
  height: 100%;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg-white);
  color: var(--text-primary);
}

.explore-tab-view {
  flex: 1;
  min-height: 0;
}

.position-workspace {
  height: 100%;
  min-height: 0;
}

.position-workspace-panel,
.position-workspace-results {
  display: flex;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
}

.position-workspace-panel {
  flex: 1 1 0;
}

/* The side bar (results and panels) left of the board: results, panel, board
   reads in the order of the work, and the panel is next to the board in XL/XXL.
   Apart from the game tab, where the board is left. The panel tabs stay on the
   panel's left edge. min-width: the game tab's 670px is wider than some phones,
   which the game tab handles with LS (off here, PositionWorkspace.jsx). */
.position-workspace .react-gametab-root.layout-landscape {
  flex-direction: row-reverse;
  min-width: 0;
}

/* Added: in portrait the board comes last, above the toolbar that acts on it: the results and
   panels first, as the side bar is left of the board in landscape (above). By order, not in the
   JSX, as the canvas host must never unmount (PositionWorkspace.jsx). Apart from the game tab,
   where the board is on top. */
.position-workspace .react-gametab-root.layout-portrait > .react-gametab-portrait-bottom-area,
.position-workspace .react-gametab-root.layout-small-size > .react-gametab-square-mid {
  order: -1;
}

/* A fixed split where results and panel are stacked (landscape L and LM): the
   panel tabs must not move when switching panels. Results take 30% (the game
   log has 40%), as the panels hold more than a list of a few rows. min-height: 0
   is what makes it fixed: without it the frame cannot shrink below its content,
   so a tall panel (Details) took height from the results, and the taller frame
   then turned the tabs from a column into a row. The panel scrolls instead. */
.position-workspace .react-gametab-panel-frame,
.position-workspace .react-gametab-lm-panel-column {
  min-height: 0;
}

.position-workspace .react-gametab-root.layout-landscape:is(.landscape-l, .landscape-lm) .react-gametab-side-scroll > .react-gametab-moves-panel {
  flex: 3 1 0;
  min-height: 0;
}

.position-workspace .react-gametab-root.layout-landscape:is(.landscape-l, .landscape-lm) .react-gametab-side-scroll > :is(.react-gametab-panel-frame, .react-gametab-lm-panel-column) {
  flex: 7 1 0;
  min-height: 0;
}

/* The bottom area is sized by computePortraitBoard, with a larger minimum than
   a game's, which the game's 40% cap would undo. */
.position-workspace .react-gametab-root.layout-portrait .react-gametab-portrait-bottom-area {
  max-height: none;
}

/* The board gives way to the panel: PositionWorkspace sets the height, also below
   the game's minimum */
.position-workspace .react-gametab-root.layout-small-size .react-gametab-board-pane {
  min-height: 0;
}

/* Panel tabs in a short (or, as a row, narrow) panel: they give up the space
   around their icons first, and scroll once at the icons' size, rather than
   being cut off. */
.position-workspace .react-gametab-panel-tabs {
  min-height: 0;
  min-width: 0;
  overflow: hidden auto;
  scrollbar-width: thin;
}

.position-workspace .react-gametab-panel-tabs.is-horizontal {
  overflow: auto hidden;
}

.position-workspace .react-gametab-panel-tabs > .react-gametab-toolbar-tip-target {
  display: flex;
  flex: 0 1 38px;
  min-height: 26px;
}

.position-workspace .react-gametab-panel-tabs.is-horizontal > .react-gametab-toolbar-tip-target {
  flex: 0 1 40px;
  min-width: 28px;
  min-height: 0;
}

.position-workspace .react-gametab-root .react-gametab-panel-tabs .react-gametab-toolbar-btn {
  width: 100%;
  height: auto;
  min-width: 40px;
}

.position-workspace .react-gametab-root .react-gametab-panel-tabs.is-horizontal .react-gametab-toolbar-btn {
  min-width: 0;
  height: 38px;
}

/* Full size (useMiniBoard; PositionWorkspace and the game tab's panel): the board is a small
   overlay on the window, over the lobby's header too, as it can be dragged anywhere; below
   dialogs (1000). */
.lobby-container .react-gametab-root.is-full-size .react-gametab-board-pane {
  z-index: 900;
  border-radius: 6px;
  overflow: hidden;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
}

.position-mini-board-surface {
  position: absolute;
  inset: 0;
  /* Over a game's layers on the board (notice 3, buttons and clocks 4, overlay 5) */
  z-index: 6;
  cursor: move;
  /* A drag moves the board; the page must not take it for a scroll */
  touch-action: none;
}

/* Added: the borders and corners that resize the board (useMiniBoard), over the surface and
   wide enough for a finger; the corners over the borders, the minimize button over the corners */
.position-mini-board-handle {
  position: absolute;
  z-index: 7;
  touch-action: none;
}

.position-mini-board-handle.is-n,
.position-mini-board-handle.is-s {
  left: 0;
  right: 0;
  height: 12px;
  cursor: ns-resize;
}

.position-mini-board-handle.is-e,
.position-mini-board-handle.is-w {
  top: 0;
  bottom: 0;
  width: 12px;
  cursor: ew-resize;
}

.position-mini-board-handle.is-n { top: 0; }
.position-mini-board-handle.is-s { bottom: 0; }
.position-mini-board-handle.is-e { right: 0; }
.position-mini-board-handle.is-w { left: 0; }

.position-mini-board-handle.is-ne,
.position-mini-board-handle.is-nw,
.position-mini-board-handle.is-se,
.position-mini-board-handle.is-sw {
  z-index: 8;
  width: 20px;
  height: 20px;
}

.position-mini-board-handle.is-ne { top: 0; right: 0; cursor: nesw-resize; }
.position-mini-board-handle.is-sw { bottom: 0; left: 0; cursor: nesw-resize; }
.position-mini-board-handle.is-nw { top: 0; left: 0; cursor: nwse-resize; }
.position-mini-board-handle.is-se { bottom: 0; right: 0; cursor: nwse-resize; }

.position-mini-board-minimize {
  position: absolute;
  z-index: 9;
  top: 2px;
  right: 2px;
  width: 28px;
  height: 28px;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.6);
  color: #fff;
  font-size: 18px;
  cursor: pointer;
}

.position-mini-board-pill {
  position: fixed;
  transform: translate(-50%, -50%);
  z-index: 900;
  /* A drag moves the pill; the page must not take it for a scroll */
  touch-action: none;
  min-height: 36px;
  padding: 0 12px;
  border: none;
  border-radius: 18px;
  background: var(--primary-color);
  color: #fff;
  font-size: 13px;
  cursor: pointer;
}

.lobby-container .react-gametab-root.is-full-size .react-gametab-square-mid {
  flex: 1 1 0;
  min-height: 0;
  height: auto;
}

.lobby-container .react-gametab-root.is-full-size .react-gametab-portrait-bottom-area {
  flex: 1 1 0;
  height: auto;
  min-height: 0;
  max-height: none;
}

/* Only what was made full size is shown */
.position-workspace .react-gametab-root.is-full-panel .position-workspace-results,
.position-workspace .react-gametab-root.is-full-results :is(.react-gametab-panel-frame, .react-gametab-lm-panel-column, .react-gametab-xlxxl-switch-column) {
  display: none;
}

.position-workspace .react-gametab-root.is-full-size :is(.position-panel-body, .position-results-scroll) {
  padding-bottom: var(--position-mini-board-height-px, 0px);
}

/* Beside the panel (portrait, XL, XXL) results get 40% of the width. The game
   log there is as wide as its content, but this list scrolls sideways, so it has
   no width of its own. The selectors repeat the game log's classes to outrank
   its rule, which gametab.css (loaded after this file) would win on a tie. */
.position-workspace .react-gametab-root.layout-portrait .react-gametab-portrait-bottom-area > .react-gametab-info-box.react-gametab-moves-panel.position-workspace-results,
.position-workspace .react-gametab-root.layout-landscape:is(.landscape-xl, .landscape-xxl) .react-gametab-xlxxl-split-area > .react-gametab-info-box.react-gametab-moves-panel.position-workspace-results {
  flex: 2 1 0;
  width: auto;
  min-width: 0;
}

.position-workspace .react-gametab-root.layout-portrait .react-gametab-portrait-bottom-area > .react-gametab-panel-frame,
.position-workspace .react-gametab-root.layout-landscape:is(.landscape-xl, .landscape-xxl) .react-gametab-xlxxl-split-area > .react-gametab-xlxxl-switch-column {
  flex: 3 1 0;
  min-width: 0;
}

/* Collapsed: only the query row, and the panel takes the rest instead of 70%,
   where results are stacked above the panel. In portrait, beside the panel, they
   go entirely (the panel tabs then have the way back, PositionWorkspace). Beside
   it in XL and XXL, or as a tab, it is not offered: the button is not shown. */
.position-workspace .react-gametab-root.layout-portrait .position-workspace-results.is-collapsed {
  display: none;
}

.position-workspace .react-gametab-root.layout-landscape:is(.landscape-l, .landscape-lm) .react-gametab-side-scroll > .position-workspace-results.is-collapsed {
  flex: 0 0 auto;
}

.position-workspace .react-gametab-root.layout-landscape:is(.landscape-l, .landscape-lm) .position-workspace-results.is-collapsed :is(.position-results-head, .position-results-scroll) {
  display: none;
}

.position-workspace .react-gametab-root.layout-landscape:is(.landscape-l, .landscape-lm) .position-workspace-results.is-collapsed .position-results-query {
  border-bottom: none;
}

.position-workspace .react-gametab-root:not(.is-full-size):is(.layout-portrait, .layout-landscape.landscape-l, .layout-landscape.landscape-lm) .position-workspace-results .position-results-collapse {
  display: inline-block;
}

.position-workspace-lm-row {
  display: flex;
  justify-content: center;
  width: 100%;
}

/* SetupPositionPanel's fields: a wrapper for disabled only, the grid stays its parent's */
.setup-position-fields {
  display: contents;
}

.position-details-heading {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
}

/* The Notes panel's fields (ExplorePositionView notesPanel; moved from inline styles): the label
   above its input, the checkbox beside its label */
.position-meta-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 13px;
}

.position-meta-field.is-checkbox {
  flex-direction: row;
  align-items: center;
  gap: 8px;
}

.position-meta-field input[type="text"],
.position-meta-field textarea {
  padding: 6px 8px;
  font-size: 13px;
}

.position-meta-field textarea {
  resize: vertical;
}

/* The Variant section, below the anchor's */
.position-details-heading:not(:first-child) {
  margin-top: 4px;
  padding-top: 12px;
  border-top: 1px solid var(--border-color);
}

.position-panel-body {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.position-panel-empty {
  padding: 16px;
  text-align: center;
  color: var(--text-light);
  font-size: 13px;
}

/* The counter between the pager's arrows reads as text, not as a disabled icon */
.react-gametab-toolbar-btn.position-toolbar-counter {
  width: auto;
  min-width: 46px;
  padding: 0 4px;
  font-size: 12px;
  white-space: nowrap;
  opacity: 1;
}

.position-results {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  font-size: 12px;
}

.position-results-head,
.position-results-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 8px;
  box-sizing: border-box;
  border-bottom: 1px solid var(--border-color);
}

.position-results-head {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--bg-white);
  color: var(--text-light);
  font-weight: bold;
}

.position-results-head button {
  padding: 0;
  border: none;
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.position-results-head button.is-sorted {
  color: var(--primary-color);
}

.position-results-scroll {
  flex: 1;
  min-height: 0;
  overflow: auto;
  position: relative;
}

.position-results-row {
  cursor: pointer;
}

.position-results-row.is-selected {
  background: var(--select-highlight-bg);
}

.position-results-head-cell {
  position: relative;
  align-self: stretch;
  display: flex;
  align-items: center;
  min-width: 0;
}

.position-results-head-cell > .position-results-cell {
  flex: 1;
  min-width: 0;
}

/* On the gap to the next column, wider than it looks so that a finger finds it */
.position-results-resize {
  position: absolute;
  top: 0;
  bottom: 0;
  right: -10px;
  width: 12px;
  z-index: 1;
  cursor: col-resize;
  touch-action: none;
}

/* A thin column border, which grows into a grip under the pointer or a finger */
.position-results-resize::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  border-radius: 2px;
  background: var(--text-light);
  transform: translateX(-50%);
  transition: width 0.12s ease, background-color 0.12s ease;
}

.position-results-resize:hover::after,
.position-results-resize:active::after {
  width: 4px;
  background: var(--primary-color);
}

.position-results-cell {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.position-results-cell.is-right {
  text-align: right;
}

.position-results-index {
  flex: 0 0 var(--results-index-width);
  font-variant-numeric: tabular-nums;
  color: var(--text-light);
}

/* A narrow column of its own between # and the first column, in every row (TOGGLE_WIDTH in
   positionColumns.js), so that nothing moves where a row has the button. The button is wider than
   the column for a finger; without min-width: 0 it would widen the column in just those rows. */
.position-results-toggle {
  flex: 0 0 20px;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.position-results-toggle button {
  flex: 0 0 26px;
  height: 30px;
  padding: 0;
  border: none;
  background: none;
  color: var(--text-primary);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}

/* A variant: below its anchor, indented by the first column's cell */
.position-results-row.is-variant .position-results-toggle + .position-results-cell,
.position-results-row.is-variant .position-results-index + .position-results-cell {
  padding-left: 14px;
  box-sizing: border-box;
}

/* Explore's query picker, above the result list */
.position-results-query {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 4px;
  border-bottom: 1px solid var(--border-color);
}

.position-results-query select {
  flex: 1;
  min-width: 0;
  min-height: 30px;
  font-size: 13px;
}

.position-results-query select.is-modified,
.position-overlay-heading.is-modified {
  font-style: italic;
}

.position-results-query .position-results-collapse {
  display: none;
  min-width: 18px;
}

.position-results-query button.is-active {
  color: var(--primary-color);
}

/* Narrow, so the query's name gets the width; the height stays for touch */
.position-results-query button {
  min-width: 24px;
  min-height: 30px;
  padding: 0;
  border: none;
  background: none;
  color: inherit;
  cursor: pointer;
}

/* The overlay of Explore and Setup (PositionOverlay.jsx): a dialog over the
   Workspace, the whole screen on a phone. */
.position-overlay {
  width: min(560px, 92vw);
  height: min(720px, 90vh);
  display: flex;
  flex-direction: column;
  border-radius: 12px;
  overflow: hidden;
  background: var(--bg-white);
  color: var(--text-primary);
}

.position-overlay.is-wide {
  width: min(880px, 92vw);
}

.position-overlay.is-phone {
  width: 100vw;
  height: 100dvh;
  border-radius: 0;
  /* The overlay centres it; with the keyboard up it must stay at the top */
  align-self: flex-start;
}

.position-overlay-title {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--border-color);
}

.position-overlay-heading {
  font-size: 15px;
  font-weight: bold;
}

.position-overlay-close {
  margin-left: auto;
  min-width: 32px;
  min-height: 32px;
  border: none;
  background: none;
  color: inherit;
  cursor: pointer;
}

.position-overlay-body {
  flex: 1;
  min-height: 0;
  overflow: auto;
}

.position-overlay-footer {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-top: 1px solid var(--border-color);
}

/* The query builder (ExploreQueries.jsx QueryEditorOverlay). Rows are touch sized. */
.explore-editor-body h3 {
  margin: 16px 0 6px;
  font-size: 12px;
  text-transform: uppercase;
  color: var(--text-light);
}

.explore-editor-summary {
  flex: 0 0 auto;
  padding: 4px 12px;
  font-size: 12px;
  color: var(--text-light);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.explore-query-notice {
  flex: 0 0 auto;
  padding: 2px 12px 4px;
  font-size: 12px;
  color: var(--danger-color);
}

.explore-query-notice.is-dismissable {
  display: flex;
  align-items: center;
  gap: 8px;
}

.explore-query-notice.is-dismissable span {
  flex: 1 1 auto;
  min-width: 0;
}

.explore-query-notice.is-dismissable button {
  flex: 0 0 auto;
  padding: 0 4px;
  border: none;
  background: none;
  color: inherit;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.prefs-threshold-notice {
  margin-top: 2px;
  font-size: 12px;
  color: var(--danger-color);
}

.explore-query-name-explanation {
  margin: 0 0 12px;
}

.explore-query-name {
  width: 100%;
  box-sizing: border-box;
  padding: 8px;
}

.explore-editor-body {
  padding: 0 12px 16px;
}

.explore-filter-card {
  margin-bottom: 8px;
  padding: 8px;
  border: 1px solid var(--border-color);
  border-radius: 4px;
}

.explore-filter-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
  font-size: 13px;
  font-weight: bold;
}

.explore-filter-head button {
  border: none;
  background: none;
  color: var(--text-light);
  cursor: pointer;
}

.explore-filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.explore-filter-row input {
  width: 110px;
}

.explore-add {
  margin: 4px 0;
}

.explore-picker {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 4px 0 8px;
}

.explore-column-row {
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 40px;
  border-bottom: 1px solid var(--border-color);
}

.explore-column-row .btn {
  min-width: 32px;
  min-height: 32px;
  padding: 4px;
}

.explore-column-handle {
  padding: 8px;
  cursor: grab;
  /* A drag on the handle reorders; the page must not take it for a scroll */
  touch-action: none;
  user-select: none;
}

.explore-column-label {
  flex: 1;
  min-width: 0;
  font-size: 14px;
}

.explore-count {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--text-light);
}

/* Added: the board summary below the board (GameTab boardSummary): move error,
   played and correct move or cube decision, cube error. One line of
   BOARD_SUMMARY_HEIGHT_PX (32px), which the board gives up. The errors use the
   game log's colours (.gamelog-move.warning / .error / .blunder). */
.react-gametab-board-summary {
  flex: 0 0 32px;
  height: 32px;
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  font-size: 14px;
  color: var(--text-primary);
}
.react-gametab-board-summary-decisions {
  flex: 1 1 auto;
  min-width: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 8px;
  white-space: nowrap;
}
/* Each half centres its move (auto margins rather than justify-content, so
   one that does not fit starts at the half's start instead of spilling out of
   both sides). A long move is cut with an ellipsis unless it is expanded
   (is-expanded, GameTab boardSummaryExpand: when selected, lying over the
   other move, or when it stays clear of the other move): then it keeps its
   full width, the played move (left half) growing to the right, the correct
   one (is-correct: row-reverse, so its start is the right edge) to the left. */
.react-gametab-board-summary-slot {
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: flex-start;
}
.react-gametab-board-summary-slot.is-correct {
  flex-direction: row-reverse;
}
.react-gametab-board-summary-slot > * {
  flex: 0 1 auto;
  min-width: 0;
  max-width: 100%;
  margin: 0 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.react-gametab-board-summary-slot > .is-expanded {
  flex-shrink: 0;
  max-width: none;
}
.react-gametab-board-summary-slot > .is-selected {
  position: relative;
  z-index: 1;
}
/* Full row height; the width fits "Correct" (a hidden copy in the same grid
   cell as the label), so the button does not change size with its value */
.react-gametab-board-summary-error {
  flex: 0 0 auto;
  align-self: stretch;
  display: grid;
  place-items: center;
  padding: 0 8px;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  background: var(--bg-white);
  color: inherit;
  font: inherit;
  white-space: nowrap;
  cursor: pointer;
}
.react-gametab-board-summary-error {
  font-variant-numeric: tabular-nums;
}
/* The error of the part not shown (GameTab): keeps its width and stays a
   click target (opacity, not visibility), so its place switches to that part
   too, a bigger target than the icon on phones */
.react-gametab-board-summary-error.is-hidden {
  opacity: 0;
}
.react-gametab-board-summary-error-label,
.react-gametab-board-summary-error::after {
  grid-area: 1 / 1;
}
.react-gametab-board-summary-error::after {
  content: 'Correct';
  visibility: hidden;
}
.react-gametab-board-summary-error.warning {
  background: greenyellow;
  color: #111;
}
.react-gametab-board-summary-error.error {
  background: yellow;
  color: #111;
}
.react-gametab-board-summary-error.blunder {
  background: red;
  color: #fff;
  font-weight: 700;
}
.react-gametab-board-summary-text {
  overflow: hidden;
  text-overflow: ellipsis;
}
.react-gametab-board-summary-text.is-correct {
  font-weight: 600;
}

/* The selected log entry's checker / cube (GameLogEntryChecker / -Cube) beside
   the error buttons, larger than in the log */
.react-gametab-board-summary-icon {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  padding: 2px;
  border: 2px solid transparent;
  border-radius: 6px;
  cursor: pointer;
}
/* The shown part (move / cube) when the entry has both (GameTab) */
.react-gametab-board-summary-icon.is-selected {
  border-color: var(--primary-color);
}
.react-gametab-board-summary-icon svg {
  width: 22px;
  height: 22px;
}

/* The played move / cube decision in its error's colours (GameTab
   boardSummaryErrorClass), like the game log's .gamelog-move. Scoped to the
   row so it wins over the move link's hover and selected fills; a selected
   coloured move keeps the selection as a blue outline. */
.react-gametab-board-summary .react-gametab-board-summary-played {
  padding: 2px 8px;
  border-radius: 6px;
}
.react-gametab-board-summary .react-gametab-board-summary-played.warning {
  background: greenyellow;
  color: #111;
}
.react-gametab-board-summary .react-gametab-board-summary-played.error {
  background: yellow;
  color: #111;
}
.react-gametab-board-summary .react-gametab-board-summary-played.blunder {
  background: red;
  color: #fff;
  font-weight: 700;
}
.react-gametab-board-summary .react-gametab-board-summary-played.is-selected:is(.warning, .error, .blunder) {
  box-shadow: inset 0 0 0 2px var(--gametab-accent, #3a7bd5);
}

/* Lobby tiles (LobbyHome): the three Play tiles, then a tile per area with something new. The
   grid fits as many columns of narrow tiles (150-220px) as the width allows: two on a phone. */
.lobby-home {
  padding: 24px 16px;
  box-sizing: border-box;
}

/* The tile grid's width, for the taller Play tiles (container query below). Changed: a wrapper
   of its own, no longer .lobby-home: that one scrolls, and its query measured the width with its
   scrollbar (442px of grid + 15px scrollbar passed a 456px threshold with one column) */
.lobby-home-tiles {
  container-type: inline-size;
}

.lobby-home-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 220px));
  justify-content: center;
  gap: 16px;
}

/* The divider after the Play tiles (LobbyHome): spanning every column of the grid, it ends the
   Play tiles' row, so the area tiles always start a row of their own */
.lobby-home-divider {
  grid-column: 1 / -1;
  height: 1px;
  background: var(--border-color);
}

.lobby-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  min-height: 190px;
  padding: 16px 14px;
  border-radius: 14px;
  border: 1px solid var(--border-color);
  background: var(--bg-white);
  color: var(--text-primary);
  text-align: center;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(35, 52, 63, 0.06);
  transition: transform 0.15s, box-shadow 0.15s;
}

.lobby-tile:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 24px rgba(35, 52, 63, 0.12);
}

.lobby-tile-play {
  background: linear-gradient(180deg, rgba(236, 249, 235, 0.98), rgba(221, 241, 218, 0.98));
}

/* Added: the Play tiles are 30% taller
   than the others (190px), the same width, so they stand out. Changed: only while the grid has
   room for four tiles side by side (was two): with fewer columns they only push the rest further
   down. Four columns need 4 x 220px + 3 x the 16px gap (auto-fill counts the columns with the
   tracks' maximum, 220px, not their minimum: at 363px it made one 220px column, while a first
   threshold of 2 x 150px + 16px had the tiles tall). The container's content box is the grid's
   width. */
@container (min-width: 928px) {
  .lobby-tile-play {
    min-height: 247px;
  }
}

/* Added: only one column fits (2 x 220px + the 16px gap do not; narrow portrait screens): the
   tiles are as high as their content needs (no min-height), so the player scrolls less, and 80% of the width instead of
   the 220px column that left empty space on both sides */
@container (max-width: 455.98px) {
  .lobby-home-grid {
    grid-template-columns: 80%;
  }

  .lobby-tile {
    min-height: 0;
  }
}

/* Added: a phone in landscape has about 250px of height for the page (title bar, the apps' "now
   playing" strip and the system bars take the rest): compact tiles, so the first row fits whole
   (they were cut off at the bottom); further rows scroll. Two classes: wins over .lobby-tile and
   the container queries' tile rules (one class each). */
.lobby-container.smartphone-landscape .lobby-tile {
  min-height: 0;
  gap: 4px;
  padding: 10px 12px;
}

.lobby-container.smartphone-landscape .lobby-tile-icon {
  width: 40px;
  height: 40px;
}

.lobby-container.smartphone-landscape .lobby-tile-title {
  font-size: 16px;
}

[data-theme="dark"] .lobby-tile-play {
  background: linear-gradient(180deg, rgba(38, 66, 58, 0.56), rgba(26, 46, 40, 0.62));
}

/* The other Play tiles while a human game runs: a player is in one running game at a time */
/* A Play tile while a challenge of the player's is out (Play a human): the slow glow of the title
   bar's indicator, and its status line in bold. Still for reduced
   motion (the bold line stays). */
.lobby-tile.is-pulsing {
  animation: play-tab-choice-pulse 3s ease-in-out infinite;
}

/* The challenge's status line; a tile pulsing for an open game has none (LobbyHome Tile) */
.lobby-tile.is-pulsing.has-status-emphasis .lobby-tile-status:first-child {
  font-weight: 700;
  color: var(--primary-color);
}

@media (prefers-reduced-motion: reduce) {
  .lobby-tile.is-pulsing {
    animation: none;
  }
}

.lobby-tile:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.lobby-tile-icon {
  width: 64px;
  height: 64px;
  flex: 0 0 auto;
}

.lobby-tile-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 18px;
  font-weight: 700;
}

.lobby-tile-count {
  min-width: 22px;
  padding: 1px 7px;
  border-radius: 11px;
  background: var(--primary-color);
  color: #fff;
  font-size: 13px;
  font-weight: 700;
  text-align: center;
}

.lobby-tile-lines {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.lobby-tile-status {
  color: var(--text-secondary);
  font-size: 13px;
}

/* Play area (PlayTab): the mode switch, the challenge form, then the mode's lists (SessionsTab) */
.play-tab {
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
}

/* Changed: the page's content below its tabs. Its padding is the 30px every lobby page had (the
   generic .tab-content > div rule, which overrode the 16px .play-tab had here) */
.play-tab-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 30px;
  box-sizing: border-box;
}

/* Added: the Play page's tabs (Human, Bot, Chouette; PlayTab), in the style of Google Drive's
   (Material) tabs: equal widths, the selected one in the primary colour with a rounded bar below.
   Across the page's full width and kept at the top while the page (.play-tab) scrolls. On a phone
   the tabs share the width; on a wide page each keeps at most 200px, from the content's left edge
   (.play-tab-body's padding), as Material's tabs do on large screens. */
.play-mode-tabs {
  position: sticky;
  top: 0;
  z-index: 2;
  flex-shrink: 0;
  display: flex;
  padding: 0 14px;
  border-bottom: 1px solid var(--border-color);
  background: var(--bg-white);
}

.play-mode-tab {
  flex: 1 1 0;
  max-width: 200px;
  display: flex;
  justify-content: center;
  padding: 0;
  border: 0;
  background: none;
  color: var(--text-secondary);
  font: inherit;
  font-size: 15px;
  font-weight: 500;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.play-mode-tab-label {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 14px 4px 12px;
}

.play-mode-tab.is-active {
  color: var(--primary-end);
  cursor: default;
}

[data-theme="dark"] .play-mode-tab.is-active {
  color: var(--primary-hover);
}

.play-mode-tab.is-active .play-mode-tab-label::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 3px;
  border-radius: 3px 3px 0 0;
  background: currentColor;
}

.play-mode-tab:not(.is-active):hover {
  background: var(--app-hover-fill);
}

.play-mode-tab-badge {
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  box-sizing: border-box;
  border-radius: 9px;
  background: var(--danger-color);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  line-height: 18px;
  text-align: center;
}

/* The mode's lists (SessionsTab) below the form: their own height, not what the form leaves
   over. SessionsTab's container fills a tab (flex 1, min-height 0, own scrolling); here that
   squeezed the lists to nearly nothing below a tall form (the bot mode's) and hid their rows. The
   Play page scrolls as a whole instead. */
.play-tab-body > .sessions-tab-container {
  flex: 0 0 auto;
  min-height: auto;
  overflow: visible;
}

/* The page's parts keep their natural height and the page scrolls: the mode switch has
   overflow hidden (for its rounded border), so as a shrinkable flex item it was squeezed to
   nothing once the content was taller than the page (e.g. with the friends to choose) */
.play-tab-body > * {
  flex-shrink: 0;
}

/* Changed: the page's whole width (was at most 520px, centred), so that on a phone in landscape
   the labels and their controls share a line and the form needs less scrolling */
.play-tab-form {
  width: 100%;
  padding: 16px;
  border: 1px solid var(--border-color);
  border-radius: 12px;
  background: var(--bg-white);
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Added: as below for one field in a dialog: its control on its label's line, below it only when
   both do not fit. Two classes, to win over .form-group and the media queries. */
.form-group.form-group-inline {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
}

.form-group.form-group-inline > label {
  margin-bottom: 0;
}

.form-group.form-group-inline > select {
  width: auto;
  max-width: 100%;
}

/* Added: a control stays on the line of its label and only drops below it when both do not fit.
   Scoped to the Play page's cards: MatchSettingsForm is also in the Play from Position dialog,
   which keeps its stacked fields. Two classes, to win over .form-group's and the media queries'
   rules (.form-group label's margin, .form-group select's and .form-select-compact's width 100%,
   which would always force the wrap). The cards' gap replaces .form-group's margin.
   Changed: also the chouette form as a page step (SessionModal asPage); as a dialog it stays
   stacked, and so do its sub-dialogs, which are rendered outside .session-form-page. */
.play-tab-form .form-group,
.session-form-page .form-group {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 12px;
  margin: 0;
}

.play-tab-form .form-group > label,
.session-form-page .form-group > label {
  margin-bottom: 0;
}

.play-tab-form .form-group select,
.session-form-page .form-group select {
  width: auto;
  max-width: 100%;
}

/* Added: at full width these would stretch across the page */
.play-tab-form .match-settings-clock {
  max-width: 420px;
}

/* Added: Find a match's slider takes the rest of its label's line, up to .level-range's maximum */
.play-tab-form .level-range {
  flex: 1 1 200px;
  width: auto;
}

.play-tab-friends {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  max-height: 160px;
  overflow-y: auto;
}

.play-tab-friend {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border: 1px solid var(--border-color);
  border-radius: 999px;
  cursor: pointer;
  font-size: 14px;
}

.play-tab-friend.is-selected {
  border-color: var(--primary-color);
  background: var(--secondary-bg);
}

.play-tab-hint,
.play-dialog-intro {
  margin: 0;
  color: var(--text-secondary);
  font-size: 13px;
}

.play-tab-submit {
  align-self: flex-end;
  min-width: 120px;
}

/* MatchSettingsForm: the settings of a two-player match */
.match-settings {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.match-settings .form-group {
  margin: 0;
}

.match-settings-dim {
  opacity: 0.5;
}

.match-settings-clock {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.match-settings-clock label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--text-secondary);
}

.match-settings-clock input {
  width: 100%;
  font-size: 13px;
  box-sizing: border-box;
}

/* Play's chouette mode as a flow (SessionsTab creatingChouette): the create step's head with
   Back, and the prompt leading to it / to a new chouette */
.st-chouette-create-head {
  display: flex;
  align-items: center;
  gap: 12px;
}

.st-chouette-create-new {
  display: flex;
  align-items: center;
  /* Changed: the button right behind the text (was at the row's end) */
  justify-content: flex-start;
  flex-wrap: wrap;
  gap: 12px;
  padding: 12px 14px;
  border: 1px solid var(--border-color);
  border-radius: 8px;
  background: var(--bg-white);
  color: var(--text-secondary);
}

/* SessionModal as a step of a page (asPage, Play's chouette mode): the dialog's title, content
   and buttons in a panel */
/* Changed: the page's whole width (was at most 560px, centred), as Play's other forms
   (.play-tab-form, which also has the rules for the fields on their labels' lines) */
.session-form-page {
  width: 100%;
  border: 1px solid var(--border-color);
  border-radius: 12px;
  background: var(--bg-white);
  box-sizing: border-box;
}

.session-form-page-title {
  padding: 14px 16px;
  border-bottom: 1px solid var(--border-color);
  font-size: 18px;
  font-weight: 700;
}

.session-form-page-body {
  padding: 16px;
}

.session-form-page-footer {
  display: flex;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 8px;
  padding: 12px 16px;
  border-top: 1px solid var(--border-color);
}

/* Added: the body has no gap as .play-tab-form has, so the fields keep a margin (the shared rule
   sets it to 0) */
.session-form-page .form-group {
  margin-bottom: 12px;
}

/* Added: the chouette's name on its label's line (.form-group input's width 100% would force the
   wrap), taking the rest of the line up to a sensible length */
.session-form-page .form-group input[type="text"] {
  flex: 1 1 200px;
  width: auto;
  max-width: 420px;
}

/* ManageChouettesModal: both tabs' contents in one cell, so that the larger one sizes the dialog */
.manage-chouettes-stack {
  display: grid;
}

.manage-chouettes-stack > * {
  grid-area: 1 / 1;
  min-width: 0;
}

.manage-chouettes-stack > .is-hidden {
  visibility: hidden;
}

/* ManageChouettesModal: what the tab shown is for */
.manage-chouettes-note {
  margin: 0 0 12px;
  color: var(--text-secondary);
  font-size: 13px;
  text-align: center;
}

/* ChouetteInviteDialog: when the session starts, and the button changing it */
.chouette-invite-start {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
}

/* A long friends list scrolls, so that the checkboxes below it and the dialog's buttons stay near.
   Changed: only the list, so that the search box above it stays in view */
.chouette-invite-friends .checkbox-list {
  max-height: 200px;
  overflow-y: auto;
}

/* FriendInviteList's search box, its ✓ and the match it cannot complete in place */
/* The ✓ sits in the field, behind the browser's clear x: the input's right padding keeps the x
   and the text clear of it */
.friend-invite-search-row {
  position: relative;
  margin-bottom: 8px;
}

.friend-invite-select {
  position: absolute;
  top: 50%;
  right: 4px;
  transform: translateY(-50%);
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  background: none;
  color: var(--primary-color);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}

.friend-invite-select:disabled {
  color: var(--text-secondary);
  opacity: 0.5;
  cursor: default;
}

.friend-invite-match {
  margin-bottom: 8px;
  color: var(--text-secondary);
  font-size: 13px;
}

.friend-invite-search {
  width: 100%;
  padding: 6px 30px 6px 10px;
  border: 1px solid var(--border-color);
  border-radius: 6px;
  box-sizing: border-box;
  background: var(--bg-white);
  color: var(--text-primary);
  font-size: 14px;
}

/* When the session starts */
.chouette-invite-start > span {
  color: var(--text-secondary);
  font-size: 14px;
}

/* The friends' caption, looking like the .form-group labels above it */
.chouette-invite-caption {
  margin-bottom: 8px;
  color: var(--text-primary);
  font-size: 14px;
  font-weight: 500;
}

/* Whether the invited players get an email, below the friends */
.chouette-invite-notify {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border-color);
}

/* Play's chouette mode, my chouettes: actions left-aligned (Clone, Edit, Start session #n), so
   each row's buttons start at the same place whatever the session number's width */
.st-table-my-chouettes .st-cell-actions {
  justify-content: flex-start;
}

/* My games: the note before a bot game's Resume that it starts the search for a human too */
.st-row-resume-note {
  font-size: 12px;
  color: var(--text-secondary);
  margin-right: 4px;
  white-space: nowrap;
}

/* Find a match (MatchSearch, Play → Human, Stage 5b): the search form, or its status card while
   it runs; the section titles of Play → Human use the same heading */
.match-search-title {
  font-weight: 600;
  font-size: 15px;
  color: var(--text-primary);
  margin-bottom: 10px;
}

.match-search-range,
.match-search-options {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
}

/* The length selects and PR inputs side by side: .form-group gives its selects and inputs the
   full width otherwise */
.match-search-range select,
.match-search-range input {
  width: auto;
}

.match-search-range input {
  width: 90px;
}

/* A choice of several (clocks, modes): buttons that are each selected or not (in the colours the
   Play page's mode switch had: the primary colour when selected) */
.match-search-toggle {
  padding: 6px 16px;
  border: 1px solid var(--border-color);
  border-radius: 999px;
  background: var(--bg-white);
  color: var(--text-primary);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

/* Play → Bot: the suspended bot games in the form's heading, quieter than the heading */
.play-tab-title-note {
  font-weight: 400;
  color: var(--text-secondary);
}

/* A new challenge flying into the notification icon (utils/flyToNotification): a copy of the
   area that created it, in the primary colour, above everything and not clickable; the
   animation itself (position, scale, opacity) is set by the script */
.fly-to-notification {
  position: fixed;
  z-index: 20000;
  pointer-events: none;
  box-sizing: border-box;
  background: linear-gradient(135deg, var(--primary-start) 0%, var(--primary-end) 100%);
  border: 1px solid var(--primary-color);
  border-radius: 12px;
  transform-origin: center;
}

/* The title bar's indicator of a running match search (MainLobby notifications 'search'): the
   slow glow of the Find a match button, and the icon itself pulsing (fading and shrinking a
   little), as the glow alone was hard to see on the header's buttons */
.header-overlay-btn.search-toggle.is-searching {
  animation: play-tab-choice-pulse 3s ease-in-out infinite;
}

.header-overlay-btn.search-toggle.is-searching .header-control-icon {
  animation: search-icon-pulse 3s ease-in-out infinite;
  transform-origin: center;
}

@keyframes search-icon-pulse {
  0%, 100% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.35;
    transform: scale(0.85);
  }
}

@media (prefers-reduced-motion: reduce) {
  .header-overlay-btn.search-toggle.is-searching,
  .header-overlay-btn.search-toggle.is-searching .header-control-icon {
    animation: none;
  }
}

/* Play → Bot: "Also look for a human opponent while I play a bot" (only while no search runs) */
.play-tab-also-search {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  border: 1px solid var(--border-color);
  border-radius: 8px;
}

.play-tab-also-search .play-tab-hint {
  margin: 0;
}

.play-tab-also-search .match-search-title {
  margin-bottom: 2px;
}

.play-tab-also-search.is-disabled {
  opacity: 0.6;
}

.play-tab-link {
  border: none;
  background: none;
  padding: 0;
  color: var(--primary-color);
  font: inherit;
  text-decoration: underline;
  cursor: pointer;
}

/* Play → Human: "Challenge a friend" below Find a match's card (PlayTab), the secondary action.
   Changed: was two choice buttons (.play-tab-choices) that disclosed the forms. */
.play-tab-or {
  align-self: center;
}

/* The pulse of a running search (the title bar's indicator, the floating notification button) */
@keyframes play-tab-choice-pulse {
  0%, 100% {
    box-shadow: 0 0 0 0 transparent;
  }
  50% {
    box-shadow: 0 0 14px 3px color-mix(in srgb, var(--primary-color) 55%, transparent);
  }
}


.match-search-toggle.is-selected {
  background: var(--primary-color);
  border-color: var(--primary-color);
  color: #fff;
}

/* The buttons of Play's cards (Find a match, its form and summary, the friend form and summary):
   on the right. Changed: in every card (was only Find a match's quick card, .is-end) */
.match-search-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 10px;
}

/* Added: Find a match's opponent level (MatchSearch LevelRange): two range inputs on one track,
   only their thumbs taking the pointer, the chosen part of the track filled in the primary
   colour; the levels chosen above, the two ends of the scale below */
.level-range {
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: 100%;
  max-width: 360px;
}

.level-range-value {
  font-weight: 600;
  color: var(--text-primary);
}

.level-range-slider {
  position: relative;
  height: 28px;
}

/* The rail runs between the thumbs' centres, which stop half a thumb (11px) inside the input's
   ends; the fill is placed on it in percent of the scale */
.level-range-rail {
  position: absolute;
  top: 50%;
  left: 11px;
  right: 11px;
  height: 4px;
  margin-top: -2px;
  border-radius: 2px;
  background: var(--border-color);
}

.level-range-fill {
  position: absolute;
  top: 0;
  bottom: 0;
  border-radius: 2px;
  background: var(--primary-color);
}

/* Added: the player's own level on the rail, the limit of the weakest end (LevelRange
   maxWeakest): a red line across the rail */
.level-range-limit {
  position: absolute;
  top: -8px;
  bottom: -8px;
  width: 2px;
  margin-left: -1px;
  background: var(--danger-color);
}

.level-range-slider input[type="range"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  background: none;
  pointer-events: none;
  -webkit-appearance: none;
  appearance: none;
}

/* Not the form's text-input look (.form-group input / :focus: border, padding, background,
   focus ring), which drew a box around the slider; the focus shows on the thumb instead */
.form-group .level-range-slider input[type="range"],
.form-group .level-range-slider input[type="range"]:focus {
  padding: 0;
  border: none;
  border-radius: 0;
  background: none;
  box-shadow: none;
  outline: none;
}

.level-range-slider input[type="range"]:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-color) 40%, transparent);
}

.level-range-slider input[type="range"]:focus-visible::-moz-range-thumb {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-color) 40%, transparent);
}

.level-range-slider input[type="range"].is-top {
  z-index: 1;
}

.level-range-slider input[type="range"]::-webkit-slider-runnable-track {
  background: transparent;
}

.level-range-slider input[type="range"]::-moz-range-track {
  background: transparent;
}

.level-range-slider input[type="range"]::-webkit-slider-thumb {
  pointer-events: auto;
  -webkit-appearance: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid var(--bg-white);
  background: var(--primary-color);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  cursor: pointer;
}

.level-range-slider input[type="range"]::-moz-range-thumb {
  pointer-events: auto;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid var(--bg-white);
  background: var(--primary-color);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  cursor: pointer;
}

.level-range-ends {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--text-secondary);
}

/* Added: the panel of an open challenge (Find a match's search, Play a friend's challenge;
   MatchSearch, FriendChallengeSummary): a read-only summary, its status line first. */
.match-search-summary-status {
  font-weight: 600;
  color: var(--text-primary);
}

.match-search-summary .play-tab-hint {
  margin: 0;
}

/* Its status text (a running session, the scheduled ones) is plain text, not tags: the font of
   the other tables' info tags (.st-info-tag), as the cell sets none of its own */
.st-table-my-chouettes .st-cell-info {
  font-size: 13px;
  color: var(--text-secondary);
  white-space: nowrap;
}

/* ===========================================================================================
   Apps (iOS and Android, components/NativeShell.jsx): the tab bar, the sheets and the Play
   areas' segmented control. One structure, two looks: .is-ios (translucent bars, small labels,
   an action sheet with a separate Cancel) and .is-android (Material 3: a pill behind the active
   icon, a bottom sheet with a drag handle). The lobby counts as fullscreen in the apps
   (MainLobby isFullscreen), so .lobby-container keeps out of the safe areas by padding; the tab
   bar reaches down into the bottom one instead, as the platforms' bars do.
   =========================================================================================== */

/* The app's pages with the lobby's title bar (MainLobby native-lobby-page: all but a game's;
   changed: was with the bottom bar, which now shows on four pages only). Three classes: their later position wins the tie with
   .smartphone-portrait/landscape.fullscreen's black, meant for a game in fullscreen. isolation: the
   title bar's ::before below (z-index -1) is painted above this background. */
.lobby-container.fullscreen.native-lobby-page {
  isolation: isolate;
  background: var(--bg-white);
}

/* Three classes: wins over .lobby-container.fullscreen, which sets the insets. The bottom bar
   reaches into the bottom one, the rail (landscape, Android) into the left one */
.lobby-container.fullscreen.has-native-tab-bar {
  --lobby-safe-bottom: 0px;
}

.lobby-container.fullscreen.has-native-tab-rail {
  --lobby-safe-left: 0px;
}

/* On the lobby's pages the title bar's gradient continues behind the status bar, as one gradient
   (two boxes with a gradient each showed a seam): the title bar's background is a ::before that
   reaches up over the container's top padding. Not done by padding the title bar, whose height
   MainLobby measures (--header-live-height) to size its controls. */
.lobby-container.fullscreen.native-lobby-page > .lobby-header {
  position: relative;
  background: transparent;
  /* On the ::before, which spans the status bar strip too: the title bar's own shadow blurred
     upwards into the strip and drew a line there */
  box-shadow: none;
}

.lobby-container.fullscreen.native-lobby-page > .lobby-header::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: calc(-1 * var(--lobby-safe-top));
  bottom: 0;
  z-index: -1;
  background: linear-gradient(135deg, var(--primary-start) 0%, var(--primary-end) 100%);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.native-tab-bar {
  flex: 0 0 auto;
  display: flex;
  background: var(--bg-white);
  border-top: 1px solid var(--border-color);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  user-select: none;
  -webkit-user-select: none;
}

.native-tab {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 6px 0 4px;
  border: 0;
  background: none;
  color: var(--text-light);
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.native-tab.is-active {
  color: var(--primary-color);
}

.native-tab-icon {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 26px;
}

.native-tab-icon svg {
  width: 24px;
  height: 24px;
}

.native-tab-label {
  font-size: 10px;
  font-weight: 500;
  line-height: 12px;
  white-space: nowrap;
}

.native-tab-badge {
  position: absolute;
  top: -4px;
  left: calc(50% + 5px);
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  box-sizing: border-box;
  border-radius: 8px;
  background: var(--danger-color);
  color: #fff;
  font-size: 10px;
  font-weight: 600;
  line-height: 16px;
  text-align: center;
}

.native-tab-bar.is-ios {
  background: rgba(249, 249, 249, 0.94);
  border-top: 0.5px solid rgba(0, 0, 0, 0.25);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  backdrop-filter: saturate(180%) blur(20px);
}

[data-theme="dark"] .native-tab-bar.is-ios {
  background: rgba(22, 22, 22, 0.94);
  border-top-color: rgba(255, 255, 255, 0.15);
}

.native-tab-bar.is-android {
  padding-top: 12px;
  padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  background: var(--secondary-bg);
  border-top: 0;
}

.native-tab-bar.is-android .native-tab {
  gap: 4px;
  padding: 0;
}

.native-tab-bar.is-android .native-tab-icon {
  width: 56px;
  height: 32px;
  border-radius: 16px;
}

.native-tab-bar.is-android .native-tab.is-active .native-tab-icon {
  background: rgba(45, 157, 168, 0.2);
}

.native-tab-bar.is-android .native-tab-label {
  font-size: 12px;
  line-height: 16px;
}

.native-tab-bar.is-android .native-tab.is-active .native-tab-label {
  font-weight: 700;
}

.native-sheet-badge,
.native-drawer-badge {
  position: static;
  display: inline-block;
}

/* The menu as a navigation drawer from the left (NativeDrawer) */
.native-drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  background: rgba(0, 0, 0, 0.4);
  animation: native-sheet-fade 0.2s ease-out;
}

.native-drawer {
  display: flex;
  flex-direction: column;
  width: min(320px, 85vw);
  height: 100%;
  box-sizing: border-box;
  padding: calc(12px + env(safe-area-inset-top, 0px)) 12px calc(12px + env(safe-area-inset-bottom, 0px)) calc(12px + env(safe-area-inset-left, 0px));
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--bg-white);
  box-shadow: 2px 0 16px rgba(0, 0, 0, 0.2);
  animation: native-drawer-in 0.22s ease-out;
}

@keyframes native-drawer-in {
  from { transform: translateX(-40px); opacity: 0.6; }
  to { transform: translateX(0); opacity: 1; }
}

/* The app's name with its icon on top of the drawer */
.native-drawer-brand {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 16px 12px;
  color: var(--text-primary);
  font-size: 20px;
  font-weight: 600;
}

.native-drawer-brand img {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  object-fit: cover;
}

.native-drawer-heading {
  padding: 12px 16px 4px;
  color: var(--text-light);
  font-size: 13px;
}

.native-drawer-divider {
  height: 1px;
  margin: 8px 16px;
  background: var(--border-color);
}

.native-drawer-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 52px;
  padding: 0 16px;
  border: 0;
  border-radius: 26px;
  background: none;
  color: var(--text-primary);
  font: inherit;
  font-size: 16px;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.native-drawer-item:active {
  background: var(--app-hover-fill);
}

/* navMenuItems disables the area the player is in: shown as the current one, not greyed */
.native-drawer-item.is-active:disabled {
  background: rgba(45, 157, 168, 0.18);
  color: var(--text-primary);
  font-weight: 600;
  cursor: default;
}

/* iOS: a plain list, the current entry tinted rather than a pill */
.is-ios .native-drawer-item {
  min-height: 48px;
  border-radius: 10px;
  font-size: 17px;
}

@media (prefers-reduced-motion: reduce) {
  .native-drawer-backdrop,
  .native-drawer {
    animation: none;
  }
}

/* The navigation rail (a phone in landscape, Android: Material's rail) at the left of the page,
   reaching into the left safe area (the camera side) */
.native-tab-bar.is-rail {
  flex-direction: column;
  justify-content: flex-start;
  gap: 12px;
  width: calc(80px + env(safe-area-inset-left, 0px));
  padding: 12px 0 env(safe-area-inset-bottom, 0px) env(safe-area-inset-left, 0px);
  border-top: 0;
  border-right: 1px solid var(--border-color);
  overflow-y: auto;
}

.native-tab-bar.is-rail .native-tab {
  flex: 0 0 auto;
}

/* The compact tab bar (a phone in landscape, iOS): icon and label side by side, about 32pt */
.native-tab-bar.is-compact .native-tab {
  flex-direction: row;
  justify-content: center;
  gap: 6px;
  padding: 4px 0;
}

.native-tab-bar.is-compact .native-tab-icon {
  width: 24px;
  height: 24px;
}

.native-tab-bar.is-compact .native-tab-label {
  font-size: 12px;
}

/* The title bar's way back to the running game (MainLobby back-to-game-btn): its title and
   the strip's chevron (below), on one line, the title cut with "…" where the header is short.
   In the size of the Menu button's text it replaced (.menu-button-text); the classes of
   .lobby-header .header-menu-button so as to win over its gap. */
.lobby-header .header-menu-button.back-to-game-btn {
  display: inline-flex;
  align-items: center;
  min-width: 0;
  max-width: 40vw;
  gap: 4px;
  /* Added: some room from the page title's × on its left, which the header's
     space-between gives only while there is width to spare */
  margin-left: clamp(6px, calc(var(--header-live-height, 42px) * 0.2), 12px);
}
.lobby-header .back-to-game-btn .back-to-game-title {
  overflow: hidden;
  font-size: clamp(11px, 0.95vw, 17px);
  line-height: 1.2;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.back-to-game-chevron {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
}

/* "Back to game" with the apps' navigation: a "now playing" strip above the bottom bar (or at the
   page's bottom where there is none), as in Spotify, YouTube or Maps (NativeNowPlaying) */
.native-now-playing {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 8px 16px;
  border: 0;
  border-top: 1px solid rgba(0, 0, 0, 0.08);
  background: linear-gradient(135deg, var(--primary-start) 0%, var(--primary-end) 100%);
  color: #fff;
  font: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.native-now-playing:active {
  filter: brightness(0.95);
}

.native-now-playing-text {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.native-now-playing-label {
  font-size: 11px;
  opacity: 0.85;
}

.native-now-playing-title {
  overflow: hidden;
  font-size: 14px;
  font-weight: 600;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.native-now-playing-chevron {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  opacity: 0.85;
}

/* In the title bar (landscape): the same content as a compact pill on the title bar's gradient */
.native-now-playing.is-titlebar {
  width: auto;
  max-width: 45vw;
  gap: 8px;
  padding: 2px 10px 2px 12px;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.16);
}

.native-now-playing.is-titlebar .native-now-playing-label {
  font-size: 10px;
  line-height: 12px;
}

.native-now-playing.is-titlebar .native-now-playing-title {
  font-size: 12px;
  line-height: 15px;
}

.native-now-playing.is-titlebar .native-now-playing-chevron {
  width: 16px;
  height: 16px;
}

/* Sheets: the account menu in the apps */
.native-sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 10000;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  background: rgba(0, 0, 0, 0.4);
  animation: native-sheet-fade 0.2s ease-out;
}

.native-sheet {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 560px;
  max-height: 85vh;
  box-sizing: border-box;
  animation: native-sheet-up 0.22s ease-out;
}

@keyframes native-sheet-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes native-sheet-up {
  from { transform: translateY(40px); opacity: 0.6; }
  to { transform: translateY(0); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .native-sheet-backdrop,
  .native-sheet {
    animation: none;
  }
}

.native-sheet-group {
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.native-sheet-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  border: 0;
  background: none;
  font: inherit;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.native-sheet-item:active {
  background: var(--app-hover-fill);
}

/* navMenuItems disables the area the player is in: shown as the current one, not greyed */
.native-sheet-item.is-active:disabled {
  color: var(--primary-color);
  font-weight: 600;
  cursor: default;
}

.native-sheet-title,
.native-sheet-heading {
  color: var(--text-light);
  font-size: 13px;
}

.native-sheet-divider {
  height: 8px;
}

/* iOS: an action sheet, a rounded group of centred rows and a separate Cancel below */
.is-ios .native-sheet {
  gap: 8px;
  padding: 0 8px calc(8px + env(safe-area-inset-bottom, 0px));
}

.is-ios .native-sheet-group,
.is-ios .native-sheet-cancel {
  border-radius: 14px;
  background: rgba(249, 249, 249, 0.97);
}

[data-theme="dark"] .is-ios .native-sheet-group,
[data-theme="dark"] .is-ios .native-sheet-cancel {
  background: rgba(44, 44, 46, 0.97);
}

.is-ios .native-sheet-title,
.is-ios .native-sheet-heading {
  padding: 14px 16px;
  text-align: center;
}

.is-ios .native-sheet-item {
  justify-content: center;
  min-height: 56px;
  padding: 0 16px;
  border-top: 0.5px solid rgba(60, 60, 67, 0.29);
  color: var(--primary-color);
  font-size: 19px;
}

.is-ios .native-sheet-group > .native-sheet-item:first-child {
  border-top: 0;
}

.is-ios .native-sheet-cancel {
  flex: 0 0 auto;
  min-height: 56px;
  border: 0;
  color: var(--primary-color);
  font: inherit;
  font-size: 19px;
  font-weight: 600;
  cursor: pointer;
}

/* Android: a Material bottom sheet, left-aligned rows below a drag handle */
.is-android .native-sheet-group {
  padding: 0 0 calc(16px + env(safe-area-inset-bottom, 0px));
  border-radius: 28px 28px 0 0;
  background: var(--bg-white);
}

.is-android .native-sheet-handle {
  width: 32px;
  height: 4px;
  margin: 16px auto 8px;
  border-radius: 2px;
  background: var(--text-light);
  opacity: 0.4;
}

.is-android .native-sheet-title,
.is-android .native-sheet-heading {
  padding: 8px 24px;
}

.is-android .native-sheet-item {
  justify-content: space-between;
  min-height: 56px;
  padding: 0 24px;
  color: var(--text-primary);
  font-size: 16px;
}

/* Added: the account deletion's dialog (DeleteAccountDialog) */
.delete-account-dialog ul {
  margin: 0 0 16px;
  padding-left: 20px;
}

.delete-account-dialog li {
  margin-bottom: 6px;
}

.delete-account-dialog input {
  width: 100%;
  margin-top: 8px;
  box-sizing: border-box;
}

.delete-account-error {
  margin-top: 12px;
}

/* ========================================
   Phones and small windows: lobby pages without a frame
   ======================================== */
/* On a phone (MainLobby deviceType 'smartphone') a lobby page reaches the screen's edges, as the
   game tab does (.react-gametab-root.is-mobile). Changed: also in a window narrower than 600px or
   lower than 800px (MainLobby FRAMED_MIN_*), both as .frameless on the lobby container: no page
   padding, and the panels that framed the page or its sections (lists, My games, the Play forms,
   Messages) lose their border and rounded corners. Their header strips and the gaps between
   sections separate them instead. Cards inside a page (tiles, player cards, profile entries,
   bubbles) keep theirs: they are content, not a frame. Content that relied on the page padding
   gets its own here. Larger windows keep the frames. At the end of the file, with .lobby-container.frameless in front, so these win over
   the rules they change. */
.lobby-container.frameless .tab-content > div:not([id^="game-root-"]):not(.react-gametab-shell):not(.lobby-floating-titlebar):not(.lobby-overlay-layer) {
  padding: 0;
}

.lobby-container.frameless .st-panel,
.lobby-container.frameless .st-my-games-section,
.lobby-container.frameless .play-tab-form,
.lobby-container.frameless .session-form-page,
.lobby-container.frameless .play-tab-also-search,
.lobby-container.frameless .st-chouette-create-new,
.lobby-container.frameless .messages-frame {
  border: none;
  border-radius: 0;
}

/* The Play page's sections span the width; their own padding keeps their content off the edges
   (only the top and bottom keep the page's room) */
.lobby-container.frameless .play-tab-body {
  padding: 16px 0;
}

.lobby-container.frameless .play-tab-also-search,
.lobby-container.frameless .st-chouette-create-new {
  padding-left: 16px;
  padding-right: 16px;
}

/* Back in the chouette steps had the page's padding on its left */
.lobby-container.frameless .st-chouette-create-head {
  padding: 0 16px;
}

/* The Profile has no padding of its own (MyProfileTab) */
.lobby-container.frameless .my-profile-tab {
  padding: 12px 16px;
  box-sizing: border-box;
}

/* Review's filters on one line: the dropdowns keep their width and the title field takes what is
   left (st-filter-title's 180px did not fit beside them). Only the row with the title field:
   the other pages' filter rows also hold toggles, which still wrap. */
.lobby-container.smartphone .st-filter-row:has(> .st-filter-title) {
  flex-wrap: nowrap;
  /* The header's width, not the row's content's: as an item of the wrapping header its minimum
     was its min-content, which counts the input's intrinsic width (~20 characters) whatever the
     input's own min-width, so the row outgrew the screen instead of shrinking the field */
  width: 100%;
  min-width: 0;
}

.lobby-container.smartphone .st-filter-row > .st-filter-title {
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
}

.lobby-container.smartphone .st-filter-row > .st-filter-dropdown {
  flex: 0 0 auto;
}

/* Review's summary line ("316 sessions to review") in normal lower case
   text, as in capitals with letter spacing it ran past the screen's edge. Dark theme too: its
   rule only sets the colour. */
.lobby-container.smartphone .st-panel-title-caps.st-summary-title {
  font-size: 14px;
  font-weight: 400;
  letter-spacing: normal;
  text-transform: none;
  white-space: normal;
}


/* The session lists (the bottom panel: Review, Observe, Play's lists) on a phone: the columns keep
   their full width and the list scrolls sideways, with the actions (Review, download, Join, ...)
   pinned at the right edge. Squeezed into the screen's width the name was cut and the info tags
   (match length, players, date) were clipped to a sliver. The panel body already scrolls the
   list vertically below the fixed header, so it scrolls both ways. Not the previews (My games,
   My chouettes), which are not in .st-panel-body. */
.lobby-container.smartphone .st-panel-body {
  overflow: auto;
}

.lobby-container.smartphone .st-panel-body > .st-table {
  grid-template-columns: max-content minmax(max-content, 1fr) auto;
  width: max-content;
  min-width: 100%;
}

.lobby-container.smartphone .st-panel-body .st-row > .st-cell-name {
  overflow: visible;
}

/* Opaque, as the other columns scroll beneath it; a shadow on its left edge shows that */
.lobby-container.smartphone .st-panel-body .st-row > .st-cell-actions {
  position: sticky;
  right: 0;
  z-index: 1;
  background: var(--bg-white);
  box-shadow: -6px 0 6px -6px rgba(0, 0, 0, 0.35);
}

/* The hover fill is translucent in the light theme: laid over the opaque background */
.lobby-container.smartphone .st-panel-body .st-row:hover > .st-cell-actions {
  background: linear-gradient(var(--app-hover-fill), var(--app-hover-fill)), var(--bg-white);
}

[data-theme="dark"] .lobby-container.smartphone .st-panel-body .st-row:hover > .st-cell-actions {
  background: #2a2a2a;
}

/* Review on a phone in landscape: the summary line ("316 sessions to review") goes behind the
   type toggles (… Play from Position) instead of on a line of its own, to leave the list more of
   the little height. The header is a column (.st-panel-bottom > .st-panel-header); here it becomes
   a wrapping row and the order puts the title after the toggles' row, the filters' row (the one
   with the title field, a full line) last. Only with Review's summary (.st-summary-title): the
   other lists' first row already holds their summary. */
.lobby-container.smartphone-landscape .st-panel-bottom > .st-panel-header:has(.st-summary-title) {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
}

.lobby-container.smartphone-landscape .st-panel-bottom > .st-panel-header:has(.st-summary-title) > .st-filter-row {
  order: 0;
}

.lobby-container.smartphone-landscape .st-panel-bottom > .st-panel-header:has(.st-summary-title) > .st-bottom-list-title {
  order: 1;
  flex: 1 1 auto;
  width: auto;
  min-width: 0;
  margin: 0;
}

.lobby-container.smartphone-landscape .st-panel-bottom > .st-panel-header:has(.st-summary-title) > .st-filter-row:has(> .st-filter-title) {
  order: 2;
  width: 100%;
}
