/* Control sidebar (csb-)
 *
 * #control-sidebar     — conteneur principal (grid dans #page-header)
 * .csb-toggle           — bouton ‹/› latéral
 * .csb-body             — corps collapsible
 * .csb-inset            — pad/bordure uniforme autour de .csb-content (mesuré par
 *                         measureControlSidebar() pour --csb-h, pas .csb-content lui-même)
 * .csb-content          — flex column: toolbar + layout + footer, stacked, gap between them
 * .csb-toolbar          — full-width row above .csb-layout: collapse, share, confederation
 *                         dropdown, params badge — all four icon controls in one place
 * .csb-footer           — full-width row below .csb-layout, hosts #elo-meta
 * .csb-layout           — flex row: sort-stack + filter table, side by side (border.html's
 *                         "independent tables + flex" fix — three separate <table>s instead
 *                         of one table with cross-cutting rowspans, which is what caused the
 *                         double-border misalignment. See border.html / control-sidebar-test.html.)
 * .csb-sort-stack       — flex column: sort table + display table, stacked
 * .csb-table            — shared look (border-collapse) for all three tables. Base font-size!important
 *                         (11px) lives on #control-sidebar and most descendants just inherit
 *                         it — non-Bootstrap elements (global.css's .elo-name) still need their
 *                         own explicit re-declaration to fall in line; Bootstrap's own .btn/
 *                         .dropdown-menu no longer do, now that css/bootstrap-custom.scss's
 *                         $input-btn-font-size/$dropdown-font-size already match (11px)
 * .csb-header            — cellule d'en-tête (tri / sélection)
 * .csb-sort-col         — colonne tri (gauche)
 * .csb-sort-list        — flex column des options de tri
 * .csb-sort-item        — option de tri individuelle
 * .csb-sort-dir         — bouton ↑/↓ direction
 * .csb-display-toggle   — switch équipes/match (bas de la colonne tri)
 * .csb-col              — en-tête de colonne cliquable (exp / non-exp)
 * .csb-group            — en-tête de groupe de lignes (qualifié / non-qual.)
 *                         (le carrousel d'étapes Qualifiés → … → Vainqueur vit maintenant dans
 *                         <elo-ranking> — voir .elo-viz / .elo-stage-carousel dans global.css)
 * .csb-row              — sous-ligne de groupe
 * .csb-check            — label checkbox □/▣
 * .csb-collapse         — bouton › repli (dans .csb-toolbar)
 * .csb-share            — bouton de partage (copie une URL de config, dans .csb-toolbar)
 */

/* ── Container ─────────────────────────────────────────────────────────── */

/* .csb-panel — shared by #control-sidebar (this file) and #players-sidebar
   (css/wc2026_players.css, js/players_sidebar.js): both roots carry this class so the pieces
   that are genuinely identical between the two sidebars (font-size, background, .csb-content/
   .csb-inset/.csb-table basics, .csb-row, .csb-sort-item, .csb-sort-dir, .csb-header,
   --sort-extra-pad) live here exactly once instead of two id-scoped copies drifting apart.
   Stays a class (not merged onto the ids themselves) specifically so it can't silently
   outrank #control-sidebar's own more specific rules below (an id always wins over any number
   of classes — see .csb-body's own note) — anything below that needs id-level priority over a
   .csb-panel rule keeps its #control-sidebar/#players-sidebar prefix. */
.csb-panel {
  font-size: 11px;
  background-color: rgba(256,256,256,.667);
}

#control-sidebar {
  display: flex; flex-direction: row-reverse; align-items: flex-start;
  position: relative;
}

/* No second flex item to space out from once the body has collapsed to nothing —
   without this the gap would still reserve 0.5rem next to the now-invisible body. */
#control-sidebar.collapsed { gap: 0; }
#control-sidebar.collapsed .csb-body { max-width: 0; pointer-events: none;}

/* Always-open variant (countries page) — no toggle, transparent bg, natural height. Stays
   #control-sidebar-scoped rather than generalized to .csb-always-open: its specificity
   (id+class) has to beat #control-sidebar .csb-body's own (id+class) base rule below via
   source order, which a bare .csb-always-open (class+class) couldn't do regardless of order —
   an id always outranks any number of classes. #players-sidebar has no competing base .csb-body
   rule to out-rank, so its own equivalent (css/wc2026_players.css) can stay a plain, lower-
   specificity rule without needing this same guard. */
#control-sidebar.csb-always-open { margin-top: 0; }
#control-sidebar.csb-always-open .csb-body { background: transparent; height: auto; max-width: none; }

/* ── Toggle button ─────────────────────────────────────────────────────── */

#control-sidebar .csb-toggle {
  width: 16px; min-width: 16px; padding: 0;
  background: var(--bg-hover);
  /* Removing the border earlier exposed the browser's native <button> chrome
     (appearance:button's default outset border, themed per OS/browser — the "ugly
     border") since nothing was left to override it. border:none neutralizes that. */
  border: none; appearance: none;
  cursor: pointer; color: var(--text-muted);
  align-self: stretch;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  min-height: var(--csb-h, 8rem);
  user-select: none; -webkit-user-select: none;
}
#control-sidebar .csb-toggle:hover { background: var(--bg-hover); color: #333; }

/* Browser default focus ring (bright blue) was harmless back when these buttons had their
   own border to blend into — now that borders are gone (.csb-toggle, .csb-icon-btn,
   .csb-conf-btn), it stands out on its own. Replace with something in the sidebar's own
   muted palette, kept inset so it doesn't add layout width. .csb-panel-scoped, same reason
   as .csb-icon-btn above — #players-sidebar's Share button needs this too. */
.csb-panel button:focus-visible {
  outline: 1px solid var(--border-strong);
  outline-offset: -1px;
}

/* ── Body ──────────────────────────────────────────────────────────────── */

#control-sidebar .csb-body {
  max-width: var(--csb-w, 300px); height: var(--csb-h, 8rem);
  overflow: hidden;
  transition: max-width 0.5s ease;
  background: transparent;
}

/* Stacks the toolbar above .csb-layout. Block-level (not inline-flex like .csb-layout)
   so it stretches to the body's full measured width — see measureControlSidebar() in
   control_sidebar.js, which now reads this element's offsetHeight (toolbar + gap +
   .csb-layout) instead of .csb-layout's alone.
   padding-block: .25rem adds the "space above/below .csb-body" gap indirectly rather than
   via margin on .csb-body itself — .csb-body's own height (above) and .csb-toggle's
   min-height are both driven by --csb-h, which is exactly this element's measured
   offsetHeight, padding included. So the extra .5rem here automatically grows *both* boxes
   by the same amount, with .csb-content's real content sitting centered within it (equal
   padding top/bottom) — no separate height recalculation needed anywhere else. */
.csb-panel .csb-content {
  width: 100%;
  /* padding-block: .25rem; */
}

/* Sits between .csb-body and .csb-content — the single place for a uniform pad/border
   around the whole toolbar+layout+footer stack. measureControlSidebar() in
   control_sidebar.js reads *this* element's rendered box (not .csb-content's) for --csb-h,
   so it stays correct no matter what border/padding/margin ends up here.
   TODO: replace debug border with the real design. */
.csb-panel .csb-inset {
  /* border: 2px red solid; */
  padding: .25rem;
}

/* Houses .csb-collapse/#zoom-conf-dropdown/.csb-share/.csb-params-badge — see .csb-icon-btn
   and the confederation-dropdown rules further down for their own styling. Same background
   as .csb-table's cells, so it reads as one of the sidebar's top-level blocks rather than
   bare on .csb-body's background. */
.csb-toolbar {
  width: 100%;
  padding: 2px 6px;
  background: var(--bg-hover);
}

/* Hosts #elo-meta (source/date attribution) — .sub itself has no padding, so it comes
   from here instead, same recipe as .csb-toolbar (including its background/gap —
   no negative margin here anymore, so it now spaces from .csb-layout the same
   way .csb-toolbar does above it). */
.csb-footer {
  width: 100%;
  background: var(--bg-hover);
  padding: 0 6px;
  /* #elo-meta is empty at initSidebar()'s own measureControlSidebar() call — data hasn't
     loaded yet — so it contributes 0 height there. Reserving one line's worth up front
     means that first measurement already gets the right --csb-h, instead of a second,
     visible resize once the real text arrives and pushes .csb-toggle taller. */
  min-height: 22px;
  align-content: center;
}

/* #elo-meta-count (e.g. "66/236 Countries") left, #elo-meta-source (source
   link + update date) right — one line, never wraps. min-width:0 on the
   source span overrides flexbox's default min-width:auto (which otherwise
   blocks shrinking below content size) so text-overflow can actually engage
   once the row is too narrow for both; count doesn't shrink, so it's never
   the one that gets truncated. */
#elo-meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px;
  overflow-x: hidden;
  white-space: nowrap;
}
#elo-meta-count { flex-shrink: 0; }
#elo-meta-source {
  display: none;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── Table ─────────────────────────────────────────────────────────────── */

.csb-panel .csb-table {
  border-collapse: collapse; margin: 0;
  --sort-extra-pad: 26px;
}
.csb-panel .csb-table td { padding: 2px 6px; background: var(--bg-hover); text-align: right; }

/* Strip each table's outer perimeter, keep Bootstrap's .table-bordered grid lines between
   cells. With border-collapse, Bootstrap's top/bottom border-width lives on the <tr> and
   left/right on the <td> — the override has to land on that same box, since a collapsed
   border is resolved by comparing widths across all contributing boxes (widest wins), not
   by normal cascade specificity alone. */
.csb-panel .csb-table tr:first-child { border-top: 0; }
.csb-panel .csb-table tr:last-child  { border-bottom: 0; }
.csb-panel .csb-table tr > td:last-child { border-right: 0; }
/* .csb-sort-table is single-column on both sidebars, so every cell is the left edge — shared.
   The rest of the left-edge story diverges per sidebar (control 1's .csb-display-table/
   .csb-native-table/rowspan-colspan .csb-filter-table vs. control 2's simpler :first-child
   .csb-filter-table, see css/wc2026_players.css), so only this common piece lives here. */
.csb-panel .csb-sort-table td { border-left: 0; }
#control-sidebar .csb-display-table td,
#control-sidebar .csb-native-table td,
#control-sidebar .csb-filter-table td[rowspan],
#control-sidebar .csb-filter-table td[colspan] {
  border-left: 0;
}

#control-sidebar .elo-item { padding: 0 0.2rem; gap: 2px; border-radius: 0.375rem; }
/* global.css's .elo-name sets its own 12px, unscoped — needs beating back down to 11px here */
#control-sidebar .elo-name { font-size: 11px; }
#control-sidebar .csb-table .form-check-input { display: none; }

/* exp/non-exp column headers and import./non-imp. row headers: symbol-only (name text
   emptied in JS), full word still available via the cell's title tooltip. ".elo-item--exp"
   and ".elo-item--imp" reuse taxonomy.css's existing blue "▶" / red "◀" pill decorations;
   ".elo-item--nexp" / ".elo-item--nimp" are control-sidebar-only and mirror them with a
   hollow grey "▷" / "◁" — same shape, muted/outline reads as each one's negation. */
#control-sidebar .elo-item--nexp .elo-name::after {
  content: '▷'; color: var(--light-text, #999); font-size: 14px; margin-left: 2px;
}
#control-sidebar .elo-item--nimp .elo-name::after {
  content: '◁'; color: var(--light-text, #999); font-size: 14px; margin-left: 2px;
}
/* Fine-tuned centering nudge for the exp/non-exp column-header arrows specifically
   (empty .elo-name box the arrow hangs off of) — not needed on the qi/qni row arrows. */
#control-sidebar .csb-col .elo-name { margin: 0 -0.5px 0 1.5px; }
/* import./non-imp./non-FIFA rows: push the symbol pill to the right of its (wide)
   cell, next to the checkbox columns, instead of stranding it against the left edge. */
#control-sidebar .csb-table td[data-row="qi"],
#control-sidebar .csb-table td[data-row="qni"],
#control-sidebar .csb-table td[data-row="nqn"] {
  text-align: right;
}

/* Shared by any page whose header follows this pattern (currently wc2026_countries.html
   and wc2026_players.html): title + #sidebar-host sit side by side (flex,
   justify-content:space-between) until they don't fit, at which point #sidebar-host
   wraps onto its own line and — being the sole item there — sticks to the line's
   start rather than centering. The wrap point depends on content width (title
   text length varies by locale, sidebar table width varies by filter state), so
   it's detected in JS by comparing offsetTop rather than guessed via a media
   query breakpoint — see each page's own _syncHeaderLayout(). */
#countries-header.stacked #sidebar-host,
#players-header.stacked #sidebar-host {
  width: 100%;
  display: flex;
  justify-content: center;
}

#countries-header #sidebar-host { background-color: transparent; }

/* ── Badge (●/○) ───────────────────────────────────────────────────────── */

/* ── Column / group / row headers — colors from taxonomy.css ──────────── */

/* .csb-row itself is shared (.csb-panel below); .csb-col/.csb-group have no players-sidebar
   equivalent (no country-shaped filter matrix there) and stay control-1-only. */
#control-sidebar .csb-col,
#control-sidebar .csb-group { cursor: pointer; white-space: nowrap; }
.csb-panel .csb-row { cursor: pointer; white-space: nowrap; }
#control-sidebar .csb-group { text-align: center; vertical-align: middle; }
#control-sidebar .csb-col:hover,
#control-sidebar .csb-group:hover {
  background: var(--bg-hover); border-radius: 3px; color: var(--text-muted);
}
.csb-panel .csb-row:hover {
  background: var(--bg-hover); border-radius: 3px; color: var(--text-muted);
}

/* ── Sort column ───────────────────────────────────────────────────────── */

.csb-panel .csb-header { text-align: left !important; }
#control-sidebar .csb-header[data-col] { cursor: pointer; }
.csb-panel .csb-table td.csb-sort-col {
  padding: 0 var(--sort-extra-pad);
  vertical-align: top;
  width: 1px;
  height: 1px;
}
/* Its own single-row table now (see .csb-layout above) — no longer needs the
   --sort-extra-pad gutter reserved for .csb-sort-col's csb-sort-dir icon, or the
   position:absolute centering trick .csb-display-toggle used to need (see below):
   normal flow + text-align:center, with the shared .csb-table td padding for
   breathing room from the cell border. Control-1-only — players has no team/match toggle. */
#control-sidebar .csb-table td.csb-toggle-col { text-align: center; }
.csb-panel .csb-sort-item { cursor: pointer; padding: 0; }
/* #control-sidebar .csb-sort-item:first-of-type { text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 3px; }*/
/* Groups elo+pop visually (was a '}' glyph via .csb-sort-list::after) — a plain vertical
   line instead, centered in the --sort-extra-pad gutter rather than flush against the
   item's own edge. One element on .csb-sort-list itself (not per-item) so there's no seam:
   two independently-positioned 1px borders meeting at a flex-item boundary can show a
   hairline gap from sub-pixel rounding. height:50% assumes exactly 4 equal-flex-grow items
   with elo+pop as the first two — update if that count ever changes. Control-1-only: players'
   own 4-item list has no such elo/pop grouping to call out. */
#control-sidebar .csb-sort-list::after {
  content: '';
  position: absolute;
  top: 2px;
  height: calc(50% - 4px);
  right: calc(var(--sort-extra-pad) / -2);
  border-right: 1px solid #999;
}
.csb-panel .csb-sort-item:hover { background: var(--bg-hover); color: #555; }
/* Control-1-only — players' equivalent is .csb-sort-item--active (always clickable, never
   disabled; see css/wc2026_players.css's own comment for why the two controls' semantics
   diverge here). */
#control-sidebar .csb-sort-item--disabled { opacity: 0.3; pointer-events: none; }
.cbs-header-label {
  font-style: italic;
  color:#777;
}
/* ── Team/match display switch (bottom of the sort column) ───────────────
   Not a sort criterion (see control_sidebar.js's _displayMode) — a persistent two-state
   switch, always visible, that decides whether rows are one team each or grouped fixture
   couples. Bootstrap's btn-check pattern (hidden radio + label, see
   getbootstrap.com/docs/5.3/forms/checks-radios) — raw Bootstrap .btn-check/.btn look and
   behavior otherwise untouched; only margin/padding/font-size/color below, to match the
   rest of the sort column (.csb-sort-item) instead of Bootstrap's full-size default. */
/* No longer needs to be taken out of flow — that was only to stop its natural
   nowrap width from inflating a table column shared with the sort-list above,
   back when both lived in the same table (see .csb-layout: they're now two
   independent tables, stacked via flex, each free to size to its own content). */
#control-sidebar .csb-display-toggle { display: flex; align-items: center; justify-content: center; white-space: nowrap; }
/* font-size no longer needs a re-declaration here — css/bootstrap-custom.scss's own
   $input-btn-font-size already matches the rest of the sort column (11px) by default. margin/
   padding stay: horizontal-only padding and no margin is a deliberate layout choice, not a
   full-size-default patch. */
#control-sidebar .csb-display-toggle .btn { margin: 0; padding: 0 3px; }
/* #control-sidebar .csb-display-toggle .btn-check:checked + .btn {
  color: rgba(33, 37, 41, 0.75);
} */

/* ── Players-tab export/native/import filter (csb-native-table) ──────────
   Same bundled-on-one-line pattern as .csb-display-toggle above, 3 buttons instead of 2.
   Deliberately NOT reusing .elo-item/.elo-item--exp/.elo-item--imp here (unlike the countries
   filter table below, which is genuinely rendering country-pill-shaped cells) — taxonomy.css's
   .elo-item:not(.elo-item--qualified) rule unconditionally zeroes border (needed there, for
   plain map pills), which fought against Bootstrap's own .btn-check:checked+.btn border and
   made the pushed/not-pushed state inconsistent across the 3 buttons. Self-contained glyphs +
   border, no dependency on taxonomy.css's own rules. */
#control-sidebar .csb-native-toggle { white-space: nowrap; gap: 2px; }
#control-sidebar .csb-native-toggle .btn {
  margin: 0; padding: 0 4px; border: 1px solid transparent; font-size: 14px; line-height: 1;
  display: inline-flex; align-items: center; justify-content: center; min-height: 16px;
}
#control-sidebar .csb-native-toggle .btn-check:checked + .btn { border-color: rgba(23, 23, 21, 0.75); }
#control-sidebar .csb-pf-export::after { content: '▶'; color: var(--exp-accent); }
#control-sidebar .csb-pf-native::after { content: '●'; font-size: 10px; color: rgba(23, 23, 21, 0.75); }
#control-sidebar .csb-pf-import::after { content: '◀'; color: var(--imp-accent); }
/* .csb-kind-toggle: 2nd TD in the same row — same button chrome (shares .csb-native-toggle's
   own rules above), just plain letter glyphs instead of a shape, since "player" vs "coach" has
   no natural directional/dot symbol the way native/import/export does. */
#control-sidebar .csb-pf-player::after { content: 'P'; font-size: 11px; font-weight: 600; color: rgba(23, 23, 21, 0.75); }
#control-sidebar .csb-pf-coach::after { content: 'C'; font-size: 11px; font-weight: 600; color: rgba(23, 23, 21, 0.75); }

/* ── "filter players" / "filter countries" table headers ──────────────────
   The plain "filter" label reused for both tables gets a small disambiguating icon right after
   it — same icon players already use elsewhere (index.js's #tab-players-btn) for
   "players", a flag for "countries" (this table's cells are literally country-category pills).
   The row's own title tooltip still carries the full description. */
#control-sidebar .csb-header-icon { vertical-align: -2px; margin-left: 3px; opacity: 0.6; }

/* ── Sort direction button ─────────────────────────────────────────────── */

.csb-panel .csb-sort-dir {
  position: absolute; top: 1px; left: calc((18px - var(--sort-extra-pad)) / 2 - 18px); width: 18px; height: 18px;
  background: url('../images/sort-vertical-svgrepo-com.svg') no-repeat center / 18px 18px;
  border: none; padding: 0; cursor: pointer; opacity: 0.75;
}
.csb-panel .csb-sort-dir[data-dir="asc"] { background-image: url('../images/sort-vertical-asc.svg'); }
.csb-panel .csb-sort-dir:hover { opacity: 1; }

/* ── Icon button (shared recipe) ───────────────────────────────────────────
   18×18, own SVG (not Bootstrap's stock .btn-close, whose hardcoded black
   glyph didn't match this icon set's #1C274C navy stroke), opacity fades in
   on hover. Shared by .csb-collapse, .csb-share, .csb-params-badge below —
   each adds only what makes it different. .csb-panel-scoped (not
   #control-sidebar-only) since #players-sidebar's own Share button
   (js/players_sidebar.js) reuses this same .csb-icon-btn/.csb-share markup —
   without it, that button falls back to the browser's default <button> chrome. */
.csb-panel .csb-icon-btn {
  width: 18px; height: 18px; padding: 0;
  border: none; background: none;
  display: flex; align-items: center; justify-content: center;
  opacity: 0.75; cursor: pointer;
}
.csb-panel .csb-icon-btn:hover { opacity: 1; }
.csb-panel .csb-icon-btn img { width: 100%; height: 100%; }

/* .csb-collapse swaps the shared 18×18 square for an auto-width "ESC" kbd hint —
   overrides the fixed square from the shared recipe above. */
#control-sidebar .csb-collapse { width: auto; }
#control-sidebar .csb-esc-kbd {
  font: 9px/1 var(--bs-font-monospace, ui-monospace, monospace);
  letter-spacing: .03em;
  padding: 3px 4px 2px;
  border: 1px solid var(--border, #e4e0d8);
  border-radius: 3px;
  background: var(--bg-hover);
  /* Matches the icon set's own #1C274C navy stroke — .csb-icon-btn already applies a
     shared opacity:.75 on hover-fade, so this text needs the same base color weight
     as the SVGs to read the same, not var(--text-muted)'s lighter grey on top of it. */
  color: #1C274C;
}

/* ── Share button (copies a URL reproducing the current sidebar config) ──
   Normal flex item of .csb-toolbar — nothing to add beyond the shared recipe. */

/* ── URL params badge ──────────────────────────────────────────────────── */

/* Normal flex item of .csb-toolbar — round, and stays highlighted while its
   explanation panel is open. */
#control-sidebar .csb-params-badge {
  border-radius: 50%; user-select: none; -webkit-user-select: none;
}
#control-sidebar .csb-params-badge.active { opacity: 1; background: var(--bg-hover, rgba(0,0,0,0.08)); }

/* ── Checkbox ──────────────────────────────────────────────────────────── */

#control-sidebar .csb-check { cursor: pointer; color: var(--text-muted); }
#control-sidebar .csb-check::before { content: '□'; }
#control-sidebar .csb-check:has(input:checked)::before { content: '▣'; } /* ■ */

/* ── Clickable cells (cursor / hover) ──────────────────────────────────── */

.csb-table [data-col] { cursor: pointer; }
.csb-table [data-col]:hover { background-color: var(--bg-hover); }
.csb-table td:has(.csb-check) { vertical-align: middle; padding: 0; cursor: pointer; }
.csb-table td:has(.csb-check):hover { background-color: var(--bg-hover); }
.csb-check { display: flex; align-items: center; justify-content: center; height: 100%; cursor: pointer; }

/* ── Confederation dropdown ─────────────────────────────────────────────── */
/* .csb-conf-dropdown/.csb-conf-label are shared classes — #zoom-conf-dropdown/#zoom-conf-label
   (this file) and #players-conf-dropdown/#players-conf-label (css/wc2026_players.css) each
   keep their own id too, purely as JS query hooks / Bootstrap data-bs-target anchors; the ids
   were never what made these two pairs look identical, so styling now targets the class both
   elements actually share instead of duplicating the same declarations under two ids. */

/* Lives in .csb-toolbar now (flex item, normal flow) — the "nqf" row itself only
   shows the plain "FIFA" label; picking a confederation is a global zoom action,
   not scoped to that one filter row. */
.csb-conf-dropdown { display: inline-flex; z-index: 2000; }
.csb-conf-btn { cursor: pointer; background: none; border: none; padding: 0; display: flex; align-items: center; justify-content: center; opacity: 0.75; }
.csb-conf-btn:hover { opacity: 1; }

/* Plain Bootstrap radio look (unlike .csb-check's custom □/▣ glyphs elsewhere in the
   sidebar) — .form-check-input renders natively here, just laid out inline with its label. */
.csb-conf-dropdown .dropdown-item { display: flex; align-items: center; gap: 6px; cursor: pointer; }

/* Truncates instead of pushing whatever sits after it in .csb-toolbar out of shape on a long
   confederation name — min-width:0 overrides the flex-item default (min-width:auto, which
   blocks shrinking below content size and would otherwise make text-overflow a no-op here). */
.csb-conf-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; cursor: pointer; }

 