/* ────────────────────────────────────────────────────────────────────────
 * dc-table.css — dc_table (Tabulator 6.5) theme override layer.
 *
 * Skins Tabulator's base tabulator.min.css (vendor/) onto the dc-* design
 * tokens (--dc-*). Loaded AFTER vendor/tabulator.min.css so these rules
 * win the cascade. Dark mode follows the same `[data-bs-theme="dark"]`
 * attribute every other dc-* stylesheet in this app keys off (see
 * dc-theme.css) — the tokens themselves flip value under that selector,
 * so almost nothing here needs a dark-specific override.
 *
 * Typography rule (design system): cap font-weight at 600, hierarchy via
 * colour / size / caps-tracking — never anything above 600 in this file.
 * ──────────────────────────────────────────────────────────────────────── */

/* Tabulator adds its own `.tabulator` class directly onto THIS SAME div
   (`<div id="..." class="dc-table-output shiny-bound-output tabulator">`),
   not onto a nested child — so every rule below is `.dc-table-output
   .tabulator-X`, never `.dc-table-output .tabulator .tabulator-X`. A
   descendant selector with that redundant middle `.tabulator` segment
   matches nothing (bug caught in review 2026-07-13: the theme layer wasn't
   applying at all — vendor grey tableholder, 14px non-uppercase headers).
   Root-level Tabulator chrome (background/border/font) is folded into the
   base `.dc-table-output` rule below for the same reason. */
.dc-table-output {
  flex: 1 1 auto;
  min-height: 0;
  height: 100%;
  overflow: hidden;
  background: transparent;
  border: none;
  font-family: var(--dc-font-sans);
  font-size: 13px;
  color: var(--dc-ink);
}

/* ── Header ─────────────────────────────────────────────────────────── */

/* panel-2 header band (was panel) — .ig-films-table spec, 2026-07-21
   Library migration: `thead th { background: var(--dc-panel-2) }`. */
.dc-table-output .tabulator-header {
  background: var(--dc-panel-2);
  border-bottom: 1px solid var(--dc-line);
}

.dc-table-output .tabulator-header .tabulator-col {
  background: var(--dc-panel-2);
  border-right: none;
}

/* ── Single-row headers (2026-07-13 operator feedback, round 2 + round 3) ──
   Tabulator stacks the column title above the header filter by default —
   two rows per header. Every filtered column here carries its name on the
   filter control itself instead (an `input`'s placeholder, or a
   dcMultiSelectPicker button's label — see pages/library.py column defs
   + the `dcMultiSelectPicker` widget in this file's JS twin), so the
   title text is redundant there.
   Round 3 fix: the flex-row layout below used to be scoped to
   `:has(.tabulator-header-filter)` only, so an unfiltered column (Runtime)
   kept the vendor's default stacked layout with DIFFERENT padding —
   its title sat at a different vertical position than every other
   column's label, and used a different font-weight (700, over the
   design system's 600 cap). Applying the row layout + ONE shared label
   typography to every column (not just filtered ones) puts every header
   label — static title, input placeholder, or picker button label — on
   the same row, same baseline, same font. */
/* NOTE the 4-class selector. Vendor tabulator.min.css ships
   `.tabulator .tabulator-header .tabulator-col .tabulator-col-content
   { padding: 4px }` — four class steps. The 2-step selector this rule used
   to carry lost on specificity, so its `padding: 0 8px` never applied and
   every header cell sat at the vendor's 4px: the check column's box landed
   4px from the rail edge while the search box below it sat at 8px, and the
   sort arrows inherited the same inconsistency (operator 2026-08-10: "check
   box same margin left as search bar and platform dropdown ... title and
   relaese label and arrow should have consistent padding"). Matching the
   vendor's specificity and loading after it is what makes this win. */
.dc-table-output .tabulator-header .tabulator-col .tabulator-col-content {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 8px;
  /* exactly one 34px grid row — view-bar (34) + this header (34) = 68,
     the same y where the sidebar's first nav band and the drawer's chrome
     end, so the first horizontal line connects across the whole console
     (full-screen composite, 2026-07-20). 33px content + the header's 1px
     border-bottom = 34 total (verified via getBoundingClientRect — a plain
     34px here measured 35 and drifted every row 1px off the sidebar bands).
     Was 32px min + 5px v-padding. */
  min-height: calc(var(--dc-topbar-h) - 1px);
  box-sizing: border-box;
}

.dc-table-output .tabulator-col-title-holder {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
}

/* Shared header-label typography — the ONE style every header-row label
   uses, whichever control carries it (static title text, an `input`'s
   placeholder, or a dcMultiSelectPicker button's label). Design system
   typography rule: cap font-weight at 600 (was 700 pre-round-3 on both
   the title and the picker label — fixed here). */
.dc-table-output .tabulator-col-title,
.dc-table-output .tabulator-header-filter input::placeholder,
.dc-hf-btn__lbl {
  font-family: var(--dc-font-sans);
  /* 10.5px / 0.08em tracking per the .ig-films-table header spec
     (2026-07-21; was 10px / 0.06em). Weight stays 600 — the spec's 700
     exceeds this file's design-system cap (operator feedback, round 3). */
  font-size: 10.5px;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  /* NOT BOLD (operator 2026-08-31: "theyre all bold I dont like bold outside
     of film titles"). Was 600. A column name is a label, and the row content
     under it is the thing worth reading — 600 across a twelve-column header
     put the loudest type on the page furthest from the point.
     `--dc-muted` rather than `--dc-faint` to buy back the legibility the
     weight was carrying at 10.5px. */
  font-weight: var(--dc-fw-normal);
  color: var(--dc-muted);
  white-space: nowrap;
}

/* Round 9 (operator feedback, "remove hover on column headers"): headers
   must stay visually inert on plain mouse-over — no background reveal.
   `cursor: pointer` stays (it's a functional affordance, not visual
   chrome — the column is still click-to-sort).

   Round 11 (operator re-test): the background reveal SURVIVED on the four
   sortable columns (Film/Year/Director/Runtime) despite round 9's fix,
   because it isn't ours — vendor/tabulator.min.css ships its own hover
   rule, `.tabulator .tabulator-header .tabulator-col.tabulator-sortable
   .tabulator-col-sorter-element:hover{background-color:#cdcdcd}`, gated to
   sortable columns via a THIRD class (`tabulator-col-sorter-element`,
   added by Tabulator's own JS to every sortable column — confirmed live via
   DOM inspection) that this file's override never matched. That vendor
   selector chains 6 class/pseudo-class steps
   (.tabulator .tabulator-header .tabulator-col .tabulator-sortable
   .tabulator-col-sorter-element :hover) — equal specificity to the 6-step
   selector below (`.tabulator` and `.tabulator-header` are real ancestors
   of `.tabulator-col` here, same as in the vendor rule; `.dc-table-output`
   IS the `.tabulator` element per the note atop this file), so this
   override wins purely on source order (loaded after vendor CSS). The
   generic 4-step `.dc-table-output .tabulator-col.tabulator-sortable:hover`
   selector above is LOWER specificity than the vendor's 6-step one and
   never set a background anyway, so it never neutralized this — kept only
   for the `cursor: pointer` declaration on any future sortable column that
   doesn't carry `tabulator-col-sorter-element`. */
.dc-table-output .tabulator-col.tabulator-sortable:hover {
  cursor: pointer;
}
.dc-table-output .tabulator-header
  .tabulator-col.tabulator-sortable.tabulator-col-sorter-element:hover {
  background: var(--dc-panel);
  cursor: pointer;
}

.dc-table-output .tabulator-col-sorter {
  color: var(--dc-faint);
}

/* Consistent label-left / arrow-right across every sortable header cell
   (operator 2026-08-10: "title and relaese label and arrow should have
   consistent padding").

   The two kinds of header cell were laid out differently and it showed:
   a FILTERED column (Title) renders as [filter input, flex:1][sorter], so
   its arrow lands at the column's right edge; an UNFILTERED column
   (Release) renders as [title-holder, flex:0 0 auto] with the sorter
   absolutely positioned INSIDE that holder — so its arrow sat wherever the
   title text happened to end (measured 12px vs 27px from their respective
   column edges). Letting the unfiltered holder grow puts its absolute
   sorter on the same right edge, so both read the same. */
.dc-table-output .tabulator-header
  .tabulator-col:not(:has(.tabulator-header-filter)) .tabulator-col-title-holder {
  flex: 1 1 auto;
  min-width: 0;
}

.dc-table-output .tabulator-col-content:has(.tabulator-header-filter)
  .tabulator-col-title-holder {
  /* Vendor CSS positions `.tabulator-col-sorter` (the click-to-sort arrow)
     with `position:absolute` INSIDE this holder — absolutely-positioned
     children never contribute to their parent's layout size. With the
     title (the holder's only in-flow child) hidden below, the holder
     collapsed to 0×0 and the sort arrow became unreachable/unclickable
     (caught live in review verification: `getBoundingClientRect()` on the
     holder measured 0×0 despite the arrow still being present in the DOM).
     An explicit min box gives the absolutely-positioned arrow somewhere to
     actually render + be clicked. Only needed on filtered columns — Runtime
     keeps its title visible so its holder sizes to the text normally.
     `order: 1` moves it AFTER the header-filter below (operator feedback:
     headers read as centered) — as the first flex child by DOM order, this
     holder's reserved 18px + the row's `gap` pushed every filter/picker
     control ~24-28px right of the column's true left padding, while
     Runtime's plain (unfiltered) title sat flush left — the mismatch is
     what read as "off-center". Reordering after the filter control removes
     that phantom left inset without changing the sort arrow's own
     clickability (CSS `order` is visual-only, DOM/event wiring untouched). */
  position: relative;
  min-width: 18px;
  min-height: 18px;
  order: 1;
}
.dc-table-output .tabulator-col-content:has(.tabulator-header-filter)
  .tabulator-col-title {
  display: none;
}
.dc-table-output .tabulator-col-content:has(.tabulator-header-filter)
  .tabulator-header-filter {
  flex: 1 1 auto;
  min-width: 0;
  padding-top: 0;
  margin: 0;
  order: 0;   /* renders before the title-holder — see order:1 above */
}

/* Column resize handle — stays invisible even on hover (round 9, "headers
   inert on mouse-over"); the drag zone is still there and still functional
   (vendor CSS gives it `cursor: ew-resize` on its own :hover), just without
   the colour reveal that used to fire on hovering anywhere in the header. */
.dc-table-output .tabulator-col-resize-handle {
  background: transparent;
}

/* Column show/hide + any other header menu popup */
.dc-table-output .tabulator-header-popup-button {
  color: var(--dc-muted);
}
.dc-table-output .tabulator-header-popup-button:hover {
  color: var(--dc-ink);
}

/* ── Header filters (Tabulator's built-in per-column filter row) ─────────
   Rendered inside the same header cell, in the single-row layout above.
   The TYPED value stays normal-case/readable (this rule); the EMPTY-state
   placeholder gets the shared header-label typography instead (see the
   `::placeholder` selector folded into the shared rule above) — same
   height (22px) and vertical centring as the dcMultiSelectPicker buttons
   so every header control's label lands on the same baseline.

   Round 6 (operator feedback, "header visual consistency"): every column
   header must read as ONE system — same flat/quiet chrome as the mockup's
   plain `<th>` (claude-design/skills/dc-skill/dc-library.html has no box
   around its header text at all), with the filter TYPE as the only
   differentiator (this input's placeholder text vs the picker button's
   icon+label vs Runtime's bare sort arrow — see `.dc-hf-btn` below for the
   picker half of this pair). The input/select box itself is transparent by
   default (matches Runtime's chrome-less label) and only takes on
   form-control styling (background + border) on focus, or once it actually
   holds a typed value — `:not(:placeholder-shown)` is a CSS-only way to
   detect "this column has an active filter" without any JS change,
   mirroring the picker button's persistent `.on` state below.

   Round 9 (operator feedback, "remove hover on headers"): dropped the
   :hover rule that used to reveal this same chrome on mouse-over — headers
   now only pick up visible chrome on FOCUS (typing needs the affordance)
   or once a value/selection is actually active, never on a passing
   mouse-over. */
.dc-table-output .tabulator-header-filter {
  padding-top: 0;
  display: flex;
  align-items: center;
}
.dc-table-output .tabulator-header-filter input,
.dc-table-output .tabulator-header-filter select {
  width: 100%;
  height: 22px;
  line-height: 1;
  font-size: 12px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: normal;
  color: var(--dc-ink);
  background: transparent;
  border: 1px solid transparent;
  /* ROUNDED 2026-08-31 (operator: "the inputs are still boxy no rounded
     corners"). Round 12 squared these on the reasoning that the whole
     header/popover system is flush — but that rule is about the SHELL, and
     the editing register (anything you type into) was rounded the same day
     across the modals and the drawer. `--dc-radius-sm`, not `--dc-radius`:
     these are 22px in-table controls, which is exactly what the sm token is
     documented for. The popover PANEL stays square — it is chrome that
     floats, not a control. */
  border-radius: var(--dc-radius-sm);
  padding: 2px 6px;
  box-sizing: border-box;
  transition: background 120ms ease, border-color 120ms ease;
}
.dc-table-output .tabulator-header-filter input:focus,
.dc-table-output .tabulator-header-filter select:focus {
  outline: none;
  border-color: var(--dc-primary);
  background: var(--dc-panel);
}
.dc-table-output .tabulator-header-filter input:not(:placeholder-shown) {
  background: var(--dc-panel-2);
  border-color: var(--dc-line-2);
}

/* ── Custom header-filter picker widget (dc-table.js
   DC_TABLE_HEADER_FILTERS) — a small trigger button in the header cell +
   a checklist popover positioned via fixed coordinates (see dc-table.js
   dcMultiSelectPicker). Generic naming (.dc-hf-*) — not Library/Festivals
   specific; every enumerable column (Genre/Country/Tags/Festivals) reuses
   this one widget (generalized 2026-07-13, operator feedback) instead of
   Tabulator's native "list" header filter, so `.tabulator-edit-list*`
   (the vendor multiselect popup) is unused now — removed rather than left
   as dead CSS. */
/* Round 6: flat by default (no border/background), matching the header
   text-input's chrome-less default above — the SAME one-system treatment,
   the icon+label is the only thing that differentiates a picker column
   from a text-search column. Chrome (border+background) only appears
   persistently once a selection is active (`.on`) — round 9 dropped the
   :hover reveal that used to also show it on mouse-over (operator
   feedback: headers must stay visually inert on plain hover). The
   popover-open state doesn't need its own rule here: the button's `.on`
   class already tracks "has an active selection" independently of
   hover/open, which is the state this rule needs to survive. */
.dc-hf-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  border: 1px solid transparent;
  background: transparent;
  /* Rounded 2026-08-31 with the text-filter input above — this button is the
     picker-column equivalent of that input, same one-system treatment. */
  border-radius: var(--dc-radius-sm);
  padding: 2px 7px;
  height: 22px;
  box-sizing: border-box;
  cursor: pointer;
  color: var(--dc-muted);
  line-height: 1;
  white-space: nowrap;
  transition: background 120ms ease, border-color 120ms ease;
}
.dc-hf-btn.on {
  border-color: var(--dc-primary);
  color: var(--dc-primary);
  background: var(--dc-primary-soft);
}
/* .dc-hf-btn__lbl's font-size/weight/case/tracking/color come from the
   shared header-label rule above (same declaration as .tabulator-col-title
   and the header-filter input placeholder) — this button carries the
   column's name exactly like a filter input's placeholder does, so it
   must look identical, not a separate one-off style. */
.dc-hf-btn__cnt {
  background: var(--dc-primary);
  color: #fff;
  border-radius: 999px;
  font-size: 10px;
  padding: 0 5px;
  /* 600, not 700 — this file's documented cap. It keeps some weight because
     it is 10px reversed out of a filled pill, where 400 stops being legible. */
  font-weight: 600;
  line-height: 15px;
}
/* Round 9 (operator feedback): a dropdown affordance chevron, trailing the
   label (after the count badge, if any — always the last element so it
   reads as a fixed "this opens a picker" cue regardless of selection
   state). Sized/coloured to match `.tabulator-col-sorter`'s sort arrow
   (var(--dc-faint), a few px tall) rather than inheriting `.dc-hf-btn`'s
   own --dc-muted or the `.on` state's --dc-primary — this is a static
   affordance icon, not a value that should shift with selection state,
   same as the sort arrow never changes colour just because a filter is
   active on a sortable column. */
.dc-hf-btn__chev {
  font-size: 9px;
  color: var(--dc-faint);
  margin-left: 1px;
}

/* Round 10 (operator feedback): flush against the header column, same
   flush language as the sidebar/view-switcher — no border-radius, and the
   popover's top edge meets the header row's bottom edge directly (see the
   JS positioning in DC_TABLE_HEADER_FILTERS.dcMultiSelectPicker, which
   used to add a 4px gap before `r.bottom` and no longer does). Left edge
   stays aligned to the column (unchanged from an earlier round). */
.dc-hf-pop {
  z-index: 4000;
  background: var(--dc-panel);
  border: 1px solid var(--dc-line);
  border-radius: 0;
  box-shadow: 0 12px 30px -10px rgba(0, 0, 0, 0.35);
  padding: 6px;
  width: 240px;
}
/* Search box (operator feedback, round 8) — top of every dcMultiSelectPicker
   popover (Genre/Country/Tags/Festivals share this one component, so this
   styles all four at once). Same visual language as the header-filter
   input/picker-button chrome: quiet border, dc tokens, focus ring in
   --dc-primary — but ALWAYS has its chrome visible (unlike the flat-until-
   active header controls) since this is inside an already-open popover,
   not sitting in the quiet header row. */
.dc-hf-pop__search {
  display: flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--dc-line-2);
  /* Rounded 2026-08-31 with the header inputs — it is a control you type
     into. The popover it sits in stays square: that is chrome that floats. */
  border-radius: var(--dc-radius-sm);
  background: var(--dc-panel-2);
  padding: 5px 8px;
  margin-bottom: 6px;
}
.dc-hf-pop__search:focus-within {
  border-color: var(--dc-primary);
  background: var(--dc-panel);
}
.dc-hf-pop__search i {
  font-size: 12px;
  color: var(--dc-faint);
  flex: none;
}
.dc-hf-pop__search-input {
  flex: 1 1 auto;
  min-width: 0;
  border: none;
  background: none;
  outline: none;
  font-size: 12px;
  font-weight: 400;
  color: var(--dc-ink);
  padding: 0;
}
.dc-hf-pop__search-input::placeholder { color: var(--dc-faint); }
.dc-hf-pop__nomatch {
  padding: 10px 6px;
  text-align: center;
  font-size: 12px;
  color: var(--dc-muted);
}
.dc-hf-pop__list { max-height: 220px; overflow-y: auto; }
.dc-hf-check {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 5px 6px;
  border-radius: var(--dc-radius-sm, 5px);
  font-size: 12px;
  cursor: pointer;
  color: var(--dc-ink);
}
.dc-hf-check:hover { background: var(--dc-panel-2); }
.dc-hf-check__box {
  width: 14px;
  height: 14px;
  border: 1.5px solid var(--dc-line-2);
  border-radius: 4px;
  display: grid;
  place-items: center;
  color: #fff;
  font-size: 9px;
  flex-shrink: 0;
}
.dc-hf-check.on .dc-hf-check__box { background: var(--dc-primary); border-color: var(--dc-primary); }
.dc-hf-check__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dc-hf-check__count { font-size: 11px; color: var(--dc-faint); flex-shrink: 0; }
.dc-hf-pop__foot {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--dc-line);
  font-size: 11px;
  color: var(--dc-muted);
}
.dc-hf-pop__hint { font-size: 11px; color: var(--dc-muted); }
.dc-hf-pop__link {
  color: var(--dc-primary);
  cursor: pointer;
  background: none;
  border: none;
  font-size: 12px;
  font-weight: 600;
  padding: 0;
}
.dc-hf-pop__link:hover { text-decoration: underline; }

/* ── Body / rows / cells ────────────────────────────────────────────── */

.dc-table-output .tabulator-tableholder {
  background: transparent;
}

/* Vendor's base CSS sets color/background directly on `.tabulator-table`
   via `.tabulator .tabulator-tableholder .tabulator-table` — a 3-class
   selector. `.tabulator` is the SAME element as `.dc-table-output` (see
   the note atop this file), so a single-class `.dc-table-output { color }`
   loses to that 3-class vendor rule regardless of load order: found live
   in dark-mode verification (2026-07-13 review fix) as near-invisible
   (#333) cell text over a stray white table background. Match the vendor
   selector's shape 1:1 (swap `.tabulator` → `.dc-table-output`, same
   specificity) so the later-loaded override actually wins. */
.dc-table-output .tabulator-tableholder .tabulator-table {
  background-color: transparent;
  color: var(--dc-ink);
}

.dc-table-output .tabulator-row {
  background: var(--dc-panel);
  border-bottom: 1px solid var(--dc-line);
  cursor: pointer;
}

.dc-table-output .tabulator-row.tabulator-row-even {
  background: var(--dc-panel);
}

.dc-table-output .tabulator-row:hover {
  background: color-mix(in srgb, var(--dc-panel-2) 80%, transparent);
}

.dc-table-output .tabulator-row.is-sel {
  background: var(--dc-primary-soft) !important;
}

/* Scheduling bulk-selection highlight (checkbox path, managed by _dcSchedSelSet) */
.dc-table-output .tabulator-row.is-selected {
  background: var(--dc-primary-soft) !important;
}

/* ── `.dc-table--gallery` — the taller, content-driven row ────────────────
   Opt-in modifier on `.dc-table-output`. Rows size to their content instead
   of the dense 34px grid below, which is what a poster column and a stacked
   title/original-title cell need.

   Introduced on the Curation page (2026-08-24/25, scoped `.cur-page`),
   generalised here on 2026-08-26 when the operator asked for the Library
   catalogue to match it. Two pages sharing a row/cell rule makes it table
   styling, not page styling.

   THE CAVEAT, carried over verbatim because it is still real: Tabulator's
   vertical virtual DOM is happiest with uniform rows. It measures variable
   ones, but scroll behaviour wants checking at LENGTH. Verified clean at 34
   rows; re-check when a batch that size lands, and if it jitters the
   fallback is a fixed height at the 72px worst case rather than reverting
   to 34.

   NO `display:flex` on the cells. An earlier version set it to stretch them,
   and it worked visually while quietly changing the row's hit area —
   Tabulator lays its own cells out, and overriding that left a strip of row
   that looked clickable and was not. The cells already stretch via their own
   `align-items`, so the row only needs a floor. */
.dc-table-output.dc-table--gallery .tabulator-cell {
  height: auto;
  min-height: 47px;
  white-space: normal;      /* the pills need to wrap; at 34px they could not */
  padding-top: 6px;
  padding-bottom: 6px;
  align-items: center;
}
.dc-table-output.dc-table--gallery .tabulator-row { min-height: 48px; }
.dc-table-output.dc-table--gallery .film-cell { align-items: center; }
.dc-table-output.dc-table--gallery .tags { row-gap: 2px; }
/* The poster fills the row's full height. Inside the film cell it floated
   against a two- or three-line cell instead of filling it, which is why it
   moved out into its own column (operator 2026-08-24). */
.dc-table-output.dc-table--gallery .tabulator-cell.cur-poster-col {
  padding: 0;
  align-items: stretch;
}

/* Dense 34px rows (.ig-films-table spec, 2026-07-21 Library migration):
   cell height 33px + the row's 1px border-bottom = one 34px grid row, so
   table rows stay in phase with the sidebar bands and drawer sections.
   inline-flex centres single-line content vertically (the vendor cell is
   inline-block + padding-sized, which drifts with content height). */
.dc-table-output .tabulator-cell {
  height: 33px;
  /* 8px, matching the header cell's own inner padding (see the 4-class
     `.tabulator-col-content` rule above). They were 10 vs 4, so a column's
     header content and its body content never sat on the same x — most
     visibly the check column, whose header box and row boxes were 8px
     apart. Operator 2026-08-10: "check, title and status consistant
     spacing". */
  padding: 0 8px;
  border-right: none;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  overflow: hidden;
  box-sizing: border-box;
  font-size: 13px;
  color: var(--dc-muted);   /* quiet row content — the title carries the ink */
}

/* Selection strip on the FIRST cell (Library has no checkbox column —
   gx-nocheck variant of the .ig-films-table spec): a 4px state edge that
   fills with primary on the click-selected row. Padding drops 10 → 8 so
   content keeps its visual left position. `.is-selected` (Scheduling's
   checkbox bulk path) intentionally NOT included — its strip belongs on
   the cell after the checkbox and is that page's migration, not this one. */
.dc-table-output .tabulator-cell:first-child {
  border-left: 4px solid transparent;
  padding-left: 8px;
}
.dc-table-output .tabulator-row.is-sel .tabulator-cell:first-child {
  border-left-color: var(--dc-primary);
}

/* Row state edges (IMPORT_GROUPS.md §11) — rows carrying `_rowClass` in
   their data get these via dc-table.js's rowFormatter. Selection (.is-sel)
   wins via source order below. */
.dc-table-output .tabulator-row.row-locked   .tabulator-cell:first-child { border-left-color: var(--dc-edge-locked); }
.dc-table-output .tabulator-row.row-decision .tabulator-cell:first-child { border-left-color: var(--dc-edge-decision); }
.dc-table-output .tabulator-row.row-running  .tabulator-cell:first-child { border-left-color: var(--dc-edge-running); }
.dc-table-output .tabulator-row.row-danger   .tabulator-cell:first-child { border-left-color: var(--dc-danger); }
.dc-table-output .tabulator-row.row-pending  .tabulator-cell:first-child { border-left-color: var(--dc-edge-pending); }
.dc-table-output .tabulator-row.is-sel       .tabulator-cell:first-child { border-left-color: var(--dc-primary) !important; }

/* Year used to be forced center here too (`[tabulator-field="year"]`) as a
   leftover from being modeled on the destination-view status columns — but
   Year is ordinary row content like Film/Director, not a centered status
   icon (same class of fix as the Festivals `dc-col-c` removal, round 10).
   Dropped (operator feedback, round 11): `.tabulator-cell` has no
   `text-align` override of its own, so Year now falls back to the browser
   default (left), matching every other catalogue column. `.dc-col-c` stays
   — it's still the deliberate opt-in for the destination-view status
   columns, which ARE meant to stay centered. */
.dc-table-output .tabulator-cell.dc-col-c {
  text-align: center;
  justify-content: center;   /* cells are inline-flex now — text-align alone no longer centres */
}

/* Mono value columns (Year — `font-family: mono; font-size: 12px` in the
   .ig-films-table spec). Opt-in via cssClass on the column def. */
.dc-table-output .tabulator-cell.dc-col-mono {
  font-family: var(--dc-font-mono);
  font-size: 12px;
}

/* Orig. Title column — italic mono muted (.ig-film-orig-col). */
.dc-table-output .tabulator-cell.dc-col-orig {
  font-family: var(--dc-font-mono);
  font-size: 12px;
  font-style: italic;
}

/* ── Empty state ────────────────────────────────────────────────────── */

.dc-table-output .tabulator-placeholder {
  color: var(--dc-muted);
  font-size: 13px;
}

/* Vendor's empty-state text colour is set on the nested `.tabulator-
   placeholder-contents` element via a 4-class selector
   (`.tabulator .tabulator-tableholder .tabulator-placeholder
   .tabulator-placeholder-contents`) — same specificity-mismatch issue as
   `.tabulator-table` above. Match the shape 1:1. */
.dc-table-output .tabulator-tableholder .tabulator-placeholder .tabulator-placeholder-contents {
  color: var(--dc-muted);
  font-size: 13px;
  font-weight: 400;
}

.dc-table-empty {
  padding: 32px 12px;
  text-align: center;
  color: var(--dc-muted);
  font-size: 13px;
}

/* ── Header menu dropdown (column show/hide) ───────────────────────── */

.tabulator-menu {
  background: var(--dc-panel);
  border: 1px solid var(--dc-line);
  border-radius: var(--dc-radius, 7px);
  box-shadow: 0 12px 30px -14px rgba(0, 0, 0, 0.4);
  padding: 5px;
}

.tabulator-menu .tabulator-menu-item {
  padding: 7px 8px;
  font-size: 13px;
  color: var(--dc-ink);
  border-radius: var(--dc-radius-sm, 5px);
}

.tabulator-menu .tabulator-menu-item:hover {
  background: var(--dc-panel-2);
}

/* ── Reused cell content classes (ported verbatim from library-page.css
   .ltable rules — same markup, now rendered inside a tabulator-cell) ──── */

/* Dense title cell (dcTitle formatter) — `font-weight: 500; color: ink`
   per the .ig-films-table spec; the only ink-weighted content in the row.
   (The old two-line .film-cell/.poster/.film-name/.film-sub block was
   removed with the 2026-07-21 dense migration — dcFilm renders it but no
   dc_table page uses dcFilm anymore; restore from git history if a
   tall-row view ever returns.) */
.dc-table-output .film-title {
  font-weight: 400;   /* operator 2026-07-21: 500 read too heavy */
  color: var(--dc-ink);
  overflow: hidden;
  text-overflow: ellipsis;
}

.dc-table-output .tags { display: inline-flex; gap: 4px; flex-wrap: wrap; }
.dc-table-output .tag {
  font-size: 10px;
  border: 1px solid var(--dc-line-2);
  border-radius: 4px;
  padding: 0 5px;
  color: var(--dc-muted);
  white-space: nowrap;
}

.dc-table-output .festcnt {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--dc-ink);
}
.dc-table-output .festcnt i { color: var(--dc-warn); }
.dc-table-output .festcnt.zero { color: var(--dc-faint); }
.dc-table-output .festcnt.zero i { color: var(--dc-faint); }

.dc-table-output .st {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 5px;
  font-size: 12px;
  white-space: nowrap;
}
.dc-table-output .st i { font-size: 15px; }
.dc-table-output .st--done { color: var(--dc-ok); }
.dc-table-output .st--pend { color: var(--dc-faint); }
.dc-table-output .st--warn { color: var(--dc-warn); }
.dc-table-output .st--live { color: var(--dc-ok); font-weight: 600; }
.dc-table-output .st--priv { color: var(--dc-muted); }
.dc-table-output .st__lbl { font-size: 11px; font-weight: 600; }
