@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 200 800;   /* variable; also carries an opsz 6–72 axis */
  font-display: swap;
  src: url(assets/fonts/newsreader-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url(assets/fonts/newsreader-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 100 700;   /* variable */
  font-display: swap;
  src: url(assets/fonts/plex-sans-latin.woff2) format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 100 700;
  font-display: swap;
  src: url(assets/fonts/plex-sans-latin-ext.woff2) format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  /* Official KDU-ČSL palette — Grafický manuál KDU-ČSL 2022 (v0.3), § 0.3
     "Základní barevnost": https://www.kdu.cz/o-nas/grafika/graficky-manual
       MODRÁ  CMYK 100/70/0/50   RGB 0/50/100     #003264
       ŽLUTÁ  CMYK 0/15/90/0     RGB 255/215/25   #FFD719
       BÍLÁ   CMYK 0/0/0/0       RGB 255/255/255  #FFFFFF
     Held as channels so the scrims further down can vary alpha off the same
     source instead of hardcoding the colour again. */
  --primary-rgb: 0 50 100;
  --primary-dark-rgb: 0 31 62; /* derived — the manual defines no dark blue, and
                                  the photo needs a deeper ground than MODRÁ */
  --accent-rgb: 255 215 25;

  --color-primary: rgb(var(--primary-rgb));
  --color-primary-dark: rgb(var(--primary-dark-rgb));
  --color-accent: rgb(var(--accent-rgb));

  --color-text: #12253d;
  --color-paper: #f6f3ec; /* warm stock — the card is printed matter, not screen white.
                             The manual's BÍLÁ is for logo grounds, not every surface. */

  /* Ink for the profile card. It is a ballot slip, so it is set in ink:
     the party yellow deliberately never appears inside the card — on this
     paper it measures 1.26:1, far below any legible threshold. */
  --ink-rgb: 22 35 58;
  --ink: rgb(var(--ink-rgb));
  --ink-muted: #5d6b7e;
  --rule: rgb(var(--ink-rgb) / .16);
  --rule-strong: rgb(var(--ink-rgb) / .42);

  --font-display: "Newsreader", Georgia, "Times New Roman", serif;
  --font-ui: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;

  /* Aspect ratio of the photo. Set this to the real photo's ratio after swapping. */
  --photo-ratio: 16/9;

  /* The portraits' aspect ratio, 3:4 (1200×1600 and the like), as two numbers
     so calc() can use it either way up. Every rule that has to meet the
     portrait's edge — the panel, the shading box, the card's top on a phone —
     reads these; the one thing that can't is the @media bound in the
     "portrait" section, which repeats 3/4 as a literal. If the portraits are
     ever reshot to another ratio, change it here and there. Two of the fifteen
     are narrower than 3:4 (09, and 14 at 2:3) and leave a strip of bare paper
     inside that edge rather than overflowing it. */
  --portrait-w: 3;
  --portrait-h: 4;

  /* Width the contain-fitted portrait actually takes: its height decides it.
     Here that height is the window; the wide-landscape block subtracts the
     card from it, since there the photo stops above the card instead of
     running behind it. */
  --portrait-width: calc(100dvh * var(--portrait-w) / var(--portrait-h));

  --fade-duration: 720ms;
  --ease-out: cubic-bezier(.22, .61, .36, 1);
  --banner-height: 0px; /* height of the dev banner, set further down */
  /* height of the profile card — app.js measures it and sets the real value
     on <html> whenever a profile is open; the guess here only covers rules
     evaluated before then */
  --card-height: 40dvh;
  /* left edge of the profile card. On the wide layout app.js sets it to the
     kandidátka's own left edge, so the card sits under that list and the
     portrait alone, and the letter column beside it keeps the full height.
     0 — the card spanning the window — is every other layout. */
  --card-left: 0px;
}

/* ---------------------------------------------------------------------------
 * The generated pages: kandidati/<slug>/, program/ and 404.html.
 *
 * tools/build-site.js prints this file after the @font-face blocks and the
 * :root tokens it lifts out of styles.css, and writes the result as pages.css.
 * styles.css itself cannot be linked from these pages: it pins html and body
 * to the window and forbids scrolling, which the photo needs and a page of
 * text must not have.
 *
 * Same printed matter as the profile card — warm stock, ink, hairline rules,
 * the number in a box in the left gutter with the text hanging off it, cut
 * edges. The party colours stay in the masthead, where the logotype needs
 * its navy ground.
 * ------------------------------------------------------------------------- */

* { box-sizing: border-box; }

/* Same root scale as styles.css, and the same 2560px-wide reference — but width
   only. These are scrolling documents, so their type has no window height to fit
   inside, and a short browser window must not shrink them. The 68rem wrap, the
   `columns: 2 22rem` and the 58ch measure all grow in step, so the line length
   in characters is unchanged; only the type gets bigger.
   It lives here rather than in the :root block build-site.js lifts out of
   styles.css, which is what keeps the two formulas independent. */
html {
  -webkit-text-size-adjust: 100%;
  font-size: max(1em, 100vw / 160);
}

body {
  margin: 0;
  background: var(--color-paper);
  color: var(--ink);
  font-family: var(--font-display);
  font-size: clamp(1rem, .95rem + .3vw, 1.12rem);
  line-height: 1.65;
}

a { color: var(--color-primary); text-underline-offset: .18em; }
a:hover { text-decoration-thickness: 2px; }
/* party blue, not the gold used on the photo — gold on this paper is 1.26:1 */
a:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 3px; }

/* --- masthead ------------------------------------------------------------- */

.masthead {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .6rem 1.5rem;
  padding: calc(.9rem + env(safe-area-inset-top)) clamp(1.2rem, 5vw, 3rem) .9rem;
  background: var(--color-primary-dark);
  font-family: var(--font-ui);
  font-size: .78rem;
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.masthead a { color: #fff; text-decoration: none; }
.masthead a:hover { text-decoration: underline; }
.masthead a:focus-visible { outline-color: var(--color-accent); }
.masthead-home { display: flex; align-items: center; gap: .9rem; }
.masthead-home img { display: block; }
.masthead nav { display: flex; gap: 1.5rem; }

/* --- the sheet ------------------------------------------------------------ */

main {
  max-width: 68rem;
  margin: 0 auto;
  padding: clamp(1.5rem, 5vw, 3.5rem) clamp(1.2rem, 5vw, 3rem);
}

/* portrait beside the entry; under 860px the portrait goes above it — at 720px
   the bio was left a 200px column beside it on a tablet held upright */
.entry {
  display: grid;
  grid-template-columns: minmax(0, 22rem) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}
.entry-photo {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--rule-strong);
}

/* gutter holds the ballot number, the text column hangs off it — the profile
   card's own grid */
.entry-text {
  display: grid;
  grid-template-columns: [gutter] auto [text] minmax(0, 58ch);
  justify-content: start;
  column-gap: clamp(.9rem, 3vw, 1.6rem);
  align-content: start;
}
.entry-text > * { grid-column: text; }

/* a page with no number to hang from: the same measure, from the left edge */
.sheet { max-width: 58ch; }

.order {
  grid-column: gutter;
  grid-row: 1 / span 2;
  margin: 0;
  text-align: center;
}
/* on the lístek the number is a box, not a numeral */
.order-num {
  display: inline-grid;
  place-items: center;
  min-width: 2.1em;
  aspect-ratio: 1;
  border: 1px solid var(--rule-strong);
  font-family: var(--font-ui);
  font-size: clamp(1.3rem, 4vw, 1.8rem);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
  color: var(--color-primary);
}
/* readable by screen readers, invisible on screen */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.order-label,
.kicker,
.job {
  font-family: var(--font-ui);
  font-weight: 500;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.order-label { display: block; margin-top: .5em; font-size: .6rem; letter-spacing: .13em; }
.kicker { margin: 0 0 .4rem; font-size: .78rem; }
.job { margin: 0; font-size: .78rem; }

h1 {
  margin: 0 0 .25rem;
  font-size: clamp(1.7rem, 4.6vw, 2.6rem);
  font-weight: 600;
  line-height: 1.08;
  color: var(--color-primary);
}

.bio,
.sheet-body {
  margin: clamp(1rem, 2.6vh, 1.5rem) 0 0;
  padding-top: clamp(1rem, 2.6vh, 1.5rem);
  border-top: 1px solid var(--rule);
}

/* set as on the profile card */
.bio {
  text-align: justify;
  hyphens: auto; /* lang="cs": without it a justified line opens holes */
}

.entry-links {
  margin: 1.5rem 0 0;
  padding: 1rem 0 0;
  border-top: 1px solid var(--rule);
  list-style: none;
  font-family: var(--font-ui);
  font-size: .9rem;
}
.entry-links li + li { margin-top: .35rem; }

/* previous / next on the kandidátka */
.steps {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  margin-top: clamp(2rem, 5vw, 3rem);
  padding: .8rem 0;
  border-top: 1px solid var(--rule-strong);
  border-bottom: 1px solid var(--rule);
  font-family: var(--font-ui);
  font-size: .9rem;
}
.steps a { text-decoration: none; }
.steps a:hover { text-decoration: underline; }
.steps .next { margin-left: auto; text-align: right; }

/* --- programme ------------------------------------------------------------ */

.panel-intro-salutation { margin: 0 0 .5em; font-size: 1.12em; font-weight: 700; }
.panel-intro-text, .panel-outro-text { margin: 0 0 1em; }
/* the label takes the line above it, so the text needs a box of its own */
.program-text { display: block; }
.panel-outro-vote { font-weight: 700; }

.program-group {
  margin: 1.8rem 0 .6rem;
  font-family: var(--font-ui);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--color-primary);
}
.program ul { margin: 0 0 1em; padding-left: 1.4em; }
.program li { margin: 0 0 .55em; padding-left: .2em; }
.program li::marker { color: var(--color-primary); font-weight: 600; }

/* the sheet is one 58ch measure, too narrow for the column the index page
   sets the labels in — here the label just takes the line above its text */
.program li strong {
  display: block;
  font-weight: 600;
  font-size: 1.12em;
  text-transform: uppercase;
  letter-spacing: .03em;
}

/* --- kandidátka ----------------------------------------------------------- */

.ballot { margin-top: clamp(2.5rem, 6vw, 4rem); }
.ballot h2 {
  margin: 0;
  padding-bottom: .6rem;
  /* the double rule that heads the profile card */
  border-bottom: 1px solid var(--rule-strong);
  box-shadow: 0 3px 0 var(--color-paper), 0 4px 0 var(--rule);
  font-family: var(--font-ui);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--color-primary);
}
.ballot ol {
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
  columns: 2 22rem;
  column-gap: clamp(1.5rem, 4vw, 3rem);
}
.ballot li { break-inside: avoid; border-bottom: 1px solid var(--rule); }
.ballot a {
  display: grid;
  grid-template-columns: 2.2em minmax(0, 1fr);
  column-gap: .6rem;
  align-items: baseline;
  padding: .5rem 0;
  color: var(--ink);
  text-decoration: none;
}
.ballot a:hover .ballot-name { text-decoration: underline; }
.ballot-num {
  font-family: var(--font-ui);
  font-size: .85em;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-primary);
}
.ballot-job {
  grid-column: 2;
  font-family: var(--font-ui);
  font-size: .78rem;
  color: var(--ink-muted);
  line-height: 1.4;
}
.ballot [aria-current] .ballot-name { font-weight: 700; }

/* --- foot ----------------------------------------------------------------- */

.foot {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  padding: 1.2rem clamp(1.2rem, 5vw, 3rem) calc(1.2rem + env(safe-area-inset-bottom));
  border-top: 1px solid var(--rule-strong);
  text-align: center;
  color: var(--ink-muted);
}
.foot p { margin: 0; }
.foot .slogan { font-style: italic; color: var(--ink); }

@media (max-width: 860px) {
  .entry { grid-template-columns: minmax(0, 1fr); }
  .entry-photo { max-width: 22rem; }
}

@media (max-width: 720px) {
  .masthead-title { display: none; } /* the logotype alone leads home */
}

