/* Base styles.
 * Logical properties throughout (inline-start/end, not left/right) so the same
 * CSS serves he/ar RTL and en LTR with no per-language branching. The one
 * physical exception is the bar cluster's lean and warm order (tokens.css).
 *
 * T62 rebuilt the visual layer on the direction docs/DESIGN-DIRECTION.md sets:
 * flat ink, hard edges, one angle, two palettes that never overlap, depth from
 * overlap and colour only, content flush to the inline-start edge. */

*, *::before, *::after { box-sizing: border-box; }

/* Any author `display` rule silently defeats the [hidden] attribute — and the
 * wizard hides steps and buttons with it. This one line is load-bearing. */
[hidden] { display: none !important; }
/* The scrollbar goes on the RIGHT. A `dir="rtl"` root puts the browser's
 * vertical scrollbar on the left, and with a classic (non-overlay) scrollbar
 * that is a pale strip beside the hero's left edge — what the operator saw as "the
 * hero colour doesn't spill all the way to the left border" (2026-09-03,
 * seventh round). Direction on the root element decides the scrollbar side;
 * the document itself stays RTL on <body>. The `dir` attribute on <html>
 * remains for assistive technology and the bidi algorithm. */
html { -webkit-text-size-adjust: 100%; scroll-padding-block-start: 1rem; direction: ltr; }
body { direction: rtl; }
html[dir="ltr"] body { direction: ltr; }
body {
  margin: 0;
  font-family: var(--font-ui, var(--font-he));
  font-size: var(--step-0);
  line-height: 1.65;
  color: var(--c-body);
  background: var(--c-bg);
}
/* The footer ends at the bottom of the screen on a short page (review C7): the
 * thank-you and volunteer pages left a white band under it on a phone. A
 * column with <main> taking the slack.
 *
 * The space above the footer moves INTO <main>, as a zero-height ::after.
 * A flex item is its own formatting context, so the last block's bottom
 * margin no longer collapses out of <main> with the footer's top margin — the
 * gap grew by 16–40 px on every page when the margin stayed on the footer.
 * Inside <main> it collapses with that last margin exactly as before, so the
 * gap is still max(last block's margin, the footer's spacing): measured 48 px
 * at 390 on every page, before and after. */
body { min-block-size: 100vh; min-block-size: 100svh; display: flex; flex-direction: column; }
body > main { flex: 1 0 auto; }
body > main::after { content: ""; display: block; margin-block-start: clamp(3rem, 8vw, 5rem); }

.wrap { width: min(100% - (var(--gutter) * 2), 72rem); margin-inline: auto; }

/* Full-width bands (the hero, the מצע's tinted band, the footer) are ordinary
 * blocks: <main> is full width and pages wrap their own column in `.wrap`. The
 * old `.bleed` negative-margin trick is gone — one of the operator's browsers laid it
 * out with a gap on the left. */

/* Skip link — visible on focus, a WCAG requirement people routinely omit. */
.skip {
  position: absolute; inset-inline-start: 0; inset-block-start: -100%;
  background: var(--c-teal-inkest); color: #fff;
  padding: 0.75rem 1.25rem; z-index: 100; text-decoration: none;
}
.skip:focus { inset-block-start: 0; }

/* Visually hidden, still read aloud. Not `[hidden]` — that removes it from the
 * accessibility tree, which is the opposite of what a screen-reader-only label
 * is for. */
.u-vh {
  position: absolute; inline-size: 1px; block-size: 1px;
  margin: -1px; padding: 0; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* The honeypot. Pushed off-screen rather than `display: none`: a script that
 * fills a form blind fills what it can read, and skips what is obviously
 * hidden. `aria-hidden` and `tabindex="-1"` in the markup keep it away from
 * anyone using a keyboard or a screen reader. */
.u-trap { position: absolute; inset-inline-start: -9999px; inline-size: 1px; block-size: 1px; overflow: hidden; }

/* The focus ring. ONE definition for every focusable thing on the site. Two
 * bands, abutting: the halo fills 0-3px out from the border box, the outline
 * sits on top of that at 3-6px. Whichever band contrasts with what is behind
 * is the one the eye finds; worst case across the palette is 4.38:1. See
 * tokens.css for the measurements and why one colour cannot do this. */
:where(a, button, input, select, textarea, legend, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--c-focus);
  outline-offset: 3px;
  box-shadow: 0 0 0 3px var(--c-focus-halo);
}

/* Type. The scale is --step--1 … --step-3 plus the display step for two uses;
 * headings are 700 (the only bold that exists), tight, balanced. */
h1, h2, h3 { line-height: 1.15; color: var(--c-ink); text-wrap: balance; font-weight: 700; }
/* A heading never widens the page (review A5): "Политика конфиденциальности"
 * made /ru/privacy/ 396 px wide on a 390 px phone. A word too long for the
 * line breaks — hyphenated where the browser has the language's dictionary,
 * only in words of 12+ letters so ordinary English headings are left alone —
 * and `scripts/check-overflow.mjs` fails the build if one still overflows. */
h1, h2, h3 { overflow-wrap: break-word; -webkit-hyphens: auto; hyphens: auto; hyphenate-limit-chars: 12 5 5; }
h1 { font-size: var(--step-3); margin-block: clamp(1.5rem, 4vw, 2.5rem) 1rem; }
h2 { font-size: var(--step-2); margin-block: clamp(2rem, 5vw, 3rem) 0.75rem; }
h3 { font-size: var(--step-1); margin-block: 1.75rem 0.5rem; }
p, ul, ol { max-width: var(--measure); }
p { margin-block: 0 1rem; }
h1 + p, h2 + p, h3 + p { margin-block-start: 0; }
.lede { font-size: var(--step-1); color: var(--c-ink); line-height: 1.45; max-width: 36ch; margin-block-end: 1.5rem; }

a { color: var(--c-teal-ink); text-underline-offset: 0.2em; text-decoration-thickness: 2px; }
a:hover { color: var(--c-teal-inkest); }

/* ---------------------------------------------------------------- Header */
.site-head { border-block-end: 4px solid var(--c-teal-ink); background: var(--c-bg); }
.site-head__inner {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: 0.5rem var(--gutter); padding-block: 1.1rem 0.9rem;
}
.site-head__logo { display: block; }
/* The header carries logo-mark.png — the lockup cropped to wordmark + mark
 * (the operator, 2026-09-20), because the tagline band is illegible at this size.
 * The full lockup stays on the gate and the share card, where it is legible. */
.site-head__logo img { display: block; height: clamp(2.6rem, 5.5vw, 3.6rem); width: auto; }

.site-nav ul, .lang-nav ul, .site-foot__links {
  list-style: none; display: flex; flex-wrap: wrap;
  gap: 0.25rem 1.25rem; margin: 0; padding: 0; max-width: none;
}
.site-nav { margin-inline-start: auto; }
.site-nav ul { gap: 0 clamp(0.9rem, 2.2vw, 1.75rem); align-items: center; }
/* Current page: a flat amber bar under the word — the mark's own colour used
 * as decoration, never as text (D12). Hover uses the ink teal. */
.site-nav a {
  display: inline-block; color: var(--c-ink); text-decoration: none; font-weight: 700;
  padding-block: 0.55rem 0.35rem; border-block-end: 4px solid transparent;
}
.site-nav a:hover { border-color: var(--c-teal-ink); color: var(--c-ink); }
.site-nav a[aria-current="page"] { border-color: var(--c-amber); }
/* Square, with the small hard fold — the house treatment (the operator, 2026-09-20). */
.site-nav a.cta { border: 0; margin-inline-start: 0.25rem; border-radius: 0; box-shadow: 0.3rem 0.3rem 0 var(--c-fold); }
.site-nav a.cta[aria-current="page"] { background: var(--c-teal-inkest); }

.lang-nav { flex-basis: 100%; }
.lang-nav ul { gap: 0.75rem; font-size: var(--step--1); }
.lang-nav a { color: var(--c-muted); }
.lang-nav [aria-current="true"] { color: var(--c-ink); font-weight: 700; text-decoration: none; }
/* Narrow screens (the operator, 2026-09-20: the phone header "needs to be redone to
 * make sense"). Rows with a job each: the logo with the language switcher
 * stacked small and quiet at the far end of its row; then, under a hairline, the navigation
 * with the volunteer button pushed to the far end so it reads as the row's
 * action rather than the first item. Same markup, ordered by `order`. */
@media (max-width: 48rem) {
  .site-head__inner { gap: 0.65rem var(--gutter); padding-block: 0.85rem 0; }
  .site-head__logo { order: 1; }
  .site-head__logo img { height: 2.5rem; }
  /* The switcher as a three-line column at the far end of the logo's row,
   * ragged toward that edge (the operator, 2026-09-20) — shorter than a row of its own. */
  .lang-nav { order: 2; flex-basis: auto; margin-inline-start: auto; }
  .lang-nav ul { flex-direction: column; align-items: flex-end; gap: 0.1rem; line-height: 1.15; }
  /* The nav row on a light grey band, bled to the screen's edges (the operator,
   * 2026-09-20: on the candidates page the button sat against the banner's
   * teal with nothing between them). */
  .site-nav {
    order: 3; flex-basis: calc(100% + 2 * var(--gutter)); margin-inline: calc(-1 * var(--gutter));
    padding: 0.45rem var(--gutter) 0.6rem; background: var(--c-surface); border-block-start: 1px solid var(--c-rule);
  }
  .site-nav ul { gap: 0 1.1rem; }
  .site-nav li:last-child { margin-inline-start: auto; }
  .site-nav a.cta { margin-inline-start: 0; padding: 0.5rem 1rem; }
}

/* Call to action. Ink teal, not brand teal — brand teal fails AA behind white text. */
.cta {
  display: inline-block; background: var(--c-teal-ink); color: #fff !important;
  text-decoration: none; font-weight: 700; line-height: 1.3;
  padding: 0.65rem 1.4rem; border-radius: var(--radius); border: 0; font: inherit; font-weight: 700;
}
.cta:hover { background: var(--c-teal-inkest); }
.cta--big { font-size: var(--step-1); padding: 0.9rem 2rem; }

/* ------------------------------------------------- The bar cluster (§6) */
/* A cluster is a set of bars sharing one width, one gap and one angle; the
 * count is content. `.cluster__bars` is `direction: ltr` so the warm order —
 * amber, orange, red, physically left to right — never mirrors, and the skew
 * never mirrors either. The element AROUND it is positioned in the page's own
 * direction, so the cluster as a whole sits at inline-start in every locale.
 * Chrome resolves `inset-inline-start` against the element's OWN direction,
 * which is why those are two elements and not one. */
.cluster__bars {
  display: flex; gap: calc(var(--bar) * 0.6); block-size: 100%; direction: ltr;
  transform: skewX(var(--lean)); transform-origin: 50% 0;
}
.cluster__bar { inline-size: var(--bar); block-size: 100%; flex: none; }
/* The stagger index rides on the colour class — the warm order is fixed by
 * the mark (§6; orange → amber → red left to right since the 2026-09-20
 * lockup), so the index is too — rather than on an inline style attribute,
 * which the strict CSP in _headers forbids. */
.cluster__bar--orange { background: var(--c-orange); --i: 0; }
.cluster__bar--amber  { background: var(--c-amber);  --i: 1; }
.cluster__bar--red    { background: var(--c-red);    --i: 2; }

/* A heading marker: the same cluster at em scale, before section headings. */
.cluster--mark {
  display: inline-block; --bar: 0.38em; block-size: 0.95em;
  vertical-align: -0.08em; margin-inline-end: 0.55em;
}

/* --------------------------------------------------------------- Hero */
/* THE RIBBON (T62 · the operator's mockups of 2026-09-03 and 2026-09-07; the second,
 * animation-mockup.png in the project root — a copy in docs/reviews/ — is the
 * final composition AND the order it is drawn in). MEASURED OFF THAT DRAWING,
 * not read from it (the reading went wrong twice): stripes 56 px wide, 570
 * tall, leaning 4.1°, gaps 36 px; the flat trace 56 px thick at exactly the
 * stripes' mid-height; and FOUR DIAGONALS OF ONE SHAPE — a band as wide as a
 * stripe, sloping from behind the top of the stripe on its left to behind
 * the bottom of the stripe on its right (1.6 stripe-widths of travel over the
 * height, in the leaning frame). Between two stripes it shows as a sliver
 * starting exactly at the left stripe's top-right corner, the whole gap at
 * mid-height, and a point exactly at the right stripe's bottom-left corner.
 * Right of red the same band starts at red's top-right corner and widens to
 * where it meets the trace; left of amber it hangs full-width from the
 * trace's bottom edge and ends in a point at amber's bottom-left corner.
 * Nothing above the trace on the left, nothing below it on the right; the
 * trace runs from red's edge to the right and from amber's edge to the left,
 * and the diagonals' wide ends sit on it, so nothing shows between them.
 *
 * Read right to left it is one ribbon: the back comes in flat, turns up into
 * red, down red, up to orange, down orange, up to amber, down amber, and out
 * flat to the left. Each piece is its own element so it can be drawn alone,
 * in its own direction, one after another (the arrival, below): one flex row
 * in the physical order, from a DOM in D31's party order under row-reverse —
 * the first party stands at the right, and a fourth would take its place in
 * the row and in the drawing. Every diagonal is a "blade": the same
 * stripe-wide band, 2.6 units wide and the ribbon's full height, seen through
 * a window — the gap between two stripes, or a 1.6-unit box beside an outer
 * stripe cut off at the trace — so all four share one polygon and one slope,
 * whatever the viewport makes of the stripes' height. Faces are the mark's
 * ramps, everything grey is --c-fold, one lean — never mirrored — on the
 * whole row. Text never touches the field (§5.2). Proportions: a face is one
 * sixth of the ribbon's height, capped at 9vw; the drawing's own ratio is
 * ten to one, which the hero's height cannot carry at a prominent width. */
.hero {
  isolation: isolate; margin-block-end: clamp(2.5rem, 6vw, 4rem);
  --rise: clamp(3rem, 10vh, 5.5rem);
  /* Short enough that field + name box fit a desktop screen together, header
   * included (the operator, tenth round): at 1280×720 the box ends about 35 px above the fold, at 1440×800 about 75. */
  --field-h: clamp(18rem, 50vh, 30rem);
}
@supports (block-size: 1svh) { .hero { --rise: clamp(3rem, 10svh, 5.5rem); --field-h: clamp(18rem, 50svh, 30rem); } }
.hero__field {
  position: relative;
  background: var(--c-teal-logo);   /* the lockup's flat teal (the operator, 2026-09-20), not the gradient */
  block-size: var(--field-h);
  overflow: hidden; overflow: clip;
}
/* The ribbon hangs in the part of the field the name box leaves visible, and
 * its feet run 1rem under the box — "slightly hidden by the title-CTA box"
 * (the operator, tenth round) — so the box stands in front of it. A hair wider than
 * the field, so the trace's leaning ends fall outside the viewport. */
.ribbon {
  position: absolute; inset-inline: -1rem;
  --shown: calc(var(--field-h) - var(--rise));
  --ribbon-h: calc(var(--shown) * 0.88 + 1rem);
  inset-block-start: calc(var(--shown) * 0.12);
  block-size: var(--ribbon-h);
  --seg: min(calc(var(--ribbon-h) / 6), 9vw);
  --gap: calc(var(--seg) * 0.6);
  --trace: var(--seg);                                  /* the flat back is a stripe thick: 56 to 56 in the drawing */
  --blade: calc(2 * var(--seg) + var(--gap));           /* two stripes and the gap between: 2.6 units */
  --shoulder: calc(var(--seg) + var(--gap));            /* an end window: 1.6 units beside the outer stripe */
  display: flex; flex-direction: row-reverse; align-items: stretch; direction: ltr;
  transform: skewX(var(--lean)); transform-origin: 50% 50%;
}
/* A piece is a window that clips its ink. In the arrival the window slides
 * while the ink slides back by the same amount, so the ink never moves and
 * only the window's edge travels across it. */
.ribbon__part { position: relative; overflow: clip; flex: none; }
.ribbon__ink { display: block; position: relative; inline-size: 100%; block-size: 100%; background: var(--c-fold); }
.ribbon__band { flex: 1 1 0; align-self: center; block-size: var(--trace); }
/* The trace runs on under the end windows to the outer stripes' edges. */
.ribbon__band--end   { margin-inline-start: calc(-1 * var(--shoulder)); }
.ribbon__band--start { margin-inline-end:   calc(-1 * var(--shoulder)); }
.ribbon__seg { inline-size: var(--seg); }
.ribbon__seg .ribbon__ink { background: var(--face); }
/* A diagonal: a transparent window over a blade. Left stripe 0–1, gap 1–1.6,
 * right stripe 1.6–2.6; top edge 0–1, bottom edge 1.6–2.6. */
.ribbon__rise .ribbon__ink { background: none; }
.ribbon__blade {
  position: absolute; display: block; inset-block-start: 0;
  inline-size: var(--blade); block-size: var(--ribbon-h);
  background: var(--c-fold);
  clip-path: polygon(0 0, 38.46% 0, 100% 100%, 61.54% 100%);
}
.ribbon__rise { inline-size: var(--gap); }
.ribbon__rise .ribbon__blade { inset-inline-start: calc(-1 * var(--seg)); }
/* The ends: a 1.6-unit window beside the outer stripe, cut off at the trace.
 * Right, from the top down to the trace's top edge, the blade anchored to the
 * window's far edge so its first unit lies under red; left, from the trace's
 * bottom edge to the foot, the blade anchored bottom and near so its last
 * unit lies under amber. */
.ribbon__rise--end, .ribbon__rise--start { inline-size: var(--shoulder); block-size: calc(50% - var(--trace) / 2); }
.ribbon__rise--end   { align-self: flex-start; }
.ribbon__rise--start { align-self: flex-end; }
.ribbon__rise--end .ribbon__blade   { inset-inline-start: auto; inset-inline-end: 0; }
.ribbon__rise--start .ribbon__blade { inset-inline-start: 0; inset-block-start: auto; inset-block-end: 0; }
/* An end blade is taller than its window, so the ink must clip it too: when
 * window and ink slide apart at the start of the drawing, the window must
 * land on nothing — not on a lower or higher reach of the same blade. */
.ribbon__rise--end .ribbon__ink, .ribbon__rise--start .ribbon__ink { overflow: clip; }
.ribbon__seg--amber  { --face: var(--ramp-amber); }
.ribbon__seg--orange { --face: var(--ramp-orange); }
.ribbon__seg--red    { --face: var(--ramp-red); }
/* The party's index in D53's order, for the drawing's timing. The order is
 * fixed by the mark and by D53, so the index rides on the hue class rather
 * than on an inline style, which the strict CSP forbids. */
.ribbon__part--red    { --i: 0; }
.ribbon__part--amber  { --i: 1; }
.ribbon__part--orange { --i: 2; }

/* Arrival — one continuous drawing (the operator, 2026-09-07): "start on the right
 * with the gray line moving towards the left, then up only with the gray,
 * down only red, up only gray, down only orange, up only gray, down only
 * yellow, up only gray, and then left all the way … at no point should two
 * colors reveal together." Each piece is wiped in its own direction, and the
 * next begins the instant the previous ends, at one speed throughout, so the
 * pen never lifts and never doubles. Transform only (D16): every wipe is a
 * window sliding one way while its ink slides the other. A CSS animation on
 * the first paint, before any script (D43); `backwards` holds each piece
 * unseen until its turn. Reduced motion removes it all and the resting
 * rules are the finished composition. The per-piece times are set for a
 * common speed: a face's height at 1280 wide takes a face-time, an end
 * window (0.42 of the height) an end-time, the flat trace to the edge a
 * band-time, and the band-time follows the viewport in three steps, since
 * CSS cannot turn a length into a time.
 *
 * ORDER MATTERS BELOW. The generic diagonal rule computes its delay from the
 * party index; the right end has none, so that rule must not be the last
 * word on it — the end rules come after and restate the whole animation.
 * (This is the bug that once left the right diagonal standing from the
 * first frame.) */
@keyframes ribbon-sweep-left     { from { transform: translateX(100%); }  to { transform: none; } }
@keyframes ribbon-sweep-left-ink { from { transform: translateX(-100%); } to { transform: none; } }
@keyframes ribbon-sweep-up       { from { transform: translateY(100%); }  to { transform: none; } }
@keyframes ribbon-sweep-up-ink   { from { transform: translateY(-100%); } to { transform: none; } }
@keyframes ribbon-sweep-down     { from { transform: translateY(-100%); } to { transform: none; } }
@keyframes ribbon-sweep-down-ink { from { transform: translateY(100%); }  to { transform: none; } }
.ribbon {
  --delay-sweep: 0.2s;
  --t-band: 0.44s; --t-end: 0.1s; --t-face: 0.23s; --t-wedge: 0.23s;
  --d-end: calc(var(--delay-sweep) + var(--t-band));
  --d-faces: calc(var(--d-end) + var(--t-end));
  --pitch: calc(var(--t-face) + var(--t-wedge));
}
@media (max-width: 48rem)  { .ribbon { --t-band: 0.1s; } }
@media (min-width: 100rem) { .ribbon { --t-band: 0.62s; } }
.ribbon__seg                      { animation: ribbon-sweep-down     var(--t-face)  linear calc(var(--d-faces) + var(--i, 0) * var(--pitch)) backwards; }
.ribbon__seg .ribbon__ink         { animation: ribbon-sweep-down-ink var(--t-face)  linear calc(var(--d-faces) + var(--i, 0) * var(--pitch)) backwards; }
.ribbon__rise                     { animation: ribbon-sweep-up       var(--t-wedge) linear calc(var(--d-faces) + var(--i, 0) * var(--pitch) + var(--t-face)) backwards; }
.ribbon__rise .ribbon__ink        { animation: ribbon-sweep-up-ink   var(--t-wedge) linear calc(var(--d-faces) + var(--i, 0) * var(--pitch) + var(--t-face)) backwards; }
.ribbon__rise--start              { animation: ribbon-sweep-up       var(--t-end)   linear calc(var(--d-faces) + var(--i, 0) * var(--pitch) + var(--t-face)) backwards; }
.ribbon__rise--start .ribbon__ink { animation: ribbon-sweep-up-ink   var(--t-end)   linear calc(var(--d-faces) + var(--i, 0) * var(--pitch) + var(--t-face)) backwards; }
.ribbon__band--end                { animation: ribbon-sweep-left     var(--t-band)  linear var(--delay-sweep) backwards; }
.ribbon__band--end .ribbon__ink   { animation: ribbon-sweep-left-ink var(--t-band)  linear var(--delay-sweep) backwards; }
.ribbon__rise--end                { animation: ribbon-sweep-up       var(--t-end)   linear var(--d-end) backwards; }
.ribbon__rise--end .ribbon__ink   { animation: ribbon-sweep-up-ink   var(--t-end)   linear var(--d-end) backwards; }
.ribbon__band--start              { animation: ribbon-sweep-left     var(--t-band)  linear calc(var(--d-faces) + var(--i, 0) * var(--pitch) + var(--t-face) + var(--t-end)) backwards; }
.ribbon__band--start .ribbon__ink { animation: ribbon-sweep-left-ink var(--t-band)  linear calc(var(--d-faces) + var(--i, 0) * var(--pitch) + var(--t-face) + var(--t-end)) backwards; }
/* A tab opened in the background: the inline snippet in base.njk marks <html>
 * `is-unseen` while hidden; the drawing waits, paused at its start, and runs
 * the first time the tab is looked at. */
.is-unseen .hero .ribbon__part, .is-unseen .hero .ribbon__ink { animation-play-state: paused; }

/* The name, centred beneath the warm faces — the operator's composition. The panel
 * is the one centred block on a flush-left site besides the root fallback;
 * it rises into the field so the ribbon stands on it (depth by overlap). */
/* The home page's boxes — this panel and the party rows — are one width and
 * centre on the box, not on box plus shadow; the shadow overhangs to the
 * physical right. Both sit in a `.wrap`, and where the gutter is narrower
 * than the shadow plus some white (phones) they step in further, so the
 * shadow never meets the screen edge (the operator, 2026-09-24). */
.hero__panel, .party-rows {
  --fold: 0.9rem;
  --fold-room: max(0px, var(--fold) + 0.75rem - var(--gutter));
  inline-size: min(100% - 2 * var(--fold-room), 52rem); margin-inline: auto;
}
.hero__panel {
  /* A size container, so the third name line can be capped to the panel's
   * own width (cqi) rather than guessed from the viewport's. */
  container-type: inline-size;
  position: relative; z-index: 1;
  margin-block-start: calc(-1 * var(--rise));
  padding: clamp(1.5rem, 4vw, 2.5rem) clamp(1.25rem, 4vw, 2.5rem) clamp(1.5rem, 4vw, 2.25rem);
  background: var(--c-teal-inkest); color: #fff; text-align: center;
  /* A 1px black line around every box on the home page — this one and the
   * party rows (the operator, 2026-09-06). */
  border: 1px solid #000;
  /* The box's depth is a hard offset block in the ribbon's own dark — a
   * flat, print-registration shadow, zero blur — after the operator turned down the
   * soft shadow (2026-09-03, seventh round). It is the same colour as the
   * ribbon's back, so the box and the ribbon read as one object. */
  box-shadow: var(--fold) var(--fold) 0 var(--c-fold);
}
/* The two scripts overlap slightly: line-height well below 1 on a 700 face,
 * as the operator asked (2026-09-03, rounds three and four). */
/* The name is set in Assistant ExtraBold, the headline face of the designer's
 * campaign artwork (the operator, 2026-09-20). The face ships Hebrew only, so the
 * Arabic line (and an English or Russian third line) falls through the stack
 * to its own family at the nearest weight it has, 700 — no synthetic bold. */
.hero__title { color: #fff; font-weight: 800; font-size: var(--step-4); line-height: 0.76; margin: 0 0 1.5rem; letter-spacing: -0.01em; text-wrap: balance; }
/* On the spans, not the heading: each line carries its own `lang`, and
 * tokens.css re-declares font-family wherever `lang` is set, which would
 * otherwise win over anything inherited from the h1. */
.hero__title [lang] { font-family: "Assistant", var(--font-ui); }
/* The Arabic name traced from the lockup (scripts/hero/outline-arabic.py),
 * set to the WIDTH of the Hebrew line under it — 3.981 em, המשותפת in
 * Assistant ExtraBold at 1 em less the letter-spacing above — as the lockup
 * sets its two lines to one width (the operator, 2026-09-20). 0.993 em tall at that
 * width, of which the last tenth is the reh's tail, which in the lockup drops
 * over the Hebrew line's ו — hence the pull-up under it. The span is a block with no "\A" of its own and no line-height, so
 * the whitespace after the included svg cannot open a line box under it; the
 * Hebrew line's 0.76 line-height tucks it up beneath. */
/* Painted above the Hebrew line, which follows it in the DOM and would
 * otherwise cover the reh's tail where it drops into the line below — in
 * the lockup the tail runs over the Hebrew (the operator, 2026-09-20). */
.hero__title [lang="ar"] { display: block; line-height: 0; position: relative; z-index: 1; }
.hero__title [lang="ar"]::after { content: none; }
.hero__name-svg { display: block; inline-size: 3.981em; max-inline-size: 100%; block-size: auto; margin-inline: auto; margin-block-end: -0.2em; }
.hero__title span:not(:last-child)::after { content: "\A"; white-space: pre; }
/* The third line — the page's own name where it is neither the Hebrew nor the
 * Arabic one (en, ru). Two fixes (review A5, C7):
 *  · it is capped to the panel's width. "Объединённый" is one word of about
 *    7.9 em in the Cyrillic face, so at the display size it ran 33 px out of
 *    the panel on a 390 px phone and the page scrolled sideways. 12.4cqi fits
 *    it inside the panel's content box at every width; on a desktop-sized
 *    panel the cap exceeds 1em and changes nothing. The vw line is the
 *    fallback for a browser without container units, tuned the same way.
 *  · it sits a little below the Hebrew line. The title's 0.76 line-height is
 *    the deliberate overlap of the two scripts (the operator, 2026-09-03); the third
 *    line is not part of that lockup and was touching it. */
.hero__title .hero__alt {
  display: block; line-height: 0.95; margin-block-start: 0.16em;
  font-size: min(1em, 8.4vw); font-size: min(1em, 12.4cqi);
}
.hero__panel p { max-width: none; }   /* the panel centres its content; a measure-capped p would sit off-centre */
.hero__cta { margin: 0; }
/* The CTA rests white on the deep teal and, on hover, becomes the mark's
 * colours — red through orange to amber, red at the physical right as the
 * ribbon has it (the operator, 2026-09-03, fifth round: "only on hover"). Ink text on
 * the gradient: 3.44:1 on the red end, AA for large bold text; 5.64 and 9.05
 * on the rest. The lift is transform only (D16); the colour swap is instant. */
.hero .cta {
  background: #fff; color: var(--c-teal-inkest) !important;
  border-radius: 0;   /* square, like the box it sits in (the operator, 2026-09-20) */
  transition: transform 0.18s var(--ease-arrive);
}
.hero .cta:hover, .hero .cta:focus-visible {
  background: linear-gradient(to left, var(--c-red) 0%, var(--c-amber) 50%, var(--c-orange) 100%);
  color: var(--c-ink) !important;
  transform: translateY(-2px) scale(1.04);
}
/* A SHORT screen — a phone on its side, 844×390 (review C7). The field's 18rem
 * floor put the name box's top at the fold, so the list's name and the one
 * call to action were both below it. Here the field is a strip and the name
 * steps down with the screen's height, so name and CTA share the first screen
 * with the header (measured at 844×390: the CTA ends at 296 px in Hebrew and
 * 339 with the Russian third line). After every hero rule on purpose: same specificity,
 * so source order is what makes it win. */
@media (max-height: 30rem) and (orientation: landscape) {
  .hero { --field-h: 4rem; --rise: 2rem; }
  .hero__title { font-size: min(var(--step-4), 10vh); margin-block-end: 1rem; }
  .hero__panel { padding-block: 1rem 1.1rem; }
  .hero .cta--big { padding-block: 0.6rem; }
}

/* ------------------------------------------------------- Home sections */
.centred { text-align: center; }
/* Three parallel things are a full-width list at full type size (§4). Each
 * row is one link to the party's own site, resting on a grey ground with the
 * party's own colour on its pill; on hover the row fills with that colour and
 * the pill takes the grey (the operator, 2026-09-03). Flat and instant — no colour
 * transition (D16). Text on each colour is measured (D12): white on red
 * 5.35:1, ink on orange 5.64:1, ink on amber 9.05:1 — at body size too. */
/* Straight corners and clear white space between the rows: the offset block
 * is 0.9rem deep, so the row gap has to be well over that (the operator, tenth round). */
.party-rows { list-style: none; margin-block: 1rem 2.5rem; padding: 0 0 var(--fold); max-width: none; display: grid; gap: 2rem; }
/* Each row carries the same hard offset block as the name box (the operator, eighth round). */
.party-rows__row { box-shadow: var(--fold) var(--fold) 0 var(--c-fold); border: 1px solid #000; }   /* the 1px black line, as the hero's box (the operator, 2026-09-06) */
.party-rows__row--red    { --party-bg: var(--c-red);    --party-ink: #fff; }
.party-rows__row--orange { --party-bg: var(--c-orange); --party-ink: var(--c-ink); }
.party-rows__row--amber  { --party-bg: var(--c-amber);  --party-ink: var(--c-ink); }
/* The pill keeps the corner; the names centre (the operator, seventh round). */
.party-rows__row, .party-rows__link { display: block; position: relative; text-align: center; }
/* Ink on the row itself, not only on its link: a party with no supplied URL
 * (תע״ל today) renders a row without a link, and its name fell back to the
 * body grey while the linked rows were ink (review C2). */
.party-rows__row { background: var(--c-surface-deep); color: var(--c-ink); padding: 1.1rem 4.5rem 1rem; border-radius: 0; }
.party-rows__row:has(.party-rows__link) { padding: 0; }
.party-rows__link {
  padding: 1.1rem 4.5rem 1rem; inline-size: 100%; border-radius: 0;
  color: var(--c-ink); text-decoration: none;
}
.party__abbr {
  position: absolute; inset-inline-start: 0.75rem; inset-block-start: 0.75rem;
  background: var(--party-bg, var(--c-teal-ink)); color: var(--party-ink, #fff);
  padding: 0.05rem 0.6rem; border-radius: var(--radius);
  font-size: var(--step-0); font-weight: 700;
}
.party-rows__link:hover, .party-rows__link:focus-visible { background: var(--party-bg); color: var(--party-ink); }
.party-rows__link:hover .party__alt, .party-rows__link:focus-visible .party__alt { color: var(--party-ink); }
.party-rows__link:hover .party__abbr, .party-rows__link:focus-visible .party__abbr { background: var(--c-surface-deep); color: var(--c-ink); }
/* A party with no site (תע״ל today) has no link, but keeps the same colour fill on
   hover (the operator, 2026-09-25): the fill is the party's colour, not a link cue. */
.party-rows__row:not(:has(.party-rows__link)):hover { background: var(--party-bg); color: var(--party-ink); }
.party-rows__row:not(:has(.party-rows__link)):hover .party__alt { color: var(--party-ink); }
.party-rows__row:not(:has(.party-rows__link)):hover .party__abbr { background: var(--c-surface-deep); color: var(--c-ink); }
/* On a phone the pill's side room would leave the names a third of the box:
 * the names clear it from below instead and take the full width. */
@media (max-width: 34rem) {
  .party-rows__row, .party-rows__link { padding: 3rem 1rem 1rem; }
  .party-rows__row:has(.party-rows__link) { padding: 0; }
}
.party__name { margin: 0; font-size: var(--step-2); font-weight: 700; line-height: 1.15; }
/* The Arabic name as big as the Hebrew one — the operator, 2026-09-03 — and as bold:
 * the two scripts are peers here, as on the mark. */
/* Balanced, as the headings are: a name that needs two lines splits into two
 * even halves — החזית הדמוקרטית / לשלום ולשוויון, not a lone last word
 * (the operator, 2026-09-24). One line wherever it fits. */
.party__name, .party__alt { display: block; text-wrap: balance; }
.party__alt { margin: 0; font-size: var(--step-2); font-weight: 700; line-height: 1.15; color: var(--c-ink); }

.help-list {
  list-style: none; margin: 0 0 1.75rem; padding: 0; max-width: none;
  display: grid; gap: 0.75rem var(--gutter);
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
}
.help-list li { border-inline-start: 4px solid var(--c-teal-ink); padding-inline-start: 0.75rem; font-weight: 700; color: var(--c-ink); }

/* Editorial notes: a provenance line, an aside. Calm, muted, one teal edge —
 * NOT the placeholder treatment, because these are decisions, not holes (§9). */
.note {
  font-size: var(--step--1); color: var(--c-muted); line-height: 1.55;
  border-inline-start: 4px solid var(--c-teal-ink); padding: 0.2rem 0.9rem;
  margin-block: 0 1.5rem; max-width: var(--measure);
}
.note--foot { margin-block-start: 2.5rem; }

/* Folded sections — the מצע (the operator, 2026-09-03, sixth and seventh rounds).
 * Native <details>: closed by default, one tap or Enter to open, printable, no
 * script. The heading lives inside the summary so the outline survives. The
 * body fades and rises on open — transform and opacity only, none under
 * reduced motion. The sections step in like tabs, one after another, all
 * sharing one inline-end edge at the reading width; the last section (the
 * parliamentary plan) returns to the first position and holds two folded
 * chapters of its own. The whole list sits on a soft teal-tinted band. */
.sections { background: linear-gradient(180deg, #e6f0f2 0%, var(--c-bg) 100%); padding-block: 2rem 2.5rem; margin-block: 0 1.5rem; }
.sections__inner { inline-size: min(100%, 52rem); margin-inline-end: auto; --tab: clamp(0rem, 3.5vw - 0.9rem, 1.6rem); }
.section { background: var(--c-bg); margin-block-end: 0.6rem; border-inline-start: 6px solid var(--c-ink); }
.section:nth-of-type(2) { margin-inline-start: var(--tab); }
.section:nth-of-type(3) { margin-inline-start: calc(var(--tab) * 2); }
.section:nth-of-type(4) { margin-inline-start: calc(var(--tab) * 3); }
.section:nth-of-type(5) { margin-inline-start: 0; }
.section__head {
  list-style: none; cursor: pointer; padding: 1rem 1.1rem 0.9rem;
  display: flex; align-items: center; gap: 1rem;
}
.section__head::-webkit-details-marker { display: none; }
.section__head h2 { margin: 0; flex: 1 1 auto; font-size: var(--step-2); }
.section__head:hover .section__title { color: var(--c-teal-ink); }
/* The toggle: a chevron drawn from two borders, turned when open. Physical
 * borders on purpose: a chevron pointing down is the same shape in both
 * directions, and logical borders would turn it sideways in RTL. */
.section__head::after, .subsection__head::after {
  content: ""; flex: none; inline-size: 0.8rem; block-size: 0.8rem;
  border-right: 3px solid var(--c-ink); border-bottom: 3px solid var(--c-ink);
  transform: translateY(-25%) rotate(45deg); transition: transform 0.2s var(--ease-arrive);
}
.section[open] > .section__head::after, .subsection[open] > .subsection__head::after { transform: translateY(15%) rotate(225deg); }
.section__body { padding: 0 1.1rem 1.5rem; }
.section__body > :first-child { margin-block-start: 0; }
@keyframes section-reveal { from { opacity: 0; transform: translateY(0.75rem); } }
.section[open] > .section__body, .subsection[open] > .subsection__body { animation: section-reveal var(--dur-arrive) var(--ease-arrive) backwards; }
/* Chapters inside a section: the same fold one step down. */
.subsection { border-block-start: 2px solid var(--c-rule); margin-block-start: 0.75rem; }
.subsection__head { list-style: none; cursor: pointer; padding-block: 0.8rem 0.7rem; display: flex; align-items: center; gap: 1rem; }
.subsection__head::-webkit-details-marker { display: none; }
.subsection__head h3 { margin: 0; flex: 1 1 auto; }
.subsection__head:hover h3 { color: var(--c-teal-ink); }
.subsection__body { padding-block: 0 0.5rem; }

/* Table of contents on a long document. */
.toc { background: var(--c-surface); padding: 1rem 1.25rem; margin-block: 1rem 2rem; max-width: var(--measure); }
.toc p { margin: 0 0 0.35rem; font-weight: 700; color: var(--c-ink); font-size: var(--step--1); }
.toc ol { margin: 0; padding-inline-start: 1.25rem; columns: 2 14rem; column-gap: 2rem; }
.toc li { break-inside: avoid; padding-block: 0.15rem; }
.toc a { font-weight: 700; text-decoration: none; }
.toc a:hover { text-decoration: underline; }

/* Loud placeholders — these must look unfinished, not shippable (D29, §9).
 * `.notice` and `.attribution--missing` are blocks; `.pending-inline` is the
 * inline form and, on a <p>, a one-line block. */
.notice, .attribution--missing {
  border-inline-start: 5px solid var(--c-red-ink);
  background: #fdf3f3; color: #5a1013;
  padding: 0.85rem 1rem; border-radius: var(--radius);
  max-width: var(--measure);
}
.pending-inline {
  background: #fdf3f3; color: #5a1013;
  border-inline-start: 3px solid var(--c-red-ink);
  padding-inline: 0.4rem; font-weight: 700;
}
p.pending-inline { display: block; padding: 0.6rem 0.9rem; border-inline-start-width: 5px; border-radius: var(--radius); }

/* ---------------------------------------------------------------- Footer */
.site-foot {
  /* Its top spacing is `body > main::after` (see the body rule). */
  background: var(--c-teal-inkest); color: #fff;
  padding-block: clamp(2rem, 5vw, 3rem) 1.75rem;
  font-size: var(--step--1);
}
.site-foot a { color: #fff; }
.site-foot a:hover { color: #fff; text-decoration-thickness: 3px; }
/* Four scripts on one line: a flex row, each name an isolated bidi run that
 * never wraps internally, each separator in one item with the name after it —
 * so the visual order is the flex order in both directions and no script's
 * punctuation strays. */
.site-foot__name { color: #fff; font-size: var(--step-1); font-weight: 700; margin: 0 0 1.75rem; line-height: 1.3; display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.2em 0.6em; max-width: none; }
.site-foot__name span { white-space: nowrap; unicode-bidi: isolate; }
/* A separator and the name after it are one item, so a wrapped row starts
 * with "·" rather than ending with one (review C7). */
.site-foot__name .sep { opacity: 1; margin-inline-end: 0.6em; }
.site-foot__links { margin-block-end: 1.75rem; gap: 0.35rem 1.5rem; font-weight: 700; }
.site-foot__links:last-child { margin-block-end: 0; }

/* Reduced motion: no CSS animation at all, not merely a short one. Durations
 * alone are not enough — a delayed animation with `backwards` fill would hold
 * its element invisible for the whole delay and then pop (measured, T62). The
 * finished composition is what the CSS renders; motion only adds to it (§8). */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
}

/* ------------------------------------------------------ Volunteer intake */
/* THE VOLUNTEER PAGE (T62, twelfth round · the operator: the form first, in colour,
 * four steps, consent inside the last; "make volunteers use it"). A band in
 * the logo's teal carries the title; the form is a white card rising into the band with
 * the site's hard offset block — the home hero's depth by overlap — and the
 * explanatory prose stands beside it on wide screens. Colour is spent where
 * the choice is: the party cards fill with the party's colour when chosen,
 * the help options are tiles that turn ink teal with an amber bar, the step
 * rail is the mark's bars. Hard corners, one lean, no shadows but the offset
 * block (§4, §6). Every text/ground pair below is one already measured for
 * the home page's rows or the hero's CTA. */
.enlist { --enlist-rise: clamp(2.5rem, 6vw, 4.5rem); margin-block-end: clamp(2.5rem, 6vw, 4rem); }
/* The band's ground is the logo's own (the operator, 2026-09-06: the band was "too
 * dark. it should be the same teal of the logo background"): --c-teal-deep,
 * the deep end of the mark's gradient and the share card's ground. Not the
 * gradient itself — white on its light end is 2.88:1, under AA even for
 * large text — and not --c-teal-inkest, which is the darker ink this replaced.
 * White on #0c849c measures 4.38:1: AA for LARGE text only, so everything on
 * this band is large text — the title by size, the lede by weight — and no
 * body text may ever sit on it (tokens.css, ACCESSIBILITY NOTE). */
.enlist__band {
  background: var(--c-teal-deep); color: #fff;
  padding-block: clamp(1.75rem, 4vw, 3rem) calc(clamp(1.75rem, 4vw, 3rem) + var(--enlist-rise));
}
.enlist__title { color: #fff; font-size: var(--step-3); margin: 0; }
/* The contact page's lede sits IN the band, reversed, so the sentence that
 * sends routine business to the parties is read before the form rather than
 * under it. The volunteer page has no lede and this rule costs it nothing.
 * It is bold because the band's white-on-teal pair is AA for large text only:
 * --step-1 is 20px at its smallest, and 20px bold is WCAG large text (≥ 18.66px
 * bold); at 400 it would be body text on a 4.38:1 ground, which fails. */
.enlist__lede {
  color: #fff; font-size: var(--step-1); font-weight: 700; line-height: 1.45;
  max-inline-size: 46rem; margin: 1.1rem 0 0;
}
/* The card alone under the band, flush to inline-start on the wrap grid (§4),
 * at a width a form reads well at. No lede, no explanation beside it: "nobody
 * needs an explanation for how to fill a form" (the operator, thirteenth round). */
.enlist__body { position: relative; z-index: 1; margin-block-start: calc(-1 * var(--enlist-rise)); }
/* The ס' 2א1 attribution, under the contact card (moved from the footer,
 * the operator, 2026-09-24): small print, clear of the card's offset block. */
.attribution { margin: 2.5rem 0 0; color: var(--c-body); font-size: var(--step--1); max-inline-size: 46rem; }
.attribution--missing { color: #5a1013; }
.enlist__card { background: var(--c-bg); padding: clamp(1.25rem, 3.5vw, 2.5rem); border: 1px solid var(--c-fold); box-shadow: 0.9rem 0.9rem 0 var(--c-fold); max-inline-size: 46rem; min-inline-size: 0; }
.enlist__card .note--foot { margin: 0; }
/* On a phone the card plus its offset block filled the whole width between
 * the gutters, so the block sat 3px from the screen's edge and the card read
 * as pushed to one side (the operator, 2026-09-05: "more centered, with a bit more
 * white space to the right"). The card gives up the block's depth plus a
 * little on its RIGHT — a physical side, not a logical one, because the block
 * is drawn by box-shadow, whose offset is physical: it sits bottom-right in
 * Hebrew and in English alike. Card and block together then sit centred
 * between the gutters with slightly more air on the right. Desktop is
 * untouched: there the card is flush to inline-start on purpose. */
@media (max-width: 44rem) {
  .enlist__card { margin-right: 1.25rem; }
}

.intake { max-width: none; margin: 0; }
.intake__head { display: flex; align-items: center; gap: 1rem; margin-block-end: 1.5rem; min-block-size: 2rem; }
/* The rail: one bar per step, the page's own direction so the first step is
 * at inline-start. The lean never mirrors. Built by intake.js; hidden empty.
 * The bars are teal, amber, orange, red in turn (the operator, fourteenth round),
 * cycling if a form ever has more steps; a step not yet reached is the same
 * colour faded, so the colours and the progress both read. */
.intake__rail { --rail-bar: 0.8rem; display: flex; gap: calc(var(--rail-bar) * 0.6); block-size: 2rem; transform: skewX(var(--lean)); transform-origin: 50% 100%; }
.intake__rail:empty, .intake__progress:empty { display: none; }
.intake__rail-bar { inline-size: var(--rail-bar); opacity: 0.22; }
.intake__rail-bar:nth-child(4n+1) { background: var(--c-teal-ink); }
.intake__rail-bar:nth-child(4n+2) { background: var(--c-amber); }
.intake__rail-bar:nth-child(4n+3) { background: var(--c-orange); }
.intake__rail-bar:nth-child(4n+4) { background: var(--c-red); }
.intake__rail-bar.is-done, .intake__rail-bar.is-now { opacity: 1; }
.intake__progress { margin: 0; font-weight: 700; font-size: var(--step--1); color: var(--c-teal-inkest); }

.intake__step { border: 0; padding: 0; margin: 0 0 1.5rem; min-inline-size: 0; }
.intake__legend { padding: 0; margin-block-end: 1rem; font-size: var(--step-2); font-weight: 700; line-height: 1.15; color: var(--c-ink); }
.intake__step.is-in { animation: step-in 0.35s var(--ease-arrive) both; }
@keyframes step-in { from { opacity: 0; transform: translateY(0.6rem); } }

/* Short answers get short boxes: a field is capped, flush to inline-start. */
.field { margin-block-end: 1.1rem; max-inline-size: 30rem; }
.field label { display: block; font-weight: 700; margin-block-end: 0.35rem; }
.intake input[type="text"], .intake input[type="email"], .intake input[type="tel"], .intake textarea {
  inline-size: 100%; padding: 0.85rem 1rem; font: inherit; font-size: var(--step-0);
  color: var(--c-ink); background: #fff; border: 2px solid var(--c-rule); border-radius: var(--radius);
}
.intake input:focus-visible, .intake textarea:focus-visible { border-color: var(--c-teal-ink); }
.intake input[aria-invalid="true"], .intake textarea[aria-invalid="true"] { border-color: var(--c-red-ink); }
/* What is wrong with a field, beside it and for as long as it is wrong (review
 * C5) — built by intake.js, tied to the field by aria-describedby, and in the
 * red ink, the one warm tone measured safe for text. The browser's own bubble
 * vanished after a moment and spoke English on a Hebrew page. */
.field__error { margin: 0.4rem 0 0; color: var(--c-red-ink); font-weight: 700; font-size: var(--step--1); line-height: 1.4; }
.party-pick + .field__error { margin-block: 0.9rem 0; }
.consent + .field__error { margin-block: -0.6rem 1.1rem; }
/* The form's own line (a refused step, a failed send), beside the buttons and
 * never in the step counter. Takes no space while it is empty. */
.intake__alert { margin: 1.25rem 0 0; padding: 0.75rem 1rem; border-inline-start: 4px solid var(--c-red-ink); background: var(--c-surface); color: var(--c-ink); font-weight: 700; }
.intake__alert:empty { display: none; }
/* The no-JavaScript "not sent" notice: absent until the endpoint's redirect
 * makes it the page's :target (#not-sent). Pure CSS, for the visitor who has
 * no script (review B8). */
.intake__notsent { display: none; margin: 0 0 1.5rem; padding: 0.9rem 1.1rem; border-inline-start: 4px solid var(--c-red-ink); background: var(--c-surface); color: var(--c-ink); }
.intake__notsent:target { display: block; }
.intake__notsent p { margin: 0; }
/* An address and a phone number are typed left to right in every language
 * (dir="ltr" on the field); on a right-to-left page they still sit against the
 * same edge as every other field. */
[dir="rtl"] .intake input[dir="ltr"] { text-align: right; }
/* A message is prose, so it gets a prose measure and room to grow. Vertical
 * resize only: horizontal dragging in an RTL layout escapes the card. */
/* Wider than a name or a phone number, and deliberately NOT the card's full
 * width: a prose measure that reads as a choice rather than as the field
 * having run out of card. */
.field--long { max-inline-size: 36rem; }
.intake textarea { display: block; min-block-size: 11rem; line-height: 1.55; resize: vertical; }

/* The יישוב field's suggestions (locality.js). A panel hanging off the field it
 * belongs to, capped at eight rows so it stays a glance rather than a scroll,
 * and absent from the document entirely until there is something in it. One set
 * of logical properties serves both directions, as everywhere else here.
 *
 * The teal border is the ink teal and not the brand teal, because this box sits
 * against text and D12 is not negotiable. */
.combo { position: relative; }
.combo__list {
  position: absolute; z-index: 20; inset-inline: 0; inset-block-start: calc(100% + 0.25rem);
  margin: 0; padding: 0.3rem; list-style: none;
  background: #fff; border: 2px solid var(--c-teal-ink); border-radius: var(--radius);
  box-shadow: 0 0.6rem 1.4rem rgb(0 0 0 / 0.14);
  max-block-size: 17rem; overflow-y: auto; overscroll-behavior: contain;
}
.combo__opt {
  display: flex; align-items: center; gap: 0.55rem;
  padding: 0.5rem 0.6rem; cursor: pointer; border-radius: calc(var(--radius) * 0.5);
}
/* The same leaning tick the pick tiles and the step rail carry. */
.combo__opt::before {
  content: ""; flex: none; inline-size: 0.32rem; block-size: 1.1rem;
  background: var(--c-rule); transform: skewX(var(--lean));
}
.combo__opt:hover { background: var(--c-surface); }
/* After the hover rule on purpose: the keyboard's active row outranks whatever
 * the mouse happens to be resting on. */
.combo__opt.is-active, .combo__opt.is-active:hover { background: var(--c-teal-ink); color: #fff; }
.combo__opt.is-active::before { background: var(--c-amber); }
.combo__name { font-weight: 700; }
/* The name the visitor's typing actually matched, when it is not the one shown
 * — type "haifa" on the Hebrew page and the list has to explain itself. */
.combo__alt { font-size: var(--step--1); color: var(--c-muted); }
.combo__opt.is-active .combo__alt { color: #fff; }

/* Selectable tiles and cards. The box is a real, focusable input whose own
 * rendering is hidden; the visible state lives on its sibling, so this needs
 * no :has() and works wherever a radio works. */
.pick, .party-pick__item { position: relative; display: block; cursor: pointer; }
.pick__input { position: absolute; inset-block-start: 0; inset-inline-start: 0; inline-size: 1px; block-size: 1px; margin: 0; opacity: 0; pointer-events: none; }
.pick-grid { display: grid; gap: 0.75rem; grid-template-columns: repeat(auto-fill, minmax(12.5rem, 1fr)); }
.pick__body {
  display: flex; align-items: center; gap: 0.8rem; min-block-size: 3.4rem;
  padding: 0.75rem 1rem; background: var(--c-surface); color: var(--c-ink); font-weight: 700;
}
.pick__body::before { content: ""; flex: none; inline-size: 0.42rem; block-size: 1.35rem; background: var(--c-rule); transform: skewX(var(--lean)); }
.pick:hover .pick__body { background: var(--c-surface-deep); }
.pick__input:checked + .pick__body { background: var(--c-teal-ink); color: #fff; }
/* The tile's marker in the chosen party's colour (set on the form by intake.js). */
.pick__input:checked + .pick__body::before { background: var(--accent, var(--c-amber)); }
.intake[data-party="red"]    { --accent: var(--c-red); }
.intake[data-party="orange"] { --accent: var(--c-orange); }
.intake[data-party="amber"]  { --accent: var(--c-amber); }
.pick__input:focus-visible + .pick__body, .pick__input:focus-visible + .party-pick__body {
  outline: 3px solid var(--c-focus); outline-offset: 2px; box-shadow: inset 0 0 0 2px var(--c-focus-halo);
}

/* `אחר` opens a box, and it does so WITHOUT JAVASCRIPT.
 *
 * The default is visible and this rule hides it, which is the safe way round:
 * a browser that does not understand `:has()` drops the whole rule and shows a
 * usable field, where the inverse would hide it for ever. Selected by value
 * rather than by id because the tiles are rendered in a loop and none of them
 * carries one.
 *
 * NOT the `hidden` attribute — `[hidden] { display: none !important }` at the
 * top of this file is load-bearing for the wizard and cannot be overridden. */
/* Full width of the tile grid it belongs to, overriding `.field`'s 30rem prose
 * measure: this box is the answer to the tile directly above it, and a box that
 * stops short of the grid's edge reads as a different, unrelated question. */
.help-other { margin-block-start: 1rem; max-inline-size: none; }
.pick-grid:not(:has(.pick__input[value="other"]:checked)) + .help-other { display: none; }
/* Two paragraphs' worth, not the contact form's eleven-rem essay box: this is a
 * sentence or two about how someone can help, and a field sized far beyond what
 * it wants reads as an obligation to fill it. */
.intake .help-other textarea { min-block-size: 6.5rem; }
/* On a phone the tiles are already one per row, so the box needs the full width
 * and a little more air above it — otherwise it reads as part of the last tile
 * rather than as the thing that tile opened. */
@media (max-width: 34rem) {
  .help-other { margin-block-start: 1.25rem; }
  .intake .help-other textarea { min-block-size: 7.5rem; }
}

.party-pick { display: grid; gap: 1.1rem; padding-inline-end: 0.6rem; }
.party-pick__item--red    { --party-bg: var(--c-red);    --party-ink: #fff; }
.party-pick__item--orange { --party-bg: var(--c-orange); --party-ink: var(--c-ink); }
.party-pick__item--amber  { --party-bg: var(--c-amber);  --party-ink: var(--c-ink); }
.party-pick__body {
  display: block; position: relative; text-align: center;
  padding: 1.1rem 4.5rem 1rem; background: var(--c-surface-deep); color: var(--c-ink);
  box-shadow: 0.6rem 0.6rem 0 var(--c-fold);
}
.party-pick__item:hover .party-pick__body { background: var(--c-rule); }
/* With a real pointer the card behaves exactly like the home page's party
 * rows (the operator, 2026-09-05): it fills with the party's colour, the names take
 * that row's ink, and the badge takes the grey. Flat and instant, no
 * transition (D16). Touch screens keep the grey above: a hover that sticks
 * after a tap would look like a choice that was not made. */
@media (hover: hover) {
  .party-pick__item:hover .party-pick__body { background: var(--party-bg); color: var(--party-ink); }
  .party-pick__item:hover .party-pick__body .party__alt { color: var(--party-ink); }
  .party-pick__item:hover .party-pick__body .party__abbr { background: var(--c-surface-deep); color: var(--c-ink); }
}
/* Narrow screens: the badge keeps its corner, the names get the whole width
 * below it and a step smaller, so a long party name wraps in phrases, not words. */
@media (max-width: 44rem) {
  .party-pick__body { padding: 2.75rem 1rem 1rem; }
  .party-pick .party__name, .party-pick .party__alt { font-size: var(--step-1); }
}
.pick__input:checked + .party-pick__body { background: var(--party-bg); color: var(--party-ink); }
.pick__input:checked + .party-pick__body .party__alt { color: var(--party-ink); }
.pick__input:checked + .party-pick__body .party__abbr { background: var(--c-surface-deep); color: var(--c-ink); }

/* D58 · the forms are Tally's. The party cards are LINKS to each party's form
 * (tally.js opens it on the page instead), so they take the chosen style from a
 * class rather than from a checked radio, and once one is chosen the other two
 * step aside — the chosen card stays as the form's heading, since the form's
 * own title is hidden in the embed. */
a.party-pick__item { color: inherit; text-decoration: none; }
.party-pick__item.is-chosen .party-pick__body { background: var(--party-bg); color: var(--party-ink); }
.party-pick__item.is-chosen .party-pick__body .party__alt { color: var(--party-ink); }
.party-pick__item.is-chosen .party-pick__body .party__abbr { background: var(--c-surface-deep); color: var(--c-ink); }
.tally[data-chosen] .party-pick__item:not(.is-chosen) { display: none; }
.tally[data-chosen] .tally__pick .intake__legend { display: none; }
.tally__form { margin-block-start: 1.25rem; }
.tally__bar { margin: 0 0 0.75rem; }
.tally__frame { display: block; inline-size: 100%; border: 0; min-block-size: 20rem; }
.tally__privacy { margin-block-start: 1.5rem; }
.tally__open { margin: 0; }

.intake__consent { margin-block-start: 1.75rem; padding-block-start: 1.25rem; border-block-start: 3px solid var(--c-ink); }
.intake__sub { margin: 0 0 0.75rem; font-size: var(--step-1); font-weight: 700; color: var(--c-ink); }
.consent { display: flex; align-items: flex-start; gap: 0.75rem; margin-block-end: 1.25rem; font-weight: 400; }
.consent input { flex: none; inline-size: 1.35rem; block-size: 1.35rem; margin-block-start: 0.15rem; accent-color: var(--c-teal-ink); }
.consent__link { display: block; margin-block-start: 0.35rem; font-weight: 700; }
/* The submit is the hero's CTA in reverse: ink teal at rest, the mark's
 * colours on hover, the lift on transform only (D16). */
.intake__submit { inline-size: 100%; text-align: center; transition: transform 0.18s var(--ease-arrive); }
.intake__submit:hover, .intake__submit:focus-visible {
  background: linear-gradient(to left, var(--c-red) 0%, var(--c-amber) 50%, var(--c-orange) 100%);
  color: var(--c-ink) !important; transform: translateY(-2px);
}
.intake__nav { display: flex; justify-content: center; gap: 0.75rem; margin: 1.5rem 0 0; }
.cta--ghost { background: transparent; color: var(--c-teal-ink) !important; border: 2px solid var(--c-teal-ink); padding-block: calc(0.65rem - 2px); }
.cta--ghost:hover { background: var(--c-surface); }

/* The 404 page (review A10): one file for every locale, Hebrew and Arabic, and
 * a way back to each published edition. */
.not-found h1 span { display: block; }
.not-found .lede { max-width: 40ch; }
.not-found__homes { list-style: none; margin: 2rem 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.75rem; max-width: none; }

/* Language gate at the site root. Also the no-JS fallback, so it has to look
 * finished rather than like a loading state. The one centred composition on
 * the site (§4). On white, not the gradient: the 2026-09-20 lockup is teal
 * ink on transparent and has no white edition, so it needs a light ground.
 * Its width is capped at the supplied file's own 257 px — a larger raster or
 * a vector is still wanted (Q4). */
.gate { background: var(--c-bg); min-block-size: 100svh; display: grid; place-items: center; }
.gate__inner { text-align: center; padding-block: 3rem; }
.gate__logo { width: min(100%, 16rem); height: auto; margin-block-end: 2.5rem; }
.gate__langs { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 0.75rem; justify-content: center; max-width: none; }

/* Candidates (D54; the layout is the operator's, 2026-09-20, chosen from mockups).
 *
 * THE BANNER. The designer's banner artboard as one image (see
 * scripts/build-candidate-banner.py), under the heading. The heading used to
 * be laid over the image's top; measured 2026-09-24 (review A6), white on its
 * bright cyan was about 2.4:1, failing even large-text AA — and IS 5568 is a
 * legal requirement here — and between 769 and ~1000 px it covered faces. It
 * now sits on its own solid --c-teal-inkest strip above the image (white on
 * it is 8.41:1), with no text-shadow standing in for contrast. On a phone the
 * image is 14rem tall, wider than the screen, and scrolls; candidates.js
 * starts it centred.
 *
 * THE CARDS. Sixteen, four across on a desktop. The portrait is a square on
 * the teal gradient (a large graphic — the one use --c-teal is for), standing
 * over a grey box that holds the name, the party in its own colour (D53), and
 * the bio. The position badge stays on --c-teal-ink. Corners square and the
 * shadow a hard fold, as the hero's box and the party rows (the operator, 2026-09-20:
 * the home and volunteer pages "use sharp corners and boxy shadows") — one fold
 * per card, behind the portrait, and none on the box. */
.banner { position: relative; background: var(--c-teal-deep); overflow: hidden; }
.banner h1 {
  background: var(--c-teal-inkest); color: #fff; text-align: center;
  margin: 0; padding: 0.7rem var(--gutter) 0.8rem; font-size: clamp(2rem, 5vw, 3.2rem);
}
.banner__scroll { overflow: hidden; }
.banner__img { display: block; inline-size: 100%; block-size: auto; }
@media (max-width: 48rem) {
  .banner__scroll { overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
  .banner__scroll::-webkit-scrollbar { display: none; }
  .banner__img { block-size: 14rem; inline-size: auto; max-inline-size: none; }
  .banner h1 { font-size: 1.75rem; padding-block: 0.5rem 0.6rem; }
}
@media (prefers-reduced-motion: no-preference) { .banner__scroll { scroll-behavior: smooth; } }

.candidates {
  list-style: none; margin: 4rem 0 2rem; padding: 0; max-width: none;
  display: grid; gap: 3.25rem var(--gutter);
  grid-template-columns: repeat(4, 1fr);
}
.candidate { display: flex; flex-direction: column; }
.candidate__portrait {
  position: relative; aspect-ratio: 1; overflow: hidden; border-radius: 0;
  inline-size: 68%; margin: 0 auto -2.4rem; z-index: 1;
  background: var(--c-teal-deep) linear-gradient(160deg, var(--c-teal-light), var(--c-teal-deep) 70%, var(--c-teal-inkest));
  border: 1px solid #000; box-shadow: 0.4rem 0.4rem 0 var(--c-fold);
}
.candidate__photo { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }
.candidate__position {
  position: absolute; inset-block-end: 0; inset-inline-start: 0;
  margin: 0; padding: 0.1rem 0.6rem;
  background: var(--c-teal-ink); color: #fff;
  font-weight: 700; font-size: var(--step-0); line-height: 1.4;   /* one step down from step-1, ~80 % (the operator, 2026-09-20: "±75%") */
  border-start-end-radius: 0;
}
.candidate__text {
  flex: 1; display: flex; flex-direction: column; gap: 0.35rem;
  background: var(--c-surface); border-radius: 0; border: 1px solid var(--c-rule);
  padding: 3.2rem 1.1rem 1.25rem;
}
.candidate__name { font-size: var(--step-1); margin: 0; text-align: center; }
.candidate__party { margin: 0 0 0.3rem; font-size: var(--step--1); font-weight: 700; color: var(--c-muted); text-align: center; }
.candidate__hue {
  display: inline-block; inline-size: 0.7em; block-size: 0.7em; border-radius: 2px;
  margin-inline-end: 0.4em; vertical-align: -0.02em;
}
.candidate__hue--red    { background: var(--c-red); }
.candidate__hue--orange { background: var(--c-orange); }
.candidate__hue--amber  { background: var(--c-amber); }
.candidate__bio { margin: 0; font-size: var(--step--1); }
@media (max-width: 64rem) { .candidates { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 48rem) { .candidates { grid-template-columns: repeat(2, 1fr); gap: 2.75rem 1rem; } }
@media (max-width: 30rem) {
  .candidates { grid-template-columns: 1fr; margin-block-start: 3rem; }
  .candidate__portrait { inline-size: 52%; }
}
