/* Layout */
body {
  display: flex;
  overflow: hidden;
}

.sidebar {
  width: var(--sidebar-width);
  height: 100vh;
  background: var(--bg-secondary);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  flex-shrink: 0;
  position: fixed;
  left: 0;
  top: 0;
  z-index: 100;
}

.sidebar-header {
  padding: 20px 16px;
  border-bottom: 1px solid var(--border);
}

.logo {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--accent);
  font-weight: 700;
  font-size: 16px;
}

/* Workspace switcher (Phase 3 MVP). Sits in sidebar-header below the logo.
   Three render modes via JS: dropdown (>1 ws), static text (1 ws),
   muted empty state (0 ws). */
.workspace-switcher { position: relative; margin-top: 12px; }
.workspace-switcher-button {
  display: flex; align-items: center; justify-content: space-between;
  width: 100%; padding: 8px 10px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius); color: var(--text-primary);
  font-size: 13px; cursor: pointer; transition: all var(--transition);
}
.workspace-switcher-button:hover { border-color: var(--accent); }
.workspace-switcher-static {
  display: block; padding: 4px 2px;
  color: var(--text-primary); font-size: 13px; font-weight: 500;
}
.workspace-switcher-static::before {
  content: 'Workspace';
  display: block;
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--text-muted); margin-bottom: 2px;
}
.workspace-switcher-empty {
  display: block; padding: 8px 10px;
  color: var(--text-muted); font-size: 12px; font-style: italic;
}
.workspace-switcher-button .chev {
  flex-shrink: 0; margin-left: 8px; color: var(--text-muted);
  transition: transform var(--transition);
}
.workspace-switcher.open .chev { transform: rotate(180deg); }
.workspace-switcher-menu {
  display: none;
  /* Width: detach from the narrow sidebar-header (188px content width). The
     sidebar is z-indexed and the dropdown is free to extend beyond the
     sidebar into the main content area. min/max bounds keep it readable
     for normal-length names without sprawling on extreme cases. */
  position: absolute; top: calc(100% + 4px); left: 0;
  min-width: 280px; max-width: 360px;
  background: var(--bg-card); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: 0 4px 12px rgba(0,0,0,0.3);
  max-height: 360px; padding: 4px 0; overflow-y: auto; z-index: 100;
}
.workspace-switcher.open .workspace-switcher-menu { display: block; }
.workspace-switcher-item {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 12px; cursor: pointer;
  border-bottom: 1px solid var(--border);
  color: var(--text-primary); font-size: 13px;
}
.workspace-switcher-item:last-child { border-bottom: none; }
.workspace-switcher-item:hover { background: var(--bg-input); }
.workspace-switcher-item.current { font-weight: 600; }
.workspace-switcher-item .check {
  flex-shrink: 0; color: var(--accent); width: 14px;
}
.workspace-switcher-item .ws-meta { flex: 1; min-width: 0; }
.workspace-switcher-item .ws-name {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.workspace-switcher-item .ws-org {
  font-size: 11px; color: var(--text-muted); margin-top: 1px;
  /* nowrap + ellipsis: long "Org Name . N devices" lines truncate cleanly
     instead of wrapping onto a second line that doubles row height. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.workspace-switcher-pencil {
  flex-shrink: 0; visibility: hidden;
  background: none; border: none; padding: 4px;
  color: var(--text-muted); cursor: pointer;
  border-radius: 4px; transition: all var(--transition);
}
.workspace-switcher-item:hover .workspace-switcher-pencil { visibility: visible; }
.workspace-switcher-pencil:hover { color: var(--accent); background: var(--bg-input); }
/* Members icon - same shape as the pencil; navigates to #/workspace/:id/members. */
.workspace-switcher-members {
  flex-shrink: 0; visibility: hidden;
  background: none; border: none; padding: 4px;
  color: var(--text-muted); cursor: pointer;
  border-radius: 4px; transition: all var(--transition);
}
.workspace-switcher-item:hover .workspace-switcher-members { visibility: visible; }
.workspace-switcher-members:hover { color: var(--accent); background: var(--bg-input); }

/* Workspace members page (Phase 2 user-mgmt, slice 2A read-only). Three
   sections render via JS: direct members, via_org access, pending invites.
   Row layout mirrors the sidebar user card's avatar pattern for visual
   continuity. via_org rows are opacity-reduced and invite rows use the
   input-bg shade so the three states are distinguishable at a glance. */
.members-list { display: flex; flex-direction: column; gap: 4px; }
.member-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 12px; border: 1px solid var(--border);
  border-radius: var(--radius); background: var(--bg-card);
}
.member-row--via-org { opacity: 0.75; }
.member-row--invited { background: var(--bg-input); }
.member-avatar {
  flex-shrink: 0;
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--accent); color: white;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 600;
}
.member-avatar--muted { background: var(--text-muted); }
.member-meta { flex: 1; min-width: 0; }
.member-name {
  font-size: 13px; font-weight: 500; color: var(--text-primary);
  display: flex; align-items: center; gap: 8px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.member-email {
  font-size: 11px; color: var(--text-muted); margin-top: 1px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.member-role {
  flex-shrink: 0; font-size: 12px; color: var(--text-secondary);
  padding: 4px 8px; background: var(--bg-input);
  border-radius: 4px; min-width: 60px; text-align: center;
}
.member-detail {
  flex-shrink: 0; font-size: 11px; color: var(--text-muted);
  min-width: 110px; text-align: right;
}
.member-via-org { font-style: italic; }
.member-badge {
  font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px;
  padding: 2px 6px; background: var(--bg-input); color: var(--text-muted);
  border-radius: 3px; font-weight: 600;
}

/* Slice 2B - mutation affordances. .member-actions is the cell that holds
   per-row admin buttons (remove on direct-member rows, cancel on invited
   rows). via_org rows omit the cell entirely. The role select replaces the
   .member-role div for admins on direct-member rows. */
.member-role-select {
  flex-shrink: 0; font-size: 12px;
  background: var(--bg-input); color: var(--text-primary);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 4px 8px; min-width: 90px; cursor: pointer;
}
.member-role-select:hover { border-color: var(--accent); }
.member-actions {
  flex-shrink: 0; display: flex; align-items: center; gap: 4px;
  margin-left: 4px;
}
.member-action-btn {
  display: inline-flex; align-items: center; justify-content: center;
  background: none; border: none; padding: 6px;
  color: var(--text-muted); cursor: pointer;
  border-radius: 4px; transition: all var(--transition);
}
.member-action-btn:hover { background: var(--bg-input); }
.member-action-btn--danger:hover { color: var(--danger); }

.nav-links {
  flex: 1;
  padding: 12px 8px;
}

.nav-link {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--radius);
  color: var(--text-secondary);
  transition: all var(--transition);
  margin-bottom: 2px;
}

.nav-link:hover {
  background: var(--bg-card);
  color: var(--text-primary);
}

.nav-link.active {
  background: var(--accent);
  color: white;
}

.sidebar-footer {
  padding: 16px;
  border-top: 1px solid var(--border);
}

.connection-status {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-muted);
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}

.status-dot.online { background: var(--success); box-shadow: 0 0 6px var(--success); }
.status-dot.offline { background: var(--danger); }
.status-dot.provisioning { background: var(--warning); animation: pulse 2s infinite; }

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.4; }
}

.content {
  margin-left: var(--sidebar-width);
  flex: 1;
  height: 100vh;
  overflow-y: auto;
  /* Clip stray horizontal overflow rather than letting body{overflow:hidden}
     swallow it invisibly. Combined with min-width:0 below this keeps wide
     inline-styled rows from forcing the whole page wider than the viewport. */
  overflow-x: hidden;
  min-width: 0;
  padding: 24px 32px;
}

/* Page Header */
.page-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 24px;
}

.page-header h1 {
  font-size: 24px;
  font-weight: 600;
}

.page-header .subtitle {
  color: var(--text-secondary);
  font-size: 13px;
  margin-top: 2px;
}

/* Buttons */
.btn {
  padding: 8px 16px;
  border-radius: var(--radius);
  font-weight: 500;
  font-size: 13px;
  transition: all var(--transition);
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

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

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

.btn-secondary {
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text-primary);
}

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

.btn-danger {
  background: var(--danger-dim);
  color: #fca5a5;
}

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

.btn-sm {
  padding: 5px 10px;
  font-size: 12px;
}

.btn-icon {
  padding: 6px;
  border-radius: var(--radius);
  color: var(--text-secondary);
  transition: all var(--transition);
}

.btn-icon:hover {
  background: var(--bg-card);
  color: var(--text-primary);
}

/* Device Grid */
.device-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
}

.device-card {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  transition: all var(--transition);
  cursor: pointer;
}

.device-card:hover {
  border-color: var(--accent);
  box-shadow: var(--shadow);
  transform: translateY(-2px);
}

.device-card-preview {
  aspect-ratio: 16/9;
  background: var(--bg-primary);
  position: relative;
  overflow: hidden;
}

.device-card-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.device-card-preview .no-preview {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  gap: 8px;
}

.device-card-preview .no-preview svg {
  opacity: 0.3;
}

.device-card-status {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  align-items: center;
  gap: 6px;
  background: rgba(0,0,0,0.7);
  backdrop-filter: blur(4px);
  padding: 4px 10px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 500;
}

.device-card-select {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 5;
  background: rgba(0,0,0,0.6);
  border-radius: 4px;
  padding: 3px 5px;
  display: flex;
  align-items: center;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s;
}
.device-card:hover .device-card-select,
.device-card.selected .device-card-select { opacity: 1; }
.device-card-select input { cursor: pointer; margin: 0; }
.device-card.selected { outline: 2px solid var(--primary, #3B82F6); outline-offset: -2px; }

/* Wall editor — free-form pan/zoom canvas */
.wall-viewport {
  position: relative;
  overflow: hidden;
  cursor: grab;
  user-select: none;
  background:
    linear-gradient(rgba(255,255,255,0.04) 1px, transparent 1px) 0 0 / 40px 40px,
    linear-gradient(90deg, rgba(255,255,255,0.04) 1px, transparent 1px) 0 0 / 40px 40px,
    var(--bg-primary);
}
.wall-viewport.panning { cursor: grabbing; }
/* Inner canvas: a 0×0 anchor whose CSS transform supplies pan + zoom.
   All rect children are absolutely positioned in canvas-data coordinates
   and inherit the parent transform. transform-origin is the canvas's
   top-left so pan offsets map cleanly to data → screen pixels. */
.wall-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 0;
  transform-origin: 0 0;
  /* Disable transition so panning doesn't lag behind the cursor */
}
.wall-zoom-readout {
  position: absolute;
  bottom: 8px;
  right: 12px;
  background: rgba(0,0,0,0.65);
  color: #fff;
  padding: 3px 8px;
  border-radius: 12px;
  font-size: 11px;
  pointer-events: none;
  font-variant-numeric: tabular-nums;
}

.wall-screen {
  position: absolute;
  background: rgba(59,130,246,0.08);
  border: 2px solid var(--primary, #3B82F6);
  border-radius: 4px;
  box-sizing: border-box;
  cursor: move;
  user-select: none;
  touch-action: none;
  overflow: hidden;
}
.wall-screen-overlap {
  position: absolute;
  background: rgba(96,165,250,0.35);
  pointer-events: none;
  display: none;
  z-index: 1;
}
.wall-screen-label {
  position: absolute;
  top: 4px;
  left: 6px;
  right: 24px;
  pointer-events: none;
  z-index: 2;
}
.wall-screen-name {
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary, #fff);
  text-shadow: 0 1px 2px rgba(0,0,0,0.6);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.wall-screen-meta {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  color: var(--text-muted);
  text-shadow: 0 1px 2px rgba(0,0,0,0.6);
}
.wall-screen-remove {
  position: absolute;
  top: 4px;
  right: 4px;
  z-index: 3;
  width: 20px;
  height: 20px;
  background: rgba(0,0,0,0.6);
  color: #fff;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0;
}
.wall-screen-remove:hover { background: var(--danger, #ef4444); }

.wall-player {
  position: absolute;
  background: rgba(96,165,250,0.18);
  border: 2px dashed #60a5fa;
  border-radius: 4px;
  box-sizing: border-box;
  cursor: move;
  user-select: none;
  touch-action: none;
  z-index: 5;
  box-shadow: 0 0 0 9999px transparent; /* keeps stacking explicit */
}
.wall-player-label {
  position: absolute;
  top: 4px;
  left: 6px;
  pointer-events: none;
  color: #dbeafe;
  text-shadow: 0 1px 2px rgba(0,0,0,0.6);
  font-size: 11px;
  letter-spacing: 1px;
}

/* Selected rect highlight (works for both screens and the player) */
.wall-screen.selected,
.wall-player.selected {
  outline: 3px solid #facc15;
  outline-offset: 1px;
  z-index: 6;
}

/* Fine-position panel inputs */
.wall-pos-grid {
  display: grid;
  grid-template-columns: auto 1fr auto 1fr;
  gap: 6px 8px;
  align-items: center;
  font-size: 12px;
}
.wall-pos-grid label {
  font-size: 11px;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.wall-pos-grid input {
  width: 100%;
  padding: 4px 6px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text-primary, #fff);
  font: inherit;
  font-variant-numeric: tabular-nums;
}
.wall-pos-grid input:focus { outline: 1px solid var(--primary); outline-offset: 0; border-color: var(--primary); }

/* Eight resize handles, used by both screens and the player */
.wall-handle {
  position: absolute;
  width: 10px;
  height: 10px;
  background: #fff;
  border: 1px solid #1d4ed8;
  border-radius: 2px;
  z-index: 4;
}
.wall-player .wall-handle { border-color: #60a5fa; }
.wall-handle-nw { top: -5px; left: -5px; cursor: nw-resize; }
.wall-handle-n  { top: -5px; left: 50%; transform: translateX(-50%); cursor: n-resize; }
.wall-handle-ne { top: -5px; right: -5px; cursor: ne-resize; }
.wall-handle-e  { top: 50%; right: -5px; transform: translateY(-50%); cursor: e-resize; }
.wall-handle-se { bottom: -5px; right: -5px; cursor: se-resize; }
.wall-handle-s  { bottom: -5px; left: 50%; transform: translateX(-50%); cursor: s-resize; }
.wall-handle-sw { bottom: -5px; left: -5px; cursor: sw-resize; }
.wall-handle-w  { top: 50%; left: -5px; transform: translateY(-50%); cursor: w-resize; }

/* Wall editor — legacy cells (kept for migration; new editor uses wall-canvas) */
.wall-cell {
  position: relative;
  background: var(--bg-card);
  border: 2px dashed var(--border);
  border-radius: var(--radius);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  color: var(--text-secondary);
  user-select: none;
}
.wall-cell.occupied {
  background: rgba(59,130,246,0.15);
  border: 2px solid var(--primary, #3B82F6);
  cursor: grab;
}
.wall-cell.occupied:active { cursor: grabbing; }
.wall-cell.drag-over {
  border-color: var(--success, #10b981);
  box-shadow: 0 0 0 2px rgba(16,185,129,0.25) inset;
}
.wall-cell-name { font-weight: 500; padding: 0 6px; text-align: center; }
.wall-cell-pos {
  position: absolute;
  bottom: 4px;
  font-size: 9px;
  color: var(--text-muted);
  letter-spacing: 0.5px;
}
.wall-cell-remove {
  position: absolute;
  top: 4px; right: 4px;
  background: rgba(0,0,0,0.6);
  border: none;
  color: #fff;
  border-radius: 50%;
  width: 20px; height: 20px;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 0;
}
.wall-cell-remove:hover { background: var(--danger, #ef4444); }

.wall-card .wall-card-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, rgba(139,92,246,0.15), rgba(59,130,246,0.1));
}
.wall-card-grid {
  display: grid;
  gap: 4px;
  width: 65%;
  aspect-ratio: 16/9;
  padding: 8px;
}
.wall-card-cell {
  background: rgba(255,255,255,0.05);
  border: 1px solid rgba(139,92,246,0.3);
  border-radius: 2px;
}
.wall-card-cell.filled {
  background: rgba(139,92,246,0.5);
  border-color: rgba(139,92,246,0.9);
}

.device-card-progress {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 6px 10px 8px;
  background: linear-gradient(to top, rgba(0,0,0,0.85), rgba(0,0,0,0));
  color: #fff;
  font-size: 11px;
  pointer-events: none;
}
.device-card-progress-label {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 4px;
  font-weight: 500;
  text-shadow: 0 1px 2px rgba(0,0,0,0.6);
}
.device-card-progress-label .dcp-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}
.device-card-progress-label .dcp-time {
  font-variant-numeric: tabular-nums;
  opacity: 0.85;
}
.device-card-progress-track {
  height: 3px;
  background: rgba(255,255,255,0.2);
  border-radius: 2px;
  overflow: hidden;
}
.device-card-progress-fill {
  height: 100%;
  width: 0%;
  background: var(--primary, #3B82F6);
  transition: width 0.9s linear;
}
.device-card-progress-fill.indeterminate {
  background: linear-gradient(90deg, transparent, var(--primary, #3B82F6), transparent);
  background-size: 50% 100%;
  animation: dcp-indeterminate 1.4s linear infinite;
}
@keyframes dcp-indeterminate {
  0% { background-position: -50% 0; }
  100% { background-position: 150% 0; }
}

.device-card-body {
  padding: 14px 16px;
}

.device-card-name {
  font-weight: 600;
  font-size: 15px;
  margin-bottom: 6px;
}

.device-card-meta {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--text-secondary);
  font-size: 12px;
}

.device-card-meta .meta-item {
  display: flex;
  align-items: center;
  gap: 4px;
}

/* Device Detail */
.device-detail {
  max-width: 1200px;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--text-secondary);
  margin-bottom: 16px;
  font-size: 13px;
  transition: color var(--transition);
}

.back-link:hover { color: var(--text-primary); }

.device-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  margin-bottom: 20px;
}

.device-header-left {
  display: flex;
  align-items: center;
  gap: 16px;
}

.device-header-left h1 {
  font-size: 22px;
}

.device-status-badge {
  padding: 4px 12px;
  border-radius: 20px;
  font-size: 12px;
  font-weight: 500;
}

.device-status-badge.online { background: var(--success-dim); color: var(--success); }
.device-status-badge.offline { background: var(--danger-dim); color: #fca5a5; }
.device-status-badge.provisioning { background: var(--warning-dim); color: var(--warning); }

.tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--border);
  margin-bottom: 20px;
}

.tab {
  padding: 10px 20px;
  color: var(--text-secondary);
  font-size: 13px;
  font-weight: 500;
  border-bottom: 2px solid transparent;
  transition: all var(--transition);
  cursor: pointer;
}

.tab:hover { color: var(--text-primary); }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }

.tab-content { display: none; }
.tab-content.active { display: block; }

/* Screenshot Preview */
.screenshot-container {
  background: var(--bg-primary);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  aspect-ratio: 16/9;
  position: relative;
  margin-bottom: 20px;
}

.screenshot-container img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.screenshot-container .no-screenshot {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
  gap: 8px;
}

/* Remote Control */
.remote-container {
  display: flex;
  gap: 20px;
}

.remote-screen {
  flex: 1;
  background: #000;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  position: relative;
  cursor: crosshair;
}

.remote-screen canvas {
  width: 100%;
  display: block;
}

.remote-controls {
  width: 120px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.remote-controls .btn {
  width: 100%;
  justify-content: center;
}

/* Playlist */
.playlist-container {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.playlist-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  transition: all var(--transition);
}

.playlist-item:hover {
  border-color: var(--border-light);
}

.playlist-item-thumb {
  width: 80px;
  height: 45px;
  border-radius: 4px;
  object-fit: cover;
  background: var(--bg-primary);
  flex-shrink: 0;
}

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

.playlist-item-name {
  font-weight: 500;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.playlist-item-meta {
  font-size: 11px;
  color: var(--text-secondary);
}

.playlist-item-actions {
  display: flex;
  gap: 4px;
}

/* Info Grid */
.info-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}

.info-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
}

.info-card-label {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--text-muted);
  margin-bottom: 6px;
}

.info-card-value {
  font-size: 20px;
  font-weight: 600;
}

.info-card-value.small {
  font-size: 14px;
}

/* Progress bar */
.progress-bar {
  height: 6px;
  background: var(--bg-primary);
  border-radius: 3px;
  overflow: hidden;
  margin-top: 8px;
}

.progress-bar-fill {
  height: 100%;
  border-radius: 3px;
  transition: width var(--transition);
}

.progress-bar-fill.success { background: var(--success); }
.progress-bar-fill.warning { background: var(--warning); }
.progress-bar-fill.danger { background: var(--danger); }

/* Content Library */
.content-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 16px;
}

.content-item {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: all var(--transition);
}

.content-item:hover {
  border-color: var(--border-light);
}

.content-item-preview {
  aspect-ratio: 16/9;
  background: var(--bg-primary);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.content-item-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.content-item-preview .video-icon {
  color: var(--text-muted);
}

.content-item-body {
  padding: 10px 12px;
}

.content-item-name {
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-bottom: 4px;
}

.content-item-size {
  font-size: 11px;
  color: var(--text-muted);
}

.content-item-actions {
  display: flex;
  justify-content: flex-end;
  padding: 0 12px 10px;
  gap: 4px;
}

/* Upload Area */
.upload-area {
  border: 2px dashed var(--border);
  border-radius: var(--radius-lg);
  padding: 48px 24px;
  text-align: center;
  cursor: pointer;
  transition: all var(--transition);
  margin-bottom: 24px;
}

.upload-area:hover,
.upload-area.dragover {
  border-color: var(--accent);
  background: rgba(59, 130, 246, 0.05);
}

.upload-area svg {
  margin: 0 auto 12px;
  color: var(--text-muted);
}

.upload-area p {
  color: var(--text-secondary);
  font-size: 14px;
}

.upload-area .upload-hint {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 4px;
}

/* Modal */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal {
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  width: 440px;
  max-width: 90vw;
  box-shadow: var(--shadow);
}

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

.modal-header h3 {
  font-size: 16px;
  font-weight: 600;
}

.modal-body {
  padding: 20px;
}

.modal-description {
  color: var(--text-secondary);
  font-size: 13px;
  margin-bottom: 16px;
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  padding: 16px 20px;
  border-top: 1px solid var(--border);
}

/* Form Elements */
.form-group {
  margin-bottom: 16px;
}

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

.input {
  width: 100%;
  padding: 8px 12px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-primary);
  transition: border-color var(--transition);
}

.input:focus {
  outline: none;
  border-color: var(--accent);
}

.pairing-input {
  width: 100%;
  padding: 12px 16px;
  background: var(--bg-input);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--text-primary);
  font-size: 28px;
  font-weight: 700;
  text-align: center;
  letter-spacing: 8px;
  font-family: 'Courier New', monospace;
}

.pairing-input:focus {
  outline: none;
  border-color: var(--accent);
}

/* Toast */
.toast-container {
  position: fixed;
  bottom: 24px;
  right: 24px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 2000;
}

.toast {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 16px;
  min-width: 280px;
  box-shadow: var(--shadow);
  display: flex;
  align-items: center;
  gap: 10px;
  animation: slideIn 0.3s ease;
}

.toast.success { border-left: 3px solid var(--success); }
.toast.error { border-left: 3px solid var(--danger); }
.toast.info { border-left: 3px solid var(--accent); }

@keyframes slideIn {
  from { transform: translateX(100%); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}

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

.empty-state svg {
  margin: 0 auto 16px;
  opacity: 0.3;
}

.empty-state h3 {
  color: var(--text-secondary);
  margin-bottom: 8px;
}

.empty-state p {
  font-size: 13px;
  max-width: 360px;
  margin: 0 auto;
}

/* Settings */
.settings-section {
  background: var(--bg-card);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 24px;
  margin-bottom: 20px;
}

.settings-section h3 {
  font-size: 16px;
  margin-bottom: 16px;
}

/* Assign Modal */
.assign-content-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 12px;
  max-height: 400px;
  overflow-y: auto;
}

.assign-content-item {
  background: var(--bg-input);
  border: 2px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  cursor: pointer;
  transition: all var(--transition);
}

.assign-content-item:hover {
  border-color: var(--accent);
}

.assign-content-item.selected {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}

.assign-content-item img {
  width: 100%;
  aspect-ratio: 16/9;
  object-fit: cover;
}

.assign-content-item-name {
  padding: 6px 8px;
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Scrollbar */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: transparent;
}

::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--border-light);
}

/* Upload progress */
.upload-progress {
  margin-top: 16px;
}

.upload-progress-bar {
  height: 4px;
  background: var(--bg-primary);
  border-radius: 2px;
  overflow: hidden;
}

.upload-progress-fill {
  height: 100%;
  background: var(--accent);
  border-radius: 2px;
  transition: width 0.3s ease;
}

/* Help tooltips */
.help-tip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--bg-card);
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  cursor: help;
  position: relative;
  margin-left: 6px;
  flex-shrink: 0;
}

.help-tip:hover::after {
  content: attr(data-tip);
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 8px 12px;
  font-size: 12px;
  font-weight: 400;
  color: var(--text-secondary);
  white-space: normal;
  width: 250px;
  z-index: 1000;
  box-shadow: var(--shadow);
  margin-bottom: 6px;
  line-height: 1.4;
}

/* Table wrapper: enables horizontal scroll when table min-width exceeds viewport */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* Mobile hamburger toggle */
.mobile-menu-btn {
  display: none;
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 200;
  width: 44px;
  height: 44px;
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  align-items: center;
  justify-content: center;
  color: var(--text-primary);
  cursor: pointer;
}

/* Responsive */
@media (max-width: 768px) {
  .mobile-menu-btn { display: flex; }
  .sidebar {
    transform: translateX(-100%);
    transition: transform 0.3s ease;
    z-index: 150;
  }
  .sidebar.open {
    transform: translateX(0);
  }
  .sidebar-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.5);
    z-index: 140;
  }
  .sidebar-backdrop.open { display: block; }
  .nav-link { min-height: 44px; padding: 10px 14px; }
  .content { margin-left: 0; padding: 16px; padding-top: 68px; }
  .page-header { flex-direction: column; gap: 12px; align-items: flex-start; }
  .device-grid { grid-template-columns: 1fr; }
  .content-grid { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
  .info-grid { grid-template-columns: 1fr; }
  .remote-container { flex-direction: column; }
  .remote-controls { width: 100%; flex-direction: row; flex-wrap: wrap; }
  .modal { width: 95vw; max-height: 90vh; overflow-y: auto; }
  .tabs {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    mask-image: linear-gradient(to right, black calc(100% - 24px), transparent 100%);
    -webkit-mask-image: linear-gradient(to right, black calc(100% - 24px), transparent 100%);
  }
  .tab { white-space: nowrap; flex-shrink: 0; }
  .playlist-item { flex-wrap: wrap; }

  /* Dashboard stats stack to single column */
  .dash-stats-row { flex-direction: column; }
  .dash-stats-row .info-card { flex: none; }

  /* Content-library 3-up toolbar stacks vertically */
  .content-toolbar { flex-direction: column; }
  .content-toolbar > div[style*="width:320px"] { width: auto !important; }

  /* Schedule controls: allow wrap and widen select to full row */
  .schedule-controls { gap: 8px; }
  .schedule-controls > select { flex: 1 1 100%; }
  .schedule-controls > button,
  .schedule-controls > span { flex: 0 1 auto; }

  /* Tap targets: minimum 44px height for interactive elements */
  .btn { min-height: 44px; padding: 10px 16px; }
  .btn-sm { min-height: 36px; padding: 8px 12px; }
  .btn-icon { min-width: 40px; min-height: 40px; }

  /* Form inputs: 16px font to prevent iOS focus zoom; 44px tap target */
  .input,
  input[type="text"],
  input[type="email"],
  input[type="password"],
  input[type="number"],
  input[type="url"],
  input[type="search"],
  input[type="tel"],
  select,
  textarea {
    font-size: 16px;
    min-height: 44px;
  }
  .pairing-input { font-size: 24px; letter-spacing: 6px; }

  /* Modals: adjust padding at 95vw so content doesn't touch edges */
  .modal-header,
  .modal-footer { padding: 14px 16px; }
  .modal-body { padding: 16px; }

  /* Toast container: full-width bar instead of 280px fixed to right */
  .toast-container {
    left: 12px;
    right: 12px;
    bottom: 12px;
  }
  .toast { min-width: 0; width: 100%; }

  /* --- Generic mobile overflow guards ---------------------------------
     Many views are built with inline styles (style="width:300px", flex
     toolbars with no wrap, etc.) that overflow narrow screens and get
     clipped by body{overflow:hidden}. Rather than edit every view, cap
     widths and let rows wrap at the layout level. */

  /* The page-header action cluster is an inline display:flex sibling of
     the title; let its buttons wrap and span the row once the header
     itself stacks. */
  .page-header > div { flex-wrap: wrap; }
  .page-header > div:last-child { width: 100%; }

  /* Any inline-fixed-width form control must not exceed the viewport.
     max-width:100% overrides the inline width: declaration without
     needing !important because the media query is more specific... it
     isn't, so cap via the element + attribute selector below too. */
  .content input.input,
  .content select.input,
  .content textarea.input,
  .content input[type="text"],
  .content input[type="search"],
  .content input[type="number"],
  .content input[type="email"] {
    max-width: 100%;
  }

  /* Toolbars: top-level inline flex rows directly under a view get wrap so
     children fall to the next line instead of overflowing. Scoped to direct
     children of .content (and one level into the rendered view root) to avoid
     wrapping avatar/name rows and editor canvases deeper in the tree. */
  .content > div[style*="display:flex"],
  .content > div > div[style*="display:flex"][style*="margin-bottom"] {
    flex-wrap: wrap;
  }

  /* Selects with inline pixel widths (e.g. group playlist/command pickers
     at 150-160px) stay fine, but the search+filter row should fill. */
  #deviceSearch { flex: 1 1 100%; max-width: none; }
  #deviceFilter { flex: 1 1 auto; }
}

@media (max-width: 480px) {
  .content-grid { grid-template-columns: 1fr; }
  .assign-content-grid { grid-template-columns: 1fr 1fr; }
}
