/* Zensus -- design tokens and layout.
 *
 * Two palettes here, and they answer to different masters.
 *
 * The interface palette is a warm neutral grey ramp with one accent, chosen so
 * that nothing in the chrome competes with the data. Every colour is declared
 * once on :root in light, and re-declared for dark under both the media query
 * and the [data-theme] attribute, so the toggle wins in either direction.
 *
 * The party palette is not chosen at all. Green for the Grünen and red for the
 * SPD are what every German reader already knows, and a "better" palette would
 * make these charts harder to read, not easier. So the hues are fixed by
 * convention and only the lightness is picked -- one step per surface, so that
 * the Union's conventional black stays visible on a dark background and the
 * FDP's conventional yellow stays legible on a light one. Those live in
 * data/parties.py, because the same two values are wanted by anything that
 * renders this data, and arrive here as inline custom properties.
 */

:root {
  color-scheme: light;

  --surface-0: #f7f6f3;   /* page */
  --surface-1: #fffefb;   /* cards, chart ground */
  --surface-2: #efeee9;   /* inset wells, table stripes */
  --surface-3: #e4e2db;   /* track of a slider */

  --line:      #d9d7cf;
  --line-soft: #e8e6df;

  --ink:       #17161a;
  --ink-2:     #4e4c52;
  --ink-3:     #78757e;

  --accent:    #1d5fa8;
  --accent-2:  #e7eefa;
  --warn:      #9a5b00;

  --radius: 10px;
  --radius-sm: 6px;
  --gap: 16px;

  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Inter, Roboto,
          "Helvetica Neue", Arial, sans-serif;

  --shadow: 0 1px 2px rgba(20, 18, 14, .06), 0 4px 16px rgba(20, 18, 14, .05);
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --surface-0: #121214;
    --surface-1: #1b1b1e;
    --surface-2: #232327;
    --surface-3: #2e2e33;
    --line:      #34343a;
    --line-soft: #26262b;
    --ink:       #f4f3f0;
    --ink-2:     #b9b7b2;
    --ink-3:     #8a888a;
    --accent:    #79aeee;
    --accent-2:  #1c2b3e;
    --warn:      #e0a94a;
    --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 16px rgba(0, 0, 0, .3);
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --surface-0: #121214;
  --surface-1: #1b1b1e;
  --surface-2: #232327;
  --surface-3: #2e2e33;
  --line:      #34343a;
  --line-soft: #26262b;
  --ink:       #f4f3f0;
  --ink-2:     #b9b7b2;
  --ink-3:     #8a888a;
  --accent:    #79aeee;
  --accent-2:  #1c2b3e;
  --warn:      #e0a94a;
  --shadow: 0 1px 2px rgba(0, 0, 0, .4), 0 4px 16px rgba(0, 0, 0, .3);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.5;
  color: var(--ink);
  background: var(--surface-0);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { margin: 0; font-weight: 600; letter-spacing: -0.01em; }
h1 { font-size: 19px; }
h2 { font-size: 15px; }
h3 { font-size: 13px; }
p  { margin: 0 0 10px; }
a  { color: var(--accent); }

.num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* ------------------------------------------------------------------ chrome -- */

.topbar {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: 14px;
  padding: 10px 20px;
  background: color-mix(in srgb, var(--surface-1) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}
.brand { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.brand strong { font-size: 18px; letter-spacing: -0.02em; }
.brand span { color: var(--ink-3); font-size: 13px; }
.topbar .spacer { flex: 1; }

.btn {
  font: inherit; font-size: 13px;
  padding: 6px 11px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-1);
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover { background: var(--surface-2); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.btn.primary {
  background: var(--accent); border-color: var(--accent);
  /* The accent lightens in dark mode, so the text on it has to darken with it
     or the button loses its contrast exactly where it is most prominent. */
  color: var(--surface-1);
}
.btn.primary:hover { filter: brightness(1.08); }
.btn.small { padding: 3px 8px; font-size: 12px; }
.btn[aria-pressed="true"] { background: var(--accent-2); border-color: var(--accent); }
.btn:disabled { opacity: .5; cursor: default; }

/* ------------------------------------------------------------------ layout -- */

.wrap { max-width: 1520px; margin: 0 auto; padding: var(--gap); }

/* Three panes -- pick the elections, set the quota, read the result -- laid out
   side by side when there is room. Below 1500px the first two stack into one
   column, which is why they are placed explicitly rather than left to grid
   auto-flow: the results pane has to span both rows, and auto-flow would put
   it underneath instead. */
.columns {
  display: grid;
  grid-template-columns: minmax(320px, 380px) minmax(0, 1fr);
  gap: var(--gap);
  align-items: start;
}
#colSelection { grid-column: 1; grid-row: 1; }
#colQuota     { grid-column: 1; grid-row: 2; }
#colResults   { grid-column: 2; grid-row: 1 / span 2; }

@media (min-width: 1500px) {
  .columns { grid-template-columns: 310px 330px minmax(0, 1fr); }
  #colQuota   { grid-column: 2; grid-row: 1; }
  #colResults { grid-column: 3; grid-row: 1; }
}
@media (max-width: 1080px) {
  .columns { grid-template-columns: 1fr; }
  #colSelection, #colQuota, #colResults { grid-column: 1; grid-row: auto; }
}

.card {
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  margin-bottom: var(--gap);
}
.card > header {
  display: flex; align-items: center; gap: 10px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--line-soft);
}
.card > header .spacer { flex: 1; }
.card > .body { padding: 14px; }
.card > .body.tight { padding: 10px 14px 14px; }

.hint { color: var(--ink-3); font-size: 12.5px; line-height: 1.45; }
.hint.block { margin-top: 8px; }

.field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; }
.field > label { font-size: 12px; color: var(--ink-2); font-weight: 500; }
select, input[type="number"], input[type="search"] {
  font: inherit; font-size: 13px;
  padding: 5px 8px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface-1);
  color: var(--ink);
  width: 100%;
}
.row { display: flex; gap: 8px; align-items: center; }
.row.wrap { flex-wrap: wrap; }

/* chips ------------------------------------------------------------------- */

.chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chip {
  font-size: 12px; padding: 3px 8px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface-1); color: var(--ink-2);
  cursor: pointer; user-select: none;
}
.chip[aria-pressed="true"] {
  background: var(--accent-2); border-color: var(--accent); color: var(--ink);
}

/* election list ------------------------------------------------------------ */

.electionlist {
  max-height: 260px; overflow-y: auto;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-1);
}
.electionlist label {
  display: grid; grid-template-columns: 18px 1fr auto;
  gap: 8px; align-items: center;
  padding: 4px 9px; font-size: 12.5px; cursor: pointer;
  border-bottom: 1px solid var(--line-soft);
}
.electionlist label:last-child { border-bottom: 0; }
.electionlist label:hover { background: var(--surface-2); }
.electionlist .when { color: var(--ink-3); font-size: 11.5px; }
.electionlist input { margin: 0; }

/* quota sliders ------------------------------------------------------------ */

.dim { border-top: 1px solid var(--line-soft); padding: 11px 14px; }
.dim:first-of-type { border-top: 0; }
.dim > .head { display: flex; align-items: center; gap: 8px; margin-bottom: 2px; }
.dim > .head h3 { flex: 0 0 auto; }
.dim > .head .spacer { flex: 1; }
.tag {
  font-size: 10.5px; letter-spacing: .03em; text-transform: uppercase;
  padding: 1px 6px; border-radius: 999px;
  border: 1px solid var(--line); color: var(--ink-3);
}
.tag.measured { border-color: color-mix(in srgb, var(--accent) 45%, var(--line)); color: var(--accent); }
.dim .unit { font-size: 11.5px; color: var(--ink-3); margin-bottom: 8px; }

.group { display: grid; grid-template-columns: 1fr; gap: 1px; margin-bottom: 7px; }
.group .top {
  display: flex; align-items: baseline; gap: 6px;
  font-size: 12px; color: var(--ink-2);
}
.group .top .spacer { flex: 1; }
.group .top .val { font-weight: 600; color: var(--ink); }
.group .top .delta { font-size: 11px; color: var(--ink-3); min-width: 44px; text-align: right; }
.group .top .delta.up { color: #1a7a3c; }
.group .top .delta.down { color: #a33; }
:root[data-theme="dark"] .group .top .delta.up { color: #64c98a; }
:root[data-theme="dark"] .group .top .delta.down { color: #e88; }

/* A range input with a tick showing the real share, drawn behind the thumb. */
.slider { position: relative; height: 18px; }
.slider input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 18px; margin: 0; background: transparent; cursor: pointer;
  position: relative; z-index: 2;
}
.slider input[type="range"]::-webkit-slider-runnable-track {
  height: 5px; border-radius: 3px; background: var(--surface-3);
}
.slider input[type="range"]::-moz-range-track {
  height: 5px; border-radius: 3px; background: var(--surface-3);
}
.slider input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 13px; height: 13px; margin-top: -4px;
  border-radius: 50%; background: var(--accent);
  border: 2px solid var(--surface-1);
}
.slider input[type="range"]::-moz-range-thumb {
  width: 13px; height: 13px; border-radius: 50%;
  background: var(--accent); border: 2px solid var(--surface-1);
}
.slider .basemark {
  position: absolute; top: 3px; width: 2px; height: 11px;
  background: var(--ink-3); opacity: .55; border-radius: 1px; z-index: 1;
  transform: translateX(-1px); pointer-events: none;
}
.dim.free .slider input[type="range"]::-webkit-slider-thumb { background: var(--ink-3); }
.dim.free .slider input[type="range"]::-moz-range-thumb { background: var(--ink-3); }

/* charts ------------------------------------------------------------------- */

.chart { width: 100%; display: block; }
.chart text { font-family: var(--sans); fill: var(--ink-2); }
.chart .axis line, .chart .axis path { stroke: var(--line); }
.chart .grid line { stroke: var(--line-soft); }
.chart .label { fill: var(--ink); font-size: 12px; }
.chart .value { fill: var(--ink); font-size: 12px; font-weight: 600; }
.chart .muted { fill: var(--ink-3); font-size: 11px; }
.chart .bar { transition: width .18s ease, x .18s ease; }
.chart .actualtick { stroke: var(--ink); stroke-width: 2; opacity: .75; }
.chart .hit { fill: transparent; cursor: default; }
.chart .hit:hover + .hl, .chart g.row:hover .hl { opacity: 1; }
.chart .hl { fill: var(--ink); opacity: 0; pointer-events: none; }

.legend { display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 8px; font-size: 12px; color: var(--ink-2); }
.legend .item { display: flex; align-items: center; gap: 5px; }
.legend .swatch { width: 10px; height: 10px; border-radius: 2px; flex: none; }
.legend .tickmark { width: 2px; height: 11px; background: var(--ink); opacity: .75; }

.ribbon { display: block; width: 100%; }
.majority { font-size: 12.5px; color: var(--ink-2); margin-top: 8px; }
.majority b { color: var(--ink); }

/* tables ------------------------------------------------------------------- */

table.data { border-collapse: collapse; width: 100%; font-size: 12.5px; }
table.data th, table.data td {
  padding: 5px 8px; text-align: right; border-bottom: 1px solid var(--line-soft);
  white-space: nowrap;
}
table.data th:first-child, table.data td:first-child { text-align: left; }
table.data thead th { color: var(--ink-2); font-weight: 600; font-size: 11.5px; }
table.data tbody tr:hover { background: var(--surface-2); }
table.data .cellbar {
  display: inline-block; height: 9px; border-radius: 2px; vertical-align: -1px;
  margin-right: 5px; min-width: 2px;
}
.scroll-x { overflow-x: auto; }

/* misc --------------------------------------------------------------------- */

.notice {
  display: flex; gap: 8px; align-items: flex-start;
  font-size: 12.5px; color: var(--ink-2);
  background: var(--surface-2);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  padding: 8px 10px; margin-bottom: 12px;
}
.notice.warn { border-color: color-mix(in srgb, var(--warn) 40%, var(--line)); }
.notice b { color: var(--ink); font-weight: 600; }

details.method { border-top: 1px solid var(--line-soft); }
details.method > summary {
  cursor: pointer; padding: 10px 14px; font-size: 13px; font-weight: 600;
  list-style: none;
}
details.method > summary::-webkit-details-marker { display: none; }
details.method > summary::before { content: "▸ "; color: var(--ink-3); }
details.method[open] > summary::before { content: "▾ "; }
details.method > div { padding: 0 14px 14px; font-size: 13px; color: var(--ink-2); max-width: 74ch; }
details.method h3 { margin: 12px 0 4px; color: var(--ink); }
details.method code { font-family: var(--mono); font-size: 12px; background: var(--surface-2); padding: 1px 4px; border-radius: 3px; }
details.method ul { margin: 4px 0 10px; padding-left: 20px; }
details.method li { margin-bottom: 3px; }

footer.page { padding: 8px 20px 32px; color: var(--ink-3); font-size: 12px; max-width: 1520px; margin: 0 auto; }
footer.page a { color: inherit; }

.busy { opacity: .55; transition: opacity .1s; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
