/* ==========================================================================
   OneTab Media Network - Final UI/UX Overhaul (Clean, Solid, Data-Focused)
   ========================================================================== */

:root {
  /* --- 1. Color Palette (Premium Indigo Slate) --- */
  --ot-bg-base: #0a0b10 !important;
  --ot-bg-surface: #12131a !important;
  --ot-bg-elevated: #1b1c26 !important;
  --ot-bg-hover: #222433 !important;

  --ot-border: rgba(255, 255, 255, 0.08) !important;
  --ot-border-focus: #6366f1 !important;

  --ot-text-primary: #f8fafc !important;
  --ot-text-secondary: #94a3b8 !important;
  --ot-text-muted: #64748b !important;

  --ot-accent: #6366f1 !important;
  --ot-accent-hover: #4f46e5 !important;
  --ot-accent-soft: rgba(99, 102, 241, 0.15) !important;

  /* Status Colors */
  --ot-status-success: #10B981;
  --ot-status-warning: #F59E0B;
  --ot-status-danger: #EF4444;

  /* --- 2. Typography --- */
  --ot-font-sans: 'Roboto', 'Inter', system-ui, sans-serif;
  --ot-font-mono: 'Roboto Mono', 'JetBrains Mono', monospace;
  --ot-font-weight-regular: 400;
  --ot-font-weight-medium: 500;
  --ot-font-weight-bold: 600;

  /* --- 3. Spacing & Radius --- */
  --ot-space-xs: 4px;
  --ot-space-sm: 8px;
  --ot-space-md: 16px;
  --ot-space-lg: 24px;
  --ot-space-xl: 32px;

  --ot-radius: 12px !important;
  --ot-radius-sm: 6px;

  /* --- 4. Utilities --- */
  --ot-transition: all 0.15s ease-in-out;

  /* --- 5. Solid Design System Overrides --- */
  --ot-sidebar-w: 216px !important; /* 2026-07-15: slimmed from 260px */
  --ot-bg: var(--ot-bg-base) !important;
  --bg: var(--ot-bg-base) !important;
  --ot-glass-blur: none !important;
  --ot-glass-bg: var(--ot-bg-surface) !important;
  --ot-glass-border: 1px solid var(--ot-border) !important;
  --ot-glass-border-glow: 1px solid var(--ot-border) !important;
  --ot-glass-shadow: 0 4px 20px -2px rgba(0, 0, 0, 0.4), 0 0 20px rgba(99, 102, 241, 0.03) !important;
  --ot-shadow-1: 0 1px 3px rgba(0,0,0,0.25) !important;
  --ot-shadow-2: 0 4px 12px rgba(0,0,0,0.3) !important;
  --ot-shadow-3: 0 12px 24px rgba(0,0,0,0.5) !important;
}

/* ==========================================================================
   Base Styles
   ========================================================================== */
body.ot-body, body.ot-body-v2 {
  background-color: var(--ot-bg-base) !important;
  background: var(--ot-bg-base) !important;
  color: var(--ot-text-primary);
  font-family: var(--ot-font-sans);
  line-height: 1.5;
  margin: 0;
  -webkit-font-smoothing: antialiased;
}
body.ot-body::before, body.ot-body-v2::before {
  display: none !important; /* Hide purple gradient radial background overlay */
}

h1, h2, h3, h4, h5, h6 {
  color: var(--ot-text-primary);
  margin-top: 0;
  font-weight: var(--ot-font-weight-bold);
}

a {
  color: var(--ot-accent);
  text-decoration: none;
  transition: var(--ot-transition);
}
a:hover {
  color: var(--ot-accent-hover);
}

/* ==========================================================================
   Layout Helpers
   ========================================================================== */
.ot-grid-v2 {
  display: grid;
  gap: var(--ot-space-lg);
}
.ot-grid-cols-2 { grid-template-columns: repeat(2, 1fr); }
.ot-grid-cols-3 { grid-template-columns: repeat(3, 1fr); }
.ot-grid-cols-4 { grid-template-columns: repeat(4, 1fr); }

.ot-flex { display: flex; }
.ot-flex-col { flex-direction: column; }
.ot-items-center { align-items: center; }
.ot-justify-between { justify-content: space-between; }
.ot-gap-sm { gap: var(--ot-space-sm); }
.ot-gap-md { gap: var(--ot-space-md); }

/* ==========================================================================
   Components
   ========================================================================== */

/* Cards (.ot-card-v2) */
.ot-card-v2 {
  background: var(--ot-bg-surface) !important;
  border: 1px solid var(--ot-border) !important;
  border-radius: var(--ot-radius) !important;
  padding: var(--ot-space-lg) !important;
  box-shadow: var(--ot-shadow-2) !important;
  display: flex !important;
  flex-direction: column !important;
  gap: 12px !important;
}

.ot-card-v2-header {
  display: flex !important;
  justify-content: space-between !important;
  align-items: center !important;
  border-bottom: none !important;
  padding-bottom: 0 !important;
  margin-bottom: 0 !important;
  margin-top: 0 !important;
}

.ot-card-v2-title {
  font-size: 0.875rem !important; /* 14px */
  font-weight: var(--ot-font-weight-medium) !important;
  color: var(--ot-text-secondary) !important;
  text-transform: uppercase !important;
  letter-spacing: 0.05em !important;
  margin: 0 !important;
}

.ana-kpi-val {
  font-family: var(--ot-font-mono) !important;
  font-size: 2.25rem !important; /* 36px */
  font-weight: var(--ot-font-weight-bold) !important;
  color: var(--ot-text-primary) !important;
  line-height: 1.1 !important;
  margin: 0 !important;
}

.ana-kpi-sub {
  font-size: 0.825rem !important; /* 13px */
  color: var(--ot-text-muted) !important;
  margin: 0 !important;
  line-height: 1.3 !important;
}

/* Tables (.ot-table-v2) */
.ot-table-wrapper {
  width: auto !important;
  overflow-x: auto !important;
  background: var(--ot-bg-surface) !important;
  border: 1px solid var(--ot-border) !important;
  border-radius: var(--ot-radius) !important;
  -webkit-overflow-scrolling: touch !important;
  box-shadow: none !important;
  margin: 0 24px 24px 24px !important;
}

.ot-table-v2 {
  width: 100% !important;
  border-collapse: collapse !important;
  text-align: left !important;
  font-size: 0.875rem !important; /* 14px */
}

.ot-table-v2 th, .ot-table-v2 td {
  padding: 12px 16px !important;
  border-bottom: 1px solid var(--ot-border) !important;
  white-space: nowrap !important;
  line-height: 1.4 !important;
}

/* Add breathing room on the left and right edges of the table */
.ot-table-v2 th:first-child, .ot-table-v2 td:first-child {
  padding-left: 20px !important;
}
.ot-table-v2 th:last-child, .ot-table-v2 td:last-child {
  padding-right: 20px !important;
}

.ot-table-v2 th {
  background: var(--ot-bg-elevated) !important;
  color: var(--ot-text-secondary) !important;
  font-weight: var(--ot-font-weight-medium) !important;
  text-transform: uppercase !important;
  font-size: 0.75rem !important;
  letter-spacing: 0.06em !important;
  position: sticky !important;
  top: 0 !important;
  z-index: 10 !important;
}

.ot-table-v2 tr {
  background: var(--ot-bg-surface) !important;
  transition: background var(--ot-transition) !important;
}

.ot-table-v2 tr:hover td {
  background: var(--ot-bg-hover) !important;
}

.ot-table-v2 td {
  color: var(--ot-text-primary) !important;
}

.ot-truncate {
  max-width: 250px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  display: inline-block;
  vertical-align: middle;
}

/* Top Navigation Bar Overrides */
.ot-topbar {
  background: var(--ot-bg-surface) !important;
  border-bottom: 1px solid var(--ot-border) !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* Buttons (.ot-btn-v2) */
.ot-btn-v2 {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--ot-space-sm);
  padding: 8px 16px;
  border-radius: var(--ot-radius-sm);
  font-weight: var(--ot-font-weight-medium);
  font-size: 0.875rem;
  cursor: pointer;
  transition: var(--ot-transition);
  border: 1px solid transparent;
  font-family: var(--ot-font-sans);
  box-shadow: none !important;
}

.ot-btn-primary {
  background: var(--ot-accent) !important;
  color: #fff !important;
  border-color: var(--ot-accent) !important;
  box-shadow: none !important;
}
.ot-btn-primary:hover {
  background: var(--ot-accent-hover) !important;
  border-color: var(--ot-accent-hover) !important;
  box-shadow: none !important;
}

.ot-btn-secondary {
  background: var(--ot-bg-elevated) !important;
  color: var(--ot-text-primary) !important;
  border-color: var(--ot-border) !important;
  box-shadow: none !important;
}
.ot-btn-secondary:hover {
  background: var(--ot-bg-hover) !important;
  border-color: var(--ot-border) !important;
  box-shadow: none !important;
}

/* Inputs (.ot-input-v2), Selects (.ot-select-v2), Textareas (.ot-textarea-v2) */
.ot-input-v2,
.ot-select-v2,
.ot-textarea-v2 {
  width: 100%;
  padding: 8px 12px;
  background: var(--ot-bg-base) !important;
  border: 1px solid var(--ot-border) !important;
  border-radius: var(--ot-radius-sm) !important;
  color: var(--ot-text-primary) !important;
  font-family: inherit;
  font-size: 0.875rem;
  transition: var(--ot-transition);
}

.ot-input-v2:focus,
.ot-select-v2:focus,
.ot-textarea-v2:focus,
#filterInp:focus,
#sortCol:focus {
  outline: none !important;
  border-color: var(--ot-border-focus) !important;
  box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2), 0 0 12px rgba(99, 102, 241, 0.1) !important;
}

/* Badges (.ot-badge-v2) and status/custom badges */
.ot-badge-v2,
.miss-badge,
.restrict-badge {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  padding: 3px 8px !important;
  border-radius: 4px !important;
  font-size: 0.75rem !important;
  font-weight: 600 !important;
  text-transform: uppercase !important;
  letter-spacing: 0.05em !important;
  line-height: 1 !important;
  border: 1px solid transparent !important;
}

.ot-badge-success,
.restrict-badge {
  background: rgba(16, 185, 129, 0.1) !important;
  color: var(--ot-status-success) !important;
  border-color: rgba(16, 185, 129, 0.25) !important;
}

.ot-badge-warning,
.miss-badge.miss-long {
  background: rgba(245, 158, 11, 0.1) !important;
  color: var(--ot-status-warning) !important;
  border-color: rgba(245, 158, 11, 0.25) !important;
}

.ot-badge-danger,
.miss-badge.miss-shorts {
  background: rgba(239, 68, 68, 0.1) !important;
  color: var(--ot-status-danger) !important;
  border-color: rgba(239, 68, 68, 0.25) !important;
}

.ot-badge-info {
  background: var(--ot-accent-soft) !important;
  color: var(--ot-accent) !important;
  border-color: rgba(99, 102, 241, 0.3) !important;
}

/* Sidebar Navigation Overrides */
@media (min-width: 1025px) {
  .ot-app {
    grid-template-columns: var(--ot-sidebar-w) minmax(0, 1fr) !important;
  }
}

@media (min-width: 861px) {
  .ana-shell {
    grid-template-columns: var(--ot-sidebar-w) minmax(0, 1fr) !important;
  }
}

@media (min-width: 761px) {
  .adm-shell {
    grid-template-columns: var(--ot-sidebar-w) minmax(0, 1fr) !important;
  }
}

.ot-sidebar, .ana-sidebar, .adm-sidebar {
  background: var(--ot-bg-surface) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border-right: 1px solid var(--ot-border) !important;
  box-shadow: none !important;
  width: var(--ot-sidebar-w) !important;
  min-width: var(--ot-sidebar-w) !important;
  max-width: var(--ot-sidebar-w) !important;
  flex-shrink: 0 !important;
}

.ot-sidebar::before, .ana-sidebar::before, .adm-sidebar::before {
  display: none !important;
}

.ot-sidebar-nav, .ot-sb-nav, .ana-sb-section, .adm-sb-nav, .adm-sb-section {
  display: flex !important;
  flex-direction: column !important;
  gap: 4px !important;
}

.ot-sb-group, .ana-sb-section, .adm-sb-section {
  margin-bottom: 16px !important;
}

.ot-sb-group-label, .ana-sb-label, .adm-sb-label {
  font-size: 0.75rem !important; /* 12px */
  color: var(--ot-text-secondary) !important;
  text-transform: uppercase !important;
  letter-spacing: 0.06em !important;
  padding: 0 16px !important;
  margin-bottom: 6px !important;
  font-weight: var(--ot-font-weight-medium) !important;
}

.ot-nav-item, .ana-sb-item, .adm-sb-item {
  display: flex !important;
  align-items: center !important;
  gap: 12px !important;
  padding: 10px 16px !important;
  margin: 2px 8px !important;
  border-radius: var(--ot-radius-sm) !important;
  font-size: 0.875rem !important; /* 14px */
  color: var(--ot-text-secondary) !important;
  transition: var(--ot-transition) !important;
  text-decoration: none !important;
  background: transparent !important;
  position: relative !important;
  white-space: nowrap !important;
  text-overflow: ellipsis !important;
  overflow: hidden !important;
}

/* Use standard absolute active bar positioning to match design system layout */
.ot-nav-item::before, .ana-sb-item::before, .adm-sb-item::before {
  content: '' !important;
  position: absolute !important;
  left: -8px !important; /* Align to the left edge of the sidebar wall */
  top: 8px !important;
  bottom: 8px !important;
  width: 3px !important;
  border-radius: 0 4px 4px 0 !important;
  background: transparent !important;
  display: block !important;
}

.ot-nav-item:hover, .ana-sb-item:hover, .adm-sb-item:hover {
  background: var(--ot-bg-hover) !important;
  color: var(--ot-text-primary) !important;
  transform: none !important;
}

.ot-nav-item.active, .ana-sb-item.active, .adm-sb-item.active {
  background: var(--ot-bg-elevated) !important;
  color: var(--ot-text-primary) !important;
  box-shadow: none !important;
}

.ot-nav-item.active::before, .ana-sb-item.active::before, .adm-sb-item.active::before {
  background: var(--ot-accent) !important;
  box-shadow: 0 0 8px rgba(99, 102, 241, 0.8), 0 0 3px rgba(99, 102, 241, 0.5) !important;
}

/* Align icons correctly by centering them inside 28px bounding box */
.ot-nav-icon, .ana-sb-icon, .adm-sb-icon {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  flex-shrink: 0 !important;
  width: 28px !important;
  height: 28px !important;
  color: inherit !important;
  border-radius: var(--ot-radius-sm) !important;
  background: transparent !important;
  transition: var(--ot-transition) !important;
}

.ot-nav-item.active .ot-nav-icon, .ana-sb-item.active .ana-sb-icon, .adm-sb-item.active .adm-sb-icon {
  color: var(--ot-accent) !important;
  background: transparent !important;
  filter: drop-shadow(0 0 4px rgba(99, 102, 241, 0.6)) !important;
}

.ot-nav-icon svg, .ot-nav-icon .ot-icon, .ana-sb-icon svg, .adm-sb-icon svg {
  width: 16px !important;
  height: 16px !important;
}

/* ==========================================================================
   Responsive Display Logic & Column priorities
   ========================================================================== */

/* Hide mobile card list on desktop */
@media (min-width: 1024px) {
  .mobile-card-list {
    display: none !important;
  }
}

/* Hide desktop table on mobile */
@media (max-width: 1023px) {
  .ot-table-wrapper {
    display: none !important;
  }
}

/* Hide tertiary columns on medium screens */
@media (max-width: 1300px) {
  .ot-table-v2 .ot-col-tertiary {
    display: none !important;
  }
}

/* Hide secondary columns on small-medium screens */
@media (max-width: 1150px) {
  .ot-table-v2 .ot-col-secondary {
    display: none !important;
  }
}

/* ==========================================================================
   Table Special Rows (Dynamic JS classes)
   ========================================================================== */
#dataTable tr.rank1-row, #dataTable tr.rank1-row td, .ot-table-v2 tr.rank1-row, .ot-table-v2 tr.rank1-row td {
  background-color: rgba(245, 158, 11, 0.08) !important;
}
#dataTable tr.rank1-row:hover, #dataTable tr.rank1-row:hover td, .ot-table-v2 tr.rank1-row:hover, .ot-table-v2 tr.rank1-row:hover td {
  background-color: rgba(245, 158, 11, 0.12) !important;
}

#dataTable tr.overdue-row, #dataTable tr.overdue-row td, .ot-table-v2 tr.overdue-row, .ot-table-v2 tr.overdue-row td {
  background-color: rgba(239, 68, 68, 0.08) !important;
}
#dataTable tr.overdue-row:hover, #dataTable tr.overdue-row:hover td, .ot-table-v2 tr.overdue-row:hover, .ot-table-v2 tr.overdue-row:hover td {
  background-color: rgba(239, 68, 68, 0.12) !important;
}

/* ==========================================================================
   Badges (Miss Badge / Restrict Badge)
   ========================================================================== */
/* Custom badges are now standardized and consolidated under the main badge styles block */

/* ==========================================================================
   DASHBOARD CHANNEL TABLE (#dataTable) — grid consistency pass v2 (2026-06-25)
   --------------------------------------------------------------------------
   Verified against the live bundle row markup. Body number cells carry the
   classes .views-num (V1/V2/V3/Ch-hr/48H), .vhr-cell (V1/hr) and .subs-num
   (Subs) — targeted directly (robust to column re-order). Headers have no
   class hooks, so they are aligned by :nth-child position. !important so this
   wins over the compiled bundle's own td rules. 16 columns:
     1 #  2 Logo  3 Channel  4 PC  5 Last Upload  6 Age  7 V1  8 V2  9 V3
     10 V1/hr  11 Ch/hr  12 48H  13 Thumb  14 Subs  15 Sched  16 Restrictions
   ========================================================================== */

/* Every cell vertically centred — Last-Upload / Sched cells stack two badges
   and used to push the single-value cells (V1, Subs…) off the baseline. */
#dataTable th,
#dataTable td { vertical-align: middle !important; }

/* All numeric cells: one tabular monospace so digits line up by place value
   (Roboto Mono is loaded in <head>), and right-aligned to read as a column. */
/* Tabular Monospace and right alignment for numeric fields */
.ot-table-v2 td.ot-num,
#dataTable td.views-num,
#dataTable td.subs-num,
#dataTable td.vhr-cell {
  font-family: var(--ot-font-mono) !important;
  font-variant-numeric: tabular-nums !important;
  font-feature-settings: "tnum" 1 !important;
  text-align: right !important;
}

/* Numeric HEADERS right-aligned to match their body column:
   7 V1 · 8 V2 · 9 V3 · 10 V1/hr · 11 Ch/hr · 12 48H · 14 Subs. */
.ot-table-v2 th.ot-num,
#dataTable thead th:nth-child(7),
#dataTable thead th:nth-child(8),
#dataTable thead th:nth-child(9),
#dataTable thead th:nth-child(10),
#dataTable thead th:nth-child(11),
#dataTable thead th:nth-child(12),
#dataTable thead th:nth-child(14) {
  text-align: right !important;
}

/* Index, Logo and Thumbnail centred — header (by position) + body (by class). */
#dataTable thead th:nth-child(1),
#dataTable thead th:nth-child(2),
#dataTable thead th:nth-child(13),
#dataTable td.td-logo,
#dataTable td.td-thumb,
#dataTable tbody td:first-child {
  text-align: center !important;
}

/* Last Upload (.date-split) and Sched (.miss-cell) wrap their badges in a
   block-level `display:flex; flex-direction:column` box — that box ignores the
   cell's text-align, so the badges sat hard-left under a centred header. Center
   the flex box itself (cross-axis = align-items for a column) so the stacked
   badges sit under their centred header. */
#dataTable td:nth-child(5) .date-split,
#dataTable td:nth-child(15) .miss-cell {
  align-items: center !important;
  justify-content: center !important;
}

/* ==========================================================================
   FIT-TO-WIDTH — the 16-column table always fits the screen, NO horizontal
   (left↔right) scroll. Its natural width was ~1638px, so on any container
   narrower than that it overflowed and the last column (Restrictions) was
   clipped / needed sideways scrolling. table-layout:fixed + width:100% pins
   the table to exactly its container; over-long text truncates with “…”.
   ========================================================================== */
#dataTable {
  table-layout: fixed !important;
  width: 100% !important;
}
#dataTable th,
#dataTable td {
  overflow: hidden;
  text-overflow: ellipsis;
  padding-left: 8px;
  padding-right: 8px;
  /* Kill the inline min-width on PC (60px) / Restrictions (140px) headers. With
     table-layout:fixed those minimums forced the table WIDER than its container,
     which is what produced the stray left↔right scroll and the clipped right
     column. With min-width:0 the % widths below are the single source of truth. */
  min-width: 0 !important;
  max-width: none !important;
}
#dataTable th:first-child,
#dataTable td:first-child { padding-left: 16px !important; }
#dataTable th:last-child,
#dataTable td:last-child  { padding-right: 16px !important; }
/* Thumbnail scales inside its (now fixed-width) cell instead of forcing it wide. */
#dataTable td.td-thumb img { max-width: 100% !important; height: auto !important; }

/* HEADER LABELS SHOW IN FULL — the column headers were being cut to "Lo…",
   "Subs…", "V1/h…" because table-layout:fixed + tight widths + ellipsis clipped
   them. Letting ONLY the <thead> labels wrap to a 2nd line shows the whole word
   inside the same fixed column — no truncation, no extra width, no h-scroll.
   Body cells are untouched (numbers stay on one line). */
#dataTable thead th {
  white-space: normal !important;
  text-overflow: clip !important;
  line-height: 1.18 !important;
  word-break: normal;
}

/* PROPORTIONAL column widths for ALL 16 columns (sum = 99.9%, 0.1% slack so
   sub-pixel rounding can never overflow). The # and Logo headers carried INLINE
   px widths (68px / 58px) that table-layout:fixed added ON TOP of what the other
   columns asked for — wider than the screen, and one cause of the horizontal
   scroll + clipped right edge. Making every column a % (and !important to beat
   the inline px) pins the table to exactly its container width.

   Each % is derived from the column's MEASURED natural width — its widest real
   cell, measured ON THE LIVE PAGE against real channel rows at the 10px padding
   set below (thumbnails excluded: they scale via max-width:100% and demand no
   width of their own). Measuring against hand-written sample rows is NOT good
   enough: the Age cell is rebuilt by onetab-age-fix.js into .age-wrap + pill +
   status face and really needs ~138px, not the ~99px a plain badge suggests — an
   under-measured Age silently ate its status face.

   All 16 need 1559px; the table gets 1650px (1654 container − the 4px hover
   gutter), so every column sits above its need with the slack spread
   proportionally. Sum is 99.0%, NOT ~100%: each column rounds up to whole pixels
   and at 99.9% that rounding accumulated to 1656px in a 1654px box — a 2-3px
   overflow on its own. The ~16px of headroom absorbs it.

   Each comment is measured-need → px yielded at 1920. Keep a column above its
   need when editing, or its content silently ellipsis-truncates. */
#dataTable th:nth-child(1),  #dataTable td:nth-child(1)  { width: 3.3%  !important; } /* need  52 → 54  (26px gold badge + 16px first-child pad-left) */
#dataTable th:nth-child(2),  #dataTable td:nth-child(2)  { width: 4.2%  !important; } /* need  66 → 69  */
#dataTable th:nth-child(3),  #dataTable td:nth-child(3)  { width: 8.5%  !important; } /* need 132 → 140 (roomy: names vary) */
#dataTable th:nth-child(4),  #dataTable td:nth-child(4)  { width: 4.2%  !important; } /* need  66 → 69  */
#dataTable th:nth-child(5),  #dataTable td:nth-child(5)  { width: 12.8% !important; } /* need 204 → 211 */
#dataTable th:nth-child(6),  #dataTable td:nth-child(6)  { width: 8.6%  !important; } /* need 138 → 142 (.age-wrap: pill + status face) */
#dataTable th:nth-child(7),  #dataTable td:nth-child(7)  { width: 4.8%  !important; } /* need  75 → 79  */
#dataTable th:nth-child(8),  #dataTable td:nth-child(8)  { width: 3.7%  !important; } /* need  57 → 61  */
#dataTable th:nth-child(9),  #dataTable td:nth-child(9)  { width: 4.6%  !important; } /* need  72 → 76  */
#dataTable th:nth-child(10), #dataTable td:nth-child(10) { width: 5.2%  !important; } /* need  81 → 86  */
#dataTable th:nth-child(11), #dataTable td:nth-child(11) { width: 5.2%  !important; } /* need  81 → 86  */
#dataTable th:nth-child(12), #dataTable td:nth-child(12) { width: 4.2%  !important; } /* need  65 → 69  */
#dataTable th:nth-child(13), #dataTable td:nth-child(13) { width: 4.6%  !important; } /* need  72 → 76  */
#dataTable th:nth-child(14), #dataTable td:nth-child(14) { width: 4.7%  !important; } /* need  73 → 78  */
#dataTable th:nth-child(15), #dataTable td:nth-child(15) { width: 10.3% !important; } /* need 164 → 170 */
#dataTable th:nth-child(16), #dataTable td:nth-child(16) { width: 10.1% !important; } /* need 161 → 167 (16px last-child pad-right) */

/* AGE cell (col 6): the "2mo" pill + its little status dot were colliding in a
   too-tight column. Center them on one line and let the cell breathe so the
   month label always shows in full. */
#dataTable td:nth-child(6) {
  text-align: center !important;
  white-space: nowrap !important;
}
#dataTable td:nth-child(6) > * {
  vertical-align: middle !important;
}

/* Body cells must drop on the SAME breakpoints as their headers. The headers
   carry .ot-col-tertiary / .ot-col-secondary (hidden at ≤1300 / ≤1150px) but
   the JS-rendered body cells have no such class, so without this the header
   would shrink to 10 columns while the body stayed 16 → mis-alignment. Both
   row variants render exactly 16 <td>, so position-matching is safe.
   Tertiary: 8 V2 · 9 V3 · 11 Ch/hr · 12 48H · 15 Sched · 16 Restrictions. */
@media (max-width: 1300px) {
  #dataTable td:nth-child(8),
  #dataTable td:nth-child(9),
  #dataTable td:nth-child(11),
  #dataTable td:nth-child(12),
  #dataTable td:nth-child(15),
  #dataTable td:nth-child(16) { display: none !important; }
}
/* Secondary: 4 PC · 5 Last Upload · 10 V1/hr. */
@media (max-width: 1150px) {
  #dataTable td:nth-child(4),
  #dataTable td:nth-child(5),
  #dataTable td:nth-child(10) { display: none !important; }
}




/* Topbar / Header buttons compactness */
.hdr-toolbar .ot-btn-v2 {
  padding: 6px 10px !important;
  font-size: 12px !important;
  height: auto !important;
  line-height: 1.2 !important;
}
.hdr-toolbar .ot-btn-v2 span[data-oti] {
  width: 13px !important;
  height: 13px !important;
  margin-right: 4px !important;
}


/* Modals Design System Overrides (Flat & Solid) */
.ot-modal-bg {
  background: rgba(10, 11, 16, 0.85) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

.ot-modal {
  background: var(--ot-bg-elevated) !important;
  border: 1px solid var(--ot-border) !important;
  box-shadow: var(--ot-shadow-3) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border-radius: 12px !important;
}

.ot-modal-head {
  border-bottom: 1px solid var(--ot-border) !important;
  padding: 16px 20px !important;
  background: transparent !important;
}

.ot-modal-foot {
  border-top: 1px solid var(--ot-border) !important;
  background: var(--ot-bg-elevated) !important;
  padding: 14px 20px !important;
}

/* Magic Clean Modal Fixes */
body.ot-mcm-open #mcmOverlay {
  display: block !important;
  position: fixed !important;
  inset: 0 !important;
  z-index: 100510 !important;
  background: rgba(10, 11, 16, 0.85) !important;
}

#mcmPanel {
  position: fixed !important;
  top: 50% !important;
  left: 50% !important;
  transform: translate(-50%, -50%) !important;
  margin: 0 !important;
  background: var(--ot-bg-elevated) !important;
  border: 1px solid var(--ot-border) !important;
  box-shadow: var(--ot-shadow-3) !important;
  border-radius: 12px !important;
  width: 90% !important;
  max-width: 600px !important;
  z-index: 100511 !important;
  display: flex !important;
  flex-direction: column !important;
  /* Never taller than the screen. Without this the centred panel grew past the
     viewport on a long scan list — pushing the header (and its X / close button)
     ABOVE the top edge where it could not be clicked ("close not working"), and
     letting the results overflow under the footer. Capping height + scrolling the
     body keeps the header and footer pinned and always reachable. */
  max-height: 90vh !important;
  overflow: hidden !important;
}

/* The scan-results area scrolls; the header (X) and footer (Clean All) stay put. */
#mcmPanel #mcmBody {
  flex: 1 1 auto !important;
  overflow-y: auto !important;
  min-height: 0 !important;
  -webkit-overflow-scrolling: touch !important;
}
/* Head, intro, progress and footer keep their natural height (don't get squeezed). */
#mcmPanel .ot-modal-head,
#mcmPanel #mcmProgWrap,
#mcmPanel #mcmFooter,
#mcmPanel .ot-modal-foot {
  flex: 0 0 auto !important;
}

#mcmPanel .ot-modal-head {
  display: grid !important;
  grid-template-columns: 1fr auto 1fr !important;
  align-items: center !important;
  padding: 16px 22px !important;
  border-bottom: 1px solid var(--ot-border) !important;
  background: transparent !important;
}

#mcmPanel .ot-modal-head > div:first-child {
  grid-column: 2 !important;
  margin: 0 !important;
}

#mcmPanel .ot-modal-head > button[data-ot-close] {
  grid-column: 3 !important;
  justify-self: end !important;
  position: static !important;
  transform: none !important;
  margin: 0 !important;
}

/* ──────────────────────────────────────────────────────────────────────────
   PROFESSIONAL / CLIENT VIEW — hide Magic Clean's developer "guide" lines.
   The scan prints green status notes ("Offline datasets ready…", "OAuth write
   scope OK…", "Read N playlist item(s) via OAuth") and a gray timing line
   ("Scan Xms · fetch Yms"). These are diagnostics, not something a client needs.
   They are rendered with fixed inline styles (no class), so we target those exact
   style signatures inside the scan body. Red errors / amber warnings are NOT
   matched, so a real problem still surfaces — only the "all good" noise is gone.
   ────────────────────────────────────────────────────────────────────────── */
#mcmBody div[style*="font-size:11px"][style*="color:var(--green)"][style*="line-height:1.45"] {
  display: none !important;
}
#mcmBody div[style*="font-size:10px"][style*="color:var(--text3)"] {
  display: none !important;
}

/* ==========================================================================
   Dashboard Control Bar Alignment & Search Bar Fixes (2026-06-25)
   ========================================================================== */
#sortCol,
#sortDirBtn,
#filterInp {
  height: 38px !important;
  box-sizing: border-box !important;
  vertical-align: middle !important;
}

/* Ensure the select element's text aligns nicely */
#sortCol {
  line-height: 20px !important;
  padding: 8px 32px 8px 12px !important; /* Extra padding-right for browser arrow */
}

/* Ensure the button element aligns its text and icon nicely */
#sortDirBtn {
  padding: 0 16px !important;
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
}

/* Search Bar Wrapper & Icon Placement */
.filter-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
}

/* Give the search input room for the icon */
.filter-wrap #filterInp {
  padding-left: 36px !important;
  padding-right: 12px !important;
}

/* Render the search icon robustly inside the wrapper */
.filter-wrap::before {
  content: '' !important;
  position: absolute !important;
  left: 12px !important;
  top: 50% !important;
  transform: translateY(-50%) !important;
  width: 14px !important;
  height: 14px !important;
  opacity: 0.45 !important;
  pointer-events: none !important;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23a1a1aa' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='16.5' y1='16.5' x2='21' y2='21'/%3E%3C/svg%3E") center/contain no-repeat !important;
  z-index: 2 !important;
}

/* ==========================================================================
   RESPONSIVE — Post-login dashboard header + first-screen layout (2026-06-25)
   --------------------------------------------------------------------------
   REFLOW ONLY — no design change. Colours, type, spacing intent and the
   desktop single-row layout are untouched; the rows below simply WRAP instead
   of overflowing once the screen is too narrow for them.
   Fixes the reported bugs: on tablet/phone the header toolbar row (#studio-
   header .hdr-right has 7 tool buttons + Fetch + Admin) was wider than the
   viewport — no flex-wrap, no media query — so the page scrolled sideways and
   the logo wordmark got clipped. The channel table already has its own mobile
   card list (see "Responsive Display Logic" above); this fills the header gap.
   ========================================================================== */

/* KILL page-level horizontal (left↔right) scroll on the dashboard — at EVERY
   width, not just on tablet. `clip` (not `hidden`) is used on purpose: it stops
   sideways scrolling WITHOUT turning <html>/<body> into a scroll container, so
   the table's sticky header (position:sticky) keeps sticking to the viewport. */
html, body.ot-body, body.ot-body-v2 { overflow-x: clip !important; max-width: 100% !important; }
#mainApp, #dashboard-content { max-width: 100% !important; }

/* Brand (logo + page title) never compresses — keeps the full logo wordmark
   from being clipped, which was the reported bug. */
#studio-header .hdr-brand { min-width: 0 !important; }
#studio-header .logo { flex-shrink: 0 !important; }
#studio-header .logo .logo-img { height: 32px !important; width: auto !important; max-width: none !important; }

/* The header toolbar row WRAPS at every width (this is the real cure for the
   sideways scroll): between desktop and ~1450px the 7 tool buttons + Fetch +
   Admin were wider than the viewport and pushed the whole page sideways. With
   flex-wrap it can never overflow — and on a wide screen there is enough room
   that it still sits on one line, so the desktop look is unchanged. */
#studio-header .header-inner { flex-wrap: wrap !important; gap: 12px 16px !important; }
#studio-header .hdr-right { flex-wrap: wrap !important; row-gap: 10px !important; }
#studio-header .hdr-toolbar { flex-wrap: wrap !important; }

/* Phone: stack the brand above the controls, each on its own full-width row. */
@media (max-width: 640px) {
  #studio-header .header-inner { flex-direction: column !important; align-items: stretch !important; }
  #studio-header .hdr-brand { flex-wrap: wrap !important; }
  #studio-header .hdr-right { width: 100% !important; justify-content: flex-start !important; }
  /* Vertical 1px dividers read oddly once items wrap onto new lines. */
  #studio-header .hdr-brand-divider,
  #studio-header .nav-group-divider { display: none !important; }
}

/* Shared metric / KPI grids: collapse columns as width drops (same cards, reflow
   only). One place fixes every page that loads this override last:
   upload.html (.ot-grid-cols-4), index KPIs (#dashKpis .ot-grid-cols-3),
   templates / ai / oauth stat strips (.metrics), AI usage (.usage-grid). */
@media (max-width: 1023px) {
  .ot-grid-v2.ot-grid-cols-4,
  .ot-grid-v2.ot-grid-cols-3 { grid-template-columns: repeat(2, 1fr) !important; }
  .metrics { grid-template-columns: repeat(2, 1fr) !important; }
}
@media (max-width: 640px) {
  .ot-grid-v2.ot-grid-cols-2,
  .ot-grid-v2.ot-grid-cols-3,
  .ot-grid-v2.ot-grid-cols-4 { grid-template-columns: 1fr !important; }
  .metrics, .usage-grid { grid-template-columns: 1fr !important; }
  #dashKpis.ot-grid-cols-3 { margin: 16px !important; }
}

/* ==========================================================================
   UPLOAD PAGE — drag-&-drop zone centering (upload.html)
   --------------------------------------------------------------------------
   The .drop-zone box is full-width but its icon + "Drag & drop…" + "or click
   to browse" text were hugging the LEFT. Laying the box out as a centred flex
   column pins the icon and both lines to the horizontal middle regardless of
   box width or any inherited text-align — the box, border, padding and colours
   from the compiled stylesheet are untouched, only the content is centred.
   ========================================================================== */
.drop-zone {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  text-align: center !important;
}
/* The icon sits in its own line, centred, with a little breathing room. */
.drop-zone > span[data-oti],
.drop-zone svg { display: block !important; margin-left: auto !important; margin-right: auto !important; }

/* Sort / filter control bar: wrap its two groups; the filter input goes
   full-width so the 140px select + 200px filter no longer overflow on phones. */
@media (max-width: 760px) {
  div.ot-justify-between:has(#sortCol) { flex-wrap: wrap !important; gap: 12px !important; }
  div.ot-justify-between:has(#sortCol) > div { flex-wrap: wrap !important; }
  .filter-wrap { margin-left: 0 !important; flex: 1 1 100%; }
  .filter-wrap #filterInp { width: 100% !important; }
}

/* ==========================================================================
   SOLID THEME OVERRIDES — Force Disable Compiled/Hashed Glassmorphism Blurs
   ========================================================================== */

#studio-header {
  background: var(--ot-bg-surface) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  box-shadow: 0 1px 0 var(--ot-border) !important;
}

.panel-overlay {
  background: rgba(10, 11, 16, 0.85) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

.clock-modal {
  background: rgba(10, 11, 16, 0.85) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

.adm-topbar {
  background: var(--ot-bg-surface) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  box-shadow: 0 1px 0 var(--ot-border) !important;
}

#adminOverlay.adm-overlay {
  background: rgba(10, 11, 16, 0.85) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

#adminOverlay .adm-savebar {
  background: var(--ot-bg-base) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  box-shadow: 0 -1px 0 var(--ot-border) !important;
}

.ana-spark-wrap {
  background: linear-gradient(180deg, var(--ot-bg-surface), var(--ot-bg-base)) !important;
}

.topbar {
  background: var(--ot-bg-base) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}

/* ==========================================================================
   CUSTOM RESPONSIVENESS AND LAYOUT FIXES (2026-06-25)
   ========================================================================== */

/* Utility spacing classes that were missing in the layout helpers */
.ot-gap-2 { gap: 8px !important; }
.ot-gap-3 { gap: 12px !important; }
.ot-gap-4 { gap: 16px !important; }

/* 1. Header Toolbar wrap and flex configuration on mobile/tablet */
#studio-header .hdr-right {
  display: flex !important;
  flex-wrap: wrap !important;
  align-items: center !important;
  gap: 12px 16px !important;
}
#studio-header .hdr-toolbar {
  display: flex !important;
  flex-wrap: wrap !important;
  gap: 8px !important;
}

/* 3. Table Column Widths and Truncation overrides */
.ot-table-scroll {
  overflow-x: auto !important;
  max-width: 100% !important;
}
/* Last Upload (5), Sched (15) and Restrictions (16) keep their nowrap content but
   NOT their own widths. These three used to carry `width:auto` + a px min-width
   (160/135/145). Being later in the file at identical specificity, that beat the
   % widths above and re-introduced the content-driven sizing — 440px of hard
   minimums the table could not shrink below, which is what clipped Restrictions
   at the right edge. Width is now owned solely by the % block above. */
#dataTable th:nth-child(5), #dataTable td:nth-child(5),
#dataTable th:nth-child(15), #dataTable td:nth-child(15),
#dataTable th:nth-child(16), #dataTable td:nth-child(16) {
  min-width: 0 !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
}

/* 5. Badge Spacing (vertical/horizontal spacing for status/missing badges) */
#dataTable .date-split,
#dataTable .miss-cell {
  display: flex !important;
  flex-direction: column !important;
  gap: 6px !important;
}
#dataTable .date-row {
  display: flex !important;
  align-items: center !important;
  gap: 6px !important;
}

/* Foolproof CSS fix to ensure modal overlays and close buttons are clickable */
.ot-modal-bg, #mcmOverlay, #monetOverlay {
  position: fixed !important;
  inset: 0 !important;
  background: rgba(10, 11, 16, 0.85) !important;
  display: none;
  align-items: center !important;
  justify-content: center !important;
  z-index: 999999 !important; /* Ensure it is above everything else */
}

.ot-modal-bg.open,
#mcmOverlay.open,
#monetOverlay.open,
body.ot-mcm-open #mcmOverlay,
#pinLock:not([style*="display: none"]) {
  display: flex !important;
  pointer-events: auto !important;
}

/* BUGFIX: the previous group also had `body.ot-modal-open #mcmOverlay` and
   `body.ot-modal-open #monetOverlay`. `ot-modal-open` is a GENERIC body flag, so
   opening Magic Clean (which sets it) also force-opened the Monetize overlay
   behind it. Those two selectors were removed above.
   These overlays are instead opened by their own JS via an inline
   `display:block`, which beat the base flex rule and left the panel stuck to the
   side (Monetize / AI Core / Neural-Eye opened squashed left). Re-assert flex
   centering only while the inline style actually marks them shown. */
#monetOverlay[style*="display: block"],
#aiCoreOverlay[style*="display: block"],
#neuralEyeOverlay[style*="display: block"] {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  pointer-events: auto !important;
}

.ot-modal, #mcmPanel {
  position: relative !important;
  z-index: 1000000 !important;
  pointer-events: auto !important; /* Ensure clicks inside are captured */
}

/* #mcmPanel still carried a stale `top:50%;left:50%;transform:translate(-50%,-50%)`
   from an old position:fixed rule. Once its position became relative inside the
   already flex-centered overlay, those offsets double-shifted it off-centre.
   Reset them so the flex centering alone positions the panel. */
#mcmOverlay #mcmPanel {
  top: auto !important;
  left: auto !important;
  right: auto !important;
  bottom: auto !important;
  inset: auto !important;
  transform: none !important;
  margin: auto !important;
}

.ot-btn-icon[data-ot-close], 
button[data-ot-close], 
.ot-overlay-close {
  position: relative !important;
  z-index: 1000005 !important; /* Must sit higher than the modal head content */
  cursor: pointer !important;
  pointer-events: auto !important; /* Force click events to be captured */
}

.ot-btn-icon[data-ot-close] svg, 
button[data-ot-close] svg, 
button[data-ot-close] span {
  pointer-events: none !important; /* Pass mouse events to the parent button */
}

/* ==========================================================================
   Milestone 2 PIN Gate & Button Overhaul
   ========================================================================== */

.ot-modal-pin {
  max-width: 360px !important;
  width: 90% !important;
  text-align: center !important;
}
.ot-modal-pin .ot-modal-body {
  padding: 32px 28px !important;
}
.ot-modal-monet {
  max-width: 880px !important;
}

.ota-pin-dots, .pin-dots {
  display: flex !important;
  gap: 12px !important;
  justify-content: center !important;
  margin: 16px 0 !important;
}
.ota-pin-dot, .pin-dot {
  width: 14px !important;
  height: 14px !important;
  border-radius: 50% !important;
  border: 1.5px solid var(--ot-border) !important;
  background: transparent !important;
  transition: all 0.15s ease-in-out !important;
}
.ota-pin-dot.filled, .pin-dot.filled {
  background: var(--ot-accent) !important;
  border-color: var(--ot-accent) !important;
  box-shadow: 0 0 8px rgba(99, 102, 241, 0.55) !important;
}
.pin-dot.error {
  border-color: var(--ot-status-danger) !important;
  background: var(--ot-status-danger) !important;
  animation: otPinShake 0.4s !important;
}

.ota-pin-error, .lock-error {
  min-height: 18px !important;
  font-size: 12.5px !important;
  color: var(--ot-status-danger) !important;
  font-weight: 600 !important;
  margin-bottom: 12px !important;
  text-align: center !important;
}

.ota-numpad, .pin-numpad {
  display: grid !important;
  grid-template-columns: repeat(3, 1fr) !important;
  gap: 8px !important;
  max-width: 220px !important;
  margin: 0 auto !important;
}
.ota-numpad button {
  height: 44px !important;
  font-size: 18px !important;
}
#pinLock .pin-numpad {
  grid-template-columns: repeat(3, 72px) !important;
  gap: 16px !important;
  justify-content: center !important;
}
#pinLock .pin-btn {
  width: 72px !important;
  height: 72px !important;
  border-radius: 50% !important;
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  background: var(--ot-bg-surface) !important;
  border: 1px solid var(--ot-border) !important;
  color: var(--ot-text-primary) !important;
  font-size: 24px !important;
  font-weight: 600 !important;
  font-family: inherit !important;
  line-height: 1 !important;
  padding: 0 !important;
  cursor: pointer !important;
  transition: var(--ot-transition) !important;
}
#pinLock .pin-btn:hover { background: var(--ot-bg-hover) !important; }
#pinLock .pin-btn:active { transform: scale(0.94) !important; background: var(--ot-bg-elevated) !important; }
#pinLock .pin-btn .sub {
  font-size: 9px !important;
  letter-spacing: 1.5px !important;
  color: var(--ot-text-secondary) !important;
  margin-top: 3px !important;
  font-weight: 500 !important;
}
#pinLock .pin-btn.empty-btn { background: transparent !important; border: none !important; cursor: default !important; pointer-events: none !important; }
#pinLock .pin-btn.del-btn { font-size: 18px !important; }

@keyframes otPinShake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  75% { transform: translateX(5px); }
}

.ot-btn-ai {
  background: var(--ot-accent-soft) !important;
  color: var(--ot-accent) !important;
}
.ot-btn-ai:hover {
  background: rgba(99, 102, 241, 0.25) !important;
}

.ot-btn-neural {
  border: 1px solid rgba(168, 85, 247, 0.45) !important;
  background: rgba(168, 85, 247, 0.1) !important;
  color: #c084fc !important;
}
.ot-btn-neural:hover {
  background: rgba(168, 85, 247, 0.2) !important;
}

/* Custom overrides to remove inline styles for HTML verification compliance */
.ot-card-flat {
  background: var(--ot-bg-base) !important;
  box-shadow: none !important;
}

.ot-mb-24 {
  margin-bottom: 24px !important;
}

#studio-header.ot-card-v2 {
  padding: 16px !important;
  margin-bottom: 24px !important;
  border-radius: 0 0 16px 16px !important;
  border-top: none !important;
}

#mcmOverlay.ot-modal-bg {
  z-index: 100510 !important;
}

#monetOverlay.ot-modal-bg {
  z-index: 9999 !important;
}

#monetOverlay .ot-modal {
  max-width: 880px !important;
}

#metric-scheduled.ot-card-v2 {
  position: relative !important;
  cursor: help !important;
}

#mcmFooter.ot-modal-foot {
  /* Visibility is toggled by JS (hidden until a scan starts, then flex).
     Was `display:none !important`, which overrode the scan's inline
     display:flex and permanently hid the "Clean All Selected" button. */
  justify-content: space-between !important;
  align-items: center !important;
}

#analyticsOverlay {
  align-items: stretch !important;
  justify-content: center !important;
  padding: 0 !important;
  /* Solid backdrop — the 0.65-opacity background let the dashboard behind the
     Analytics Hub bleed through, so its text "floated" over the panel. */
  background: var(--ot-bg-base) !important;
}
/* The Analytics Hub is a full-screen shell: a fixed-width sidebar + a main area
   that must grow to fill the rest. Without flex-grow the main pane shrank to its
   content (~470px), squashing the whole panel into the left edge. */
#analyticsOverlay .ana-shell {
  background: var(--ot-bg-base) !important;
}
#analyticsOverlay .ana-main {
  flex: 1 1 auto !important;
  min-width: 0 !important;
}

/* --- OAuth Page Additions --- */
.ch-head { display: flex !important; align-items: center !important; gap: 10px !important; margin-bottom: 12px !important; }
.ch-thumb { width: 36px !important; height: 36px !important; border-radius: 50% !important; border: 1px solid var(--ot-border) !important; flex-shrink: 0 !important; object-fit: cover !important; }
.ch-thumb.placeholder { display: flex !important; align-items: center !important; justify-content: center !important; color: var(--ot-text-secondary) !important; font-weight: 700 !important; background: var(--ot-bg-elevated) !important; }
.ch-info { flex: 1 !important; min-width: 0 !important; }
.ch-label { font-size: 13.5px !important; font-weight: 600 !important; color: var(--ot-text-primary) !important; overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important; }
.ch-yt-title { font-size: 11px !important; color: var(--ot-text-secondary) !important; margin-top: 2px !important; overflow: hidden !important; text-overflow: ellipsis !important; white-space: nowrap !important; font-family: var(--ot-font-mono) !important; }

.ch-meta { font-size: 10.5px !important; color: var(--ot-text-secondary) !important; margin-bottom: 10px !important; display: flex !important; gap: 12px !important; flex-wrap: wrap !important; font-family: var(--ot-font-mono) !important; }
.ch-meta-item { display: flex !important; align-items: center !important; gap: 4px !important; }
.ch-meta-item .lbl { color: var(--ot-text-muted) !important; }
.ch-error { margin-top: 8px !important; padding: 8px 10px !important; background: rgba(239, 68, 68, 0.1) !important; border: 1px solid rgba(239, 68, 68, 0.2) !important; border-radius: 6px !important; font-size: 11px !important; color: var(--ot-status-danger) !important; line-height: 1.4 !important; }
.ch-actions { display: flex !important; gap: 6px !important; }

.filters-row { display: flex !important; align-items: center !important; gap: 10px !important; margin-bottom: 12px !important; flex-wrap: wrap !important; }
.filter-chip { padding: 5px 12px !important; border-radius: 999px !important; font-size: 11px !important; font-weight: 600 !important; color: var(--ot-text-secondary) !important; background: var(--ot-bg-surface) !important; border: 1px solid var(--ot-border) !important; cursor: pointer !important; transition: var(--ot-transition) !important; }
.filter-chip:hover { color: var(--ot-text-primary) !important; border-color: var(--ot-border-focus) !important; }
.filter-chip.active { background: var(--ot-accent) !important; color: var(--ot-text-primary) !important; border-color: var(--ot-accent) !important; }
.filter-chip .count { font-family: var(--ot-font-mono) !important; opacity: .7 !important; margin-left: 4px !important; }

.settings-card { background: var(--ot-bg-surface) !important; border: 1px solid var(--ot-border) !important; border-radius: 12px !important; padding: 20px !important; margin-bottom: 14px !important; }
.section-head { display: flex !important; align-items: flex-end !important; justify-content: space-between !important; margin-bottom: 14px !important; gap: 16px !important; }
.section-title { font-size: 14px !important; font-weight: 700 !important; color: var(--ot-text-primary) !important; letter-spacing: -.01em !important; }
.section-sub { font-size: 11px !important; color: var(--ot-text-secondary) !important; margin-top: 2px !important; }
.field-code { font-family: var(--ot-font-mono) !important; background: var(--ot-bg-base) !important; border: 1px solid var(--ot-border) !important; padding: 7px 10px !important; border-radius: 6px !important; font-size: 11px !important; color: var(--ot-accent) !important; display: inline-block !important; user-select: all !important; }
.copy-btn { background: var(--ot-bg-elevated) !important; color: var(--ot-text-secondary) !important; border: 1px solid var(--ot-border) !important; padding: 4px 8px !important; border-radius: 5px !important; font-size: 10px !important; font-weight: 700 !important; cursor: pointer !important; font-family: inherit !important; margin-left: 6px !important; }
.copy-btn:hover { background: var(--ot-bg-hover) !important; color: var(--ot-text-primary) !important; }
.guide-box { background: rgba(99, 102, 241, 0.1) !important; border: 1px solid rgba(99, 102, 241, 0.25) !important; border-radius: 10px !important; padding: 14px 16px !important; margin-bottom: 14px !important; font-size: 12px !important; color: var(--ot-text-secondary) !important; line-height: 1.55 !important; }
.guide-box strong { color: var(--ot-accent) !important; }
.guide-box a { color: var(--ot-accent) !important; text-decoration: underline !important; }

/* Metrics */
.metrics { display: grid !important; grid-template-columns: repeat(4, 1fr) !important; gap: 0 !important; background: var(--ot-bg-surface) !important; border: 1px solid var(--ot-border) !important; border-radius: 10px !important; overflow: hidden !important; margin-bottom: 14px !important; }
.metric { padding: 12px 16px !important; border-right: 1px solid var(--ot-border) !important; display: flex !important; flex-direction: column !important; gap: 4px !important; }
.metric:last-child { border-right: none !important; }
.metric-label { font-size: 10px !important; letter-spacing: .1em !important; text-transform: uppercase !important; color: var(--ot-text-secondary) !important; font-weight: 700 !important; }
.metric-value { font-family: var(--ot-font-mono) !important; font-size: 19px !important; font-weight: 700 !important; color: var(--ot-text-primary) !important; letter-spacing: -.02em !important; display: flex !important; align-items: baseline !important; gap: 6px !important; }
.metric-value .unit { font-size: 11px !important; color: var(--ot-text-secondary) !important; font-weight: 500 !important; }
.metric-value.green { color: var(--ot-status-success) !important; }
.metric-value.amber { color: var(--ot-status-warning) !important; }

/* Confirm modal styling in oauth */
#confirmModal .modal {
  max-width: 420px !important;
  text-align: left !important;
}

/* --- Creative Intelligence Redesign Additions --- */
.ot-btn-v2-danger {
  background: var(--ot-status-danger) !important;
  color: #fff !important;
  border-color: var(--ot-status-danger) !important;
  box-shadow: none !important;
}
.ot-btn-v2-danger:hover {
  background: #d32f2f !important;
  border-color: #d32f2f !important;
}

.ot-btn-v2.ot-btn-ghost {
  background: transparent !important;
  border-color: transparent !important;
  color: var(--ot-text-secondary) !important;
}
.ot-btn-v2.ot-btn-ghost:hover {
  background: var(--ot-bg-hover) !important;
  color: var(--ot-text-primary) !important;
}

.ot-tab.active, .ot-tab.ot-active {
  color: var(--ot-text-primary) !important;
  border-bottom-color: var(--ot-accent) !important;
}

.ot-progress-fill {
  background: linear-gradient(90deg, var(--ot-accent), #4f46e5) !important;
  box-shadow: 0 0 10px var(--ot-accent-soft) !important;
}

button.ot-nav-item {
  border: none !important;
  background: transparent !important;
  cursor: pointer !important;
  text-align: left !important;
  font-family: inherit !important;
  width: 100% !important;
  outline: none !important;
}







/* ── FIX: PIN lock visibility ──────────────────────────────────────────────
   #pinLock carries the .ot-modal-bg class, which is display:none by default
   and only becomes display:flex via an .open class. Nothing adds .open to the
   PIN lock, so the lock screen never appeared (blank page on a locked load).
   The lock is gated client-side by pin-lock.js, which hides it after a correct
   PIN by setting an inline style.display='none' (inline beats this ID rule, so
   unlocking still works). This also acts as the intended JS-broken fail-safe:
   if pin-lock.js never runs, the keypad is still shown. */
#pinLock { display: flex; }

/* ==========================================================================
   V2.2 Theme-v2 Integration & Layout Glitches Fixes
   ========================================================================== */

/* 1. Cohesive Standard CSS Variable Mapping in Root */
:root {
  --bg-base: var(--ot-bg-base) !important;
  --bg-surface: var(--ot-bg-surface) !important;
  --bg-elevated: var(--ot-bg-elevated) !important;
  --bg-hover: var(--ot-bg-hover) !important;
  --border: var(--ot-border) !important;
  --border-strong: rgba(255, 255, 255, 0.15) !important;
  --text: var(--ot-text-primary) !important;
  --text-primary: var(--ot-text-primary) !important;
  --text-secondary: var(--ot-text-secondary) !important;
  --text-muted: var(--ot-text-muted) !important;
  --text-2: var(--ot-text-secondary) !important;
  --text-3: var(--ot-text-muted) !important;
  --accent: var(--ot-accent) !important;
  --accent-hover: var(--ot-accent-hover) !important;
}

/* 2. PIN Lock Brand Layout & Centering */
.lock-brand {
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  justify-content: center !important;
  gap: 8px !important;
  margin-bottom: 24px !important;
}
.lock-logo {
  width: 200px !important;
  height: auto !important;
  margin: 0 auto !important;
  display: flex !important;
  justify-content: center !important;
  align-items: center !important;
}
.lock-logo img {
  width: 100% !important;
  height: auto !important;
  max-width: 100% !important;
  max-height: 80px !important;
  object-fit: contain !important;
  display: block !important;
}
.lock-logo-fallback {
  width: 64px !important;
  height: 64px !important;
  background: var(--ot-accent-soft) !important;
  color: var(--ot-accent) !important;
  border: 2px solid var(--ot-accent) !important;
  border-radius: 50% !important;
  /* Hidden by default — the inline style="display:none" used to be overridden
     by `display:flex !important` here, so the "OT" badge always showed even when
     the real logo loaded fine. Default to none and let the <img> onerror handler
     reveal it (inline display:flex) ONLY when the logo actually fails to load. */
  display: none;
  align-items: center !important;
  justify-content: center !important;
  font-weight: 700 !important;
  font-size: 24px !important;
  letter-spacing: 0.5px !important;
}
.lock-wordmark {
  text-align: center !important;
  margin-top: 10px !important;
}
.lock-wordmark .lock-word-main {
  font-size: 20px !important;
  font-weight: 700 !important;
  color: var(--ot-text-primary) !important;
  line-height: 1.2 !important;
}
.lock-wordmark .lock-word-sub {
  font-size: 10px !important;
  font-weight: 600 !important;
  color: var(--ot-text-secondary) !important;
  letter-spacing: 1.5px !important;
  text-transform: uppercase !important;
  margin-top: 4px !important;
}
.lock-subtitle {
  font-size: 13.5px !important;
  color: var(--ot-text-secondary) !important;
  margin-bottom: 20px !important;
  text-align: center !important;
}

/* 3. Fit Modal & Numpad Down to 320px Viewport without horizontal clipping */
.ot-modal-pin {
  max-width: 320px !important;
  min-width: 290px !important;
  width: 90% !important;
  box-sizing: border-box !important;
}
.ot-modal-pin .ot-modal-body {
  padding: 32px 16px !important;
}

@media (max-width: 360px) {
  .ot-modal-pin {
    width: 95% !important;
  }
  .ot-modal-pin .ot-modal-body {
    padding: 24px 12px !important;
  }
  #pinLock .pin-numpad {
    grid-template-columns: repeat(3, 68px) !important;
    gap: 10px !important;
  }
  #pinLock .pin-btn {
    width: 68px !important;
    height: 68px !important;
    font-size: 18px !important;
  }
}

/* 4. Prevent Vertical Clipping on short screens (< 600px height) */
@media (max-height: 600px) {
  .ot-modal-pin .ot-modal-body {
    padding: 16px 20px !important;
  }
  .lock-brand {
    margin-bottom: 12px !important;
    gap: 4px !important;
  }
  #pinLock .pin-numpad {
    gap: 10px !important;
  }
  #pinLock .pin-btn {
    width: 60px !important;
    height: 60px !important;
    font-size: 18px !important;
  }
}

/* 5. KPI Metric Size Scope Fix (ai.html & upload.html) */
.ot-card-v2 .metric-value {
  font-size: 2.25rem !important;
  font-weight: var(--ot-font-weight-bold) !important;
  font-family: var(--ot-font-mono) !important;
  line-height: 1.1 !important;
}
.ot-card-v2 .metric-value .unit {
  font-size: 1rem !important;
  color: var(--ot-text-secondary) !important;
  margin-left: 8px !important;
}

/* 6. Tab Layout & Style Compatibility (ai.html, templates.html) */
.tabs {
  display: flex !important;
  gap: 8px !important;
  border-bottom: 1px solid var(--ot-border) !important;
  margin-bottom: 24px !important;
  flex-wrap: wrap !important;
}
.tab {
  padding: 10px 16px !important;
  border: none !important;
  background: transparent !important;
  font-family: var(--ot-font-sans) !important;
  font-size: 0.875rem !important;
  font-weight: var(--ot-font-weight-bold) !important;
  color: var(--ot-text-secondary) !important;
  cursor: pointer !important;
  border-bottom: 2px solid transparent !important;
  margin-bottom: -1px !important;
  transition: var(--ot-transition) !important;
}
.tab:hover {
  color: var(--ot-text-primary) !important;
}
.tab.active, .tab.ot-active {
  color: var(--ot-text-primary) !important;
  border-bottom-color: var(--ot-accent) !important;
}

/* 7. Legacy Modal Classes Compatibility (upload.html, oauth.html, ai.html)
   BUGFIX: this rule used `display: flex !important` as the DEFAULT, which beat
   the bundle's `.modal-bg{display:none}` (theme-v2 loads last + !important) and
   force-opened EVERY modal on page load — upload.html showed addChannel,
   confirm, cleanup and thumbnail modals all stacked at once. Default to hidden
   and only show when the JS adds `.open` (the same trigger the bundle uses). */
.modal-bg {
  position: fixed !important;
  inset: 0 !important;
  background: rgba(10, 11, 16, 0.85) !important;
  display: none !important;
  align-items: center !important;
  justify-content: center !important;
  z-index: 999999 !important;
  pointer-events: auto !important;
}
.modal-bg.open {
  display: flex !important;
}
.modal {
  position: relative !important;
  background: var(--ot-bg-elevated) !important;
  border: 1px solid var(--ot-border) !important;
  box-shadow: var(--ot-shadow-3) !important;
  border-radius: 12px !important;
  z-index: 1000000 !important;
  pointer-events: auto !important;
}
.modal h2 {
  font-size: 1.1rem !important;
  font-weight: 700 !important;
  margin-bottom: 8px !important;
  color: var(--ot-text-primary) !important;
}
.modal p {
  font-size: 0.875rem !important;
  color: var(--ot-text-secondary) !important;
  margin-bottom: 16px !important;
  line-height: 1.5 !important;
}
.modal-actions {
  display: flex !important;
  justify-content: flex-end !important;
  gap: 8px !important;
  margin-top: 20px !important;
}

/* 8. Legacy Button Compatibility (ai.html, upload.html) */
.btn {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  gap: var(--ot-space-sm) !important;
  padding: 8px 16px !important;
  border-radius: var(--ot-radius-sm) !important;
  font-weight: var(--ot-font-weight-medium) !important;
  font-size: 0.875rem !important;
  cursor: pointer !important;
  transition: var(--ot-transition) !important;
  border: 1px solid var(--ot-border) !important;
  font-family: var(--ot-font-sans) !important;
  background: var(--ot-bg-elevated) !important;
  color: var(--ot-text-primary) !important;
  box-shadow: none !important;
}
.btn:hover {
  background: var(--ot-bg-hover) !important;
  border-color: var(--ot-border) !important;
}
.btn.brand, .btn.btn-primary {
  background: var(--ot-accent) !important;
  color: #fff !important;
  border-color: var(--ot-accent) !important;
}
.btn.brand:hover, .btn.btn-primary:hover {
  background: var(--ot-accent-hover) !important;
  border-color: var(--ot-accent-hover) !important;
}

/* 9. Modal Close Button & Inputs Styling (upload.html, ai.html) */
.modal-close {
  color: var(--ot-text-secondary) !important;
  background: transparent !important;
  border: none !important;
  cursor: pointer !important;
  font-size: 18px !important;
  line-height: 1 !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  width: 28px !important;
  height: 28px !important;
  border-radius: 6px !important;
  transition: var(--ot-transition) !important;
}
.modal-close:hover {
  background: var(--ot-bg-hover) !important;
  color: var(--ot-text-primary) !important;
}
.field-input, .field-select {
  width: 100%;
  padding: 8px 12px;
  background: var(--ot-bg-base) !important;
  border: 1px solid var(--ot-border) !important;
  border-radius: var(--ot-radius-sm) !important;
  color: var(--ot-text-primary) !important;
  font-family: inherit;
  font-size: 0.875rem;
  transition: var(--ot-transition);
}
.field-input:focus, .field-select:focus {
  outline: none !important;
  border-color: var(--ot-border-focus) !important;
  box-shadow: 0 0 0 2px rgba(99, 102, 241, 0.2), 0 0 12px rgba(99, 102, 241, 0.1) !important;
}

/* ==========================================================================
   PIN LOCK — Modern Redesign (scoped to #pinLock only)
   Glassmorphism card · ambient glow · tactile numpad · glowing dots.
   Everything here is namespaced under #pinLock so no other surface changes.
   ========================================================================== */

/* Ambient gradient backdrop behind the lock card */
#pinLock {
  background:
    radial-gradient(820px 520px at 50% -8%, rgba(99, 102, 241, 0.20), transparent 62%),
    radial-gradient(680px 480px at 50% 112%, rgba(139, 92, 246, 0.14), transparent 60%),
    #07080c !important;
}

/* Glass card */
#pinLock .ot-modal-pin,
#pinLock .lock-card {
  background: linear-gradient(180deg, rgba(27, 28, 38, 0.74), rgba(16, 17, 24, 0.72)) !important;
  border: 1px solid rgba(255, 255, 255, 0.10) !important;
  border-radius: 26px !important;
  box-shadow:
    0 32px 80px -24px rgba(0, 0, 0, 0.7),
    0 0 0 1px rgba(99, 102, 241, 0.05),
    inset 0 1px 0 rgba(255, 255, 255, 0.06) !important;
  backdrop-filter: blur(22px) saturate(140%) !important;
  -webkit-backdrop-filter: blur(22px) saturate(140%) !important;
  overflow: hidden !important;
  position: relative !important;
}
/* Soft top sheen */
#pinLock .ot-modal-pin::before {
  content: "" !important;
  position: absolute !important;
  inset: 0 0 auto 0 !important;
  height: 120px !important;
  background: radial-gradient(120% 100% at 50% 0%, rgba(99, 102, 241, 0.12), transparent 70%) !important;
  pointer-events: none !important;
}
#pinLock .ot-modal-pin .ot-modal-body {
  padding: 36px 30px 34px !important;
  position: relative !important;
  z-index: 1 !important;
}

/* Brand + subtitle spacing — logo only, freshened with a soft glow */
#pinLock .lock-brand { margin-bottom: 22px !important; }
#pinLock .lock-logo { width: 212px !important; margin-bottom: 2px !important; }
#pinLock .lock-logo img {
  max-height: 82px !important;
  filter: drop-shadow(0 4px 18px rgba(99, 102, 241, 0.28)) !important;
}
#pinLock .lock-subtitle {
  font-size: 13px !important;
  letter-spacing: 0.2px !important;
  color: var(--ot-text-secondary) !important;
  margin-top: 6px !important;
  margin-bottom: 22px !important;
}

/* PIN dots — glowing on fill */
#pinLock .pin-dots { gap: 14px !important; margin: 6px 0 20px !important; }
#pinLock .pin-dot {
  width: 13px !important;
  height: 13px !important;
  border: 1.5px solid rgba(255, 255, 255, 0.18) !important;
  background: rgba(255, 255, 255, 0.04) !important;
  transition: transform .22s cubic-bezier(.16,1,.3,1), background .2s ease, box-shadow .2s ease, border-color .2s ease !important;
}
#pinLock .pin-dot.filled {
  background: linear-gradient(180deg, #818cf8, #6366f1) !important;
  border-color: #818cf8 !important;
  box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.14), 0 0 14px rgba(99, 102, 241, 0.6) !important;
  transform: scale(1.14) !important;
}

/* Numpad — tactile glass keys */
#pinLock .pin-numpad {
  grid-template-columns: repeat(3, 74px) !important;
  gap: 18px !important;
  justify-content: center !important;
}
#pinLock .pin-btn {
  width: 74px !important;
  height: 74px !important;
  border-radius: 50% !important;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0.02)) !important;
  border: 1px solid rgba(255, 255, 255, 0.08) !important;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.06) !important;
  color: #f1f5f9 !important;
  font-size: 26px !important;
  font-weight: 500 !important;
  transition: transform .12s ease, background .18s ease, border-color .18s ease, box-shadow .18s ease !important;
}
#pinLock .pin-btn:hover {
  background: linear-gradient(180deg, rgba(99, 102, 241, 0.24), rgba(99, 102, 241, 0.10)) !important;
  border-color: rgba(129, 140, 248, 0.5) !important;
  box-shadow: 0 8px 20px -6px rgba(99, 102, 241, 0.5), inset 0 1px 0 rgba(255, 255, 255, 0.08) !important;
  transform: translateY(-2px) !important;
}
#pinLock .pin-btn:active {
  transform: translateY(0) scale(0.95) !important;
  background: linear-gradient(180deg, rgba(99, 102, 241, 0.32), rgba(99, 102, 241, 0.16)) !important;
}
#pinLock .pin-btn .sub {
  font-size: 8.5px !important;
  letter-spacing: 2px !important;
  color: var(--ot-text-muted) !important;
  margin-top: 4px !important;
}
/* Empty + delete keys stay ghosted */
#pinLock .pin-btn.empty-btn {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}
#pinLock .pin-btn.del-btn {
  background: transparent !important;
  border-color: transparent !important;
  box-shadow: none !important;
}
#pinLock .pin-btn.del-btn:hover {
  background: rgba(255, 255, 255, 0.07) !important;
  transform: none !important;
}

/* Responsive — keep the redesigned keypad inside small viewports */
@media (max-width: 360px) {
  #pinLock .pin-numpad { grid-template-columns: repeat(3, 66px) !important; gap: 12px !important; }
  #pinLock .pin-btn { width: 66px !important; height: 66px !important; font-size: 22px !important; }
}
@media (max-height: 640px) {
  #pinLock .ot-modal-pin .ot-modal-body { padding: 22px 24px !important; }
  #pinLock .lock-brand { margin-bottom: 14px !important; }
  #pinLock .lock-subtitle { margin-bottom: 16px !important; }
  #pinLock .pin-numpad { gap: 12px !important; }
  #pinLock .pin-btn { width: 62px !important; height: 62px !important; font-size: 22px !important; }
}

/* ==========================================================================
   DASHBOARD CHANNEL TABLE — logo crop fix + wider responsive breakpoints
   --------------------------------------------------------------------------
   The full 16-column table is ~1610px wide and only fits at >=1920px. Below
   that it used to overflow horizontally because the low-priority columns only
   dropped at <=1300 / <=1150 — so 19"–24" monitors (1366–1680) showed a
   cramped, horizontally-scrolling table. We drop those columns earlier so the
   table fits common desktop widths cleanly. The existing overflow-x:auto on
   .ot-table-scroll stays as the final fallback, so nothing ever breaks layout.
   Scoped to #dataTable only — no other surface is affected.
   ========================================================================== */

/* 0) Fill the container, never the content. width:max-content sized the table to
      whatever its cells happened to need, leaving only ~15px of margin against the
      1654px container at 1920 — so a web font finishing load or one extra icon
      pushed it over and produced a stray scrollbar + clipped Restrictions; when
      content came in under, it left up to 236px of dead space instead. Pinning to
      the container and letting the % widths below spread the slack proportionally
      fixes both. min-width:0 overrides the global `table{min-width:1000px}` so the
      breakpoints below can shrink it (that 1000px floor also overflowed at 1024).

      The 4px gutter is deliberate: `tbody tr:hover` in main-BaM0DGch.css (built
      from assets/onetab-studio.css, minified there to `transform:translate(3px)`)
      nudges the hovered row 3px RIGHT. At a flush width:100% that 3px lands past
      the container edge and raises a horizontal scrollbar for as long as the
      pointer is over any row — which reads as a permanent scrollbar, since the
      mouse is always on the table while you look at it. This is the "sub-pixel
      scrollbar that flickered on hover" the old max-content comment blamed on
      width. Reserving 4px gives the nudge somewhere to go, keeping the animation.
      If the nudge is ever dropped, this can go back to a flat width:100%. */
#dataTable {
  width: calc(100% - 4px) !important;
  max-width: 100% !important;
  min-width: 0 !important;
}

/* 1) Logo no longer clipped. The 46px round avatar sat inside a 56px cell with
      16px side padding (24px content box) under overflow:hidden, so its left/
      right edges were cut. Trim the padding and allow the avatar to show. */
#dataTable td.td-logo {
  padding: 8px 6px !important;
  overflow: visible !important;
}

/* 2) Alignment polish.
      - Header cells were uneven because the sort arrow (↕) wrapped onto a
        second line for the longer labels (V1/HR, CH/HR, 48H, SUBS), making the
        header row look ragged. Keep every header on a single line with its
        arrow inline so the whole header row sits on one baseline.
      - Body cells centered vertically; number columns use tabular figures so
        digits line up column-to-column. */
#dataTable thead th { white-space: nowrap !important; vertical-align: middle !important; }
#dataTable thead th .ot-sort-arrow {
  display: inline-block !important;
  margin-left: 4px !important;
  vertical-align: middle !important;
}
#dataTable tbody td { vertical-align: middle !important; }
#dataTable td.views-num,
#dataTable td.vhr-cell { font-variant-numeric: tabular-nums !important; }

/* Fresh, subtle row hover for scannability */
#dataTable tbody tr { transition: background .15s ease; }
#dataTable tbody tr:hover { background: rgba(99, 102, 241, 0.06) !important; }

/* 2b) Tighter horizontal padding — buys the headroom the % widths above need.
       At 12px the 16 columns need 1611px of the 1654px available: 2.6% headroom, so
       one longer channel name or a 5-digit sub count re-broke the layout. 10px
       costs 2px per side (barely visible) and drops the requirement to 1559px —
       6.5% headroom, enough to absorb normal data variance. */
#dataTable thead th, #dataTable tbody td {
  padding-left: 10px !important;
  padding-right: 10px !important;
}

/* 2c) Number columns (V1, V2, V3, V1/hr, Ch/hr, 48H, Subs) — centre both the
       header label and the value so each figure sits directly under its title
       instead of floating to the right edge of the column. */
#dataTable thead th:nth-child(7),  #dataTable tbody td:nth-child(7),
#dataTable thead th:nth-child(8),  #dataTable tbody td:nth-child(8),
#dataTable thead th:nth-child(9),  #dataTable tbody td:nth-child(9),
#dataTable thead th:nth-child(10), #dataTable tbody td:nth-child(10),
#dataTable thead th:nth-child(11), #dataTable tbody td:nth-child(11),
#dataTable thead th:nth-child(12), #dataTable tbody td:nth-child(12),
#dataTable thead th:nth-child(14), #dataTable tbody td:nth-child(14) {
  text-align: center !important;
}

/* 2d) Channel column: truncation only. The 150px cap here dated from when this
       column was `auto` and soaked up every leftover pixel (≈200px for an ~87px
       name). Its 12.5% above now bounds it, so the cap only fought the % scheme;
       the ellipsis behaviour it existed for is kept. */
#dataTable thead th:nth-child(3),
#dataTable td.td-name {
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
}
#dataTable td.td-name .ch-name {
  display: inline-block !important;
  max-width: 100% !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  white-space: nowrap !important;
  vertical-align: middle !important;
}

/* 3) Tertiary columns (V2, V3, Ch/hr, 48H, Sched) drop below ~1900px. */
@media (max-width: 1900px) {
  #dataTable thead th:nth-child(8),  #dataTable tbody td:nth-child(8),
  #dataTable thead th:nth-child(9),  #dataTable tbody td:nth-child(9),
  #dataTable thead th:nth-child(11), #dataTable tbody td:nth-child(11),
  #dataTable thead th:nth-child(12), #dataTable tbody td:nth-child(12),
  #dataTable thead th:nth-child(15), #dataTable tbody td:nth-child(15) {
    display: none !important;
  }
}

/* 4) Secondary columns (PC, Last Upload, V1/hr) drop below ~1500px so the
      core table (#, Logo, Channel, Age, V1, Thumb, Subs, Restrictions) fits
      1366–1440 laptops/monitors without a horizontal scrollbar. */
@media (max-width: 1550px) {
  #dataTable thead th:nth-child(4),  #dataTable tbody td:nth-child(4),
  #dataTable thead th:nth-child(5),  #dataTable tbody td:nth-child(5),
  #dataTable thead th:nth-child(10), #dataTable tbody td:nth-child(10) {
    display: none !important;
  }
}


/* -------------------------------------------------------------
   Compliance heatmap layout — the .ana-hm-grid was rendering
   with no grid styles, so every cell (width:100%) became a
   full-width block ("giant bars"). Column count is set inline
   by JS; this gives the container its grid + tidy cell styling.
   ------------------------------------------------------------- */
.ana-heatmap-container { overflow-x: auto; padding: 4px 0 8px; }
.ana-hm-grid { display: grid; align-items: center; gap: 5px 4px; min-width: min-content; }
.ana-hm-date-row { display: contents; }
.ana-hm-date {
  writing-mode: horizontal-tb;
  height: auto;
  padding: 0 0 6px;
  font-size: 10px;
  line-height: 1;
  color: var(--text3);
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.ana-hm-cell {
  width: auto;
  height: 22px;
  border-radius: 4px;
  transition: transform .1s ease;
}
.ana-hm-cell:hover { transform: scale(1.15); }
.ana-hm-chname { font-size: 11.5px; padding-right: 10px; }
/* Legend swatch for the compliance heatmap (colour meaning key). */
.ana-hm-swatch { width: 12px; height: 12px; border-radius: 3px; display: inline-block; flex-shrink: 0; box-shadow: inset 0 0 0 1px rgba(255,255,255,.12); }


/* ── Video-type icons (additive 2026-07-02): official-style Shorts logo on SHORT
   badges + long-video player icon on LONG badges. Pure CSS — inherits each
   badge's own color via currentColor mask. Safe to append; touches no rule. ── */
.date-type.shorts::before,.date-type.long::before,
.vtype-badge.vt-short::before,.vtype-badge.vt-short2::before,.vtype-badge.vt-long::before{
  content:"";display:inline-block;width:11px;height:11px;margin-right:4px;
  vertical-align:-1.5px;background-color:currentColor;
  -webkit-mask:var(--ot-vticon) center/contain no-repeat;
  mask:var(--ot-vticon) center/contain no-repeat}
.date-type.shorts::before,.vtype-badge.vt-short::before,.vtype-badge.vt-short2::before{
  --ot-vticon:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='white' d='m18.931 9.99-1.441-.601 1.717-.913a4.48 4.48 0 0 0 1.874-6.078 4.506 4.506 0 0 0-6.09-1.874L4.792 5.929a4.504 4.504 0 0 0-2.402 4.193 4.521 4.521 0 0 0 2.666 3.904c.036.012 1.442.6 1.442.6l-1.706.901a4.51 4.51 0 0 0-2.369 3.967A4.528 4.528 0 0 0 6.93 24c.725 0 1.437-.174 2.08-.508l10.21-5.406a4.494 4.494 0 0 0 2.39-4.192 4.525 4.525 0 0 0-2.678-3.904ZM9.597 15.19V8.824l6.007 3.184z'/%3E%3C/svg%3E")}
.date-type.long::before,.vtype-badge.vt-long::before{
  --ot-vticon:url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect x='1.5' y='5' width='21' height='14' rx='4' fill='none' stroke='white' stroke-width='2.6'/%3E%3Cpath d='M9.8 9l5.4 3-5.4 3z' fill='white'/%3E%3C/svg%3E")}
/* ── Embed/no-sidebar layout fix (additive 2026-07-02) ──
   The 1025px override above forces `.ot-app` to reserve a sidebar column
   with !important. In embed mode (growth.html?embed=1 inside CI Studio) the
   shell renders NO sidebar, so the single .ot-main child landed in the
   260px sidebar column and the whole page squeezed into a narrow strip.
   Higher-specificity exception so sidebar-less shells span full width. */
@media (min-width: 1025px) {
  .ot-app.ot-app--no-sidebar {
    grid-template-columns: minmax(0, 1fr) !important;
  }
}

/* ── Missing v2 card-head classes (additive 2026-07-02) ──
   OTT pages (growth.js, intel.js …) emit .ot-card-v2-head/.ot-card-v2-sub,
   but the theme only ever defined .ot-card-v2-header — so those card heads
   rendered as unstyled blocks: the right-side badge ("2 LIVE", win/lose
   pills) dropped below the title and pressed against the bottom-left edge.
   Define them to match the design language: title left, badges right. */
.ot-card-v2-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.ot-card-v2-sub {
  font-size: 11.5px;
  color: var(--ot-text-muted);
  margin-top: 2px;
  line-height: 1.5;
}

/* ── Embed-mode breathing room (additive 2026-07-02) ──
   .ot-main--no-topbar strips ALL .ot-content padding (design-system:447),
   so pages embedded in CI Studio (growth/intel iframes, body.ot-embed)
   rendered their heading, tabs and toolbar flush against the panel's left
   edge. Restore the normal content padding for embedded pages only. */
body.ot-embed .ot-content {
  padding: 24px 28px 48px !important;
}

/* ── Equal-width schedule badges (additive 2026-07-02) ──
   "Shorts Missing" / "Long Missing" are inline-flex badges sized to their
   text, so the two stacked pills in the dashboard SCHED column rendered
   with different widths (142px vs 127px — looked ragged). One shared
   min-width (widest text, measured live) makes every pill in the stack
   identical; content stays centered via the base rule above. */
.miss-badge {
  min-width: 144px !important;
}

/* ── Equal-width SHORT/LONG pills in LAST UPLOAD column (additive 2026-07-02) ──
   Same ragged-pill problem as the SCHED column: SHORT (60px) vs LONG (54px)
   made the stacked rows uneven, and .date-split centers each .date-row, so a
   row with no date ("—") floated toward the middle instead of lining up with
   its sibling. Equal pill width + full-width rows = one clean left column;
   missing uploads keep their slot and just show the dash. */
.date-row .date-type {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 60px;
}
.date-split .date-row {
  width: 100%;
}

/* ── Peak Optimizer modal table fits the dialog (additive 2026-07-04) ──
   The global `table { min-width:1000px }` rule (meant for the wide dashboard
   leaderboard) leaked onto the Peak Optimizer's .adm-table inside the Upload
   Schedule modal, forcing it 1000px wide inside an 860px dialog. Result: the
   channel names on the left and the "Apply Recommendation" button on the right
   were clipped, with a mid-position horizontal scrollbar hiding both ends.
   Fix in two parts:
   1) Drop the inherited 1000px floor on the optimizer table so it sizes to its
      own content (~914px natural). Scoped to #optimizerResults so no other
      .adm-table (admin panels, all in overflow-x:auto wrappers) is touched.
   2) Widen the shared schedule modal 860 → 980px so the full table fits with
      margin to spare. max-width:100% still shrinks it on narrow screens, and
      #optimizerResults keeps overflow-x:auto as the final fallback. */
#optimizerResults .adm-table { min-width: 0 !important; }
.cal-box { width: 980px !important; }

/* ── Green highlight on the velocity columns V1/hr · Ch/hr · 48H (additive 2026-07-04) ──
   User wants these momentum values to stand out. The first pass used filled
   pills on Ch/hr & 48H plus a tinted V1/hr cell — but the full-cell V1/hr
   backgrounds stacked into one tall green block and the pills read as clutter
   ("box box"). So this keeps it clean: just green, slightly bold TEXT — no
   backgrounds, borders or pills. The "—" no-data cells (.vhr-na / .growth-na)
   are left untouched so blanks still read dim as "no data yet". */
/* ONLY colour the text green — never touch the cell background. An earlier pass
   set `background: none` on the V1/hr cell to kill the pill, but that also
   overrode the rank1-row / overdue-row highlight tint (rgba(245,158,11,.08),
   rule ~line 512) because .vhr-cell.vhr-pos out-specifies `.rank1-row td`. The
   cell then lost the amber every neighbour kept, showing as a dark box on the
   gold row. Leaving the background untouched lets each row's own highlight paint
   the cell normally — green text, no box. */
#dataTable td.vhr-cell.vhr-pos,
#dataTable td.views-num .growth-pos {
  color: #4ade80 !important;
  font-weight: 700 !important;
}
/* Ch/hr & 48H render as a span inside the cell — make sure the span carries no
   pill of its own (the td keeps the row highlight); it's just plain green text. */
#dataTable td.views-num .growth-pos {
  display: inline !important;
  background: none !important;
  border: none !important;
  padding: 0 !important;
}

/* ==========================================================================
   2026-07-15 — Dashboard UI polish (user request)
   • Remove "Channel Dashboard"/SNAP heading noise (done in index.html)
   • Minimal, non-boring status pill (dot + short text; loud only on error)
   • Smaller KPI stat cards → more breathing room
   • Slimmer sidebar nav (width already 216px via --ot-sidebar-w)
   • Topbar toolbar that never overflows on mid widths
   • Fluid, better-responsive PIN login
   ========================================================================== */

/* Force-hide the LIVE/SNAP mode badge — the bundle's setDashModeBadge() clears
   the element's inline display, so only an !important rule keeps it gone. */
#dashModeBadge { display: none !important; }

/* ── Status pill: subtle by default, loud only when it matters ──
   The idle/done text ("snapshot", "live") is intentionally quiet — a small
   muted chip with a soft dot. Progress ("…fetching") and errors keep their
   colour so real signals still stand out. */
#studio-header .status-pill {
  font-size: 12px !important;
  font-weight: 600 !important;
  color: var(--ot-text-muted) !important;
  background: transparent !important;
  border: none !important;
  padding: 2px 4px !important;
  letter-spacing: .1px !important;
  max-width: 240px !important;
  white-space: nowrap !important;
  overflow: hidden !important;
  text-overflow: ellipsis !important;
  display: inline-flex !important;
  align-items: center !important;
  gap: 7px !important;
}
/* soft leading dot; colour tracks the state class */
#studio-header .status-pill::before {
  content: "" !important;
  width: 7px !important; height: 7px !important;
  border-radius: 50% !important;
  background: var(--ot-text-muted) !important;
  flex-shrink: 0 !important;
  box-shadow: 0 0 6px currentColor !important;
}
#studio-header .status-pill.done { color: var(--ot-status-success, #34d399) !important; }
#studio-header .status-pill.done::before { background: var(--ot-status-success, #34d399) !important; }
#studio-header .status-pill.running { color: var(--ot-accent) !important; }
#studio-header .status-pill.running::before {
  background: var(--ot-accent) !important;
  animation: otPulseDot 1s ease-in-out infinite !important;
}
#studio-header .status-pill.error {
  color: var(--ot-status-danger, #f87171) !important;
  max-width: 420px !important;
  white-space: normal !important;
}
#studio-header .status-pill.error::before { background: var(--ot-status-danger, #f87171) !important; }
@keyframes otPulseDot { 0%,100% { opacity: 1 } 50% { opacity: .35 } }

/* ── Smaller KPI stat cards (Total Views / Active Channels / Pending) ──
   Overrides the inline font-size:2rem / margin on the values. */
#dashKpis { margin: 16px 24px !important; gap: 14px !important; }
#dashKpis .ot-card-v2 { padding: 14px 18px !important; gap: 3px !important; }
#dashKpis .ot-card-v2-title { font-size: 0.72rem !important; letter-spacing: 0.04em !important; }
#dashKpis .ana-kpi-val { font-size: 1.55rem !important; margin-bottom: 0 !important; line-height: 1.15 !important; }
#dashKpis .ana-kpi-sub { font-size: 0.72rem !important; line-height: 1.25 !important; }
#dashKpis .ot-card-v2-header span[data-oti] { transform: scale(0.85) !important; }

/* ── Slimmer sidebar nav rows (matches the narrower 216px rail) ── */
.ot-nav-item, .ana-sb-item, .adm-sb-item {
  padding: 8px 14px !important;
  margin: 1px 8px !important;
  font-size: 0.84rem !important;
}
.ot-sb-group, .ana-sb-section, .adm-sb-section { margin-bottom: 12px !important; }
.ot-sb-group-label, .ana-sb-label, .adm-sb-label { padding: 0 14px !important; margin-bottom: 4px !important; }

/* ── Topbar toolbar: never overflow horizontally on mid widths ──
   Between the drawer breakpoint (1024px) and full desktop the tool buttons
   used to wrap into an untidy second row. Let the toolbar scroll instead. */
@media (min-width: 1025px) and (max-width: 1400px) {
  #studio-header .hdr-right { flex-wrap: nowrap !important; min-width: 0 !important; }
  #studio-header .hdr-toolbar {
    flex-wrap: nowrap !important;
    overflow-x: auto !important;
    scrollbar-width: none !important;
    -ms-overflow-style: none !important;
  }
  #studio-header .hdr-toolbar::-webkit-scrollbar { display: none !important; }
  #studio-header .status-pill { max-width: 150px !important; }
}

/* ── Mobile drawer polish: dim + slide the slimmer rail cleanly ── */
@media (max-width: 1024px) {
  .ot-sidebar-backdrop {
    position: fixed !important; inset: 0 !important;
    background: rgba(0,0,0,0.5) !important;
    opacity: 0 !important; pointer-events: none !important;
    transition: opacity .25s ease !important; z-index: 99 !important;
  }
  .ot-sidebar-backdrop.open { opacity: 1 !important; pointer-events: auto !important; }
  .ot-sidebar { box-shadow: 8px 0 32px rgba(0,0,0,0.45) !important; }
  #dashKpis { margin: 14px 16px !important; }
  .ot-table-wrapper, .ot-flex.ot-justify-between { margin-left: 16px !important; margin-right: 16px !important; }
}

/* ── PIN login: fluid sizing so it stays centered & tidy at every width ──
   Replaces the fixed 320px cap with a clamp so mid/large phones and tablets
   get a comfortably sized card instead of a cramped one. */
#pinLock .ot-modal-pin, #pinLock .lock-card {
  width: clamp(280px, 88vw, 360px) !important;
  max-width: 360px !important;
  min-width: 0 !important;
}
#pinLock .pin-numpad {
  grid-template-columns: repeat(3, clamp(58px, 20vw, 74px)) !important;
  gap: clamp(12px, 3.5vw, 18px) !important;
}
#pinLock .pin-btn {
  width: clamp(58px, 20vw, 74px) !important;
  height: clamp(58px, 20vw, 74px) !important;
  font-size: clamp(20px, 6vw, 24px) !important;
}
@media (max-height: 640px) {
  #pinLock .ot-modal-pin .ot-modal-body { padding: 20px 22px !important; }
  #pinLock .lock-brand { margin-bottom: 12px !important; }
  #pinLock .lock-subtitle { margin-bottom: 14px !important; }
  #pinLock .pin-dots { margin: 4px 0 12px !important; }
  #pinLock .pin-btn { width: clamp(52px, 16vh, 68px) !important; height: clamp(52px, 16vh, 68px) !important; }
}

/* ── Topbar: logo hard-left (remove the centered gap) ──
   .header-inner ships with `margin: 0 auto`; once the "Channel Dashboard"
   heading was removed the inner content got narrow enough to visibly centre,
   leaving a big empty box on the left and pushing the OneTab logo inward.
   Force full-width so justify-between pins the logo to the far left and the
   controls to the far right — the normal topbar layout. */
#studio-header .header-inner {
  width: 100% !important;
  max-width: 100% !important;
  margin: 0 !important;
}

/* ── Topbar brand column: logo centred over the sidebar, Live beside it ──
   Full-width alone jammed the logo against the viewport edge. Give the brand
   the sidebar's own width and centre the logo inside it, so the mark sits over
   the middle of the sidebar rail exactly like the nav below it. The status
   pill (Live/Snapshot) then follows immediately, and the toolbar + controls
   keep to the right. Desktop only — below 1025px the header stacks (drawer). */
@media (min-width: 1025px) {
  #studio-header { padding-left: 0 !important; }
  #studio-header .header-inner {
    justify-content: flex-start !important;
    flex-wrap: nowrap !important;
  }
  #studio-header .hdr-brand {
    width: var(--ot-sidebar-w) !important;
    justify-content: center !important;
    flex-shrink: 0 !important;
    margin: 0 !important;
  }
  #studio-header #statusBar {
    margin: 0 16px 0 4px !important;
    flex-shrink: 0 !important;
  }
  #studio-header .hdr-right {
    flex: 1 1 auto !important;
    justify-content: flex-end !important;
    min-width: 0 !important;
  }
}
