/* בחירות – design system. RTL Hebrew, no framework (ADR-0013).
   Idea: paper, ink, one ballot-envelope blue. The only bold element is the dual-marker stance scale. */
@import url("https://fonts.googleapis.com/css2?family=Frank+Ruhl+Libre:wght@400;500;700&family=Heebo:wght@300;400;500;700&display=swap");

:root {
  --paper: #f4f5f3;
  --surface: #ffffff;
  --ink: #171b21;
  --ink-2: #4a525c;
  /* 4.58:1 on --paper, 5.01:1 on --surface. It was #7c848e, which is 3.46:1 - under the 4.5:1 that
     WCAG AA asks of normal text, and everything on this site at this colour is normal text: the
     root is 17px, so --fs-1 is 14.96px and even --fs-4 lands 0.2px short of the large-text
     exemption. Measured across every page type, it was the only colour in the palette that failed
     anywhere, and it failed 968 times. The dark palette's --ink-3 is untouched; it already passes
     at 5.28:1 and 4.81:1. ADR-0031. */
  --ink-3: #697079;
  --line: #d9dcd8; --line-control: #8c8e8b;
  --line-2: #eceeea;
  --blue: #2247b2; --on-blue: #ffffff;
  --blue-ink: #1a3688;
  --blue-soft: #e4e9f8;
  --amber: #8a5a00;
  --amber-soft: #fff1c2;
  --rose: #9b2c2c;
  --rose-soft: #fbe3e3;
  --moss: #2e6b3e;
  --moss-soft: #e0f0e4;
  --serif: "Frank Ruhl Libre", "David", Georgia, serif;
  --sans: "Heebo", "Segoe UI", "Noto Sans Hebrew", Arial, sans-serif;
  --r: 6px;
  --r-sm: 3px;
  --r-pill: 999px;
  /* Type scale. Six steps, because 29 sizes -- fifteen of them between .72 and .95rem -- read as
     drift rather than hierarchy. --fs-ref is deliberately relative: it is the superscript source
     marker, which has to grow with whatever text it sits in. */
  --fs-1: .88rem;
  --fs-2: 1rem;
  --fs-3: 1.15rem;
  --fs-4: 1.4rem;
  --fs-5: 1.75rem;
  --fs-6: clamp(1.9rem, 4vw, 2.8rem);
  --fs-ref: .75em;
  /* Spacing scale. Hairlines of 1-3px are not on it; they are borders and optical nudges. */
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 24px;
  --s6: 40px;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #14171b; --surface: #1c2025; --ink: #eef0ec; --ink-2: #b6bcc3; --ink-3: #848c95;
    --line: #333940; --line-control: #5f6b78; --line-2: #262b31; --blue: #8faaf0; --on-blue: #14171b; --blue-ink: #b6c8f7; --blue-soft: #232c45;
    --amber: #e5b957; --amber-soft: #3b3115; --rose: #ef8d8d; --rose-soft: #3d2222; --moss: #8ccf9c; --moss-soft: #1f3526;
  }
}
:root[data-theme="dark"] {
  --paper: #14171b; --surface: #1c2025; --ink: #eef0ec; --ink-2: #b6bcc3; --ink-3: #848c95;
  --line: #333940; --line-control: #5f6b78; --line-2: #262b31; --blue: #8faaf0; --on-blue: #14171b; --blue-ink: #b6c8f7; --blue-soft: #232c45;
  --amber: #e5b957; --amber-soft: #3b3115; --rose: #ef8d8d; --rose-soft: #3d2222; --moss: #8ccf9c; --moss-soft: #1f3526;
}

* { box-sizing: border-box; }
html { font: 400 17px/1.6 var(--sans); color: var(--ink); background: var(--paper); -webkit-text-size-adjust: 100%; }
body { margin: 0; }
a { color: var(--blue-ink); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--blue); }
:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/**
 * The skip link (WCAG 2.4.1, level A).
 *
 * Positioned off screen rather than `display: none` or `visibility: hidden`, because both of those
 * remove an element from the focus order, which is the one thing this element exists to be in. It
 * returns on focus, and it is the first focusable thing in the document, so one Tab from the top of
 * any page reaches it.
 */
.skip-to-main { position: absolute; inset-inline-start: -9999px; top: var(--s2); z-index: 100;
  background: var(--surface); color: var(--blue-ink); border: 2px solid var(--blue);
  border-radius: var(--r); padding: var(--s2) var(--s3); text-decoration: none; font-weight: 500; }
.skip-to-main:focus { inset-inline-start: var(--s3); }
h1, h2, h3 { font-family: var(--serif); font-weight: 500; line-height: 1.2; margin: 0; }
h1 { font-size: var(--fs-6); letter-spacing: -.01em; }
h2 { font-size: var(--fs-4); }
h3 { font-size: var(--fs-3); }
p { margin: var(--s2) 0; }
.wrap { max-width: 1180px; margin: 0 auto; padding: 0 var(--s4); }
/* Text fills the block it belongs to. Three different measures on one page read as accident
   rather than intent, and a half-width paragraph inside a full-width block reads as broken.
   The text-only page keeps this full page width - see `.reading` below for which pages narrow
   and why, and for the note that used to sit here and had stopped being true of it. */
.kicker, .lead, .note, .person-bg, .prose li, .small.muted { max-width: none; }
.muted { color: var(--ink-2); }
.faint { color: var(--ink-3); }
.small { font-size: var(--fs-1); }
.num { font-variant-numeric: tabular-nums; }
.serif { font-family: var(--serif); }
@media (prefers-reduced-motion: reduce) { * { transition: none !important; animation: none !important; } }

/* header */
.site-header { border-bottom: 1px solid var(--line); background: var(--paper); }
.site-header .wrap { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s4); padding: var(--s4) var(--s4); flex-wrap: wrap; }
.brand { font-family: var(--serif); font-size: var(--fs-3); color: var(--ink); text-decoration: none; }
.brand small { font-family: var(--sans); font-size: var(--fs-1); color: var(--ink-3); margin-inline-start: var(--s2); }
.nav { display: flex; gap: var(--s4); flex-wrap: wrap; }
.nav a { color: var(--ink-2); text-decoration: none; padding-bottom: 2px; border-bottom: 2px solid transparent; }
.nav a[aria-current] { color: var(--ink); border-bottom-color: var(--blue); }
.nav a:hover { color: var(--ink); }

/* The menu, folded away on a phone.
   Five links and a brand that wraps to two lines made the header 190px of an 812px screen - a
   quarter of the viewport spent on furniture before a word of the page, and on the long pages a
   second sticky row of chips sits directly beneath it. Below 620px the links fold into one
   control and the header is the brand and a way in.
   A <details> and not a button, for the reason the front-page legend had to be rewritten once
   already: with no JS the menu still opens, closes, takes focus and answers Escape, all from the
   browser. It ships open, so a reader with no JS at all gets exactly the row that shipped before
   this rule existed. The inline line in the header closes it on a phone before the first paint -
   deferring that to the module would fold the menu away in front of the reader. */
.navbox > summary { display: none; }
@media (min-width: 621px) {
  /* Above the phone the links are a plain row; the disclosure is not part of the design. The
     pseudo-element keeps the row visible for a reader who narrowed the window and widened it
     again with no JS to re-open it; nav-menu.js does the same where it is not supported. */
  .navbox::details-content { content-visibility: visible; block-size: auto; }
}
/* "and (scripting: enabled)" is the whole fallback. Where JS is off, or where the browser is old
   enough not to know the feature, none of this applies and the header is the plain wrapped row
   that shipped before - working, just taller. Nothing here can leave a reader without navigation,
   which is why the menu is gated on the stylesheet rather than the stylesheet on the menu. */
@media (max-width: 620px) and (scripting: enabled) {
  .site-header .wrap { position: relative; align-items: center; flex-wrap: nowrap; }
  /* The tagline runs on from the title as one inline flow, so it started mid-line and broke over
     three lines with "אחד" alone on the last - a whole row of header bought for one word. On its
     own line it needs 194px and has 235px, so it costs two lines instead of three. */
  .brand { min-width: 0; }
  .brand small { display: block; margin-inline-start: 0; text-wrap: balance; }
  /* At the start of the line, which in Hebrew is the right. Mirroring the English header exactly
     would put it on the left, and that is not where an Israeli reader reaches: ynet and mako both
     sit it at the right edge on a phone (x=336 and x=335 of 375, measured). */
  .navbox { flex: 0 0 auto; order: -1; }
  /* The summary keeps display: list-item and the chip is a span inside it. WebKit has a long
     history of dropping the disclosure's role and its click behaviour when a summary is given any
     other display, and a control that looks like a button and does nothing is the exact failure
     the front-page legend already shipped once. */
  .navbox > summary { display: list-item; list-style: none; cursor: pointer; }
  .navbox > summary::-webkit-details-marker { display: none; }
  .nav-toggle-in {
    display: inline-flex; align-items: center; gap: var(--s2); min-height: 44px;
    padding: var(--s2) var(--s3); border: 1px solid var(--line); border-radius: var(--r-sm);
    color: var(--ink-2); font-size: var(--fs-1);
  }
  .navbox > summary:hover .nav-toggle-in,
  .navbox[open] > summary .nav-toggle-in { color: var(--ink); background: var(--line-2); }
  /* Borders and not backgrounds: in forced-colors mode a background is replaced by Canvas and the
     three bars would vanish. The word beside them carries the control either way. */
  .burger { width: 18px; height: 0; border-top: 2px solid currentColor; position: relative; }
  .burger::before, .burger::after { content: ""; position: absolute; inset-inline: 0; border-top: 2px solid currentColor; }
  .burger::before { top: -8px; }
  .burger::after { top: 4px; }
  /* Over the page rather than pushing it: opening a menu should not move the thing being read.
     Which means it has to look like it is over the page. The first cut used --paper and the
     faintest line in the set, so it landed on the hero as a pane of the same colour with the
     tagline showing through the gaps - not a menu, a fault. --surface is the one colour that is
     never the page behind it in either theme, and the shadow is the one in the stylesheet,
     because this is the one element that floats. */
  .navbox .nav {
    position: absolute; z-index: 20; top: calc(100% - var(--s2)); inset-inline-start: var(--s4);
    flex-direction: column; gap: 0; min-width: 12rem; padding: var(--s2);
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
    box-shadow: 0 10px 28px rgb(0 0 0 / 18%);
  }
  .navbox .nav a { padding: var(--s3); border-bottom: 0; border-radius: var(--r-sm); }
  /* --line and not --line-2: the fainter of the two is a hairline against white and the row read
     as unresponsive. Grey and not blue, because blue is taken - it marks the page you are on. */
  .navbox .nav a:hover, .navbox .nav a:focus-visible { background: var(--line); color: var(--ink); }
  .navbox .nav a[aria-current] { color: var(--ink); background: var(--blue-soft); }
}

.site-footer { margin: 4rem auto 2rem; padding-top: var(--s4); border-top: 1px solid var(--line); color: var(--ink-3); font-size: var(--fs-1); }
.site-footer p { max-width: none; }

/* notices */
.notice { display: flex; gap: var(--s3); align-items: flex-start; font-size: var(--fs-1); padding: var(--s3) var(--s4); margin: var(--s4) 0; border-radius: var(--r); background: var(--surface); border: 1px solid var(--line); color: var(--ink-2); }
.notice-warn { background: var(--amber-soft); border-color: transparent; color: var(--amber); }
.notice p { margin: 0; max-width: none; }

/* tags: small factual labels, never judgments */
.tag { display: inline-block; font-size: var(--fs-1); line-height: 1.5; padding: 0 var(--s2); border-radius: var(--r-sm); background: var(--line-2); color: var(--ink-2); white-space: nowrap; vertical-align: middle; }
.tag-blue { background: var(--blue-soft); color: var(--blue-ink); }
.tag-amber { background: var(--amber-soft); color: var(--amber); }
.tag-rose { background: var(--rose-soft); color: var(--rose); }
.tag-moss { background: var(--moss-soft); color: var(--moss); }
.tag-outline { background: transparent; border: 1px dashed var(--line); }

/* ---------- stance scale: the one bold element ---------- */
.scale { position: relative; height: 26px; min-width: 120px; }
.scale-track { position: absolute; inset-inline: 6px; top: 12px; height: 2px; background: var(--line); }
.scale-tick { position: absolute; top: 9px; width: 1px; height: 8px; background: var(--line); }
.scale-mid { position: absolute; top: 6px; width: 1px; height: 14px; background: var(--ink-3); }
.scale-gap { position: absolute; top: 11px; height: 4px; background: var(--amber); opacity: .55; border-radius: var(--r-sm); }
.mark { position: absolute; top: 6px; width: 14px; height: 14px; transform: translateX(50%); }
.mark-stated { border: 2px solid var(--ink); border-radius: 50%; background: var(--surface); }
.mark-actual { background: var(--blue); transform: translateX(50%) rotate(45deg); border-radius: var(--r-sm); }
.mark-both { border: 2px solid var(--ink); background: var(--blue); border-radius: 50%; }
.scale-unknown { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: var(--fs-1); color: var(--ink-3); }
.legend { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s4); font-size: var(--fs-1); color: var(--ink-2); align-items: center; }
.legend .mark { position: static; transform: none; display: inline-block; vertical-align: -2px; margin-inline-start: var(--s1); }
.legend .mark-actual { transform: rotate(45deg); width: 11px; height: 11px; }
.legend .swatch-gap { display: inline-block; width: 20px; height: 4px; background: var(--amber); opacity: .6; border-radius: var(--r-sm); vertical-align: middle; margin-inline-start: var(--s1); }

/* ---------- landing ---------- */
.hero { padding: var(--s6) 0 var(--s5); display: grid; gap: var(--s4); }
.hero p { font-size: var(--fs-3); color: var(--ink-2); }
.hero-actions { display: flex; gap: var(--s3); flex-wrap: wrap; align-items: center; }
/**
 * The label on a filled button is a token, not white.
 *
 * `color: #fff` is right in the light theme, where --blue is a dark blue. In the dark theme --blue
 * is a *light* blue meant for text on a dark ground, and white on it measured 2.28:1 - on the main
 * call to action, "להתחיל את השאלון", which is the one control on the site that most needs to be
 * legible. --on-blue flips with the palette: white on the light theme's #2247b2, and the dark
 * theme's own background on its #8faaf0, which measures 7.86:1 and 10.78:1 on hover.
 */
.btn { font: 500 1rem var(--sans); padding: var(--s3) var(--s4); border-radius: var(--r); border: 1px solid var(--blue); background: var(--blue); color: var(--on-blue); cursor: pointer; text-decoration: none; display: inline-block; }
.btn:hover { background: var(--blue-ink); border-color: var(--blue-ink); color: var(--on-blue); }
.btn-quiet { background: transparent; color: var(--blue-ink); }
.btn-quiet:hover { background: var(--blue-soft); }

/* The negative-margin bleed existed so a wide table could reach the page edge on a phone. Below
   720px the matrix is hidden in favour of the single-issue view, so the trick now only added 32px
   of phantom scroll on desktop. */
.matrix-wrap { overflow-x: auto; margin: var(--s4) 0; }
.matrix { border-collapse: separate; border-spacing: 0; min-width: 640px; width: 100%; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); }
.matrix th, .matrix td { padding: var(--s3) var(--s2); border-bottom: 1px solid var(--line-2); vertical-align: middle; text-align: right; }
.matrix thead th { border-bottom: 1px solid var(--line); vertical-align: bottom; }
.matrix tbody tr:last-child td, .matrix tbody tr:last-child th { border-bottom: 0; }
.matrix .issue { font-weight: 500; width: 22%; min-width: 160px; }
.matrix .issue small { display: block; font-weight: 400; color: var(--ink-3); font-size: var(--fs-1); margin-top: 2px; }
.matrix td.cell { min-width: 150px; }

.coverage-line { display: flex; gap: 3px; margin-top: var(--s2); }
.coverage-line i { display: block; flex: 1; height: 5px; border-radius: var(--r-sm); background: var(--line-2); }
.coverage-line i.done { background: var(--blue); }
.coverage-line i.partial { background: var(--blue); opacity: .4; }
/* no_record is not a lesser done: the work is finished and the rest of it does not exist
   (ADR-0023). It gets its own mark rather than a faded one, so the strip cannot be read as
   a progress bar with a gap in it. */
.coverage-line i.no_record { background: var(--line-2); border: 1px solid var(--blue); box-sizing: border-box; }


/* A sub-part of a section: the conduct block gathers office findings, proxy speech and departed
   members under one heading instead of giving each its own h2 at the level of "the team". */
.subblock { margin-top: var(--s5); padding-top: var(--s4); border-top: 1px solid var(--line); }
.subblock h3 { font-family: var(--serif); font-size: var(--fs-3); }
/* The party background used to be a section heading with two lines under it, at the bottom of the
   page. It belongs to the title. */
.page-intro { color: var(--ink-2); max-width: 62ch; }

/* ---------- party / person pages ---------- */
.page-head { padding: var(--s6) 0 var(--s3); display: grid; gap: var(--s2); }
.page-head .kicker { color: var(--ink-2); }
.page-head .kicker a { color: inherit; }
.facts { display: grid; gap: var(--s4); grid-template-columns: 1fr; margin: var(--s3) 0 var(--s2); }
@media (min-width: 900px) { .facts { grid-template-columns: repeat(3, 1fr); } }
.fact { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: var(--s3) var(--s4); }
.fact .v { font-family: var(--serif); font-size: var(--fs-5); line-height: 1.1; }
.fact .k { color: var(--ink-3); font-size: var(--fs-1); margin-top: 2px; }
.fact .sub { font-size: var(--fs-1); color: var(--ink-2); margin-top: var(--s1); }

.layout { display: grid; gap: var(--s5); grid-template-columns: 1fr; }
@media (min-width: 1100px) { .layout { grid-template-columns: minmax(0, 1fr) 260px; } .rail { position: sticky; top: 16px; align-self: start; } }
/* The reading measure. A paragraph in the content column ran to 108-128 characters, which is
   roughly twice what anyone reads comfortably. Narrowing the paragraph alone was rejected before,
   and rightly: a half-width paragraph inside a full-width block reads as broken. So the whole
   reading column narrows together -- head, facts and body keep one measure between them, which is
   the thing the earlier note asked for. 620px at ~7.5px per Hebrew character is about 82 per line.

   Which pages: the ones with a head, a facts strip and a rail to keep on one measure - party,
   person and evidence pages. NOT the map or the poll tables, which are scanned rather than read,
   and NOT the methodology page: that one is only prose, so narrowing it buys no alignment and
   costs the alignment with the header and with every page beside it in the nav. It was given
   this class with the others and the owner caught it twice; the second time it went back to the
   page width for good. */
/* Constrain the container, not each child. Centring every child with margin-inline:auto looked
   right until a child carried its own margin shorthand -- `section.block { margin: 40px 0 }` and
   the stance strip both set the inline margins to 0 and won, so those blocks sat flush to the
   start edge while their neighbours centred, 120px apart. One max-width on main settles it. */
.reading { max-width: 940px; }
.layout > div:first-child { container-type: inline-size; container-name: col; }
.rail { display: grid; gap: var(--s4); }
.rail-box { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: var(--s3) var(--s4); font-size: var(--fs-1); }
.rail-box h3 { font-family: var(--sans); font-size: var(--fs-1); font-weight: 500; margin-bottom: var(--s2); }
.rail-box dl { margin: 0; display: grid; grid-template-columns: auto 1fr; gap: var(--s1) var(--s3); }
.rail-box dt { color: var(--ink-3); }
.rail-box dd { margin: 0; }
.toc { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s1); }
.toc a { text-decoration: none; color: var(--ink-2); }

section.block { margin: var(--s6) 0; }
section.block > h2 { margin-bottom: var(--s1); }
section.block > .lead { color: var(--ink-2); margin-top: 0; }

/* The roster kept its three desktop columns on a phone, which left 50px for the name and role and
   wrapped a single candidate into a 387px sliver. Position and name share the top line, the tags
   go underneath. */
@media (max-width: 620px) {
  .roster li { grid-template-columns: 30px minmax(0, 1fr); gap: var(--s1) var(--s2); align-items: baseline; }
  .roster li .meta { grid-column: 1 / -1; justify-content: flex-start; }
  .roster .pos { font-size: var(--fs-2); text-align: start; }
}

/* The stance strip: the seven contested topics on one screen, right under the fact tiles. The
   full rows with the quotes and the sources are further down; this is the glance. */
.stance-strip { margin: var(--s4) 0; border: 1px solid var(--line); border-radius: var(--r);
  background: var(--surface); padding: var(--s2) var(--s4); }
.stance-strip > h2 { font-family: var(--sans); font-size: var(--fs-1); font-weight: 500;
  color: var(--ink-3); margin: var(--s2) 0; }
.strip-list { list-style: none; margin: 0; padding: 0; }
.strip-list li { display: grid; grid-template-columns: minmax(0, 1fr) minmax(150px, 210px);
  gap: var(--s3); align-items: center; padding: var(--s2) 0; border-top: 1px solid var(--line-2); }
.strip-scale { display: block; }
.strip-scale .ends { padding: 0 6px; }
.stance-strip .legend { margin-bottom: var(--s2); }
.strip-list li:first-child { border-top: 0; }
.strip-list .strip-name { font-size: var(--fs-1); }
.strip-list .scale { height: 22px; min-width: 110px; }
.strip-more { font-size: var(--fs-1); margin: var(--s2) 0 var(--s1); }

.stance-text > summary, .events-more > summary, .roster-more > summary {
  cursor: pointer; color: var(--blue-ink); padding: var(--s2) 0; }
.stance-text > summary:hover, .events-more > summary:hover, .roster-more > summary:hover { color: var(--blue); }
/* `display: flex` on a summary stops it being a list-item, which takes the marker with it. The
   sweep that found the claim card's cramped triangle found this one and .rview-fold had no
   triangle at all - two disclosures whose only hint that they open was that the text was blue.
   Under ADR-0028 the triangle is the affordance, so they get one, as a flex item. */
.stance-text > summary { display: flex; flex-wrap: wrap; gap: var(--s1) var(--s2); align-items: baseline; }
.stance-text > summary::before { content: "◂"; color: var(--ink-3); }
.stance-text[open] > summary::before { content: "▾"; }
.stance-gapnote { color: var(--amber); font-weight: 500; }
.events-more, .roster-more { margin-top: var(--s3); border-top: 1px solid var(--line-2); }
.events-more > ul, .roster-more > ol { margin-top: var(--s3); }

/* Tiles line up as a row: same top, same bottom. That only works while every tile holds a short
   fact, which is why the legal history moved to its own section - one runaway tile used to drag
   the whole row to 3,112px. If a tile ever needs a paragraph again, the paragraph is what is
   wrong, not the alignment. */
.facts > .fact { align-self: stretch; }
.legal-summary { margin: 0 0 var(--s3); }
.proceedings { margin-top: var(--s3); }
.proceedings > .k { color: var(--ink-3); font-size: var(--fs-1); margin-bottom: var(--s2); }
.proceedings ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s2); }
.proceedings li { display: grid; grid-template-columns: 5ch minmax(0, 1fr); gap: var(--s3);
  align-items: baseline; padding: var(--s2) 0; border-top: 1px solid var(--line-2); }
.proc-when { font-variant-numeric: tabular-nums; color: var(--ink-3); font-size: var(--fs-1); }
@media (max-width: 520px) {
  .proceedings li { grid-template-columns: 1fr; gap: var(--s1); }
}

/* An event still being checked is not a verdict; it reads as an open item, not a soft one. */
.pending-note { color: var(--amber); margin: var(--s1) 0 0; }
.event.is-pending { border-inline-start: 3px solid var(--amber); }

/* ---------- "why?" for one list ---------- */
/* The why panel lives in a cell of a table that scrolls sideways, so it inherited that table's
   width - 605px against a 375px phone - and reading it meant dragging it into view. It takes the
   narrower of its cell and the viewport, and sticks to the start edge so horizontal scrolling of
   the table leaves it where it is. */
.why-list { display: grid; gap: var(--s4); margin: var(--s3) 0;
  max-width: min(100%, calc(100vw - var(--s6)));
  position: sticky; inset-inline-start: 0; }
.why-row > td { position: relative; }
.why-q { border-top: 1px solid var(--line-2); padding-top: var(--s3); }
.why-text { font-weight: 500; margin: 0; }
/* The premise, not a reading. It belongs to the question above it, so it sits tight under it and
   above the rule; the three readings below are what we found, and they are the only list. */
.why-you { margin: var(--s1) 0 0; font-size: var(--fs-1); color: var(--ink-2); }
.why-you strong { color: var(--ink); font-variant-numeric: tabular-nums; }
.sc-basis { color: var(--ink-3); font-size: var(--fs-1); }
/* Who a people-reading cell rests on: folded, one short line per person, each a link to that
   person's own stance. Closed by default so ten names never push the other readings off screen. */
.who-why { margin-top: var(--s1); }
.who-why > summary { cursor: pointer; color: var(--ink-2); }
.who-why-list { margin: var(--s1) 0 0; padding-inline-start: var(--s3); display: grid; gap: 2px; }
.who-why-list a { overflow-wrap: anywhere; }
.why-vals { display: grid; grid-template-columns: max-content minmax(0, 1fr);
  gap: var(--s1) var(--s3); align-items: baseline;
  /* dashed, so it reads as a lighter division than the solid rule between whole questions */
  margin: var(--s2) 0 0; padding-top: var(--s2); border-top: 1px dashed var(--line-2); }
.why-vals dt { color: var(--ink-3); font-size: var(--fs-1); white-space: nowrap; }
.why-vals dd { margin: 0; font-size: var(--fs-1); }
@media (max-width: 520px) {
  .why-vals { grid-template-columns: 1fr; gap: 0; }
  .why-vals dt { margin-top: var(--s2); }
}

/* The issue titles were bottom-aligned with the scale legends under them, so a title that wrapped
   to two lines pushed its own scale down and sat higher than its neighbours. Title block on top at
   a fixed line, scale underneath, so every heading starts on the same line. */
.matrix thead th.issue-head { vertical-align: top; }
.matrix .issue-head .issue-title { display: block; min-height: 2.6em; }
.matrix .party-cell .sub.seats { display: block; white-space: nowrap; }

/* ---------- polls grid ---------- */
/* Seventeen numeric columns will not fit a phone and there is no honest way to make them; what
   the grid can do is stop being wider than it needs to be, and keep the row's own identity in
   view while you scroll it. The poll identifier is a row header, frozen at the start edge. */
.polls-now th.poll-list { position: sticky; inset-inline-start: 0; background: var(--surface);
  z-index: 1; text-align: start; width: 118px; min-width: 118px; font-weight: 500; }
.polls-now th.poll-list a { color: var(--ink); text-decoration: none; }
.polls-now thead th { position: sticky; top: 0; background: var(--surface); z-index: 2;
  vertical-align: bottom; padding-inline: var(--s2); }
.polls-now thead th.poll-list { z-index: 3; }
.polls-now .poll-house { font-weight: 500; font-size: var(--fs-1); }
.polls-now .poll-house span { display: block; white-space: nowrap; }
.polls-now .poll-avg-col { color: var(--blue-ink); }
.polls-now td { text-align: center; padding-inline: var(--s2); }

/* On a phone eight outlet names across the top cannot be read horizontally and still leave room
   for the numbers, so the headings turn. Columns drop to the width of a two-digit number, which
   is as narrow as this table can honestly get: the alternative is showing fewer polling houses
   on a small screen, and hiding data by screen size is the thing this redesign removed. */
@media (max-width: 720px) {
  .polls-now .poll-house { writing-mode: vertical-rl; text-orientation: mixed; padding-block: var(--s2); }
  .polls-now .poll-house span:last-child { display: none; }
  .polls-now thead th, .polls-now td { padding-inline: var(--s1); }
  /* width alone is only a hint to an auto-laid-out table: the longest list name was setting the
     column at 181px regardless. Letting it wrap brings it back to the width of its longest word. */
  .polls-now th.poll-list { width: 108px; min-width: 108px; max-width: 108px; font-size: var(--fs-1); }
  .polls-now th.poll-list a { display: block; white-space: normal; }
}

/**
 * The phone: this grid fits, so it should not offer to scroll.
 *
 * At 375px it came to 453px in a 341px window - 112px over, which showed four of the seven
 * polling houses and put a drag gesture on a table that has no need of one. None of the 112px was
 * information. 89px of it was padding around two-digit numbers (8px a side, from the desktop
 * rule), the average column was holding 65px for "21.7", and the name column 108px for names that
 * had already been shortened. The cells keep their size; what goes is the air around them.
 *
 * `fixed` so the seven houses split what is left in equal parts rather than each taking the width
 * of whatever it happens to contain (ADR-0032, trap 4). Above 620px no rule here matches.
 *
 * The shares below add up for the seven houses that publish today (32 + 15 + 7x7.5). An eighth
 * takes them past a hundred and the table scrolls again, and the answer then is the front page's
 * pattern - pages of columns - rather than eight thinner ones: a house column is already down to
 * a two-digit number and a turned caption, and there is nothing left in it to give.
 *
 * Measured clean at 360, 375, 390, 412 and 620px. At 320px the table still runs 3px over, because
 * the word "ממוצע" in the heading is wider than that column's share of a 286px table; the fix
 * there would be a smaller heading, which is shrinking a label to win three pixels.
 */
@media (max-width: 620px) {
  .polls-now { table-layout: fixed; width: 100%; min-width: 0; }
  /* Under `fixed` the widths are read off the first row and nowhere else, so all three groups are
     stated in the head or the table divides itself into equal parts: the name column, which has
     to hold "המילואימניקים" without breaking it across lines, the average, and a house column,
     which needs a two-digit number and a turned caption and nothing more. The body's own width
     and min-width are ignored under `fixed`; they are cleared so they do not read as the rule. */
  /* Proportions and not pixels. Pixel widths fit 375px and then fell 11px short at 360 and 51px
     at 320, which is a cliff rather than a layout; as shares of the table the same columns hold
     their ratio at any width the phone turns out to be. */
  .polls-now thead th:first-child { width: 32%; }
  .polls-now th.poll-list { width: auto; min-width: 0; max-width: none; }
  /* The one name long enough to outgrow its column on the narrowest screens. Breaking a list name
     across lines is bad; pushing it through the numbers beside it is worse. */
  .polls-now th.poll-list a { overflow-wrap: anywhere; }
  .polls-now .poll-avg-col { width: 15%; }
  /* Turned text swaps the meaning of both of these. In `vertical-rl` the block axis runs across
     the column, so the `padding-block: 8px` above is 16px of width, not height, and the body's
     line-height is measured across the caption rather than down it. Seven columns were each 6px
     wider than the width they had been given, and that was the last of the overflow. */
  .polls-now .poll-house { width: 7.5%; padding-block: 3px; }
  .polls-now .poll-house span { line-height: 1.1; }
  .polls-now thead th, .polls-now td, .polls-now td.num { padding-inline: 2px; }
}


.polls th.pollster { position: sticky; inset-inline-start: 0; background: var(--surface);
  z-index: 1; text-align: start; width: 150px; min-width: 150px; font-weight: 400; }
.polls thead th { position: sticky; top: 0; background: var(--surface); z-index: 2; }
.polls thead th.pollster { z-index: 3; }
.polls .poll-party { min-width: 0; }
.polls .poll-party a { display: inline-block; max-width: 8ch; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
.polls td.num { min-width: 0; padding-inline: var(--s2); text-align: center; }

/**
 * The phone: the full grid is read as one card per poll.
 *
 * At 375px it was 1,336px in a 341px window - 995px of drag, nearly three screens - and eight of
 * the fifteen headings were clipped to eight characters with an ellipsis, so the columns a reader
 * dragged to were labelled "הדמוקרט…" and "המילואימני…". A number under a name that has been cut
 * in half is the same problem as a number with no name at all (ADR-0032).
 *
 * Shortening the names does not reach it, and this was measured rather than assumed: with every
 * party name deleted outright and the padding at its minimum, fifteen columns of two-digit numbers
 * plus the poll's own identifier still came to 359px. The grid is 18px too wide for the screen
 * before a single name is drawn, and the table is expected to grow.
 *
 * So the rows come apart instead. One poll is one card, the lists inside it are name-and-number
 * pairs two to a line, and every number keeps the name it belongs to. Growth lands where it can be
 * absorbed: another poll is another card, another list is another pair inside each card. The
 * section stays folded behind its `<details>`, which is what it was before - this table is for
 * checking a number, not for reading through.
 */
@media (max-width: 620px) {
  /* A wide gutter, because each pair ends in a number and the next one begins with a name: at
     12px "18" and "ישר!" sat close enough to read as one thing. */
  .polls.cards tbody tr { display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--s5);
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
    padding: var(--s3) var(--s4) var(--s2); margin-bottom: var(--s3); }
  /* Which poll this is, across the top of its own card: no longer a column to be frozen against
     a scroll that no longer happens. */
  .polls.cards tbody th.pollster { grid-column: 1 / -1; position: static; display: block;
    width: auto; min-width: 0; border-bottom: 1px solid var(--line-2); padding: 0 0 var(--s2);
    margin-bottom: var(--s1); font-size: var(--fs-2); white-space: normal; }
  /* `table.polls th, table.polls td` is nowrap, which is right for a numeric grid and wrong for a
     pair whose label is "המילואימניקים והכלכלית" in half a phone. */
  .polls.cards td[data-label] { white-space: normal; }
  .polls.cards td[data-label]::before { overflow-wrap: anywhere; }
}
.poll-notes { margin: var(--s3) 0 0; padding-inline-start: var(--s4); display: grid; gap: var(--s2);
  font-size: var(--fs-1); color: var(--ink-2); }
.table-note { margin-top: var(--s3); }

/* ---------- foldable claims ---------- */
/* .claim is a <details> now. Closed it is the header plus two lines of the statement; open it is
   exactly what it always was. content-visibility keeps the browser from laying out the hundreds
   that are off screen, and each card carries its own contain-intrinsic-size from the build. */
.claim { content-visibility: auto; }
/**
 * The claim card draws its own triangle.
 *
 * It used the native marker with `list-style-position: outside`, which puts the marker box outside
 * the summary's border box - inside the card's padding. The card has 16px of it, and the marker
 * plus its gap is about that wide, so the triangle came to rest flat against the card's border
 * with no space at all. It is the most repeated component on the site: 87 of them on one evidence
 * page, and the reader meets it before any claim text.
 *
 * Adding padding to the summary would not have moved it - an outside marker sits outside the
 * padding too - so the card would have had to be indented instead, shifting all of its content to
 * buy room for one glyph. The site already draws its own marker in two other places, so this is
 * the third: the summary becomes a two-column grid, the triangle gets a column and a real gap, and
 * the glyphs are the same ▸/▾ used by evidence-block and .disclose (ADR-0028).
 */
.claim > summary { cursor: pointer; list-style: none;
  display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: var(--s2); }
.claim > summary::-webkit-details-marker { display: none; }
/* ◂ and not ▸. A closed disclosure points the way the text runs, which in Hebrew is leftward, and
   that is what the browser's own marker does on this very page - the .cat-block headings above
   these cards draw ◂. The hand-written ones were copied from an LTR habit and pointed back at the
   margin, which is why they read as the wrong way round beside the native ones. */
.claim > summary::before { content: "◂"; grid-column: 1; grid-row: 1; color: var(--ink-3); }
.claim[open] > summary::before { content: "▾"; }
.claim > summary > * { grid-column: 2; }
.claim > summary:hover .text { color: var(--blue-ink); }
.claim:not([open]) > summary .text {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.claim > summary .text { margin: var(--s1) 0 0; }
.cat-block > summary { cursor: pointer; padding: var(--s3) 0; border-top: 1px solid var(--line); }
.cat-block > summary:hover { color: var(--blue); }
.cat-block > summary .cat-name { font-family: var(--serif); font-size: var(--fs-4); }
.cat-block[open] > summary { border-bottom: 1px solid var(--line-2); }
@media print { .claim, .cat-block, details { content-visibility: visible; } }

/* ---------- progressive disclosure: the answer, then the evidence ---------- */
/* The results page ran to 141 phone screens with nothing folded, and 91% of that was the deep
   dive: one fifteen-row table per topic you marked important. Folding is ordering, not hiding -
   every row stays in the DOM, findable by the browser's own search, one click from view. */
.rview-fold { border-top: 1px solid var(--line-2); }
.rview-fold > summary {
  cursor: pointer; padding: var(--s3) 0; display: flex; flex-wrap: wrap;
  gap: var(--s1) var(--s3); align-items: baseline; }
.rview-fold > summary::before { content: "◂"; color: var(--ink-3); }
.rview-fold[open] > summary::before { content: "▾"; }
.rview-fold > summary:hover { color: var(--blue); }
.rview-fold > summary { color: var(--blue-ink); }

/* ---------- section nav: the phone's version of the rail ---------- */
/* The rail's table of contents is min-width:1100px, so on a phone the only map of an 18,000px
   page rendered at 94% of its height. This is the same list, at the top, and it stays put. */
.section-nav { position: sticky; top: 0; z-index: 5; background: var(--paper);
  border-bottom: 1px solid var(--line); margin: 0 calc(var(--s4) * -1) var(--s4);
  padding: 0 var(--s4); overflow-x: auto; scrollbar-width: none; }
.section-nav::-webkit-scrollbar { display: none; }
.section-nav ul { list-style: none; display: flex; gap: var(--s1); margin: 0; padding: 0; }
.section-nav a { display: block; white-space: nowrap; text-decoration: none; color: var(--ink-2);
  padding: var(--s3) var(--s3) var(--s2); border-bottom: 2px solid transparent; }
.section-nav a[aria-current="true"] { color: var(--ink); border-bottom-color: var(--blue); }
@media (min-width: 1100px) { .section-nav { display: none; } }
/* below 1100px the chip row is the table of contents; the rail keeps only what it adds */
@media (max-width: 1099px) { .rail-toc { display: none; } }

/* stance rows */
.stance-list { list-style: none; padding: 0; margin: var(--s4) 0 0; display: grid; gap: var(--s3); }
.stance-row { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: var(--s3) var(--s4); display: grid; gap: var(--s2) var(--s4); grid-template-columns: 1fr; }
@media (min-width: 720px) { .stance-row { grid-template-columns: 170px minmax(0, 1fr); align-items: start; } .stance-row .stance-text { grid-column: 1 / -1; } }
@media (min-width: 1000px) { .stance-row { grid-template-columns: 170px 200px minmax(0, 1fr); } .stance-row .stance-text { grid-column: auto; } }
@container col (max-width: 760px) {
  .stance-row { grid-template-columns: 170px minmax(0, 1fr); }
  .stance-row .stance-text { grid-column: 1 / -1; }
}
.stance-row .issue-name { font-weight: 500; }
.stance-row .issue-name small { display: block; font-weight: 400; color: var(--ink-3); font-size: var(--fs-1); }
.stance-row .scale { margin-top: var(--s1); }
.stance-text { display: grid; gap: var(--s2); font-size: var(--fs-1); }
.stance-text .dim { color: var(--ink-3); font-size: var(--fs-1); }
.stance-text .dim + span { display: block; }
.stance-text .refs { font-size: var(--fs-1); }
.stance-row.is-gap { border-inline-start: 3px solid var(--amber); }

/* team roster */
.roster { list-style: none; padding: 0; margin: var(--s3) 0 0; display: grid; gap: var(--s2); }
.roster li { display: grid; grid-template-columns: 44px minmax(0, 1fr) auto; gap: var(--s3); align-items: center; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: var(--s2) var(--s3); }
.roster .pos { font-family: var(--serif); font-size: var(--fs-4); color: var(--ink-3); text-align: center; }
.roster .name a { color: var(--ink); text-decoration: none; font-weight: 500; }
.roster .role { color: var(--ink-2); font-size: var(--fs-1); }
.roster .meta { display: flex; gap: var(--s2); flex-wrap: wrap; justify-content: flex-end; }
.roster li.below-line { background: var(--paper); border-style: dashed; }
.roster li.leader { border-color: var(--blue); }
/**
 * Neither "below the line" nor "not counted" fades its own text any more.
 *
 * `opacity` on the row dimmed the text inside it too, and the text was already the palette's
 * lightest ink: axe found 16 contrast failures on one party page and 9 on one person page, and
 * every one of them traced back to these two rules. A reader who needs the contrast is exactly
 * the reader who cannot afford to lose 30% of it.
 *
 * Nothing is lost by dropping it, because the fade was never carrying the meaning - both rows
 * already print a tag that says it in words ("מתחת לקו הכניסה בסקר", and the classification tag
 * on an event). The visual distinction moves to the box: the paper colour and a dashed border,
 * which say "set apart" without touching a single letter.
 */

/* conduct tally */
.tally { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s3); margin: var(--s3) 0; max-width: 560px; }
.tally > div { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: var(--s3) var(--s3); }
.tally .v { font-family: var(--serif); font-size: var(--fs-4); line-height: 1; }
.tally .k { color: var(--ink-3); font-size: var(--fs-1); }
.tally .p { color: var(--ink-2); font-size: var(--fs-1); margin-top: var(--s1); }
.events { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s2); }
.event { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: var(--s3) var(--s4); font-size: var(--fs-1); }
.event.not-counted { background: var(--paper); border-style: dashed; }
.event .head { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; color: var(--ink-3); font-size: var(--fs-1); margin-bottom: var(--s1); }
.event p { margin: 2px 0; max-width: none; }

/* evidence */
details.evidence-block > summary { cursor: pointer; color: var(--blue-ink); font-weight: 500; list-style: none; }
details.evidence-block > summary::-webkit-details-marker { display: none; }
details.evidence-block > summary::before { content: "◂ "; color: var(--ink-3); }
details.evidence-block[open] > summary::before { content: "▾ "; }
.claims { display: grid; gap: var(--s3); margin-top: var(--s3); }
.claim { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: var(--s3) var(--s4); scroll-margin-top: var(--s5); }
.claim.unverified { border-style: dashed; }
.claim.debunked { border-color: var(--rose); }
.claim .head { display: flex; gap: var(--s2); flex-wrap: wrap; align-items: center; margin-bottom: var(--s1); font-size: var(--fs-1); color: var(--ink-3); }
.claim .text { font-weight: 500; margin: 0; max-width: none; }
.claim .note { color: var(--ink-2); font-size: var(--fs-1); }
.quotes { list-style: none; padding: 0; margin: var(--s2) 0 0; display: grid; gap: var(--s2); }
.quote { border-inline-start: 3px solid var(--line); padding-inline-start: var(--s3); }
.quote.contradicts, .quote.debunks { border-inline-start-color: var(--rose); }
.quote blockquote { margin: 0; font-family: var(--serif); font-size: var(--fs-2); color: var(--ink-2); }
.quote .src { font-size: var(--fs-1); color: var(--ink-3); margin-top: 3px; }
.quote .src a { color: var(--ink-2); }

/* plain tables */
table.plain { border-collapse: collapse; width: 100%; background: var(--surface); font-size: var(--fs-1); }
table.plain th, table.plain td { border-bottom: 1px solid var(--line-2); padding: var(--s2) var(--s3); text-align: right; vertical-align: top; }

/**
 * The narrowest phones still in use, where the last two tables overshoot.
 *
 * Not required by anything. The standard this site is held to - WCAG 2.0 AA, through ת"י 5568 -
 * has no reflow criterion at all, and 2.1's 1.4.10 excepts content that needs a two-dimensional
 * layout, which a data table is the textbook case of. The page itself does not scroll sideways at
 * 320px either; only the table inside its own box does.
 *
 * It is done because the cost is air. 12px of side padding on four columns is 96px of a 271px
 * table, and "מי זז" needed 24 of them. Nothing is made smaller except the gap around it, and the
 * query stops at 360 so every width the site is actually checked at is untouched.
 */
@media (max-width: 360px) {
  table.plain th, table.plain td { padding-inline: var(--s1); }
}
table.plain thead th { color: var(--ink-3); font-weight: 500; font-size: var(--fs-1); border-bottom: 1px solid var(--line); }
.table-scroll { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--r); }

/* prose (methodology) */
.prose { max-width: none; font-size: var(--fs-2); }
/* Paragraphs here run the full column, like the text on every other page. */
.prose p, .prose li { max-width: none; }
.prose h1 { margin: var(--s6) 0 var(--s3); }
.prose h2 { margin: var(--s5) 0 var(--s2); }
.prose h3 { margin: var(--s4) 0 var(--s1); }
.prose table { margin: var(--s2) 0; }
.prose blockquote { border-inline-start: 3px solid var(--line); margin: var(--s2) 0; padding-inline-start: var(--s3); color: var(--ink-2); }
.prose li { margin: 3px 0; }

/* questionnaire */

.q-question { padding: var(--s3) 0; border-bottom: 1px solid var(--line-2); }
.q-question:last-child { border-bottom: 0; }
.q-question .qt { margin: 0 0 var(--s2); max-width: none; }
.views { display: grid; gap: var(--s4); grid-template-columns: 1fr; margin-top: var(--s3); }
@media (min-width: 960px) { .views { grid-template-columns: repeat(3, 1fr); } }
.view { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: var(--s4) var(--s4); }
.view > h2 { margin-bottom: 2px; }
.view > .lead { font-size: var(--fs-1); color: var(--ink-2); margin: 0 0 var(--s2); max-width: none; }
.view h3 { font-family: var(--sans); font-size: var(--fs-1); font-weight: 500; color: var(--ink-3); margin: var(--s3) 0 var(--s1); }
.res { padding: var(--s2) 0; border-bottom: 1px solid var(--line-2); display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s1) var(--s3); align-items: start; }
.res:last-child { border-bottom: 0; }
.res .n a { color: var(--ink); text-decoration: none; font-weight: 500; }
.res .big { font-family: var(--serif); font-size: var(--fs-4); line-height: 1; }
.res .sub { font-size: var(--fs-1); color: var(--ink-3); }
.bar { height: 5px; background: var(--line-2); border-radius: var(--r-sm); overflow: hidden; margin-top: var(--s1); }
.bar > span { display: block; height: 100%; background: var(--blue); }

/* The four parts of a fit, always filling the width: agrees, disagrees, and the two kinds of
   blank - one we may still fill, one that has nothing behind it to fill (ADR-0021). Not red and green — green reads as "good party" rather than "close to you", which is
   the reason this tool has no red/green flags at all, and it is the colour-blind pair besides. The
   figures are printed beside the bar, so colour never carries the meaning on its own. */
.fit { display: flex; height: 6px; border-radius: var(--r-sm); overflow: hidden; margin-top: var(--s1); background: var(--line-2); }
.fit > span { display: block; height: 100%; }
.fit-yes { background: var(--blue); }
.fit-no { background: var(--amber); }
.fit-unk { background: var(--line); }
/* Not-found and no-record are both grey because neither counts for or against the list; the
   hatching says which grey is finished work. The stripes are a gradient rather than a colour, so
   the difference survives greyscale, colour-blindness and a forced-colors palette. */
.fit-none {
  background: repeating-linear-gradient(135deg, var(--line) 0 2px, var(--surface) 2px 4px);
}
/* a hairline between neighbouring bands so they stay countable at small sizes and in high contrast */
.fit-no, .fit-unk, .fit-none { box-shadow: inset 1px 0 0 var(--surface); }
/* A reading that does not apply is not a zero. It gets the weight of a value without pretending
   to be one - the serif size of .sc-v would read as a measurement. */
.sc-na { font-family: var(--serif); font-size: var(--fs-3); line-height: 1; color: var(--ink-3); }
/* A sortable header is a button, so it is reachable by keyboard and announces itself; it should
   still look like a table heading rather than a control. The arrow shows the current column only. */
/* `inherit` was --ink-3 from the table head: 3.46:1, on a control the reader is meant to press.
   A sortable heading is now darker than the plain text around it, which is also the honest signal
   - the ones you can press do not look like the ones you cannot. */
.th-sort { font: inherit; color: var(--ink-2); background: none; border: 0; padding: 0; cursor: pointer; text-align: inherit; }
.th-sort:hover { color: var(--blue-ink); text-decoration: underline; text-underline-offset: 3px; }
/* The arrows are written as characters. An earlier version used a CSS escape, it was mangled
   on the way into the file, and the heading showed a control glyph followed by a literal 93. */
.th-sort[aria-sort]::after { content: " ↓"; color: var(--blue); }
.th-sort[aria-sort="ascending"]::after { content: " ↑"; }
.fit-key { display: inline-flex; align-items: center; gap: var(--s1); margin-inline-end: var(--s3); white-space: nowrap; }
.fit-sw { display: inline-block; width: 14px; height: 8px; border-radius: var(--r-sm); }
.sc-pct { font-size: var(--fs-ref); font-weight: 600; margin-inline-start: 1px; opacity: .75; }
@media (forced-colors: active) {
  .fit-yes { background: Highlight; }
  .fit-no { background: CanvasText; }
  .fit-unk { background: GrayText; }
  .fit-none { background: repeating-linear-gradient(135deg, GrayText 0 2px, Canvas 2px 4px); }
}
.res details { grid-column: 1 / -1; font-size: var(--fs-1); }
.res details summary { cursor: pointer; color: var(--blue-ink); }
.res ul { padding-inline-start: var(--s4); margin: var(--s1) 0; }
.risk-high { color: var(--rose); } .risk-medium { color: var(--amber); } .risk-low { color: var(--moss); }

/* ---------- landing v2: parties as rows ---------- */
.toolbar { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s4); align-items: center; margin: var(--s2) 0 var(--s3); }
.filter { flex: 1 1 240px; max-width: 360px; font: inherit; padding: var(--s2) var(--s3); border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); color: var(--ink); }
.check { display: inline-flex; gap: var(--s2); align-items: center; font-size: var(--fs-1); color: var(--ink-2); }
.select { font: inherit; padding: var(--s2) var(--s3); border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); color: var(--ink); margin: var(--s2) 0 var(--s3); }
.matrix .party-cell { width: 148px; min-width: 132px; font-weight: 500; padding-inline: var(--s2); }
.matrix .party-cell a { font-family: var(--serif); font-size: var(--fs-2); color: var(--ink); text-decoration: none; }
.matrix .party-cell .sub { display: block; font-weight: 400; font-size: var(--fs-1); color: var(--ink-3); }
.matrix .issue-head { font-weight: 500; font-size: var(--fs-1); color: var(--ink-2); min-width: 118px; padding-inline: var(--s2); }
.matrix td.cell { min-width: 118px; padding: var(--s2); }
.matrix thead th { position: sticky; top: 0; background: var(--surface); z-index: 1; }
.party-row[hidden], .focus-row[hidden] { display: none; }
.focus-ends { display: flex; justify-content: space-between; font-size: var(--fs-1); color: var(--ink-3); max-width: none; margin: var(--s1) 0; }
.focus-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 2px; }
.focus-row { display: grid; grid-template-columns: 160px minmax(0, 1fr); gap: var(--s2) var(--s4); align-items: center; padding: var(--s2) 0; border-bottom: 1px solid var(--line-2); }
.focus-row .focus-name a { color: var(--ink); text-decoration: none; font-weight: 500; }
/* Fifteen lists, each with a paragraph of vote numbers and dates, is a wall rather than a view.
   The sentence stays in the page in full - findable, copyable, and the whole thing is one click
   away on the list's own page - but it shows two lines, so the column can be scanned. The same
   answer the outcome table already reached: the marker is the answer, the words are the reason. */
/* Not clamped. Two lines with the rest revealed on hover meant the whole list of fifteen rows
   reflowed under the pointer as it crossed them, and on a touch screen the hidden half was
   simply unreachable. The axis now lives on a page of its own with room for the full text. */
.focus-row .focus-text { grid-column: 2; }
@media (max-width: 640px) { .focus-row { grid-template-columns: 1fr; } .focus-row .focus-text { grid-column: 1; } }

/* ---------- questionnaire stepper ---------- */
.stepper { display: grid; gap: var(--s4); max-width: 720px; }
.stepper-wide { max-width: none; }
.progress { display: flex; align-items: center; gap: var(--s3); font-size: var(--fs-1); color: var(--ink-3); }
.progress .track { flex: 1; height: 4px; background: var(--line-2); border-radius: var(--r-sm); overflow: hidden; }
.progress .track > span { display: block; height: 100%; background: var(--blue); }
.step { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r); padding: var(--s4) var(--s5); }
.step h2 { margin-bottom: var(--s1); }
.step .hint { color: var(--ink-2); font-size: var(--fs-1); margin: 0 0 var(--s3); }
.likert { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--s2); margin-top: var(--s2); }
/**
 * A control's own outline carries 3:1 (WCAG 2.1, 1.4.11); a decorative line does not have to.
 *
 * `--line` is 1.27:1 against paper, which is right for what it mostly does - separating rows of a
 * table, drawing the edge of a card whose surface colour already sets it apart. None of that is
 * "information required to identify a component", so none of it is in scope, and darkening the
 * variable itself would have repainted 58 rules to fix three.
 *
 * These three are in scope, because here the outline is the whole of what says "this is something
 * you can choose": an unanswered Likert row is five empty boxes, and its radio is a ring with
 * nothing in it. The chosen state was never the problem - it carries a blue fill and a blue border
 * (ADR-0031 said as much) - the unchosen one was.
 *
 * #8c8e8b keeps the hue of --line and reaches 3.02:1 on paper and 3.30:1 on white; the dark
 * palette's #5f6b78 reaches 3.01:1 on surface and 3.31:1 on paper.
 */
.likert label { display: grid; gap: var(--s1); justify-items: center; text-align: center; padding: var(--s2) var(--s1); border: 1px solid var(--line-control); border-radius: var(--r); cursor: pointer; font-size: var(--fs-1); color: var(--ink-2); }
.likert label:hover { border-color: var(--ink-3); }
.likert input { position: absolute; opacity: 0; width: 0; height: 0; }
.likert label:has(input:checked) { background: var(--blue-soft); border-color: var(--blue); color: var(--blue-ink); font-weight: 500; }
.likert .dot { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--line-control); }
.likert label:has(input:checked) .dot { background: var(--blue); border-color: var(--blue); }
.skip { font-size: var(--fs-1); color: var(--ink-3); background: none; border: 0; padding: var(--s1) 0; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.skip.on { color: var(--blue-ink); }
.step-nav { display: flex; justify-content: space-between; gap: var(--s3); align-items: center; }
.importance { display: grid; gap: var(--s2); }
.importance .row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s2) var(--s4); align-items: center; padding: var(--s2) 0; border-bottom: 1px solid var(--line-2); }
.importance .row:last-child { border-bottom: 0; }
/* On a phone the four weight chips claim the whole `auto` column, leaving the topic name a sliver
   to wrap in — "מערכת המשפט ויחסי הרשויות" broke over three lines and the chips wrapped back across
   it. Below 640px the name gets its own row and the chips sit under it. */
@media (max-width: 640px) {
  .importance .row { grid-template-columns: 1fr; gap: var(--s2); align-items: start; }
}
/* The weight now closes each topic instead of opening the questionnaire, so it needs to read as
   a question rather than as a settings row: a rule above it, and the prompt in the body voice. */
/* No border of its own: the last question already draws one, and the two together read as a
   double rule under a heading that is not a heading. */
.topic-weight { margin-top: var(--s3); }
.topic-weight .tw-q { margin: 0 0 var(--s2); font-weight: 500; color: var(--ink-2); font-size: var(--fs-1); }
.topic-weight .faint { margin-top: var(--s2); }
.chips { display: inline-flex; gap: var(--s1); flex-wrap: wrap; }
/* a chip never breaks its own label across lines - that is what makes the row's width predictable */
.chips label { padding: var(--s1) var(--s3); border: 1px solid var(--line-control); border-radius: var(--r-pill); font-size: var(--fs-1); cursor: pointer; color: var(--ink-2); white-space: nowrap; }
.chips input { position: absolute; opacity: 0; width: 0; height: 0; }
.chips label:has(input:checked) { background: var(--blue-soft); border-color: var(--blue); color: var(--blue-ink); }
/* Four chips that fit on one line are one control; a fourth dropped onto its own line reads as a
   separate thing, and "מכריע" - the end of the scale - was the one that dropped. The four need
   about 210px of text between them, so the room comes from the two places that were spending it
   on air: the card's 24px side padding, which is desktop generosity on a phone, and 12px inside
   each chip. That is ~62px recovered, which holds them on one line down to about 350px. Narrower
   than that they wrap again, which is the right failure - the alternative is shrinking the words.
   This block sits after the base .chips rules on purpose: a media query adds no specificity, so
   an identical selector earlier in the file loses, and the first attempt at this changed nothing. */
@media (max-width: 640px) {
  .step { padding-inline: var(--s3); }
  .chips { gap: 3px; }
  .chips label { padding-inline: var(--s2); }
}
/* The measurements above leave 12px of slack at 360px, which is the narrowest width phones still
   in use actually report. Twelve pixels is about four percent of the row, and a different Hebrew
   fallback font on someone else's Android can eat four percent. So below 380px - where the only
   alternative is the wrap we are removing - the chips give up another 2px a side and 1px of gap,
   which buys thirty. Above 380px nothing tightens, because nothing needs to. */
@media (max-width: 380px) {
  .chips { gap: 2px; }
  .chips label { padding-inline: 6px; }
}

/* inline scale ends */
.ends { display: flex; justify-content: space-between; gap: var(--s2); font-size: var(--fs-1); line-height: 1.2; color: var(--ink-3); font-weight: 400; }
.ends .end { max-width: 48%; }
.ends .end-l { text-align: left; }
.matrix .issue-head .issue-title { display: block; margin-bottom: var(--s1); color: var(--ink); }
.matrix .issue-head .ends { padding: 0 var(--s2); }
.stance-row .ends { margin-top: 2px; padding: 0 var(--s2); }
.focus-axis { display: grid; grid-template-columns: 160px minmax(0, 1fr); gap: var(--s2) var(--s4); padding: var(--s1) 0; border-bottom: 1px solid var(--line); }
.focus-axis .ends { font-size: var(--fs-1); color: var(--ink-2); padding: 0 var(--s2); }
/* .focus-axis is the header row of the single-issue view and its .focus-name is an empty spacer
   that lines the scale legend up with the party rows below. Once the row collapses to one column
   the spacer has nothing to align, so it goes; the party names themselves are in .focus-row and
   were never hidden. (An earlier read of this file had it backwards.) */
@media (max-width: 640px) { .focus-axis { grid-template-columns: 1fr; } .focus-axis .focus-name { display: none; } }

/* questionnaire results v2 */
.recap { margin-bottom: var(--s2); padding-block: var(--s3); }
/* One line, open or closed. The heading stays a real h2 for anyone navigating by headings; it is
   simply inline, so the counts sit beside it instead of under it. The summary is deliberately not
   a flex container - that removes the native disclosure triangle, and then nothing says it opens. */
/* A control that opens in place, not a record that expands, so it wears the control's colour
   (ADR-0028). It was the one summary on the site in --ink that was not a .claim, and it was the
   example the first version of that decision was wrongly generalised from. */
.recap-d > summary { cursor: pointer; color: var(--blue-ink); }
.recap-d > summary:hover, .recap-d > summary:focus-visible { color: var(--blue); }
.recap-d > summary h2 { display: inline; font-size: var(--fs-3); margin: 0; color: inherit; }
.recap-d > summary::marker { color: var(--ink-3); }
.recap-sum { color: var(--ink-2); font-size: var(--fs-1); margin-inline-start: var(--s2); }
.recap-acts { margin: var(--s2) 0 0; }
/* Nine topics in one column left half the width empty on a desktop; two columns from 720px up.
   auto-fill rather than a fixed 2, so it collapses to one column on a phone without a media query. */
.recap-list { list-style: none; padding: 0; margin: var(--s2) 0; display: grid; gap: var(--s1) var(--s5); grid-template-columns: repeat(auto-fill, minmax(min(100%, 430px), 1fr)); }
/**
 * The three things a control can be, and what each one wears (ADR-0028).
 *
 * `.linkish` used to be all of them: blue with an underline, which on this site is what a link to
 * another page looks like, worn by twenty-five controls that did three different jobs - jumping to
 * a step, opening a panel, and erasing every answer the reader had given. The last of those sat
 * beside the first, separated by a "·", in identical dress.
 *
 * It keeps the costume only for what earns it: moving the reader to another screen of the tool,
 * which is navigation even though no page is fetched. The other two are below.
 */
.linkish { font: inherit; font-size: var(--fs-1); color: var(--blue-ink); background: none; border: 0; padding: 0; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
/* Destructive, and the only one on the site. Not blue, because blue here means "this will take you
   somewhere" and this takes nothing anywhere - it removes what the reader spent the session on.
   The underline stays: it is still a control in a line of text. 6.88:1 on paper. */
.linkish.danger { color: var(--rose); }
.linkish.danger:hover, .linkish.danger:focus-visible { color: var(--rose); text-decoration-thickness: 2px; }
/* Opens in place. The costume is the one the site already uses for a disclosure that is a control
   rather than a record - blue text, grey marker, no underline - copied from
   details.evidence-block's summary so that the two are the same thing wherever they appear.
   The marker is drawn from aria-expanded, which means it cannot show open while the control says
   closed: the attribute is the state, not a second copy of it. */
.disclose { font: inherit; font-size: var(--fs-1); color: var(--blue-ink); background: none;
  border: 0; padding: 0; cursor: pointer; }
.disclose::before { content: "◂ "; color: var(--ink-3); }
.disclose[aria-expanded="true"]::before { content: "▾ "; }
.disclose:hover, .disclose:focus-visible { color: var(--blue); }
.sc-v { font-family: var(--serif); font-size: var(--fs-4); line-height: 1; }
.sc-c { font-size: var(--fs-1); color: var(--ink-3); }
.why summary { cursor: pointer; font-size: var(--fs-1); color: var(--blue-ink); }
.why table { font-size: var(--fs-1); }
.deep h3 { margin: var(--s4) 0 var(--s2); }
.deep table { font-size: var(--fs-1); }

/* results: stacked views, tables */
.rview { margin: var(--s5) 0; }
.rview > h2 { margin-bottom: var(--s1); }
.rview > .lead { color: var(--ink-2); margin-top: 0; }
.rtable .pname { font-weight: 500; white-space: nowrap; }
.rtable .pname a { color: var(--ink); text-decoration: none; }
.rtable td.num { min-width: 130px; }
.rtable .sc-v { font-family: var(--serif); font-size: var(--fs-4); line-height: 1; }
.rtable .bar { max-width: 140px; }
.rtable .why-row td { background: var(--paper); }
.rtable table.inner { font-size: var(--fs-1); background: transparent; min-width: 560px; }
.rtable .why-row .table-scroll { border: 0; }
.rtable table.inner th, .rtable table.inner td { border-bottom-color: var(--line); }

/* Present to a screen reader, absent from the page. */
.vh { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0; }

/* The explanation a phone reader could not reach: it was written on the cell as a `title`, and a
   touch screen has no hover. Printed in the card, hidden wherever the hover works. */
.sc-touch { display: none; }
/* The unit belongs to the card, where there is no column heading over the number. */
.sc-unit { display: none; }

/* The light/dark control, in the footer. A label and a select rather than a cycling button: three
   states behind one button means pressing it twice to reach the one you want, and guessing which
   one you are on. */
.theme-pick { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; }
.theme-pick select { font: inherit; font-size: var(--fs-1); color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: var(--s1) var(--s2); min-height: 32px; }

/* The same debt, where the text behind the hover is a paragraph rather than a sentence: it is on
   the card, one tap down. It was left deliberately plain while the affordances on this page did
   not agree with each other; ADR-0028 settled that, and this is a control that opens in place. */
.sc-more > summary { cursor: pointer; color: var(--blue-ink); font-size: var(--fs-1);
  padding-block: var(--s1); }
.sc-more > summary:hover, .sc-more > summary:focus-visible { color: var(--blue); }
.sc-more > p { margin: var(--s1) 0 0; }

/* Both arrangements of the words above the first number are in the page and the stylesheet shows
   one. Written this way rather than chosen when the results are built, so that a window dragged
   across 620px needs no re-render and nothing can be left over from the other width. What is not
   shown is `display: none`, so it is out of the accessibility tree too and nothing is read twice. */
.narrow-only { display: none; }
@media (max-width: 620px) {
  .wide-only { display: none; }
  .narrow-only { display: block; }
  .fit-legend.narrow-only, .fit-sortbar.narrow-only { display: flex; }
}

/* The fold over the words above the first number, and the key to the bar beside the bars. */
.fit-help { margin: var(--s2) 0 0; }
.fit-help > summary { cursor: pointer; color: var(--blue-ink); font-size: var(--fs-1);
  padding-block: var(--s1); }
.fit-help > p { margin: var(--s2) 0 0; }
/* These two carry no `display` of their own: `.narrow-only` above hides them, and a later rule of
   equal weight saying `flex` would quietly win it back at every width - which is exactly what it
   did, leaving the legend and the phone's sort control on a 1000px page. The flex is set on the
   compound selector inside the media query, where it outranks both. */
.fit-legend { flex-wrap: wrap; gap: var(--s1) var(--s3); margin: var(--s2) 0 0; }
.fit-legend .fit-key { margin-inline-end: 0; }
.fit-sortbar { align-items: center; gap: var(--s2); margin: var(--s3) 0 var(--s2); }
.fit-sortbar select { font: inherit; font-size: var(--fs-1); color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: var(--s1) var(--s2); min-height: 32px; max-width: 100%; }

/* The "why?" sheet. Its own scroll, so ten screens of reasoning do not move the list behind it.
   The head does not scroll with the body: the panel is as tall as fourteen questions, and a close
   button that is only at the top is a close button a reader loses on the first swipe - on a phone
   there is no Escape key to fall back on either. So the dialog is a column, the head is fixed at
   its top and only the body moves. The padding that .sheet puts on the element itself moves onto
   the two rows, or the head would be a floating band with content sliding past beside it. */
/* `display` belongs on [open] alone. Written as `.why-sheet, .why-sheet[open]` it also applied to
   the CLOSED dialog, overriding the `display: none` a closed <dialog> gets from the UA - so an
   empty panel with an unclosable × sat at the foot of the questionnaire, at every width, with no
   way to dismiss it because nothing had opened it. Everything that is not `display` can stay on
   the element; only this one line decides whether the dialog exists. */
.why-sheet { padding: 0; }
.why-sheet[open] { display: flex; flex-direction: column; max-height: 85vh; overflow: hidden; }
.why-sheet .sheet-head { flex: 0 0 auto; padding: var(--s4) var(--s5) var(--s2);
  border-bottom: 1px solid var(--line); }
.why-sheet .sheet-head h2 { font-size: var(--fs-3); margin: 0; }
.why-sheet .why-sheet-body { flex: 1 1 auto; overflow: auto; padding: 0 var(--s5) var(--s5); }
.why-sheet .why-list { max-width: none; padding-inline: 0; }
/* the × is the only way out on a touch screen: a tap target, not a glyph */
.why-sheet .sheet-x { min-width: 44px; min-height: 44px; margin: calc(-1 * var(--s2)) calc(-1 * var(--s2)) 0 0; }

/**
 * The phone: the fit table is read as cards.
 *
 * Measured at 375px, the table was 628px wide inside a 343px window - name plus one reading on
 * screen at a time, no frozen name, so scrolling to the third reading left a column of percentages
 * belonging to nobody, and the "why?" button sat in a trailing column that was off screen until you
 * dragged the table sideways. Comparing the three readings for one list, which is the whole point
 * of showing three, could not be done at all.
 *
 * One list is one card and the three readings stack inside it, each with the name of its column in
 * front of it. Nothing scrolls sideways. Above 620px not one of these rules applies and the table
 * is the table it has always been.
 *
 * The head is hidden the way .vh hides things, not with `display: none`: `display: block` on the
 * table already costs the implicit table semantics (the roles in the markup put those back), and
 * removing the column headings from the accessibility tree as well would leave the cells with
 * nothing to be associated with.
 *
 * The skeleton below - block layout, the clipped head, and the labelled row built out of
 * `data-label` - is the shape of every card on the site, so each table that reads as cards joins
 * those selectors rather than getting a copy that drifts. What is particular to one table (which
 * cell is the headline, which value is a sentence, how many pairs sit on a line) stays with that
 * table: the questionnaire's `.pname` / `.seats` rules are below, the lists table's are beside
 * `.party-table`, the poll grid's beside `.polls`.
 *
 * Four tables share the list now, which is one more than it was meant to carry. The next one to
 * join turns it into `table.cards` instead: that selector has the same specificity as
 * `table.plain` and so wins on order, and the only reason it is not written that way already is
 * that `.rtable.cards` got here first.
 */
@media (max-width: 620px) {
  .cards-wrap { border: 0; border-radius: 0; overflow: visible; }
  .rtable.cards, .party-table.cards, .polls.cards, .spread.cards { display: block; background: transparent; font-size: var(--fs-2); }
  .rtable.cards thead, .party-table.cards thead, .polls.cards thead, .spread.cards thead { position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip-path: inset(50%); white-space: nowrap; }
  .rtable.cards tbody, .party-table.cards tbody, .polls.cards tbody, .spread.cards tbody { display: block; }
  .rtable.cards tr { display: block; }
  /* `display: block` on a tr outranks the UA's `[hidden] { display: none }`, which is an attribute
     selector alone - so every one of the fifteen collapsed panels unfolded at once and the page
     measured 144,928px. Anything hidden stays hidden. */
  .rtable.cards tr[hidden] { display: none; }
  .rtable.cards tr[data-party] { background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--r); padding: var(--s3) var(--s4) var(--s2); margin-bottom: var(--s3); }
  .rtable.cards td, .party-table.cards td, .polls.cards td, .spread.cards td { display: block; border-bottom: 0; padding: 0; }
  .rtable.cards td.pname { font-size: var(--fs-3); white-space: normal; padding-bottom: var(--s2); }
  /* A cell earns its label by carrying one: `data-label` is both the text printed in front of the
     value and the mark that says this cell is a labelled row of a card. Keying on the attribute
     rather than on `.num` is what lets a cell that is not a number - the threshold verdict, the
     coalition line - take the same shape without being given a class that means something else on
     a desktop. */
  .rtable.cards td[data-label], .party-table.cards td[data-label], .polls.cards td[data-label], .spread.cards td[data-label] { display: grid; grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline; column-gap: var(--s3); min-width: 0;
    padding: var(--s2) 0; border-top: 1px solid var(--line-2); }
  .rtable.cards td[data-label]::before, .party-table.cards td[data-label]::before, .polls.cards td[data-label]::before, .spread.cards td[data-label]::before { content: attr(data-label); grid-column: 1; grid-row: 1;
    color: var(--ink-3); font-size: var(--fs-1); }
  .rtable.cards td[data-label] > .sc-v, .rtable.cards td[data-label] > .sc-na,
  .rtable.cards td[data-label] > .risk-text { grid-column: 2; grid-row: 1; justify-self: end; }
  .rtable.cards td[data-label] > .sc-when { grid-column: 2; justify-self: end; }
  .rtable.cards td[data-label] > .fit, .rtable.cards td[data-label] > .sc-c,
  .rtable.cards td[data-label] > .sc-basis, .rtable.cards td[data-label] > .sc-touch { grid-column: 1 / -1; }
  .rtable.cards td[data-label] > .sc-touch { display: block; margin-top: var(--s1); }
  /* A cell whose value is a sentence, not a figure: the label goes above it and the text gets the
     whole width. Beside a label in the same line it would be a 107px column again. */
  .rtable.cards td[data-label].stack, .party-table.cards td[data-label].stack { display: block; }
  .rtable.cards td[data-label].stack::before, .party-table.cards td[data-label].stack::before { display: block; margin-bottom: 2px; }
  /**
   * The head of an outcome card: the list and its seats on one line, and the threshold only when
   * it has something to say.
   *
   * As four labelled rows this card spent three of them on two numbers - "מנדטים, ממוצע בתי
   * הסקרים" over 21.7, the poll's date under it, and "אחוז החסימה" over the word "מעל", which is
   * the unremarkable answer eleven of fifteen lists give. The seats move up beside the name, where
   * a reader looking at "הליכוד" is already looking, and the threshold line appears only for a
   * list that is under it, near it, or has no poll at all.
   *
   * `low` is the only one hidden, and not "anything that is not below": a list polling above the
   * line whose range dips under it is the borderline case a voter most needs told about, and
   * hiding it would make it look exactly like the largest list in the country. Today's data has
   * none - four high, eleven low - which is precisely why the rule has to be written for the day
   * it does.
   *
   * The date stays on the card. It reads like boilerplate because fifteen lists usually share one
   * poll, but they do not always: two of these sit at 0 seats on an older date than the rest, and
   * "0 as of the 11th" is a different statement from "0 as of the 18th".
   */
  .rtable.cards tr[data-party] { display: grid; grid-template-columns: minmax(0, 1fr) auto;
    column-gap: var(--s3); align-items: baseline; }
  .rtable.cards tr[data-party] > td { grid-column: 1 / -1; }
  .rtable.cards td.pname { grid-column: 1; grid-row: 1; padding-bottom: 0; }
  .rtable.cards td.seats { grid-column: 2; grid-row: 1; display: block; text-align: end;
    border-top: 0; padding: 0; }
  .rtable.cards td.seats::before { content: none; }
  .rtable.cards td.seats .sc-v { font-size: var(--fs-3); }
  .rtable.cards td.seats .sc-unit { display: inline; color: var(--ink-3); font-size: var(--fs-1);
    margin-inline-start: 3px; }
  .rtable.cards td.risk { display: block; border-top: 0; padding: var(--s1) 0 0; font-weight: 500; }
  .rtable.cards td.risk::before { content: none; }
  /* The one verdict with nothing to report. Written as `.risk-low` and not as "everything except
     high" so that `medium` and `unknown` keep showing. */
  .rtable.cards td.risk-low { display: none; }
  /* the coalition cell is the first thing under the head, so it carries the rule */
  .rtable.cards td.stack { margin-top: var(--s2); }
  .rtable.cards td.why-cell { border-top: 1px solid var(--line-2); padding-top: var(--s2); margin-top: var(--s2); }
  /* the tap target the button did not have when it was one cell of a row */
  .rtable.cards td.why-cell .linkish { display: inline-block; min-height: 32px; line-height: 32px; }
  /* the inline panel, for a browser with no showModal(): it is a block in the card, not a cell */
  .rtable.cards .why-row > td { padding-top: var(--s2); }
}

/* polls */
table.polls th, table.polls td { white-space: nowrap; }
table.polls .pollster { min-width: 160px; white-space: normal; }
table.polls td.num { text-align: center; font-variant-numeric: tabular-nums; }
table.polls td.num.below { color: var(--rose); font-weight: 600; }

/* ---- candidate page ----
   The old page was one column of same-weight paragraphs: a fourteen-number list of Knesset terms in
   the header, roles as bullets reading "? עד היום", and every claim in one collapsed blob at the
   bottom. This gives it a spine: who they are, then what they did, then where they stand. */
.person-head { padding-bottom: var(--s1); }
.person-head h1 { margin-bottom: 2px; }
.person-role { color: var(--ink-2); font-size: var(--fs-2); margin: 0; }
.person-role strong { color: var(--ink); }

.facts-person { grid-template-columns: 1fr; gap: var(--s3); margin-bottom: var(--s5); }
@media (min-width: 620px) { .facts-person { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) { .facts-person { grid-template-columns: repeat(4, 1fr); } }
.facts-person .fact .sub { padding-top: var(--s1); }
/**
 * A tinted tile needs one step more ink than a white one.
 *
 * `--ink-3` was tuned in ADR-0031 against the two backgrounds it usually sits on: paper (4.58:1)
 * and surface (5.01:1). The site has seven. On the four tinted fills and on --line-2 the same ink
 * lands between 4.10 and 4.44 - under AA for normal text, by a margin too small to see and too
 * real to keep. This tile is the one place the combination actually occurs, and the fix is local
 * rather than another darkening of the variable: dropping `--ink-3` further would shorten the
 * step between it and `--ink-2` everywhere, which is the cost ADR-0031 already weighed once.
 */
.fact-legal { border-color: var(--rose); background: var(--rose-soft); }
.fact-legal .k { color: var(--ink-2); }

/* roles as a spine with the years pinned to the start of the line, so the eye reads down the dates */
.role-timeline { list-style: none; padding: 0; margin: var(--s3) 0 var(--s4); display: grid; gap: 0; }
.role-timeline li { display: grid; grid-template-columns: 10.5ch 1fr; gap: var(--s4); align-items: baseline;
  padding: var(--s2) 0; border-bottom: 1px solid var(--line-2); }
.role-timeline li:last-child { border-bottom: 0; }
.role-when { font-variant-numeric: tabular-nums; color: var(--ink-3); font-size: var(--fs-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.role-what { min-width: 0; }
@media (max-width: 520px) {
  .role-timeline li { grid-template-columns: 1fr; gap: 1px; }
  .role-when { font-size: var(--fs-1); }
}

.person-bg { color: var(--ink-2); margin: 0 0 var(--s4); }

/* the record as one column of dated lines with a kind chip, rather than a stack of accordions each
   holding one item. Reading down the years is how a record is actually judged. */
.rec-tally { color: var(--ink-3); font-size: var(--fs-1); margin: 2px 0 var(--s3); }
.record-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.rec-item { display: grid; grid-template-columns: 10ch 8.5ch 1fr; gap: var(--s3); align-items: baseline;
  padding: var(--s3) 0; border-top: 1px solid var(--line-2); font-size: var(--fs-1); }
.rec-item:first-child { border-top: 0; }
.rec-when { font-variant-numeric: tabular-nums; color: var(--ink-3); font-size: var(--fs-1); white-space: nowrap; }
.rec-kind { font-size: var(--fs-1); color: var(--ink-2); background: var(--line-2); border-radius: var(--r-sm);
  padding: 1px var(--s2); text-align: center; white-space: nowrap; }
.rec-kind-say { background: transparent; border: 1px solid var(--line); color: var(--ink-3); }
.rec-text { min-width: 0; }
@media (max-width: 620px) {
  .rec-item { grid-template-columns: auto auto; gap: var(--s1) var(--s2); }
  .rec-text { grid-column: 1 / -1; }
}
.record-more { margin-top: var(--s3); border-top: 1px solid var(--line-2); }
.record-more > summary { cursor: pointer; padding: var(--s3) 0 var(--s1); color: var(--blue-ink); font-size: var(--fs-1); }
.record-more > summary:hover { color: var(--blue); }

/* said on their behalf by someone else — visually separate from their own conduct on purpose */
.proxy-list { margin-top: var(--s3); }
.proxy-item { border-inline-start: 3px solid var(--line); padding-inline-start: var(--s3); }
.proxy-response { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: baseline;
  font-size: var(--fs-1); color: var(--ink-2); margin: var(--s2) 0 2px; }
.ref-missing { color: var(--ink-3); font-size: var(--fs-1); white-space: nowrap; }
/* polls: the average row is the number the rest of the site uses, so it leads the table */
.polls td.num.strong { font-weight: 700; }
.move-up { color: var(--moss); font-weight: 600; }
.move-down { color: var(--rose); font-weight: 600; }
.event-response { font-size: var(--fs-1); color: var(--ink-2); border-inline-start: 2px solid var(--line); padding-inline-start: var(--s3); margin: var(--s2) 0 2px; max-width: none; }

/* Evidence pulled from a database, shown as a record rather than dressed as a quotation. */
.record { border: 1px solid var(--line); border-radius: var(--r); background: var(--paper); margin: var(--s2) 0; overflow: hidden; }
.record-label { font-size: var(--fs-1); color: var(--ink-3); padding: var(--s1) var(--s3) 0; }
.record pre { margin: 0; padding: var(--s1) var(--s3) var(--s2); font-size: var(--fs-1); line-height: 1.45; overflow-x: auto; white-space: pre-wrap; word-break: break-word; }

/* The hero's standing caveat: what this is, what it is not, and that a gap is a gap and not a clean bill. */
.site-footer p + p { margin-top: var(--s2); }


/* A grid or flex item defaults to min-width:auto, so a wide table inside one pushes the container
   past the viewport instead of scrolling within it. The results view did exactly that: 750px of
   document on a 375px phone. Letting these shrink is what makes the scroll container work. */
.stepper, .stepper > *, .rview, .rview > *, .table-scroll, .matrix-wrap { min-width: 0; }
.table-scroll, .matrix-wrap { max-width: 100%; }

/* Citation chips are the most-tapped thing on a phone and were 15x20px. Inline links inside a
   sentence are exempt from the 24px target rule, but being exempt does not make them tappable. */
a.ref { display: inline-block; min-width: 24px; min-height: 24px; line-height: 24px; text-align: center; }
/**
 * One colour for a citation chip, wherever it sits (ADR-0028).
 *
 * The same [1] rendered in two colours on the same page, decided by its container rather than by
 * anything about it: grey inside .stance-text, the default blue everywhere else. On one party page
 * that was 21 grey and 4 blue; on one candidate page, 3 grey and 6 blue.
 *
 * It settles on --ink-2 and not on the --ink-3 the grey ones were using, because --ink-3 measures
 * 3.46:1 against the paper and these are small text: the majority colour was failing AA, and
 * extending it would have spread a contrast failure in the name of consistency. --ink-2 is 7.24:1,
 * quiet enough that a paragraph with twenty of them still reads as a paragraph, and blue is left
 * to mean a link the reader is meant to follow rather than a marker beside a sentence.
 */
a.ref { color: var(--ink-2); }
a.ref:hover, a.ref:focus-visible { color: var(--blue-ink); }

/* The matrix is 15 lists by 7 policy issues (wedge_issues.json holds 8; the coalition one is
   filtered out in templates/html.js). In a 343px window that is a 1044px table whose scales get
   sliced mid-symbol at the scroll edge — correct overflow that reads as breakage. The single-issue
   view below is the same data in a shape a phone can hold, so on small screens it takes over. */

/* The matrix used to be display:none below 720px, which deleted the main comparison view from
   every phone. It scrolls sideways instead, with the list name frozen so a row never loses its
   subject. party-cell needs its own background and stacking order or the scrolling cells show
   through it; the head cells sit above the body cells, and the corner above both. */
@media (max-width: 720px) {
  .matrix .issue-head { min-width: 112px; }
  .matrix td.cell { min-width: 112px; }
  .matrix .party-cell { width: 132px; min-width: 132px; }
}

/**
 * The phone: two axes on screen, stepped with a labelled control, nothing compressed.
 *
 * Which two is decided here and not in JavaScript, so that above 620px no rule matches, every
 * column is shown whatever `data-page` says, and a window dragged across the breakpoint cannot
 * leave a reader looking at two columns of a table with room for seven.
 *
 * 343px of usable width, 100px of frozen list name, two columns of about 121px each - which is
 * what the scale needs to draw a track, five ticks and two markers without crowding them. Seven
 * axes are four pages; the rules run to six so that an eighth and a ninth axis page themselves
 * without anyone having to remember this block exists.
 */
@media (max-width: 620px) {
  .matrix[data-page="0"] [data-col]:not([data-col="0"]):not([data-col="1"]) { display: none; }
  .matrix[data-page="1"] [data-col]:not([data-col="2"]):not([data-col="3"]) { display: none; }
  .matrix[data-page="2"] [data-col]:not([data-col="4"]):not([data-col="5"]) { display: none; }
  .matrix[data-page="3"] [data-col]:not([data-col="6"]):not([data-col="7"]) { display: none; }
  .matrix[data-page="4"] [data-col]:not([data-col="8"]):not([data-col="9"]) { display: none; }
  .matrix[data-page="5"] [data-col]:not([data-col="10"]):not([data-col="11"]) { display: none; }
  .matrix-wrap { overflow-x: visible; }
  /* `fixed`, or the widest end-label sets the column: "נגד ועדה ממלכתית" pushed its column to
     156px and the page 13px past the screen. Fixed lets the two visible columns split whatever is
     left after the frozen name, and the labels wrap inside it. */
  .matrix { min-width: 0; table-layout: fixed; width: 100%; }
  .matrix .issue-head .end { white-space: normal; overflow-wrap: anywhere; }
  .matrix .party-cell { width: 100px; min-width: 100px; padding-inline: var(--s2) var(--s1); }
  .colpager.narrow-only { display: flex; }
  .matrix .issue-head, .matrix td.cell { min-width: 0; }
  .matrix th, .matrix td { padding-inline: var(--s1); }
  /* the scale fills whatever the column gives it, rather than demanding 120px of its own */
  .matrix .scale { min-width: 0; }
}

/**
 * The phone: the house-effect table is read as cards.
 *
 * Six columns, and two of them hold a name. Before the names were shortened the table was 447px
 * in a 341px window and two of its six rows were 400px tall, a single cell of prose setting the
 * height of everything beside it. Shortening the name fixed the prose; six columns still do not
 * fit a phone.
 *
 * The gap sits on the headline beside the list, because it is what the row is for and what the
 * table is sorted by. Under it the four readings keep their order - highest, at whom, lowest, at
 * whom - so "אצל" needs no disambiguating label: it is directly under the number it belongs to,
 * which is the adjacency the desktop column heading relies on too.
 */
@media (max-width: 620px) {
  .spread.cards tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) auto;
    column-gap: var(--s3); align-items: baseline;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
    padding: var(--s3) var(--s4) var(--s2); margin-bottom: var(--s3); }
  .spread.cards tbody tr > td { grid-column: 1 / -1; }
  .spread.cards td.sp-name { grid-column: 1; grid-row: 1; padding: 0; border-top: 0;
    font-size: var(--fs-3); line-height: 1.25; }
  .spread.cards td.sp-gap { grid-column: 2; grid-row: 1; display: block; padding: 0; border-top: 0;
    text-align: end; }
  /* The label above the figure rather than beside it: a two-word heading and a four-character
     number, and this is the corner of the card where the eye lands. */
  .spread.cards td.sp-gap::before { display: block; }
  .spread.cards td.sp-gap strong { font-size: var(--fs-3); font-weight: 600; }
}

/* The pager itself. Hidden until the script has counted the columns and written a label, so a
   reader without JavaScript never meets two dead buttons - there the table simply scrolls, which
   is what it did before any of this. */
/* No `display` here. `.narrow-only` has to win, and a later rule of equal weight takes it back -
   which is now the third time in this stylesheet: .fit-legend, .map-key, and this. The flex goes
   on the compound selector inside the media query, where it outranks both. */
.colpager { align-items: center; gap: var(--s2); flex-wrap: wrap;
  margin: var(--s3) 0 var(--s2); }
.colpager .btn { font-size: var(--fs-1); padding: var(--s1) var(--s3); white-space: nowrap; }
.colpager .btn:disabled { opacity: .45; cursor: default; }
.colpager .btn:disabled:hover { background: transparent; color: var(--blue-ink); }
.colpager-at { flex: 1 1 100%; order: -1; font-size: var(--fs-1); color: var(--ink-2); }
.matrix .party-cell { position: sticky; inset-inline-start: 0; background: var(--surface); z-index: 1; }
.matrix thead th { z-index: 2; }
.matrix thead th.party-cell { z-index: 3; }
.matrix-wrap:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/* Nine columns do not fit a phone, and scrolling them sideways loses the one thing that says
   which row you are reading. The map already freezes the list name; this table did not, so the
   same gesture behaved differently on two pages that show the same fifteen lists. The name is a
   row header now - it is what the row is about, not one of its values - which is also what lets
   it be frozen, and it carries the surface colour so the cells pass underneath rather than
   through. Same pattern as the poll identifier on the polls page. */
.party-table th.party-name { position: sticky; inset-inline-start: 0; background: var(--surface);
  z-index: 1; text-align: start; width: 140px; min-width: 132px;
  /* a th is bold by default and this cell was a td: the freeze is the only change being made,
     and the name stays the table's own blue underlined link, like every other link in the row */
  font-weight: 400; }
.party-table thead th { position: sticky; top: 0; background: var(--surface); z-index: 2; }
.party-table thead th.party-name { z-index: 3; }

/**
 * The phone: the lists table is read as cards (ADR-0029, ADR-0032).
 *
 * Measured at 375px, the table was 793px inside a 341px window - 452px of sideways drag, a third
 * of it. The name was already frozen, so this was not the questionnaire's "percentages belonging
 * to nobody"; the cost was different and larger. Every row's height is set by the two count
 * columns, and both of them are off screen: הליכוד filled 184px with 46px of text, עוצמה יהודית
 * filled 232px with 22px, and **683px of the table's 1,714px - forty per cent - was blank.** The
 * frozen name itself took 132px of a 341px window, leaving 209px, which is two of the seven value
 * columns at a time.
 *
 * Two things no check could have caught. `npm run a11y` passes the page, because the overflow is
 * contained inside `.table-scroll` and the document measures a clean 375px - the check reads the
 * document, and the document was never the problem. And `.table-scroll` carries no `tabindex`, so
 * those 452px were not reachable by keyboard at all; below 620px nothing scrolls sideways any
 * more, which is the only place that overflow ever existed.
 *
 * One list is one card. The name and the seats sit on the headline row together, because a reader
 * looking at "הליכוד" is already looking there, and everything else is a labelled line under it.
 * Above 620px not one of these rules applies.
 */
@media (max-width: 620px) {
  .party-table.cards tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) 38%;
    column-gap: var(--s3); align-items: baseline;
    background: var(--surface); border: 1px solid var(--line); border-radius: var(--r);
    padding: var(--s3) var(--s4) var(--s2); margin-bottom: var(--s3); }
  .party-table.cards tbody tr > * { grid-column: 1 / -1; }
  /* Nothing scrolls sideways here any more, so there is nothing for the freeze to hold still
     against, and the 132px it reserved is the card's whole width. */
  .party-table.cards th.party-name { position: static; width: auto; min-width: 0; display: block;
    grid-column: 1; grid-row: 1; border-bottom: 0; padding: 0;
    font-size: var(--fs-3); line-height: 1.25; }
  /* The headline number. It drops its label the way the outcome card does: the column heading is
     a full sentence ("מנדטים, ממוצע בתי הסקרים") and the noun alone belongs beside a figure, so
     the `::before` is off and the markup's `.unit` span carries the word. The note under the
     table still says what the average is made of. */
  .party-table.cards td.c-seats { display: block; grid-column: 2; grid-row: 1; text-align: end;
    border-top: 0; padding: 0; }
  .party-table.cards td.c-seats::before { content: none; }
  .party-table.cards td.c-seats .sv { font-size: var(--fs-3); }
  .party-table.cards td.c-seats .unit { color: var(--ink-3); font-size: var(--fs-1); }
  /* `.tag` is nowrap, which is what a table row wants and what a 130px column cannot have:
     "מתחת לאחוז החסימה" is wider than the column it now lives in. */
  .party-table.cards td.c-seats .tag { white-space: normal; display: inline-block; margin-top: var(--s1); }
  .party-table.cards td.c-seats .faint.small { margin-top: 2px; }
  .party-table.cards td.c-cov .coverage-line { margin-top: var(--s1); }
  /* No `display` here: `.narrow-only` is what shows it, and an equal-weight rule later in the
     file would take that back (ADR-0032, trap 1). */
  .party-table.cards td.c-cov .cov-tally { margin-top: var(--s1); }
}

/* What the site rests on, under the hero. A strip of figures, not a sentence: every cell holds
   its number and its noun together and never breaks inside, and the strip wraps between cells, so
   the worst case is a tidy extra row instead of a ragged paragraph. Quiet on purpose - a statement
   of method, not a dashboard, so no boxes and no oversized numerals. */
/* Above the buttons now, not under them: the evidence is what earns the click, and the call to
   action is the right last thing in a hero. That puts the strip between a tagline and two buttons,
   so it needs air on both sides or its bottom row reads as chrome attached to the button. */
/* The figures back up the sentence above them, so they sit close to it and away from the buttons
   below. The hero is a grid, where margins do not collapse: the tagline's own 8px, the grid's 16px
   row gap and this element's margin all add up, which is how the space above reached 32px. The
   negative pull is deliberate - 32 becomes 12 above, against 28 below - so do not "tidy" it away
   without re-measuring both gaps. */
.corpus { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s2) var(--s4);
  margin: calc(-1 * var(--s3)) 0 var(--s3); font-size: var(--fs-1); color: var(--ink-2); }
.corpus-stat { white-space: nowrap; }
.corpus-stat b { font-size: var(--fs-2); color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; }
/* the one figure that is a caveat rather than a credential: present, and visibly lighter */
.corpus-quiet, .corpus-quiet b { color: var(--ink-3); }
.corpus-quiet b { font-weight: 500; }
/* The strip now sits directly above a button that also goes to the methodology page, and a blue
   underlined link immediately above a blue button reads as a second, competing call to action.
   This one points deeper - to the coverage section - so it stays, but as a quiet text link. It
   keeps --ink-2 rather than dropping to --ink-3, which would not hold contrast at this size. */
.corpus-more { white-space: nowrap; color: var(--ink-2); text-underline-offset: 3px;
  text-decoration-thickness: 1px; }
.corpus-more:hover, .corpus-more:focus-visible { color: var(--blue-ink); }
.corpus span[title] { border-bottom: 1px dotted var(--line); cursor: help; }
@media (max-width: 380px) { .corpus { gap: var(--s2) var(--s3); } }
/* The corpus legend, and any later dialog. Sized to the reading measure, full width on a phone. */

.sheet { max-width: 46rem; width: calc(100% - 2 * var(--s4)); border: 1px solid var(--line);
  border-radius: var(--r); padding: var(--s5); background: var(--paper); color: var(--ink); }
.sheet::backdrop { background: rgba(0, 0, 0, .45); }
/* The fallback path, for a browser without showModal(): [open] alone shows a <dialog> in flow,
   so it is positioned as a centred panel here and .has-sheet on <html> supplies the dim that
   ::backdrop would otherwise draw. Under showModal() the browser positions it and this rule is
   simply never the one in effect. */
.sheet[open] { position: fixed; inset-block-start: 50%; inset-inline-start: 50%;
  transform: translate(50%, -50%); margin: 0; z-index: 50; max-height: 85vh; overflow: auto; }
.has-sheet::before { content: ""; position: fixed; inset: 0; background: rgba(0, 0, 0, .45); z-index: 49; }
@supports selector(dialog::backdrop) { .has-sheet::before { display: none; } }
.sheet h2 { margin: 0 0 var(--s3); }
.sheet-x { float: inline-end; background: none; border: 0; font-size: var(--fs-4); line-height: 1;
  cursor: pointer; color: var(--ink-3); padding: 0 var(--s1); }
.sheet-x:hover, .sheet-x:focus-visible { color: var(--ink); }
.sheet-dl { margin: 0; display: grid; gap: var(--s3); }
.sheet-dl dt { font-weight: 600; }
.sheet-dl dd { margin: var(--s1) 0 0; color: var(--ink-2); }
@media (max-width: 560px) { .sheet { padding: var(--s4); } }

/* ---------- issue pages ---------- */
/* The homepage now lists the issues instead of carrying eight hidden copies of the axis. */
.issue-links { list-style: none; padding: 0; margin: var(--s3) 0 0; display: grid; gap: var(--s2);
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); }
/* Cards in a row must end level. A grid stretches its items, but only if the link inside
   fills the cell - so the anchor is the flex column, not the li. */
.issue-links li { display: flex; }
.issue-links a { display: flex; flex-direction: column; gap: var(--s1); width: 100%;
  padding: var(--s3) var(--s4); border: 1px solid var(--line);
  border-radius: var(--r); background: var(--surface); text-decoration: none; color: var(--ink); }
.issue-links a:hover { border-color: var(--blue); }
.issue-links strong { display: block; font-family: var(--serif); font-size: var(--fs-3); }
/* The two ends used to run as one string and wrap mid-phrase, orphaning a word on line two
   with nothing to attach it to. Each end is its own nowrap unit now. */
.issue-links .ends-pair { display: flex; flex-wrap: wrap; gap: var(--s1); align-items: baseline;
  margin-top: auto; padding-top: var(--s2); }
.issue-links .ends-pair span { white-space: nowrap; }
.issue-links .ends-pair .arrow { color: var(--ink-3); }
/* the scale, spelled out, because the axis below it is unreadable without the ends defined */
.scale-defs { list-style: none; padding: 0; margin: var(--s3) 0 0; display: grid; gap: var(--s2); }
.scale-defs li { display: grid; grid-template-columns: 2.5rem minmax(0, 1fr); gap: var(--s3); align-items: baseline; }
.scale-defs .num { font-family: var(--serif); font-size: var(--fs-3); color: var(--blue-ink); }
/* The scale definitions used to open the issue page and pushed the axis itself below the fold.
   Folded under the axis they answer a question the reader only has after seeing one. */
.scale-key { margin: var(--s4) 0 0; }
.scale-key summary { cursor: pointer; color: var(--blue-ink); font-size: var(--fs-1); }
.scale-key .scale-defs { margin-top: var(--s3); }
/* two columns of quotations, one per end of the scale; one column on a phone */
/* One list of what the biggest lists say, ordered by polling. Replaced a two-column for/against
   layout that duplicated the axis above it and silently dropped every list sitting in the middle. */
.said { list-style: none; padding: 0; margin: var(--s3) 0 0; display: grid; gap: var(--s4); }
.said li { border-inline-start: 2px solid var(--line); padding-inline-start: var(--s3); }
.said-who { margin: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--s1) var(--s3); }
.said-who a { font-weight: 600; }
.said li > p + p { margin: var(--s1) 0 0; font-size: var(--fs-1); color: var(--ink-2); }

/* the in-place explainer under a question: present, quiet, and it never moves the page */
.q-explain { margin: var(--s2) 0 0; font-size: var(--fs-1); }
.q-explain summary { cursor: pointer; color: var(--blue-ink); }
.q-explain p { margin: var(--s2) 0 0; color: var(--ink-2); }
