/**
 * Clear View - Unified Stylesheet
 * Console token layer (Media redesign) + legacy compatibility shim.
 * The :root / [data-theme="light"] blocks below come from UI Clearview/tokens.
 */

/* ============================================================================
   Clearview — "Console" token layer  (drop-in replacement for the old
   :root / [data-theme="light"] blocks). Dark-first, single accent, 4px grid.
   Re-exports the legacy --color-* names so the unmigrated ~9,700 lines below
   keep rendering unchanged, and declares the phantom --accent-h/-s/-l tokens
   that ~23 rules referenced but nothing defined.
   ============================================================================ */

:root {
  /* surfaces */
  --cv-bg-page:        #0A0A0B;
  --cv-bg-surface:     #101012;
  --cv-bg-raised:      #16161A;
  --cv-bg-overlay:     #1E1E23;
  --cv-bg-hover:       #1A1A1F;
  --cv-bg-active:      #26262D;
  --cv-bg-inset:       #070708;

  /* borders */
  --cv-border-subtle:  #1F1F24;
  --cv-border:         #2C2C34;
  --cv-border-strong:  #3F3F4A;

  /* text */
  --cv-text:           #FAFAFA;
  --cv-text-secondary: #A1A1AA;
  --cv-text-muted:     #7A7A85;
  --cv-text-disabled:  #52525B;
  --cv-text-inverse:   #0A0A0B;

  /* accent */
  --cv-accent:         #00BDF6;
  --cv-accent-rgb:     0, 189, 246;
  --cv-accent-hover:   #38CDF9;
  --cv-accent-press:   #00A3D4;
  --cv-accent-dim:     #0E5E77;
  --cv-accent-wash:    rgba(0, 189, 246, 0.10);
  --cv-accent-edge:    rgba(0, 189, 246, 0.32);
  --cv-on-accent:      #001318;

  /* status */
  --cv-success:        #10B981;
  --cv-success-wash:   rgba(16, 185, 129, 0.12);
  --cv-success-edge:   rgba(16, 185, 129, 0.34);
  --cv-on-success:     #00120B;
  --cv-warning:        #F59E0B;
  --cv-warning-wash:   rgba(245, 158, 11, 0.12);
  --cv-warning-edge:   rgba(245, 158, 11, 0.34);
  --cv-on-warning:     #1A1000;
  --cv-danger:         #EF4444;
  --cv-danger-wash:    rgba(239, 68, 68, 0.12);
  --cv-danger-edge:    rgba(239, 68, 68, 0.34);
  --cv-danger-solid:   #C0271F;   /* filled danger (LIVE badge): 5.6:1 w/ white */
  --cv-on-danger:      #FFFFFF;
  --cv-info:           #3B82F6;
  --cv-info-wash:      rgba(59, 130, 246, 0.12);
  --cv-info-edge:      rgba(59, 130, 246, 0.34);
  --cv-on-info:        #FFFFFF;
  --cv-neutral:        #8B8B96;
  --cv-neutral-wash:   rgba(139, 139, 150, 0.12);
  --cv-neutral-edge:   rgba(139, 139, 150, 0.34);

  /* media-domain verdicts */
  --cv-match:            var(--cv-success);
  --cv-match-wash:       var(--cv-success-wash);
  --cv-short:            var(--cv-warning);
  --cv-short-wash:       var(--cv-warning-wash);
  --cv-long:             var(--cv-info);
  --cv-long-wash:        var(--cv-info-wash);
  --cv-missing:          var(--cv-danger);
  --cv-missing-wash:     var(--cv-danger-wash);
  --cv-unscheduled:      var(--cv-neutral);
  --cv-unscheduled-wash: var(--cv-neutral-wash);

  /* typography */
  --cv-font-ui:   'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
  --cv-font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;
  --cv-text-2xs: 0.6875rem;
  --cv-text-xs:  0.75rem;
  --cv-text-sm:  0.8125rem;
  --cv-text-md:  0.875rem;
  --cv-text-lg:  1rem;
  --cv-text-xl:  1.25rem;
  --cv-text-2xl: 1.5rem;
  --cv-weight-normal:   400;
  --cv-weight-medium:   500;
  --cv-weight-semibold: 600;
  --cv-leading-tight: 1.25;
  --cv-leading-ui:    1.4;
  --cv-leading-body:  1.6;
  --cv-tracking-tight: -0.011em;
  --cv-tracking-caps:   0.06em;

  /* layout — 4px grid */
  --cv-space-0:  0;
  --cv-space-1:  0.25rem;
  --cv-space-2:  0.5rem;
  --cv-space-3:  0.75rem;
  --cv-space-4:  1rem;
  --cv-space-5:  1.5rem;
  --cv-space-6:  2rem;
  --cv-space-7:  3rem;
  --cv-radius-sm:   2px;
  --cv-radius:      3px;
  --cv-radius-lg:   4px;
  --cv-radius-full: 9999px;
  --cv-row-dense:   28px;
  --cv-row:         34px;
  --cv-row-comfy:   44px;
  --cv-control:     30px;
  --cv-control-sm:  24px;
  --cv-hit-min:     44px;
  --cv-sidebar-w:      260px;
  --cv-sidebar-w-rail:  80px;
  --cv-header-h:        56px;

  /* depth */
  --cv-shadow-popover: 0 4px 16px rgba(0, 0, 0, 0.55);
  --cv-shadow-modal:   0 16px 48px rgba(0, 0, 0, 0.65);

  /* motion */
  --cv-ease:     cubic-bezier(0.2, 0, 0.2, 1);
  --cv-dur-fast: 120ms;
  --cv-dur:      160ms;
  --cv-dur-slow: 200ms;

  /* focus */
  --cv-focus-ring:  0 0 0 2px var(--cv-bg-page), 0 0 0 4px var(--cv-accent);
  --cv-focus-inset: inset 0 0 0 1px var(--cv-accent);

  /* z-index scale */
  --cv-z-base:     0;
  --cv-z-sticky:   10;
  --cv-z-toolbar:  20;
  --cv-z-dropdown: 100;
  --cv-z-popover:  200;
  --cv-z-modal:    300;
  --cv-z-toast:    400;
  --cv-z-tooltip:  500;

  /* phantom tokens the old CSS referenced but never defined (accent as HSL
     parts so hsl(var(--accent-h) ...) composes; misnamed aliases revived). */
  --accent-h: 194;
  --accent-s: 100%;
  --accent-l: 48%;
  --text-muted:        var(--cv-text-muted);
  --text-primary:      var(--cv-text);
  --text-color:        var(--cv-text);
  --color-text:        var(--cv-text);
  --color-text-light:  var(--cv-text-secondary);
  --color-bg:          var(--cv-bg-surface);
  --bg-secondary:      var(--cv-bg-raised);
  --card-bg:           var(--cv-bg-surface);
  --border-color:      var(--cv-border);
  --primary-color:     var(--cv-accent);
  --font-mono:         var(--cv-font-mono);
  --color-primary-100: var(--cv-accent-wash);
  --font-size-md:            var(--cv-text-md);
  --color-text-tertiary:     var(--cv-text-muted);
  --color-border-secondary:  var(--cv-border-subtle);
  --vw-cols:     3;
  --slot-height: 60px;
  --color-success-alt: var(--cv-success);
}

/* ---- legacy --color-* compatibility shim (keeps unmigrated CSS rendering) -- */
:root {
  --color-bg-primary:    var(--cv-bg-page);
  --color-bg-secondary:  var(--cv-bg-surface);
  --color-bg-tertiary:   var(--cv-bg-raised);
  --color-bg-elevated:   var(--cv-bg-overlay);
  --color-surface:        var(--cv-bg-surface);
  --color-surface-hover:  var(--cv-bg-hover);
  --color-surface-active: var(--cv-bg-active);
  --color-border:        var(--cv-border);
  --color-border-light:  var(--cv-border-strong);
  --color-text-primary:   var(--cv-text);
  --color-text-secondary: var(--cv-text-secondary);
  --color-text-muted:     var(--cv-text-muted);
  --color-primary:       var(--cv-accent);
  --color-primary-rgb:   var(--cv-accent-rgb);
  --color-primary-light: var(--cv-accent-hover);
  --color-primary-900:   var(--cv-accent-wash);
  --color-accent:        var(--cv-accent);
  --color-accent-light:  var(--cv-accent-hover);
  --color-accent-dark:   var(--cv-accent-press);
  --color-success:       var(--cv-success);
  --color-success-light: var(--cv-success);
  --color-success-900:   var(--cv-success-wash);
  --color-warning:       var(--cv-warning);
  --color-warning-light: var(--cv-warning);
  --color-warning-900:   var(--cv-warning-wash);
  --color-danger:        var(--cv-danger);
  --color-danger-light:  var(--cv-danger);
  --color-danger-900:    var(--cv-danger-wash);
  --color-info:          var(--cv-info);
  --color-info-light:    var(--cv-info);
  --color-info-900:      var(--cv-info-wash);
  --color-neutral:       var(--cv-neutral);
  --color-neutral-light: var(--cv-neutral);
  --color-neutral-900:   var(--cv-neutral-wash);
  --font-family-sans: var(--cv-font-ui);
  --font-family-mono: var(--cv-font-mono);
  --font-size-xs:   var(--cv-text-xs);
  --font-size-sm:   var(--cv-text-sm);
  --font-size-base: var(--cv-text-md);
  --font-size-lg:   var(--cv-text-lg);
  --font-size-xl:   var(--cv-text-xl);
  --font-size-2xl:  var(--cv-text-2xl);
  --font-size-3xl:  2rem;
  --font-weight-normal:   var(--cv-weight-normal);
  --font-weight-medium:   var(--cv-weight-medium);
  --font-weight-semibold: var(--cv-weight-semibold);
  --font-weight-bold:     var(--cv-weight-semibold);
  --line-height-tight:   var(--cv-leading-tight);
  --line-height-normal:  var(--cv-leading-ui);
  --line-height-relaxed: var(--cv-leading-body);
  --spacing-xs:  var(--cv-space-1);
  --spacing-sm:  var(--cv-space-2);
  --spacing-md:  var(--cv-space-4);
  --spacing-lg:  var(--cv-space-5);
  --spacing-xl:  var(--cv-space-6);
  --spacing-2xl: var(--cv-space-7);
  --radius-sm:   var(--cv-radius-sm);
  --radius-md:   var(--cv-radius);
  --radius-lg:   var(--cv-radius-lg);
  --radius-xl:   var(--cv-radius-lg);
  --radius-full: var(--cv-radius-full);
  --shadow-sm: none;
  --shadow-md: none;
  --shadow-lg: var(--cv-shadow-popover);
  --shadow-xl: var(--cv-shadow-modal);
  --transition-fast: var(--cv-dur-fast) var(--cv-ease);
  --transition-base: var(--cv-dur) var(--cv-ease);
  --transition-slow: var(--cv-dur-slow) var(--cv-ease);
  --sidebar-width: var(--cv-sidebar-w);
  --header-height: var(--cv-header-h);
}

/* Light Theme Override — re-darkens status/accent so they clear AA on white. */
[data-theme="light"] {
  --cv-bg-page:        #F7F7F8;
  --cv-bg-surface:     #FFFFFF;
  --cv-bg-raised:      #F2F2F4;
  --cv-bg-overlay:     #FFFFFF;
  --cv-bg-hover:       #F0F0F2;
  --cv-bg-active:      #E4E4E8;
  --cv-bg-inset:       #EDEDF0;
  --cv-border-subtle:  #EAEAEE;
  --cv-border:         #D6D6DC;
  --cv-border-strong:  #B4B4BE;
  --cv-text:           #101012;
  --cv-text-secondary: #52525B;
  --cv-text-muted:     #6E6E78;
  --cv-text-disabled:  #A8A8B2;
  --cv-text-inverse:   #FFFFFF;
  --cv-accent:         #0369A1;
  --cv-accent-rgb:     3, 105, 161;
  --cv-accent-hover:   #075985;
  --cv-accent-press:   #024E7C;
  --cv-accent-dim:     #7DD3FC;
  --cv-accent-wash:    rgba(3, 105, 161, 0.08);
  --cv-accent-edge:    rgba(3, 105, 161, 0.28);
  --cv-on-accent:      #FFFFFF;
  --cv-success:        #047857;
  --cv-success-wash:   rgba(4, 120, 87, 0.10);
  --cv-success-edge:   rgba(4, 120, 87, 0.30);
  --cv-on-success:     #FFFFFF;
  --cv-warning:        #B45309;
  --cv-warning-wash:   rgba(180, 83, 9, 0.10);
  --cv-warning-edge:   rgba(180, 83, 9, 0.30);
  --cv-on-warning:     #FFFFFF;
  --cv-danger:         #B91C1C;
  --cv-danger-wash:    rgba(185, 28, 28, 0.10);
  --cv-danger-edge:    rgba(185, 28, 28, 0.30);
  --cv-danger-solid:   var(--cv-danger);   /* already dark enough on white (6.5:1) */
  --cv-on-danger:      #FFFFFF;
  --cv-info:           #1D4ED8;
  --cv-info-wash:      rgba(29, 78, 216, 0.10);
  --cv-info-edge:      rgba(29, 78, 216, 0.30);
  --cv-on-info:        #FFFFFF;
  --cv-neutral:        #5F5F6B;
  --cv-neutral-wash:   rgba(95, 95, 107, 0.10);
  --cv-neutral-edge:   rgba(95, 95, 107, 0.30);
  --cv-shadow-popover: 0 4px 16px rgba(16, 16, 18, 0.12);
  --cv-shadow-modal:   0 16px 48px rgba(16, 16, 18, 0.18);
  --cv-focus-ring:     0 0 0 2px var(--cv-bg-surface), 0 0 0 4px var(--cv-accent);
  --accent-h: 201;
  --accent-s:  96%;
  --accent-l:  32%;
}

@media (prefers-reduced-motion: reduce) {
  :root { --cv-dur-fast: 0ms; --cv-dur: 0ms; --cv-dur-slow: 0ms; }
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==================== Reset & Base ==================== */
*, *::before, *::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    font-size: 16px;
    scroll-behavior: smooth;
    /* Clip stray horizontal overflow at the viewport so a flyout from the
       fixed sidebar (e.g. the collapsed-rail nav tooltips, which sit to the
       right of the 80px rail) can never produce a page horizontal scrollbar.
       `clip` (not `hidden`) avoids turning the root into a scroll container,
       so it won't force a vertical scrollbar or affect sticky headers. Real
       horizontal scrolling lives in dedicated overflow-x:auto containers. */
    overflow-x: clip;
}

body {
    font-family: var(--font-family-sans);
    font-size: var(--font-size-base);
    line-height: var(--line-height-normal);
    color: var(--color-text-primary);
    background: var(--color-bg-primary);
    min-height: 100vh;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

a {
    color: var(--color-primary);
    text-decoration: none;
    transition: color var(--transition-fast);
}

a:hover {
    color: var(--color-primary-light);
}

code {
    font-family: var(--font-family-mono);
    font-size: 0.9em;
    background: var(--color-bg-tertiary);
    padding: 0.2em 0.4em;
    border-radius: var(--radius-sm);
}

/* ==================== Layout ==================== */
.app-container {
    display: flex;
    min-height: 100vh;
}

/* Sidebar */
.sidebar {
    width: var(--sidebar-width);
    background: var(--color-bg-secondary);
    border-right: 1px solid var(--color-border);
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    z-index: 100;
    transition: width var(--transition-base);
}

.sidebar.collapsed {
    width: 80px;
}

.sidebar-header {
    height: var(--header-height);
    padding: var(--spacing-lg);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: relative;
}

.sidebar-toggle {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    color: var(--color-text-secondary);
    cursor: pointer;
    padding: var(--spacing-sm);
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all var(--transition-fast);
    /* Always visible so the collapse control is easy to find (it used to be
       hidden until you hovered the header). */
    opacity: 1;
    pointer-events: all;
    width: 32px;
    height: 32px;
    flex-shrink: 0;
}

/* Hovering anywhere on the header emphasises the toggle. */
.sidebar-header:hover .sidebar-toggle {
    border-color: var(--color-primary);
    color: var(--color-text-primary);
}

.sidebar-toggle:hover {
    background: var(--color-surface-hover);
    color: var(--color-text-primary);
    border-color: var(--color-primary);
}

/* Collapsed (80px rail): stack the logo icon and the toggle vertically so the
   arrow never overlaps the logo. Header grows to fit the two stacked controls. */
.sidebar.collapsed .sidebar-header {
    flex-direction: column;
    justify-content: center;
    gap: var(--spacing-sm);
    height: auto;
    min-height: var(--header-height);
    padding: var(--spacing-md) var(--spacing-sm);
}

.sidebar.collapsed .sidebar-toggle {
    /* Static (not absolute) so it flows under the logo instead of overlapping
       it. The right-chevron icon signals "expand". */
    position: static;
    transform: none;
    opacity: 1;
    pointer-events: all;
}

.sidebar.collapsed .toggle-icon .icon-expand {
    display: none;
}

.sidebar.collapsed .toggle-icon .icon-collapse {
    display: block;
}

.sidebar:not(.collapsed) .toggle-icon .icon-collapse {
    display: none;
}

.logo {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
}
.icon {
    width: 25px;
    height: 25px;
    filter: invert(1);
}
.icon.invert {
    width: 25px;
    height: 25px;
    filter: none;
}
.logo-icon {
    width: 40px;
    height: 40px;
    /*background: linear-gradient(135deg, var(--color-primary), var(--color-accent));*/
    border-radius: var(--radius-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-lg);
    color: white;
    box-shadow: var(--shadow-glow);
}

.logo-text {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-primary);
    transition: opacity var(--transition-base), width var(--transition-base);
    white-space: nowrap;
    overflow: hidden;
}

.sidebar.collapsed .logo-text {
    opacity: 0;
    width: 0;
}

.sidebar-nav {
    flex: 1;
    padding: var(--spacing-md);
}

.nav-item {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    padding: var(--spacing-md) var(--spacing-lg);
    color: var(--color-text-secondary);
    border-radius: var(--radius-md);
    margin-bottom: var(--spacing-xs);
    transition: all var(--transition-fast);
    position: relative;
    justify-content: flex-start;
}

.sidebar.collapsed .nav-item {
    justify-content: center;
    padding: var(--spacing-md);
}

.sidebar.collapsed .nav-item::after {
    content: attr(data-tooltip);
    position: absolute;
    left: calc(100% + var(--spacing-md));
    top: 50%;
    transform: translateY(-50%);
    background: var(--color-bg-elevated);
    color: var(--color-text-primary);
    padding: var(--spacing-sm) var(--spacing-md);
    border-radius: var(--radius-md);
    white-space: nowrap;
    /* Kept OUT of layout while idle. With opacity:0 the tooltip still occupied
       a box to the right of the 80px rail, which extended the page's scroll
       width and produced a horizontal scrollbar when collapsed. display:none
       removes it from layout entirely; it's revealed only on hover below. */
    display: none;
    pointer-events: none;
    z-index: 1000;
    border: 1px solid var(--color-border);
    box-shadow: var(--shadow-lg);
    font-size: var(--font-size-sm);
}

.sidebar.collapsed .nav-item:hover::after {
    display: block;
}

/* media.css sets `.sidebar .sidebar-nav { overflow-y: auto }`, which per the
   CSS spec forces overflow-x to compute to `auto` too — making the nav its own
   scroll container. In the collapsed rail the hover tooltips fly out to the
   RIGHT of the 80px column, so the nav grew its own horizontal scrollbar on
   hover. overflow:visible lets the tooltips escape instead of scrolling; the
   collapsed list is icon-only and short, so it doesn't need the vertical scroll
   that the expanded nav keeps. Any residual overflow is clipped at the viewport
   by html{overflow-x:clip}. Higher specificity than media.css, so no !important. */
.sidebar.collapsed .sidebar-nav {
    overflow: visible;
}

.nav-item:hover {
    background: var(--color-surface-hover);
    color: var(--color-text-primary);
}

.nav-item.active {
    background: var(--color-primary-900);
    color: var(--color-primary);
    font-weight: var(--font-weight-medium);
}

.nav-icon {
    font-size: var(--font-size-lg);
    width: 30px;
    height: 30px;
    filter: contrast(0.5);
    flex-shrink: 0;
}

.nav-text {
    transition: opacity var(--transition-base), width var(--transition-base);
    white-space: nowrap;
    overflow: hidden;
}

.sidebar.collapsed .nav-text {
    opacity: 0;
    width: 0;
    position: absolute;
}

.nav-divider {
    height: 1px;
    background: var(--color-border);
    margin: var(--spacing-md) 0;
}

.sidebar-footer {
    padding: var(--spacing-lg);
    border-top: 1px solid var(--color-border);
}

/* Footer action cluster: relocated Users / Settings / Logs / Documentation nav
   items rendered as compact buttons (they keep .nav-item for routing). Log Out
   is kept visually separate below this cluster. */
.sidebar-footer-actions {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-md);
    padding-bottom: var(--spacing-md);
    border-bottom: 1px solid var(--color-border);
}
.sidebar-footer-link {
    width: auto;
    margin: 0;
    padding: var(--spacing-sm) var(--spacing-md);
    font-size: var(--font-size-sm);
    gap: var(--spacing-sm);
}
.sidebar-footer-link .nav-icon {
    width: 18px;
    height: 18px;
}
/* Log Out — kept separate below the cluster divider, full width. */
.sidebar-footer-logout {
    width: 100%;
    justify-content: center;
}
/* Collapsed sidebar: stack the footer actions as full-width icon buttons. */
.sidebar.collapsed .sidebar-footer-actions {
    grid-template-columns: 1fr;
    gap: var(--spacing-sm);
}
.sidebar.collapsed .sidebar-footer-link {
    justify-content: center;
    padding: var(--spacing-md);
}

.sidebar.collapsed .sidebar-footer {
    padding: var(--spacing-md);
}

/* Section labels (e.g. "Admin") are meaningless in the 80px rail — hide them. */
.sidebar.collapsed .sidebar-nav-label {
    display: none;
}

.user-profile {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    margin-bottom: var(--spacing-md);
    transition: all var(--transition-base);
}

.sidebar.collapsed .user-profile {
    justify-content: center;
    gap: 0;
}

.sidebar.collapsed .user-profile .user-info {
    opacity: 0;
    width: 0;
    overflow: hidden;
}

.user-info {
    transition: opacity var(--transition-base), width var(--transition-base);
    white-space: nowrap;
    overflow: hidden;
}

.sidebar.collapsed .sidebar-footer .btn {
    width: 100%;
    justify-content: center;
    padding: var(--spacing-sm);
}

.avatar {
    width: 40px;
    height: 40px;
    background: linear-gradient(135deg, var(--color-primary), var(--color-accent));
    border-radius: var(--radius-full);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: var(--font-weight-semibold);
    color: white;
}

.avatar-sm {
    width: 32px;
    height: 32px;
    font-size: var(--font-size-sm);
}

.user-info {
    display: flex;
    flex-direction: column;
}

.user-name {
    font-weight: var(--font-weight-medium);
    color: var(--color-text-primary);
}

.user-role {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

/* v3.3 — view-only badge styling. Amber background tints the label so
   the operator can see at a glance why action buttons might be missing
   on the page they're looking at. Matches the warning palette used
   elsewhere (session tabs, sync toggle, ending-soon alert). */
.user-role.user-role-viewer {
    display: inline-block;
    color: var(--color-warning-light, #fbbf24);
    background: var(--color-warning-900, rgba(245, 158, 11, 0.12));
    border: 1px solid var(--color-warning, #f59e0b);
    border-radius: 9999px;
    padding: 1px 8px;
    font-weight: var(--font-weight-semibold, 600);
    font-size: 11px;
    letter-spacing: 0.02em;
}

/* Main Content
   The sidebar is position:fixed (out of the document flow), so we reserve
   horizontal space for it on .main-content with BOTH margin-left and an
   explicit width. The margin-left pushes the content past the fixed
   sidebar; the width clamp prevents the flex:1 from blowing the content
   out to 100vw (which would overflow on the right). Both values switch in
   lockstep with the sidebar state via the adjacent-sibling selector below
   so there's no gap and no horizontal overflow at either size. */
.main-content {
    flex: 1;
    margin-left: var(--sidebar-width);
    width: calc(100% - var(--sidebar-width));
    max-width: calc(100vw - var(--sidebar-width));
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    transition: margin-left var(--transition-base),
                width var(--transition-base),
                max-width var(--transition-base);
    overflow-x: hidden;
}

/* Use the GENERAL sibling combinator (~), not adjacent (+). The
   .mobile-overlay div sits between .sidebar and .main-content in the
   markup, which made the adjacent selector silently no-op — the freed
   200px of horizontal space wasn't being reclaimed. */
.sidebar.collapsed ~ .main-content {
    margin-left: 80px;
    width: calc(100% - 80px);
    max-width: calc(100vw - 80px);
}

.page-header {
    height: var(--header-height);
    padding: 0 var(--spacing-xl);
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: var(--color-bg-secondary);
    border-bottom: 1px solid var(--color-border);
    position: sticky;
    top: 0;
    z-index: 50;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

.page-header-left {
    display: flex;
    align-items: center;
    gap: var(--spacing-lg);
}

.page-header-right {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    flex-wrap: wrap;
}

.page-header-right > *:not(:last-child) {
    position: relative;
}

.page-header-right > div:has(.badge):after {
    content: '';
    position: absolute;
    right: calc(-1 * var(--spacing-md) / 2);
    top: 50%;
    transform: translateY(-50%);
    height: 24px;
    width: 1px;
    background: var(--color-border);
}

.page-title {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    margin: 0;
}

.page-content {
    flex: 1;
    padding: var(--spacing-xs);
    overflow-y: auto;
    overflow-x: hidden;
    max-width: 100%;
    width: 100%;
    min-width: 0; /* Fixes flexbox shrinking lock-out so children can shrink below their intrinsic size */
}

/* Make every direct .page wrapper inside page-content fill the available
   width — this fixes the "not fluid" feel where the dashboard / monitor
   pages used to hug a narrower implicit max-width when the sidebar was
   collapsed or hidden. */
.page-content > .page,
.page-content > section,
.page-content > .panel {
    width: 100%;
    max-width: 100%;
    box-sizing: border-box;
}

/* ==================== Components ==================== */

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-sm);
    padding: var(--spacing-sm) var(--spacing-lg);
    font-family: inherit;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    border: none;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: all var(--transition-fast);
    white-space: nowrap;
}

.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.btn-primary {
    background: var(--color-primary);
    color: white;
}

.btn-primary:hover:not(:disabled) {
    background: var(--color-primary-light);
    box-shadow: var(--shadow-glow);
}

.btn-secondary {
    background: var(--color-surface);
    color: var(--color-text-primary);
    border: 1px solid var(--color-border);
}

.btn-secondary:hover:not(:disabled) {
    background: var(--color-surface-hover);
    border-color: var(--color-border-light);
}

.btn-accent {
    background: var(--color-accent);
    color: white;
}

.btn-accent:hover:not(:disabled) {
    background: var(--color-accent-light);
}

.btn-success {
    background: var(--color-success);
    color: white;
}

.btn-success:hover:not(:disabled) {
    background: var(--color-success-light);
}

.btn-danger {
    background: var(--color-danger);
    color: white;
}

.btn-danger:hover:not(:disabled) {
    background: var(--color-danger-light);
}

.btn-ghost {
    background: transparent;
    color: var(--color-text-secondary);
}

.btn-ghost:hover:not(:disabled) {
    background: var(--color-surface-hover);
    color: var(--color-text-primary);
}

.btn-disabled,
.btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    pointer-events: none;
}

.btn-disabled:hover,
.btn:disabled:hover {
    transform: none;
}

.btn-sm {
    padding: var(--spacing-xs) var(--spacing-md);
    font-size: var(--font-size-xs);
}

.btn-block {
    width: 100%;
}

/* Cards */
.card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    display: grid;
    align-content: space-between;
}

/* OBS Monitor page only: drop the border on the page's wrapping card. That
   card is the one containing #obs-content-area, so this stays scoped to the
   OBS Monitor without needing a page-level body class. */
.card:has(#obs-content-area) {
    border: none;
}

.card-header {
    padding: var(--spacing-lg);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.card-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
}

.card-subtitle {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    margin-top: var(--spacing-xs);
}

.card-body {
    padding: var(--spacing-lg);
    max-width: 100%;
}

.card-footer {
    padding: var(--spacing-lg);
    border-top: 1px solid var(--color-border);
    background: var(--color-bg-tertiary);
}

/* Connection Cards */
.connection-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: var(--spacing-lg);
    transition: all var(--transition-base);
}

.connection-card:hover {
    border-color: var(--color-primary);
    box-shadow: var(--shadow-md);
}

.connection-card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
}

.connection-name {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
}

.connection-ip {
    font-family: var(--font-family-mono);
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
}

/* Stats */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(50px, 0.25fr));
    gap: var(--spacing-xs);
}

.stat-card {
    background: var(--color-bg-tertiary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--spacing-md);
    text-align: center;
}

.stat-label {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: var(--spacing-xs);
}

.stat-value {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
}

.stat-value.good { color: var(--color-success); }
.stat-value.warning { color: var(--color-warning); }
.stat-value.critical { color: var(--color-danger); }

.loading-text {
    color: var(--text-muted);
    font-style: italic;
    font-size: var(--font-size-sm);
}

/* ==================== Dashboard ==================== */

.dash-stats-bar {
    display: flex;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-lg);
    flex-wrap: wrap;
}

.dash-stat {
    background: var(--color-bg-secondary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--spacing-sm) var(--spacing-md);
    flex: 1 1 0;
    min-width: 90px;
    text-align: center;
}

.dash-stat-value {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-primary);
    line-height: 1.2;
}

.dash-stat-label {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.dash-main {
    display: grid;
    grid-template-columns: 1fr 280px;
    gap: var(--spacing-lg);
    align-items: start;
}

@media (max-width: 900px) {
    .dash-main {
        grid-template-columns: 1fr;
    }
}

.dash-chart-card {
    min-height: 320px;
}

.dash-chart-wrap {
    position: relative;
    width: 100%;
}

.dash-chart-wrap canvas {
    display: block;
    width: 100%;
}

.dash-chart-legend {
    display: flex;
    gap: var(--spacing-md);
    margin-bottom: var(--spacing-sm);
    flex-wrap: wrap;
}

.dash-legend-item {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--font-size-xs);
    color: var(--color-text-secondary);
}

.dash-legend-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
}

.dash-sidebar {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-sm);
    min-width: 0;
}

.dash-log-row {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    padding: var(--spacing-xs) 0;
    border-bottom: 1px solid var(--color-border);
    font-size: var(--font-size-xs);
}

.dash-log-row:last-child {
    border-bottom: none;
}

.dash-log-time {
    color: var(--color-text-muted);
    flex-shrink: 0;
    min-width: 60px;
}

.dash-log-module {
    color: var(--color-text-secondary);
    flex-shrink: 0;
}

.dash-log-msg {
    color: var(--color-text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
    min-width: 0;
}

/* OBS Machine List Sidebar */
.dash-obs-list-card {
    min-width: 0;
}

.dash-obs-rows {
    display: flex;
    flex-direction: column;
}

.dash-obs-row {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    padding: 6px var(--spacing-md);
    border-bottom: 1px solid var(--color-border);
    font-size: var(--font-size-xs);
    transition: background var(--transition-fast);
}

.dash-obs-row:last-child {
    border-bottom: none;
}

.dash-obs-row:hover {
    background: var(--color-surface-hover);
}

.dash-obs-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    flex-shrink: 0;
}

.dash-obs-name {
    flex: 1;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--color-text-primary);
}

.dash-obs-status {
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    flex-shrink: 0;
}

.dash-obs-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-sm);
    padding: var(--spacing-xs) var(--spacing-md);
    border-top: 1px solid var(--color-border);
}

.dash-obs-page-info {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    min-width: 40px;
    text-align: center;
}

.dash-obs-legend-footer {
    padding: var(--spacing-xs) var(--spacing-md) !important;
    border-top: 1px solid var(--color-border);
}

.dash-obs-key {
    display: flex;
    flex-wrap: wrap;
    gap: var(--spacing-sm);
}

.dash-obs-key-item {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 0.65rem;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

/* Badges */
.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-xs);
    padding: var(--spacing-xs) var(--spacing-md);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    border-radius: var(--radius-md);
    white-space: nowrap;
    letter-spacing: 0.025em;
}

.badge-primary { background: var(--color-primary-900); color: var(--color-primary-light); }
.badge-success { 
    background: var(--color-success-900); 
    color: var(--color-success-light);
    border: 1px solid rgba(34, 197, 94, 0.2);
}
.badge-warning { 
    background: var(--color-warning-900); 
    color: var(--color-warning-light);
    border: 1px solid rgba(251, 191, 36, 0.2);
}
.badge-danger { 
    background: var(--color-danger-900); 
    color: var(--color-danger-light);
    border: 1px solid rgba(239, 68, 68, 0.2);
}
.badge-info { 
    background: var(--color-info-900); 
    color: var(--color-info-light);
    border: 1px solid rgba(59, 130, 246, 0.2);
}
.badge-neutral { 
    background: var(--color-neutral-900); 
    color: var(--color-neutral-light);
    border: 1px solid var(--color-border);
}
.badge-accent { 
    background: rgba(6, 182, 212, 0.1); 
    color: var(--color-accent-light);
    border: 1px solid rgba(6, 182, 212, 0.2);
}

/* Status Dot */
.status-dot {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-full);
    display: inline-block;
}

.status-dot-online { background: var(--color-success); }
.status-dot-offline { background: var(--color-danger); }
.status-dot-warning { background: var(--color-warning); }

/* Forms */
.form-group {
    margin-bottom: var(--spacing-lg);
}
.form-group.upcoming {
    background: #242424;
    padding: 1rem;
    border-radius: var(--radius-md);
}

.form-label {
    display: block;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-text-secondary);
    margin-bottom: var(--spacing-sm);
}

.form-input,
.form-select,
.form-textarea {
    width: 100%;
    padding: var(--spacing-sm) var(--spacing-md);
    font-family: inherit;
    font-size: var(--font-size-sm);
    color: var(--color-text-primary);
    background: var(--color-bg-tertiary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    transition: all var(--transition-fast);
}

.form-input:focus,
.form-select:focus,
.form-textarea:focus {
    outline: none;
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px var(--color-primary-900);
}

.form-input::placeholder {
    color: var(--color-text-muted);
}
.checkmark {
    position: absolute;
    top: 0;
    left: 0;
    height: 25px;
    width: 25px;
    background-color: #eee;
}
.form-checkbox {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    cursor: pointer;
}

.form-checkbox input[type="checkbox"] {
    width: 18px;
    height: 18px;
    accent-color: var(--color-primary);
}

.form-row {
    display: flex;
    gap: var(--spacing-md);
}

.form-row .form-group {
    margin-bottom: 0;
}

.form-divider {
    height: 1px;
    background: var(--color-border);
    margin: var(--spacing-lg) 0;
}

/* Notes & Diagnostics — quick-note audio preset chips (cvn = ClearView Notes) */
.cvn-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
}
.cvn-chip {
    font-size: var(--font-size-xs, 0.75rem);
    line-height: 1;
    padding: 6px 10px;
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: var(--color-bg-secondary, rgba(255,255,255,0.03));
    color: var(--color-text-secondary);
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.cvn-chip:hover {
    background: var(--color-primary, #3b82f6);
    border-color: var(--color-primary, #3b82f6);
    color: #fff;
}
/* Details line shown under Schedule/Item when a note is started from the editor. */
.cvn-item-details {
    margin-top: 6px;
    font-size: var(--font-size-xs, 0.75rem);
    color: var(--color-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Optional-timestamp checkbox row. */
.cvn-check {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-size: var(--font-size-sm, 0.85rem);
    color: var(--color-text);
}
.cvn-check input { cursor: pointer; }

/* Multi-select issue-type toggle chips. */
.cvn-types {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 8px;
}
.cvn-type-chip {
    font-size: var(--font-size-xs, 0.75rem);
    line-height: 1;
    padding: 6px 12px;
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: transparent;
    color: var(--color-text-secondary);
    cursor: pointer;
    transition: background 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}
.cvn-type-chip:hover {
    border-color: var(--color-primary, #3b82f6);
    color: var(--color-text);
}
.cvn-type-chip.selected {
    background: var(--color-primary, #3b82f6);
    border-color: var(--color-primary, #3b82f6);
    color: #fff;
}
.cvn-custom-row {
    display: flex;
    gap: 6px;
    margin-bottom: 8px;
}
.cvn-custom-row .form-input { flex: 1; }
/* Read-only "Created by" — visibly locked. */
#cvn-createdby[disabled] {
    opacity: 0.75;
    cursor: not-allowed;
}

/* Progress Bars */
.progress-bar {
    width: 100%;
    height: 24px;
    background: var(--color-bg-secondary);
    border-radius: var(--radius-full);
    overflow: hidden;
    border: 1px solid var(--color-border);
}

.progress-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--color-primary), var(--color-accent));
    transition: width 0.3s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-medium);
}

/* Data Tables */
.data-table {
    width: 100%;
    border-collapse: collapse;
}

.data-table th,
.data-table td {
    padding: var(--spacing-md) var(--spacing-lg);
    text-align: left;
    border-bottom: 1px solid var(--color-border);
}

.data-table th {
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: var(--color-bg-tertiary);
}

.data-table tbody tr:hover {
    background: var(--color-surface-hover);
}

.data-table .active-row {
    background: var(--color-primary-900);
}

/* Go Live row highlighting */
.data-table tbody tr.row-go-live-active {
    background: rgba(34, 197, 94, 0.15);
    border-left: 3px solid var(--color-success);
}

.data-table tbody tr.row-go-live-active:hover {
    background: rgba(34, 197, 94, 0.25);
}

/* Responsive Table Wrapper */
.card-body {
    padding: var(--spacing-lg);
    min-width: 0;
    overflow-x: hidden;
}

.table-responsive {
    display: grid;
    width: 100%;
    overflow-x: auto;
    overflow-y: visible;
    -webkit-overflow-scrolling: touch; /* Smooth scrolling on iOS */
    position: relative;
}

/* Matrix top scrollbar (profile migration) */
.matrix-scroll-top {
    overflow-x: scroll;
    overflow-y: hidden;
    scrollbar-gutter: stable both-edges;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
}

.matrix-scroll-top::-webkit-scrollbar {
    height: 8px;
}

.matrix-scroll-top::-webkit-scrollbar-track {
    background: var(--color-bg);
}

.matrix-scroll-top::-webkit-scrollbar-thumb {
    background: var(--color-border);
    border-radius: var(--radius-sm);
}

.matrix-scroll-top::-webkit-scrollbar-thumb:hover {
    background: var(--color-primary);
}

.matrix-scroll-body {
    overflow-x: auto;
    height: 600px;
}

/* Reflex DB dual scrollbars */
.reflex-scroll-top {
    margin-bottom: 8px;
}

.reflex-scroll-top .matrix-scroll-spacer {
    height: 1px;
}

/* Size to content so all rows on the current page (default 10) are
   visible without a fixed-height scrollbar appearing. The max-height
   cap kicks in only when the viewport is shorter than the rendered
   table — at which point overflow-y: auto adds a scrollbar.
   Net effect: tall monitor → no vertical scroll at all; short laptop
   / narrow window → table scrolls within its container instead of
   blowing out the whole page layout. */
.reflex-scroll-body {
    overflow-x: auto;
    overflow-y: auto;
    height: auto;
    /* The buffer (260px) accounts for the app header (60), DB card
       header (~70), filters/tabs (~60), pagination footer (~50), and a
       little breathing room. Adjust if those elements ever shift. */
    max-height: calc(100vh - 260px);
}

.data-table {
    min-width: 600px; /* Ensure table doesn't get too small */
    width: 100%;
    /*table-layout: fixed;*/
}

.data-table thead th {
    position: sticky;
    top: 0;
    background: var(--color-bg-tertiary);
    z-index: 10;
}

.data-table td {
    max-width: 300px; /* Prevent cells from getting too wide */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    word-break: break-word;
}

/* Actions cells should never truncate */
.data-table td:last-child:has(.btn) {
    max-width: none;
    overflow: visible;
    text-overflow: clip;
}

/* Force table to respect container width */
.card-body > .data-table {
    display: table;
}

/* Ensure Actions column doesn't shrink */
.data-table th:last-child,
.data-table td:last-child {
    min-width: 50px;
}

/* Ensure Go Live column stays fixed. Widened in v3.3.2 so the header
   label "Go Live" + the column-options ▾ button fit on one line; body
   cells get the same width so header/body alignment stays clean. */
.data-table .checkbox-cell {
    min-width: 110px;
    max-width: 110px;
    text-align: center;
}

/* Custom checkbox styling for Go Live column */
.data-table .checkbox-cell input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    width: 20px;
    height: 20px;
    border: 2px solid var(--color-border);
    border-radius: 4px;
    background-color: var(--color-bg);
    cursor: pointer;
    position: relative;
    transition: all 0.2s ease;
}

.data-table .checkbox-cell input[type="checkbox"]:hover {
    border-color: var(--color-primary);
}

.data-table .checkbox-cell input[type="checkbox"]:checked {
    background-color: var(--color-primary);
    border-color: var(--color-primary);
}

.data-table .checkbox-cell input[type="checkbox"]:checked::after {
    content: '✓';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: white;
    font-size: 14px;
    font-weight: bold;
}

/* NOTE (v3.3.2): the earlier 40px rule below was overriding the 110px
   width set above for the Go Live header, clipping the label. We keep
   text-align + vertical-align here but drop the conflicting width — the
   min/max-width pair above is the single source of truth now. */
.data-table .checkbox-cell {
    text-align: center;
    vertical-align: middle;
}

/* ── Go Live — circular pill toggle ──────────────────────────────────────
   Muted track by default, green when the row is set Live. Visually distinct
   from the square row-select checkbox in the leftmost column. */
.data-table .go-live-cell { text-align: center; vertical-align: middle; }
.go-live-toggle {
    display: inline-flex;
    align-items: center;
    cursor: pointer;
}
/* Hide the raw checkbox (override the generic square .checkbox-cell styling)
   but keep it interactive + focusable as the toggle's control. */
.go-live-toggle input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    margin: 0;
    border: 0;
    pointer-events: none;
}
.go-live-track {
    display: inline-block;
    position: relative;
    width: 38px;
    height: 20px;
    border-radius: 999px;
    background: var(--color-border, #555);
    transition: background 0.2s ease, filter 0.2s ease;
}
.go-live-knob {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--color-bg, #fff);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
    transition: transform 0.2s ease;
}
.go-live-toggle input[type="checkbox"]:checked + .go-live-track {
    background: var(--color-success, #22c55e);
}
.go-live-toggle input[type="checkbox"]:checked + .go-live-track .go-live-knob {
    transform: translateX(18px);
}
.go-live-toggle:hover .go-live-track { filter: brightness(1.15); }
.go-live-toggle input[type="checkbox"]:focus-visible + .go-live-track {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
}

/* ── Row-select column — tighter than the Go Live column ─────────────────── */
.data-table .reflex-select-cell {
    min-width: 34px;
    max-width: 40px;
    width: 36px;
    padding-left: 4px;
    padding-right: 4px;
    text-align: center;
}

/* Column Mapping Styles */
#column-mapping-form .form-group {
    margin-bottom: var(--spacing-lg);
}

#column-mapping-form .form-label {
    font-weight: 600;
    margin-bottom: var(--spacing-xs);
}

#column-mapping-form .form-label span[style*="color"] {
    margin-left: var(--spacing-xs);
}

/* Bulk Reorder Styles */
#bulk-reorder-list {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-sm);
    max-height: 400px;
    overflow-y: auto;
    padding: var(--spacing-sm);
    background: var(--color-bg);
    border-radius: var(--radius-md);
}

.reorder-column-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-md);
    padding: var(--spacing-sm) var(--spacing-md);
    background: var(--color-surface);
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-border);
}

.reorder-column-name {
    flex: 1;
    font-weight: 500;
    color: var(--color-text);
}

.reorder-column-input {
    width: 80px;
    text-align: center;
    font-weight: 600;
}

/* Documentation Styles */
.docs-container {
    display: grid;
    grid-template-columns: 250px 1fr;
    gap: var(--spacing-xl);
    margin-top: var(--spacing-lg);
}

.docs-sidebar {
    position: sticky;
    top: var(--spacing-lg);
    height: fit-content;
    background: var(--color-surface);
    border-radius: var(--radius-md);
    padding: var(--spacing-lg);
    border: 1px solid var(--color-border);
}

.docs-sidebar h3 {
    margin: 0 0 var(--spacing-md) 0;
    font-size: var(--font-size-lg);
    color: var(--color-text);
}

.docs-nav {
    list-style: none;
    padding: 0;
    margin: 0;
}

.docs-nav li {
    margin-bottom: var(--spacing-xs);
}

.docs-nav a {
    display: block;
    padding: var(--spacing-xs) var(--spacing-sm);
    color: var(--color-text-muted);
    text-decoration: none;
    border-radius: var(--radius-sm);
    transition: all 0.2s;
    font-size: var(--font-size-sm);
}

.docs-nav a:hover {
    background: var(--color-bg);
    color: var(--color-primary);
}

.docs-content {
    background: var(--color-surface);
    border-radius: var(--radius-md);
    padding: var(--spacing-xl);
    border: 1px solid var(--color-border);
    max-width: 100%;
    overflow-x: auto;
}

.doc-section {
    margin-bottom: var(--spacing-2xl);
    padding-bottom: var(--spacing-2xl);
    border-bottom: 1px solid var(--color-border);
}

.doc-section:last-child {
    border-bottom: none;
    margin-bottom: 0;
    padding-bottom: 0;
}

.doc-section h2 {
    color: var(--color-text);
    margin-top: 0;
    margin-bottom: var(--spacing-lg);
    font-size: var(--font-size-2xl);
    font-weight: 700;
}

.doc-section h3 {
    color: var(--color-text);
    margin-top: var(--spacing-xl);
    margin-bottom: var(--spacing-md);
    font-size: var(--font-size-xl);
    font-weight: 600;
}

.doc-section h4 {
    color: var(--color-text);
    margin-top: var(--spacing-lg);
    margin-bottom: var(--spacing-sm);
    font-size: var(--font-size-lg);
    font-weight: 600;
}

.doc-section p {
    line-height: 1.7;
    margin-bottom: var(--spacing-md);
    color: var(--color-text);
}

.doc-section ul,
.doc-section ol {
    line-height: 1.8;
    margin-bottom: var(--spacing-lg);
    padding-left: var(--spacing-xl);
    color: var(--color-text);
}

.doc-section li {
    margin-bottom: var(--spacing-xs);
}

.doc-section code {
    background: var(--color-bg);
    padding: 2px 6px;
    border-radius: var(--radius-sm);
    font-family: 'Courier New', monospace;
    font-size: 0.9em;
    color: var(--color-primary);
    border: 1px solid var(--color-border);
}

.doc-section pre {
    background: var(--color-bg);
    padding: var(--spacing-md);
    border-radius: var(--radius-md);
    overflow-x: auto;
    margin: var(--spacing-md) 0;
    border: 1px solid var(--color-border);
}

.doc-section pre code {
    background: none;
    padding: 0;
    border: none;
    color: var(--color-text);
}

.doc-section hr {
    border: none;
    border-top: 1px solid var(--color-border);
    margin: var(--spacing-2xl) 0;
}

.doc-section strong {
    color: var(--color-text);
    font-weight: 600;
}

.doc-section em {
    color: var(--color-text-muted);
}

@media (max-width: 1024px) {
    .docs-container {
        grid-template-columns: 1fr;
    }
    
    .docs-sidebar {
        position: static;
    }
}

/* Responsive adjustments for smaller screens */
@media (max-width: 768px) {
    .data-table {
        min-width: 500px;
        font-size: 0.9em;
    }
    
    .data-table th,
    .data-table td {
        padding: var(--spacing-sm) var(--spacing-md);
    }
    
    .data-table td {
        max-width: 200px;
    }
}

/* Ensure table scrolls smoothly */
.table-responsive::-webkit-scrollbar {
    height: 8px;
}

.table-responsive::-webkit-scrollbar-track {
    background: var(--color-surface);
    border-radius: 4px;
}

.table-responsive::-webkit-scrollbar-thumb {
    background: var(--color-border);
    border-radius: 4px;
}

.table-responsive::-webkit-scrollbar-thumb:hover {
    background: var(--color-primary);
}

.table-responsive {
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}

/* Match app scrollbar styling for top/bottom scroll helpers */
.matrix-scroll-top::-webkit-scrollbar,
.matrix-scroll-body::-webkit-scrollbar,
.reflex-scroll-top::-webkit-scrollbar,
.reflex-scroll-body::-webkit-scrollbar {
    height: 8px;
}

.matrix-scroll-top::-webkit-scrollbar-track,
.matrix-scroll-body::-webkit-scrollbar-track,
.reflex-scroll-top::-webkit-scrollbar-track,
.reflex-scroll-body::-webkit-scrollbar-track {
    background: var(--color-surface);
    border-radius: 4px;
}

.matrix-scroll-top::-webkit-scrollbar-thumb,
.matrix-scroll-body::-webkit-scrollbar-thumb,
.reflex-scroll-top::-webkit-scrollbar-thumb,
.reflex-scroll-body::-webkit-scrollbar-thumb {
    background: var(--color-border);
    border-radius: 4px;
}

.matrix-scroll-top::-webkit-scrollbar-thumb:hover,
.matrix-scroll-body::-webkit-scrollbar-thumb:hover,
.reflex-scroll-top::-webkit-scrollbar-thumb:hover,
.reflex-scroll-body::-webkit-scrollbar-thumb:hover {
    background: var(--color-primary);
}

.matrix-scroll-top,
.matrix-scroll-body,
.reflex-scroll-top,
.reflex-scroll-body {
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}

/* Editor recent-renders table — themed horizontal scroll matching the app. */
.ed-jobs-scroll {
    overflow-x: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}
.ed-jobs-scroll::-webkit-scrollbar {
    height: 8px;
}
.ed-jobs-scroll::-webkit-scrollbar-track {
    background: var(--color-surface);
    border-radius: 4px;
}
.ed-jobs-scroll::-webkit-scrollbar-thumb {
    background: var(--color-border);
    border-radius: 4px;
}
.ed-jobs-scroll::-webkit-scrollbar-thumb:hover {
    background: var(--color-primary);
}

/* ── File Compare: waveform pre-build toolbar + tolerance sliders ──────── */
.fc-wf-toolbar {
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-surface);
    /* Clear separation from the filters / file list that follow so the
       toolbars read as their own block, not crammed against the rows. */
    margin-bottom: 0.85rem;
}
.fc-wf-cat { cursor: pointer; }
.fc-wf-cat-empty { opacity: 0.5; cursor: not-allowed; }
.fc-wf-built { white-space: nowrap; }
.fc-wf-progress {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}
/* The status line carries the current filename — force it onto its own full-width
   line below the bar and let long, space-less filenames break instead of spilling
   out of the (fixed-width) dropdown panel. */
#fc-wf-status, #fc-tr-status {
    flex: 1 1 100%;
    min-width: 0;
    overflow-wrap: anywhere;
    word-break: break-word;
}
.fc-wf-bar {
    flex: 1;
    height: 8px;
    min-width: 120px;
    background: var(--color-border);
    border-radius: 4px;
    overflow: hidden;
}
.fc-wf-bar-fill {
    height: 100%;
    width: 0%;
    background: var(--color-primary);
    border-radius: 4px;
    transition: width 0.3s ease;
}

/* Per-file transcription progress list (name · status tag · mini bar). */
.fc-tr-files {
    margin-top: 8px;
    max-height: 220px;
    overflow-y: auto;
    overscroll-behavior: contain;   /* wheel at the list edge won't scroll the page (which would close the panel) */
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.fc-tr-file {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.8rem;
}
.fc-tr-file-name {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 240px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.fc-tr-file-bar {
    flex: 1;
    height: 6px;
    min-width: 60px;
    background: var(--color-border);
    border-radius: 3px;
    overflow: hidden;
}
.fc-tr-file-bar-fill {
    display: block;
    height: 100%;
    width: 0%;
    background: var(--color-primary);
    border-radius: 3px;
    transition: width 0.3s ease;
}

/* Range sliders for tolerance / hard limit, themed to match the app. */
.fc-range {
    width: 100%;
    accent-color: var(--color-primary);
    cursor: pointer;
    margin: 0.35rem 0;
}

/* ── Editor: Audio cleanup controls ──────────────────────────────────── */
/* Each effect (EQ / compressor / gate / de-noise) is its own bordered
   container so the operator can enable them independently. */
.ed-fx-modules {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 0.75rem;
}
.ed-fx-mod {
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-surface);
    padding: 0.6rem 0.75rem;
}
.ed-fx-mod-head { margin-bottom: 0.35rem; }
.ed-fx-mod .form-label { display: block; margin-top: 0.4rem; }
/* Dim a module whose toggle is off (or master off). */
.ed-fx-mod-off { opacity: 0.55; }
.ed-fx-mod-off .form-label,
.ed-fx-mod-off .fc-range { pointer-events: none; }
.ed-fx-divider {
    border: none;
    border-top: 1px solid var(--color-border);
    margin: 0.85rem 0;
}

/* ── Cloud Upload tab ─────────────────────────────────────────────────── */
.cu-layout { display: flex; flex-direction: column; gap: var(--spacing-md); width: 100%; min-width: 0; }
.cu-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 0.6rem 1rem;
}
.cu-form-wide { grid-column: 1 / -1; }
.cu-pending-list { display: flex; flex-direction: column; gap: 2px; max-height: 38vh; overflow-y: auto; }
.cu-pending-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.5rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    background: var(--color-surface);
}
.cu-pending-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.85rem; }
.cu-dest-grid {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 0.5rem 1rem;
    align-items: start;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-surface);
}
@media (max-width: 720px) { .cu-dest-grid { grid-template-columns: 1fr; } }
.cu-preset-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.75rem;
    font-family: var(--font-mono, monospace);
    padding: 1px 6px;
    border: 1px solid var(--color-border);
    border-radius: 10px;
    color: var(--color-text-muted, #9ca3af);
}
.cu-preset-chip a { color: var(--color-danger, #ef4444); text-decoration: none; }
/* Pending row: checkbox · name · per-file destination select · remove */
.cu-pending-row { display: flex; align-items: center; gap: 0.5rem; }
.cu-pend-dest { width: auto; min-width: 130px; flex-shrink: 0; font-size: 0.8rem; padding: 2px 6px; }
.cu-pend-check { flex-shrink: 0; cursor: pointer; }
/* Media/folder browser modal */
.cu-browse-list { max-height: 52vh; overflow-y: auto; display: flex; flex-direction: column; gap: 2px; }
.cu-browse-row {
    display: flex; align-items: center; gap: 0.5rem;
    padding: 0.25rem 0.5rem; border: 1px solid var(--color-border); border-radius: 6px;
    background: var(--color-surface);
}
.cu-browse-name { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 0.85rem; }

/* Media grid → Cloud Upload selection */
.media-card { position: relative; }
.media-cu-check {
    position: absolute;
    top: 6px; left: 6px;
    z-index: 3;
    display: inline-flex;
    padding: 3px;
    background: rgba(0, 0, 0, 0.45);
    border-radius: 5px;
    cursor: pointer;
}
.media-cu-check input { cursor: pointer; width: 16px; height: 16px; margin: 0; }
.media-cu-bar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.5rem;
    border: 1px solid var(--color-border);
    border-radius: 8px;
    background: var(--color-surface);
}

/* File Compare: upload select checkbox + ☁ uploaded badge */
.fc-upload-check { margin-right: 4px; cursor: pointer; flex-shrink: 0; }
.fc-cloud-built { white-space: nowrap; }

/* ── Editor: keyboard-shortcuts legend ───────────────────────────────── */
.ed-keys-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 0.35rem 0.6rem;
}
/* Each shortcut is its own bordered chip so the keystroke + action read as
   one unit. Kept compact to keep the legend tidy. */
.ed-key-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.25rem 0.5rem;
    border: 1px solid var(--color-border);
    border-radius: 6px;
    background: var(--color-surface);
    font-size: 0.82rem;
}
.ed-keys {
    display: inline-flex;
    gap: 0.2rem;
    flex: 0 0 auto;
    min-width: 70px;
}
.ed-keys-grid kbd,
.ed-shortcuts-hint kbd,
.editor-layout kbd {
    display: inline-block;
    font-family: var(--font-mono, monospace);
    font-size: 0.72em;
    line-height: 1;
    padding: 2px 5px;
    background: var(--color-bg, var(--color-surface));
    border: 1px solid var(--color-border);
    border-bottom-width: 2px;
    border-radius: 4px;
    color: var(--color-text);
    white-space: nowrap;
}

/* Pagination */
.btn-sm[disabled],
.btn-xs[disabled] {
    opacity: 0.4;
    cursor: not-allowed;
    pointer-events: none;
}

.card-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--spacing-md) var(--spacing-lg);
    border-top: 1px solid var(--color-border);
    background: var(--color-surface);
}

/* Log Entries */
.log-entry {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    padding: var(--spacing-md) var(--spacing-lg);
    border-bottom: 1px solid var(--color-border);
    font-size: var(--font-size-sm);
}

.log-entry:last-child {
    border-bottom: none;
}

.log-timestamp {
    color: var(--color-text-muted);
    font-family: var(--font-family-mono);
    font-size: var(--font-size-xs);
    min-width: 120px;
}

.log-message {
    flex: 1;
    color: var(--color-text-primary);
}

/* Modal */
.modal-backdrop {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(4px);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 1000;
    padding: var(--spacing-xl);
}

.modal-backdrop.active {
    display: flex;
}

.modal {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    width: 100%;
    max-width: 500px;
    max-height: 90vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    animation: modal-in 0.2s ease;
}

@keyframes modal-in {
    from {
        opacity: 0;
        transform: scale(0.95) translateY(-10px);
    }
    to {
        opacity: 1;
        transform: scale(1) translateY(0);
    }
}

.modal-header {
    padding: var(--spacing-lg);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.modal-title {
    font-size: var(--font-size-lg);
    font-weight: var(--font-weight-semibold);
}

.modal-body {
    padding: var(--spacing-lg);
    overflow-y: auto;
    flex: 1;
}

.modal-footer {
    padding: var(--spacing-lg);
    border-top: 1px solid var(--color-border);
    display: flex;
    gap: var(--spacing-sm);
    justify-content: flex-end;
}

/* Toast Notifications */
.toast-container {
    position: fixed;
    bottom: var(--spacing-xl);
    right: var(--spacing-xl);
    z-index: 2000;
    display: flex;
    flex-direction: column;
    gap: var(--spacing-sm);
}

.toast {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    padding: var(--spacing-md) var(--spacing-lg);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    animation: slide-in 0.3s ease;
}

@keyframes slide-in {
    from {
        opacity: 0;
        transform: translateX(100%);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

.toast-success { border-left: 3px solid var(--color-success); }
.toast-error { border-left: 3px solid var(--color-danger); }
.toast-warning { border-left: 3px solid var(--color-warning); }
.toast-info { border-left: 3px solid var(--color-info); }

/* ==================== Notification Center (bell) ==================== */
.page-header-end {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
}

.notif-center {
    position: relative;
    flex-shrink: 0;
}

.notif-bell {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--color-text-secondary);
    cursor: pointer;
    transition: background var(--transition-base), color var(--transition-base);
}
.notif-bell:hover {
    background: var(--color-surface-hover);
    color: var(--color-text-primary);
}
.notif-center.open .notif-bell {
    background: var(--color-surface-hover);
    color: var(--color-text-primary);
}

/* Ring animation — added briefly each time a new notification arrives. */
.notif-bell.ringing svg {
    transform-origin: top center;
    animation: bell-ring 0.8s ease;
}
@keyframes bell-ring {
    0%   { transform: rotate(0); }
    15%  { transform: rotate(14deg); }
    30%  { transform: rotate(-12deg); }
    45%  { transform: rotate(10deg); }
    60%  { transform: rotate(-8deg); }
    75%  { transform: rotate(4deg); }
    100% { transform: rotate(0); }
}

.notif-badge {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: var(--color-danger);
    color: #fff;
    font-size: 11px;
    font-weight: var(--font-weight-bold, 700);
    line-height: 18px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--color-bg-secondary);
}

.notif-panel {
    position: absolute;
    top: calc(100% + var(--spacing-sm));
    right: 0;
    width: min(380px, calc(100vw - 32px));
    max-height: min(70vh, 520px);
    display: flex;
    flex-direction: column;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    z-index: 1500;
    overflow: hidden;
    animation: slide-in 0.18s ease;
}
/* The author `display: flex` above beats the UA `[hidden] { display: none }`
   rule, so without this the panel could never collapse. This restores it. */
.notif-panel[hidden] { display: none; }

.notif-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--spacing-md) var(--spacing-lg);
    border-bottom: 1px solid var(--color-border);
    flex-shrink: 0;
}
.notif-panel-title {
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-primary);
}

.notif-list {
    overflow-y: auto;
    padding: var(--spacing-xs);
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}
.notif-list::-webkit-scrollbar { width: 8px; }
.notif-list::-webkit-scrollbar-track { background: var(--color-surface); border-radius: 4px; }
.notif-list::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 4px; }
.notif-list::-webkit-scrollbar-thumb:hover { background: var(--color-primary); }

.notif-item {
    display: flex;
    align-items: flex-start;
    gap: var(--spacing-md);
    padding: var(--spacing-md);
    border-radius: var(--radius-md);
    border-left: 3px solid var(--color-border);
}
.notif-item:hover { background: var(--color-surface-hover); }
.notif-item + .notif-item { margin-top: 2px; }
.notif-item.notif-success { border-left-color: var(--color-success); }
.notif-item.notif-error   { border-left-color: var(--color-danger); }
.notif-item.notif-warning { border-left-color: var(--color-warning); }
.notif-item.notif-info    { border-left-color: var(--color-info); }

.notif-item-icon { font-size: 1.1em; line-height: 1.4; flex-shrink: 0; }
.notif-item-body { flex: 1; min-width: 0; }
.notif-item-msg {
    color: var(--color-text-primary);
    font-size: var(--font-size-sm);
    word-break: break-word;
}
.notif-item-time {
    color: var(--color-text-tertiary, var(--color-text-secondary));
    font-size: var(--font-size-xs);
    margin-top: 2px;
}
.notif-item-dismiss {
    flex-shrink: 0;
    border: none;
    background: transparent;
    color: var(--color-text-secondary);
    cursor: pointer;
    font-size: 1em;
    line-height: 1;
    padding: 2px 4px;
    border-radius: var(--radius-sm);
}
.notif-item-dismiss:hover { color: var(--color-text-primary); background: var(--color-surface); }

.notif-empty {
    padding: var(--spacing-2xl) var(--spacing-lg);
    text-align: center;
    color: var(--color-text-secondary);
    font-size: var(--font-size-sm);
}

/* Repeat-count pill shown when identical alerts are grouped. */
.notif-count {
    display: inline-block;
    margin-left: var(--spacing-xs);
    padding: 0 6px;
    border-radius: 9px;
    background: var(--color-surface-hover);
    color: var(--color-text-secondary);
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    vertical-align: middle;
}

/* Auto-open toggle row in the panel header. */
.notif-setting {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    padding: var(--spacing-sm) var(--spacing-lg);
    border-bottom: 1px solid var(--color-border);
    color: var(--color-text-secondary);
    font-size: var(--font-size-xs);
    cursor: pointer;
    flex-shrink: 0;
}
.notif-setting input { cursor: pointer; margin: 0; }
.notif-setting:hover { color: var(--color-text-primary); }

/* Empty State */
.empty-state {
    text-align: center;
    padding: var(--spacing-2xl);
}

.empty-state-icon {
    font-size: 48px;
    margin-bottom: var(--spacing-lg);
}

.empty-state-title {
    font-size: var(--font-size-xl);
    font-weight: var(--font-weight-semibold);
    margin-bottom: var(--spacing-sm);
}

.empty-state-description {
    color: var(--color-text-muted);
    margin-bottom: var(--spacing-lg);
}

/* Loading */
.loading {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--spacing-2xl);
}

.spinner {
    width: 40px;
    height: 40px;
    border: 3px solid var(--color-border);
    border-top-color: var(--color-primary);
    border-radius: var(--radius-full);
    animation: spin 0.8s linear infinite;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

/* Alert */
.alert {
    padding: var(--spacing-md) var(--spacing-lg);
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    margin-bottom: var(--spacing-lg);
}

.alert-danger {
    background: var(--color-danger-900);
    color: var(--color-danger-light);
    border: 1px solid var(--color-danger);
}

.alert-info {
    background: rgba(59, 130, 246, 0.1);
    color: #93c5fd;
    border: 1px solid rgba(59, 130, 246, 0.3);
}

/* ==================== Login Page ==================== */
.login-page {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
    padding: var(--spacing-xl);
    position: relative;
    overflow: hidden;
}

.login-container {
    position: relative;
    z-index: 1;
}

.login-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-xl);
    padding: var(--spacing-2xl);
    width: 100%;
    max-width: 400px;
    box-shadow: var(--shadow-xl);
    position: relative;
    z-index: 10;
}

.login-header {
    text-align: center;
    margin-bottom: var(--spacing-xl);
}

.logo-large {
    display: flex;
    justify-content: center;
    margin-bottom: var(--spacing-lg);
}

.logo-icon-large {
    width: 80px;
    height: 80px;
    /*background: linear-gradient(135deg, var(--color-primary), var(--color-accent));*/
    border-radius: var(--radius-xl);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: var(--font-weight-bold);
    font-size: var(--font-size-2xl);
    color: white;
    box-shadow: var(--shadow-glow);
}

.login-header h1 {
    font-size: var(--font-size-2xl);
    font-weight: var(--font-weight-bold);
    margin-bottom: var(--spacing-xs);
}

.login-header p {
    color: var(--color-text-muted);
}

.login-form {
    margin-bottom: var(--spacing-lg);
}

.login-footer {
    text-align: center;
}

.default-creds {
    display: none;
    background: var(--color-warning-900);
    border: 1px solid var(--color-warning);
    border-radius: var(--radius-md);
    padding: var(--spacing-md);
    font-size: var(--font-size-sm);
}

.default-creds strong {
    display: block;
    margin-bottom: var(--spacing-xs);
    color: var(--color-warning-light);
}

.default-creds p {
    margin-bottom: var(--spacing-xs);
}

.default-creds small {
    color: var(--color-text-muted);
}

/* Background Animation */
.login-bg {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    overflow: hidden;
    z-index: 0;
}

.gradient-orb {
    position: absolute;
    border-radius: 50%;
    filter: blur(80px);
    opacity: 0.3;
}

.orb-1 {
    width: 600px;
    height: 600px;
    background: var(--color-primary);
    top: -200px;
    right: -100px;
    animation: float 20s ease-in-out infinite;
}

.orb-2 {
    width: 400px;
    height: 400px;
    background: var(--color-accent);
    bottom: -100px;
    left: -100px;
    animation: float 15s ease-in-out infinite reverse;
}

.orb-3 {
    width: 300px;
    height: 300px;
    background: var(--color-success);
    bottom: 30%;
    right: 20%;
    animation: float 18s ease-in-out infinite;
}

@keyframes float {
    0%, 100% { transform: translate(0, 0) scale(1); }
    25% { transform: translate(30px, -30px) scale(1.05); }
    50% { transform: translate(-20px, 20px) scale(0.95); }
    75% { transform: translate(20px, 30px) scale(1.02); }
}

/* ==================== Utility Classes ==================== */
.flex { display: flex; gap: var(--spacing-md); }
.flex-col { flex-direction: column; }
.items-center { align-items: center; }
.justify-between { justify-content: space-between; }
.justify-end { justify-content: flex-end; }
.gap-1 { gap: 0.25rem; }
.gap-2 { gap: var(--spacing-sm); }
.gap-4 { gap: var(--spacing-md); }
.gap-6 { gap: var(--spacing-lg); }
.w-full { width: 100%; }

.mt-4 { margin-top: var(--spacing-md); }
.mt-6 { margin-bottom: var(--spacing-lg); }
.mb-4 { margin-bottom: var(--spacing-md); }
.mb-6 { margin-bottom: var(--spacing-lg); }

.text-center { text-align: center; }
.text-muted { color: var(--color-text-muted); }

/* Grid System */
.grid {
    display: grid;
    gap: var(--spacing-lg);
}

.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.grid-auto { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

/* ==================== Responsive ==================== */
@media (max-width: 1024px) {
    .grid-2, .grid-3, .grid-4 {
        grid-template-columns: 1fr;
    }
}

/* Mobile Menu Button — hidden on desktop */
.mobile-menu-btn {
    display: none;
    background: transparent;
    border: none;
    color: var(--color-text-secondary);
    cursor: pointer;
    padding: var(--spacing-sm);
    border-radius: var(--radius-md);
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    transition: all var(--transition-fast);
}

.mobile-menu-btn:hover {
    background: var(--color-surface-hover);
    color: var(--color-text-primary);
}

/* Mobile Overlay — backdrop behind sidebar when open on mobile */
.mobile-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
    z-index: 99;
    opacity: 0;
    transition: opacity var(--transition-base);
}

.mobile-overlay.active {
    opacity: 1;
}

@media (max-width: 768px) {
    .mobile-menu-btn {
        display: flex;
    }

    .mobile-overlay {
        display: block;
        pointer-events: none;
    }

    .mobile-overlay.active {
        pointer-events: all;
    }

    .sidebar {
        transform: translateX(-100%);
        transition: transform var(--transition-base);
        width: var(--sidebar-width);
    }

    .sidebar.open {
        transform: translateX(0);
    }

    .sidebar.collapsed {
        width: var(--sidebar-width);
    }

    .sidebar.collapsed .logo-text,
    .sidebar.collapsed .nav-text,
    .sidebar.collapsed .user-info,
    .sidebar.collapsed .sidebar-footer .btn {
        opacity: 1;
        width: auto;
        display: flex;
    }

    .sidebar.collapsed .nav-item {
        justify-content: flex-start;
        padding: var(--spacing-md) var(--spacing-lg);
    }

    .sidebar.collapsed .nav-item::after {
        display: none;
    }

    .sidebar-toggle {
        display: none !important;
    }

    .main-content {
        /* The sidebar is transform:translateX(-100%) on mobile (it doesn't
           visually occupy space), so the desktop width clamp that subtracts
           sidebar-width would leave main-content artificially narrow. Reset
           to the full viewport so cards, search inputs, and grids get their
           expected space. */
        margin-left: 0 !important;
        width: 100% !important;
        max-width: 100vw !important;
    }

    .page-header {
        padding: 0 var(--spacing-md);
        height: auto;
        min-height: var(--header-height);
        flex-direction: column;
        align-items: flex-start;
        gap: var(--spacing-sm);
        padding-top: var(--spacing-md);
        padding-bottom: var(--spacing-md);
    }

    .page-header-left {
        width: 100%;
        display: flex;
        align-items: center;
        gap: var(--spacing-sm);
    }

    .page-header-right {
        width: 100%;
        justify-content: space-between;
    }

    /* The flex parent of .page-header-right + the notification bell must also
       stretch, or the column's cross-axis leaves it shrink-wrapped and the bell
       ends up mid-row instead of at the right edge. */
    .page-header-end {
        width: 100%;
        justify-content: space-between;
    }

    .page-header-right > div:has(.badge):after {
        display: none;
    }

    .page-content {
        padding: var(--spacing-md);
    }

    .grid-auto {
        grid-template-columns: 1fr;
    }

    /* ─────────────────────────────────────────────────────────────────
       Mobile responsiveness pass — v3.3.2
       Card grids: drop the 280px minmax floor that forces 1 column at
       ~300px viewport widths but eats horizontal margin. Use full-width
       single column with a max-width cap so very wide phones (tablets)
       still get a sensible card width.
       ───────────────────────────────────────────────────────────────── */
    .obs-cards-grid,
    .video-cards-grid,
    .machines-grid,
    .grid-cards {
        grid-template-columns: 1fr !important;
        gap: var(--spacing-sm);
    }

    .obs-card,
    .video-card {
        padding-right: var(--spacing-md);  /* drop the desktop 34px VU-meter reserve */
        min-width: 0;                       /* let flex/grid shrink content as needed */
    }

    .obs-card-actions-grid {
        grid-template-columns: 1fr 1fr;
    }

    /* Stat cards (CPU, Disk, etc.) — stack to two-column on mobile so
       labels and values stay legible on narrow screens. */
    .obs-card-stats {
        grid-template-columns: 1fr 1fr;
    }

    /* Forms and inputs — fill width, no fixed widths that overflow viewport. */
    .form-input,
    .form-select,
    .search-input {
        width: 100% !important;
        max-width: 100% !important;
        box-sizing: border-box;
    }

    /* Tables that don't fit get horizontal scroll inside their container
       instead of breaking the page layout. */
    .table-container,
    .machines-table-wrapper,
    .data-table {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Modals — full-width on mobile. The backdrop keeps a large desktop padding
       (spacing-xl) that, combined with a 95vw modal, made the dialog wider than
       its padded container on ~360px phones (so it spilled to the edges and got
       clipped) and pushed the header/close button off-screen vertically. Shrink
       the backdrop padding and let the modal fill it. */
    .modal-backdrop {
        padding: var(--spacing-sm);
    }
    .modal {
        width: 100% !important;
        max-width: 100% !important;
        max-height: 92vh;
        margin: 0 auto;
    }
    .modal-body {
        max-height: calc(92vh - 120px);
        overflow-y: auto;
    }

    /* Notification panel — anchored right:0 to the bell, which sits mid-row on
       mobile, so a ~348px panel extended past the left edge and got clipped.
       Pin it across the viewport under the header instead. */
    .notif-panel {
        position: fixed;
        left: 8px;
        right: 8px;
        top: var(--header-height);
        width: auto;
        max-height: 70vh;
    }

    /* The OBS Monitor run-of-show search keeps a fixed px width (the generic
       input reset doesn't target it) — let it fill the row on mobile. */
    .ros-search-input {
        width: 100% !important;
        max-width: 100% !important;
    }

    /* Toasts — cap width and clear the floating help button so they don't
       overlap it or overflow a narrow viewport. */
    .toast-container {
        left: 0.5rem;
        right: 0.5rem;
        bottom: 96px;
    }
    .toast {
        width: 100%;
        max-width: 100%;
        box-sizing: border-box;
    }

    /* Tabs row — let them scroll horizontally instead of wrapping into
       multiple lines that consume vertical space. */
    .tabs {
        overflow-x: auto;
        flex-wrap: nowrap;
        -webkit-overflow-scrolling: touch;
    }
    .tabs .tab {
        flex-shrink: 0;
    }

    /* The Reflex DB Page Builder's three-pane editor (toolbar / canvas /
       props) is too wide for mobile — let the operator scroll horizontally
       to reach each pane instead of trying to compress everything. */
    .pb-editor {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* Extra-narrow screens (< 480px) — tighten further. */
@media (max-width: 480px) {
    .page-content {
        padding: var(--spacing-sm);
    }
    .page-title {
        font-size: 1.25rem;
    }
    .btn-xs {
        font-size: 0.7rem;
        padding: 4px 6px;
    }
    .obs-card-name {
        font-size: 1rem;
    }
}

/* ==================== Bulk Actions / File Upload ==================== */
.file-upload-zone {
    border: 2px dashed var(--color-border-light);
    border-radius: var(--radius-lg);
    padding: var(--spacing-xl);
    text-align: center;
    transition: all var(--transition-base);
    cursor: pointer;
    background: var(--color-bg-secondary);
}

.file-upload-zone:hover {
    border-color: var(--color-primary);
    background: var(--color-primary-900);
}

.file-upload-zone.drag-over {
    border-color: var(--color-primary);
    background: var(--color-primary-900);
    box-shadow: var(--shadow-glow);
    transform: scale(1.02);
}

.file-upload-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--spacing-sm);
}

.file-upload-icon {
    font-size: 3rem;
    margin-bottom: var(--spacing-sm);
}

.file-upload-zone p {
    color: var(--color-text-secondary);
    margin: 0;
}

.file-upload-zone .text-sm {
    font-size: var(--font-size-xs);
}

/* File Preview */
.file-preview {
    margin-top: var(--spacing-lg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
}

.file-preview.hidden {
    display: none;
}

.preview-header {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    padding: var(--spacing-md);
    background: var(--color-bg-tertiary);
    border-bottom: 1px solid var(--color-border);
}

.preview-header .badge {
    flex-shrink: 0;
}

.preview-header .text-muted {
    flex: 1;
}

.preview-table {
    overflow-x: auto;
    max-height: 300px;
    overflow-y: auto;
}

.preview-table table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--font-size-sm);
}

.preview-table th,
.preview-table td {
    padding: var(--spacing-sm) var(--spacing-md);
    text-align: left;
    border-bottom: 1px solid var(--color-border);
    white-space: nowrap;
}

.preview-table th {
    background: var(--color-bg-tertiary);
    color: var(--color-text-secondary);
    font-weight: var(--font-weight-medium);
    position: sticky;
    top: 0;
}

.preview-table tr:hover td {
    background: var(--color-surface-hover);
}

.preview-table td {
    max-width: 200px;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Code tag in cards */
.card-body code {
    background: var(--color-bg-tertiary);
    padding: 2px 6px;
    border-radius: var(--radius-sm);
    font-family: var(--font-family-mono);
    font-size: var(--font-size-xs);
    color: var(--color-accent);
}

/* Card footer alignment */
.card-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--spacing-md);
}

/* ==================== OBS Cards - Compact Uniform Grid ==================== */
.obs-cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(225px, 1fr));
    gap: var(--spacing-md);
    /* Each card sizes to its OWN content. Without this, the grid default
       (align-items: stretch) stretches every card in a row to the tallest
       one — so a collapsed card stays tall and then visibly "snaps" to its
       real height a beat later when the grid re-evaluates track heights
       (as previews load / a scrollbar toggles). start = no stretch, no snap. */
    align-items: start;
}

/* Fixed column-count mode (OBS Gear → Grid Layout). Targets --obs-cols columns
   on wide screens and sizes each card to 1/N of the row. Uses auto-FILL (not
   auto-fit) so empty column slots are RESERVED — with fewer machines than the
   chosen count, each card keeps its 1/N width and the remaining slots stay
   blank (rather than the lone card stretching to full width). Stays responsive
   via the per-card minimum, so narrower screens drop columns automatically (and
   the mobile media query above still forces a single column on phones). Higher
   specificity (.obs-cards-grid.obs-grid-fixed) overrides the auto rule. */
.obs-cards-grid.obs-grid-fixed {
    grid-template-columns: repeat(
        auto-fill,
        minmax(
            max(200px, calc((100% - (var(--obs-cols, 4) - 1) * var(--spacing-md)) / var(--obs-cols, 4))),
            1fr
        )
    );
}

.obs-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--spacing-md);
    padding-right: 34px;   /* make room for the 26px dual VU meter strip */
    display: flex;
    flex-direction: column;
   /* max-height: 370px;*/
}

.obs-card-warning {
    border-color: #f59e0b;
    background: rgba(245, 158, 11, 0.08);
}

.obs-card-danger {
    border-color: #ef4444;
    background: rgba(239, 68, 68, 0.12);
}

.obs-card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: var(--spacing-sm);
    padding-bottom: var(--spacing-sm);
    border-bottom: 1px solid var(--color-border);
    /* Sit above the absolute-positioned VU meter strip */
    position: relative;
    z-index: 10;
    background: inherit;   /* inherits card bg — works for normal, warning, danger variants */
}

.obs-card-header-warning {
    border: 1px solid #f59e0b;
    background: rgba(245, 158, 11, 0.15);
    border-radius: var(--radius-md);
    padding: 6px 8px;
    position: relative;
    z-index: 10;
}

.obs-card-header-danger {
    border: 1px solid #ef4444;
    background: rgba(239, 68, 68, 0.18);
    border-radius: var(--radius-md);
    padding: 6px 8px;
    position: relative;
    z-index: 10;
}

.obs-profile-times-group {
    background: var(--color-bg-secondary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--spacing-md);
    margin-bottom: var(--spacing-md);
}

.obs-profile-times-row {
    display: flex;
    gap: var(--spacing-md);
    margin-bottom: var(--spacing-sm);
}

.obs-profile-times-row:last-child {
    margin-bottom: 0;
}

.obs-profile-time-col {
    flex: 1;
    min-width: 0;
}

.obs-profile-time-col .text-muted {
    margin-bottom: 4px;
}

.obs-profile-time-col > div:not(.text-muted) {
    word-wrap: break-word;
    overflow-wrap: break-word;
}

.obs-card-info {
    flex: 1;
    min-width: 0;
}

.obs-card-name {
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-base);
    color: var(--color-text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.obs-card-ip {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    font-family: var(--font-family-mono);
}

/* Legacy HLS wrapper kept for any existing references */
.obs-inline-video-wrap {
    margin-top: var(--spacing-xs);
    margin-bottom: var(--spacing-xs);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    overflow: hidden;
    background: #000;
    width: 100%;
    position: relative;
    height: 0;
    padding-top: 56.25%;
}
.obs-inline-video {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    background: #000;
}

/* ── WebSocket frame preview ── */
.obs-frame-wrap {
    position: relative;
    width: 100%;
    height: 0;
    padding-top: 56.25%; /* 16:9 */
    background: #000;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    overflow: hidden;
    margin-top: var(--spacing-xs);
    margin-bottom: var(--spacing-xs);
}

.obs-frame-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: #000;
    display: block;
}

.obs-frame-placeholder {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-text-muted);
    font-size: 0.8rem;
    pointer-events: none;
}

.obs-frame-controls {
    position: absolute;
    bottom: 4px;
    right: 4px;
    display: flex;
    gap: 4px;
    opacity: 0;
    transition: opacity 0.15s;
    z-index: 2;
}

.obs-frame-wrap:hover .obs-frame-controls {
    opacity: 1;
}

.obs-frame-fullscreen-btn {
    background: rgba(0, 0, 0, 0.65);
    border: 1px solid rgba(255, 255, 255, 0.25);
    color: #fff;
    border-radius: 4px;
    padding: 2px 6px;
    font-size: 1rem;
    cursor: pointer;
    line-height: 1;
    backdrop-filter: blur(4px);
}
.obs-frame-fullscreen-btn:hover {
    background: rgba(0, 0, 0, 0.9);
}

/* Fullscreen state: fill the screen */
.obs-frame-wrap:fullscreen,
.obs-frame-wrap:-webkit-full-screen {
    height: 100vh;
    width: 100vw;
    padding-top: 0;
    border-radius: 0;
}
.obs-frame-wrap:fullscreen .obs-frame-img,
.obs-frame-wrap:-webkit-full-screen .obs-frame-img {
    object-fit: contain;
}

.obs-card-stats {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--spacing-xs);
    margin-bottom: var(--spacing-sm);
    flex: 1;
    overflow: hidden;
    min-width: 0;
    justify-items: stretch;
}

.obs-stat {
    background: var(--color-bg-secondary);
    border-radius: var(--radius-sm);
    padding: var(--spacing-xs);
    text-align: center;
    overflow: hidden;
    min-width: 0;
}

.obs-stat-span-2 {
    grid-column: span 2;
    max-width: none;
}

.obs-stat-label {
    display: block;
    font-size: 10px;
    color: var(--color-text-muted);
    text-transform: uppercase;
    margin-bottom: 2px;
}

.obs-stat-value {
    display: block;
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.obs-stat-value.good { color: var(--color-success); }
.obs-stat-value.warning { color: var(--color-warning); }
.obs-stat-value.critical { color: var(--color-danger); }

.obs-stat-text {
    font-size: 10px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/* Header "Synapse" button — accent tint so it reads apart from Overflow/Studio.
   (ISO status renders as a normal .obs-stat tile in the stat grid.) */
.obs-synapse-btn {
    color: var(--color-primary);
}

.obs-card-actions {
    display: flex;
    gap: var(--spacing-xs);
    flex-wrap: wrap;
    margin-top: auto;
    flex-direction: column;
}

.obs-card-actions-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--spacing-xs);
    width: 100%;
}

.obs-card-actions-grid .btn {
    width: 100%;
    justify-content: center;
}

.obs-action-span-2 {
    grid-column: span 2;
}

.obs-card-offline {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: var(--spacing-sm);
}

.btn-xs {
    padding: 4px 8px;
    font-size: 11px;
}

.badge-sm {
    padding: 2px 8px;
    font-size: 10px;
}

/* ==================== Tabs ==================== */
.tabs {
    display: flex;
    border-bottom: 2px solid var(--color-border);
    margin-bottom: var(--spacing-lg);
    gap: var(--spacing-xs);
}

.tab {
    padding: var(--spacing-sm) var(--spacing-lg);
    border: none;
    background: transparent;
    color: var(--color-text-secondary);
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    transition: all var(--transition-fast);
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
}

.tab:hover {
    color: var(--color-text-primary);
    background: var(--color-surface-hover);
}

.tab.active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}

/*
 * OBS card "Sync" button.
 * - Off: muted ghost-style pill so it doesn't compete with the primary
 *   action buttons when synced control is unused.
 * - On:  amber/warning fill so it's obvious which machines are wired up
 *   and that any action will cascade to room-mates.
 */
.obs-sync-btn {
    border: 1px dashed var(--color-border, #4b5563);
    font-weight: var(--font-weight-medium, 500);
    letter-spacing: 0.01em;
}
.obs-sync-btn.obs-sync-off {
    background: transparent;
    color: var(--color-text-secondary, #9ca3af);
}
.obs-sync-btn.obs-sync-off:hover {
    color: var(--color-warning, #f59e0b);
    border-color: var(--color-warning, #f59e0b);
    background: rgba(245, 158, 11, 0.06);
}
.obs-sync-btn.obs-sync-on {
    background: var(--color-warning-900, rgba(245, 158, 11, 0.1));
    color: var(--color-warning-light, #fbbf24);
    border-style: solid;
    border-color: var(--color-warning, #f59e0b);
    box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.15) inset;
}
.obs-sync-btn.obs-sync-on::before {
    content: '';
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--color-warning, #f59e0b);
    margin-right: 6px;
    vertical-align: middle;
    box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.25);
}
.obs-sync-btn.obs-sync-on:hover {
    background: rgba(245, 158, 11, 0.18);
}

/*
 * Session-view tabs (Current / Upcoming) on the OBS Monitor.
 * Distinct accent color so they stand out from the regular group tabs
 * even when not active. Uses the warning/amber accent so it visually ties
 * to the same "yellow ending soon" alert that drives the bucket logic.
 */
.tab.tab-session {
    color: var(--color-warning, #f59e0b);
    font-weight: var(--font-weight-semibold, 600);
    position: relative;
}
.tab.tab-session::before {
    content: '';
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--color-warning, #f59e0b);
    margin-right: var(--spacing-xs, 4px);
    vertical-align: middle;
    box-shadow: 0 0 0 2px rgba(245, 158, 11, 0.18);
}
.tab.tab-session:hover {
    color: var(--color-warning, #f59e0b);
    background: rgba(245, 158, 11, 0.08);
}
.tab.tab-session.active {
    color: var(--color-warning, #f59e0b);
    border-bottom-color: var(--color-warning, #f59e0b);
}

.tab-content {
    display: none;
}

.tab-content.active {
    display: block;
    overflow: hidden;
    max-width: 100%;
}

/* Column Resizing - Removed drag resize, now using manual input */

/* Column Drag & Drop */
.data-table thead th[draggable="true"] {
    cursor: move;
}

.data-table thead th.drag-over {
    border-left: 3px solid var(--color-primary);
    background: var(--color-primary-100);
}

/* ==================== Additional Utility Classes ==================== */

/* Card header without bottom padding/border */
.card-header-no-border {
    padding-bottom: 0;
    border-bottom: none;
}

/* Tabs container styles */
.tabs-scrollable {
    margin-bottom: 16px;
    white-space: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    flex-wrap: nowrap;
}

.tabs-scrollable::-webkit-scrollbar {
    height: 8px;
}

.tabs-scrollable::-webkit-scrollbar-track {
    background: var(--color-bg);
}

.tabs-scrollable::-webkit-scrollbar-thumb {
    background: var(--color-border);
    border-radius: var(--radius-sm);
}

.tabs-scrollable::-webkit-scrollbar-thumb:hover {
    background: var(--color-primary);
}

.tabs-scrollable .tab {
    flex-shrink: 0;
}

/* Flexible header with wrapping */
.card-header-flex-wrap {
    flex-wrap: wrap;
    max-width: 100%;
}

/* ROS tab header responsiveness */
#overlay-tab-ros .card-header,
#overlay-tab-ros .card-header-flex-wrap {
    max-width: 100%;
    overflow-x: visible;
}

#overlay-tab-ros .card-header-flex-wrap {
    align-items: flex-start;
    flex-wrap: wrap;
    row-gap: var(--spacing-sm);
}

#overlay-tab-ros .card-body {
    max-width: 100%;
    overflow-x: hidden;
}

#overlay-tab-ros {
    overflow-x: hidden;
}

#overlay-tab-ros .card {
    max-width: 100%;
    overflow-x: hidden;
}

#overlay-tab-ros .ros-timeline-header {
    overflow-x: visible;
}

/* Flex item with min width */
.flex-item-minw-200 {
    flex: 1;
    min-width: 200px;
}

/* Action row with margin */
.action-row-margin {
    margin: 8px 8px;
}

/* Small font text */
.text-small {
    font-size: 0.85em;
}

/* Small form inputs */
.form-input-small {
    width: auto;
    padding: 2px 4px;
    font-size: 0.85em;
}

/* Medium width input */
.form-input-medium {
    width: 160px;
    padding: 2px 4px;
    font-size: 0.85em;
}

/* Clear search button hidden by default */
.clear-search-btn {
    display: none;
}

/* Hidden columns button */
.hidden-cols-btn {
    display: none;
}

/* Pagination footer */
.pagination-footer {
    display: none;
}

/* Card with no margin */
.card-no-margin {
    margin: 0;
}

/* List with no margin */
.list-no-margin {
    margin: 0;
}

/* Notification list styling */
.notification-item-live {
    border-left: 4px solid var(--color-success);
    background: rgba(34, 197, 94, 0.08);
}

.notification-item-upcoming {
    border-left: 4px solid var(--color-primary);
    background: rgba(59, 130, 246, 0.08);
    margin-top: 1rem;
}

.tab-close {
    margin-left: 8px;
    font-weight: 700;
    opacity: 0.6;
}

.tab-close:hover {
    opacity: 1;
}

/* OBS link matrix */
.obs-link-matrix-grid {
    max-height: 420px;
    overflow: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
}

.obs-link-matrix-table {
    width: max-content;
    min-width: 100%;
}

.obs-link-matrix-table .matrix-row {
    display: flex;
    align-items: stretch;
}

.obs-link-matrix-table .matrix-row:nth-child(even) {
    background: rgba(255, 255, 255, 0.02);
}

.obs-link-matrix-table .matrix-cell {
    min-width: 180px;
    width: 180px;
    padding: 8px;
    border-right: 1px solid var(--color-border-light);
    border-bottom: 1px solid var(--color-border-light);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.85rem;
    box-sizing: border-box;
}

.obs-link-matrix-table .matrix-header {
    position: sticky;
    top: 0;
    z-index: 3;
    background: var(--color-bg-tertiary);
}

.obs-link-matrix-table .matrix-header-cell {
    font-weight: 600;
    text-align: center;
    line-height: 1.2;
    word-break: break-word;
}

.obs-link-matrix-table .matrix-sticky-col {
    position: sticky;
    left: 0;
    z-index: 4;
    justify-content: flex-start;
    background: var(--color-bg-tertiary);
}

.obs-link-matrix-table .matrix-checkbox-cell {
    justify-content: center;
}

/* Pagination container */
.pagination-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
}

/* Pagination info text */
.pagination-info {
    font-size: 0.85em;
}

/* Pagination controls */
.pagination-controls {
    display: flex;
    gap: 8px;
    align-items: center;
}

/* Pagination page text */
.pagination-page {
    font-size: 0.9em;
}

/* Table header cell with relative positioning */
.th-resizable {
    position: relative;
    user-select: none;
}

/* Table header content flex */
.th-content {
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* Single-line header — long field names truncate with ellipsis instead
       of wrapping to two lines and adding row height. Horizontal scroll
       reveals the rest, and the full name shows up in the tooltip. */
    white-space: nowrap;
    overflow: hidden;
    gap: 4px;
}

/* Sortable header span */
.th-sortable {
    cursor: pointer;
    flex: 1;
    /* Match the th-content single-line rule and clip with ellipsis. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

/* Sort icon */
.sort-icon {
    font-size: 1.2em;
    opacity: 0.6;
}

/* Column menu button */
.column-menu-btn {
    padding: 0 4px;
    font-size: 1.5rem;
}

/* ──────────────────────────────────────────────────────────────────────────
   Right-click row context menu — Reflex DB tables
   Floats above the page, anchored at the cursor by JS. Items use the same
   surface / border / text vars as other panels so it inherits the theme.
   ────────────────────────────────────────────────────────────────────────── */
/* ──────────────────────────────────────────────────────────────────────────
   File Compare (Media Management tab) + Editor (nav item) — v3.3.2
   Reuses the .card / .form-input / .badge primitives so the look matches
   the rest of ClearView. Only adds the bits that are genuinely new
   (chip lists, mapping grids, file-tech rows, plan summary, etc.).
   ────────────────────────────────────────────────────────────────────────── */
/* .fc-layout lives inside #media-grid which is a CSS grid laid out for
   200px-min media thumbnails. Span the full width so the config card +
   results table get real estate instead of being squeezed into one
   thumbnail-sized column. Side-effect: forcing block layout on the host
   #media-grid would be cleaner, but other code keys off the grid layout
   for the other tabs — so we just claim every column via 1/-1. */
.fc-layout {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-md);
    grid-column: 1 / -1;
    width: 100%;
    min-width: 0;
}

/* When the File Compare tab is active, suppress the media-toolbar
   (search input + grid/list view toggle) and the media-info-bar (the
   "0 B · Upload files to share across the network" footer) — neither
   applies to scan/reconcile results. The breadcrumb is hidden in JS
   already; this CSS handles the rest. */
.media-layout-fc .media-toolbar,
.media-layout-fc .media-info-bar { display: none !important; }
.media-layout-fc #media-grid {
    display: block;       /* drop the thumbnail grid for full-width content */
    padding: 0;
}
.fc-config-grid { display: flex; flex-direction: column; gap: var(--spacing-md); }
.fc-mapping-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--spacing-sm);
}
.fc-tolerance-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--spacing-md);
}
.fc-chip-list {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    min-height: 28px;
    align-items: center;
}
.fc-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--color-surface-hover);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 4px 8px;
    font-size: 0.8rem;
    max-width: 100%;
}
.fc-chip > span:first-child {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    max-width: 320px;
}
.fc-chip-x {
    background: transparent; border: none; color: var(--color-text-secondary);
    cursor: pointer; font-size: 0.85rem; padding: 0 2px;
}
.fc-chip-x:hover { color: #ef4444; }

.fc-table th, .fc-table td { vertical-align: top; }
.fc-file-row {
    display: flex; align-items: center; gap: 10px;
    flex-wrap: wrap; padding: 9px 10px; row-gap: 4px;
    border-bottom: 1px dashed var(--color-border);
    border-radius: 4px;
    transition: background-color 80ms ease;
}
.fc-file-row:last-child { border-bottom: none; }
/* Per-row hover highlight. The previous behavior shaded EVERY file under
   the detail row at once because the global `.data-table tbody tr:hover`
   rule (line 1183) was firing on the parent <tr.fc-session-detail-row>.
   We disable that hover on detail rows below so the individual file row
   can light up on its own. */
.fc-file-row:hover {
    background: var(--color-surface-hover);
}

/* Suppress the global table-row hover for File Compare's detail rows so
   hovering one file inside the expanded block doesn't tint every file
   underneath. The per-file .fc-file-row:hover above takes over. */
.data-table tbody tr.fc-session-detail-row:hover {
    background: transparent;
}
.data-table tbody tr.fc-session-detail-row:hover > td {
    background: var(--color-bg); /* keep the existing detail-cell bg */
}

/* ── ISO sub-folder ──────────────────────────────────────────────────── */
.fc-iso-folder {
    margin-top: 6px;
    border: 1px dashed var(--color-border);
    border-radius: 6px;
    background: var(--color-bg-secondary, transparent);
}
.fc-iso-folder-header {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 6px 8px;
    cursor: pointer;
    user-select: none;
    border-radius: 6px;
}
.fc-iso-folder-header:hover { background: var(--color-surface-hover); }
.fc-iso-folder-icon { font-size: 0.95rem; }
.fc-iso-folder-body {
    padding: 4px 8px 6px;
    border-top: 1px dashed var(--color-border);
}

/* ── Rename modal ────────────────────────────────────────────────────── */
.fc-rename-tabs {
    display: flex;
    gap: 6px;
}
.fc-rename-tab.active { font-weight: 600; }

/* ── Row-presence filter (All / Found / Missing) ─────────────────────── */
/* A segmented button group sitting between the result summary and the
   search row. Only ONE state is active at a time. The Found and Missing
   buttons borrow the success/danger accent colours so the operator can
   tell them apart at a glance. */
.fc-found-filter {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--color-bg-secondary, transparent);
}
.fc-found-btn {
    appearance: none;
    border: none;
    background: transparent;
    color: var(--color-text-secondary);
    padding: 6px 14px;
    font-size: var(--font-size-sm);
    font-weight: 600;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    transition: background-color 80ms ease, color 80ms ease;
}
.fc-found-btn + .fc-found-btn {
    border-left: 1px solid var(--color-border);
}
.fc-found-btn:hover {
    background: var(--color-surface-hover);
    color: var(--color-text-primary);
}
.fc-found-btn.active {
    background: var(--color-surface-hover);
    color: var(--color-text-primary);
}
.fc-found-btn-found.active {
    background: var(--color-success-900, var(--color-surface-hover));
    color: var(--color-success-light, var(--color-text-primary));
}
.fc-found-btn-missing.active {
    background: var(--color-danger-900, var(--color-surface-hover));
    color: var(--color-danger-light, var(--color-text-primary));
}
.fc-found-btn-count {
    display: inline-block;
    min-width: 22px;
    padding: 1px 6px;
    border-radius: 9px;
    background: rgba(0, 0, 0, 0.18);
    font-size: var(--font-size-xs);
    font-weight: 700;
    text-align: center;
    line-height: 1.3;
}

/* ── Kind filter (Show: MAIN / BACKUP / ISO / EDITED) ─────────────────── */
.fc-kind-filter {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    padding: 6px 10px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-bg-secondary, transparent);
}
.fc-kind-filter-label {
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.fc-kind-toggle {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    cursor: pointer;
    user-select: none;
    font-size: var(--font-size-sm);
}
.fc-kind-toggle input { cursor: pointer; }
.fc-kind-toggle-only {
    color: var(--color-info, var(--color-primary));
    font-weight: 600;
}
.fc-kind-sep {
    color: var(--color-text-secondary);
    opacity: 0.4;
    user-select: none;
}

/* ── ✂ Edited badge — clickable, opens metadata-aware playback modal ── */
.fc-edited-badge {
    cursor: pointer;
    transition: filter 80ms ease;
}
.fc-edited-badge:hover { filter: brightness(1.15); }

/* ── Per-file rows in Media → Transfer ────────────────────────────────
   Dedicated layout — does NOT reuse .fc-file-row (which has flex-wrap
   and align-items:center that made things look centered when the row
   couldn't fit, and made the progress bar lose its sized parent).
   Single-line flex: icon · filename (left-aligned, ellipsis) ·
   fixed-width progress bar · fixed-width tail. */
.mt-file-line {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 5px 10px;
    border-left: 3px solid transparent;
    border-bottom: 1px dashed var(--color-border);
    border-radius: 4px;
    transition: background-color 100ms ease, border-color 100ms ease;
}
.mt-file-line:last-child { border-bottom: none; }
.mt-file-icon {
    flex: 0 0 1.2em;
    text-align: center;
    font-size: 0.9em;
    color: var(--color-text-secondary);
}
.mt-file-name {
    flex: 1 1 auto;
    min-width: 0;
    font-family: monospace;
    font-size: 0.85rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: left;
    color: var(--color-text-primary);
}
.mt-file-bar {
    flex: 0 0 180px;
    height: 6px;
    background: rgba(255, 255, 255, 0.08);
    border-radius: 3px;
    overflow: hidden;
}
.mt-file-bar-fill {
    height: 100%;
    width: 0%;
    background: rgba(255, 255, 255, 0.2);
    transition: width 250ms ease, background-color 120ms ease;
}
/* Indeterminate sweep — shown while a file is copying but Robocopy /MT
   isn't reporting a per-file percentage (its multithreaded mode usually
   doesn't). Reads as "working" instead of a stuck empty bar. */
.mt-file-bar-indeterminate {
    position: relative;
}
.mt-file-bar-indeterminate .mt-file-bar-fill {
    width: 35% !important;
    border-radius: 3px;
    background: var(--color-primary, #3b82f6);
    animation: mt-bar-sweep 1.1s ease-in-out infinite;
}
@keyframes mt-bar-sweep {
    0%   { margin-left: -35%; }
    100% { margin-left: 100%; }
}
.mt-file-tail {
    flex: 0 0 110px;
    font-size: 0.8rem;
    text-align: right;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.mt-file-tail-muted { color: var(--color-text-secondary); }
.mt-file-tail-done  { color: var(--color-success, #22c55e); }
.mt-file-tail-pct   { color: var(--color-primary, #3b82f6); font-weight: 600; }
.mt-file-tail-warn  { color: var(--color-warning, #f59e0b); }
.mt-file-tail-err   { color: var(--color-danger, #ef4444); }

/* Status-driven row tint + left rule + bar fill colour. Each state has
   its own subtle background so completed/failed files are visible at a
   glance without needing to read the tail text. */
.mt-file-status-completed {
    background: rgba(34, 197, 94, 0.10);
    border-left-color: var(--color-success, #22c55e);
}
.mt-file-status-completed .mt-file-bar-fill { background: var(--color-success, #22c55e); }

.mt-file-status-failed {
    background: rgba(239, 68, 68, 0.12);
    border-left-color: var(--color-danger, #ef4444);
}
.mt-file-status-failed .mt-file-bar-fill { background: var(--color-danger, #ef4444); }

.mt-file-status-skipped {
    background: rgba(245, 158, 11, 0.10);
    border-left-color: var(--color-warning, #f59e0b);
}
.mt-file-status-skipped .mt-file-bar-fill { background: var(--color-warning, #f59e0b); }

.mt-file-status-retrying {
    background: rgba(245, 158, 11, 0.10);
    border-left-color: var(--color-warning, #f59e0b);
}
.mt-file-status-retrying .mt-file-bar-fill { background: var(--color-warning, #f59e0b); }

.mt-file-status-transferring {
    background: rgba(59, 130, 246, 0.08);
    border-left-color: var(--color-primary, #3b82f6);
}
.mt-file-status-transferring .mt-file-bar-fill { background: var(--color-primary, #3b82f6); }

.mt-file-status-queued {
    border-left-color: var(--color-border);
}
.mt-file-status-queued .mt-file-bar-fill { background: rgba(255, 255, 255, 0.15); }

/* 'unchanged' = file was already at the destination and skipped this run
   (conflictMode=skip). Deliberately muted — NOT the green of a freshly
   copied file — so a rerun's "completed" reads as just the new files. */
.mt-file-status-unchanged {
    border-left-color: var(--color-border);
    opacity: 0.72;
}
.mt-file-status-unchanged .mt-file-icon { color: var(--color-text-secondary); }
.mt-file-status-unchanged .mt-file-bar-fill { background: rgba(255, 255, 255, 0.18); }

/* Narrow screens: drop the fixed widths so things stack instead of
   crushing the name into 2 characters. */
@media (max-width: 760px) {
    .mt-file-bar  { flex: 1 1 100px; }
    .mt-file-tail { flex: 0 0 90px; }
}

/* "▶✂" Play-edited button shown next to the regular ▶ on source rows that
   have on-disk edits. The little scissors mark sits next to the play
   triangle so the operator can scan past the row and see at a glance
   that BOTH original and edited playback are available. */
.fc-play-edited-btn {
    position: relative;
    /* Small border so the ▶✂ reads as its own button alongside the plain ▶. */
    border: 1px solid var(--color-border);
    border-radius: 6px;
}
.fc-play-edited-btn:hover {
    border-color: var(--color-primary);
}
.fc-play-edited-mark {
    font-size: 0.7em;
    margin-left: 2px;
    color: var(--color-info, var(--color-primary));
}

/* ── Source + edit grouping ──────────────────────────────────────────── */
/* Wraps one source file and any of its on-disk edits so they render as a
   single visual unit. The edits sit indented just below the source with
   a left rule, making the parent/child relationship obvious without the
   operator having to expand or click anything. */
.fc-file-group {
    /* No outer border — the underlying .fc-file-row dashed dividers do
       the visual job. We just need an anchor for the indented children. */
}
.fc-file-group + .fc-file-group {
    margin-top: 2px;
}
.fc-edit-children {
    margin-left: 18px;
    padding-left: 10px;
    border-left: 2px solid rgba(59, 130, 246, 0.35);
    /* Tighten the spacing of the nested file rows so the cluster reads
       as one block visually. */
}
.fc-edit-children .fc-file-row {
    padding-top: 3px;
    padding-bottom: 3px;
    border-bottom-style: dotted;
    opacity: 0.95;
}
/* An edit file rendered without a source in the same list (orphan) gets
   a subtle marker so the operator can tell it's not under a parent.
   Currently no visible decoration — the absence of a source row above
   it is its own signal — but the hook is here if we want one later. */
.fc-file-group-orphan-edit .fc-edit-children {
    margin-left: 0;
    padding-left: 0;
    border-left: none;
}

/* ── Edited-playback metadata block ──────────────────────────────────── */
.fc-edited-meta {
    margin-top: 10px;
    display: grid;
    grid-template-columns: 110px 1fr;
    row-gap: 6px;
    column-gap: 12px;
    padding: 10px 12px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}
.fc-edited-meta-row {
    display: contents;
}
.fc-edited-meta-label {
    color: var(--color-text-secondary);
    font-size: var(--font-size-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    align-self: center;
}
.fc-edited-meta-value {
    color: var(--color-text-primary);
    font-size: var(--font-size-sm);
    word-break: break-word;
}
.fc-file-main {
    display: flex; align-items: center; gap: 10px;
    flex: 1; min-width: 220px;
    overflow: hidden;
}
.fc-file-name {
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-family: monospace; font-size: 0.85rem;
}
.fc-file-tech {
    display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
    row-gap: 4px;
}

/* File Compare chip-button variant — used for the "quick-pick from
   external folders" buttons. Same look as a chip but clickable. */
.fc-chip-clickable {
    cursor: pointer;
    background: var(--color-surface-hover);
    color: var(--color-text-primary);
}
.fc-chip-clickable:hover {
    background: var(--color-primary, #3b82f6);
    color: white;
    border-color: var(--color-primary, #3b82f6);
}
.fc-summary {
    padding: 0.6rem 0.8rem;
    margin: var(--font-size-xs);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    font-size: 0.9rem;
    line-height: 1.5;
}

/* Editor */
/* Like .fc-layout, the editor renders into #media-grid (a thumbnail grid).
   Claim the full row + width so it fills the area on first paint instead of
   being squeezed into one thumbnail-sized column until a re-layout. */
.editor-layout {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-md);
    grid-column: 1 / -1;
    width: 100%;
    min-width: 0;
}
.ed-file-tech {
    display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
.ed-trim-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--spacing-md);
}

/* Stage: video + VU side by side. Video flex-grows; VU is fixed-width. */
.ed-stage {
    display: flex;
    gap: 12px;
    align-items: stretch;
}

/* 16:9 wrapper for the editor's main <video>. Locks the frame aspect even
   when no file is loaded so the layout below (waveform/timeline/controls)
   stays in its final position from the very first render. */
.ed-video-wrap {
    position: relative;
    flex: 1;
    min-width: 0;
    aspect-ratio: 16 / 9;
    max-height: 60vh;
    background: #000;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    overflow: hidden;
}
.ed-video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    background: #000;
    /* `object-fit: contain` so non-16:9 sources letterbox instead of
       stretching the inner image — the 16:9 frame is the *container*, the
       video respects its own aspect. */
    object-fit: contain;
}
.ed-video-placeholder {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    pointer-events: none;
}

/* Placeholder visual when the source/file isn't loaded yet: dim and disable
   the cards so it's obvious they're awaiting data, without removing them
   from the layout (the operator sees the editor shape immediately). */
.card.ed-disabled {
    opacity: 0.55;
}
.card.ed-disabled .card-body {
    pointer-events: none;
    user-select: none;
}
.ed-vu {
    display: flex;
    gap: 4px;
    width: 54px;
    flex-shrink: 0;
    background: #0a0a0a;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 4px;
}
/* Two meter bars share the left side; the dB tick scale sits on the right. */
.ed-vu-meters {
    display: flex;
    gap: 4px;
    flex: 1;
}
.ed-vu-scale {
    position: relative;
    width: 18px;
    flex-shrink: 0;
    font-size: 8px;
    line-height: 1;
    color: var(--color-text-muted, #9ca3af);
}
.ed-vu-scale span {
    position: absolute;
    right: 0;
    transform: translateY(50%);
    white-space: nowrap;
}
.ed-vu-scale span::before {
    content: '';
    position: absolute;
    right: 100%;
    top: 50%;
    margin-right: 2px;
    width: 4px;
    border-top: 1px solid var(--color-border);
}
.ed-vu-track {
    flex: 1;
    background: rgba(255, 255, 255, 0.04);
    border-radius: 2px;
    overflow: hidden;
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
.ed-vu-fill {
    width: 100%;
    background: #22c55e;
    transition: height 50ms linear, background 100ms linear;
}

/* Custom timeline with draggable in/out handles. Built from absolutely-
   positioned divs so we get hardware-accelerated movement and clean
   pointer-event handling on each handle. */
.ed-timeline-wrap {
    user-select: none;
}
.ed-timeline {
    position: relative;
    height: 28px;
    cursor: pointer;
}
.ed-tl-base {
    position: absolute; left: 0; right: 0; top: 11px; height: 6px;
    background: rgba(255,255,255,0.08);
    border-radius: 3px;
}
.ed-tl-range {
    position: absolute; top: 11px; height: 6px;
    background: linear-gradient(90deg, rgba(59,130,246,0.55), rgba(59,130,246,0.85));
    border-radius: 3px;
    pointer-events: none;
}
.ed-tl-playhead {
    position: absolute; top: 4px; width: 2px; height: 20px;
    background: #f59e0b;
    transform: translateX(-1px);
    pointer-events: none;
    box-shadow: 0 0 4px rgba(245, 158, 11, 0.7);
}
.ed-tl-handle {
    position: absolute; top: 0;
    width: 14px; height: 28px;
    transform: translateX(-7px);
    cursor: ew-resize;
    border-radius: 3px;
    background: #fb923c;       /* orange — matches "trim points" branding */
    border: 1px solid #c2410c;
    box-shadow: 0 0 0 1px rgba(0,0,0,0.4);
    z-index: 2;
}
.ed-tl-handle::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 6px;
    bottom: 6px;
    width: 2px;
    background: rgba(0,0,0,0.4);
    transform: translateX(-1px);
}
.ed-tl-handle:hover { filter: brightness(1.1); }
.ed-tl-in::before  { content: 'IN';  position: absolute; left: 50%; top: -16px; transform: translateX(-50%); font-size: 0.65rem; font-weight: 700; color: #fb923c; }
.ed-tl-out::before { content: 'OUT'; position: absolute; left: 50%; top: -16px; transform: translateX(-50%); font-size: 0.65rem; font-weight: 700; color: #fb923c; }
.ed-tl-labels {
    display: flex;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 18px;
    font-size: 0.85rem;
    color: var(--color-text-secondary);
}
.ed-tl-labels strong { color: var(--color-text-primary); font-family: monospace; }

/* Generic collapse chevron injected by app.js → enhanceCollapsibleCards.
   Sits at the start of any .card-header that opts in via
   data-collapsible-key="<id>". */
.collapse-chevron {
    display: inline-block;
    width: 14px;
    text-align: center;
    color: var(--color-text-secondary);
    margin-right: 6px;
    font-size: 0.85rem;
    flex-shrink: 0;
}
[data-collapsible-key]:hover .collapse-chevron { color: var(--color-text-primary); }

/* Native-details collapsibles used inside Settings (Server / Appearance
   / Logging / Performance / Licensing tabs). Each <h4> sub-section gets
   wrapped at runtime; this CSS just makes the disclosure chevron feel
   native to the rest of the app. */
.settings-section { margin-bottom: var(--spacing-md); }
.settings-section > .settings-section-summary {
    list-style: none;
    cursor: pointer;
    padding: 6px 0;
    user-select: none;
    display: flex;
    align-items: center;
    gap: 6px;
}
.settings-section > .settings-section-summary::-webkit-details-marker { display: none; }
.settings-section > .settings-section-summary::before {
    content: '▸';
    color: var(--color-text-secondary);
    font-size: 0.85rem;
    transition: transform 120ms ease;
    width: 12px;
    flex-shrink: 0;
}
.settings-section[open] > .settings-section-summary::before { content: '▾'; }
.settings-section > .settings-section-summary:hover::before { color: var(--color-text-primary); }
.settings-section > .settings-section-summary h4 { margin: 0; }

/* Active-render badge — pulses gently so the operator can see at a
   glance that something is in flight without it being distracting. */
.fc-active-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.75rem;
}
.fc-pulse-dot {
    display: inline-block;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    animation: fc-pulse 1.2s ease-in-out infinite;
    flex-shrink: 0;
}
@keyframes fc-pulse {
    0%, 100% { opacity: 0.35; transform: scale(0.85); }
    50%      { opacity: 1;    transform: scale(1.15); }
}

/* File Compare config-card header — title (with collapse chevron) on
   the left, action buttons on the right. */
.fc-config-header {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}
.fc-config-title {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    user-select: none;
}
.fc-config-title:hover .fc-chevron { color: var(--color-text-primary); }
/* Header dropdown panels for 🎵 Build Waveforms and ☁ Cloud Upload (opened
   from the page-header buttons next to Run Scan / Clear results). */
.fc-header-menu {
    position: fixed;
    z-index: 1200;
    min-width: 280px;
    max-width: min(92vw, 440px);
    padding: var(--spacing-md);
    background: var(--color-bg-elevated, var(--color-surface));
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
}
.fc-header-menu .fc-menu-title {
    font-weight: var(--font-weight-medium, 600);
    margin-bottom: 4px;
}
/* Scan summary shown in the config card header — drops onto its own full-width
   line below the title (the header is flex-wrap) and stays visible when the
   card body is collapsed. */
.fc-summary-header {
    flex-basis: 100%;
    width: 100%;
    margin: 0;
}
/* Search field relocated into the Results card header — sits between the
   "Results" title and the right-aligned status badges. */
.fc-results-search {
    flex: 1 1 220px;
    min-width: 160px;
    max-width: 360px;
}
/* Results toolbar: presence tabs (left) + status/expand/collapse/count (right). */
.fc-results-toolbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}
.fc-results-controls {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-left: auto;
}

/* File rows that ARE edit files (separate-row rendering) get a blue
   accent so the operator can spot them inside the expanded block. */
.fc-file-row-edit-file {
    background: rgba(59, 130, 246, 0.10);
    border-left: 3px solid rgba(59, 130, 246, 0.8);
    border-radius: 4px;
    padding-left: 6px;
}

/* File Compare accordion — sessions render as TWO rows in the table:
   one summary <tr.fc-session-row> + one detail <tr.fc-session-detail-row>
   that appears below it when expanded. The detail cell uses colspan=6
   so the file list spans the whole table width. Clicking anywhere on
   the summary row toggles the detail row. */
.fc-accordion-table tbody { /* shared border collapse — handled by .data-table */ }
.fc-session-row-clickable { cursor: pointer; transition: background-color 80ms ease; }
.fc-session-row-clickable:hover { background: var(--color-surface-hover); }
.fc-session-row-open { background: var(--color-surface-hover); }
.fc-session-row-open > td { border-bottom-color: transparent; }
.fc-chevron-cell { text-align: center; width: 32px; }
.fc-chevron {
    color: var(--color-text-secondary);
    font-size: 0.9rem;
    line-height: 1;
}
.fc-chevron-empty { opacity: 0.25; }

/* Room header row — top-level group divider in the hierarchical results. */
.fc-room-header {
    cursor: pointer;
    background: var(--color-bg-secondary, var(--color-surface-hover));
    border-top: 2px solid var(--color-border);
}
.fc-room-header > td {
    padding: 13px 14px !important;
    font-size: 0.95rem;
}
.fc-room-header:hover { background: var(--color-surface-hover); }
.fc-room-header strong { margin-right: 8px; }
.fc-room-header .text-muted { margin-right: 8px; }
.fc-room-header .badge { margin-left: 4px; }

/* Nested rows under a room get a small left indent so the grouping is
   visually obvious. The chevron cell already gives a column of breathing
   room — this just adds a tint band on the leftmost rendered cell. */
.fc-room-child > td:nth-child(2) {
    box-shadow: inset 3px 0 0 var(--color-primary, #3b82f6);
}
.fc-file-count {
    font-weight: 600;
    font-size: 0.85rem;
}
.fc-files-summary-cell {
    display: flex !important;     /* override the default <td> block */
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.fc-session-detail-row > td {
    background: var(--color-bg);
    padding: 14px 18px !important;
    border-top: 1px dashed var(--color-border);
}
.fc-row-files-expanded {
    border-left: 2px solid rgba(59, 130, 246, 0.4);
    padding-left: 14px;
    display: flex; flex-direction: column; gap: 6px;
}

/* Edited-file row highlight (File Compare) — gentle blue tint so the
   operator can spot "already-processed" sessions without it shouting. */
.fc-file-row-edited { background: rgba(59, 130, 246, 0.06); border-radius: 4px; padding-left: 8px; }
.fc-row-edited > td:first-child { border-left: 3px solid rgba(59, 130, 246, 0.6); }

/* Locked file (open in the editor by another operator): amber tint + outline
   so it clearly stands out as "hands off". */
.fc-file-row-locked {
    background: rgba(245, 158, 11, 0.10);
    outline: 1px solid rgba(245, 158, 11, 0.40);
    border-radius: 4px;
    padding-left: 8px;
}
.fc-lock-badge { cursor: default; }

/* Live editor-lock bubble shown on the session line / room header — a rounded
   amber pill with a pulsing dot + the locking user's name. */
.fc-lock-bubble {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: var(--color-warning, #f59e0b);
    color: #1a1a1a;
    border-radius: 999px;
    padding: 2px 9px;
    font-weight: 600;
    white-space: nowrap;
}
.fc-lock-bubble .fc-pulse-dot { background: #1a1a1a; }
/* Your own open editor session — blue, to distinguish from another operator's
   amber lock (which blocks you). */
.fc-lock-bubble-self { background: var(--color-primary, #3b82f6); color: #fff; }
.fc-lock-bubble-self .fc-pulse-dot { background: #fff; }
/* Highlight the whole session line (and room header) when a file in it is
   open in another operator's editor. */
.fc-session-row-locked > td { background: rgba(245, 158, 11, 0.12) !important; }
.fc-session-row-locked > td:first-child { box-shadow: inset 3px 0 0 var(--color-warning, #f59e0b); }
.fc-room-header-locked > td:first-child { box-shadow: inset 3px 0 0 var(--color-warning, #f59e0b); }

/* Editor: trim controls layout — paired Set/Jump button + numeric
   input column for IN and OUT, plus a misc column for Preview / Reset.
   Grid keeps them aligned on desktop and stacks them on narrow screens. */
.ed-trim-controls {
    display: grid;
    grid-template-columns: 1fr 1fr auto;
    gap: var(--spacing-md);
    align-items: start;
}
.ed-trim-side { min-width: 0; }
.ed-trim-num { width: 110px; }
.ed-trim-misc {
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-items: flex-end;
}
.form-label-inline {
    font-size: 0.8rem;
    color: var(--color-text-secondary);
    margin: 0;
    flex-shrink: 0;
    min-width: 38px;
}
@media (max-width: 768px) {
    .ed-trim-controls {
        grid-template-columns: 1fr;
    }
    .ed-trim-misc { align-items: flex-start; }
}

/* Editor card headers — chevron + clickable to collapse. */
.ed-card-header {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    user-select: none;
}
.ed-chevron {
    font-size: 0.85rem;
    width: 1rem;
    display: inline-block;
    text-align: center;
    color: var(--color-text-secondary);
}

/* Synced waveform under the player.
   Canvas + playhead + trim mask layered absolutely. */
/* Waveform zoom control row. */
.ed-wf-zoombar {
    display: flex; align-items: center; gap: 0.5rem;
}
.ed-wf-zoombar input[type="range"] { flex: 1; max-width: 260px; }
.ed-wf-zoombar #ed-wf-zoom-val { min-width: 2.6em; text-align: right; }

/* Fixed-width viewport: the waveform widens INSIDE this (via .ed-waveform-inner
   sized by JS to viewport×zoom), so zooming reveals a themed horizontal
   scrollbar instead of growing the layout. */
.ed-waveform-scroll {
    position: relative;
    background: rgba(0,0,0,0.4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}
.ed-waveform-scroll::-webkit-scrollbar { height: 8px; }
.ed-waveform-scroll::-webkit-scrollbar-track { background: var(--color-surface); border-radius: 4px; }
.ed-waveform-scroll::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 4px; }
.ed-waveform-scroll::-webkit-scrollbar-thumb:hover { background: var(--color-primary); }
.ed-waveform-inner {
    position: relative;
    height: 80px;
    width: 100%;   /* widened to viewport×zoom by _edDrawWaveform() */
    cursor: pointer;
}
.ed-waveform { display: block; width: 100%; height: 80px; }

/* Audio-cleanup preset picker row. */
.ed-fx-presets {
    display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap;
    margin-bottom: 0.25rem;
}
/* Room files panel (editor) — list of the room's captures from File Compare. */
.ed-roomfiles-filters {
    display: flex; gap: 0.85rem; flex-wrap: wrap; margin-bottom: 8px;
}
.ed-roomfiles-list {
    display: flex; flex-direction: column; gap: 2px;
    max-height: 240px; overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}
.ed-roomfile-row {
    display: flex; align-items: center; gap: 10px;
    padding: 6px 8px;
    border-bottom: 1px dashed var(--color-border);
    border-radius: 4px;
}
.ed-roomfile-row:last-child { border-bottom: none; }
.ed-roomfile-row:hover { background: var(--color-surface-hover); }
.ed-roomfile-name {
    flex: 1; min-width: 0;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    font-family: monospace; font-size: 0.85rem;
}
.ed-roomfile-current { background: rgba(59, 130, 246, 0.08); }
/* Session grouping in the room-files panel (mirrors File Compare). */
.ed-room-session { margin-bottom: 8px; }
.ed-room-session-head {
    font-weight: var(--font-weight-medium, 600);
    font-size: 0.82rem;
    padding: 4px 6px;
    position: sticky; top: 0;
    background: var(--color-bg-elevated, var(--color-surface));
    border-bottom: 1px solid var(--color-border);
    z-index: 1;
}
.ed-wf-playhead {
    position: absolute; top: 0; bottom: 0;
    width: 2px; background: #f59e0b;
    transform: translateX(-1px);
    pointer-events: none;
    box-shadow: 0 0 4px rgba(245, 158, 11, 0.7);
}
.ed-wf-trim-mask {
    position: absolute; top: 0; bottom: 0;
    background: rgba(0, 0, 0, 0.55);
    pointer-events: none;
}
.ed-wf-trim-left  { left: 0; width: 0; }
.ed-wf-trim-right { right: 0; width: 0; }
.ed-wf-loading {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    color: var(--color-text-secondary); font-size: 0.85rem;
    pointer-events: none;
}

/* ── Transcript panel (word-level; click-to-seek + karaoke follow) ── */
.ed-tr-toolbar {
    display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
    margin-bottom: 10px;
}
.ed-tr-scroll {
    max-height: 260px; overflow-y: auto;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-bg);
    padding: 10px 12px;
    line-height: 1.9;
}
.ed-tr-line { margin-bottom: 2px; }
.ed-tr-w {
    cursor: pointer;
    padding: 0 1px;
    border-radius: 3px;
    transition: background-color 0.12s ease, color 0.12s ease;
}
.ed-tr-w:hover { background: var(--color-border); }
.ed-tr-active { background: var(--color-primary, #3b82f6); color: #fff; }
.ed-tr-empty { padding: 6px 0; }
.ed-tr-loading { padding: 10px 0; }
.ed-tr-scroll::-webkit-scrollbar { width: 8px; }
.ed-tr-scroll::-webkit-scrollbar-track { background: var(--color-surface); border-radius: 4px; }
.ed-tr-scroll::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 4px; }
.ed-tr-scroll::-webkit-scrollbar-thumb:hover { background: var(--color-primary); }

/* Range slider — match input width and use ClearView primary color. */
input[type="range"]#ed-gain-slider { accent-color: var(--color-primary, #3b82f6); }

/* Auto-edit details block — disclosure-style so it doesn't dominate. */
.ed-auto {
    margin-top: var(--spacing-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: 10px;
    background: var(--color-bg);
}
.ed-auto > summary {
    cursor: pointer;
    font-weight: 600;
    user-select: none;
}
.ed-plan {
    margin-top: 8px;
    padding: 10px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-bg);
}
.ed-readonly {
    background: var(--color-bg); color: var(--color-text-primary);
    cursor: default;
}
.ed-auto-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: var(--spacing-md);
}
.ed-output-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: var(--spacing-md);
    /* Extra breathing room between the output settings grid and the
       render-button row that sits beneath it. */
    margin-bottom: var(--spacing-lg);
}
/* Bottom padding on the entire Render Output card body so the render
   button + overwrite checkbox don't crowd the card's lower edge. */
[data-card-body="output"] {
    padding-bottom: var(--spacing-lg);
}
.ed-overwrite-cell { grid-column: 1 / -1; }
.ed-overwrite-inline {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.85rem;
}
.ed-job-progress .progress-bar {
    background: var(--color-bg); border: 1px solid var(--color-border);
    border-radius: var(--radius-sm); height: 8px; overflow: hidden;
}
.ed-job-progress .progress-fill {
    height: 100%;
    background: var(--color-primary, #3b82f6);
    transition: width var(--transition-base);
}

@media (max-width: 768px) {
    .fc-mapping-grid, .ed-trim-row, .ed-auto-grid, .ed-output-grid, .fc-tolerance-grid {
        grid-template-columns: 1fr;
    }
}

.overlay-row-context-menu {
    position: fixed;
    z-index: 10000;
    min-width: 180px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
    padding: 4px;
    display: flex;
    flex-direction: column;
    font-size: 0.875rem;
    user-select: none;
}
.overlay-row-context-item {
    background: transparent;
    border: none;
    color: var(--color-text-primary);
    padding: 8px 12px;
    text-align: left;
    cursor: pointer;
    border-radius: var(--radius-sm);
    display: flex;
    align-items: center;
    gap: 8px;
    transition: background var(--transition-fast);
}
.overlay-row-context-item:hover {
    background: var(--color-surface-hover);
}
.overlay-row-context-item.danger {
    color: #ef4444;
}
.overlay-row-context-item.danger:hover {
    background: rgba(239, 68, 68, 0.12);
}

/* Checkbox cell fixed width. Widened in v3.3.2 so the "Go Live" header
   text fits on a single line alongside the column-options ▾ button —
   80px was clipping the label after the single-line header rule landed. */
.checkbox-cell-fixed {
    width: 110px;
    min-width: 110px;
}

/* Actions cell - admin */
.actions-cell-admin {
    width: 140px;
}

/* Actions cell - regular */
.actions-cell-regular {
    width: 50px;
}

/* Table cell with ellipsis */
.td-ellipsis {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Column width input */
.column-width-input {
    width: 120px;
}

/* Column value list */
.column-value-list {
    max-height: 200px;
    overflow-y: auto;
    border: 1px solid var(--color-border);
    padding: 6px;
    border-radius: 4px;
}

/* View item modal content */
.view-item-content {
    max-height: 500px;
    overflow-y: auto;
}

/* View item table */
.view-item-table {
    width: 100%;
}

/* View item table cells */
.view-item-th-field {
    width: 40%;
}

.view-item-th-value {
    width: 60%;
}

/* Hidden row background */
.hidden-row-bg {
    background: rgba(255, 193, 7, 0.1);
}

/* Hidden badge with margin */
.badge-with-margin {
    margin-left: 8px;
}

/* Word wrap cell */
.td-word-wrap {
    word-wrap: break-word;
    word-break: break-word;
    white-space: pre-wrap;
}

/* View item footer text */
.view-item-footer {
    margin-top: 12px;
    font-size: 0.85em;
}

/* Warning color text */
.text-warning-color {
    color: var(--color-warning);
}

/* Icon legend */
.icon-legend {
    display: flex;
    align-items: center;
    gap: var(--spacing-lg);
    padding: var(--spacing-sm) var(--spacing-md);
    background: var(--color-bg-tertiary);
    border-radius: var(--radius-md);
    font-size: var(--font-size-xs);
}

.legend-item {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
    color: var(--color-text-muted);
}

.legend-item img {
    width: 16px;
    height: 16px;
    filter: invert(0.7);
}

/* Flex with wrap */
.flex-wrap-enabled {
    flex-wrap: wrap;
}

/* Font weight semibold */
.font-semibold {
    font-weight: 600;
}

/* Update DB fields hidden */
.update-db-fields-hidden {
    display: none;
}

/* Key field group hidden */
.key-field-group-hidden {
    display: none;
}

/* Scrollable log content */
.log-content-scrollable {
    max-height: 400px;
    overflow-y: auto;
}

/* Log entry with flex */
.log-entry-flex {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

/* Timestamp text */
.timestamp-text {
    font-size: 11px;
}

/* Grid column widths */
.grid-col-1-3 {
    grid-column: 1 / 3;
}

.grid-col-2-3 {
    grid-column: 2 / 3;
}

/* Width utilities */
.w-50 {
    width: 50%;
}

.w-48 {
    width: 48%;
}

.w-auto {
    width: auto;
}

/* Max width utilities */
.max-w-180 {
    max-width: 180px;
}

/* Margin utilities */
.mr-1 {
    margin-right: 0.25rem;
}

.ml-1 {
    margin-left: 0.25rem;
}

.mt-1 {
    margin-top: 0.25rem;
}

.mt-2 {
    margin-top: 0.5rem;
}

.mb-2 {
    margin-bottom: 0.5rem;
}

/* Padding utilities */
.p-0 {
    padding: 0;
}

.p-1 {
    padding: 0.25rem;
}

.p-2 {
    padding: 0.5rem;
}

/* Min width utilities */
.min-w-100 {
    min-width: 100px;
}

.min-w-120 {
    min-width: 120px;
}

.min-w-150 {
    min-width: 150px;
}

.min-w-200 {
    min-width: 200px;
}

/* Warning box */
.warning-box {
    background: var(--color-warning-900);
    border-radius: var(--radius-md);
    padding: var(--spacing-md);
}

/* Info box */
.info-box {
    background: var(--color-bg-secondary);
    border-radius: var(--radius-md);
    padding: var(--spacing-md);
}

/* Transfer progress */
.transfer-progress-hidden {
    display: none;
    margin-top: var(--spacing-md);
}

/* Progress fill width */
.progress-fill-zero {
    width: 0%;
}

/* Transfer file list */
.transfer-file-list {
    margin-top: var(--spacing-sm);
    max-height: 200px;
    overflow-y: auto;
    font-size: var(--font-size-sm);
}

/* Transfer list item */
.transfer-list-item {
    padding: 4px 0;
    border-bottom: 1px solid var(--color-border);
}

/* Watch Agent cards */
/* ── Watch Agents Modal ── */

.wa-modal-toolbar {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
    margin-bottom: var(--spacing-md);
    flex-wrap: wrap;
}

.wa-modal-search {
    flex: 1;
    min-width: 160px;
}

.wa-modal-stats {
    display: flex;
    gap: var(--spacing-sm);
    align-items: center;
    flex-shrink: 0;
}

.wa-stat-pill {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    background: var(--color-bg-tertiary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-full);
    padding: 3px 10px;
    white-space: nowrap;
}

.wa-stat-pill-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    flex-shrink: 0;
}

.wa-stat-pill-dot.online  { background: var(--color-success); }
.wa-stat-pill-dot.offline { background: var(--color-text-muted); }

/* Grid */
.wa-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: var(--spacing-md);
}

/* Card */
.wa-card {
    background: var(--color-bg-secondary);
    border: 1px solid var(--color-border);
    border-left: 3px solid var(--color-border);
    border-radius: var(--radius-md);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transition: border-color 0.2s;
}

.wa-card.online  { border-left-color: var(--color-success); }
.wa-card.offline { border-left-color: var(--color-text-muted); }

/* Card header */
.wa-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--spacing-sm) var(--spacing-md);
    background: var(--color-bg-tertiary);
    border-bottom: 1px solid var(--color-border);
    gap: var(--spacing-sm);
    flex-wrap: wrap;
}

.wa-card-name {
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-sm);
    color: var(--color-text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wa-card-badges {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}

/* Key-value rows */
.wa-card-body {
    padding: var(--spacing-sm) var(--spacing-md);
    display: flex;
    flex-direction: column;
    gap: 0;
    flex: 1;
}

.wa-row {
    display: flex;
    align-items: baseline;
    gap: var(--spacing-sm);
    padding: 4px 0;
    border-bottom: 1px solid var(--color-border);
    min-width: 0;
}

.wa-row:last-child {
    border-bottom: none;
}

.wa-label {
    color: var(--color-text-muted);
    font-size: 11px;
    font-weight: var(--font-weight-medium);
    min-width: 76px;
    flex-shrink: 0;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.wa-val {
    color: var(--color-text-secondary);
    font-size: var(--font-size-sm);
    word-break: break-all;
    min-width: 0;
    flex: 1;
}

.wa-val.mono {
    font-family: var(--font-family-mono);
    font-size: 11px;
}

/* Transfer progress section */
.wa-progress-section {
    padding: var(--spacing-sm) var(--spacing-md);
    border-top: 1px solid var(--color-border);
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.wa-progress-label {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 11px;
}

.wa-progress-status { color: var(--color-text-primary); font-weight: 500; }
.wa-progress-pct    { color: var(--color-text-muted); }

.wa-progress-track {
    height: 5px;
    background: var(--color-bg-tertiary);
    border-radius: var(--radius-full);
    overflow: hidden;
}

.wa-progress-fill {
    height: 100%;
    border-radius: var(--radius-full);
    background: linear-gradient(90deg, var(--color-primary) 0%, var(--color-accent) 100%);
    transition: width 0.4s ease;
}

.wa-progress-file {
    font-size: 11px;
    color: var(--color-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.wa-progress-error {
    font-size: 11px;
    color: var(--color-danger);
}

/* Actions */
.wa-card-actions {
    display: flex;
    align-items: center;
    gap: 5px;
    padding: var(--spacing-sm) var(--spacing-md);
    border-top: 1px solid var(--color-border);
    flex-wrap: wrap;
    background: var(--color-bg-tertiary);
}

.wa-card-actions-spacer {
    flex: 1;
}

/* Empty state */
.wa-empty {
    text-align: center;
    padding: var(--spacing-xl);
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
}

/* Legacy class aliases — kept so old code that may reference them doesn't break */
.watch-agent-grid  { display: none; }
.watch-agent-card  { display: none; }

/* Raw output pre */
.raw-output-pre {
    background: var(--color-neutral-900);
    padding: var(--spacing-md);
    border-radius: var(--radius-md);
    overflow-x: auto;
    font-size: 12px;
}

/* OBS specific */
.obs-indicator-flex {
    display: flex;
    gap: 6px;
    align-items: center;
}

.obs-actions-flex {
    display: flex;
    gap: var(--spacing-sm);
    align-items: center;
}

.obs-collapse-btn {
    position: absolute;
    top: var(--spacing-sm);
    right: var(--spacing-sm);
    z-index: 10;
}

/* Vertical dual-channel VU meter — right edge of card */
.obs-vu-top {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    /* Widened to fit OBS-style dB tick labels on the left edge of the strip.
       Originally 26px; +18px for the tick column. */
    width: 44px;
    z-index: 9;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    padding: 4px 3px 4px 3px;
    gap: 2px;
}
/* The "Input VU Meter" card-pref toggle adds .hidden to the VU strip.
   Without an explicit CSS rule, the class did nothing and the bars
   stayed visible. Override with !important to win against the inline
   `display:flex` on `.obs-vu-top`. Also nudge the card-padding back so
   text isn't cramped against the right edge when the bars are gone. */
.obs-vu-top.hidden { display: none !important; }
.obs-card:has(.obs-vu-top.hidden) { padding-right: var(--spacing-md); }

/* ===== Collapsed card: VU strip matches the preview-frame height =====
   When collapsed WITH the inline preview on, the frame + VU sit in a flex row
   so the VU is only as tall as the 16:9 frame (instead of spanning the whole
   card). Name/IP and the actions row are unchanged. */
.obs-collapsed-vufit {
    /* The VU is now in-flow inside the row, so drop the card's right reserve. */
    padding-right: var(--spacing-md);
}
.obs-collapsed-row {
    display: flex;
    align-items: flex-start;
    margin-top: var(--spacing-xs);
    /* Positioning context for the absolutely-placed VU strip below. */
    position: relative;
}
.obs-collapsed-row .obs-frame-wrap {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    /* Reserve room on the right for the out-of-flow VU strip (44px + 4px gap). */
    margin-right: 48px;
    /* Use a real aspect-ratio box instead of the base padding-top:56.25% hack.
       In a flex row the padding-% is resolved against the ROW's width (the
       containing block), not the frame's own narrower width, so the frame came
       out slightly too tall and shifted as the grid column width settled ~1s
       after collapse. aspect-ratio derives height from the frame's OWN final
       width, so it's correct and stable from first paint. */
    height: auto;
    padding-top: 0;
    aspect-ratio: 16 / 9;
}
/* VU strip is absolutely positioned and pinned top→bottom of the row (whose
   height equals the frame's), so it always matches the frame height and can
   NEVER grow the card when its bars/ticks populate a second or two after
   collapse. (Previously it was in-flow with align-self:stretch, which let its
   populated content expand the flex row → the card jumped taller.) */
.obs-collapsed-vufit .obs-vu-top {
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    left: auto;
    width: 44px;
    flex: none;
    align-self: auto;
}

/* Row holding the dB-tick scale + both L + R bars side by side. Positioned
   relative so each .obs-vu-tick can anchor by `bottom: X%` against the bar
   travel range. */
.obs-vu-bars {
    display: flex;
    flex-direction: row;
    align-items: flex-end;
    gap: 2px;
    flex: 1;
    width: 100%;
    position: relative;
}

/* Vertical column of dB tick labels (OBS-style scale). Sits to the LEFT of
   the L/R bars. Each label is absolute-positioned by `bottom: X%` so it
   tracks the same -60..0 dB → 0..100% mapping the bars use. */
.obs-vu-ticks {
    position: relative;
    width: 16px;
    height: 98%;
    flex: 0 0 16px;
    margin-right: 1px;
}
.obs-vu-tick {
    position: absolute;
    right: 0;
    font-size: 7px;
    line-height: 1;
    color: var(--color-text-primary);
    opacity: 0.7;
    /* Center the label vertically on its dB position, but clamp at the
       extremes so the "0" and "-60" labels aren't half-cut at the edges. */
    transform: translateY(50%);
    pointer-events: none;
    white-space: nowrap;
    letter-spacing: -0.3px;
}
.obs-vu-tick[style*="bottom:100%"] { transform: translateY(0); }
.obs-vu-tick[style*="bottom:0%"]   { transform: translateY(100%); }

/* File Compare ↔ Active-transfer panel rows. Lives above the results
   table and shows per-machine progress while transfers are in flight. */
.fc-xfer-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px 8px;
  border: 1px solid var(--color-border);
  border-radius: 6px;
  background: var(--color-surface);
}
.fc-xfer-bar {
  height: 6px;
  background: rgba(255, 255, 255, 0.08);
  border-radius: 3px;
  overflow: hidden;
}
.fc-xfer-fill {
  height: 100%;
  background: linear-gradient(90deg, #22c55e, #3b82f6);
  border-radius: 3px;
  transition: width 200ms linear;
}

/* OBS Monitor health-alert badge — gentle pulse so it pulls the eye
   without strobing. Clickable; opens the alert config modal. */
.obs-health-badge {
  cursor: pointer;
  animation: obs-health-pulse 1.6s ease-in-out infinite;
}
@keyframes obs-health-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.55); }
  50%      { box-shadow: 0 0 0 4px rgba(239, 68, 68, 0.10); }
}

.obs-vu-track {
    width: 8px;
    flex: 1;
    border-radius: 3px;
    background: rgba(255, 255, 255, 0.10);
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.08);
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    height: 100%;
}

.obs-vu-fill {
    width: 100%;
    height: 0%;
    transition: height 180ms linear;
    background: linear-gradient(0deg, #22c55e 0%, #f59e0b 70%, #ef4444 100%);
    border-radius: 3px 3px 0 0;
}

/* Horizontal dB label — landscape, no rotation */
.obs-vu-db {
    font-size: 8px;
    color: var(--color-text-muted);
    line-height: 1.2;
    white-space: nowrap;
    text-align: center;
    letter-spacing: -0.3px;
    /* Breathing room so the value doesn't overlap the bars / bottom tick. */
    padding: 4px 2px 2px;
    margin-top: 2px;
}

.obs-card {
    position: relative;
}

.obs-card.collapsed {
    position: relative;
}

/* Body section below the header — VU is positioned relative to this */
.obs-card-body {
    position: relative;
    /* Extend right to the card's inner-right border so the VU strip
       stays at the card edge, not the content edge */
    margin-right: -34px;
    padding-right: 45px;
    flex: 1;
}

/* Scene/Profile list */
.scene-profile-list {
    max-height: 400px;
    overflow-y: auto;
}

/* OBS Monitor top-nav legend key (reuses .dash-obs-key dot styling). */
.obs-legend-key {
    margin-left: var(--spacing-sm);
    padding-left: var(--spacing-sm);
    border-left: 1px solid var(--color-border);
}

/* ==================== Studio (preview / program monitor) ==================== */
.obs-studio { display: flex; flex-direction: column; gap: var(--spacing-md); }
.obs-studio-stage {
    display: flex;
    align-items: stretch;
    gap: var(--spacing-md);
}
.obs-studio-pane {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.obs-studio-pane-label {
    font-size: var(--font-size-xs);
    font-weight: var(--font-weight-semibold);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-secondary);
}
.obs-studio-pane-label.live { color: var(--color-danger); }
.obs-studio-pane-label.preview { color: var(--color-success); }
.obs-studio-img-wrap {
    aspect-ratio: 16 / 9;
    background: #000;
    border: 2px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}
.obs-studio-pane:has(.preview) .obs-studio-img-wrap { border-color: var(--color-success); }
.obs-studio-pane:has(.live) .obs-studio-img-wrap { border-color: var(--color-danger); }
.obs-studio-img { width: 100%; height: 100%; object-fit: contain; display: none; }
.obs-studio-scene-name {
    font-size: var(--font-size-sm);
    color: var(--color-text-primary);
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.obs-studio-take {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    padding: 0 var(--spacing-sm);
}
.obs-studio-scenes {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: var(--spacing-sm);
    max-height: 320px;
    overflow-y: auto;
    padding-top: 2px;
}
.obs-studio-scene-btn {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 6px;
    background: var(--color-surface);
    border: 2px solid var(--color-border);
    border-radius: var(--radius-md);
    cursor: pointer;
    text-align: center;
    transition: border-color var(--transition-base);
}
.obs-studio-scene-btn:hover { border-color: var(--color-text-secondary); }
.obs-studio-scene-btn.preview-active { border-color: var(--color-success); }
.obs-studio-scene-btn.live-active { box-shadow: inset 0 0 0 2px var(--color-danger); }
.obs-studio-scene-thumb-wrap {
    aspect-ratio: 16 / 9;
    background: #000;
    border-radius: 4px;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}
.obs-studio-scene-thumb { width: 100%; height: 100%; object-fit: contain; }
.obs-studio-scene-cap {
    font-size: var(--font-size-xs);
    color: var(--color-text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.scene-profile-item {
    cursor: pointer;
}

.scene-profile-item-active {
    background: var(--color-primary-900);
}

.scene-profile-item-name {
    flex: 1;
}

/* Info text box */
.info-text-box {
    background: var(--color-info-900);
    padding: var(--spacing-sm);
    border-radius: var(--radius-sm);
}

/* Logs specific */
.filters-flex {
    display: flex;
    gap: var(--spacing-md);
    flex-wrap: wrap;
}

.filter-item {
    min-width: 150px;
    margin: 0;
}

.filter-item-search {
    flex: 1;
    min-width: 200px;
    margin: 0;
}

.filter-item-button {
    margin: 0;
    align-self: flex-end;
}

/*
 * Logs page action toolbar — keeps Clear Filters / Export / Upload to
 * Licensing / Clear Logs the same height + spacing regardless of the
 * inline icons that some of them once had. The Clear Logs separator
 * pushes the destructive action to the right edge so it's harder to
 * mis-click while doing routine exports.
 */
.log-actions-toolbar {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm, 8px);
    flex-wrap: wrap;
}
.log-actions-toolbar .log-action-btn {
    height: 32px;
    min-width: 116px;
    padding: 0 var(--spacing-md, 12px);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    white-space: nowrap;
}
.log-actions-toolbar .log-action-separator {
    flex: 1 0 auto;
    min-width: var(--spacing-md, 12px);
}

.transfer-entry {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--spacing-sm);
}

.transfer-header {
    display: flex;
    justify-content: space-between;
    width: 100%;
    align-items: center;
}

.transfer-body {
    width: 100%;
}

.transfer-progress-bar {
    height: 20px;
    margin-bottom: var(--spacing-xs);
}

.transfer-stats {
    display: flex;
    justify-content: space-between;
    font-size: var(--font-size-sm);
}

.transfer-details {
    width: 100%;
    font-size: var(--font-size-sm);
}

.transfer-throughput {
    margin-top: var(--spacing-xs);
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
}

.transfer-error {
    margin-top: var(--spacing-xs);
}

.log-detail-value {
    background: var(--color-neutral-900);
}

.warning-icon-large {
    font-size: 3rem;
    margin-bottom: var(--spacing-md);
}

/* Video Cards Grid */
.video-cards-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
    gap: 1.5rem;
}

.video-card {
    background: var(--card-bg);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    overflow: hidden;
    transition: transform 0.2s, box-shadow 0.2s;
}

.video-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}

.video-card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem;
    border-bottom: 1px solid var(--border-color);
    background: var(--bg-secondary);
}

.video-card-info {
    flex: 1;
}

.video-card-name {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 0.25rem;
}

.video-card-ip {
    font-size: 0.875rem;
    color: var(--text-muted);
    font-family: var(--font-mono);
}

.video-player-container {
    position: relative;
    width: 100%;
    flex: 1;
    min-width: 0;
    background: #000;
    overflow: hidden;
}

.video-player-container::before {
    content: "";
    display: block;
    padding-top: 56.25%; /* 16:9 aspect ratio */
}

.video-player {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.video-placeholder {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: var(--text-muted);
    font-size: 0.875rem;
    text-align: center;
}

.video-loading {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    color: var(--text-primary);
    font-size: 0.875rem;
    text-align: center;
    background: rgba(0, 0, 0, 0.8);
    padding: 0.5rem 1rem;
    border-radius: 4px;
}

/* Toggle Switch */
.toggle-with-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.toggle-label {
  font-size: 0.875rem;
  color: var(--text-muted);
  font-weight: 500;
  min-width: 60px;
}

.toggle-switch {
  position: relative;
  display: inline-block;
  width: 48px;
  height: 24px;
  cursor: pointer;
}

.toggle-switch input {
  opacity: 0;
  width: 0;
  height: 0;
}

.toggle-switch input:disabled {
  cursor: not-allowed;
}

.toggle-slider {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: var(--color-text-muted);
  transition: 0.3s;
  border-radius: 24px;
}

.toggle-slider:before {
  position: absolute;
  content: "";
  height: 18px;
  width: 18px;
  left: 3px;
  bottom: 3px;
  background-color: white;
  transition: 0.3s;
  border-radius: 50%;
}

.toggle-switch input:checked + .toggle-slider {
  background-color: var(--color-success);
}

.toggle-switch input:checked + .toggle-slider:before {
  transform: translateX(24px);
}

.toggle-switch input:focus + .toggle-slider {
  box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2);
}

.toggle-loading {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.1);
  border-radius: 24px;
  z-index: 1;
}

.spinner {
  width: 16px;
  height: 16px;
  border: 2px solid rgba(255, 255, 255, 0.3);
  border-top-color: white;
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

@keyframes spin {
  to { transform: rotate(360deg); }
}

/* Video Controls Group */
.video-controls-group {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.video-url-btn {
  padding: 0.25rem 0.5rem;
  font-size: 1rem;
  line-height: 1;
}

/* Video Content Container */
.video-content-container {
  display: flex;
  gap: 0.5rem;
  width: 100%;
}

/* VU Meter */
.vu-meter-container {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  /* gap: 0.5rem; */
  /* padding: 0.2rem 0.5rem; */
  background: var(--bg-secondary);
  /* min-width: 120px; */
  flex-shrink: 0;
}

.vu-meter-channel {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.vu-meter-canvas {
  width: 40px;
  height: 200px;
  border: 2px solid var(--primary-color);
  border-radius: 4px;
  background: #1a1a1a;
  margin: 0 4px;
}

.vu-meter-label {
  font-size: 0.75rem;
  color: var(--text-muted);
  text-align: center;
  font-weight: 600;
  letter-spacing: 0.05em;
}

.vu-meter-status {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 0.75rem;
  color: var(--text-muted);
  background: rgba(0, 0, 0, 0.7);
  padding: 4px 8px;
  border-radius: 4px;
  white-space: nowrap;
}

/* Video Preview Modal */
.video-preview-container {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.video-preview-info {
  padding: 0.5rem 0;
  font-size: 1rem;
  color: var(--text-color);
}

.video-preview-player {
  position: relative;
  width: 100%;
  max-width: 800px;
  aspect-ratio: 16 / 9;
  background: #000;
  border-radius: 8px;
  overflow: hidden;
  margin: 0 auto;
}

.video-preview-player .video-player {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.video-preview-player .video-loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #fff;
  font-size: 1rem;
  text-align: center;
}

.video-preview-footer {
  width: 100%;
  max-width: 800px;
  padding-top: 0.5rem;
  border-top: 1px solid var(--color-border);
}

/* Stage: player on the left, VU strip on the right */
.video-preview-stage {
  display: flex;
  gap: 0.5rem;
  align-items: stretch;
  width: 100%;
  max-width: 854px;  /* 800px player + 44px VU + 10px gap */
  margin: 0 auto;
}
.video-preview-stage .video-preview-player {
  flex: 1;
  margin: 0; /* override default auto-center inside the flex row */
}
.video-preview-stage .preview-vu-strip {
  position: relative; /* override .obs-vu-top absolute positioning */
  /* Match the card meter's 44px so the dB tick column + L/R bars fit without
     cramping. Was 26px (the pre-tick-column width), which squeezed the ticks
     and bars together and made the overflow meter read inaccurately. */
  width: 44px;
  min-width: 44px;
  background: rgba(0, 0, 0, 0.35);
  border-radius: 8px;
  padding: 6px 3px 6px 3px;
}

.video-preview-footer .form-label {
  display: block;
  margin-bottom: 0.5rem;
  color: var(--color-text);
}

.video-preview-footer .form-input {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  color: var(--color-text);
}

.video-preview-footer .form-input:focus {
  outline: none;
  border-color: var(--color-primary);
}

.video-preview-footer code {
  background: var(--bg-secondary);
  padding: 2px 6px;
  border-radius: 4px;
  font-size: 0.875rem;
}

/* HLS URL Modal */
.hls-url-container {
  padding: 0.5rem 0;
}

.hls-url-box {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: 4px;
  padding: 0.5rem;
}

.hls-url-box input {
  background: transparent;
  border: none;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  cursor: pointer;
}

.hls-url-box input:focus {
  outline: none;
  box-shadow: none;
}

/* ==================== ROS Timeline ==================== */
.ros-timeline-container {
  background: var(--color-bg);
  border-radius: var(--radius-md);
  overflow: hidden;
  max-width: 100%;
  width: 100%;
}

.ros-timeline-header {
  padding: var(--spacing-md);
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  overflow-x: auto;
}

.ros-timeline-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--spacing-md);
  padding: var(--spacing-md);
  flex-wrap: wrap;
}

.ros-day-buttons-container {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-xs);
  align-items: center;
  justify-content: center;
  max-width: 100%;
}

.ros-day-btn {
  min-width: auto;
  white-space: nowrap;
}

.ros-search-container {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  position: relative;
}

.ros-search-input {
  width: 250px;
  padding: var(--spacing-xs) var(--spacing-sm);
  font-size: 0.875rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  transition: all 0.2s ease;
}

.ros-search-input:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1);
}

.ros-search-results {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.ros-realtime-clock {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  padding: var(--spacing-xs) var(--spacing-sm);
  background: var(--color-surface);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}

.ros-clock-time {
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-primary);
  font-family: 'Courier New', monospace;
}

.ros-clock-date {
  font-size: 0.75rem;
  color: var(--color-text-muted);
}

.ros-date-info {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 300px;
}
/* On very narrow phones the 300px min-width overflows the timeline nav — let it
   shrink and take the full row (it already wraps to its own line). */
@media (max-width: 480px) {
  .ros-date-info { min-width: 0; width: 100%; }
}

.ros-current-date {
  font-size: 1.125rem;
  font-weight: 600;
  text-align: center;
}

.ros-date-range {
  font-size: 0.75rem;
  color: var(--color-text-muted);
  text-align: center;
}

/* ---- New layout: fixed header bar + scrollable body grid ---- */
.ros-timeline-grid-wrap {
  overflow: hidden;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}

/* Header bar: corner + room names — never participates in scroll */
.ros-timeline-header-bar {
  display: flex;
  overflow: hidden;              /* hides rooms strip overflow */
  background: var(--color-surface);
  border-bottom: 2px solid var(--color-border);
  flex-shrink: 0;
}

.ros-timeline-rooms-strip {
  flex: 1;
  overflow: hidden;              /* horizontal position synced via JS */
  min-width: 0;
}

/* Scrollable body */
.ros-timeline-grid {
  display: flex;
  overflow-x: auto;
  overflow-y: auto;
  max-height: 68vh;
  width: 100%;
}

.ros-timeline-grid::-webkit-scrollbar {
  height: 8px;
  width: 6px;
}

.ros-timeline-grid::-webkit-scrollbar-track {
  background: var(--color-bg);
}

.ros-timeline-grid::-webkit-scrollbar-thumb {
  background: var(--color-border);
  border-radius: var(--radius-sm);
}

.ros-timeline-grid::-webkit-scrollbar-thumb:hover {
  background: var(--color-primary);
}

/* Corner: fixed part of header bar, always visible */
.ros-timeline-corner {
  width: 140px;
  flex-shrink: 0;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 600;
  border-right: 2px solid var(--color-border);
  background: var(--color-surface);
}

/* Sidebar: time labels, sticky left inside scrollable grid */
.ros-timeline-sidebar {
  flex-shrink: 0;
  width: 140px;
  background: var(--color-surface);
  border-right: 2px solid var(--color-border);
  position: sticky;
  left: 0;
  z-index: 5;
}

.ros-timeline-times {
  display: flex;
  flex-direction: column;
}

.ros-timeline-time {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--spacing-xs);
  border-bottom: 1px solid var(--color-border);
  font-weight: 500;
  font-size: 0.85rem;
  background: var(--color-bg);
}

.ros-timeline-resource {
  min-height: 120px;
  height: auto;
  display: flex;
  align-items: center;
  padding: var(--spacing-sm);
  border-bottom: 1px solid var(--color-border);
  font-weight: 500;
  font-size: 0.9rem;
}

.ros-timeline-main {
  flex: 1;
  overflow: visible;
  min-width: 0;
}

/* Room headers row (inside the strip, not sticky — strip handles it) */
.ros-timeline-rooms {
  height: 50px;
  display: flex;
  width: fit-content;
  min-width: 100%;
}

.ros-timeline-room {
  min-width: 180px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-right: 1px solid var(--color-border);
  font-size: 0.875rem;
  font-weight: 600;
  text-align: center;
  padding: var(--spacing-xs);
}

.ros-timeline-body-vertical {
  position: relative;
  width: fit-content;
  min-width: 100%;
}

.ros-timeline-columns {
  display: flex;
}

.ros-timeline-column {
  position: relative;
  min-width: 180px;
  border-right: 1px solid var(--color-border-light);
  background: repeating-linear-gradient(
    to bottom,
    transparent,
    transparent calc(var(--slot-height, 60px) - 1px),
    var(--color-border-light) calc(var(--slot-height, 60px) - 1px),
    var(--color-border-light) var(--slot-height, 60px)
  );
}

@media (max-width: 1024px) {
  .ros-search-input {
    width: 200px;
  }

  .ros-timeline-sidebar {
    width: 120px;
  }

  .ros-timeline-room,
  .ros-timeline-column {
    min-width: 150px;
  }
}

@media (max-width: 768px) {
  .ros-search-input {
    width: 160px;
  }

  .ros-timeline-header {
    padding: var(--spacing-xs);
  }

  .ros-timeline-sidebar,
  .ros-timeline-corner {
    width: 100px;
  }

  .ros-timeline-room,
  .ros-timeline-column {
    min-width: 130px;
  }
}

/* Current time "now" indicator line */
.ros-now-line {
  position: absolute;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--color-danger, #ef4444);
  z-index: 5;
  pointer-events: none;
}

.ros-now-line::before {
  content: '';
  position: absolute;
  left: -4px;
  top: -3px;
  width: 8px;
  height: 8px;
  background: var(--color-danger, #ef4444);
  border-radius: 50%;
}

/* Highlight the current time slot in the sidebar */
.ros-timeline-time.ros-time-now {
  background: rgba(239, 68, 68, 0.15);
  font-weight: 700;
  color: var(--color-danger, #ef4444);
}

.ros-event {
  position: absolute;
  left: 6px;
  right: 6px;
  border-radius: var(--radius-sm);
  padding: var(--spacing-xs);
  color: white;
  font-size: 0.875rem;
  font-weight: 500;
  overflow: hidden;
  transition: all 0.2s ease;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  cursor: pointer;
}

.ros-event:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
  z-index: 10;
}

.ros-event-live {
  animation: pulse-live 2s ease-in-out infinite;
  box-shadow: 0 0 15px rgba(76, 175, 80, 0.6);
}

.ros-event-search-match {
  background-color: #ffc107 !important;
  color: #000 !important;
  animation: pulse-search 1.5s ease-in-out infinite;
  box-shadow: 0 0 25px rgba(255, 193, 7, 0.9), 0 0 15px rgba(255, 193, 7, 0.7), 0 4px 8px rgba(0, 0, 0, 0.3) !important;
  border: 3px solid #ff9800 !important;
  z-index: 100;
  font-weight: 600;
  overflow: visible !important;
}

.ros-event-search-match .ros-event-line {
  color: #000 !important;
  text-shadow: 0 1px 2px rgba(255, 255, 255, 0.5);
}

.ros-event-search-match::before {
  content: '🔍 MATCH';
  position: absolute;
  top: -12px;
  right: 5px;
  background: linear-gradient(135deg, #ff9800 0%, #ffc107 100%);
  padding: 2px 8px;
  border-radius: 10px;
  font-size: 10px;
  font-weight: 700;
  color: #000;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.4);
  animation: bounce-indicator 1s ease-in-out infinite;
  letter-spacing: 0.5px;
  border: 2px solid #ff6f00;
}

@keyframes pulse-live {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.85; }
}

@keyframes pulse-search {
  0%, 100% { 
    transform: scale(1);
    box-shadow: 0 0 25px rgba(255, 193, 7, 0.9), 0 0 15px rgba(255, 193, 7, 0.7), 0 4px 8px rgba(0, 0, 0, 0.3);
  }
  50% { 
    transform: scale(1.05);
    box-shadow: 0 0 35px rgba(255, 193, 7, 1), 0 0 20px rgba(255, 193, 7, 0.9), 0 6px 12px rgba(0, 0, 0, 0.4);
  }
}

@keyframes bounce-indicator {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-3px); }
}

.ros-event-content {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
}

.ros-event-line {
  white-space: normal;
  word-wrap: break-word;
  line-height: 1.3;
}

.ros-event-details-btn {
  background: rgba(255, 255, 255, 0.2);
  border: none;
  border-radius: var(--radius-sm);
  padding: 2px 6px;
  cursor: pointer;
  transition: background 0.2s ease;
  flex-shrink: 0;
}

.ros-event-details-btn:hover {
  background: rgba(255, 255, 255, 0.3);
}

.ros-event-details-btn .icon {
  width: 16px;
  height: 16px;
  filter: brightness(0) invert(1);
}

.ros-live-indicator {
  background: rgba(255, 255, 255, 0.3);
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-align: center;
  animation: blink-live 1.5s ease-in-out infinite;
}

@keyframes blink-live {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.6; }
}

.checkbox-list {
  max-height: 300px;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--spacing-sm);
}

.btn-group {
  display: flex;
  gap: 0;
}

.btn-group .btn {
  border-radius: 0;
  border-right: 1px solid var(--color-border);
}

.btn-group .btn:first-child {
  border-top-left-radius: var(--radius-sm);
  border-bottom-left-radius: var(--radius-sm);
}

.btn-group .btn:last-child {
  border-top-right-radius: var(--radius-sm);
  border-bottom-right-radius: var(--radius-sm);
  border-right: none;
}

.color-preview {
  width: 50px;
  height: 40px;
  border-radius: var(--radius-sm);
  border: 2px solid var(--color-border);
  flex-shrink: 0;
  cursor: pointer;
  transition: all 0.2s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.75rem;
  color: var(--color-text-light);
  position: relative;
}

.color-preview:hover {
  transform: scale(1.05);
  border-color: var(--color-primary);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.color-preview::after {
  content: attr(title);
  position: absolute;
  bottom: -20px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 0.7rem;
  color: var(--color-text-muted);
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.2s ease;
}

.color-preview:hover::after {
  opacity: 1;
}

.ros-color-rule {
  background: var(--color-surface);
  padding: var(--spacing-sm);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}

.ros-color-preview {
  transition: all 0.2s ease;
  font-weight: 600;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

.ros-color-preview:hover {
  transform: scale(1.05);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

.ros-zoom-controls {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  padding: var(--spacing-sm);
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
}

.ros-field-display-list {
  max-height: 400px;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--spacing-sm);
}

.ros-field-display-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--spacing-xs) 0;
  border-bottom: 1px solid var(--color-border-light);
}

.ros-field-display-row:last-child {
  border-bottom: none;
}

.ros-field-name {
  font-weight: 500;
  flex: 1;
}

.ros-field-options {
  display: flex;
  gap: var(--spacing-md);
}

.ros-field-option {
  display: flex;
  align-items: center;
  gap: var(--spacing-xs);
  cursor: pointer;
  font-size: 0.875rem;
}

.ros-field-option input[type="radio"] {
  cursor: pointer;
}

/* ==================== Video Wall ==================== */

.vw-body {
  background: var(--color-bg-primary);
  color: var(--color-text-primary);
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 14px;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

/* Toolbar */
.vw-toolbar {
  height: 52px;
  min-height: 52px;
  background: var(--color-bg-secondary);
  border-bottom: 1px solid var(--color-border);
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 14px;
  flex-shrink: 0;
  overflow-x: auto;
}

.vw-toolbar-title {
  font-weight: 700;
  font-size: 15px;
  white-space: nowrap;
}

.vw-div {
  width: 1px;
  height: 22px;
  background: var(--color-border);
  flex-shrink: 0;
}

.vw-label {
  font-size: 12px;
  color: var(--color-text-muted);
  white-space: nowrap;
}

/* Column buttons */
.vw-col-btns {
  display: flex;
  gap: 2px;
}

.vw-col-btn {
  background: var(--color-bg-tertiary);
  border: none;
  color: var(--color-text-primary);
  padding: 3px 9px;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}

.vw-col-btn.active {
  background: var(--color-primary);
  color: #fff;
}

.vw-col-btn:hover:not(.active) {
  background: var(--color-surface-hover);
}

/* Toggle pill */
.vw-toggle {
  display: flex;
  align-items: center;
  gap: 5px;
  cursor: pointer;
  user-select: none;
  font-size: 12px;
  white-space: nowrap;
}

.vw-toggle input[type=checkbox] {
  display: none;
}

.vw-toggle-pill {
  width: 32px;
  height: 17px;
  background: var(--color-bg-tertiary);
  border-radius: 9px;
  position: relative;
  flex-shrink: 0;
  transition: background 0.2s;
}

.vw-toggle-pill::after {
  content: '';
  position: absolute;
  left: 2px;
  top: 2px;
  width: 13px;
  height: 13px;
  background: #fff;
  border-radius: 50%;
  transition: left 0.2s;
}

.vw-toggle input:checked + .vw-toggle-pill {
  background: var(--color-primary);
}

.vw-toggle input:checked + .vw-toggle-pill::after {
  left: 17px;
}

/* Close button */
.vw-btn {
  background: transparent;
  border: 1px solid var(--color-border);
  color: var(--color-text-primary);
  padding: 4px 12px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 12px;
  white-space: nowrap;
  margin-left: auto;
  flex-shrink: 0;
}

.vw-btn:hover {
  background: var(--color-surface-hover);
}

/* Scroll + grid */
.vw-scroll {
  flex: 1;
  overflow-y: auto;
  padding: 10px;
}

.vw-grid {
  display: grid;
  grid-template-columns: repeat(var(--vw-cols, 3), 1fr);
  gap: 10px;
}

/* Card */
.vw-card {
  background: var(--color-bg-secondary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Video + VU side-by-side row */
.vw-media-row {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  background: #000;
  position: relative;
}

/* 16:9 video wrapper using padding-top trick */
.vw-video-outer {
  flex: 1;
  position: relative;
  overflow: hidden;
}

.vw-video-outer::before {
  content: '';
  display: block;
  padding-top: 56.25%;
}

.vw-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
}

/* Status dot */
.vw-dot {
  position: absolute;
  top: 7px;
  left: 7px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--color-text-muted);
  border: 1.5px solid rgba(0, 0, 0, 0.6);
  z-index: 5;
}

.vw-dot.online  { background: var(--color-success); }
.vw-dot.offline { background: var(--color-danger); }

/* Offline overlay — hidden by default, toggled via .show */
.vw-nosig {
  display: none;
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  color: var(--color-text-muted);
  font-size: 12px;
  z-index: 4;
}

.vw-nosig.show {
  display: flex;
}

.vw-nosig span {
  font-size: 12px;
  color: var(--color-text-muted);
}

/* Vertical VU meter column */
.vw-vu-col {
  width: 18px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  background: rgba(0, 0, 0, 0.45);
  padding: 4px 3px 20px;
  position: relative;
}

.vw-vu-track-v {
  flex: 1;
  width: 100%;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
}

/* Fill rises from bottom */
.vw-vu-fill-v {
  width: 100%;
  height: 0%;
  background: linear-gradient(to top, #22c55e 0%, #f59e0b 65%, #ef4444 100%);
  transition: height 180ms linear;
  border-radius: 2px;
}

.vw-vu-db-v {
  position: absolute;
  bottom: 2px;
  left: 0;
  right: 0;
  text-align: center;
  font-size: 9px;
  color: var(--color-text-muted);
  line-height: 1;
  pointer-events: none;
}

/* Machine info row */
.vw-info {
  padding: 7px 10px 4px;
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-wrap: wrap;
}

.vw-name {
  font-weight: 600;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.vw-ip {
  font-size: 11px;
  color: var(--color-text-muted);
  font-family: monospace;
}

/* Profile rows */
.vw-profile {
  padding: 0 10px 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.vw-prow {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
}

.vw-plabel {
  color: var(--color-text-muted);
  min-width: 56px;
}

.vw-pval {
  font-weight: 500;
}

.vw-profile.match    .vw-pval { color: var(--color-success); }
.vw-profile.mismatch .vw-pval { color: var(--color-warning); }

/* Toolbar toggle visibility classes */
.vw-hide-video   .vw-video-outer { display: none; }
.vw-hide-vu      .vw-vu-col      { display: none; }
.vw-hide-info    .vw-info        { display: none; }
.vw-hide-profile .vw-profile     { display: none; }

/* Splash / loading screen */
.vw-splash {
  position: fixed;
  inset: 0;
  background: var(--color-bg-primary);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  z-index: 100;
}

.vw-splash-title {
  font-size: 22px;
  font-weight: 700;
}

.vw-splash-msg {
  font-size: 14px;
  color: var(--color-text-muted);
}

.vw-spinner {
  width: 32px;
  height: 32px;
  border: 3px solid var(--color-border);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: vw-spin 0.7s linear infinite;
}

@keyframes vw-spin {
  to { transform: rotate(360deg); }
}

@media (max-width: 600px) {
  .vw-grid { --vw-cols: 1 !important; }
}

/* ==================== Settings Page ==================== */

.settings-layout {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg);
}

/* Three equal cards */
.settings-row {
  display: grid;
  gap: var(--spacing-md);
  align-items: start;
}

.settings-row-3 {
  grid-template-columns: repeat(3, 1fr);
}

/* Full-width danger zone at page bottom */
.settings-danger-full {
  width: 100%;
}

.settings-card {
  height: 100%;
}

.settings-card-header {
  border-bottom: 1px solid var(--color-border);
  padding-bottom: var(--spacing-sm);
}

.settings-card-body {
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* Field row: label stack on top, input below */
.settings-field {
  padding: var(--spacing-md) 0;
}

.settings-field:first-child {
  padding-top: 0;
}

.settings-field-label {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: var(--spacing-xs);
}

.settings-field-label .form-label {
  margin-bottom: 0;
}

/* Horizontal field: label left, control right */
.settings-field-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--spacing-md);
}

.settings-divider {
  height: 1px;
  background: var(--color-border);
  margin: 0;
}

/* Unit select (ms/s) next to a number input */
.settings-unit-select {
  width: 70px;
  flex-shrink: 0;
}

/* Toggle switch (replaces checkbox) */
.settings-toggle {
  position: relative;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  flex-shrink: 0;
}

.settings-toggle input[type="checkbox"] {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.settings-toggle-track {
  width: 38px;
  height: 22px;
  background: var(--color-bg-tertiary);
  border: 1px solid var(--color-border);
  border-radius: 11px;
  position: relative;
  transition: background 0.2s, border-color 0.2s;
}

.settings-toggle-track::after {
  content: '';
  position: absolute;
  left: 3px;
  top: 3px;
  width: 14px;
  height: 14px;
  background: var(--color-text-muted);
  border-radius: 50%;
  transition: left 0.2s, background 0.2s;
}

.settings-toggle input:checked + .settings-toggle-track {
  background: var(--color-primary);
  border-color: var(--color-primary);
}

.settings-toggle input:checked + .settings-toggle-track::after {
  left: 19px;
  background: #fff;
}

/* Accent color row */
.settings-color-row {
  display: flex;
  align-items: center;
  gap: var(--spacing-sm);
}

.settings-color-input {
  width: 48px;
  height: 40px;
  padding: 3px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
}

/* Info box inside Video card */
.settings-info-box {
  background: var(--color-bg-tertiary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--spacing-md);
  margin-top: var(--spacing-sm);
}

.settings-code {
  display: block;
  font-family: var(--font-family-mono);
  font-size: 0.8rem;
  color: var(--color-primary);
  margin-top: var(--spacing-xs);
  word-break: break-all;
}

.settings-code.mt-2 {
  margin-top: var(--spacing-sm);
}

/* Danger zone card */
.settings-danger-card {
  border-color: var(--color-danger) !important;
}

.settings-danger-header {
  background: rgba(239, 68, 68, 0.06);
}

.settings-danger-title {
  color: var(--color-danger) !important;
}

.settings-danger-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--spacing-sm);
  margin-bottom: var(--spacing-md);
}

.settings-danger-item {
  background: var(--color-bg-tertiary);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--spacing-md);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xs);
  justify-content: space-between;
}

.settings-danger-item-label {
  font-weight: 600;
  font-size: 0.875rem;
  color: var(--color-text-primary);
}

.settings-factory-reset {
  border-top: 1px solid var(--color-border);
  padding-top: var(--spacing-md);
}

/* Save row */
.settings-save-row {
  display: flex;
  justify-content: flex-end;
  gap: var(--spacing-sm);
  padding-top: var(--spacing-sm);
}

/* Responsive */
@media (max-width: 1100px) {
  .settings-row-3 { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 720px) {
  .settings-row-3 { grid-template-columns: 1fr; }
}

/* ==================== Pearl Monitor ==================== */

.pearl-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(560px, 1fr));
    gap: var(--spacing-lg);
}

/* Card shell */
.pearl-card {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-left: 3px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    transition: border-left-color 0.25s;
}
.pearl-card.pearl-card-online  { border-left-color: var(--color-success); }
.pearl-card.pearl-card-offline { border-left-color: var(--color-text-muted); }

/* Card header */
.pearl-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--spacing-sm) var(--spacing-md);
    background: var(--color-bg-tertiary);
    border-bottom: 1px solid var(--color-border);
    gap: var(--spacing-sm);
    flex-wrap: wrap;
}
.pearl-card-name {
    font-weight: var(--font-weight-semibold);
    font-size: var(--font-size-sm);
    color: var(--color-text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pearl-ip {
    font-size: 11px;
    color: var(--color-text-muted);
}

/* Card body */
.pearl-card-body {
    display: flex;
    flex-direction: column;
    gap: 0;
    flex: 1;
}

/* System stats bar */
.pearl-stats-bar {
    display: flex;
    gap: var(--spacing-lg);
    padding: var(--spacing-sm) var(--spacing-md);
    background: var(--color-bg-secondary);
    border-bottom: 1px solid var(--color-border);
    flex-wrap: wrap;
}
.pearl-stat {
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.pearl-stat-label {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--color-text-muted);
}
.pearl-stat-val {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-text-primary);
}
.pearl-stat-val.pearl-stat-warn {
    color: var(--color-warning, #f59e0b);
}

/* Storage bar */
.pearl-storage-bar {
    padding: var(--spacing-xs) var(--spacing-md);
    background: var(--color-bg-secondary);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.pearl-storage-stats {
    display: flex;
    gap: var(--spacing-lg);
    flex-wrap: wrap;
}
.pearl-storage-track {
    height: 4px;
    background: rgba(255,255,255,0.08);
    border-radius: 2px;
    overflow: hidden;
}
.pearl-storage-fill {
    height: 100%;
    background: var(--color-primary);
    border-radius: 2px;
    transition: width 400ms ease;
}
.pearl-storage-fill.pearl-storage-warn {
    background: var(--color-danger, #ef4444);
}

/* Main columns layout */
.pearl-main-cols {
    display: flex;
    gap: 0;
    flex: 1;
    min-height: 180px;
}

/* Left: channels + recorders */
.pearl-controls-col {
    flex: 1;
    min-width: 0;
    padding: var(--spacing-sm) var(--spacing-md);
    display: flex;
    flex-direction: column;
    gap: var(--spacing-sm);
    border-right: 1px solid var(--color-border);
}

/* Section (channels / recorders) */
.pearl-section {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.pearl-section-title {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-text-muted);
    font-weight: var(--font-weight-semibold);
    margin-bottom: 2px;
}
.pearl-items-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* Individual item row */
.pearl-item-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-sm);
    padding: 5px 8px;
    background: var(--color-bg-tertiary);
    border-radius: var(--radius-sm);
    border: 1px solid var(--color-border);
    flex-wrap: wrap;
}
.pearl-item-info {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}
.pearl-item-name {
    font-size: var(--font-size-sm);
    font-weight: var(--font-weight-medium);
    color: var(--color-text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.pearl-item-meta {
    font-size: 11px;
    color: var(--color-text-muted);
}
.pearl-item-controls {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}
.pearl-streaming-badge { animation: pearl-pulse 2s ease-in-out infinite; }
.pearl-rec-badge       { animation: pearl-pulse 1.5s ease-in-out infinite; }

@keyframes pearl-pulse {
    0%, 100% { opacity: 1; }
    50%       { opacity: 0.6; }
}

/* Right: preview */
.pearl-preview-col {
    width: 220px;
    flex-shrink: 0;
    padding: var(--spacing-sm);
    display: flex;
    flex-direction: column;
    align-items: stretch;
}
.pearl-preview-wrap {
    position: relative;
    background: var(--color-bg-primary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    overflow: hidden;
    aspect-ratio: 16/9;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.pearl-preview-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.pearl-preview-placeholder {
    font-size: 11px;
    color: var(--color-text-muted);
    text-align: center;
    z-index: 1;
}
.pearl-preview-footer {
    font-size: 11px;
    color: var(--color-text-muted);
    text-align: center;
    margin-top: 4px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Layout ("scene") switch button on a channel row */
.pearl-layout-btn {
    align-self: flex-start;
    margin-top: 2px;
    padding: 1px 6px;
    font-size: 11px;
    line-height: 1.4;
    max-width: 100%;
    color: var(--color-text-secondary, var(--color-text-muted));
    background: var(--color-bg-secondary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    transition: border-color 0.15s, color 0.15s;
}
.pearl-layout-btn:hover {
    border-color: var(--color-primary);
    color: var(--color-text-primary);
}
.pearl-layout-list { display: flex; flex-direction: column; }

/* Bulk multi-select action bar */
.pearl-bulk-bar {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    flex-wrap: wrap;
    padding: var(--spacing-sm) var(--spacing-md);
    margin-bottom: var(--spacing-md);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
}
.pearl-bulk-count {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    min-width: 84px;
}
.pearl-bulk-actions {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    margin-left: auto;
}
.pearl-bulk-cb { cursor: pointer; }

/* Responsive */
@media (max-width: 1200px) {
    .pearl-grid { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
    .pearl-main-cols { flex-direction: column; }
    .pearl-controls-col { border-right: none; border-bottom: 1px solid var(--color-border); }
    .pearl-preview-col { width: 100%; }
    .pearl-bulk-actions { margin-left: 0; }
}

/* ==================== Page Builder ==================== */
.pb-editor-wrap {
    overflow: hidden;
    /* Container clips any flex children that would otherwise push the
       canvas wider than its parent — most often the long DB Bindings
       header in the 160px sidebar. */
    min-width: 0;
}
.pb-editor-layout {
    display: grid;
    /* Default columns. ALWAYS overridden inline by renderPbEditor with the
       persisted toolbar/props widths plus the two 6px resize-handle tracks,
       e.g. "160px 6px 1fr 6px 220px". Kept here only as a fallback for
       very brief render windows where the inline style hasn't applied yet
       — the 5-track layout still works with 5-track CSS. */
    grid-template-columns: 160px 6px 1fr 6px 220px;
    gap: var(--spacing-sm);
    min-height: 650px;
    transition: grid-template-columns 0.15s ease;
}
.pb-toolbar {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--spacing-sm);
    background: var(--color-bg);
    overflow-y: auto;
    overflow-x: hidden;
    max-height: 800px;
    /* CRITICAL: a grid item without min-width:0 inherits min-content as a
       minimum, which is what was making "Collapse all / Expand all / Edit"
       force horizontal scroll instead of wrapping. */
    min-width: 0;
    /* Firefox scrollbar to match the rest of the app (matrix tables,
       reflex-db rows, table-responsive, etc.). */
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}
/*
 * WebKit scrollbar styling — mirrors .table-responsive / .matrix-scroll-*
 * so the toolbar and props panel feel like first-class citizens instead of
 * sticking out with the default OS scrollbar.
 */
.pb-toolbar::-webkit-scrollbar,
.pb-props-panel::-webkit-scrollbar,
.pb-canvas-area::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}
.pb-toolbar::-webkit-scrollbar-track,
.pb-props-panel::-webkit-scrollbar-track,
.pb-canvas-area::-webkit-scrollbar-track {
    background: var(--color-surface);
    border-radius: 4px;
}
.pb-toolbar::-webkit-scrollbar-thumb,
.pb-props-panel::-webkit-scrollbar-thumb,
.pb-canvas-area::-webkit-scrollbar-thumb {
    background: var(--color-border);
    border-radius: 4px;
}
.pb-toolbar::-webkit-scrollbar-thumb:hover,
.pb-props-panel::-webkit-scrollbar-thumb:hover,
.pb-canvas-area::-webkit-scrollbar-thumb:hover {
    background: var(--color-primary);
}

/* ----------------------------------------------------------------------
 * Editor top bar (above the 3-column layout). Replaces the prior
 * `flex items-center justify-between` row that was causing overflow on
 * narrow viewports. Wraps cleanly when the right cluster of buttons
 * grows (3 panel-toggles + Grid + Preview + Publish + sep).
 * ---------------------------------------------------------------------- */
.pb-editor-topbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--spacing-sm, 8px) var(--spacing-md, 12px);
    margin-bottom: var(--spacing-md, 12px);
    min-width: 0;
}
.pb-editor-topbar-left {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm, 8px);
    min-width: 0;
    flex: 1 1 auto;
}
.pb-editor-topbar-right {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
    flex: 0 0 auto;
}
.pb-editor-title {
    margin: 0;
    font-size: var(--font-size-md, 15px);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    max-width: 360px;
}
.pb-topbar-sep {
    width: 1px;
    height: 22px;
    background: var(--color-border);
    margin: 0 4px;
}
.pb-panel-toggle {
    /* Slightly tighter than default btn-sm so all three fit on a single
       row at typical screen widths. */
    padding-left: var(--spacing-sm, 8px);
    padding-right: var(--spacing-sm, 8px);
}

/* ----------------------------------------------------------------------
 * Resize handles between the side panels and the canvas. The 6px grid
 * track holds an invisible-by-default vertical bar that lights up to a
 * 2px primary-color line on hover or active drag. Double-click to reset
 * the width to the panel's default. Disabled when the adjacent panel is
 * collapsed (since there's no width to drag).
 * ---------------------------------------------------------------------- */
.pb-resize-handle-col {
    position: relative;
    cursor: col-resize;
    background: transparent;
    transition: background-color 0.12s ease;
}
.pb-resize-handle-col::before {
    content: '';
    position: absolute;
    top: 12px;
    bottom: 12px;
    left: 50%;
    transform: translateX(-50%);
    width: 2px;
    background: var(--color-border);
    border-radius: 1px;
    opacity: 0.5;
    transition: background-color 0.12s ease, opacity 0.12s ease;
}
.pb-resize-handle-col:hover::before,
.pb-resize-handle-col:active::before {
    background: var(--color-primary);
    opacity: 1;
}
.pb-resize-handle-col.pb-resize-handle-disabled {
    cursor: default;
}
.pb-resize-handle-col.pb-resize-handle-disabled::before {
    opacity: 0.2;
}
.pb-resize-handle-col.pb-resize-handle-disabled:hover::before {
    background: var(--color-border);
    opacity: 0.2;
}

/* ----------------------------------------------------------------------
 * Collapsed-panel stub. Replaces the full toolbar / props-panel column
 * with a 28px-wide vertical strip that's still clickable to expand.
 * Vertical text label keeps the affordance discoverable without taking
 * any horizontal space.
 * ---------------------------------------------------------------------- */
.pb-panel-stub {
    all: unset;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
    padding: 10px 0;
    border: 1px dashed var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-bg);
    cursor: pointer;
    color: var(--color-text-muted);
    transition: background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease;
    min-height: 200px;
}
.pb-panel-stub:hover {
    background: var(--color-surface-hover, rgba(255,255,255,0.04));
    color: var(--color-text-primary);
    border-color: var(--color-primary);
}
.pb-panel-stub-chevron {
    font-size: 12px;
    line-height: 1;
}
.pb-panel-stub-label {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

/* ----------------------------------------------------------------------
 * DB Bindings header inside the toolbar. The 160px sidebar can't hold
 * "DB Bindings" + three labeled buttons on one row, so we stack into
 * two compact rows:
 *   row 1 → title + Edit (primary action)
 *   row 2 → bulk collapse/expand icon buttons (only when groups exist)
 * Both rows respect the sidebar's min-width:0 so nothing escapes.
 * ---------------------------------------------------------------------- */
.pb-bindings-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    margin: var(--spacing-md, 12px) 0 4px;
    min-width: 0;
}
.pb-bindings-title {
    font-size: var(--font-size-xs);
    font-weight: 600;
    color: var(--color-text-muted);
    margin: 0;
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.pb-bindings-edit-btn {
    flex: 0 0 auto;
    font-size: 10px;
    padding: 2px 8px;
}
.pb-bindings-bulk-row {
    display: flex;
    gap: 4px;
    margin-bottom: 4px;
}
.pb-bindings-bulk-btn {
    flex: 1 1 0;
    font-size: 10px;
    padding: 2px 4px;
    font-family: var(--font-family-mono, ui-monospace, monospace);
    /* Mono font keeps the chevron + "All" centred at the same width
       as its sibling for visual balance. */
    text-align: center;
}
.pb-tool-items {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.pb-tool-item {
    padding: 6px 10px;
    font-size: var(--font-size-xs);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-surface);
    cursor: grab;
    user-select: none;
    transition: border-color 0.15s;
}
.pb-tool-item:hover {
    border-color: var(--color-primary);
}
.pb-tool-field {
    border-left: 3px solid var(--color-primary);
}
/* Sub-DB drag tiles use the warning amber so they're visually distinct
   from parent-DB tiles in the sidebar. Same color cue as the SUB badge
   on the group header above them. */
.pb-tool-field-sub {
    border-left: 3px solid var(--color-warning, #f59e0b);
}

/*
 * Collapsible group header in the editor's DB Bindings sidebar. Looks
 * like static text (it isn't a typical button) but is fully clickable
 * on its whole horizontal area, with a subtle hover so the operator
 * knows it's interactive. Chevron + count appear inline so the header
 * stays a single short row even with sub-DB amber pill present.
 */
.pb-binding-group-header {
    border-radius: var(--radius-sm, 4px);
    padding: 4px 6px;
    transition: background-color 0.12s ease;
}
.pb-binding-group-header:hover {
    background-color: var(--color-surface-hover, rgba(255,255,255,0.04));
}
.pb-binding-group-header:focus-visible {
    outline: 1px solid var(--color-primary);
    outline-offset: 1px;
}
.pb-upload-item {
    padding: 2px;
    cursor: grab;
}
.pb-canvas-area {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    overflow: auto;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--spacing-sm);
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}
.pb-canvas-wrapper {
    position: relative;
    flex-shrink: 0;
}
.pb-canvas {
    position: relative;
    background-color: #000;
    overflow: hidden;
    cursor: default;
}
.pb-el {
    position: absolute;
    cursor: move;
    overflow: hidden;
    word-wrap: break-word;
    box-sizing: border-box;
    user-select: none;
}
.pb-el-selected {
    outline: 2px solid var(--color-primary);
    outline-offset: 1px;
}
.pb-resize-handle {
    position: absolute;
    width: 10px;
    height: 10px;
    background: var(--color-primary);
    border-radius: 2px;
    z-index: 10;
}
.pb-rh-br { right: -5px; bottom: -5px; cursor: se-resize; }
.pb-rh-bl { left: -5px; bottom: -5px; cursor: sw-resize; }
.pb-rh-tr { right: -5px; top: -5px; cursor: ne-resize; }
.pb-rh-tl { left: -5px; top: -5px; cursor: nw-resize; }
.pb-props-panel {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-bg);
    overflow-y: auto;
    overflow-x: hidden;
    max-height: 800px;
    /* Same min-width:0 fix as .pb-toolbar — without this a long property
       label would push the canvas grid column wider than its allotted
       1fr and trigger horizontal scroll on the whole editor. */
    min-width: 0;
    /* Firefox scrollbar to match the app palette. */
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}

/* Wizard orientation selector */
.pb-orient-grid {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: var(--spacing-md);
}
.pb-orient-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--spacing-sm);
    padding: var(--spacing-md);
    border: 2px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-bg);
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
    font-family: inherit;
    font-size: var(--font-size-sm);
    color: var(--color-text);
}
.pb-orient-btn:hover {
    border-color: var(--color-primary);
}
.pb-orient-btn.active {
    border-color: var(--color-primary);
    background: var(--color-primary-900);
}
.pb-orient-preview {
    border: 2px solid var(--color-text-muted);
    border-radius: var(--radius-sm);
}
.pb-orient-land {
    width: 80px;
    height: 45px;
}
.pb-orient-port {
    width: 45px;
    height: 80px;
}
.pb-orient-resp {
    width: 80px;
    height: 50px;
    border-style: dashed;
    position: relative;
}
.pb-orient-resp::after {
    content: '';
    position: absolute;
    inset: 3px;
    border: 1px dashed var(--color-text-muted);
    border-radius: 2px;
}

/* Upload thumbnails in toolbar */
.pb-upload-thumb {
    position: relative;
    border-radius: var(--radius-sm);
    overflow: hidden;
    cursor: grab;
    border: 1px solid var(--color-border);
    aspect-ratio: 1;
}
.pb-upload-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    cursor: pointer;
}
.pb-upload-thumb:hover {
    border-color: var(--color-primary);
}

/* Media Manager */
.pb-media-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: var(--spacing-sm);
    max-height: 55vh;
    overflow-y: auto;
    padding: var(--spacing-xs);
}
.pb-media-card {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--color-bg-secondary);
}
.pb-media-thumb {
    aspect-ratio: 1;
    overflow: hidden;
    cursor: pointer;
}
.pb-media-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.15s;
}
.pb-media-thumb:hover img {
    transform: scale(1.05);
}
.pb-media-info {
    padding: 6px 8px;
}
.pb-media-name {
    display: block;
    font-size: 10px;
    color: var(--color-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin-bottom: 4px;
}

/*
 * Floating help widget — circular "?" button in the bottom-right corner,
 * paired with a slide-in panel containing per-page docs. Hidden when
 * Settings → Server → "Show help (?) button" is unchecked.
 */
#help-widget-btn {
    position: fixed;
    right: 18px;
    bottom: 18px;
    z-index: 900;   /* below the modal backdrop (1000) and toasts (2000) so it never covers modal Save/Confirm buttons */
    width: 76px;
    height: 76px;
    border: none;
    background: transparent;     /* show only the animation, no colored circle */
    color: #fff;
    line-height: 1;
    cursor: pointer;
    box-shadow: none;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    overflow: visible;
    transition: transform 0.12s ease;
}
#help-widget-btn .hw-lottie {
    width: 72px;
    height: 72px;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    background: transparent;
}
#help-widget-btn .hw-lottie svg { width: 100%; height: 100%; display: block; background: transparent; }
#help-widget-btn .hw-lottie img { width: 64px; height: 64px; }
/* Transparent icon button: no square box-shadow / outline on hover or focus —
   just a gentle scale so it stays a clean floating animation. */
#help-widget-btn:hover {
    transform: scale(1.06);
    box-shadow: none;
}
#help-widget-btn:focus,
#help-widget-btn:focus-visible {
    outline: none;
    box-shadow: none;
}

#help-widget-panel {
    position: fixed;
    right: 18px;
    bottom: 108px; /* clear the 76px Lottie launcher + a gap so they don't overlap */
    z-index: 901;  /* just above the FAB; still below the modal layer (1000) */
    width: min(420px, calc(100vw - 36px));
    max-height: min(640px, calc(100vh - 110px));
    background: var(--color-bg-elevated, #1a1a2e);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: 0 10px 32px rgba(0, 0, 0, 0.55);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    opacity: 0;
    transform: translateY(8px) scale(0.98);
    pointer-events: none;
    transition: opacity 0.16s ease, transform 0.16s ease;
}
#help-widget-panel.help-widget-panel-open {
    opacity: 1;
    transform: translateY(0) scale(1);
    pointer-events: auto;
}

/* Mobile: shrink the floating help button and tuck it into the corner so it
   doesn't crowd other controls; keep the panel within the viewport. */
@media (max-width: 768px) {
    #help-widget-btn { width: 56px; height: 56px; right: 12px; bottom: 12px; }
    #help-widget-btn .hw-lottie { width: 52px; height: 52px; }
    #help-widget-panel { right: 12px; bottom: 76px; }
}

/* ── Hybrid Assist chat popup ──────────────────────────────────────────── */
.hw-chat-panel { height: min(560px, calc(100vh - 110px)); }
.hw-chat-messages {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    padding: var(--spacing-md, 14px);
    display: flex;
    flex-direction: column;
    gap: 10px;
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}
.hw-chat-messages::-webkit-scrollbar { width: 8px; }
.hw-chat-messages::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 4px; }
.hw-msg { display: flex; }
.hw-msg.user { justify-content: flex-end; }
.hw-msg.assistant { justify-content: flex-start; }
.hw-bubble {
    max-width: 85%;
    padding: 8px 11px;
    border-radius: 12px;
    font-size: var(--font-size-sm, 13px);
    line-height: 1.5;
    white-space: normal;
    word-break: break-word;
}
.hw-msg.user .hw-bubble {
    background: var(--color-primary);
    color: #fff;
    border-bottom-right-radius: 4px;
}
.hw-msg.assistant .hw-bubble {
    background: var(--color-bg-tertiary, rgba(255,255,255,0.06));
    color: var(--color-text-primary);
    border-bottom-left-radius: 4px;
}
.hw-bubble code { background: var(--color-bg-secondary); padding: 1px 4px; border-radius: 3px; font-size: 0.9em; }
.hw-chat-inputbar {
    display: flex;
    gap: 8px;
    align-items: flex-end;
    padding: var(--spacing-sm, 10px);
    border-top: 1px solid var(--color-border);
    background: var(--color-bg, #0e0e1a);
    position: relative; /* anchor for the autocomplete popover */
}
.hw-suggest {
    position: absolute;
    left: var(--spacing-sm, 10px);
    right: var(--spacing-sm, 10px);
    bottom: calc(100% - 2px);
    max-height: 220px;
    overflow-y: auto;
    background: var(--color-bg-elevated, var(--color-bg-secondary));
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md, 8px);
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.4);
    z-index: 5;
    padding: 4px;
}
.hw-suggest-hint {
    font-size: 10px; text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--color-text-muted); padding: 4px 8px 2px;
}
.hw-suggest-item {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 8px; border-radius: var(--radius-sm, 6px);
    cursor: pointer; font-size: var(--font-size-sm, 13px);
}
.hw-suggest-item:hover, .hw-suggest-item.active {
    background: var(--color-bg-tertiary, rgba(255,255,255,0.06));
}
.hw-suggest-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hw-suggest-meta { font-size: 10px; color: var(--color-text-muted); flex-shrink: 0; }
.hw-suggest .agent-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.hw-suggest .agent-dot.online { background: var(--color-success, #22c55e); }
.hw-suggest .agent-dot.offline { background: var(--color-text-muted, #888); }
.hw-chat-inputbar textarea {
    flex: 1;
    resize: none;
    min-height: 38px;
    max-height: 96px;
    overflow-y: hidden; /* JS flips to auto only once the text exceeds max-height */
    padding: 8px 10px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm, 6px);
    background: var(--color-bg-primary, var(--color-bg-secondary));
    color: var(--color-text-primary);
    font-size: var(--font-size-sm, 13px);
    font-family: inherit;
}
.help-widget-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-sm, 8px);
    padding: var(--spacing-md, 14px);
    border-bottom: 1px solid var(--color-border);
    background: var(--color-bg, #0e0e1a);
}
.help-widget-header h3 {
    margin: 0;
    font-size: var(--font-size-md, 15px);
    color: var(--color-text-primary);
}
.help-widget-close {
    background: transparent;
    border: none;
    color: var(--color-text-muted);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    padding: 0 6px;
    border-radius: 4px;
}
.help-widget-close:hover {
    color: var(--color-text-primary);
    background: var(--color-surface-hover, rgba(255,255,255,0.06));
}
.help-widget-body {
    padding: var(--spacing-md, 14px);
    overflow-y: auto;
    color: var(--color-text-secondary);
    font-size: var(--font-size-sm);
    line-height: 1.55;
    /* Match the rest of the app's scrollbar palette. */
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}
.help-widget-body::-webkit-scrollbar { width: 8px; }
.help-widget-body::-webkit-scrollbar-track { background: var(--color-surface); border-radius: 4px; }
.help-widget-body::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 4px; }
.help-widget-body::-webkit-scrollbar-thumb:hover { background: var(--color-primary); }
.help-widget-body p { margin: 0 0 10px; }
.help-widget-body ul,
.help-widget-body ol {
    margin: 0 0 10px;
    padding-left: 18px;
}
.help-widget-body li {
    margin-bottom: 6px;
}
.help-widget-body code {
    background: var(--color-surface);
    padding: 1px 6px;
    border-radius: 3px;
    font-size: 12px;
}
.help-widget-body kbd {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 3px;
    padding: 1px 6px;
    font-size: 11px;
    font-family: var(--font-family-mono, monospace);
}
.help-widget-body em {
    font-style: normal;
    color: var(--color-text-primary);
    font-weight: 500;
}
/* Lead-in paragraph that opens every page's docs. Slightly emphasised
   so the operator can read the gist in one glance, then drop into the
   sections below for detail. */
.help-widget-overview {
    color: var(--color-text-primary);
    font-size: var(--font-size-sm);
    line-height: 1.55;
    margin-bottom: 14px;
    padding: 10px 12px;
    border-left: 3px solid var(--color-primary);
    background: var(--color-surface);
    border-radius: var(--radius-sm);
}
/* Each subheading separates a thematic chunk (Key Areas / How to / Tips
   / etc.). The bottom margin gives breathing room; the small top
   margin distinguishes one section from the next without feeling like
   a hard divider. */
.help-widget-section {
    margin-bottom: 14px;
}
.help-widget-section:last-child {
    margin-bottom: 0;
}
.help-widget-section-heading {
    margin: 12px 0 6px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-primary);
}
.help-widget-section:first-of-type .help-widget-section-heading {
    margin-top: 0;
}
.help-widget-section-body {
    color: var(--color-text-secondary);
}
.help-widget-footer {
    padding: 8px var(--spacing-md, 14px);
    border-top: 1px solid var(--color-border);
    color: var(--color-text-muted);
    font-size: 11px;
    background: var(--color-bg, #0e0e1a);
}

/* ── Documentation page (#docs) ────────────────────────────────────────── */
.docs-layout {
    display: grid;
    grid-template-columns: 260px 1fr;
    gap: var(--spacing-md);
    height: calc(100vh - 140px);
    align-items: stretch;
}
.docs-sidebar {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-bg-secondary);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}
.docs-search-wrap { padding: var(--spacing-sm); border-bottom: 1px solid var(--color-border); }
.docs-toc { overflow-y: auto; padding: var(--spacing-xs); min-height: 0; }
.docs-toc-item {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 10px; border-radius: var(--radius-sm);
    color: var(--color-text-secondary); text-decoration: none; font-size: var(--font-size-sm);
}
.docs-toc-item img { width: 18px; height: 18px; object-fit: contain; flex-shrink: 0; }
.docs-toc-item:hover { background: var(--color-bg-tertiary, rgba(255,255,255,0.05)); color: var(--color-text-primary); }
.docs-toc-item.active { background: var(--color-bg-tertiary, rgba(255,255,255,0.08)); color: var(--color-text-primary); font-weight: 600; }

.docs-content {
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-bg-primary, var(--color-bg-secondary));
    overflow-y: auto;
    padding: var(--spacing-lg);
    min-height: 0;
}
.docs-intro h1 { margin: 0 0 6px; font-size: 1.4rem; }
.docs-intro { margin-bottom: var(--spacing-lg); padding-bottom: var(--spacing-md); border-bottom: 1px solid var(--color-border); }

.docs-page { padding: var(--spacing-md) 0 var(--spacing-lg); border-bottom: 1px solid var(--color-border); scroll-margin-top: 8px; }
.docs-page:last-of-type { border-bottom: none; }
.docs-page-head { display: flex; align-items: flex-start; gap: 12px; margin-bottom: var(--spacing-sm); }
.docs-page-icon { width: 40px; height: 40px; object-fit: contain; flex-shrink: 0; border-radius: var(--radius-sm); }
.docs-page-head h2 { margin: 0 0 4px; font-size: 1.15rem; }
.docs-overview { margin: 0; color: var(--color-text-secondary); line-height: 1.55; }

.docs-figure { margin: var(--spacing-md) 0; }
.docs-figure img {
    width: 100%; max-width: 720px; display: block;
    border: 1px solid var(--color-border); border-radius: var(--radius-md); background: #000;
}
.docs-figure figcaption { font-size: 11px; color: var(--color-text-muted); margin-top: 4px; }

.docs-subsection { margin-top: var(--spacing-md); }
.docs-subsection h3 { font-size: 0.95rem; margin: 0 0 6px; color: var(--color-text-primary); }
.docs-prose { color: var(--color-text-secondary); line-height: 1.6; font-size: var(--font-size-sm); }
.docs-prose ul, .docs-prose ol { margin: 0 0 8px; padding-left: 20px; }
.docs-prose li { margin-bottom: 5px; }
.docs-prose code { background: var(--color-bg-tertiary, rgba(255,255,255,0.06)); padding: 1px 5px; border-radius: 3px; font-size: 0.9em; }
.docs-prose strong { color: var(--color-text-primary); }

.docs-back { margin-top: var(--spacing-md); }
.docs-back a { font-size: var(--font-size-xs); color: var(--color-primary); text-decoration: none; }

.docs-highlight { animation: docsFlash 1.6s ease; border-radius: var(--radius-md); }
@keyframes docsFlash {
    0% { background: var(--color-primary); box-shadow: 0 0 0 6px rgba(99,102,241,0.18); }
    100% { background: transparent; box-shadow: none; }
}

@media (max-width: 820px) {
    .docs-layout { grid-template-columns: 1fr; height: auto; }
    .docs-sidebar { height: auto; max-height: 280px; }
    .docs-content { height: auto; }
}

/*
 * Reflex DB search autocomplete. The dropdown anchors to the input via
 * absolute positioning inside .reflex-search-wrap. Keep it narrow (matches
 * input width, min 220px) so long values wrap rather than blow out the
 * card header. Matched substrings get a highlight via <mark>.
 */
.reflex-search-wrap {
    position: relative;
}
.reflex-search-suggest {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 4px;
    background: var(--color-bg-elevated, #1a1a2e);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
    max-height: 280px;
    overflow-y: auto;
    z-index: 1000;
    display: none;
    min-width: 220px;
    /* Match the rest of the app's scrollbar styling. */
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}
.reflex-search-suggest::-webkit-scrollbar {
    width: 8px;
}
.reflex-search-suggest::-webkit-scrollbar-track {
    background: var(--color-surface);
    border-radius: 4px;
}
.reflex-search-suggest::-webkit-scrollbar-thumb {
    background: var(--color-border);
    border-radius: 4px;
}
.reflex-search-suggest::-webkit-scrollbar-thumb:hover {
    background: var(--color-primary);
}
.reflex-search-suggest-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 12px;
    cursor: pointer;
    font-size: var(--font-size-xs);
    color: var(--color-text-primary);
    border-bottom: 1px solid var(--color-border-secondary, rgba(255,255,255,0.04));
    transition: background-color 0.1s ease;
}
.reflex-search-suggest-item:last-child {
    border-bottom: none;
}
.reflex-search-suggest-item:hover,
.reflex-search-suggest-item.reflex-search-suggest-active {
    background: var(--color-surface-hover, rgba(255,255,255,0.06));
}
.reflex-search-suggest-value {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}
.reflex-search-suggest-value mark {
    background: rgba(99, 102, 241, 0.25);
    color: var(--color-primary, #818cf8);
    padding: 0;
    border-radius: 2px;
    font-weight: 600;
}
.reflex-search-suggest-field {
    flex: 0 0 auto;
    font-size: 10px;
    color: var(--color-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    background: var(--color-surface);
    padding: 2px 6px;
    border-radius: 8px;
}

/*
 * Reflex DB "Jump to Live" highlight pulse. Briefly flashes the targeted
 * row on a yellow/green wash so the operator can spot it after a long
 * scroll-into-view. ~1.8s total — long enough to see, short enough not
 * to be annoying. Uses background-color only (no transform) so it
 * doesn't fight the table's existing row layout.
 */
@keyframes row-jump-flash-keys {
    0%   { background-color: rgba(34, 197, 94, 0.45); }
    50%  { background-color: rgba(34, 197, 94, 0.25); }
    100% { background-color: transparent; }
}
.row-jump-flash {
    animation: row-jump-flash-keys 1.8s ease-out;
}
.row-jump-flash > td {
    /* Make sure the wash sits above any odd/even row striping. */
    background-color: transparent !important;
}

/* Snap guide lines */
.pb-guide {
    position: absolute;
    z-index: 50;
    pointer-events: none;
}
.pb-guide-v {
    width: 1px;
    top: 0;
    background: rgba(255, 60, 100, 0.7);
}
.pb-guide-h {
    height: 1px;
    left: 0;
    background: rgba(255, 60, 100, 0.7);
}

/* Toggleable alignment grid overlay — uses ::after so it doesn't clobber background-image */
.pb-canvas.pb-grid-on::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 40;
    background-image:
        linear-gradient(to right, rgba(255,255,255,0.15) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(255,255,255,0.15) 1px, transparent 1px),
        linear-gradient(to right, rgba(100,180,255,0.3) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(100,180,255,0.3) 1px, transparent 1px);
    background-size: 40px 40px, 40px 40px, 200px 200px, 200px 200px;
}

@media (max-width: 900px) {
    /* On narrow viewports we stack the three panels vertically. The
       !important here defeats the inline `grid-template-columns` that
       renderPbEditor sets to handle the collapsed-panel stub widths
       (28px / 160px / 220px). On mobile the operator should always see
       the full toolbar above and props below the canvas regardless of
       desktop collapse preferences. */
    .pb-editor-layout {
        grid-template-columns: 1fr !important;
        grid-template-rows: auto 1fr auto;
    }
    .pb-toolbar {
        max-height: none;
    }
    .pb-props-panel {
        max-height: none;
    }
    /* Hide the collapse stubs on mobile — they don't make sense in a
       stacked layout. */
    .pb-panel-stub {
        display: none;
    }
    /* Hide the resize handles on mobile — they'd render as meaningless
       horizontal 6px strips between stacked panels. */
    .pb-resize-handle-col {
        display: none;
    }
}

/* ==================== Agent Chat ==================== */

.agent-layout {
    display: flex;
    flex-direction: row;
    height: calc(100vh - 140px);
    gap: 0;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--color-bg-primary);
}

/* Sidebar config list */
.agent-sidebar {
    width: 280px;
    min-width: 280px;
    background: var(--color-bg-secondary);
    border-right: 1px solid var(--color-border);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

/* Hidden by default — toggled open via the header "☰ Chats" button. */
.agent-sidebar.collapsed {
    display: none;
}

.agent-sidebar-header {
    padding: var(--spacing-md);
    border-bottom: 1px solid var(--color-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-sm);
}

.agent-sidebar-header h4 {
    margin: 0;
    font-size: var(--font-size-sm);
    font-weight: 600;
    color: var(--color-text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.agent-config-list {
    flex: 1;
    overflow-y: auto;
    padding: var(--spacing-xs);
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}

.agent-config-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--spacing-sm) var(--spacing-md);
    margin-bottom: 2px;
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: background 0.15s;
    gap: var(--spacing-sm);
}

.agent-config-item:hover {
    background: var(--color-bg-elevated);
}

.agent-config-item.active {
    background: hsla(var(--accent-h), var(--accent-s), var(--accent-l), 0.15);
    border: 1px solid hsla(var(--accent-h), var(--accent-s), var(--accent-l), 0.3);
}

.agent-config-item-info {
    flex: 1;
    min-width: 0;
    overflow: hidden;
}

.agent-config-item-name {
    font-size: var(--font-size-sm);
    font-weight: 500;
    color: var(--color-text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.agent-config-item-meta {
    font-size: 11px;
    color: var(--color-text-muted);
    display: flex;
    gap: var(--spacing-xs);
    margin-top: 2px;
}

.agent-config-item-actions {
    display: flex;
    gap: 4px;
    opacity: 0;
    transition: opacity 0.15s;
}

.agent-config-item:hover .agent-config-item-actions {
    opacity: 1;
}

.agent-config-item-actions .btn {
    padding: 2px 6px;
    font-size: 11px;
}

/* Chat area */
.agent-chat-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    min-width: 0;
    background: var(--color-bg-primary);
}

.agent-chat-empty {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    color: var(--color-text-muted);
    gap: var(--spacing-md);
    padding: var(--spacing-xl);
    text-align: center;
}

.agent-chat-empty-icon {
    font-size: 3rem;
    opacity: 0.4;
}

.agent-chat-empty h3 {
    color: var(--color-text-secondary);
    margin: 0;
}

.agent-chat-empty p {
    max-width: 400px;
    line-height: 1.5;
}

/* Messages area */
.agent-chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: var(--spacing-lg);
    display: flex;
    flex-direction: column;
    gap: var(--spacing-md);
    scrollbar-width: thin;
    scrollbar-color: var(--color-border) var(--color-surface);
}

.agent-chat-messages::-webkit-scrollbar,
.agent-config-list::-webkit-scrollbar {
    width: 8px;
}

.agent-chat-messages::-webkit-scrollbar-track,
.agent-config-list::-webkit-scrollbar-track {
    background: var(--color-surface);
    border-radius: 4px;
}

.agent-chat-messages::-webkit-scrollbar-thumb,
.agent-config-list::-webkit-scrollbar-thumb {
    background: var(--color-border);
    border-radius: 4px;
}

.agent-chat-messages::-webkit-scrollbar-thumb:hover,
.agent-config-list::-webkit-scrollbar-thumb:hover {
    background: var(--color-primary);
}

.agent-message {
    display: flex;
    flex-direction: column;
    max-width: 75%;
    animation: agentMsgIn 0.2s ease;
}

@keyframes agentMsgIn {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

.agent-message.user {
    align-self: flex-end;
}

.agent-message.assistant {
    align-self: flex-start;
}

.agent-message-content {
    padding: var(--spacing-sm) var(--spacing-md);
    border-radius: var(--radius-lg);
    font-size: var(--font-size-sm);
    line-height: 1.6;
    word-wrap: break-word;
    overflow-wrap: break-word;
}

.agent-message.user .agent-message-content {
    background: hsla(var(--accent-h), var(--accent-s), var(--accent-l), 0.2);
    border: 1px solid hsla(var(--accent-h), var(--accent-s), var(--accent-l), 0.3);
    color: var(--color-text-primary);
    border-bottom-right-radius: var(--radius-sm);
}

.agent-message.assistant .agent-message-content {
    background: var(--color-bg-elevated);
    border: 1px solid var(--color-border);
    color: var(--color-text-primary);
    border-bottom-left-radius: var(--radius-sm);
}

.agent-message-content code {
    background: rgba(0,0,0,0.2);
    padding: 1px 5px;
    border-radius: var(--radius-sm);
    font-family: 'JetBrains Mono', monospace;
    font-size: 0.9em;
}

.agent-message-content pre {
    background: rgba(0,0,0,0.25);
    padding: var(--spacing-sm);
    border-radius: var(--radius-sm);
    overflow-x: auto;
    margin: var(--spacing-xs) 0;
}

.agent-message-content pre code {
    background: none;
    padding: 0;
}

.agent-message-time {
    font-size: 10px;
    color: var(--color-text-muted);
    margin-top: 4px;
    padding: 0 var(--spacing-sm);
}

.agent-message.user .agent-message-time {
    text-align: right;
}

/* Input bar */
.agent-chat-input-bar {
    display: flex;
    align-items: flex-end;
    gap: var(--spacing-sm);
    padding: var(--spacing-md);
    border-top: 1px solid var(--color-border);
    background: var(--color-bg-secondary);
    position: relative; /* anchor for the autocomplete popover */
}

/* ── Agent typing autocomplete popover ─────────────────────────────────── */
.agent-suggest {
    position: absolute;
    left: var(--spacing-md);
    right: var(--spacing-md);
    bottom: calc(100% - 4px);
    max-height: 240px;
    overflow-y: auto;
    background: var(--color-bg-elevated, var(--color-bg-secondary));
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.35);
    z-index: 40;
    padding: 4px;
}
.agent-suggest-hint {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-text-muted);
    padding: 4px 8px 2px;
}
.agent-suggest-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--font-size-sm);
}
.agent-suggest-item:hover,
.agent-suggest-item.active {
    background: var(--color-bg-tertiary, rgba(255, 255, 255, 0.06));
}
.agent-suggest-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.agent-suggest-meta { font-size: 10px; color: var(--color-text-muted); flex-shrink: 0; }
.agent-suggest .agent-dot {
    width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0;
}
.agent-suggest .agent-dot.online { background: var(--color-success, #22c55e); }
.agent-suggest .agent-dot.offline { background: var(--color-text-muted, #888); }

.agent-chat-input-bar textarea {
    flex: 1;
    resize: none;
    min-height: 40px;
    max-height: 120px;
    padding: var(--spacing-sm) var(--spacing-md);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-bg-primary);
    color: var(--color-text-primary);
    font-family: inherit;
    font-size: var(--font-size-sm);
    line-height: 1.5;
    outline: none;
    transition: border-color 0.15s;
}

.agent-chat-input-bar textarea:focus {
    border-color: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
}

.agent-chat-input-bar textarea::placeholder {
    color: var(--color-text-muted);
}

.agent-chat-input-bar .btn {
    height: 40px;
    min-width: 72px;
}

/* Typing / thinking indicator */
.agent-typing {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: var(--spacing-sm) var(--spacing-md);
    color: var(--color-text-muted);
    font-size: var(--font-size-xs);
}

.agent-typing-dots {
    display: flex;
    gap: 3px;
}

.agent-typing-dot {
    width: 6px;
    height: 6px;
    background: var(--color-text-muted);
    border-radius: 50%;
    animation: agentBounce 1.2s ease-in-out infinite;
}

.agent-typing-dot:nth-child(2) { animation-delay: 0.15s; }
.agent-typing-dot:nth-child(3) { animation-delay: 0.3s; }

@keyframes agentBounce {
    0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
    30% { transform: translateY(-4px); opacity: 1; }
}

/* Welcome message */
.agent-welcome {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    flex: 1;
    text-align: center;
    color: var(--color-text-muted);
    gap: var(--spacing-sm);
    padding: var(--spacing-xl);
}

.agent-welcome-icon {
    font-size: 2.5rem;
    opacity: 0.5;
}

/* Wizard step indicators */
.agent-wizard-steps {
    display: flex;
    gap: var(--spacing-xs);
    margin-bottom: var(--spacing-lg);
}

.agent-wizard-step {
    flex: 1;
    height: 4px;
    border-radius: 2px;
    background: var(--color-border);
    transition: background 0.2s;
}

.agent-wizard-step.active {
    background: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
}

.agent-wizard-step.done {
    background: hsl(var(--accent-h), var(--accent-s), calc(var(--accent-l) + 15%));
}

/* Responsive */
@media (max-width: 768px) {
    .agent-layout {
        flex-direction: column;
        height: calc(100vh - 120px);
    }
    .agent-sidebar {
        width: 100%;
        min-width: unset;
        max-height: 200px;
        border-right: none;
        border-bottom: 1px solid var(--color-border);
    }
    .agent-message {
        max-width: 90%;
    }
}

/* Inline schedule card inside chat bubble */
.inline-sched-card .form-select,
.inline-sched-card .form-input {
    background: var(--color-bg-primary);
    border-color: var(--color-border);
    font-size: var(--font-size-xs);
}

.inline-sched-card .form-select:focus,
.inline-sched-card .form-input:focus {
    border-color: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
}

/* ==================== Media Management ==================== */

/* Quick Schedule timing toggle */
.qs-timing-btn.active {
    background: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
    color: #fff;
    border-color: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
}

.media-layout {
    display: flex;
    flex-direction: column;
    gap: var(--spacing-md);
}

.media-tabs {
    display: flex;
    gap: var(--spacing-xs);
    border-bottom: 1px solid var(--color-border);
    padding-bottom: var(--spacing-xs);
}

.media-tab {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
    padding: var(--spacing-sm) var(--spacing-md);
    border: none;
    background: none;
    color: var(--color-text-muted);
    font-size: var(--font-size-sm);
    font-weight: 500;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    transition: color 0.15s, border-color 0.15s;
    border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}

.media-tab:hover {
    color: var(--color-text-primary);
    background: var(--color-bg-elevated);
}

.media-tab.active {
    color: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
    border-bottom-color: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
}

/* Breadcrumb */
.media-breadcrumb {
    display: flex;
    align-items: center;
    gap: var(--spacing-xs);
    font-size: var(--font-size-sm);
    padding: var(--spacing-xs) var(--spacing-sm);
    flex-wrap: wrap;
}

.media-crumb-link {
    color: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
    cursor: pointer;
    font-weight: 500;
    transition: opacity 0.15s;
}

.media-crumb-link:hover {
    opacity: 0.8;
    text-decoration: underline;
}

.media-crumb-sep {
    color: var(--color-text-muted);
}

.media-crumb-current {
    color: var(--color-text-primary);
    font-weight: 600;
}

.media-info-bar {
    display: flex;
    align-items: center;
    gap: var(--spacing-md);
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    padding: var(--spacing-xs) var(--spacing-sm);
}

.media-info-hint {
    margin-left: auto;
    font-style: italic;
}

.media-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: var(--spacing-md);
}

.media-grid .empty-state {
    grid-column: 1 / -1;
}

.media-card {
    background: var(--color-bg-secondary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
    transition: border-color 0.15s, box-shadow 0.15s;
}

.media-card:hover {
    border-color: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.media-card-preview {
    width: 100%;
    height: 140px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-bg-primary);
    cursor: pointer;
    overflow: hidden;
}

.media-card-preview img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.media-file-icon {
    font-size: 2rem;
    opacity: 0.5;
}

.media-folder-preview {
    background: var(--color-bg-elevated) !important;
}

.media-folder-icon {
    font-size: 3rem;
    opacity: 0.7;
}

.media-card-folder {
    border-style: dashed;
}

.media-card-folder:hover {
    border-style: solid;
}

/* Source-type folder cards on the unified Media root — visually distinct
   from regular subfolders so the operator can tell at a glance which
   bucket they're entering when they click in. */
.media-card-source-site .media-folder-preview {
    background: linear-gradient(135deg, rgba(34, 197, 94, 0.18), rgba(34, 197, 94, 0.04));
}
.media-card-source-external .media-folder-preview {
    background: linear-gradient(135deg, rgba(59, 130, 246, 0.18), rgba(59, 130, 246, 0.04));
}
.media-card-source-site,
.media-card-source-external {
    border-style: solid;
}

/* List-mode equivalents — gentle row tint so the source entries still
   read as distinct from regular folders when the operator flips to List. */
.media-list-row.media-list-source-site > td {
    background: rgba(34, 197, 94, 0.05);
}
.media-list-row.media-list-source-external > td {
    background: rgba(59, 130, 246, 0.05);
}

.media-card-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--spacing-sm);
    gap: var(--spacing-xs);
}

.media-card-name {
    font-size: var(--font-size-xs);
    font-weight: 500;
    color: var(--color-text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
}

.media-card-size {
    font-size: var(--font-size-xs);
    color: var(--color-text-muted);
    white-space: nowrap;
}

.media-card-actions {
    display: flex;
    gap: var(--spacing-xs);
    padding: 0 var(--spacing-sm) var(--spacing-sm);
    flex-wrap: wrap;
}

.media-card-actions .btn {
    font-size: 11px;
    padding: 2px 8px;
}

/* Upload modal */
.media-upload-zone {
    border: 2px dashed var(--color-border);
    border-radius: var(--radius-md);
    padding: var(--spacing-xl);
    text-align: center;
    cursor: pointer;
    transition: border-color 0.2s, background 0.2s;
}

.media-upload-zone:hover,
.media-upload-zone.drag-over {
    border-color: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
    background: hsla(var(--accent-h), var(--accent-s), var(--accent-l), 0.05);
}

.media-upload-content {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.media-upload-list {
    margin-top: var(--spacing-md);
    max-height: 200px;
    overflow-y: auto;
}

.media-upload-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-sm);
    padding: var(--spacing-xs) var(--spacing-sm);
    border-bottom: 1px solid var(--color-border);
    font-size: var(--font-size-xs);
}

.media-upload-progress {
    margin-top: var(--spacing-md);
}

.progress-bar {
    width: 100%;
    height: 6px;
    background: var(--color-bg-elevated);
    border-radius: 3px;
    overflow: hidden;
}

.progress-bar-fill {
    height: 100%;
    background: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
    border-radius: 3px;
    transition: width 0.2s;
}

@media (max-width: 768px) {
    .media-grid {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    }
    .media-card-preview {
        height: 100px;
    }
}

/* ==================== Tasks Page ==================== */
.tasks-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
    gap: var(--spacing-sm);
}

.task-card {
    background: var(--color-bg-primary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    padding: 12px 14px;
    transition: border-color var(--transition-fast);
}

.task-card:hover {
    border-color: var(--color-border-light);
}

.task-card.task-pending {
    border-left: 3px solid var(--color-warning, #f59e0b);
}

.task-card.task-completed {
    border-left: 3px solid var(--color-success, #22c55e);
    opacity: 0.7;
}

.task-card.task-cancelled {
    border-left: 3px solid var(--color-text-muted);
    opacity: 0.55;
}

.task-card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 6px;
}

.task-card-type {
    font-size: var(--font-size-xs);
    font-weight: 600;
    color: var(--color-text-primary);
}

.task-card-target {
    font-size: var(--font-size-xs);
    font-weight: 500;
    color: var(--color-text-primary);
    margin-bottom: 4px;
}

.task-card-detail {
    font-size: 11px;
    color: var(--color-text-muted);
    line-height: 1.4;
    margin-bottom: 4px;
}

.task-card-meta {
    font-size: 10px;
    color: var(--color-text-muted);
    margin-top: 6px;
}

@media (max-width: 768px) {
    .tasks-grid {
        grid-template-columns: 1fr;
    }
}

/* ==================== Groups Editor (shared chip UI) ==================== */
.cv-groups-editor {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.cv-groups-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
    min-height: 34px;
    padding: 6px 8px;
    background: var(--color-bg-secondary, #1a1d24);
    border: 1px solid var(--color-border, #2a2f38);
    border-radius: 6px;
}
.cv-group-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 4px 3px 10px;
    background: var(--color-primary-900, #4338ca);
    color: #fff;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 500;
    line-height: 1.2;
}
.cv-group-chip-label { white-space: nowrap; }
.cv-group-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    margin-left: 2px;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.18);
    color: #fff;
    cursor: pointer;
    font-size: 0.95rem;
    line-height: 1;
}
.cv-group-chip-remove:hover { background: rgba(255, 255, 255, 0.35); }
.cv-group-add-btn {
    padding: 4px 10px;
    border: 1px dashed var(--color-border, #2a2f38);
    background: transparent;
    color: var(--color-text-muted, #9ca3af);
    border-radius: 999px;
    cursor: pointer;
    font-size: 0.85rem;
}
.cv-group-add-btn:hover {
    color: var(--color-text, #e5e7eb);
    border-color: var(--color-primary, #6366f1);
}
.cv-group-empty {
    font-size: 0.85rem;
    font-style: italic;
}
.cv-groups-add-form {
    display: flex;
    gap: 6px;
    align-items: center;
}
.cv-groups-add-form .form-input { flex: 1; }
.cv-groups-suggest {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    align-items: center;
}
.cv-group-suggest {
    padding: 2px 8px;
    border: 1px solid var(--color-border, #2a2f38);
    background: transparent;
    color: var(--color-text-muted, #9ca3af);
    border-radius: 999px;
    cursor: pointer;
    font-size: 0.75rem;
}
.cv-group-suggest:hover {
    color: var(--color-text, #e5e7eb);
    border-color: var(--color-primary, #6366f1);
    background: var(--color-primary-900, rgba(99, 102, 241, 0.15));
}

/* ==================== Media Toolbar (search + view toggle) ==================== */
.media-toolbar {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem 0 0.75rem 0;
    margin-bottom: 0.25rem;
    flex-wrap: wrap;
}
.media-search-wrap {
    position: relative;
    display: flex;
    align-items: center;
    flex: 1 1 320px;
    max-width: 520px;
    min-width: 200px;
}
.media-search-icon {
    position: absolute;
    left: 10px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 0.875rem;
    color: var(--color-text-muted);
    pointer-events: none;
    opacity: 0.7;
}
.media-search-input {
    width: 100%;
    height: 36px;
    padding: 0 2.25rem 0 2rem;
    font-size: 0.875rem;
    border-radius: var(--radius-md, 8px);
    background: var(--color-bg-secondary);
    border: 1px solid var(--color-border);
    transition: border-color 0.15s, box-shadow 0.15s;
}
.media-search-input:focus {
    border-color: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
    box-shadow: 0 0 0 3px hsla(var(--accent-h), var(--accent-s), var(--accent-l), 0.15);
    outline: none;
}
.media-search-input::-webkit-search-cancel-button {
    display: none;
}
.media-search-clear {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    width: 22px;
    height: 22px;
    border: none;
    background: transparent;
    color: var(--color-text-muted);
    border-radius: 50%;
    cursor: pointer;
    display: none;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    line-height: 1;
    transition: background 0.12s, color 0.12s;
}
.media-search-clear:hover {
    background: var(--color-bg-elevated, rgba(255, 255, 255, 0.08));
    color: var(--color-text, #e5e7eb);
}
.media-view-toggle {
    display: inline-flex;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md, 8px);
    background: var(--color-bg-secondary);
    flex-shrink: 0;
}
.media-view-toggle .media-view-btn {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 6px 12px;
    height: 28px;
    font-size: 0.8rem;
    color: var(--color-text-muted);
    background: transparent;
    border: none;
    border-radius: var(--radius-sm, 6px);
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
.media-view-toggle .media-view-btn:hover {
    color: var(--color-text, #e5e7eb);
}
.media-view-toggle .media-view-btn.active {
    background: var(--color-primary-900, rgba(99, 102, 241, 0.22));
    color: var(--color-text, #e5e7eb);
}
.media-view-btn-icon {
    font-size: 0.85rem;
    line-height: 1;
}

/* Path badge for search results */
.media-path-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.7rem;
    color: var(--color-text-muted);
    background: var(--color-bg-primary);
    padding: 2px 6px;
    border-radius: 4px;
    margin-top: 2px;
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-family: var(--font-family-mono, monospace);
}
.media-path-badge.media-path-root {
    font-style: italic;
    opacity: 0.7;
}
.media-list-sub {
    margin-top: 3px;
}

.media-search-diag {
    display: block;
    width: 100%;
    margin-top: 6px;
    font-size: 0.75rem;
    color: var(--color-text-muted);
}
.media-search-diag > summary {
    cursor: pointer;
    user-select: none;
    padding: 2px 0;
    color: var(--color-text-muted);
    list-style: disclosure-closed;
}
.media-search-diag[open] > summary {
    list-style: disclosure-open;
}
.media-search-diag-body {
    margin-top: 6px;
    padding: 8px 10px;
    background: var(--color-bg-primary);
    border: 1px solid var(--color-border);
    border-radius: 6px;
    font-family: var(--font-family-mono, monospace);
    line-height: 1.6;
}

@media (max-width: 640px) {
    .media-toolbar {
        flex-direction: column;
        align-items: stretch;
    }
    .media-search-wrap {
        max-width: none;
    }
    .media-view-toggle {
        align-self: flex-start;
    }
}

/* ==================== Media List View ==================== */
.media-grid.media-grid-list {
    display: block;
    gap: 0;
}
.media-list-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--color-bg-secondary);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    overflow: hidden;
}
.media-list-table thead th {
    text-align: left;
    padding: 10px 12px;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-muted);
    background: var(--color-bg-primary);
    border-bottom: 1px solid var(--color-border);
}
.media-list-table tbody tr {
    border-bottom: 1px solid var(--color-border);
    transition: background 0.12s;
}
.media-list-table tbody tr:last-child {
    border-bottom: none;
}
.media-list-table tbody tr:hover {
    background: var(--color-bg-elevated, rgba(255, 255, 255, 0.03));
}
.media-list-table td {
    padding: 8px 12px;
    font-size: 0.875rem;
    vertical-align: middle;
}
.media-list-icon {
    width: 40px;
    text-align: center;
}
.media-folder-icon-sm {
    font-size: 1.25rem;
}
.media-list-name .media-list-link {
    color: var(--color-text, #e5e7eb);
    cursor: pointer;
    text-decoration: none;
}
.media-list-name .media-list-link:hover {
    color: hsl(var(--accent-h), var(--accent-s), var(--accent-l));
    text-decoration: underline;
}
.media-list-type,
.media-list-size {
    color: var(--color-text-muted);
    font-size: 0.8rem;
}
.media-list-actions {
    white-space: nowrap;
    text-align: right;
}
.media-list-actions .btn {
    margin-left: 4px;
}

