/* Specifika city-domény (obec: přehled hlasování, zastupitelé, strany,
   zasedání, hlasování) – sdílené tokeny, layout chrome (page-header,
   theme-toggle, back-link) a šířka stránky (.wrap/.masthead-inner
   max-width) jsou v app.css, linkovaném před tímto souborem. */
.wrap { padding: 24px clamp(16px, 4vw, 40px) 80px; }
h1 { font-size: 22px; margin: 0 0 12px; }
.subtitle { margin: 0 0 20px; }

/* Drobečková navigace (geo/show.blade.php) – vlastní styl, ne sdílené
   .subtitle a (to má jen stálé podtržení ve --border barvě, na řetěz víc
   odkazů za sebou to nestačilo, položky pořád splývaly do jednoho bloku
   textu, viz diskuze v hlavní konverzaci). Každá položka je teď vlastní
   "pilulka" s ohraničením/pozadím (stejný vizuální jazyk jako .dropdown-
   toggle), ne jen holý odkaz v textu – hranice mezi položkami je tak vidět
   i bez ohledu na barvu/podtržení, oddělovač (›) mezi pilulkami jen
   doplňuje, že jde o hierarchii, ne hlavní nositel odstupu. */
.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px;
  margin: 0 0 12px;
  font-size: 13px;
}
.breadcrumb a {
  display: inline-block;
  padding: 4px 10px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-1);
  color: var(--text-secondary);
  text-decoration: none;
}
.breadcrumb a:hover { border-color: var(--series-1); color: var(--text-primary); }
.breadcrumb-sep { color: var(--text-muted); font-size: 11px; }
.breadcrumb-mobile { display: none; }
@media (max-width: 640px) {
  .breadcrumb-desktop { display: none; }
  .breadcrumb-mobile { display: flex; position: relative; flex-wrap: nowrap; gap: 8px; }
  .breadcrumb-more { flex: none; }
  .breadcrumb-more summary {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    min-height: 44px;
    list-style: none;
    cursor: pointer;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--surface-1);
    color: var(--text-secondary);
    font-size: 20px;
  }
  .breadcrumb-more summary::-webkit-details-marker { display: none; }
  .breadcrumb-more[open] summary { border-color: var(--series-1); }
  .breadcrumb-mobile .breadcrumb-parent {
    display: flex;
    align-items: center;
    min-height: 44px;
    min-width: 0;
    overflow-wrap: anywhere;
  }
  .breadcrumb-ancestors {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 20;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--surface-1);
    box-shadow: 0 6px 16px rgba(0,0,0,.12);
  }
  .breadcrumb-ancestors a {
    display: flex;
    align-items: center;
    min-height: 44px;
    border: 0;
    border-radius: 6px;
    overflow-wrap: anywhere;
  }
}

/* Nadpis + přepínač úrovní (partials/geo-nav.blade.php) vedle sebe na
   hromadných geo.* stránkách (staty/kraje/okresy/orp/pou/obce/regiony) –
   .toggle-row nejde použít přímo, ta nemá space-between (je pro seskupení
   víc přepínačů vedle sebe, ne rozhození title/nav na opačné konce). Wrap
   na užší obrazovce, ať #geo-nav (7 položek) nepřeteče vodorovně. */
.geo-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin-bottom: 12px;
}
.geo-header-row h1 { margin-bottom: 0; }

.notice {
  border: 1px solid color-mix(in srgb, var(--status-warning) 40%, var(--border));
  background: color-mix(in srgb, var(--status-warning) 10%, var(--surface-1));
  border-radius: 10px;
  padding: 12px 16px;
  margin-bottom: 20px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--text-secondary);
}
.notice strong { color: var(--text-primary); }
.notice a { color: var(--text-primary); text-decoration: underline; text-decoration-color: var(--border); text-underline-offset: 2px; }
.notice a:hover { text-decoration-color: currentColor; }
/* Kartička "Zdroj dat" – zavřená je to jen summary řádek (nadpis + odkaz(y)
   na web), "Jak data vznikla" se rozbalí v .notice-body až kliknutím.
   Stejná šipka jako .meeting/.vote > summary jinde v appce (rotace jednoho
   glyphu, ne přepínání ▸/▾). */
.notice > summary {
  cursor: pointer;
  list-style: none;
  position: relative;
  padding-right: 22px;
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
.notice > summary::-webkit-details-marker { display: none; }
/* Šipka pevně v pravém horním rohu (u prvního řádku) – ne flex item s
   margin-left:auto, ten u víceřádkového summary (election/index) skončil
   na vlastním prázdném řádku. */
.notice > summary::after {
  content: '▸';
  position: absolute;
  right: 0;
  top: 0.25em;
  font-size: 10px;
  transition: transform .15s ease;
}
.notice[open] > summary::after { transform: rotate(90deg); }
.notice-body { margin-top: 10px; }
.notice .process-steps,
.notice-dialog .process-steps {
  margin: 8px 0 12px;
  padding-left: 20px;
}
.notice .process-steps li,
.notice-dialog .process-steps li { margin-bottom: 6px; }
.notice .process-steps li:last-child,
.notice-dialog .process-steps li:last-child { margin-bottom: 0; }
.notice-warning {
  margin: 12px 0 0;
  padding-top: 12px;
  border-top: 1px dashed color-mix(in srgb, var(--status-warning) 40%, var(--border));
}

/* Modální dialog „Jak data vznikla" (meeting/index.blade.php) – otevře štítek
   „Zpracováno AI" v .title-row-actions. Nativní <dialog> + showModal();
   `display: flex` jen ve [open], ať se zavřený nezobrazuje (autor přebíjí
   UA `dialog:not([open]){display:none}`). */
.app-dialog {
  width: min(760px, calc(100vw - 32px));
  max-height: calc(100dvh - 64px);
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-1);
  color: var(--text-secondary);
  font-size: 13px; line-height: 1.55;
  overflow: hidden;
}
.app-dialog[open] { display: flex; flex-direction: column; }
.app-dialog::backdrop { background: rgba(0, 0, 0, .45); }
/* Žlutý nádech shodný se štítkem „Zpracováno AI" (.title-action-ai). */
.app-dialog-ai {
  border-color: color-mix(in srgb, var(--status-warning) 40%, var(--border));
  background: color-mix(in srgb, var(--status-warning) 10%, var(--surface-1));
}
.app-dialog-ai .app-dialog-head {
  border-bottom-color: color-mix(in srgb, var(--status-warning) 40%, var(--border));
}
.app-dialog-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: 0; padding: 12px 16px;
  border-bottom: 1px solid var(--border);
}
.app-dialog-head h2 { margin: 0; font-size: 15px; color: var(--text-primary); }
.app-dialog-close {
  border: 0; background: none; cursor: pointer;
  font-size: 22px; line-height: 1; padding: 0 4px;
  color: var(--text-muted);
}
.app-dialog-close:hover { color: var(--text-primary); }
.app-dialog-body {
  flex: 1; min-height: 0; padding: 12px 16px 16px; overflow-y: auto;
  text-align: justify; hyphens: auto;
}

/* Řádek s nadpisem stránky + akcí vpravo (partials/download-card.blade.php) –
   využívá prázdné místo vedle krátkého h1 místo samostatného widthového
   pruhu pod ním. */
.title-row {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; flex-wrap: wrap;
  margin-bottom: 12px;
}
.title-row h1 { margin-bottom: 0; }
/* Znak vedle nadpisu na detailu geografického objektu (geo/show.blade.php)
   – vlastní flex wrapper, ať h1+znak zůstanou jeden flex item vůči
   .title-row-actions (justify-content: space-between výše). */
.title-row-name { display: flex; align-items: center; gap: 12px; min-width: 0; }
/* Přepínač stavu (partials/stav-toggle.blade.php) zarovnaný na spodní hranu
   h1, ne na svislý střed celého .title-heading (kicker + h1). Stejně
   přepínač grémia (partials/gremium-toggle.blade.php, meeting/index). */
.title-row-name #stav-toggle,
.title-row-name #gremium-toggle { align-self: flex-end; }
/* $label ("Kraj"/"Okres"/…) jako kicker nad h1, obojí vedle znaku – viz
   geo/show.blade.php. */
.title-heading { min-width: 0; }
.title-heading h1 { margin: 0; }
/* .subtitle (kód/obyvatelé/postavení, viz geo/show.blade.php) má jinde po
   appce spodní odsazení 20px (`.subtitle` výše) – uvnitř .title-heading
   je to poslední řádek, takže ta mezera jen zvětšovala výšku boxu bez
   viditelného obsahu a posouvala text mimo skutečný střed vůči znaku
   (.title-row-name's `align-items: center` centruje CELÝ box, ne jen
   viditelný text). */
.title-heading .subtitle { margin: 0; }
.title-kicker { color: var(--text-muted); font-size: 12.5px; text-transform: uppercase; letter-spacing: .03em; margin: 0 0 2px; }
/* Odkazy v kickeru na vote/show (grémium+období → seznam hlasování,
   „zasedání č. N" → detail zasedání) – tlumené, podtržení až na hover, ať
   kicker zůstane vizuálně klidný. Na geo/show kicker žádné <a> nemá. */
.title-kicker a { color: inherit; text-decoration: none; }
.title-kicker a:hover { color: var(--text-primary); text-decoration: underline; }
.title-kicker-sep { margin: 0 6px; opacity: .6; }

/* Mapka hranic na detailu geo objektu (geo/show.blade.php, Leaflet přes
   public/js/geo-map.js) – jeden ze tří pohledů přepínače Kartičky/
   Tabulka/Mapa u seznamu potomků (#child-map-view), ne samostatný blok.
   .geo-map-wrap je jen obal; vrstva potomků se řídí přepínačem úrovně
   (žádné vlastní checkboxy). */
.geo-map-wrap { margin: 0 0 4px; }
.geo-map {
  width: 100%;
  height: 480px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-1);
}
/* Marker na mapě obcí subjektu (subjekt/obce.blade.php, subjekt-obce-map.js) –
   puntík škálovaný metrikou, vždy s číslem uvnitř (velikost písma dolaďuje
   inline style v markerHtml() podle velikosti puntíku, viz jeho komentář). */
.som-marker { background: none; border: 0; }
.som-dot {
  display: flex; align-items: center; justify-content: center;
  box-sizing: border-box;
  border-radius: 50%;
  background: color-mix(in srgb, var(--series-1) 82%, transparent);
  border: 1.5px solid var(--series-1);
}
.som-dot span { font-weight: 700; line-height: 1; color: #fff; }
/* Dropdown „Zobrazit → Změna"/„Nové a zaniklé" (subjekt-obce-map.js,
   rebuildObecDelta()/rebuildObecZmena()/clusterIcon()) – puntík/shluk
   ukazuje SIGNOVANOU deltu místo aktuálního stavu, barva podle znaménka.
   is-neutral u jednotlivého puntíku nastává jen ve „Změna" (obec beze
   změny, delta přesně 0) – „Nové a zaniklé" jednotlivé puntíky s deltou 0
   vůbec nekreslí, tam je is-neutral jen na shluku s vyrovnaným ziskem/
   ztrátou. */
.som-dot.is-nova { background: color-mix(in srgb, var(--status-good) 82%, transparent); border-color: var(--status-good); }
.som-dot.is-zanikla { background: color-mix(in srgb, var(--status-critical) 82%, transparent); border-color: var(--status-critical); }
.som-dot.is-neutral { background: color-mix(in srgb, var(--status-muted) 82%, transparent); border-color: var(--status-muted); }
/* Donut prstenec kolem puntíku/bubliny shluku (subjekt-obce-map.js,
   withRing()) – vlastní/uskupení, viz jeho docblock nahoře souboru. Barva
   je `background` (plná, nebo `conic-gradient` mezi --series-1/--series-3)
   nastavená inline JS, tady jen tvar/vystředění vnitřního obsahu. */
.som-ring { display: flex; align-items: center; justify-content: center; border-radius: 50%; box-sizing: border-box; }
/* Popup markeru sdílí .geo-map-popup-* s geo-map.js (viz níže); jen ta
   metrika, podle které je zrovna škálovaná velikost puntíku, je vyzdvižená. */
.geo-map-popup-meta .is-active { color: var(--text-primary); font-weight: 600; }

/* Přebarvení výchozích bublin shlukování (MarkerCluster.Default.css, CDN,
   natvrdo žluto-zelená rgba paleta) na motiv appky – jinak by v tmavém
   režimu svítily stejně jako ve světlém. Sdílené oběma markercluster mapami
   (geo/show.blade.php, subjekt/obce.blade.php); velikostní stupně (small/
   medium/large) nechává Leaflet přiřazovat sám, jen měníme barvu. Sytost
   zvednutá (45 %/90 %, dřív 25 %/75 %) – při nižší sytosti bubliny vedle
   plných puntíků jednotlivých obcí (.som-dot, 82 % + plný okraj) po
   rozpadu shluku na poslední puntíky viditelně "vybledly". */
.marker-cluster-small, .marker-cluster-medium, .marker-cluster-large {
  background-color: color-mix(in srgb, var(--series-1) 45%, transparent);
}
.marker-cluster-small div, .marker-cluster-medium div, .marker-cluster-large div {
  background-color: color-mix(in srgb, var(--series-1) 90%, transparent);
  color: #fff;
}

/* Přebarvení výchozích ovládacích prvků Leafletu (leaflet.css, CDN, natvrdo
   bílá/černá paleta) na motiv appky – zoom +/- a atribuce vlevo dole by
   jinak v tmavém režimu svítily jako bílá záplata přes tmavé dlaždice.
   Sdílené VŠEMI Leaflet mapami v appce (geo-map.js, regiony-list.js,
   geo-uroven-list.js, obce-list.js, subjekt-obce-map.js) – tyhle třídy
   jsou z CDN, appka je nikde sama nevytváří. */
.leaflet-bar, .leaflet-bar a {
  background-color: var(--surface-1);
  border-color: var(--border);
  color: var(--text-primary);
}
.leaflet-bar a:hover, .leaflet-bar a:focus { background-color: var(--grid); }
.leaflet-bar a.leaflet-disabled { background-color: var(--surface-1); color: var(--text-muted); }
.leaflet-control-attribution {
  background: color-mix(in srgb, var(--surface-1) 85%, transparent);
  color: var(--text-muted);
}
.leaflet-control-attribution a { color: var(--text-secondary); }

/* Bod obce ve vrstvě "Obce" (L.divIcon, public/js/geo-map.js) – L.marker
   místo L.circleMarker, protože jen skutečné markery jde shlukovat přes
   Leaflet.markercluster (viz jeho komentář tamtéž). Shlukové bubliny mají
   vlastní výchozí vzhled z MarkerCluster.Default.css (CDN), beze změny. */
.geo-map-obec-marker {
  width: 10px;
  height: 10px;
  margin: 1px;
  border-radius: 50%;
  background: #3f6fb5;
  border: 1px solid #2f3f6f;
}
/* Bod regionu ve výsledcích hledání (L.divIcon, public/js/regiony-list.js,
   bodovaIkona()) – stejný princip jako .geo-map-obec-marker výše
   (L.marker přes divIcon kvůli Leaflet.markercluster), jen tady jde
   o libovolnou směs typů najednou, proto barvu nese vnitřní <span> inline
   stylem (typBarvy v JS), tahle třída jen řeší tvar/velikost/stín. */
.geo-map-region-marker span {
  display: block;
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  border-radius: 50%;
  border: 2px solid #fff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .4);
}
/* Popup na hover (bindHoverPopup(), public/js/geo-map.js) – bod obce i
   polygon okres/orp/pou (showChildLevel() tamtéž) sdílejí stejný tvar,
   staví ho buildGeoPopupHtml(). Leaflet dává obsahu vlastní
   .leaflet-popup-content wrapper, tady se jen stylizuje to, co do něj ta
   funkce vloží. closeButton: false (viz JS) – zavírání řeší
   najetí/opuštění myší nebo druhý klik, křížek by byl matoucí. Pozadí/stín
   wrapperu a hrot (.leaflet-popup-tip) mají vlastní natvrdo bílé barvy
   z leaflet.css (CDN, appka do něj nezasahuje) – vnitřní text už používá
   --text-primary/--text-muted (funguje samo), ale bez týhle přebíječky by
   zůstal na napevno bílém pozadí i v tmavém motivu. Zavírací křížek
   (regiony-list.js/geo-uroven-list.js/obce-list.js closeButton
   nevypínají, na rozdíl od geo-map.js výše) dostává stejné přebarvení. */
.geo-map-popup .leaflet-popup-content-wrapper {
  border-radius: 8px;
  background: var(--surface-1);
  color: var(--text-primary);
  box-shadow: 0 3px 14px rgba(0, 0, 0, .4);
}
.geo-map-popup .leaflet-popup-tip {
  background: var(--surface-1);
  box-shadow: none;
}
.geo-map-popup .leaflet-popup-close-button {
  color: var(--text-muted);
}
.geo-map-popup .leaflet-popup-close-button:hover {
  color: var(--text-primary);
}
.geo-map-popup-header { display: flex; align-items: center; gap: 8px; }
/* Menší než běžný .znak (36×41, city.css výše) – v popupu vedle jednořádkového
   jména, ne vedle celého h1 jako na detailu. */
.geo-map-popup-znak { width: 22px; height: 25px; }
.geo-map-popup-header-text { flex: 1 1 auto; min-width: 0; }
.geo-map-popup-name {
  display: block;
  font-weight: 600;
  color: var(--text-primary);
  text-decoration: none;
}
.geo-map-popup-name:hover { color: var(--series-1); }
.geo-map-popup-obyvatel { color: var(--text-muted); font-size: 12.5px; }
.geo-map-popup-meta { color: var(--text-muted); font-size: 12.5px; margin-top: 4px; }
/* Jen ikonka (proklik i přes jméno výše, viz JS) – vpravo v hlavičce,
   místo textového odkazu "Zobrazit detail". */
.geo-map-popup-link {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
}
.geo-map-popup-link:hover { color: var(--series-1); }
/* Checkbox shlukování bodů obcí (#geo-map-cluster-toggle) – v .toggle-row
   na detailu geo objektu (geo/show.blade.php), stejný řádek jako přepínač
   úrovně/pohledu a #card-sort-{lvl}. Vidět jen v pohledu Mapa a jen ve
   vrstvě "Obce" (updateClusterToggleVisibility() tamtéž přepíná `hidden`). */
.geo-map-cluster-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-secondary);
  cursor: pointer;
}
/* Dropdown „Podle" (subjekt/obce.blade.php) – přepíná mezi body obcí
   a choropleth agregací po POU/ORP/okresu/kraji (subjekt-obce-map.js). */
.obce-map-uroven { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--text-secondary); }
/* Menu nad mapou/tabulkou subjektu (Tabulka/Mapa + rezim + metrika +
   shlukování/úroveň) na jeden řádek – .toggle-row jinde v appce záměrně
   wrapuje (viz jeho base pravidlo), tady je ale řádek přehlednější, když
   nezalamuje. Nevejde-li se, řádek sám scrolluje vodorovně (ne celá
   stránka, viz CLAUDE.md). */
#obce-toggle-row { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 4px; }
#obce-toggle-row > * { flex: none; white-space: nowrap; }
/* Nápověda "Přibližte pomocí Ctrl/⌘ + kolečko myši" (public/js/geo-map.js)
   – zobrazí se přes celou mapu na chvíli, když uživatel zkusí zoomovat
   holým kolečkem (bez Ctrl/Cmd kolečko normálně scrolluje stránku dál,
   mapu nezoomuje). Uvnitř .geo-map (Leafletův kontejner má vlastní
   position: relative z leaflet.css), position: absolute se tak vztahuje
   rovnou k mapě bez potřeby vlastního wrapperu. */
.geo-map-scroll-hint {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 8px 20px;
  background: rgba(0, 0, 0, .4);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
  pointer-events: none;
  opacity: 0;
  transition: opacity .15s ease;
  z-index: 500;
  border-radius: 10px;
}
.geo-map-scroll-hint.visible { opacity: 1; }

.title-row-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; flex-wrap: wrap; }

.title-action {
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  border: 1px solid var(--border);
  background: var(--surface-1);
  color: var(--text-secondary);
  font: inherit;
  font-size: 13px;
  padding: 6px 14px;
  border-radius: 8px;
  text-decoration: none;
  white-space: nowrap;
}
/* <button class="title-action"> (např. „Zpracováno AI" na meeting/index) –
   reset UA vzhledu tlačítka, jinak stejné jako odkazová varianta. */
button.title-action { cursor: pointer; }
/* Štítek „Zpracováno AI" – žlutý nádech (jako dřívější .notice kartička),
   žlutý zůstává i na hover (ne modrý --series-1 jako ostatní štítky). */
.title-action-ai {
  border-color: color-mix(in srgb, var(--status-warning) 40%, var(--border));
  background: color-mix(in srgb, var(--status-warning) 10%, var(--surface-1));
}
.title-action-ai:hover {
  border-color: color-mix(in srgb, var(--status-warning) 70%, var(--border));
  color: var(--text-primary);
}
.title-action:hover { color: var(--text-primary); border-color: var(--series-1); }
.title-action .summary-card-icon { width: 15px; height: 15px; color: currentColor; opacity: .8; }
.title-action-label { color: var(--text-muted); font-weight: 600; }
@media (max-width: 640px) {
  .title-row-actions {
    flex: 1 1 100%;
    width: 100%;
    min-width: 0;
    max-width: 100%;
  }
  .title-row-actions .title-action {
    min-width: 0;
    max-width: 100%;
    flex-shrink: 1;
    white-space: normal;
    overflow-wrap: anywhere;
  }
}

.toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
  margin-bottom: 20px;
}
/* /hlasovani – řazení zasedání + „těsná první" na vlastním řádku toolbaru
   (flex-basis 100 %), pod hledáním/filtry, ať se ovládání nezalamuje
   náhodile. Accordion-only – app.js celý řádek schová s Tabulkou. */
.toolbar-sort-row {
  flex: 1 0 100%;
  display: flex; flex-wrap: wrap; align-items: center; gap: 12px;
}

/* Srovnání zastupitelů (member/compare.blade.php) – toolbar hned následuje
   tabulky mimo .wrap, takže tu nechceme .wrap's koncové 80px odsazení
   stránky (jen mezi h1 a filtrem víc místa, mezi filtrem a tabulkou skoro
   žádné). */
.compare-toolbar-wrap { padding-bottom: 24px; }
.compare-toolbar-wrap .toolbar { margin-top: 24px; margin-bottom: 0; }
#search {
  flex: 1 1 240px;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-1);
  color: var(--text-primary);
  font-size: 14px;
}
#search:focus { outline: 2px solid var(--status-good); outline-offset: -1px; }
.stats { color: var(--text-muted); font-size: 13px; white-space: nowrap; }
/* Ikonka "i" v kroužku vedle textu, který má title tooltip (viz
   partials/info-icon.blade.php) – signalizuje, že tam je vysvětlení. */
.info-icon { width: 12px; height: 12px; vertical-align: -1.5px; color: var(--text-muted); margin-left: 3px; flex: none; }

.legend-item { display: inline-flex; align-items: center; gap: 6px; }
.dot { width: 10px; height: 10px; border-radius: 3px; flex: none; }

/* Vysvětlení „Nejasné" u nedopočítaného hlasování – v rozbalené kartě
   (.vote > .vote-nejasne-note, public/js/app.js renderVote), dřív jako
   rozbalovací položka legendy na /hlasovani. Levé odsazení zarovnané
   s .deputies, žlutooranžový akcent jako .vote-flag. */
.vote-nejasne-note {
  margin: 0;
  padding: 8px 14px 10px 28px;
  font-size: 12.5px; line-height: 1.55;
  color: var(--text-secondary);
}
.vote-nejasne-note strong { color: var(--status-serious); }
.dot.a { background: var(--status-good); }
.dot.n { background: var(--status-critical); }
.dot.z { background: var(--status-warning); }
.dot.o { background: var(--status-muted); opacity: .5; }
.dot.x { background: var(--status-muted); }
.dot.u { background: var(--status-serious); }

/* Apportionment diagram (party/index.blade.php) – půlkruh puntíků, jeden
   na aktivního zastupitele, souřadnice/poloměr počítá CityStats::seatDiagram()
   + view (viz komentář tam). */
.seat-diagram-wrap { text-align: center; margin-bottom: 4px; }
.seat-diagram { width: 100%; max-width: 520px; height: auto; }
.seat-diagram circle { fill: var(--series-1); stroke: var(--surface-1); stroke-width: 1; transition: opacity .15s ease; }
.seat-diagram circle.seat-dot-none { fill: var(--grid); }
.seat-diagram-total { color: var(--text-muted); font-size: 13px; margin: 4px 0 24px; text-align: center; }

/* Detail hlasování (vote/show.blade.php) – štítek výsledku (Schváleno/
   Zamítnuto) vedle nadpisu, srovnaný na účaří h1; na úzké obrazovce se
   zalomí pod něj. Souhrnné karty (Pro/Proti/Zdržel se) zrušeny – čísla
   jsou v legendě pod diagramem. */
.vote-title { display: flex; align-items: baseline; flex-wrap: wrap; gap: 6px 14px; margin: 0 0 12px; }
.vote-title h1 { margin: 0; }
.vote-title .vote-result { flex: none; }
/* Uvnitř .title-heading (vote/show) nese spodní mezeru .title-row, takže
   .vote-title tady 0 – subtitle pak sedí těsně pod nadpisem jako na
   person/show (kde .title-heading h1 i .subtitle mají margin 0). */
.title-heading .vote-title { margin-bottom: 0; }
/* Předchozí / následující hlasování zasedání – kompaktně v subtitle
   (vote/show), předmět jen v title. „← č. N" / „č. N →" nesmí zalomit. */
.vote-pager-link { white-space: nowrap; }

/* Grafické znázornění hlasů na detailu hlasování – segmentovaný pruh
   výsledku + puntíkový diagram (fill podle typu hlasu, .seat-diagram
   geometrie sdílená s party/index). Jeden fokální graf, ne opakovaný prvek
   seznamu → plná --status-* sytost je tu v pořádku. */
/* „Pruh" jako pohled přepínače – přes celou šířku obsahu (na rozdíl od
   půlkruhu/řady, které mají max-width). */
.vote-result-bar { margin: 8px 0; }
.vote-result-bar .bar { height: 12px; border-radius: 6px; }
.vote-diagram { max-width: 460px; }
.seat-diagram circle.vote-dot.a { fill: var(--status-good); }
.seat-diagram circle.vote-dot.n { fill: var(--status-critical); }
.seat-diagram circle.vote-dot.z { fill: var(--status-warning); }
/* „Omluven" vybledlá barvou (ne opacity) – ať do zvýrazňovacího efektu
   níže nezasahuje vlastní opacity. */
.seat-diagram circle.vote-dot.o { fill: color-mix(in srgb, var(--status-muted) 50%, var(--surface-1)); }
.seat-diagram circle.vote-dot.x { fill: var(--status-muted); }
.seat-diagram circle.vote-dot.u { fill: var(--status-serious); }
/* Každý puntík je odkaz na detail osoby (person.show). Mimo tab pořadí
   (tabindex=-1) – klávesnicově se na osoby chodí seznamem níž; puntík je jen
   vizuální zkratka pro myš/dotyk. Bez href (osoba není v rosteru) = jen tvar. */
.vote-dot-link { cursor: pointer; }
.vote-dot-link:not([href]) { cursor: default; }
.vote-dot-link:focus { outline: none; }
.vote-diagram-legend {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 16px;
  margin: 2px 0 24px; font-size: 13px; color: var(--text-secondary);
}
.vote-diagram-legend b { color: var(--text-primary); }
.vote-diagram-legend .legend-item { cursor: default; }
/* Legenda je tabindexovaná (zvýraznění jde klávesnicí i dotykem, ne jen
   hoverem) – viditelný fokus, stejný jako .person-*-legend .lg jinde. */
.vote-graphic .legend-item:focus-visible {
  outline: 2px solid var(--series-1); outline-offset: 2px; border-radius: 3px;
}

/* „Rozlišit strany" (checkbox → .show-parties) – barevný lem rozdělený po
   stranách: proužek pod Pruhem (.vote-party-strip) a segmenty v SVG pod
   Řadou / za Půlkruhem (.vote-party-rim). Výchozí skryté; fill puntíků
   (= hlas) se nemění. Strana bez barvy → neutrální --grid segment. */
.vote-party-strip { display: none; }
.vote-graphic.show-parties .vote-party-strip {
  display: flex; height: 4px; border-radius: 2px; overflow: hidden;
  gap: 1px; margin-top: 5px;
}
.vote-party-rim { display: none; }
.vote-graphic.show-parties .vote-party-rim { display: inline; }
/* Druhá legenda (dekóduje barvy lemu) – jen v režimu .show-parties. */
.vote-party-legend { display: none; }
.vote-graphic.show-parties .vote-party-legend {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 14px;
  margin: -14px 0 24px; font-size: 12px; color: var(--text-muted);
}
.vote-party-legend b { color: var(--text-secondary); }

/* Hover na prvek s [data-hlas] (segment pruhu / puntík / položka legendy /
   řádek zastupitele) – JS nastaví [data-hl] na .vote-graphic; vše s jiným
   hlasem se ztlumí, stejný hlas zůstává svítit napříč všemi podáními
   i seznamem. Dim i un-dim mají stejnou specificitu → un-dim vyhrává
   pořadím v souboru (musí být níž). Žádný z cílů nemá vlastní opacity. */
.vote-graphic [data-hlas] { transition: opacity .12s ease; }
.vote-graphic[data-hl] [data-hlas] { opacity: .2; }
.vote-graphic[data-hl="a"] [data-hlas="a"],
.vote-graphic[data-hl="n"] [data-hlas="n"],
.vote-graphic[data-hl="z"] [data-hlas="z"],
.vote-graphic[data-hl="o"] [data-hlas="o"],
.vote-graphic[data-hl="x"] [data-hlas="x"],
.vote-graphic[data-hl="u"] [data-hlas="u"] { opacity: 1; }
/* Totéž podle politické strany – hover na položku druhé legendy
   (.vote-party-legend), na segment lemu (.vote-party-rim) nebo proužku
   (.vote-party-strip): JS nastaví [data-strana-hl] na .vote-graphic a značku
   .strana-hl na shodné prvky (puntíky / segmenty / řádky zastupitelů té
   strany), vše ostatní s [data-strana] se ztlumí. Hodnota strany (strana_kod)
   není výčtová jako typ hlasu → shodu musí značkovat JS, ne CSS selektor.
   Jen v režimu .show-parties (jinde druhá legenda ani lem nejsou). */
.vote-graphic.show-parties [data-strana] { transition: opacity .12s ease; }
.vote-graphic.show-parties[data-strana-hl] [data-strana] { opacity: .2; }
.vote-graphic.show-parties[data-strana-hl] [data-strana].strana-hl { opacity: 1; }
.vote-party-legend .legend-item { cursor: default; }
/* Varianta "Pruh" apportionment diagramu (výchozí, viz public/js/party.js) –
   stejný segmentovaný .bar jako docházka, ale tenký a dlouhý, přes CELOU
   šířku obsahu (zarovnaný s tabulkou pod ním). `.bar.seat-bar` (ne jen
   `.seat-bar`) kvůli specificitě – `.bar`'s height je definovaná níž
   v souboru a se stejnou specificitou by v cascade vyhrála ta pozdější. */
.bar.seat-bar { height: 14px; max-width: none; margin: 0; }
.seat-bar span { opacity: .9; transition: opacity .15s ease; }
/* Hover provázání diagram ↔ tabulka subjektů (public/js/party.js) – najetí
   na puntík/segment NEBO na řádek tabulky zvýrazní tu stranu v obojím,
   ostatní ztlumí. Párování přes `data-party`. */
.seat-diagram circle.seat-dimmed { opacity: .15; }
.seat-bar span.seat-dimmed { opacity: .15; }
#parties-table tbody tr { transition: opacity .12s ease; }
/* Zvolené / nezvolené listiny ve „stavu k datu voleb" (viz
   party/index.blade.php) se rozlišují stejně jako v tabulkách kandidátů
   (partials/election-list-section): sloupec „Výsledek" s .vote-result
   pillem („Zvolena"/„Nezvolena") + název subjektu netučně u nezvolených +
   jemný zelený podklad u zvolených – identický selektor i odstín jako
   .election-list tabulky níže (`tr[data-vysledek="0"]`, --status-good 5 %).
   Žádné ztlumení celého řádku. */
#parties-table tbody tr[data-vysledek="0"] { background: color-mix(in srgb, var(--status-good) 5%, transparent); }
#parties-table.has-hl tbody tr:not(.row-hl) { opacity: .3; }
#parties-table tbody tr.row-hl { background: var(--grid); opacity: 1; }

.meeting {
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--surface-1);
  margin-bottom: 12px;
  overflow: hidden;
}
.meeting > summary {
  position: relative;
  cursor: pointer;
  list-style: none;
  padding: 14px 18px 14px 34px;
  display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap;
}
.meeting > summary::-webkit-details-marker { display: none; }
.meeting > summary::before {
  content: "▸";
  position: absolute; left: 18px; top: 50%;
  color: var(--text-muted); font-size: 12px;
  transform: translateY(-50%);
  transition: transform .15s ease;
}
.meeting[open] > summary::before { transform: translateY(-50%) rotate(90deg); }
.meeting-title { font-weight: 600; font-size: 15px; color: inherit; text-decoration: none; }
.meeting-title:hover { text-decoration: underline; }
.meeting-date { color: var(--text-secondary); font-size: 13px; }
.meeting-link { color: var(--text-muted); font-size: 12px; text-decoration: none; border-bottom: 1px dotted var(--text-muted); }
.meeting-link:hover { color: var(--text-primary); }
/* Jeden proužek v hlavičce zasedání (viz renderMeetingBar() v app.js) –
   spojuje dřívější „výsledkový" (.meeting-result-bar) a „objemový"
   (.meeting-volume-bar) pruh: DÉLKA vyplněné části = počet hlasování vůči
   nejrušnějšímu zasedání, SEGMENTY uvnitř = schváleno / zamítnuto. Faint
   kolej (.stat-row-track, --grid) drží 100 % šířky → délky jdou porovnat.
   Odsycená červená místo plné --status-critical + nižší opacita, ať dlouhý
   seznam nepůsobí agresivně. margin-left: auto přitáhne k pravému okraji. */
.meeting-diagrams { display: inline-flex; align-items: center; gap: 8px; margin-left: auto; }
.meeting-diagram { display: inline-flex; align-items: center; gap: 8px; }
.meeting-diagram-value {
  font-size: 12px;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
/* Zlomek schváleno:zamítnuto – sekundární k počtu, proto tlumeně a menší.
   Jen samotné číslo zamítnutých (b > 0, .meeting-diagram-rej z app.js) je
   tučně červené – to je, co lidi zajímá víc. */
.meeting-diagram-split {
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.meeting-diagram-rej { color: var(--status-critical); font-weight: 700; }
.meeting-bar { display: inline-flex; align-items: center; }
/* O něco vyšší než per-hlasování proužek (.vote > summary .bar, 6px), ať je
   proužek zasedání vizuálně odlišený. */
.meeting-bar .stat-row-track { width: 150px; height: 9px; flex: none; }
.meeting-bar-fill { display: flex; height: 100%; border-radius: 4px; overflow: hidden; opacity: .72; }
.meeting-bar-fill .approved { background: var(--status-good); }
/* „Zamítnuto" je to, co lidi zajímá víc – o něco sytější červená než
   „schváleno", ale pořád ne plná alarmová --status-critical. */
.meeting-bar-fill .rejected { background: color-mix(in srgb, var(--status-critical) 78%, var(--surface-1)); }
/* Vlaječka „N× proti většině" v hlavičce karty zasedání na party/show
   (public/js/party-votes.js) – jen na zasedáních, kde se subjekt většinově
   postavil proti výsledku. Jinde nic → prázdná hlavička = klid. */
.meeting-diff-flag {
  font-size: 12px; font-weight: 600; white-space: nowrap;
  color: var(--status-critical); font-variant-numeric: tabular-nums;
}
/* „proti straně" (person/show) – žlutá, méně alarmující než „proti většině". */
.meeting-diff-flag.warn { color: var(--status-warning); }
/* Dvě vlaječky vedle sebe v accordionu person/party show – těsněji. */
#meetings .meeting-diagrams { gap: 10px; }

.votes-plain { border: 1px solid var(--border); border-radius: 12px; background: var(--surface-1); overflow: hidden; margin-bottom: 24px; }
.vote-row {
  display: grid;
  grid-template-columns: minmax(32px, auto) 1fr auto 140px;
  align-items: center;
  gap: 8px 12px;
  padding: 10px 18px;
  border-bottom: 1px solid var(--grid);
  text-decoration: none;
  color: inherit;
}
.vote-row:last-child { border-bottom: none; }
.vote-row:hover { background: var(--grid); }

.votes { border-top: 1px solid var(--grid); }
/* person/show: .votes uvnitř karty zasedání nese ploché .vote-history-row
   (ne .vote účastnický accordion jako /hlasovani) – odsadit od kraje karty. */
#meetings .votes { padding: 2px 16px 8px; }
#meetings .votes > .empty { padding: 16px 0; }
.vote { border-bottom: 1px solid var(--grid); }
.vote:last-child { border-bottom: none; }
.vote > summary {
  position: relative;
  cursor: pointer;
  list-style: none;
  padding: 10px 18px 10px 34px;
  display: grid;
  grid-template-columns: minmax(32px, auto) 1fr auto 140px;
  align-items: center;
  gap: 8px 12px;
}
.vote > summary::-webkit-details-marker { display: none; }
.vote > summary::before {
  content: "▸";
  position: absolute; left: 18px; top: 50%;
  color: var(--text-muted); font-size: 11px;
  transform: translateY(-50%);
  transition: transform .15s ease;
}
.vote[open] > summary::before { transform: translateY(-50%) rotate(90deg); }
.vote-cislo { color: var(--text-muted); font-variant-numeric: tabular-nums; font-size: 13px; white-space: nowrap; }
/* justify-self: start – .vote-predmet je teď <a> (viz renderVote() v app.js)
   a jako přímé dítě grid kontejneru (.vote > summary) by se jinak podle
   výchozího stretch chování grid itemů roztáhl přes celou šířku své buňky
   (sloupec 1fr), takže by byl proklikatelný i v prázdném místě za textem,
   ne jen na samotném textu. */
.vote-predmet {
  font-size: 14px;
  color: inherit;
  text-decoration: none;
  justify-self: start;
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.vote-predmet:hover { text-decoration: underline; }
/* Odkazy v tabulkovém zobrazení (#votes-table, viz renderVoteRow() v
   app.js) – stejné barevné/hover chování jako .vote-predmet výše. */
/* Přebíjí obecné .data-table td a { font-weight: 600 } (jinde v appce
   zvýrazňuje jméno/hlavní odkaz řádku) – tady je odkazem celý sloupec
   Zasedání/Předmět, tučné by bylo příliš výrazné pro celý text buňky. */
#votes-table td a { color: inherit; text-decoration: none; font-weight: normal; }
#votes-table td a:hover { text-decoration: underline; }
.vote-result {
  font-size: 12px; font-weight: 600; padding: 2px 8px; border-radius: 999px;
  white-space: nowrap;
}
.vote-result.approved { color: var(--status-good); background: color-mix(in srgb, var(--status-good) 14%, transparent); }
.vote-result.rejected { color: var(--status-critical); background: color-mix(in srgb, var(--status-critical) 14%, transparent); }
/* Stavy kandidatury na /volby (election/index) – náhradník žlutě „v záloze",
   nezvolen neutrálně. Zvolen(a) sdílí .approved. */
.vote-result.substitute { color: var(--status-warning); background: color-mix(in srgb, var(--status-warning) 16%, transparent); }
.vote-result.none { color: var(--text-muted); background: color-mix(in srgb, var(--text-muted) 14%, transparent); }
.vote-flag { color: var(--status-serious); font-size: 12px; margin-left: 6px; }

.bar { display: flex; height: 8px; border-radius: 4px; overflow: hidden; gap: 2px; background: var(--grid); }
.bar span { display: block; height: 100%; }
.bar .a { background: var(--status-good); }
.bar .n { background: var(--status-critical); }
.bar .z { background: var(--status-warning); }
.bar .o { background: var(--status-muted); opacity: .5; }
.bar .x { background: var(--status-muted); }
.bar .u { background: var(--status-serious); }
/* Per-hlasování proužek A/N/Z v hlavičce řádku na /hlasovani (renderBar()
   v app.js) – jemnější než výchozí .bar výše (tu sdílí docházka, historie
   na party/person show, karta na geo/show): tenčí, nižší opacita segmentů
   a odsycená červená „Proti", ať rozbalený seznam hlasování nebije do očí.
   Sladěné s proužkem v hlavičce zasedání (.meeting-bar-fill). */
.vote > summary .bar { height: 6px; }
.vote > summary .bar span { opacity: .72; }
.vote > summary .bar .n { background: color-mix(in srgb, var(--status-critical) 78%, var(--surface-1)); }
/* Schváleno/zamítnuto – stejné barvy jako .vote-result.approved/.rejected.
   Používá karta „Hlasování" na landing page obce (geo/show.blade.php).
   Proužek v hlavičce zasedání na /hlasovani má vlastní odsycenou variantu
   (.meeting-bar-fill .rejected), viz výše. */
.bar .approved { background: var(--status-good); }
.bar .rejected { background: var(--status-critical); }
/* Muži/ženy (karta Zastupitelů na landing page obce, viz geo/show.blade.php)
   – bez status sémantiky (není dobře/špatně), proto neutrální dvojice
   --series-1/--series-2 (app.css), ne status-* barvy jako segmenty výše. */
.bar .m { background: var(--series-1); }
.bar .f { background: var(--series-2); }

.stats-block-note {
  font-size: 12px;
  color: var(--text-muted);
  margin: 0 0 10px;
  line-height: 1.4;
}
/* Poznámka jako inline pokračování nadpisu nebo obsahu buňky – bez spodního
   odsazení, normální váha (samostatný .stats-block-note je odstavec). */
.stats-block-note.inline { display: inline; margin: 0; font-weight: 400; }

/* .stat-row-track/.fill – sdílené napříč appkou (.jednotnost-cell /
   .vote-share-cell v tabulce subjektů na party/index.blade.php,
   .meeting-volume-bar na meeting/index.blade.php, .entity-hlasy na
   member/index-fallback). */
.stat-row-track {
  flex: 1;
  height: 10px;
  background: var(--grid);
  border-radius: 4px;
  overflow: hidden;
}
.stat-row-track .fill { display: block; height: 100%; border-radius: 4px; }

/* Progress bar pro „dohraj všechna zasedání" (meeting/index.blade.php,
   ensureAllLoaded() v app.js) – track/fill jako výše, jen s popiskem vedle. */
.load-progress {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 12px 0;
  font-size: .9em;
  color: var(--muted, #666);
}
.load-progress .stat-row-track { max-width: 240px; }
.load-progress .fill { background: var(--series-1); transition: width .2s ease; }
/* Server-side hledání (runSearch()) – neurčitý „sweep", šířka fill se
   neřídí procenty. */
.load-progress.searching .fill {
  width: 40% !important;
  transition: none;
  animation: load-progress-sweep 1.1s ease-in-out infinite;
}
@keyframes load-progress-sweep {
  0%   { margin-left: -40%; }
  100% { margin-left: 100%; }
}

/* Sentinel pro infinite scroll v Tabulce hlasování (meeting/index.blade.php,
   loadTableBatch() v app.js) – musí mít výšku, ať ho IntersectionObserver
   chytí; text „Načítám další…" se plní z JS. */
.table-sentinel,
.votes-sentinel {
  min-height: 32px;
  padding: 8px 0;
  text-align: center;
  font-size: .9em;
  color: var(--muted, #666);
}

.deputies {
  padding: 4px 18px 16px 34px;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 4px 16px;
}
.deputy {
  display: flex; align-items: center; gap: 8px;
  font-size: 13px;
  padding: 4px 0;
  height: 30px;
  border-bottom: 1px solid var(--grid);
  min-width: 0;
}
.deputy-name {
  color: var(--text-primary);
  text-decoration: none;
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.deputy-name:hover { text-decoration: underline; }
.deputy-party {
  color: var(--text-muted); font-size: 11px;
  text-decoration: none;
  flex: 0 1 auto;
  max-width: 45%;
  min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.deputy-party:hover { text-decoration: underline; }
/* Štítky hlasů (Pro/Proti/…) – stejné „barevný text na jemném podkladu"
   podání jako štítky Schváleno/Zamítnuto (.vote-result), ne plná výplň
   s bílým textem. Ať sloupec štítků u rozbaleného hlasování / v historii /
   ve srovnání nebije do očí a obojí působí jako jedna sada. */
.tag {
  flex: none;
  font-size: 11px; font-weight: 600;
  padding: 1px 7px; border-radius: 999px;
}
.tag.a { color: var(--status-good);     background: color-mix(in srgb, var(--status-good) 14%, transparent); }
.tag.n { color: var(--status-critical); background: color-mix(in srgb, var(--status-critical) 14%, transparent); }
/* Žlutá/oranžová jako text mají slabý kontrast → ztmavit směrem k textové
   barvě (drží se v obou motivech), podklad zůstává v barevné rodině. */
.tag.z { color: color-mix(in srgb, var(--status-warning) 68%, var(--text-primary));  background: color-mix(in srgb, var(--status-warning) 18%, transparent); }
.tag.o { color: var(--text-muted);      background: color-mix(in srgb, var(--text-muted) 14%, transparent); }
.tag.x { color: var(--text-muted);      background: color-mix(in srgb, var(--text-muted) 14%, transparent); }
.tag.u { color: color-mix(in srgb, var(--status-serious) 80%, var(--text-primary));  background: color-mix(in srgb, var(--status-serious) 16%, transparent); }

.empty { color: var(--text-muted); padding: 40px 0; text-align: center; }
.hidden { display: none !important; }

.entity-list { list-style: none; margin: 0 0 24px; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.entity-list > li { position: relative; }
.entity-link {
  position: relative;
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 16px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-1);
  color: var(--text-primary);
  text-decoration: none;
  transition: border-color .15s ease;
}
.entity-link:hover { border-color: var(--series-1); }
.entity-main { display: flex; align-items: center; gap: 10px; min-width: 0; }
/* Jméno je vždy na dvou řádcích – křestní jméno nahoře, příjmení dole
   (samostatné blokové prvky, ne zalamovaný text), takže výška karty je
   konzistentní bez ohledu na délku jména. */
/* Bázový styl platí i pro entity-name s prostým textem uvnitř (např. název
   strany na party/index.blade.php, kde koncept jméno/příjmení nedává
   smysl) – .entity-firstname/.entity-lastname (osoby) mají svůj vlastní
   font-size a ořez, který tohle přebije. */
.entity-name {
  display: flex;
  flex-direction: column;
  font-weight: 600;
  font-size: 14.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}
.entity-firstname, .entity-lastname {
  font-size: 14.5px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.entity-meta { color: var(--text-muted); font-size: 12.5px; white-space: nowrap; flex: none; }
/* Jednotlivé hodnoty (počet členů, aktivních, jednotnost) jsou samostatné
   .entity-stat, ne jeden plynoucí text – odřádkování v kartě pak vždy
   proběhne mezi celými hodnotami, nikdy uprostřed čísla/procenta. */
.entity-stat { white-space: nowrap; }
.entity-stat + .entity-stat::before { content: '·'; margin: 0 5px; opacity: .55; }
/* Počet aktivních má větší váhu než celkový počet členů – barevně/řezem
   vystupuje z okolního muted textu .entity-meta. */
.entity-stat-primary { color: var(--text-primary); font-weight: 600; }
/* Chybí předpočítaný strany.json → "—" místo počtu členů, ztlumené jako
   prázdná jednotnost (.jednotnost-cell-empty). */
.entity-stat-empty { opacity: .5; font-weight: 400; }
/* Geo/subjektové dlaždice (.entity-list-center): meta jsou textové hodnoty
   (kraj, postavení obce, …), které se musí vejít i do úzké dlaždice –
   povolit zalomení MEZI .entity-stat (uvnitř hodnoty zůstává nowrap). Bez
   toho přetéká dlouhé postavení u Brna. Platí i pod 640px, kde bázové
   .entity-meta jinak drží nowrap. */
.entity-list-center .entity-meta {
  white-space: normal;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  row-gap: 2px;
  min-width: 0;
  /* Pod 640px je .entity-link řádek (znak+jméno | meta | šipka) – meta se
     smí zúžit a zalomit, ať nepřeteče (bázové .entity-meta má flex: none). */
  flex: 0 1 auto;
}
/* Počet obyvatel = hlavní údaj → vlastní řádek, zbytek se zalomí pod něj
   (návrh z konverzace). Odrážku „·" před prvním navazujícím štítkem pak
   potlačit, ať nezačíná řádek tečkou. */
.entity-list-center .entity-meta .entity-stat-primary { flex-basis: 100%; }
.entity-list-center .entity-meta .entity-stat-primary + .entity-stat::before { content: none; }
/* Sloupec „Aktivních" v tabulce stran – stejný důraz jako .entity-stat-primary
   v kartičkách. */
.data-table td.col-aktivni { font-weight: 600; color: var(--text-primary); }
/* Sloupec „Jednotnost" v tabulce subjektů (party/index) – track/fill bar
   vedle procenta, přenesený ze zrušené kartičky (dřív .entity-jednotnost).
   Sdílené .stat-row-track/.fill jako .meeting-volume-bar na meeting/index.
   Prázdný track bez fill + ztlumené „—" = nedostatek dat (< 2 hlasující),
   ne jednotnost 0 %. */
.jednotnost-cell { display: inline-flex; align-items: center; gap: 8px; }
.jednotnost-cell .stat-row-track { width: 96px; height: 8px; flex: none; }
.jednotnost-cell-value { font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--text-secondary); }
.jednotnost-cell-empty { opacity: .5; }
/* Sloupec „Podíl hlasů" ve „stavu k datu voleb" (party/index) – stejný
   track/fill vzor jako .jednotnost-cell, ale barva --series-2, ať se
   odliší od plného % ve sloupci „Podíl mandátů" hned vedle. */
.vote-share-cell { display: inline-flex; align-items: center; gap: 8px; }
.vote-share-cell .stat-row-track { width: 96px; height: 8px; flex: none; }
.vote-share-value { font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--text-secondary); }
.vote-share-empty { opacity: .5; }
/* Sloupec „Proti většině" v tabulce subjektů (party/index, „aktuální stav") –
   stejný track/fill vzor jako .jednotnost-cell, barva --status-critical
   jako zvýrazněná hlasování „proti výsledku" v detailu. Prázdný track +
   ztlumené „—" = chybí předpočítaný strany.json. */
.proti-vetsine-cell { display: inline-flex; align-items: center; gap: 8px; }
.proti-vetsine-cell .stat-row-track { width: 96px; height: 8px; flex: none; }
.proti-vetsine-cell-value { font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--text-secondary); }
.proti-vetsine-cell-empty { opacity: .5; }
/* Docházka jako segmentovaný diagram – stejné barvy/třídy (.bar .a/.n/.z/.o/.x)
   jako v panelu Statistiky a analýzy (viz renderAttendanceBar v app.js). */
.entity-attendance { display: inline-flex; align-items: center; gap: 6px; }
.entity-attendance .bar { width: 56px; flex: none; }
.entity-attendance .bar span { opacity: .45; transition: opacity .15s ease; }
.entity-link:hover .entity-attendance .bar span { opacity: 1; }
.entity-attendance-value {
  font-size: 12px;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.entity-arrow { color: var(--text-muted); font-size: 16px; flex: none; }
@media (max-width: 639px) {
  .member-card-link {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) 40px;
    column-gap: 8px;
    padding-left: 12px;
    padding-right: 12px;
  }
  .member-card-link .entity-main { grid-column: 1; grid-row: 1; }
  .member-card-link .entity-meta,
  .member-card-link .entity-attendance,
  .member-card-link .entity-hlasy { display: contents; }
  .member-card-link .entity-attendance .bar,
  .member-card-link .entity-hlasy .stat-row-track {
    grid-column: 2;
    grid-row: 1;
    width: 100%;
    min-width: 0;
  }
  .member-card-link .entity-attendance-value,
  .member-card-link .entity-hlasy-value {
    grid-column: 3;
    grid-row: 1;
    text-align: right;
  }
  .member-card-link .entity-arrow { display: none; }
  .member-election-card { grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) 7ch; }
}

/* Preferenční hlasy v kartičce (member/index-fallback.blade.php) – track/fill
   vzor (.stat-row-track/.fill, sdílené i s .meeting-volume-bar na
   meeting/index.blade.php i .jednotnost-cell v tabulce subjektů), nahrazuje
   tam docházkový pruh z bohatého pohledu (appka z KandidaturaData docházku
   nemá, viz diskuze v hlavní konverzaci). */
.entity-hlasy { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.entity-hlasy .stat-row-track { width: 56px; height: 8px; flex: none; }
.entity-hlasy-value {
  font-size: 12px;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Puntík politického subjektu – levý horní roh karty, absolutně pozicovaný
   vůči <li> (sourozenec .entity-link, ne potomek – jde o vlastní odkaz na
   detail strany, takže nejde vnořit do odkazu na zastupitele). Zkratka
   strany se při hoveru vysouvá jako text vedle puntíku (viz
   .party-badge-label). */
.party-badge { position: absolute; top: 8px; left: 8px; z-index: 1; display: flex; align-items: center; gap: 5px; text-decoration: none; color: inherit; }
.party-badge:hover { z-index: 2; }
.party-badge-label {
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  opacity: 0;
  font-size: 11px;
  font-weight: 600;
  color: var(--text-primary);
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 6px;
  transition: max-width .15s ease, opacity .15s ease;
}
.party-badge:hover .party-badge-label {
  max-width: 140px;
  opacity: 1;
  padding: 2px 6px;
}

/* Sloupce „Proti většině" / „Proti klubu" v tabulce členů (partials/
   member-table s $showKlub) – červené / žluté, tlumená 0. */
#members-table .vetsine-hit { color: color-mix(in srgb, var(--status-critical) 60%, var(--text-primary)); font-weight: 600; }
#members-table .klub-hit { color: color-mix(in srgb, var(--status-warning) 60%, var(--text-primary)); font-weight: 600; }
#members-table .klub-zero { color: var(--text-muted); }

/* „Nejčastěji jinak než většina / než klub" pod seznamem členů na party/show
   – každý řádek: popisek + chipy jméno/N× (wrap při hodně lidech).
   Červené = proti výsledku, žluté = proti klubu. */
.rebel-lines { display: grid; gap: 6px; margin: 6px 0 20px; }
.klub-rebels {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin: 0; font-size: 13px;
}
.klub-rebels-title {
  color: var(--text-muted); font-size: 11px; text-transform: uppercase; letter-spacing: .03em;
}
.klub-chip {
  display: inline-flex; align-items: baseline; gap: 4px;
  padding: 2px 8px; border-radius: 999px;
  color: color-mix(in srgb, var(--status-warning) 55%, var(--text-primary));
  background: color-mix(in srgb, var(--status-warning) 16%, var(--surface-1));
  text-decoration: none; white-space: nowrap;
}
.klub-chip:hover { background: color-mix(in srgb, var(--status-warning) 26%, var(--surface-1)); }
.klub-chip.crit {
  color: color-mix(in srgb, var(--status-critical) 55%, var(--text-primary));
  background: color-mix(in srgb, var(--status-critical) 14%, var(--surface-1));
}
.klub-chip.crit:hover { background: color-mix(in srgb, var(--status-critical) 24%, var(--surface-1)); }
.klub-chip b { font-variant-numeric: tabular-nums; }

/* Od 640px výš se seznam entit (zastupitelé/strany) mění z řádků na
   dlaždice – užší, vyšší, vedle sebe v mřížce. Pod 640px (mobil) zůstává
   beze změny řádkový seznam definovaný výše. Avatar se na vrch dlaždice
   přesouvá čistě přes flex-direction: column, bez zásahu do HTML –
   mobilní varianta tak zůstává netknutá. */
@media (min-width: 640px) {
  .entity-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 14px;
  }
  /* Krátké seznamy (např. politické subjekty) – auto-fit + pevná max.
     šířka sloupce místo 1fr, ať se pár kartiček nerozteče přes celou šířku
     stránky, a justify-content: center vycentruje výslednou mřížku. */
  .entity-list-center {
    grid-template-columns: repeat(auto-fit, minmax(160px, 220px));
    justify-content: center;
  }
  .entity-link {
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    text-align: center;
    gap: 6px;
    padding: 22px 14px 18px;
    height: 100%;
  }
  .entity-main {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    width: 100%;
  }
  .entity-main .avatar-wrap { margin-bottom: 4px; }
  .entity-main .avatar { width: 64px; height: 64px; }
  .entity-main .avatar-wrap .role-badge { font-size: 18px; top: -3px; right: -7px; }
  .entity-main .avatar-wrap .role-badge.role-mistostarosta,
  .entity-main .avatar-wrap .role-badge.role-radni { font-size: 15px; }
  .entity-main .avatar-wrap .role-badge.role-inactive { font-size: 15px; top: auto; bottom: -2px; right: -6px; }
  .avatar-placeholder.avatar-sm { font-size: 22px; }
  /* Prostý text (název strany, žádné .entity-firstname uvnitř) se v
     dlaždici smí zalomit na max. 2 řádky přes webkit-line-clamp. Jméno
     zastupitele MÁ .entity-firstname/.entity-lastname jako samostatné
     bloky – line-clamp je určený pro zalamovaný text, ne pro diskrétní
     child elementy, a spolehlivost jejich řazení pod sebe by rozbil (proto
     zůstává na základním display:flex; flex-direction:column z báze). */
  .entity-name:not(:has(.entity-firstname)) {
    white-space: normal;
    font-size: 15px;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    min-height: 2.6em;
  }
  .entity-name:has(.entity-firstname) { font-size: 15px; min-height: 2.6em; }
  .entity-firstname, .entity-lastname { font-size: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  /* Zalamování .entity-meta řeší bázové pravidlo (viz .entity-list-center
     .entity-meta výše); na dlaždici se navíc centruje a drží výšku na 2
     řádky, ať jsou kartičky stejně vysoké. Zúženo na .entity-list-center,
     ať se min-height nevynucuje i na kartičkách zastupitelů (.entity-meta
     tam drží jen jednořádkový docházkový bar). */
  .entity-list-center .entity-meta {
    justify-content: center;
    min-height: 2.8em;
  }
  .entity-attendance .bar { width: 72px; }
  .entity-arrow { display: none; }
  .entity-group-title { grid-column: 1 / -1; }
}

.color-dot { display: inline-block; vertical-align: middle; width: 11px; height: 11px; border-radius: 50%; flex: none; border: 1px solid var(--border); }
.color-dot.color-dot-lg { width: 16px; height: 16px; }
.color-dot.color-dot-none { background: var(--grid); }
/* Koláčová tečka (koalice/sdružení bez vlastní barvy) – čtvercové SVG s výsečemi
   klipnuté do kruhu; ostré vrcholy ve středu (na rozdíl od conic-gradientu). */
.color-dot.color-dot-pie { overflow: hidden; line-height: 0; }
.color-dot.color-dot-pie > svg { display: block; width: 100%; height: 100%; }

/* Subjekt v buňce Strana tabulek zastupitelů (partials/party-tag) –
   sjednocuje /zastupitele a /zastupitele?stav=volby: barevná tečka +
   zkratka, výrazněji než dřív (tučně, větší tečka), bez štítku. */
.party-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 600;
  color: var(--text-primary);
  text-decoration: none;
  white-space: nowrap;
}
a.party-tag:hover { color: var(--series-1); }
.party-tag .color-dot { width: 13px; height: 13px; }

.avatar {
  border-radius: 50%;
  object-fit: cover;
  object-position: center 20%;
  flex: none;
  display: block;
  border: 1px solid var(--border);
}
.avatar-sm { width: 32px; height: 32px; }
.avatar-lg { width: 72px; height: 72px; }
.avatar-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
  background: var(--grid);
  color: var(--text-muted);
  font-weight: 600;
}
.avatar-silhouette {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  fill: currentColor;
  opacity: .25;
}
.avatar-initials {
  position: relative;
  z-index: 1;
  color: var(--text-secondary);
  font-weight: 700;
  letter-spacing: .02em;
}
.avatar-placeholder.avatar-sm { font-size: 12px; }
.avatar-placeholder.avatar-lg { font-size: 22px; }

/* Znak obce v kartičkách (geo/obce.blade.php, geo/show.blade.php – jen
   $lvl === 'obec', kraj/okres/orp/pou nemají ekvivalentní zdroj, viz
   zastupko-data/scripts/lib/index.py). Na rozdíl od .avatar object-fit:
   contain, ne cover, a bez border-radius: 50% – erb je čtvercový/obdélníkový
   tvar, kulatý ořez by ho useknul. Vlastní pozadí + padding, ať SVG/PNG se
   znakem na průhledném pozadí (běžné na Wikimedia Commons) není v dark
   módu neviditelné. */
.znak {
  width: 36px;
  height: 41px;
  object-fit: contain;
  flex: none;
  display: block;
  background: var(--surface-1);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 2px;
  box-sizing: border-box;
}
/* Větší varianta vedle h1 na detailu (geo/show.blade.php) – stejný poměr
   stran jako .znak, jen ~2.2x. */
.znak-lg { width: 80px; height: 91px; }
/* Náhrada za chybějící/nenačtený znak (public/js/znak-fallback.js,
   znakFallback()/znakPlaceholderHtml()) – stejný princip jako .avatar-
   placeholder/.avatar-silhouette výše, jen bez iniciál (znak žádnou
   textovou zkratku nemá, jen tlumená siluetu štítu). Dědí box .znak/
   .znak-lg (velikost/pozadí/okraj), jen přidává vystředění ikonky. */
.znak-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--text-muted);
}
.znak-placeholder svg { width: 55%; height: 55%; fill: currentColor; }

/* --- Přepínač kartičky/tabulka (seznam zastupitelů) --- */
.view-toggle {
  display: inline-flex;
  gap: 4px;
  padding: 3px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-1);
}
.view-toggle button {
  border: none;
  background: transparent;
  color: var(--text-secondary);
  font-size: 13px;
  padding: 6px 14px;
  border-radius: 6px;
  cursor: pointer;
}
.view-toggle button:hover { color: var(--text-primary); }
.view-toggle button.active { background: var(--grid); color: var(--text-primary); font-weight: 600; }

/* Stejný vzor jako .view-toggle button výše, ale skutečné odkazy mezi
   routami (partials/geo-nav.blade.php) místo JS přepínače na jedné
   stránce – proto <a>, ne <button>. */
.view-toggle a {
  display: inline-flex;
  align-items: center;
  border: none;
  background: transparent;
  color: var(--text-secondary);
  font-size: 13px;
  padding: 6px 14px;
  border-radius: 6px;
  text-decoration: none;
  cursor: pointer;
}
.view-toggle a:hover { color: var(--text-primary); }
.view-toggle a.active { background: var(--grid); color: var(--text-primary); font-weight: 600; }
/* Neklikací položka přepínače – jediný dostupný stav, není kam přepnout
   (partials/stav-toggle.blade.php `$jenVolby`). */
.view-toggle span { display: inline-flex; align-items: center; font-size: 13px; padding: 6px 14px; border-radius: 6px; color: var(--text-secondary); }
.view-toggle span.active { background: var(--grid); color: var(--text-primary); font-weight: 600; }

/* Svislá oddělovací čára v #geo-nav (partials/geo-nav.blade.php) – odděluje
   "Regiony" (vyhledávač napříč všemi úrovněmi) od zbytku (jednotlivé úrovně
   hierarchie), ať je vizuálně jasné, že jde o jinou kategorii věci, ne
   další úroveň v řadě. */
.geo-nav-divider {
  align-self: stretch;
  width: 1px;
  margin: 2px 2px;
  background: var(--border);
}

/* Dvě varianty geo-nav (partials/geo-nav.blade.php) vedle sebe v DOM,
   přepínané tímhle breakpointem (stejná hodnota jako zbytek appky, viz
   ostatní @media (max-width: 640px) bloky) – plochý řádek nad ním, dropdown
   pod ním. Žádná JS detekce šířky, čistě CSS. */
.geo-nav-narrow { display: none; }
@media (max-width: 640px) {
  .geo-nav-wide { display: none; }
  .geo-nav-narrow { display: inline-block; }
}
/* Aktivní položka v panelu (na rozdíl od .dropdown-toggle sumáře, který
   místo toho rovnou ukazuje label aktivní stránky) – stejný vzhled jako
   .view-toggle a.active výše. */
.dropdown-item.active { background: var(--grid); color: var(--text-primary); font-weight: 600; }

/* Řazení kartiček podřazených geo objektů podle obyvatel (geo/show.blade.php,
   public/js/card-sort.js) – stejný .view-toggle vzhled jako Kartičky/
   Tabulka/Mapa, na stejném .toggle-row řádku (viditelnost přepíná
   updateCardSortVisibility() v geo/show.blade.php), jen se šipkou směru
   u aktivního tlačítka jako .data-table th.sort-asc/desc. */
.card-sort button.sort-asc::after { content: ' ▲'; font-size: 9px; }
.card-sort button.sort-desc::after { content: ' ▼'; font-size: 9px; }

.toggle-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 20px;
  margin-bottom: 16px;
}
.group-toggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 13px;
  color: var(--text-secondary);
  cursor: pointer;
  user-select: none;
}
.group-toggle:hover { color: var(--text-primary); }
.group-toggle input { cursor: pointer; accent-color: var(--series-1); }

.compare-toggle {
  border: 1px solid var(--border);
  background: var(--surface-1);
  color: var(--text-secondary);
  font-size: 13px;
  padding: 7px 14px;
  border-radius: 8px;
  cursor: pointer;
}
.compare-toggle:hover { color: var(--text-primary); }
.compare-toggle.active { background: var(--grid); color: var(--text-primary); font-weight: 600; border-color: var(--series-1); }

/* Checkbox pro výběr karet do porovnání – pravý horní roh, zrcadlově
   k puntíku strany (levý horní roh). Vidět jen v režimu porovnání. */
.compare-check {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
  display: none;
  cursor: pointer;
}
.entity-list.compare-mode .compare-check { display: flex; }
.compare-check input { cursor: pointer; accent-color: var(--series-1); width: 16px; height: 16px; }
/* Tatáž volba i v tabulkovém pohledu – checkbox vlevo od jména, vidět jen
   v režimu porovnání (#members-table.compare-mode). */
#members-table .compare-checkbox { display: none; }
#members-table.compare-mode .compare-checkbox {
  display: inline-block; margin-right: 8px; vertical-align: middle;
  cursor: pointer; accent-color: var(--series-1); width: 16px; height: 16px;
}
/* Totéž na seznamu subjektů (party/index) – checkbox vlevo od názvu
   subjektu, jen v režimu porovnání (#parties-table.compare-mode). */
#parties-table .compare-checkbox { display: none; }
#parties-table.compare-mode .compare-checkbox {
  display: inline-block; margin-right: 8px; vertical-align: middle;
  cursor: pointer; accent-color: var(--series-1); width: 16px; height: 16px;
}

/* V tabulce (bez fotky) je odznak prostý inline text vedle jména. */
.role-badge { font-size: 13px; margin-left: 3px; }
/* Neaktivní (partials/inactive-badge.blade.php) – malá tlumená ikonka
   (dveře + šipka ven), ne emoji jako role/radní, ať nepůsobí stejně
   výrazně jako aktivní role. Velikost drží konstantní 1em napříč všemi
   kontexty (nescáluje se s avatarem jako role-badge), protože má zůstat
   decentní i v detailu, kde je avatar velký. */
.role-inactive { color: var(--text-muted); font-size: 13px; }
/* inline-block, ne block – v .deputy-name (app.js) sedí ikonka hned za
   textem jména; display:block by uvnitř inline kontextu vynutil zalomení
   na nový řádek. V .avatar-wrap kontextu (absolutně pozicovaný .role-badge)
   na tom nezáleží, tam je ikonka jediný obsah. */
.role-inactive svg { display: inline-block; width: 1em; height: 1em; vertical-align: -0.15em; }

/* U karet/detailu (s fotkou) je odznak překryv v rohu avataru – nezabírá
   vlastní řádek v layoutu. */
.avatar-wrap { position: relative; display: inline-flex; flex: none; }
.avatar-wrap .role-badge {
  position: absolute;
  top: -3px;
  right: -5px;
  margin-left: 0;
  font-size: 13px;
  line-height: 1;
  filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, .5));
}
/* ⭐/🛡️ vizuálně "váží" víc než 👑 při stejném font-size – obojí zmenšené,
   ať v malém odznaku nepůsobí předimenzovaně (drop-shadow zůstává z
   .avatar-wrap .role-badge výše, tady se nepřebíjí). */
.avatar-wrap .role-badge.role-mistostarosta,
.avatar-wrap .role-badge.role-radni { font-size: 11px; }
/* Neaktivní (partials/inactive-badge.blade.php) – vpravo DOLE, ať se
   nepřekrývá s rolí (vpravo nahoře); člověk může mít oboje najednou. Bez
   drop-shadow (na rozdíl od role-badge výše) – tlumená barva už dost
   kontrastuje s pozadím, stín by ji zase opticky zvýraznil. Font-size se
   tu záměrně nepřebíjí v žádném z breakpointů níže – zůstává konstantní. */
.avatar-wrap .role-badge.role-inactive { top: auto; bottom: -1px; right: -5px; filter: none; }
.detail-title .avatar-wrap .role-badge,
.title-row .avatar-wrap .role-badge,
.compare-col-header .avatar-wrap .role-badge { font-size: 24px; top: -4px; right: -8px; }
.detail-title .avatar-wrap .role-badge.role-mistostarosta,
.title-row .avatar-wrap .role-badge.role-mistostarosta,
.compare-col-header .avatar-wrap .role-badge.role-mistostarosta,
.detail-title .avatar-wrap .role-badge.role-radni,
.title-row .avatar-wrap .role-badge.role-radni,
.compare-col-header .avatar-wrap .role-badge.role-radni { font-size: 19px; }
.detail-title .avatar-wrap .role-badge.role-inactive,
.title-row .avatar-wrap .role-badge.role-inactive,
.compare-col-header .avatar-wrap .role-badge.role-inactive { font-size: 16px; top: auto; bottom: -3px; right: -7px; }

.entity-group-title {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-muted);
  padding: 2px 4px;
}
.entity-group-title:not(:first-child) { margin-top: 6px; }

.table-scroll {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 12px;
  margin-bottom: 24px;
}
.table-group-title {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--text-muted);
  margin: 0 0 8px;
}
.subjekty-mobile-sort { display: none; }
@media (max-width: 700px) {
  .subjekty-mobile-sort { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 12px; }
  .subjekty-mobile-sort select {
    min-width: 0;
    max-width: 100%;
    min-height: 44px;
    padding: 8px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--surface-1);
    color: var(--text-primary);
    font: inherit;
  }
  #subjekty-table tbody tr {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px 12px;
    padding: 8px 12px;
  }
  #subjekty-table td { min-width: 0; }
  #subjekty-table td[data-label] {
    order: 1;
    text-align: left !important;
    overflow-wrap: anywhere;
    font-variant-numeric: tabular-nums;
  }
  #subjekty-table td.td-secondary { order: 2; }
  #subjekty-table td:first-child {
    grid-column: 1 / -1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 44px;
    align-items: center;
    cursor: pointer;
    overflow-wrap: anywhere;
    padding: 0;
  }
  #subjekty-table td:first-child a { min-width: 0; }
  #subjekty-table .row-toggle { min-width: 44px; min-height: 44px; }
}
.table-group:not(:first-child) .table-group-title { margin-top: 4px; }
.data-table { width: 100%; border-collapse: collapse; background: var(--surface-1); }
.data-table th, .data-table td {
  padding: 10px 14px;
  text-align: left;
  font-size: 13.5px;
  border-bottom: 1px solid var(--grid);
  white-space: nowrap;
}
.data-table th {
  color: var(--text-muted);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: .03em;
  cursor: pointer;
  user-select: none;
}
.data-table th:hover { color: var(--text-primary); }
.data-table th.sort-asc::after { content: ' ▲'; font-size: 9px; }
.data-table th.sort-desc::after { content: ' ▼'; font-size: 9px; }
/* Souhrnný řádek (subjekt/volby – „Celkem"). */
.data-table tfoot td { font-weight: 600; border-top: 2px solid var(--border); border-bottom: none; }
/* Zvýrazněný řádek = vybrané volební období (subjekt/volby). */
.data-table tr.is-selected td { background: color-mix(in srgb, var(--series-1) 14%, var(--surface-1)); }

/* Sloupcový graf vývoje mandátů po volbách (subjekt/volby.blade.php) – ručně
   CSS/flex, žádná knihovna, stejný přístup jako .bar / .meeting-volume-bar.
   Barva sloupce --series-1 (neutrální datová série, ne status-*). */
/* Dva pruhy „Listiny" / „Lidé" na stránce Volby (subjekt/volby.blade.php) –
   podíl úspěšných z kandidujících, místo souhrnných karet. Track/fill
   sdílený s appkou (.stat-row-track/.fill). */
.volby-pruhy { display: flex; flex-direction: column; gap: 16px; margin-bottom: 24px; }
.volby-pruh-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 6px; font-size: 13px; }
.volby-pruh-name { font-weight: 600; }
.volby-pruh-nums { color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.volby-pruh-nums a { color: inherit; text-decoration: none; }
.volby-pruh-nums a:hover { color: var(--series-1); text-decoration: underline; }
.volby-pruh .stat-row-track { display: flex; height: 12px; }
.volby-pruh .stat-row-track .fill { flex: none; }
.volby-pruh .fill-usk { flex: none; height: 100%; background: var(--series-3); }
.volby-pruh .fill-usk-rest { flex: none; height: 100%; background: color-mix(in srgb, var(--series-3) 28%, var(--surface-1)); }

.mandate-chart { margin: 0 0 20px; }
/* Svislá osa vlevo + plocha se sloupci v jedné řadě. */
.mandate-chart-plot-wrap { display: flex; align-items: stretch; gap: 8px; }
.mandate-y-axis {
  position: relative;
  flex: none;
  width: 42px;
  font-size: 10px;
  line-height: 1;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
/* Popisky vystředěné na svou hladinu; „max" k hornímu okraji sloupcové
   zóny (= padding-top plochy), „0" na základní čáru (border-bottom). */
.mandate-y-axis span { position: absolute; right: 0; transform: translateY(-50%); white-space: nowrap; }
.mandate-y-axis span[data-axis="max"] { top: 20px; }
.mandate-y-axis span[data-axis="mid"] { top: calc(20px + (100% - 20px) / 2); }
.mandate-y-axis span[data-axis="zero"] { top: 100%; }
.mandate-chart-plot {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: flex-end;
  gap: 6px;
  height: 230px;
  padding-top: 20px;            /* místo pro hodnotu nad nejvyšším sloupcem */
  border-left: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.mandate-col {
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
}
/* Stacked bar: dva segmenty – .mandate-bar-part zespodu je „úspěšná/zvolená"
   část (plná --series-1), .mandate-bar-rest nad ní zbytek (tlumená). Přes
   legendu jde jeden segment vypnout – pak se sloupce škálují jen na ten
   viditelný (viz data-mode na .mandate-chart a redraw() v volby.blade.php). */
.mandate-col .mandate-bar {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  flex: none;
  width: 100%;
  max-width: 46px;
  min-height: 2px;
  overflow: hidden;
  border-radius: 3px 3px 0 0;
}
.mandate-col .mandate-bar-part { flex: none; width: 100%; background: var(--series-1); }
.mandate-col .mandate-bar-rest { flex: none; width: 100%; background: color-mix(in srgb, var(--series-1) 26%, var(--surface-1)); }
/* Vrstva uskupení (celý výsledek koalic/sdružení), po zaškrtnutí „Začlenit
   i uskupení". Vlastní barva --series-3 (--series-2 je barva vybraného
   roku). Pořadí ve sloupci odspoda: tmavěmodrá solo-zvolení | tmavězelená
   usk-zvolení | světlemodrá solo-nezvolení | světlezelená usk-nezvolení
   (nejdřív úspěšní, pak neúspěšní). Nejsvrchnější (světlezelené
   usk-nezvolení) je typicky jen pár listin – redraw() v volby.blade.php mu
   drží min. výšku, ať není neviditelné. */
.mandate-col .mandate-bar-usk-part { flex: none; width: 100%; background: var(--series-3); }
.mandate-col .mandate-bar-usk-rest { flex: none; width: 100%; background: color-mix(in srgb, var(--series-3) 28%, var(--surface-1)); }
/* Vybraný ročník – odlišná barva (druhá datová série). */
/* Vybraný ročník – nepřebarvuje segmenty, jen „vysvítí" sloupec: světlá
   akcentní dráha přes celý sloupec + silný obrys a záře na pruhu. */
.mandate-col.is-selected {
  background: color-mix(in srgb, var(--series-2) 12%, transparent);
  border-radius: 4px 4px 0 0;
}
.mandate-col.is-selected .mandate-bar {
  box-shadow: 0 0 0 3px var(--series-2), 0 0 18px 5px color-mix(in srgb, var(--series-2) 60%, transparent);
}

/* Přepínač ukazatele + legenda + checkbox v jedné řadě nad grafem. */
.mandate-controls { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin-bottom: 12px; }
.usk-check { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--text-secondary); cursor: pointer; margin-left: auto; }
.usk-check input { margin: 0; accent-color: var(--series-3); }
.mandate-legend { display: flex; gap: 14px; }
.mandate-legend button {
  border: 0; background: none; padding: 2px 0; cursor: pointer;
  font: inherit; font-size: 11px; color: var(--text-muted);
  display: inline-flex; align-items: center;
}
.mandate-legend button:hover { color: var(--text-primary); }
.mandate-legend button.off { text-decoration: line-through; opacity: .55; }
.mandate-legend .lg { display: inline-block; width: 10px; height: 10px; border-radius: 2px; margin-right: 5px; }
.mandate-legend .lg-part { background: var(--series-1); }
.mandate-legend .lg-rest { background: color-mix(in srgb, var(--series-1) 26%, var(--surface-1)); }
.mandate-col .val {
  font-size: 11px;
  line-height: 1;
  margin-bottom: 3px;
  color: var(--text-muted);
  white-space: nowrap;
}
.mandate-col.is-selected .val { color: var(--text-primary); font-weight: 600; }
.mandate-chart-x { display: flex; gap: 6px; margin-top: 5px; padding-left: 51px; }
/* Rok = odkaz na to volební období (subjekt.period.volby); na stránkách
   bez period-scoped variant (subjekt/nezavisli) je to prostý <span>. */
.mandate-chart-x a,
.mandate-chart-x span {
  flex: 1 1 0;
  min-width: 0;
  text-align: center;
  font-size: 11px;
  color: var(--text-muted);
  text-decoration: none;
}
.mandate-chart-x a:hover { color: var(--text-primary); text-decoration: underline; }
.mandate-chart-x a.is-selected { color: var(--text-primary); font-weight: 700; text-decoration: underline; text-decoration-color: var(--series-2); text-decoration-thickness: 2px; text-underline-offset: 3px; }
/* Číselné sloupce zarovnané doprava (tabulka subjektů na party/index –
   Zastupitelů/Radních/Náhradníků/Podíl). Platí jen kde je třída `num`;
   na mobilu (stackovaný rozpad níže) se ruší zpět na left. */
.data-table th.num, .data-table td.num { text-align: right; }
.data-table tbody tr:last-child td { border-bottom: none; }
.data-table tbody tr:hover { background: var(--grid); }
.data-table td a { color: var(--text-primary); text-decoration: none; font-weight: 600; }
.data-table td a:hover { text-decoration: underline; }

/* Rozbalovací graf „vývoj v obci" na tabulce obcí (subjekt/obce.blade.php,
   subjekt-obce.js) – ▸/▾ ve vlastním úzkém sloupci, detail je řádek přes
   celou šířku (colspan) s .obce-vyvoj uvnitř. */
.data-table th.obce-expand-col, #obce-table td:first-child { width: 1.6em; padding-right: 0; }
/* „Kandidovali jako" (subjekt/obce.blade.php, subjekt-obce.js) – u koalic
   dost dlouhé (kandidátka nese jména všech zúčastněných stran) – bez stropu
   by protáhla celou tabulku na šířku a `.table-scroll` (overflow-x) by
   místo useknutí JEDNOHO sloupce ukázal horizontální scrollbar na CELOU
   tabulku. `max-width` funguje i bez `table-layout:fixed` (auto layout ho
   při výpočtu šířky sloupce respektuje), `title` na buňce (blade/JS) nese
   plný text pro hover. */
.data-table td.jako-col, .data-table th.jako-col { max-width: 240px; overflow: hidden; text-overflow: ellipsis; }
.obce-toggle {
  border: 0; background: none; padding: 0; cursor: pointer; color: var(--text-muted);
  font: inherit; font-size: 11px; line-height: 1; width: 1.4em; text-align: center;
}
.obce-toggle:hover { color: var(--text-primary); }
.obce-toggle:disabled { opacity: .4; cursor: default; }
.obce-detail-row > td { background: var(--surface-1); padding: 0; }
@media (max-width: 700px) {
  #obce-table-view #obce-table tr[data-obec-kod] {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px 12px;
    padding: 8px 12px;
    position: relative;
  }
  #obce-table-view #obce-table tr[data-obec-kod] > td { min-width: 0; text-align: left !important; }
  #obce-table-view #obce-table tr[data-obec-kod] > td:first-child {
    position: absolute; top: 4px; right: 8px; width: 44px; padding: 0;
  }
  #obce-table-view .obce-toggle { width: 44px; min-height: 44px; }
  #obce-table-view #obce-table tr[data-obec-kod] > td:nth-child(2) {
    grid-column: 1 / -1; padding-right: 44px; min-height: 40px;
    overflow-wrap: anywhere; cursor: pointer;
  }
  #obce-table-view #obce-table td.jako-col { display: none; }
  #obce-table-view #obce-table tr.expanded td.jako-col {
    display: block; grid-column: 1 / -1; order: 2;
    max-width: none; overflow: visible; overflow-wrap: anywhere;
  }
  #obce-table-view #obce-table .obce-detail-row > td { width: 100%; padding: 8px 12px; }
}
.obce-vyvoj { margin: 6px 10px 10px 34px; padding: 10px 12px 4px; }
/* Legenda – zapíná/vypíná segment (aspoň jeden musí zůstat vidět), stejný
   vzor jako .mandate-legend na subjekt/volby. */
.ov-legend { display: flex; gap: 12px; margin-bottom: 6px; }
.ov-legend button {
  border: 0; background: none; padding: 0; cursor: pointer; font: inherit;
  font-size: 11px; color: var(--text-muted); display: inline-flex; align-items: center;
}
.ov-legend button:hover { color: var(--text-primary); }
.ov-legend button.off { text-decoration: line-through; opacity: .55; }
.ov-lg { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 5px; }
.ov-lg-part { background: var(--series-1); }
.ov-lg-rest { background: color-mix(in srgb, var(--series-1) 26%, var(--surface-1)); }

/* Mini sloupcový graf – zjednodušená obdoba .mandate-chart (subjekt/volby):
   stejné funkční prvky (osa, legenda výše, zvýraznění prohlíženého období,
   bublina), jen v menším měřítku a bez vrstvy uskupení. .ov-bar má
   height:N% plochy (.ov-plot); .ov-bar-part/.ov-bar-rest mají height:N%
   VÝŠKY SAMOTNÉHO SLOUPCE (ne plochy) – part (mandáty) dole plnou barvou,
   rest nad ním tlumeně. `.mandate-bar` na .ov-bar je jen marker pro
   bar-tooltip.js (barish() ho pozná, žádné .mandate-col-scoped styly na
   bare .mandate-bar necílí). */
.ov-plot-wrap { display: flex; align-items: stretch; gap: 6px; }
.ov-y-axis { position: relative; flex: none; width: 24px; font-size: 9px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.ov-y-axis span { position: absolute; right: 0; transform: translateY(-50%); white-space: nowrap; }
.ov-y-axis span:nth-child(1) { top: 0; }
.ov-y-axis span:nth-child(2) { top: 50%; }
.ov-y-axis span:nth-child(3) { top: 100%; }
.ov-plot { flex: 1; min-width: 0; display: flex; align-items: flex-end; gap: 4px; height: 64px; border-bottom: 1px solid var(--border); }
.ov-col { flex: 1 1 0; min-width: 0; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; }
.ov-bar {
  display: flex; flex-direction: column; justify-content: flex-end;
  flex: none; width: 100%; max-width: 22px; min-height: 3px; overflow: hidden;
  border-radius: 2px 2px 0 0; cursor: help;
}
.ov-bar-part { flex: none; width: 100%; background: var(--series-1); }
.ov-bar-rest { flex: none; width: 100%; background: color-mix(in srgb, var(--series-1) 26%, var(--surface-1)); }
/* Rok, kdy subjekt kandidoval jen jako člen koalice/sdružení (subjekt-obce.js,
   ovChartHtml()) – stejná konvence jako .mandate-bar-usk-part/-rest na
   subjekt/volby.blade.php (--series-3 pro „uskupení", ne vlastní --series-1). */
.ov-bar-part.is-uskupeni { background: var(--series-3); }
.ov-bar-rest.is-uskupeni { background: color-mix(in srgb, var(--series-3) 26%, var(--surface-1)); }
.ov-bar.is-empty { border: 1px dashed var(--border); }
.ov-bar.is-empty .ov-bar-part, .ov-bar.is-empty .ov-bar-rest { display: none; }
/* Právě prohlížené období (aktuální $obdobi stránky) – zvýraznění jako
   .mandate-col.is-selected, jen tlumenější (kompaktní kontext). */
.ov-col.is-selected .ov-bar { box-shadow: 0 0 0 2px var(--series-2); }
/* padding-left = šířka .ov-y-axis (24px) + gap .ov-plot-wrap (6px), ať roky
   sedí pod sloupci (stejný trik jako .mandate-chart-x padding-left). */
.ov-axis { display: flex; gap: 4px; margin-top: 4px; padding-left: 30px; }
.ov-axis span, .ov-axis a { flex: 1 1 0; min-width: 0; text-align: center; font-size: 10px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.ov-axis a { text-decoration: none; }
.ov-axis a:hover { color: var(--text-primary); text-decoration: underline; }
.ov-axis span.is-selected, .ov-axis a.is-selected { color: var(--text-primary); font-weight: 700; }
/* Puntík subjektu v Tabulce uskupení (subjekt/uskupeni) – .color-dot má
   width/height, ale bez flex rodiče je to inline span a rozměr se ignoruje. */
#uskupeni-table td a { display: inline-flex; align-items: center; gap: 6px; }

/* /volby – přehled listin před tabulkami kandidátů: proč má která strana
   daný počet mandátů. Řádek = barevný název · pruh podílu hlasů (šířka vůči
   nejsilnější listině, barva listiny) · % hlasů + počet mandátů. */
/* /volby – pruh volební účasti pod souhrnnými kartami. */
.election-turnout { margin: 0 0 26px; }
.election-turnout-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 5px; }
.election-turnout-caption { font-size: 11px; text-transform: uppercase; letter-spacing: .03em; color: var(--text-muted); }
.election-turnout-value { font-weight: 600; font-variant-numeric: tabular-nums; }
.election-turnout .stat-row-track { display: block; flex: none; height: 12px; }

.election-overview { margin: 0 0 28px; }
.election-overview .view-toggle { display: inline-flex; }
.election-overview .seat-diagram { max-width: 480px; }
/* Pruh podílu hlasů přes celou šířku stránky, výška shodná s pruhem
   „Volební účast" nad ním (.election-turnout). */
.election-overview .bar.seat-bar { max-width: none; margin: 0; height: 12px; }
/* sub-5% listiny mají v pruhu jen tenký segment – ať nezmizí úplně */
.election-overview .seat-bar span { min-width: 3px; }
.election-overview .seat-diagram-total { margin: 4px 0 16px; }
/* Zvýraznění výběru (public/js/election-overview.js) – hover/focus na legendu,
   pruh listiny nebo segment diagramu rozsvítí tu listinu všude, ostatní ztlumí.
   Párování přes data-list; .has-hl je na kontejneru, .hl na dotčených prvcích. */
.seat-bar.has-hl span:not(.hl) { opacity: .16; }
.seat-bar span.hl { opacity: 1; outline: 1px solid var(--text-primary); outline-offset: -1px; }
.seat-diagram.has-hl circle:not(.hl) { opacity: .16; }
.election-overview-list.has-hl .eo-name:not(.hl),
.election-overview-list.has-hl .eo-bar:not(.hl),
.election-overview-list.has-hl .eo-meta:not(.hl) { opacity: .3; }
.eo-name, .eo-bar, .eo-meta { transition: opacity .12s ease; }
/* .eo-name je odkaz na detail listiny (party.show) – neutrální barva/bez
   podtržení, podtrhne se až na hoveru; .hl (highlight z election-overview.js)
   ho zvýrazní barvou textu. */
.eo-name { color: inherit; text-decoration: none; }
.eo-name:hover > span { text-decoration: underline; }
.eo-name.hl { color: var(--text-primary); }
.eo-name:focus-visible { outline: 2px solid var(--series-1); outline-offset: 2px; border-radius: 3px; }
/* Název listiny v hlavičce sekce na /volby + party/show – odkaz, neutrální. */
.election-list-name { color: inherit; text-decoration: none; }
.election-list-name:hover { text-decoration: underline; }
/* Grid je na <ul>, <li> je `display: contents` – název/čísla/pruh každé
   listiny se sázejí přímo do sloupců rodiče, takže drží svislé sloupce
   napříč seznamem bez per-řádkového gridu. Pořadí v DOM je název, čísla,
   pruh (viz election/index.blade.php) → auto-placement dá název|čísla na
   řádek a pruh (grid-column: 1/-1) pod ně.
   Sloupce: 1fr spacer | název (pružný, strop ~34rem – dlouhé lokální názvy
   stran využijí celou šířku popisku, teprve pak elipsa) | čísla | 1fr spacer.
   Popisek (název+čísla) tak drží čtecí šířku ~600px VYCENTROVANÝ (oba 1fr
   spacery stejné), kdežto pruh proporce jede přes CELOU šířku (grid-column:
   1/-1, spacery jsou jeho, ne popisku). Řádkový gap je malý (popisek↔pruh),
   odsazení mezi listinami řeší margin na pruhu. */
.election-overview-list {
  list-style: none; margin: 0; padding: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(84px, 34rem) auto minmax(0, 1fr);
  align-items: center;
  column-gap: 14px;
  row-gap: 2px;
  font-size: 13px;
}
.election-overview-list li { display: contents; }
.election-overview-list li.eo-zero > * { opacity: .5; }
.eo-name { grid-column: 2; display: inline-flex; align-items: center; gap: 6px; font-weight: 600; min-width: 0; }
.eo-name > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.eo-meta { grid-column: 3; justify-self: end; display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; }
.eo-bar { grid-column: 1 / -1; margin-bottom: 9px; }
.election-overview-list li:last-child .eo-bar { margin-bottom: 0; }
.eo-bar .stat-row-track { height: 10px; }
.eo-votes { color: var(--text-muted); font-variant-numeric: tabular-nums; white-space: nowrap; }
.eo-mandates { font-weight: 600; color: var(--text-primary); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* /volby (election/index) – každá kandidátní listina má vlastní <table>.
   Pevný layout + shodné šířky sloupců přes <colgroup>, ať sloupce Výsledek
   a Přednostní hlasy sedí svisle napříč tabulkami pod sebou. Jméno bere
   zbytek šířky a dlouhé se ořízne elipsou. */
.election-list .data-table { table-layout: fixed; }
.election-list .data-table .election-votes { text-align: right; }
@media (max-width: 700px) {
  .election-list .data-table colgroup { display: none; }
  .election-list .data-table .election-votes { text-align: left; }
  .election-list .row-toggle { min-width: 44px; min-height: 44px; }
  .election-list td:has(.row-toggle) { cursor: pointer; }
}
.election-list .data-table col.c-poradi { width: 3.5em; }
.election-list .data-table col.c-vysledek { width: 10em; }
.election-list .data-table col.c-mandat { width: 5.5em; }
.election-list .data-table col.c-hlasy { width: 10.5em; }
.election-list .data-table td:nth-child(2) { overflow: hidden; text-overflow: ellipsis; }
/* Zvolení – velmi jemné zelenkavé podbarvení řádku (data-vysledek="0"
   z election/index, stabilní i po přeřazení tabulky přes sortable-table.js). */
.election-list .data-table tbody tr[data-vysledek="0"] { background: color-mix(in srgb, var(--status-good) 5%, transparent); }
.election-list .data-table tbody tr[data-vysledek="0"]:hover { background: color-mix(in srgb, var(--status-good) 6%, var(--grid)); }
/* Posun mandátu vs. pořadí na kandidátce – sloupec „Mandát" na /volby
   (election/index) i karta „Pořadí mandátu" na detailu osoby (person/show).
   Šipka + drobné číslo jen když se liší: zelená ↑ = posun nahoru přednostními
   hlasy, červená ↓ = předstižen níže postavenými. Čistí nezvolení: jen „—". */
.mandat-none { color: var(--text-muted); }
.mandat-jump { font-weight: 600; }
.mandat-jump.up { color: var(--status-good); }
.mandat-jump.down { color: var(--status-critical); }
/* Delta vedle Kandidátů/Mandátů ve sloupci obcí subjektu (subjekt/obce.
   blade.php $deltaBadge(), subjekt-obce.js deltaBadge()) – VŽDY vykreslený
   span (i beze změny, prázdný), `min-width` rezervuje stejné místo napříč
   řádky, ať badge nepřesouvá číslo (sloupec je `text-align:right` jako
   blok) podle toho, jestli tam je, nebo není. `.mandat-jump` (barva/tučně)
   se přidává jen když je vůbec co ukázat. */
.mandat-jump-slot { display: inline-block; min-width: 3.6em; text-align: left; padding-left: 4px; }
/* Počet míst posunu – drobně a nenápadně vedle šipky, dědí její barvu;
   směr určuje šipka, tady je jen počet míst. */
.mandat-delta { font-size: .72em; font-weight: 400; margin-left: 1px; }

.row-toggle {
  display: none;
  border: none;
  background: transparent;
  color: var(--text-muted);
  font-size: 11px;
  padding: 2px 4px;
  cursor: pointer;
  transition: transform .15s ease;
}

/* Pod 700px se tabulka rozpadne na stackovaný seznam – každý řádek je
   blok s hlavními sloupci (jméno, strana, docházka) vždy vidět; zbytek
   (Pro/Proti/Zdržel se/Omluven/Celkem) je schovaný za tlačítko rozbalení
   (stejný vizuální jazyk jako .meeting/.vote jinde v appce). */
@media (max-width: 700px) {
  .data-table thead { display: none; }
  .data-table, .data-table tbody, .data-table tr, .data-table td { display: block; width: 100%; }
  .data-table tbody tr { padding: 10px 14px; border-bottom: 1px solid var(--grid); }
  .data-table td {
    padding: 3px 0;
    border-bottom: none;
    white-space: normal;
  }
  /* Stackovaný řádek – číselné sloupce zpět doleva (jinak by hodnota
     odlétla k pravé hraně, pryč od svého „Label:" prefixu). */
  .data-table td.num { text-align: left; }
  .data-table td[data-label]::before {
    content: attr(data-label) ": ";
    color: var(--text-muted);
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .02em;
    margin-right: 4px;
  }
  .row-toggle { display: inline-block; }
  .data-table tr.expanded .row-toggle { transform: rotate(90deg); }
  .data-table td.td-secondary { display: none; }
  .data-table tr.expanded td.td-secondary { display: block; }
  /* Mobilní seznam zastupitelů: společná osa hodnot i po rozbalení. */
  .members-data-table td[data-label],
  .members-data-table tr.expanded td.td-secondary {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: baseline;
    column-gap: 12px;
    font-variant-numeric: tabular-nums;
  }
  .members-data-table td[data-label]::before { margin-right: 0; }
  .members-data-table td[data-label] > * { min-width: 0; justify-self: start; }
  .members-data-table td.td-secondary { display: none; }
}

/* --- Detail hlavičky (zastupitel, strana, zasedání, hlasování) --- */
.detail-title { display: flex; align-items: center; gap: 10px; min-width: 0; margin-bottom: 4px; }
.detail-title h1 { margin: 0; }
/* Tituly vedle jména (person/show) – tlumeně a bez tučného řezu h1, ať
   z nadpisu vystupuje samotné jméno. Stejná --text-secondary jako ostatní
   "o stupeň světlejší" text po appce (.meeting-date, breadcrumb apod.). */
.name-tituly { color: var(--text-secondary); font-weight: 400; }

/* Hlavní oddíly detailu osoby – "Ve volbách" (volební faseta) a
   "V zastupitelstvu" (hlasovací faseta). Výraznější než vnitřní h2
   (font-size:14px, např. "Historie hlasování") a s linkou nahoře, ať jsou
   obě části zřetelně oddělené i bez rámečku/panelu. */
.detail-section-title {
  margin: 30px 0 16px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
  font-size: 15px;
}

/* Hlavička sekce s štítkem zdroje vpravo nahoře (person/show, sekce "Ve
   volbách …") – oddělovací linka + odsazení přebírá wrapper, vnořený
   .detail-section-title je pak jen text. Na úzké obrazovce štítek spadne
   pod nadpis (flex-wrap). */
.detail-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px 16px;
  flex-wrap: wrap;
  margin: 30px 0 16px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}
.detail-section-head .detail-section-title { margin: 0; padding-top: 0; border-top: 0; }
.detail-section-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Aktivita po zasedáních (person/show) – samostatný proužek přes celou
   šířku pod hlavičkou, viditelný i na mobilu. Jedna buňka na zasedání
   grémia PŘES CELÉ volební období (vlevo nejstarší). overflow:hidden, ať
   u obcí s hodně zasedáními proužek nikdy nerozšíří stránku. */
.person-activity { margin: 0 0 18px; }
.person-activity-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 5px; }
.person-activity-caption { font-size: 11px; text-transform: uppercase; letter-spacing: .03em; color: var(--text-muted); }
.person-activity-legend { display: flex; gap: 10px; font-size: 11px; color: var(--text-muted); flex-wrap: wrap; }
.person-activity-legend .lg { display: inline-flex; align-items: center; gap: 4px; }
.person-activity-legend .sw { width: 9px; height: 9px; border-radius: 2px; display: inline-block; flex: none; }
.detail-activity { display: flex; gap: 2px; height: 10px; overflow: hidden; border-radius: 2px; }
.detail-activity .cell { flex: 1 1 0; min-width: 1px; border-radius: 2px; }
/* Proužek přes celou šířku + procento aktivní účasti vpravo, jako u
   "Složení hlasů" (.person-vote-summary .entity-attendance). */
.detail-activity-row { display: flex; align-items: center; gap: 8px; }
.detail-activity-row .detail-activity { flex: 1; }
.detail-activity-value { font-size: 12px; color: var(--text-secondary); font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Zelená = byl aktivní; červená = omluven (světlejší) / chyběl bez omluvy
   (plná); skoro průhledná šedá = mimo rozsah mandátu (nebyl členem).
   --status-good/-critical jako segmenty .bar (docházka). Selektory musí
   být scoped do .detail-activity / .person-activity-legend, jinak by je
   přebilo .detail-activity .cell (vyšší specificita) a proužek by byl celý
   šedý. */
.detail-activity .cell-aktivni,  .person-activity-legend .cell-aktivni  { background: var(--status-good); }
.detail-activity .cell-omluven,  .person-activity-legend .cell-omluven  { background: var(--status-critical); }
.detail-activity .cell-chybel,   .person-activity-legend .cell-chybel   { background: var(--status-critical); }
.detail-activity .cell-mimo,     .person-activity-legend .cell-mimo     { background: var(--status-muted); }
.detail-activity .cell-omluven { opacity: .5; }
.detail-activity .cell-mimo { opacity: .18; }
/* Vzorky v legendě čitelnější než tlumené buňky v proužku. */
.person-activity-legend .sw.cell-omluven { opacity: .8; }
.person-activity-legend .sw.cell-mimo { opacity: .5; }
/* Buňka pruhu = proklik na detail toho zasedání. */
.detail-activity a.cell { text-decoration: none; }
.detail-activity a.cell:hover { outline: 1px solid var(--text-primary); outline-offset: -1px; }
/* Hover/focus na položku legendy zvýrazní buňky daného stavu, ostatní ustoupí
   (public/js/person-summary.js toggluje .hl / .has-hl). Položky jsou
   tabindex="0" (klávesnice). */
.detail-activity.has-hl .cell { opacity: .12; }
.detail-activity.has-hl .cell.hl { opacity: 1; }
.person-activity-legend .lg, .person-vote-summary-legend .lg { transition: color .12s ease; cursor: default; }
.person-activity-legend .lg.hl, .person-vote-summary-legend .lg.hl { color: var(--text-primary); }
.person-activity-legend .lg:focus-visible, .person-vote-summary-legend .lg:focus-visible {
  outline: 2px solid var(--series-1); outline-offset: 2px; border-radius: 3px;
}

/* Souhrnný pruh složení hlasů (person/show) – nad kartami Pro/Proti/… jako
   jejich vizuální souhrn (proporce těch samých $counts, karty pod ním
   slouží i jako legenda). Přes celou šířku a viditelný i na mobilu (dřív
   byl vpravo od jména, max 420px, skrytý pod 700px – viz diskuze v hlavní
   konverzaci). Přes celou šířku obsahu, jako .summary-cards pod ním. */
.person-vote-summary { margin: 0 0 18px; }
/* Hlavička jako u .person-activity – popisek vlevo, legenda vpravo. */
.person-vote-summary-head { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 5px; }
.person-vote-summary-caption { font-size: 11px; text-transform: uppercase; letter-spacing: .03em; color: var(--text-muted); }
.person-vote-summary-legend { display: flex; gap: 10px; font-size: 11px; color: var(--text-muted); flex-wrap: wrap; }
.person-vote-summary-legend .lg { display: inline-flex; align-items: center; gap: 4px; }
.person-vote-summary-legend .sw { width: 9px; height: 9px; border-radius: 2px; display: inline-block; flex: none; }
.person-vote-summary-legend .sw.a { background: var(--status-good); }
.person-vote-summary-legend .sw.n { background: var(--status-critical); }
.person-vote-summary-legend .sw.z { background: var(--status-warning); }
.person-vote-summary-legend .sw.o { background: var(--status-muted); opacity: .5; }
.person-vote-summary-legend .sw.x { background: var(--status-muted); }
.person-vote-summary-legend .sw.u { background: var(--status-serious); }
.person-vote-summary .entity-attendance { display: flex; align-items: center; gap: 8px; width: 100%; }
.person-vote-summary .bar { flex: 1; width: auto; height: 10px; }
/* Plná sytost – .entity-attendance .bar span je jinde tlumené na .45 a
   rozsvítí se až na hoveru řádku (.entity-link); tady je pruh samostatný,
   ať drží sytost jako sousední .person-activity. */
.person-vote-summary .bar span { opacity: 1; transition: opacity .12s ease; }
/* Vzájemné zvýraznění pruh ↔ karta (public/js/person-summary.js) – hover na
   segment nebo kartu Pro/Proti/… rozsvítí protějšek (.hl), ostatní segmenty
   pruhu ustoupí. */
.person-vote-summary .bar.has-hl span:not(.hl) { opacity: .28; }
.person-vote-summary .bar span.hl { outline: 1px solid var(--text-primary); outline-offset: -1px; }

/* Souhrnné proužky na meeting/show – výsledky (schváleno/zamítnuto)
   a účast (přítomno/nepřítomno). 12px, plná šířka, legenda s tečkami;
   segmenty barví .bar .approved/.rejected/.a/.o. Účast + jmenný výčet
   nepřítomných dodává App\Support\CityStats::meetingAttendance. */
.mbar { margin: 0 0 24px; }
.mbar .bar { height: 12px; border-radius: 6px; max-width: none; }
/* Nepřítomno – červená (ne šedá jako .bar .o u docházky jinde). */
.mbar .bar .o { background: color-mix(in srgb, var(--status-critical) 82%, var(--surface-1)); opacity: 1; }
/* Výsledky: sytá .approved/.rejected = jednomyslně, světlejší varianta =
   s nesouhlasným rozhodným hlasem. */
.mbar .bar .approved-soft,
.mbar-legend .dot.approved-soft { background: color-mix(in srgb, var(--status-good) 42%, var(--surface-1)); }
.mbar .bar .rejected-soft,
.mbar-legend .dot.rejected-soft { background: color-mix(in srgb, var(--status-critical) 42%, var(--surface-1)); }
.mbar-legend {
  display: flex; flex-wrap: wrap; gap: 4px 16px; align-items: center;
  margin: 6px 0 0; font-size: 13px; color: var(--text-secondary);
}
.mbar-legend b { color: var(--text-primary); font-variant-numeric: tabular-nums; }
.mbar-legend .dot {
  display: inline-block; width: 9px; height: 9px; border-radius: 2px;
  margin-right: 6px;
}
.mbar-legend .dot.approved,
.mbar-legend .dot.a { background: var(--status-good); }
.mbar-legend .dot.rejected { background: var(--status-critical); }
.mbar-legend .dot.o { background: color-mix(in srgb, var(--status-critical) 82%, var(--surface-1)); }
.mbar-total { color: var(--text-muted); }

/* Přehled období na /hlasovani (meeting/index) – proužky (.mbar) nad
   toolbarem: orientace ve výsledcích celého volebního období. */
.meeting-overview { margin: 0 0 22px; }
.meeting-overview .mbar { margin: 0 0 12px; }
.meeting-overview .mbar:last-child { margin-bottom: 0; }

.attendance-absent {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin: 10px 0 0; font-size: 13px;
}
.attendance-absent-title {
  color: var(--text-muted); font-size: 11px; text-transform: uppercase; letter-spacing: .03em;
}
.attendance-chip {
  display: inline-flex; align-items: baseline;
  padding: 2px 9px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface-1);
  color: var(--text-secondary); text-decoration: none; white-space: nowrap;
}
.attendance-chip:hover { border-color: var(--series-1); color: var(--text-primary); }
/* Nepřítomen bez omluvy – žlutě přitónovaný chip (jako .klub-chip). */
.attendance-chip.bez-omluvy {
  border-color: color-mix(in srgb, var(--status-warning) 45%, var(--border));
  background: color-mix(in srgb, var(--status-warning) 12%, var(--surface-1));
  color: color-mix(in srgb, var(--status-warning) 55%, var(--text-primary));
}

.summary-cards { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 24px; }
.summary-card {
  flex: 1 1 130px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-1);
  padding: 12px 16px;
  transition: border-color .12s ease, background-color .12s ease;
}
.summary-card.hl { border-color: var(--series-1); background: color-mix(in srgb, var(--series-1) 8%, var(--surface-1)); }
/* Karty pod sebe na mobilu – bez tohohle `flex: 1 1 130px` výše na úzké
   obrazovce jen zalamovalo do nerovnoměrných řádků (2+1, 3+1…), ne čitelný
   sloupec (subjekt/show.blade.php, subjekt/obce.blade.php, subjekt/
   lide.blade.php, party/show.blade.php, person/show.blade.php, meeting/
   show.blade.php, election/index.blade.php, member/index.blade.php a
   další – všechny sdílejí tenhle základní `.summary-cards`, bez vlastního
   mobilního stylu). `.summary-cards-obec` (geo/show.blade.php, landing
   obce/kraje/…) má svůj vlastní 2sloupcový grid o pár řádků níž – jiná
   `display` na stejném breakpointu, `flex-direction` tam nemá efekt, obě
   pravidla si nepřekáží. */
@media (max-width: 640px) {
  .summary-cards { flex-direction: column; }
  .summary-card { flex: 1 1 auto; }
}
/* Karty na landing page obce (geo/show.blade.php) – strop 33 % šířky
   rodiče (.summary-cards), ne pevný px (zkoušeno dřív, viz diskuze v
   hlavní konverzaci – na širokých obrazovkách nechal karty zbytečně
   úzké/nevyplnil řádek). Prakticky se uplatní jen když se karty kvůli
   `flex-wrap` zalomí na méně než 3 v řádku (úzká obrazovka, nebo méně
   karet celkem) – při běžných 4 v řádku je jejich přirozená šířka pod
   33 % i tak. */
.summary-cards-obec .summary-card { max-width: 33%; }
@media (max-width: 640px) {
  .summary-cards-obec {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .summary-cards-obec .summary-card { min-width: 0; max-width: none; }
}
.summary-card-label { color: var(--text-muted); font-size: 11px; text-transform: uppercase; letter-spacing: .03em; margin-bottom: 4px; }
.summary-card-value {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 20px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.summary-card-icon { width: 18px; height: 18px; flex: none; fill: currentColor; color: var(--text-muted); opacity: .5; }
/* Proklik na hodnotu karty (landing page obce, viz geo/show.blade.php) –
   `.summary-card-value` je tam <a>, ne <div> jako jinde (member/index,
   party/show, meeting/show, vote/show, member/show) – scoped na `a.`, ať
   se ty ostatní stránky nezmění. Barva/podtržení reset (jinak by zdědilo
   výchozí modré podtržení prohlížeče), zvýraznění stejnou --series-1
   barvou jako .breadcrumb a/.entity-link při hoveru jinde v appce. */
a.summary-card-value { color: inherit; text-decoration: none; }
a.summary-card-value:hover { color: var(--series-1); }

/* Doplňkové řádky pod hlavní hodnotou karty (landing page obce, viz
   geo/show.blade.php) – muži/ženy, proužky (stran/schváleno-zamítnuto/
   pro-proti-zdržel se/muži-ženy), výčet zkratek stran, odkaz na poslední
   zasedání/hlasování. Každá karta jich může mít víc pod sebou (doplněk +
   proužek) – vlevo, stejné zarovnání jako zbytek karty. Pevná výška
   (20px) na každém z nich, ať sedí na stejné vertikální ose napříč
   kartami bez ohledu na to, že mají přirozeně různě vysoký obsah (ikony+
   text u .summary-card-gender/.summary-card-link, jen 8px u .bar uvnitř
   .summary-card-composition) – obsah se v rámci téhle výšky vystředí
   (align-items: center), místo aby zůstal přilepený nahoru. */
.summary-card-gender { display: flex; align-items: center; gap: 8px; height: 20px; margin-top: 8px; font-size: 13px; font-weight: 500; color: var(--text-muted); }
.summary-card-gender .summary-card-icon { width: 14px; height: 14px; }
.summary-card-composition { display: flex; align-items: center; height: 20px; margin-top: 8px; }
/* .bar je teď flex ITEM (uvnitř .summary-card-composition), ne přímé
   dítě bloku jako jinde (seat-bar/vote-tally/attendance) – bez `flex: 1`
   by se smrsknul na obsah (jeho vlastní děti mají `flex-basis: 0`, takže
   "obsah" je prakticky nulový) místo aby vyplnil celou šířku karty. */
.summary-card-composition .bar { flex: 1; }
/* Odkaz na poslední zasedání/hlasování (karty Zasedání/Hlasování). Barva/
   podtržení stejné jako .subtitle a (app.css) – tlumený, ne plnobarevný
   odkaz. Odkaz na hlasování nese název hlasování (predmet) – ten může být
   dlouhý, proto `min-width: 0` (flex item by se jinak odmítl zmenšit pod
   svůj obsah, stejný princip jako u .summary-card-composition .bar výše)
   + ellipsis, s plným zněním v `title` na <a> pro hover. */
.summary-card-link { display: flex; align-items: center; height: 20px; margin-top: 8px; font-size: 13px; font-weight: 500; }
.summary-card-link a {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text-secondary); text-decoration: underline; text-decoration-color: var(--border); text-underline-offset: 2px;
}
.summary-card-link a:hover { color: var(--text-primary); text-decoration-color: currentColor; }
/* Výčet zkratek stran s počtem (karta Politických subjektů) – prostý blok
   (ne flex jako výše), takže mu na zkrácení elipsou stačí jen
   overflow/white-space bez .summary-card-link's `min-width: 0` triku
   (žádný flex rodič, kterému by se musel bránit zmenšení). `line-height`
   místo `align-items: center` vystředí jednořádkový text v pevné výšce. */
.summary-card-list { height: 20px; line-height: 20px; margin-top: 8px; font-size: 13px; font-weight: 500; color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Proužky (.bar) mají konzistentní bublinu na hover i klik/dotyk napříč
   appkou – public/js/bar-tooltip.js prvek s popiskem označí [data-tip]
   (přesun z `title`). */
[data-tip] { cursor: help; }
[data-tip]:focus-visible { outline: 2px solid var(--series-1); outline-offset: 1px; }
/* Popup s popiskem – floating, mimo tok, polohuje ho JS. */
.bar-tip {
  position: absolute; z-index: 200; max-width: 260px;
  padding: 4px 8px; border-radius: 5px;
  background: var(--text-primary); color: var(--surface-1);
  font-size: 12px; line-height: 1.35; font-weight: 500;
  pointer-events: none; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
}

/* --- Historie hlasování zastupitele --- */
.vote-history { list-style: none; margin: 0; padding: 0; }
.vote-history-row {
  display: flex; align-items: center; gap: 8px 14px;
  padding: 9px 0; border-bottom: 1px solid var(--grid); font-size: 13px;
}
.vote-history-row:last-child { border-bottom: none; }
/* Zvýrazněná hlasování v accordionu: proti výsledku (červená, party-votes.js
   + person-votes.js), proti své straně (žlutá, jen person-votes.js), obojí
   = střídavé pruhy. Full-bleed přes celou šířku karty (uvnitř
   `#meetings .votes` s paddingem 16px → záporný okraj). */
.vote-history-row.proti-vetsine,
.vote-history-row.proti-strane,
.vote-history-row.nejednotne {
  margin: 0 -16px; padding-left: 13px; padding-right: 16px;
  border-left: 3px solid var(--status-critical);
}
/* Jen jedna barva → decentní podklad. Obojí (pruhy níže) je výraznější. */
.vote-history-row.proti-vetsine {
  background: color-mix(in srgb, var(--status-critical) 10%, var(--surface-1));
}
/* žlutá – person/show „proti straně", party/show „nejednotné" */
.vote-history-row.proti-strane,
.vote-history-row.nejednotne {
  border-left-color: var(--status-warning);
  background: color-mix(in srgb, var(--status-warning) 16%, var(--surface-1));
}
/* obojí → střídavé červeno-žluté pruhy, o něco silnější než jednobarevné */
.vote-history-row.proti-vetsine.proti-strane,
.vote-history-row.proti-vetsine.nejednotne {
  padding-left: 12px;
  border-left: 4px solid var(--status-critical);
  background: repeating-linear-gradient(45deg,
    color-mix(in srgb, var(--status-critical) 13%, var(--surface-1)) 0 11px,
    color-mix(in srgb, var(--status-warning) 19%, var(--surface-1)) 11px 22px);
}
.vote-history-date { color: var(--text-muted); white-space: nowrap; flex: none; width: 78px; }
.vote-history-meeting { color: var(--text-muted); white-space: nowrap; text-decoration: none; flex: none; }
.vote-history-meeting:hover { color: var(--text-primary); }
.vote-history-subject { flex: 1 1 auto; min-width: 0; color: var(--text-primary); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vote-history-subject:hover { text-decoration: underline; }

/* Agregovaný pruh hlasů subjektu na místě .tag jednoho zastupitele – viz
   partials/vote-tally-bar.blade.php, použité v historii hlasování na
   party/show.blade.php. */
.vote-tally { display: inline-flex; align-items: center; gap: 6px; flex: none; }
.vote-tally .bar { width: 56px; flex: none; }
.vote-tally-value {
  font-size: 12px;
  color: var(--text-secondary);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

@media (max-width: 720px) {
  h1 { font-size: 19px; }
  .meeting > summary { padding: 12px 14px 12px 28px; gap: 4px 10px; }
  .meeting > summary::before { left: 14px; }
  .meeting-diagrams { margin-left: 0; }
  .vote > summary, .vote-row {
    padding: 10px 14px 10px 28px;
    grid-template-columns: minmax(24px, auto) 1fr auto;
    grid-template-areas:
      "cislo predmet result"
      "bar   bar     bar";
  }
  .vote-row { padding: 10px 14px; }
  .vote > summary::before { left: 14px; }
  .vote-cislo { grid-area: cislo; }
  .vote-predmet { grid-area: predmet; }
  .vote-result { grid-area: result; }
  .bar { grid-area: bar; margin-top: 2px; }
  .deputies { padding: 4px 14px 14px 28px; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
}

@media (max-width: 640px) {
  .vote-history-row { flex-wrap: wrap; }
  .vote-history-subject { flex-basis: 100%; order: 1; white-space: normal; }
}

@media (max-width: 420px) {
  .vote-result { font-size: 11px; padding: 2px 6px; }
  .deputies { grid-template-columns: 1fr; }
}

/* --- Porovnání zastupitelů (member/compare.blade.php) – vzhled jako
   srovnání produktů v e-shopu: sloupec na osobu, řádky jsou atributy.
   Widget běží mimo .wrap (žádný max-width), ať využije celou šířku
   obrazovky; když se přesto nevejde, .compare-scroll scrolluje vodorovně
   a popiskový sloupec zůstává přilepený vlevo. */
.compare-widget { padding: 0 clamp(16px, 4vw, 40px) 60px; }
.compare-scroll {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 12px;
}
/* table-layout: fixed + shodné explicitní šířky sloupců (ne jen min-width)
   napříč OBĚMA tabulkami (atributy nahoře, hlasování dole) – jsou to dvě
   samostatné <table>, takže by se jinak sloupce (jeden na osobu) mezi
   nimi neseřadily pod sebe, i kdyby měly stejný min-width, protože každá
   tabulka si šířku počítá nezávisle podle vlastního obsahu. */
.compare-table { width: 100%; border-collapse: collapse; background: var(--surface-1); table-layout: fixed; }
.compare-table th, .compare-table td {
  padding: 12px 14px;
  border-bottom: 1px solid var(--grid);
  font-size: 13.5px;
  white-space: normal;
  overflow-wrap: break-word;
}
.compare-table tbody tr:last-child th, .compare-table tbody tr:last-child td { border-bottom: none; }
.compare-table tbody tr:nth-child(even) th, .compare-table tbody tr:nth-child(even) td {
  background: color-mix(in srgb, var(--grid) 35%, transparent);
}
.compare-row-label,
.compare-votes-subject-head {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--surface-1);
  color: var(--text-muted);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .03em;
  text-align: left;
  width: 230px;
  border-right: 1px solid var(--border);
}
.compare-table tbody tr:nth-child(even) .compare-row-label {
  background: color-mix(in srgb, var(--grid) 55%, var(--surface-1));
}
.compare-col, .compare-col-sm { width: 150px; text-align: center; }
/* vertical-align: top + .compare-col-header height:100% (buňky řádku jsou
   stejně vysoké) → avatary/tečky sedí v jedné řadě nahoře, jméno teče dolů
   a „Výchozí pro shodu" badge je přes margin-top:auto přišpendlený ke dnu
   VŠECH sloupců stejně (i skrytý v ostatních drží stejné místo). Bez toho
   měl referenční sloupec badge na jiné výšce podle délky jména. */
.compare-col { vertical-align: top; padding-bottom: 18px; position: relative; }
.compare-table td { text-align: center; }
.compare-col-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  height: 100%;
  text-decoration: none;
  color: var(--text-primary);
}
.compare-col-header:hover .compare-col-name { text-decoration: underline; }
/* Křížek pro odebrání sloupce ze srovnání (zastupitel / subjekt) – vidět jen
   při hoveru nad sloupcem, klik naviguje na stejnou stránku s ?id= bez dané
   položky (viz compare.js / party-compare.js). */
.compare-remove-col {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 20px;
  height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface-1);
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1;
  padding: 0;
  cursor: pointer;
  opacity: 0;
  transform: scale(.85);
  transition: opacity .12s, transform .12s, background .12s, color .12s, border-color .12s;
}
.compare-col:hover .compare-remove-col,
.compare-remove-col:focus-visible { opacity: 1; transform: scale(1); }
.compare-remove-col:hover { background: var(--status-critical); border-color: var(--status-critical); color: #fff; }
.compare-col-name { font-weight: 700; font-size: 15px; white-space: normal; }
.compare-party { display: inline-flex; align-items: center; gap: 6px; color: var(--text-primary); text-decoration: none; white-space: normal; }
.compare-party:hover { text-decoration: underline; }
.compare-table .entity-attendance { justify-content: center; }

/* Sloupec prvního vybraného zastupitele – referenční pro řádek „Shoda
   hlasování" níže, mírně odlišený jemným podbarvením a horní linkou. */
.compare-col-reference { background: color-mix(in srgb, var(--series-1) 7%, transparent); }
th.compare-col-reference { box-shadow: inset 0 2px 0 var(--series-1); }
.compare-col-ref-badge {
  /* margin-top:auto přišpendlí badge ke dnu .compare-col-header (height:100%)
     – u všech sloupců na stejné výšce bez ohledu na délku jména nad ním. */
  margin-top: auto;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .03em;
  color: var(--series-1);
}
/* Skrytý, ale místo si drží ve všech sloupcích stejné (jinak by badge jen
   u prvního sloupce posunul fotku/jméno mimo vertikální zarovnání se
   zbytkem řádku hlaviček). */
.compare-col-ref-badge-hidden { visibility: hidden; }

@media (max-width: 640px) {
  .compare-row-label, .compare-votes-subject-head { width: 150px; font-size: 10px; }
  .compare-col, .compare-col-sm { width: 110px; }
  .compare-table th, .compare-table td { padding: 8px 10px; }
  /* Na úzkém sloupci se vedle tagu proužek nevejde – jen tag. */
  .compare-blok-bar { display: none; }
}

/* --- Tabulka jednotlivých hlasování (member/compare.blade.php) – sloupec
   „Bod jednání" nese roli sticky popiskového sloupce, šířka sdílená s
   .compare-row-label výše (viz pravidlo nahoře), jen s odkazy/datem
   uvnitř. Sloupcová šířka pro celou tabulku se v table-layout:fixed bere
   z prvního řádku (thead .compare-votes-subject-head), takže tahle .td
   třída už žádnou vlastní šířku nastavovat nemá – jen vzhled. */
.compare-col-sm { font-size: 12.5px; font-weight: 600; }
/* Předmět + zasedání/datum vedle sebe na jednom řádku (flex), místo
   předchozího "predmět nad, meta pod" stacku, který dělal z každého řádku
   tabulky dvě řádky textu. Předmět (.compare-votes-predmet) se zkracuje
   elipsou jako první – má flex:1/min-width:0 – meta (číslo zasedání +
   datum) je flex:none, zůstává vždy celá čitelná. Plný text předmětu je v
   title atributu na <td> pro případ, že se zkrátí. */
.compare-votes-subject {
  position: sticky;
  left: 0;
  z-index: 1;
  background: var(--surface-1);
  text-align: left;
  border-right: 1px solid var(--border);
  display: flex;
  align-items: baseline;
  gap: 6px;
  white-space: nowrap;
  overflow: hidden;
}
.compare-table tbody tr:nth-child(even) .compare-votes-subject {
  background: color-mix(in srgb, var(--grid) 55%, var(--surface-1));
}
/* Řádek, kde se blokový hlas vybraných subjektů lišil (data-diff="1",
   party/compare) – jemně teplé pozadí i pod sticky sloupcem „Bod jednání",
   ať v dlouhé tabulce vynikne. Zebra se pod tím ještě lehce prosadí. */
.compare-votes-table tbody tr[data-diff="1"] td,
.compare-votes-table tbody tr[data-diff="1"] .compare-votes-subject {
  background: color-mix(in srgb, var(--status-warning) 9%, var(--surface-1));
}
.compare-votes-table tbody tr[data-diff="1"]:nth-child(even) td,
.compare-votes-table tbody tr[data-diff="1"]:nth-child(even) .compare-votes-subject {
  background: color-mix(in srgb, var(--status-warning) 9%, color-mix(in srgb, var(--grid) 55%, var(--surface-1)));
}
.compare-votes-predmet {
  min-width: 0;
  flex: 1 1 auto;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text-primary);
  text-decoration: none;
  font-size: 13px;
}
.compare-votes-predmet:hover { text-decoration: underline; }
.compare-votes-meta { flex: none; color: var(--text-muted); font-size: 11px; }
.compare-votes-meta a { color: var(--text-muted); text-decoration: none; }
.compare-votes-meta a:hover { text-decoration: underline; }
.compare-votes-na { color: var(--text-muted); }
/* Buňka v tabulce hlasování srovnání subjektů (party/compare) – tag
   blokového hlasu + malý proužek rozložení hlasů členů subjektu (segmenty
   .bar .a/.n/.z/.o/.x/.u jako jinde). `title` je na .compare-blok wrapperu,
   který obaluje .bar → bar-tooltip.js z něj udělá .bar-tip bublinu. */
.compare-blok { display: inline-flex; align-items: center; gap: 6px; }
.compare-blok-bar { width: 40px; height: 8px; flex: none; }
/* Klub měl v hlasování jen O/X – žádný rozhodný hlas (odlišné od „?" =
   rozhodné hlasy bez převahy). */
.compare-blok-none { color: var(--text-muted); font-weight: 600; }
/* Placeholder v řádku „Shoda hlasování", než ho compare.js doplní z
   member.compare.votes (agreement přes celou množinu). */
.compare-shoda-loading { color: var(--text-muted); }
#diff-toggle { margin-left: 4px; }

/* Znovupoužitelný <details>/<summary> dropdown (filtr zasedání i výběr
   zastupitelů ke srovnání) – plovoucí panel se seznamem checkboxů. */
.dropdown { position: relative; }
.dropdown-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--border);
  background: var(--surface-1);
  color: var(--text-secondary);
  font-size: 13px;
  padding: 8px 14px;
  border-radius: 8px;
  cursor: pointer;
  list-style: none;
  user-select: none;
  white-space: nowrap;
}

.dropdown-toggle::-webkit-details-marker { display: none; }
.dropdown-toggle::after {
  content: '';
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg);
  margin-top: -3px;
}
.dropdown-toggle:hover,
.dropdown[open] .dropdown-toggle { border-color: var(--series-1); color: var(--text-primary); }
.dropdown-count {
  display: none;
  background: var(--series-1);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 1;
  padding: 3px 6px;
  border-radius: 999px;
}
.dropdown-count.visible { display: inline-block; }
.dropdown-panel {
  position: absolute;
  /* Leafletovy vlastní panes (dlaždice/markery/popupy) běží na z-index
     200–700 (viz geo/regiony.blade.php mapa) a nejsou uvnitř stacking
     kontextu téhle stránky, takže bez dostatečně vysoké hodnoty prosvítaly
     nad rozbaleným panelem. */
  z-index: 1000;
  top: calc(100% + 6px);
  left: 0;
  min-width: 260px;
  max-height: 320px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--surface-1);
  box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
  padding: 6px;
}
.dropdown-item {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 7px 8px;
  border: none;
  border-radius: 6px;
  background: none;
  font-size: 13px;
  font-family: inherit;
  text-align: left;
  color: var(--text-secondary);
  cursor: pointer;
  white-space: nowrap;
}
.dropdown-item:hover { background: var(--grid); color: var(--text-primary); }
.dropdown-item input { accent-color: var(--series-1); }
.dropdown-clear {
  display: block;
  width: 100%;
  text-align: left;
  margin-top: 4px;
  padding: 8px;
  border: none;
  border-top: 1px solid var(--border);
  background: none;
  color: var(--text-muted);
  font-size: 12px;
  cursor: pointer;
}
.dropdown-clear:hover { color: var(--text-primary); }
.member-picker .dropdown-panel { max-height: 360px; }

/* --- Celostátní profil politického subjektu (subjekt/index + subjekt/show) --- */
/* Chip členské/koaliční strany – proklik na její vlastní profil. */
.subjekt-slozeni { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin: 4px 0 0; font-size: 13px; }
.subjekt-slozeni-label { color: var(--text-muted); }
.subjekt-chip {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border: 1px solid var(--border); border-radius: 999px;
  color: var(--text-primary); text-decoration: none; white-space: nowrap;
}
.subjekt-chip:hover { background: var(--grid); }

/* Strom subjektu pod h1 na party/show – kořen (celostátní strana/koalice)
   + větve (členské subjekty). Jemné: menší než h1, tlumené, tenká větvení. */
.subjekt-strom { margin: 5px 0 0; font-size: 12.5px; line-height: 1.6; color: var(--text-secondary); overflow-x: auto; }
.subjekt-strom a { color: var(--text-secondary); text-decoration: none; }
.subjekt-strom a:hover { color: var(--text-primary); text-decoration: underline; }
.subjekt-strom .ss-root { display: flex; align-items: center; gap: 6px; }
.subjekt-strom .ss-note { color: var(--text-muted); font-size: 11px; }
.subjekt-strom .ss-child { display: flex; align-items: center; gap: 6px; padding-left: 1.5em; }
.subjekt-strom .ss-child-2 { padding-left: 3.2em; color: var(--text-muted); }  /* členové uskupení (subjekt/uskupeni) */
.subjekt-strom .ss-branch { color: var(--text-muted); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; flex: none; }
.subjekt-strom .color-dot { width: 9px; height: 9px; }

/* Sbalit/rozbalit větev – klik na spoj (├─ + šipka), sdílené „Složení" i „Větvení". */
.subjekt-strom .ss-toggle {
  border: 0; background: none; padding: 0; margin: 0; cursor: pointer; flex: none;
  font: inherit; color: var(--text-muted);
  display: inline-flex; align-items: center; gap: 3px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.subjekt-strom .ss-toggle:hover { color: var(--text-primary); }
.subjekt-strom .ss-caret { font-size: 9px; line-height: 1; transition: transform .12s ease; }
.subjekt-strom .ss-node.is-collapsed > * > .ss-toggle .ss-caret { transform: rotate(-90deg); }
.subjekt-strom .ss-node.is-collapsed > .ss-kids { display: none; }
/* Sbalit/rozbalit vše – malé „chip" tlačítka, ať se nepletou s popiskem
   (.stats-block-note) nad stromem. */
.ss-controls { display: flex; gap: 6px; margin: 2px 0 10px; }
.ss-all {
  border: 1px solid var(--border); border-radius: 999px;
  background: var(--surface-1); padding: 3px 10px; cursor: pointer;
  font: inherit; font-size: 11px; line-height: 1.5; color: var(--text-secondary);
}
.ss-all:hover { color: var(--text-primary); border-color: var(--text-muted); }

/* Větvení (subjekt/uskupeni) – prefixový strom, odsazení dělá vnořený .ss-kids. */
.subjekt-strom-prefix .ss-row { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 6px; }
.subjekt-strom-prefix .ss-kids { padding-left: 1.4em; }
.subjekt-strom-prefix .ss-plus { color: var(--text-muted); font-weight: 600; flex: none; }
.subjekt-strom-prefix .ss-leaf { color: var(--text-muted); }
.subjekt-strom-prefix .ss-leaf a { color: var(--text-secondary); }
.subjekt-strom-prefix .ss-leaf .ss-note { margin-left: 2px; }

/* „S kým subjekt kandidoval" – žebříček spoluspojenců (subjekt/uskupeni),
   proužek/výplň sdílený s appkou (.stat-row-track/.fill). */
.partner-list { display: flex; flex-direction: column; gap: 8px; margin: 6px 0 24px; }
.partner-row { display: grid; grid-template-columns: minmax(110px, 210px) 1fr auto; align-items: center; gap: 12px; font-size: 13px; }
.partner-name { min-width: 0; display: inline-flex; align-items: center; gap: 6px; color: var(--text-primary); text-decoration: none; }
.partner-name > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.partner-name:hover { color: var(--series-1); }
.partner-row .stat-row-track { display: block; height: 10px; }
.partner-count { color: var(--text-muted); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Chvost žebříčku / stromu (položky nad limitem) – skrytý, dokud se
   nerozbalí tlačítkem .list-more. */
.partner-row.is-extra { display: none; }
.partner-list.is-open .partner-row.is-extra { display: grid; }
.subjekt-strom .is-extra { display: none; }
.subjekt-strom.is-open .is-extra { display: block; }  /* .is-extra je na .ss-node (blok), ne na řádku */
.list-more {
  border: 0; background: none; padding: 4px 0; margin: 4px 0 24px; cursor: pointer;
  font: inherit; font-size: 12px; color: var(--text-muted);
}
.list-more:hover { color: var(--text-primary); }
.partner-list:has(+ .list-more) { margin-bottom: 6px; }
@media (max-width: 520px) {
  /* Název vlevo + „n×" vpravo na jednom řádku, proužek přes celou šířku pod nimi. */
  .partner-row { grid-template-columns: 1fr auto; row-gap: 5px; }
  .partner-name { grid-column: 1; grid-row: 1; }
  .partner-count { grid-column: 2; grid-row: 1; justify-self: end; }
  .partner-row .stat-row-track { grid-column: 1 / -1; grid-row: 2; }
}

/* „Podle typu voleb" – komunál naplněný, ostatní placeholder. Bez řádkových
   linek a bez „·" oddělovačů – klidný seznam jako .subjekt-partneri. */
.subjekt-volby-typy { list-style: none; margin: 6px 0 4px; padding: 0; }
.subjekt-volby-typy li {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px;
  padding: 5px 0;
}
.svt-name { font-weight: 600; }
.svt-note { color: var(--text-secondary); font-size: 13px; display: inline-flex; flex-wrap: wrap; gap: 2px 12px; }
.svt-todo { color: var(--text-muted); font-style: italic; }

/* ── Landing subjektu (subjekt/show) – dashboard shrnující ostatní sekce ──
   Graf „Vývoj napříč volbami" recykluje .mandate-chart / .mandate-col
   (definice výše), vlastní má jen wrapper kvůli odsazení. */
.subjekt-vyvoj { margin: 4px 0 10px; }

/* Žebříček krajů podle mandátů (blok „Kde má zastoupení"). */
.subjekt-kraje { list-style: none; margin: 6px 0 4px; padding: 0; }
.skr-row {
  display: grid;
  grid-template-columns: minmax(120px, 190px) 1fr auto;
  align-items: center; gap: 10px;
  padding: 5px 0; border-bottom: 1px solid var(--grid);
}
.skr-row:last-child { border-bottom: none; }
.skr-name {
  color: var(--text-primary); text-decoration: none; font-weight: 600; font-size: 13px;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.skr-name:hover { text-decoration: underline; }
.skr-track { display: flex; height: 10px; border-radius: 3px; background: var(--grid); overflow: hidden; }
/* Vlastní mandáty modře (--series-1); zelený segment (--series-3) přibude jen
   při „Započítat i uskupení" (subjekt/show – renderKraje()), jinak má šířku 0. */
.skr-fill { height: 100%; background: var(--series-1); }
.skr-fill-usk { height: 100%; background: var(--series-3); }
.skr-num { font-size: 12px; font-variant-numeric: tabular-nums; color: var(--text-secondary); white-space: nowrap; }
.skr-unit { color: var(--text-muted); }
/* Žebříček „Dominantní subjekty": pevná šířka pravého sloupce, ať 1fr
   proužku je na všech řádcích stejný (jinak delší číslo zkrátí proužek). */
#dominant-list .skr-num { width: 10.5em; text-align: right; }
@media (max-width: 560px) {
  .skr-row { grid-template-columns: 1fr auto; }
  .skr-track { grid-column: 1 / -1; order: 3; }
}

/* Dělený pruh poměrů (subjekt/partials/rejstrik-stats – „Podle typu
   subjektu"): jeden vodorovný pruh rozdělený na segmenty, přepínač metriky
   nad ním jen mění šířky segmentů (skript v subjekt/index.blade.php). */
.split-bar {
  display: flex; height: 22px; border-radius: 4px;
  background: var(--grid); overflow: hidden; margin: 2px 0 0;
}
.split-seg { height: 100%; min-width: 0; transition: flex-basis .25s ease; }
.split-legend {
  list-style: none; display: flex; flex-wrap: wrap; gap: 6px 16px;
  margin: 8px 0 0; padding: 0; font-size: 12.5px; color: var(--text-secondary);
}
.split-legend li { display: flex; align-items: baseline; gap: 6px; }
.split-dot { width: 10px; height: 10px; border-radius: 2px; flex: none; align-self: center; }
.split-legend-val { color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* „Dominantní subjekty" – kontejner pro treemap / bubliny / pareto (SVG,
   kreslí subjekty-dominant.js) a waffle (grid). Treemap/pareto/waffle
   jdou přes celou šířku, bubliny jsou malé a na střed. */
.dominant-viz { margin: 2px 0 0; }
/* Treemap i pareto berou plnou šířku, waffle taky; bubliny si přes inline
   max-width samy zmenší a `margin:0 auto` je vycentruje. Výšku všech
   omezuje skript přes viewBox. */
.dominant-viz svg { width: 100%; height: auto; display: block; margin: 0 auto; }
.dominant-viz svg a { cursor: pointer; }
.dominant-viz svg a:hover rect,
.dominant-viz svg a:hover circle { filter: brightness(1.08); }
.waffle { display: grid; grid-template-columns: repeat(50, 1fr); gap: 2px; width: 100%; }
/* Obal běhu políček jedné strany – bez vlastního boxu, políčka tak zůstanou
   přímo v gridu (viz subjekty-dominant.js renderWaffle). Celý běh je proklik
   na profil + jeden cíl pro bublinu. */
.waffle-group { display: contents; }
.waffle-group:hover .waffle-cell,
.waffle-group:focus-visible .waffle-cell { filter: brightness(1.15); }
a.waffle-group { cursor: pointer; }
.waffle-cell { aspect-ratio: 1; border-radius: 1px; }

/* Náhled povolání zvolených – read-only obdoba partials/subjekt-povolani-bar.
   Segment pruhu i položka legendy jsou <a> na /lide?kategorie=<token>
   (proklik předvyplní filtr povolání). Sdílí .pk-bar* třídy z app.css. */
.pk-bar-static { display: block; }
.pk-bar-static .pk-seg,
.pk-bar-static .pk-leg { text-decoration: none; color: inherit; }
.pk-bar-static .pk-bar-legend li { display: flex; align-items: center; font-size: 11px; color: var(--text-muted); }
.pk-bar-static .pk-leg-name { color: var(--text-secondary); }
.pk-bar-static .pk-leg-pct { margin-left: 2px; font-variant-numeric: tabular-nums; }

/* Partneři v uskupeních (blok „Uskupení"). */
.subjekt-partneri { list-style: none; margin: 6px 0 4px; padding: 0; font-size: 13px; }
.subjekt-partneri li { display: flex; align-items: center; gap: 7px; padding: 4px 0; }
.subjekt-partneri a { color: var(--text-primary); text-decoration: none; font-weight: 600; }
.subjekt-partneri a:hover { text-decoration: underline; }
.subjekt-partneri-note { color: var(--text-muted); font-size: 12px; }

/* Grafický seznam náhradníků na party/show (partials/nahradnici-list) –
   mřížka řádků: kolečko s pořadím nástupu · jméno · přednostní hlasy. */
.nahradnici-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 4px 20px;
}
.nahradnici-list li { display: flex; align-items: center; gap: 9px; padding: 3px 0; min-width: 0; }
.nahradnici-poradi {
  flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--grid); color: var(--text-secondary);
  font-size: 11px; font-weight: 700; font-variant-numeric: tabular-nums;
}
.nahradnici-jmeno { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nahradnici-jmeno a { color: var(--text-primary); text-decoration: none; }
.nahradnici-jmeno a:hover { text-decoration: underline; }
.nahradnici-hlasy {
  flex: none; margin-left: auto; padding-left: 8px;
  color: var(--text-muted); font-size: 12px; font-variant-numeric: tabular-nums;
}
