/*
 * Genea Bohemia — design system (redesign 2026-09)
 * One stylesheet for preview/ and theme/. Order: fonts, tokens, reset, type,
 * layout, buttons & controls, header, footer, reveal, lightbox, then sections.
 * Spec: docs/superpowers/specs/2026-09-09-visual-redesign-design.md
 */

/* ===== 1. Fonts (self-hosted, GDPR) ===== */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('../fonts/inter-var.woff2') format('woff2');
}
@font-face {
  font-family: 'Newsreader';
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url('../fonts/newsreader-var.woff2') format('woff2');
}

/* ===== 2. Tokens ===== */
:root {
  color-scheme: only light;
  --paper: #f6f1e7;
  --paper-2: #ece6d8;
  --card: #fbf8f2;
  --ink: #1f3a2e;
  --ink-2: #2f4a3d;
  --muted: #5c605a;
  --gold: #c9a04a;
  --gold-text: #7a5a1c;
  --gold-rule: rgba(184, 143, 59, 0.3);
  --gold-rule-strong: rgba(184, 143, 59, 0.45);
  --cream: #fbf6ea;
  --error: #a1403f;
  --green-2: #2a4a3a;
  --green-rule: rgba(31, 58, 46, 0.18);
  --man: #41abf7; --man-line: #0e80d0; --woman: #ff95bd; --woman-line: #cc628a;

  --font-serif: 'Newsreader', Georgia, 'Times New Roman', serif;
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;

  --s-1: 0.25rem; --s-2: 0.5rem; --s-3: 0.75rem; --s-4: 1rem; --s-6: 1.5rem;
  --s-8: 2rem; --s-12: 3rem; --s-16: 4rem;

  --r-btn: 999px; --r-input: 6px; --r-card: 12px; --r-pill: 999px;
  --header-h: 68px;
  --container: 1200px;
  --container-wide: 1440px;
  --measure: 65ch;
}
@media (min-width: 768px) { :root { --header-h: 88px; } }

/* ===== 3. Reset ===== */
*, *::before, *::after { box-sizing: border-box; }
html { font-size: 106.25%; -webkit-text-size-adjust: 100%; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 1rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
/* Scroll lock (mobile menu + lightbox, D: owner 2026-09-12): reserves the removed scrollbar's
   width as padding so fixed and flow content do not shift when overflow is hidden. The sticky
   header is a normal-flow child of body (not fixed), so the body padding narrows it along with
   everything else — verified in Chrome: a second, explicit padding-right on .site-header double-
   counts the gutter and shifts the header off-centre instead of holding it still. */
body.is-locked { overflow: hidden; padding-right: var(--scroll-gutter, 0px); }
img, picture, video, svg { display: block; max-width: 100%; }
[hidden] { display: none !important; }
img { height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
ul, ol { margin: 0; padding: 0; list-style: none; }
p { margin: 0 0 var(--s-4); text-align: left; }
a { color: var(--ink); text-decoration: underline; text-decoration-color: var(--gold-rule-strong); text-underline-offset: 3px; }
a:hover { text-decoration-color: var(--gold-text); }
strong { font-weight: 600; }
hr { border: 0; border-top: 1px solid var(--gold-rule); margin: var(--s-8) 0; }

:is(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 3px;
}
:is(a, button, input, select, textarea, summary, [tabindex]):focus:not(:focus-visible) { outline: none; }

.screen-reader-text {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; top: -100px; left: var(--s-4); z-index: 1000;
  padding: var(--s-3) var(--s-4); background: var(--ink); color: var(--cream);
  border-radius: var(--r-input); text-decoration: none; transition: none;
}
.skip-link:focus { top: var(--s-4); }

/* ===== 4. Type ===== */
h1, h2, h3, h4 { font-family: var(--font-serif); margin: 0 0 var(--s-4); color: var(--ink); text-wrap: balance; }
/* Serif headings: no letter-spacing and no common ligatures. Newsreader's "fi" ligature merges
   the two letters and drops the dot, which the owner read as broken ("Grafické", 2026-09-19); with
   the ligature off and the old -0.02em tracking the hook of the f sat on the dot of the i. At
   letter-spacing 0 the pair keeps a sliver of air (variants A–F compared in Chrome, row B chosen). */
h1 { font-size: 2.2353rem; line-height: 1.02; font-weight: 400; font-variant-ligatures: no-common-ligatures; }
h2 { font-size: 1.6471rem; line-height: 1.08; font-weight: 400; font-variant-ligatures: no-common-ligatures; }
h3 { font-size: 1.2941rem; line-height: 1.2; font-weight: 500; }
h4 { font-size: 1rem; line-height: 1.3; font-weight: 500; }
@media (min-width: 768px) {
  h1 { font-size: 3.7647rem; }
  h2 { font-size: 2.3529rem; }
  h3 { font-size: 1.4118rem; }
  body { font-size: 1.0588rem; }
  .price { font-size: 1.8824rem; }
  .lead { font-size: 1.1765rem; }
}
.price { font-family: var(--font-serif); font-size: 1.7647rem; line-height: 1.1; font-weight: 600; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
.lead { color: var(--ink-2); font-size: 1.0588rem; line-height: 1.5; max-width: var(--measure); text-wrap: pretty; }
.small { font-size: 0.7647rem; line-height: 1.45; color: var(--muted); }
.label {
  display: inline-block;
  font-family: var(--font-sans); font-size: 0.7059rem; line-height: 1.3; font-weight: 600;
  letter-spacing: .10em; text-transform: uppercase; color: var(--muted);
}
.prose > * { max-width: 70ch; }
.prose h2 { margin-top: var(--s-8); }
.prose ul { list-style: disc; padding-left: 1.2em; margin-bottom: var(--s-4); }
.prose li { margin-bottom: var(--s-2); }
.prose a { text-decoration-color: var(--gold-text); }

/* ===== 5. Layout ===== */
.container { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 var(--s-4); }
@media (min-width: 768px) { .container { padding: 0 2.5rem; } }
.section { padding: var(--s-12) 0; }
.section--alt { background: var(--paper-2); }
@media (min-width: 768px) { .section { padding: 5rem 0; } }
.section-head { margin-bottom: var(--s-8); }
.section-head .label { display: block; margin-bottom: 0.7059rem; }
/* h1 (64px, line-height 1.02) has no half-leading, so capital háčky (Články) overshoot the line
   box and crowd the eyebrow at the 12px h2 gap; give the h1 case its own room (owner, 2026-09-18).
   Collapses with the label's margin-bottom, so this value IS the gap (25.5px). */
.section-head .label + h1 { margin-top: var(--s-6); }
.section-head h2 { margin-bottom: var(--s-2); }
.section-head .lead { margin-bottom: 0; }
/* Two-line leads break evenly instead of leaving a two-word tail ("Píšeme z / vlastních zakázek",
   owner 2026-09-22 on clanky.html). Chrome balances up to six lines; longer leads are untouched. */
.section-head .lead, .section-head .lead p { text-wrap: balance; }
.main-content { display: block; }

/* ===== 6. Buttons & controls ===== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  min-height: 48px; padding: 0 1.75rem;
  font-family: var(--font-sans); font-size: 0.9412rem; line-height: 1; font-weight: 600;
  border: 0; border-radius: var(--r-btn); text-decoration: none; cursor: pointer;
  transition: background-color .2s ease-out, border-color .2s ease-out, transform .2s ease-out;
}
.btn--primary { background: var(--ink); color: var(--cream); }
.btn--primary:hover { background: var(--green-2); }
.btn--secondary { background: transparent; color: var(--ink); border: 1.5px solid var(--ink); }
.btn--secondary:hover { background: rgba(31, 58, 46, 0.06); }
.btn--ink { background: var(--ink); color: var(--cream); }
.btn--ink:hover { background: var(--green-2); }
.btn:active { transform: translateY(1px); }
.btn--block { width: 100%; }
.btn--sm { min-height: 40px; padding: 0 1.25rem; }

.link-arrow {
  display: inline;
  font-family: var(--font-sans); font-weight: 600; color: var(--ink);
  text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 1px;
  text-underline-offset: 5px; text-decoration-skip-ink: auto; /* 5px: 3px sat on the descenders (owner round 2, 2026-09-18) */
  transition: text-decoration-color .2s ease-out;
}
/* display: inline-block so text-decoration (set on .link-arrow above) never propagates
   into the arrow glyph itself. inline-flex previously made Chrome paint the underline on
   the anonymous flex item at the default depth, cutting through descenders (owner
   screenshot 2026-09-18, R20); plain inline text + an inline-block glyph fixes that. */
.link-arrow::after { content: "→"; display: inline-block; margin-left: 6px; text-decoration: none; transition: transform .2s ease-out; }
.link-arrow:hover { text-decoration-color: var(--gold-rule-strong); }
.link-arrow:hover::after { transform: translateX(3px); }
/* The "Ceník ↓" variant keeps its downward glyph and nudges on the Y axis (spec §6.3). */
.link-arrow[data-dir="down"]::after { content: "↓"; }
.link-arrow[data-dir="down"]:hover::after { transform: translateY(3px); }
/* .tier-schema is a <button>; display: inline above would drop its padding/min-height tap
   target, so it keeps its own box (R20). */
.tier-schema.link-arrow { display: inline-block; }

.band--green { background: var(--ink); color: var(--cream); }
.band--green h1, .band--green h2, .band--green h3, .band--green .lead, .band--green a { color: var(--cream); }
.band--green .label { color: var(--cream); opacity: .8; }
.band--green .btn--secondary { color: var(--cream); border-color: var(--cream); }
.band--green .btn--secondary:hover { background: rgba(251, 246, 234, 0.10); }
.band--green :is(a, button, input, select, textarea, summary, [tabindex]):focus-visible { outline-color: var(--cream); }

/* Spec §6.7 / owner ruling R14: one joined pill group, not spaced-out buttons. */
.seg { display: flex; gap: 0; }
.seg__btn {
  flex: 1;
  min-height: 48px; padding: var(--s-2) var(--s-3);
  background: var(--card); color: var(--ink);
  border: 1.5px solid var(--green-rule); border-radius: 0; margin-left: -1.5px;
  font-size: 0.9412rem; font-weight: 500; line-height: 1.2;
}
.seg__btn:first-child { border-radius: var(--r-btn) 0 0 var(--r-btn); margin-left: 0; }
.seg__btn:last-child { border-radius: 0 var(--r-btn) var(--r-btn) 0; }
.seg__btn.active { background: var(--ink); color: var(--cream); border-color: var(--ink); position: relative; z-index: 1; }
.seg__btn:active { transform: translateY(1px); }

.form__field { margin-bottom: var(--s-4); }
.form__label { display: block; margin-bottom: var(--s-2); font-weight: 500; }
.form__req { color: var(--gold-text); }
.form__input {
  display: block; width: 100%; min-height: 48px; padding: var(--s-3) var(--s-4);
  background: #fff; border: 1.5px solid var(--green-rule); border-radius: var(--r-input);
}
textarea.form__input { min-height: 140px; resize: vertical; }
/* File upload (owner 2026-11-03): no box around it; a full-size pill with a paperclip so it is easy to spot, light fill so the dark submit button stays the only primary action. */
input[type="file"].form__input { min-height: 0; padding: 0; background: none; border: 0; color: var(--ink); cursor: pointer; }
input[type="file"].form__input::file-selector-button { min-height: 48px; margin-right: var(--s-4); padding: 0 1.5rem 0 2.9rem; font: 600 0.9412rem var(--font-sans); color: var(--ink); background: var(--paper-2) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231f3a2e' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M21 11.5l-8.6 8.6a5.5 5.5 0 0 1-7.8-7.8l8.6-8.6a3.7 3.7 0 0 1 5.2 5.2l-8.6 8.6a1.8 1.8 0 0 1-2.6-2.6l7.9-7.9'/%3E%3C/svg%3E") no-repeat 1.15rem 50% / 20px; border: 1.5px solid var(--ink); border-radius: var(--r-btn); cursor: pointer; transition: background-color .2s ease-out; }
input[type="file"].form__input::file-selector-button:hover { background-color: rgba(31, 58, 46, 0.12); }
input[type="file"].form__input + .small, .wpcf7-form-control-wrap + .small { margin-top: var(--s-2); }
select.form__input { appearance: none; -webkit-appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%231f3a2e' stroke-width='1.8'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right var(--s-4) center; padding-right: 2.5rem; }
/* Chrome's customizable select: site-styled list. Other browsers keep the native popup. */
@supports (appearance: base-select) {
  select.form__input, select.form__input::picker(select) { appearance: base-select; }
  select.form__input::picker-icon { display: none; }
  select.form__input::picker(select) {
    box-sizing: border-box; inline-size: anchor-size(width); position-try-order: normal; margin-block-start: var(--s-1); padding: var(--s-1);
    background: #fff; border: 1.5px solid var(--green-rule); border-radius: var(--r-card); box-shadow: 0 8px 24px rgb(31 58 46/.1);
  }
  select.form__input option {
    min-height: 44px; padding: var(--s-2) var(--s-3); display: flex; align-items: center; gap: var(--s-3);
    font: inherit; white-space: normal; color: var(--ink); border-radius: var(--r-input);
  }
  select.form__input option:hover, select.form__input option:focus-visible { background: var(--paper-2); }
  select.form__input option:focus-visible { outline: 2px solid var(--ink); outline-offset: -2px; }
  select.form__input option:checked { font-weight: 600; }
  select.form__input option::checkmark { color: var(--ink); }
}
.form__check { display: flex; align-items: flex-start; gap: var(--s-3); min-height: 44px; padding: var(--s-2) 0; }
.form__check input { flex: 0 0 auto; width: 24px; height: 24px; margin: 0; accent-color: var(--ink); cursor: pointer; }
.form__check label { cursor: pointer; }
.wpcf7-not-valid-tip { color: var(--error); font-size: 0.8235rem; display: block; margin-top: var(--s-1); }
.wpcf7 form .wpcf7-response-output { margin: var(--s-4) 0 0; padding: var(--s-3) var(--s-4); border: 1.5px solid var(--gold-rule-strong); border-radius: var(--r-input); }
.wpcf7-spinner { display: none; }

.badge {
  display: inline-block; padding: var(--s-1) var(--s-3); border-radius: var(--r-pill);
  font-size: 0.7647rem; line-height: 1.4; font-weight: 600;
}
.badge--inc { background: var(--ink); color: var(--cream); }
.badge--opt { background: var(--card); color: var(--ink-2); border: 1px solid var(--green-rule); }

.card { background: var(--card); border: 0; border-radius: var(--r-card); padding: 20px; }
.check-list li { position: relative; padding-left: 1.6em; margin-bottom: var(--s-2); font-size: 0.8824rem; line-height: 1.45; }
.check-list li::before {
  content: ""; position: absolute; left: 0; top: 0.35em; width: 0.9em; height: 0.5em;
  border-left: 2px solid var(--ink); border-bottom: 2px solid var(--ink); transform: rotate(-45deg);
}

/* ===== 7. Header ===== */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--paper);
  border-bottom: 1px solid transparent;
}
.site-header.is-scrolled { border-bottom-color: var(--gold-rule); }
/* Header claims a wider band than the content container (owner ruling R25, 2026-09-12):
   on wide monitors the 1200px content column left the navbar looking squeezed too. */
.site-header .container { max-width: var(--container-wide); }
.site-header__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); height: var(--header-h); }
.logo { display: block; flex-shrink: 0; }
.logo img, .custom-logo-link img { height: 44px; width: auto; }
@media (min-width: 768px) { .logo img, .custom-logo-link img { height: 64px; } }
.nav__controls { display: flex; align-items: center; gap: var(--s-3); }
.nav__cta { white-space: nowrap; flex-shrink: 0; }
.nav__cta-short { display: none; }
@media (max-width: 479px) { .nav__cta-long { display: none; } .nav__cta-short { display: inline; } }

.menu-btn {
  width: 44px; height: 44px; padding: 10px; margin: 0 -10px 0 0;
  background: none; border: 0; display: flex; flex-direction: column; justify-content: center; gap: 5px;
}
.menu-btn span { display: block; height: 2px; background: var(--ink); border-radius: 1px; transition: transform .2s ease-out, opacity .2s ease-out; }
.menu-btn.active span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-btn.active span:nth-child(2) { opacity: 0; }
.menu-btn.active span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Mobile menu panel: full-screen paper below the header. */
.nav {
  position: fixed; left: 0; right: 0; top: var(--header-h);
  height: 0; overflow: hidden; visibility: hidden;
  background: var(--paper); border-top: 1px solid var(--gold-rule);
  transition: opacity .2s ease-out; opacity: 0;
}
.nav.is-open { height: calc(100dvh - var(--header-h)); overflow-y: auto; -webkit-overflow-scrolling: touch; visibility: visible; opacity: 1; }
.nav ul { padding: var(--s-4) 0; }
.nav a, .nav ul li a {
  display: block; padding: 0 var(--s-4); min-height: 56px; line-height: 56px;
  font-family: var(--font-serif); font-size: 1.5294rem; font-weight: 500;
  text-decoration: none; color: var(--ink); white-space: nowrap;
  border-bottom: 1px solid var(--gold-rule);
}
.nav a.active, .nav ul li.current-menu-item > a { color: var(--ink); box-shadow: inset 3px 0 0 var(--ink); }

@media (min-width: 992px) {
  .site-header .container { display: grid; grid-template-columns: auto 1fr auto; align-items: center; }
  .logo { grid-column: 1; }
  .nav { grid-column: 2; justify-self: center; }
  .nav__controls { grid-column: 3; justify-self: end; }
}

@media (min-width: 1440px) {
  .menu-btn { display: none; }
  .nav {
    position: static; height: auto; overflow: visible; visibility: visible; opacity: 1;
    background: none; border: 0; transition: none;
  }
  .nav ul { display: flex; align-items: center; gap: 1.25rem; padding: 0; }
  .nav a, .nav ul li a {
    padding: 6px 0 4px; min-height: 0; line-height: 1;
    font-family: var(--font-sans); font-size: 0.9412rem; font-weight: 500;
    border: 0;
  }
  .nav a.active, .nav ul li.current-menu-item > a {
    color: var(--ink); box-shadow: none; text-decoration: underline; text-decoration-color: var(--ink);
    text-decoration-thickness: 2px; text-underline-offset: 6px;
  }
  .nav a:hover { text-decoration: underline; text-decoration-color: var(--gold-rule-strong); text-decoration-thickness: 2px; text-underline-offset: 6px; }
  .site-header__inner { gap: 2.5rem; }
  .logo img, .custom-logo-link img { height: 72px; }
}

/* ===== 8. Footer ===== */
.site-footer { background: var(--ink); color: var(--cream); font-size: 0.7647rem; line-height: 1.5; padding: 3.5rem 0 2rem; }
.site-footer button { padding: 0; border: 0; background: 0 0; text-decoration: underline; text-underline-offset: 3px; }
.site-footer :is(a, button) { color: var(--cream); text-decoration-color: rgba(251, 246, 234, 0.3); }
.site-footer :is(a, button):hover { text-decoration-color: var(--cream); }
.site-footer p { margin-bottom: var(--s-2); }
.footer__grid { display: grid; gap: var(--s-8); }
@media (min-width: 768px) { .footer__grid { grid-template-columns: 1.4fr 1fr; } }
.footer__links li { display: block; }
.footer__links a { display: inline-block; padding: 0.4rem 0; color: var(--cream); opacity: .8; text-decoration: none; }
.footer__links a:hover { opacity: 1; text-decoration: underline; }
.footer__bottom { margin-top: var(--s-8); padding-top: var(--s-4); border-top: 1px solid rgba(251, 246, 234, 0.15); display: flex; flex-wrap: wrap; gap: var(--s-4); justify-content: space-between; }
.footer__bottom p { margin: 0; }
.footer__muted { color: rgba(251, 246, 234, 0.6); }

.back-to-top {
  position: fixed; right: var(--s-4); bottom: var(--s-4); z-index: 90;
  width: 44px; height: 44px; border-radius: 50%;
  background: var(--paper); color: var(--ink); border: 1px solid var(--gold-rule-strong);
  display: flex; align-items: center; justify-content: center;
  opacity: 0; visibility: hidden; transition: opacity .2s ease-out, visibility .2s;
}
.back-to-top.is-visible { opacity: 1; visibility: visible; }
.back-to-top:active { transform: translateY(1px); }

/* ===== 9. Reveal (only motion on the page) ===== */
.reveal {
  opacity: 0.001;
  transform: translateY(12px);
  transition: opacity 0.4s ease-out, transform 0.4s ease-out;
}
.reveal.is-visible { opacity: 1; transform: none; }
.no-js .reveal { opacity: 1; transform: none; }

/* ===== 10. Lightbox ===== */
.lightbox {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(31, 28, 24, 0.82);
  display: flex; align-items: center; justify-content: center; padding: var(--s-4);
  opacity: 0; visibility: hidden; transition: opacity .2s ease-out, visibility .2s;
}
/* The overlay spans the full (scrollbar-hidden) viewport while the page content is padded by
   --scroll-gutter (D, setScrollLock); without this the panel's centre sits gutter/2 right of
   the content's centre (owner 2026-09-12, round 2: panel visibly right of page centre). Extra
   padding-right, not a shift, so the overlay still covers edge-to-edge — no paper strip shows. */
body.is-locked .lightbox { padding-right: calc(var(--s-4) + var(--scroll-gutter, 0px)); }
@media (max-width: 767px) {
  .lightbox { padding: var(--s-3); }
  body.is-locked .lightbox { padding-right: calc(var(--s-3) + var(--scroll-gutter, 0px)); }
}
.lightbox.active { opacity: 1; visibility: visible; }
.lightbox-panel {
  position: relative; width: fit-content; max-width: min(96vw, 1100px); max-height: 92dvh;
  background: var(--paper); border-radius: var(--r-card); padding: var(--s-4);
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.35);
  display: flex; flex-direction: column; gap: var(--s-3); overflow: auto;
}
@media (max-width: 767px) { .lightbox-panel { padding: var(--s-3); } .lightbox-img { max-height: 70dvh; } }
/* Video keeps a full-width frame — it has no intrinsic box to hug like the image does
   (owner 2026-09-12: image not centred inside a panel sized for something else). */
.lightbox--video .lightbox-panel { width: min(96vw, 1100px); }
/* Schema dialogs size to the diagram instead of claiming a fixed wide panel, which used to
   read as content shifted left, with dead space around a narrow tree. */
.lightbox--wide .lightbox-panel {
  width: fit-content; min-width: min(96vw, 560px); max-width: min(96vw, 1800px); max-height: 96dvh;
}
/* 92dvh panel minus ~106px of chrome: tall images never scroll (owner 2026-11-03). */
.lightbox-img { max-height: calc(92dvh - 8rem); max-width: 100%; width: auto; height: auto; margin: 0 auto; }
.lightbox-title { font-family: var(--font-serif); font-size: 1rem; text-align: center; }
.lightbox--schema .lightbox-title { display: none; }
.lightbox-counter { font-size: 0.7647rem; color: var(--muted); text-align: center; }
/* The package position is redundant with the explainer's own dots + Zpět/Další arrows below
   it, at every width — not just phone — so the counter row (plus the panel's own row-gap
   next to it) never needs to be part of the schema dialog's chrome budget (round 1, D19). */
.lightbox--schema .lightbox-counter { display: none; }
.lightbox-close {
  position: absolute; top: var(--s-2); right: var(--s-2);
  width: 44px; height: 44px; padding: 0; border: 2px solid var(--paper); border-radius: 50%;
  display: inline-grid; place-items: center;
  background: var(--ink); color: var(--paper);
  /* Same ink-fill + paper-ring + shadow treatment as .lightbox-nav (owner 2026-09-12: the
     cream close button was hard to see against the white/paper panel) — one dialog-chrome family. */
  box-shadow: 0 2px 8px rgba(0, 0, 0, .35);
}
.lightbox-nav {
  position: fixed; top: 50%; transform: translateY(-50%);
  width: 48px; height: 48px; padding: 0; border: 2px solid var(--paper); border-radius: 50%;
  display: inline-grid; place-items: center;
  background: var(--ink); color: var(--paper);
  /* Ink fill + paper ring so the arrows read on both the dark overlay and the paper panel,
     where they used to blend in. Extends the lightbox-panel's box-shadow exception (§4.4)
     to the nav buttons for the same legibility reason. */
  box-shadow: 0 2px 8px rgba(0, 0, 0, .35);
}
.lightbox-prev { left: var(--s-2); }
.lightbox-next { right: var(--s-2); }
/* .lightbox-nav is position: fixed, so it does not move with the overlay's own padding — hold
   the right-hand arrow off the scrollbar gutter explicitly (the left one needs no change). */
body.is-locked .lightbox-next { right: calc(var(--s-2) + var(--scroll-gutter, 0px)); }
.lightbox-nav.is-hidden { display: none; }
.lightbox-schema { display: none; }
.lightbox--schema .lightbox-img { display: none; }
.lightbox--schema .lightbox-schema { display: block; }

/* ===== 11. Gallery (shared by co-dostanete, graficke, kniha) ===== */
.gallery { display: grid; gap: var(--s-3); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 768px) { .gallery--3 { grid-template-columns: repeat(3, 1fr); } }
.gallery__item { cursor: zoom-in; border-radius: var(--r-card); overflow: hidden; }
.gallery__item img { aspect-ratio: 4 / 3; object-fit: cover; width: 100%; border-radius: var(--r-card); }
.gallery__caption { font-size: 0.7647rem; color: var(--muted); padding: var(--s-2) 0 0; }
/* Focus moves to the thumbnail <img>, not the <li> (see initLightbox in main.js) —
   outline sits inset so it isn't clipped by .gallery__item's overflow: hidden. */
.gallery__item img:focus-visible { outline: 2px solid var(--ink); outline-offset: -3px; }
/* .gallery__media wraps just the <img> so the play circle centres on the thumbnail's own
   box, not the taller <li> (owner 2026-09-12: circle sat 28px too low). */
.gallery__media { display: block; position: relative; }
.gallery__play .gallery__media::after {
  content: ""; position: absolute; left: 50%; top: 50%; width: 48px; height: 48px; transform: translate(-50%, -50%);
  border-radius: 50%; background: var(--ink) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='18' height='20' viewBox='0 0 18 20'%3E%3Cpath d='M2 1l14 9-14 9z' fill='%23fbf6ea'/%3E%3C/svg%3E") no-repeat 55% 50%;
}

/* ===== 12. 404 ===== */
p.error-404-code { font-family: var(--font-serif); font-size: 4rem; line-height: 1; color: var(--gold-text); margin-bottom: var(--s-2); }
.error-404-actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin: var(--s-6) 0; }

/* ===== 13. Configurator scaffolding shared by both pages (styled in Task 11) ===== */
.config__options { min-width: 0; }

/* ===== 14. Hero ===== */
.hero { background: var(--paper); padding: 3rem 0 3.5rem; } /* 48/56 px, spec §6.1 */
.hero__body { display: flex; flex-direction: column; }
.hero__body .label { margin-bottom: var(--s-3); }
.hero h1 { max-width: 12ch; margin-bottom: var(--s-4); }
/* max-width 31.5ch (not 34ch): sentence 1 alone = 30.2ch, +" Na" = 32.7ch, sentence 2 = 26.4ch
   (Range widths in Chrome, Inter loaded) — 34ch let "Na" trail onto line 1; 31.5ch sits mid-window
   so each sentence keeps its own line at every width, since ch scales with the font
   (owner report 2026-09-18). */
.hero__lead { max-width: 31.5ch; font-size: 1rem; line-height: 1.5; margin-bottom: var(--s-3); color: var(--ink-2); }
.hero__facts { font-size: 0.8235rem; color: var(--muted); margin-bottom: var(--s-6); font-variant-numeric: tabular-nums; }
/* align-items: flex-start (owner report 2026-09-18): .link-arrow's R20 display:inline made it
   a blockified, stretched flex item, so its text sat at the top of a 48px box next to the pill. */
.hero__actions { display: flex; flex-direction: column; align-items: flex-start; gap: var(--s-2); }
@media (min-width: 992px) {
  .hero { padding: 4.5rem 0 5.5rem; } /* 72/88 px, spec §6.1 */
  .hero__lead { font-size: 1.0588rem; }
  .hero__facts { font-size: 0.8824rem; }
  .hero__actions { flex-direction: row; align-items: center; gap: var(--s-3); } /* owner report 2026-09-18 */
}

/* Homepage hero (R7): full-bleed collage, cream fade, feature row (ring removed, R12) */
/* Ken Burns: one pass, one direction — zoom + a drift toward the wedding photo. The 3 % / 14 s
   version (0.2 % per second) was below what the eye registers (owner 2026-09-20: "I don't see it");
   a ping-pong loop was visible but felt wrong (a photo zooming back out reads as breathing). 8 %
   over 20 s ease-in-out, then hold. Origin 62 % 50 % and the negative drift keep every edge inside
   the box at scale 1.08 (left edge moves to -6.5 % of width, right to +1.5 %). */
@keyframes hero-zoom { from { transform: scale(1) translate(0, 0); } to { transform: scale(1.08) translate(-1.5%, 0.5%); } }
@keyframes hero-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.hero--full { position: relative; isolation: isolate; overflow: hidden; background: var(--paper); }
.hero--full .hero__inner { display: block; position: relative; padding-block: var(--s-8) var(--s-12); }
.hero__bg { display: block; position: relative; aspect-ratio: 4 / 5; }
.hero__bg-img { display: block; width: 100%; height: 100%; object-fit: cover; }
.hero__scroll, .hero__wave { display: none; }
.hero__body { max-width: 34rem; }
/* Ken Burns glide on the collage, one pass then hold (see the keyframes above; `both` keeps the end
   state); staggered fade-in on the hero body's direct children. */
.hero--full .hero__bg-img { transform-origin: 62% 50%; animation: hero-zoom 20s ease-in-out both; }
.hero--full .hero__body > * { animation: hero-rise .5s ease-out both; }
.hero--full .hero__body > :nth-child(2) { animation-delay: .12s; }
.hero--full .hero__body > :nth-child(3) { animation-delay: .24s; }
.hero--full .hero__body > :nth-child(4) { animation-delay: .36s; }
.hero--full .hero__body > :nth-child(5) { animation-delay: .48s; }
.hero--full .hero__body > :nth-child(6) { animation-delay: .60s; }
/* Phone (< 992px, R18): no zoom — the image sits above the text and a scaled 4:5 box would
   look wrong there. The fade-in above still applies at every width. */
@media (max-width: 991px) {
  .hero--full .hero__bg-img { animation: none; }
  /* Phone: photo sits under the header; the next section has its own top padding. */
  .hero--full { padding-block: 0; }
  .hero--full .hero__inner { padding-bottom: var(--s-4); }
  /* Equal ~20px from the fact line to the button and from the button to the link text. */
  .hero--full .hero__facts { margin-bottom: var(--s-4); }
  .hero--full .hero__actions { gap: var(--s-4); }
}
@media (min-width: 600px) { .hero__bg { aspect-ratio: 16 / 9; } }
.hero__features { list-style: none; padding: 0; margin: var(--s-8) 0 0; display: grid; gap: var(--s-3); }
.hero__feature { display: grid; grid-template-columns: 48px 1fr; column-gap: var(--s-3); align-items: center; }
.hero__feature strong { display: block; font-family: var(--font-serif); font-weight: 500; font-size: 1rem; line-height: 1.2; grid-column: 2; }
.hero__feature > span:last-child { grid-column: 2; font-size: 0.7647rem; color: var(--muted); }
.hero__feature-icon { grid-row: 1 / 3; width: 48px; height: 48px; border-radius: 50%; border: 1px solid var(--green-rule); background: rgba(251, 246, 234, 0.6); color: var(--ink); display: inline-flex; align-items: center; justify-content: center; }
.hero__feature-icon svg { width: 22px; height: 22px; }
@media (min-width: 992px) {
  .hero--full { min-height: calc(100dvh - var(--header-h)); display: grid; align-items: center; }
  .hero--full .hero__inner { padding-block: 5rem 7rem; }
  .hero__bg { position: absolute; inset: 0; z-index: -1; aspect-ratio: auto; }
  .hero__bg-img { object-position: 72% 50%; }
  /* Fix round 1: the fade is anchored to the container's content edge (px/rem), not viewport
     percentages, so ≥88% cream still covers the text column once the container hits its
     1200px cap. 30/36/42rem are the opaque-end / 88%-cream / fully-transparent offsets from
     the content edge; .hero__body's own max-width is 36rem, so the 88% stop lands exactly at
     its right edge at every width. 42rem (not the 46rem first tried) keeps the fully-
     transparent point at ≤61% of a 1440px viewport so the castle stays uncovered — see the
     task-3c-report.md fix-round-1 numbers. */
  .hero__bg::after {
    content: ""; position: absolute; inset: 0;
    background:
      linear-gradient(90deg, var(--paper) 0, var(--paper) calc(50% - 600px + 2.5rem + 30rem), rgba(246, 241, 231, 0.88) calc(50% - 600px + 2.5rem + 36rem), rgba(246, 241, 231, 0) calc(50% - 600px + 2.5rem + 42rem)),
      linear-gradient(180deg, rgba(246, 241, 231, 0.35) 0%, rgba(246, 241, 231, 0) 22%, rgba(246, 241, 231, 0) 78%, var(--paper) 100%);
  }
  .hero__body { max-width: 36rem; position: relative; z-index: 1; }
  /* align-items: start (owner report 2026-09-18): default stretch made all three columns as
     tall as the middle one ("Dohoda o provedení služeb" wraps to 2 lines at max-width 9.5rem),
     shifting the other icons/sublines by 3px. Titles are not padded to two lines (owner
     round 2: the empty reserved line under single-line titles read as broken spacing); the
     wrapped middle title just makes its column one line taller. Title and subline sit 4px
     apart so each pair reads as one unit; the icon keeps a wider gap above the title. */
  .hero__features { grid-template-columns: repeat(3, auto); justify-content: start; align-items: start; gap: var(--s-8); margin-top: 3rem; }
  .hero__feature { grid-template-columns: 1fr; row-gap: 4px; text-align: center; max-width: 9.5rem; }
  .hero__feature-icon { grid-row: auto; margin: 0 auto 6px; }
  .hero__feature strong, .hero__feature > span:last-child { grid-column: 1; }
  .hero__feature strong { font-family: var(--font-sans); font-weight: 500; font-size: 0.8824rem; }
  .hero__scroll { display: inline-flex; flex-direction: column; align-items: center; gap: var(--s-1); position: absolute; left: 50%; bottom: 3.5rem; transform: translateX(-50%); text-decoration: none; color: var(--ink); z-index: 1; }
  .hero__scroll-arrow { font-family: var(--font-sans); line-height: 1; }
  .hero__wave { display: block; position: absolute; left: 0; right: 0; bottom: -1px; height: 72px; color: var(--paper); z-index: 0; pointer-events: none; }
  .hero__wave svg { display: block; width: 100%; height: 100%; }
}
/* Fix round 1: below the container's 1200px cap it is not centred (its left edge is the
   viewport edge, not "50% - 600px"), so the ≥1200px fade formula above would place its
   stops too far left in this range. Override with the uncapped formula: content edge is
   just the 2.5rem side padding, no viewport-centring term. */
@media (min-width: 992px) and (max-width: 1199.98px) {
  .hero__bg::after {
    background:
      linear-gradient(90deg, var(--paper) 0, var(--paper) calc(2.5rem + 30rem), rgba(246, 241, 231, 0.88) calc(2.5rem + 36rem), rgba(246, 241, 231, 0) calc(2.5rem + 42rem)),
      linear-gradient(180deg, rgba(246, 241, 231, 0.35) 0%, rgba(246, 241, 231, 0) 22%, rgba(246, 241, 231, 0) 78%, var(--paper) 100%);
  }
}

/* Living hero (homepage, spec 2026-09-23): js/living.js's canvas replaces the Ken Burns zoom;
   the text rise stays. */
.hero--living .hero__bg-img { animation: none; }
.hero__living { position: absolute; inset: 0; display: block; width: 100%; height: 100%; opacity: 0; transition: opacity .6s ease; pointer-events: none; }
.hero__living.is-on { opacity: 1; }
/* Desktop veil (L6): 80 % cream to the content edge + 26rem, clear by + 44rem, so the scene shows
   behind the text. Small text takes --ink there (--muted fails 4.5:1 on the photo; ink ≥ 6:1). */
@media (min-width: 992px) {
  .hero--living .hero__bg-img { object-position: 50% 50%; }
  .hero--living .hero__bg::after {
    --edge: max(2.5rem, calc(50% - 600px + 2.5rem));
    background:
      linear-gradient(90deg, rgba(246, 241, 231, 0.8) 0, rgba(246, 241, 231, 0.8) calc(var(--edge) + 26rem), rgba(246, 241, 231, 0) calc(var(--edge) + 44rem)),
      linear-gradient(180deg, rgba(246, 241, 231, 0.35) 0%, rgba(246, 241, 231, 0) 22%, rgba(246, 241, 231, 0) 78%, var(--paper) 100%);
  }
  .hero--living .hero__body > p.label,
  .hero--living .hero__facts,
  .hero--living .hero__feature > span:last-child,
  .hero--living .hero__scroll .label { color: var(--ink); }
}

/* ===== 16. Co dostanete ===== */
.offer { display: grid; gap: var(--s-4); }
.offer__block { background: var(--paper-2); border: 0; border-radius: var(--r-card); padding: 32px 28px; }
.offer__block .badge { margin-bottom: var(--s-3); }
.offer__block h3 { margin-bottom: var(--s-3); }
.offer__block--dashed { border: 0; }
.offer__block .gallery { margin: var(--s-4) 0; }
/* Lead image (owner round 2026-09-23): the first item of each offer gallery spans the card's full
   content width so the product is actually seen; the rest stay a thumbnail row below it. Its
   sizes attribute in the markup matches this width (480px card content at ≥1200px). */
.offer__block .gallery__item:first-child { grid-column: 1 / -1; }
.offer__block .gallery__item:first-child .gallery__caption { font-size: 0.8235rem; }
/* Round 2 (owner: "longer by making it bigger"): both leads 16:9, every thumbnail 3:2, so the two
   cards share one image geometry and stay short. The tree lead is anchored to the top of the sheet
   so the title "Předkové …" and the crown of the tree stay in the 16:9 window. */
.offer__block .gallery__item img { aspect-ratio: 3 / 2; }
.offer__block .gallery__item:first-child img { aspect-ratio: 16 / 9; }
.offer__gallery-trees .gallery__item:first-child img { object-position: 50% 0; }
/* Captions wrap under the narrow thumbnails, so they need their own tight block line box. */
.offer__block .gallery__caption { display: block; line-height: 1.35; padding-top: var(--s-1); }
/* The <img> carries its own radius; a rounded, clipping <li> would shave the first letter off a
   wrapped caption's last line (bottom-left corner). */
.offer__block .gallery__item { overflow: visible; border-radius: 0; }
.offer__block .gallery__play:first-child .gallery__media::after { width: 64px; height: 64px; background-size: 22px auto; }
/* Placeholder thumbnails (owner photos pending): reuse the post-card__media--empty fallback so the
   tile matches the real thumbnails' 3:2 aspect ratio and radius, but it isn't a lightbox trigger —
   no data-full-src/img means initLightbox() (js/main.js) skips it when building triggers. */
.offer__block .gallery__item--placeholder { cursor: default; }
.offer__block .gallery__item--placeholder .post-card__media--empty { border-radius: var(--r-card); overflow: hidden; }
/* Phone: lead + one row of three in both cards (the 5th and 6th trees/books stay desktop-only, as before). */
.offer__block .gallery { grid-template-columns: repeat(3, 1fr); }
.offer__gallery-trees .gallery__item:nth-child(n+5),
.offer__gallery-books .gallery__item:nth-child(n+5) { display: none; }
.offer__line { font-size: 0.8824rem; margin: 0; }
.offer__plus { font-family: var(--font-serif); font-size: 1.6471rem; color: var(--muted); text-align: center; line-height: 1; }
.offer__list { display: none; }
.check-list--2col { columns: 2; column-gap: var(--s-6); }
.check-list--2col li { break-inside: avoid; }
.offer__bundle { text-align: center; margin: var(--s-4) 0; }
.offer__cta { text-align: center; margin: 0; }
@media (min-width: 768px) {
  /* Both cards sit on one set of five row lines (badge, title, list, gallery, footer line) via
     subgrid, so the lead images, thumbnail rows and footer lines align across the cards and the
     cards end level (owner round 2, 2026-09-23). Browsers without subgrid just lose the alignment. */
  .offer { grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); grid-template-rows: repeat(5, auto); column-gap: var(--s-6); row-gap: 0; }
  .offer__block { display: grid; grid-column: 1; grid-row: 1 / span 5; grid-template-rows: subgrid; padding: 24px; }
  .offer__block--dashed { grid-column: 3; }
  .offer__block > .badge { justify-self: start; margin-bottom: var(--s-2); }
  .offer__block h3 { margin-bottom: var(--s-2); }
  /* Tighter rhythm inside the cards so the bigger photos cost little height (target ≤1150px). */
  .offer__list > p { margin-bottom: var(--s-2); }
  .offer__block .check-list li:last-child { margin-bottom: 0; }
  .offer__block .gallery { margin: var(--s-3) 0 var(--s-2); }
  .offer__line { align-self: end; }
  .offer__plus { grid-column: 2; grid-row: 1 / span 5; align-self: center; padding-top: 0; }
  .offer__gallery-trees .gallery__item:nth-child(n+5),
  .offer__gallery-books .gallery__item:nth-child(n+5) { display: block; }
  .offer__sentence { display: none; }
  .offer__list { display: block; }
}
/* One row of five only once the card reaches its full 480px; narrower tablets keep rows of three. */
@media (min-width: 1200px) { .offer__block .gallery { grid-template-columns: repeat(5, 1fr); gap: var(--s-2); } }
.lightbox-video { display: none; }
.lightbox--video .lightbox-img { display: none; }
.lightbox--video .lightbox-video { display: block; }
.lightbox-video video { width: 100%; max-height: 70dvh; background: var(--ink); }

/* ===== 17. Ceník ===== */
.tier-group { margin-bottom: var(--s-12); }
.tier-group__title { margin-bottom: var(--s-2); } /* h3 scale like every other ceník sub-heading (was a fixed 1.4118rem, 24px even on phone) */
.tier-group__desc { max-width: 60ch; color: var(--ink-2); margin-bottom: var(--s-6); }
.tier-grid { display: grid; gap: var(--s-4); }
@media (min-width: 768px) { .tier-grid { grid-template-columns: repeat(3, 1fr); } }
.tier-card {
  position: relative; display: flex; flex-direction: column;
  background: var(--card); border: 0; border-radius: var(--r-card); padding: 28px 24px;
}
.tier-card--popular { border: 1.5px solid var(--gold); }
.tier-card h3 { margin-bottom: var(--s-3); }
.tier-tag {
  position: absolute; top: -10px; left: 16px;
  background: var(--gold); color: var(--ink); font-size: 0.6471rem; font-weight: 600; line-height: 1;
  padding: 5px 8px; border-radius: 4px;
}
.tier-price { color: var(--gold-text); margin-bottom: var(--s-2); }
.tier-price .small, .tier-price--alt .small { display: block; margin-top: 2px; font-family: var(--font-sans); font-weight: 400; letter-spacing: 0; }
.tier-price--alt { font-family: var(--font-serif); font-size: 1.2941rem; font-weight: 500; color: var(--ink-2); margin-bottom: var(--s-4); font-variant-numeric: tabular-nums; }
.tier-card .check-list { flex: 1; margin-bottom: var(--s-4); }
.tier-schema {
  align-self: flex-start; padding: var(--s-2) 0; min-height: 44px;
  background: none; border: 0; border-radius: 0; cursor: pointer; font-size: 0.9412rem;
}
/* Under the price grid the ceník turns into editorial text (owner round 2026-09-23, "fewer
   boxes"): no card surfaces, just a gold rule over each block and a green hairline between its
   two columns. The note's columns line up with the includes columns above it, so the two blocks
   read as one ruled table of terms. Cards stay only where things are compared (tier cards). */
/* .note is a gold-ruled text block; #kontakt .hints (also .note) turns it back into its paper-2
   box further down, so only the ceník terms note reads as open text. */
.note, .includes { border-top: 1px solid var(--gold-rule-strong); padding-top: var(--s-8); }
.includes, .note--terms { display: grid; }
.includes { gap: var(--s-8); margin-bottom: var(--s-12); }
.includes .badge { margin-bottom: var(--s-3); }
.includes h3 { margin-bottom: var(--s-3); }
.includes > div + div, .note--terms p + p { padding-top: var(--s-8); border-top: 1px solid var(--green-rule); }
.check-list--x li::before { border: 0; width: 0.7em; height: 2px; background: var(--muted); top: 0.7em; transform: none; }
/* max-width removed (owner report 2026-09-18): owner wants the note as wide as the section,
   not narrower and left-aligned like it was at 70ch. One type scale with the includes block above
   (owner round 2: "different font size"): each run-in lead sets exactly like the h3 "Cena obsahuje"
   (h3 size, weight, leading and gap), the text exactly like its check-list items (0.8824rem/1.45, ink). */
.note--terms { gap: var(--s-8); }
.note--terms p { margin: 0; font-size: 0.8824rem; line-height: 1.45; }
.note--terms p > strong:first-child { display: block; margin-bottom: var(--s-3); font-family: var(--font-serif); font-size: 1.2941rem; line-height: 1.2; font-weight: 500; }
@media (min-width: 768px) {
  .includes, .note--terms { grid-template-columns: 1fr 1fr; gap: 0; }
  .includes > div, .note--terms p { padding-right: var(--s-12); }
  .includes > div + div, .note--terms p + p { padding: 0 0 0 var(--s-12); border-top: 0; border-left: 1px solid var(--green-rule); }
  .note--terms p > strong:first-child { font-size: 1.4118rem; }
}
.section-cta { text-align: center; margin: var(--s-8) 0 0; }

/* ===== 18. Schéma explainer (D19) ===== */
/* gap: 6px (not var(--s-2)'s 8.5px) at every width, not just phone — round 1 chrome trim,
   paid for by the fixed caption slot: 6 gaps between the 7 rows saves ~15px of chrome
   height, which is what let linie's 0.8-floored tree fit inside its height budget again. */
.explainer { display: flex; flex-direction: column; gap: 6px; }
/* .lightbox--wide .lightbox-panel is width: fit-content, so the panel's width is the widest
   child's max-content width. These five rows must never be that widest child — only
   .explainer__stage (sized explicitly by fit()) may size the panel. `width: 0` makes each row
   contribute nothing to the panel's fit-content computation; `min-width: 100%` is cyclic during
   intrinsic sizing (it cannot resolve against a width the panel itself hasn't settled yet) and
   so is ignored there too, then resolves normally at layout, stretching the row to whatever
   width the stage already drove the panel to. Without this the step-0 caption (a single ~800px
   line at 17px) was wider than the stage and the panel grew to fit it, then shrank on later
   steps — panel width changing with the caption text at every step. */
.explainer__ttl, .explainer__sub, .explainer__legend, .explainer__cap, .explainer__bar { width: 0; min-width: 100%; }
.explainer__ttl { margin: 0; text-align: center; padding: 0 48px; }
.explainer__sub { margin: 0; text-align: center; }
@media (max-width: 767px) { .explainer__sub { font-size: 0.8235rem; } }
/* .explainer__stage is a fixed positioned frame — fit() sets its width/height explicitly,
   once per package "kind", so prev/next between packages never resizes the dialog.
   .explainer__scroll is the inner element that actually scrolls/pans and carries the
   edge-fade mask; .explainer__hint is absolutely positioned inside the frame so it does not
   scroll away with the svg. */
.explainer__stage {
  position: relative; max-width: 100%; align-self: center;
  background: var(--card); border: 1px solid var(--gold-rule); border-radius: var(--r-card);
  padding: 12px;
}
.explainer__scroll {
  display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;
  overflow-x: auto; -webkit-overflow-scrolling: touch;
}
.explainer__scroll.is-pannable { justify-content: flex-start; }
@media (max-width: 767px) {
  .explainer__stage { padding: 8px; }
  /* The stage pans by touch on phone; a desktop-class browser reporting a phone width still
     draws its own scrollbar, stealing ~15px of chrome height. */
  .explainer__scroll { scrollbar-width: none; }
  .explainer__scroll::-webkit-scrollbar { display: none; }
}
.explainer__svg { height: auto; display: block; flex: none; }
/* Bottom-right: vývod's widest row sits at the top of the box and stays short of the right
   edge, so the pill is clear of it there; a top-right placement was tried instead and rejected
   because it sat on top of that same top row at phone width, where the box is narrow enough
   for the row to reach close to both edges. Text is kept short (~115px at 13px) so the pill
   stays clear of linie's root glyph, which sits bottom-centre: at the narrowest (phone) box
   the glyph is centred well left of the pill's left edge, and the row above it (táta/máma)
   sits well above the pill's band, so neither overlaps it. */
.explainer__hint {
  position: absolute; right: 10px; bottom: 10px;
  font: 500 0.7647rem/1 var(--font-sans); color: var(--ink); background: var(--paper-2);
  border: 1px solid var(--gold-rule-strong); border-radius: var(--r-pill); padding: 7px 10px;
  pointer-events: none;
}
/* Edge-fade mask: #000 here is alpha only (a mask gradient stop), not a paint colour — the
   "no raw hex outside :root" rule is about paint, so this is not an exception to it. */
.explainer__scroll.is-pannable.can-left.can-right { --m: linear-gradient(to right, transparent, #000 40px, #000 calc(100% - 40px), transparent); }
.explainer__scroll.is-pannable.can-left:not(.can-right) { --m: linear-gradient(to right, transparent, #000 40px); }
.explainer__scroll.is-pannable.can-right:not(.can-left) { --m: linear-gradient(to right, #000 calc(100% - 40px), transparent); }
.explainer__scroll.is-pannable { -webkit-mask-image: var(--m); mask-image: var(--m); }
.explainer__legend { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s-4); align-items: center; font-size: 0.7647rem; color: var(--muted); }
.explainer__legend svg { width: 14px; height: 14px; vertical-align: middle; display: inline-block; }
.explainer__legend-dim { border: 1px dashed #b3ab97; padding: 0 5px; }
/* Fixed slot: heading (line-height 1.2, default for a block with no line-height of its own) +
   its 2px margin-bottom + 3 body lines at 1rem/1.45 = 1.1765rem*1.2 + 2px + 3*1rem*1.45 ≈
   99.95px at the 106.25% root (1rem = 17px). overflow: hidden guards a caption that somehow
   exceeds the slot instead of pushing the panel taller (see step C verification). */
.explainer__cap { position: relative; height: calc(1.1765rem * 1.2 + 2px + 3 * 1rem * 1.45); min-height: 0; overflow: hidden; font-size: 1rem; line-height: 1.45; text-align: center; }
.explainer__cap b { display: block; font-family: var(--font-serif); font-weight: 500; font-size: 1.1765rem; margin-bottom: 2px; color: var(--ink); }
.explainer__cap .c { transition: opacity .2s cubic-bezier(.23, 1, .32, 1), transform .2s cubic-bezier(.23, 1, .32, 1); }
.explainer__cap .c.out { opacity: 0; transform: translateY(4px); transition-duration: .12s; }
.explainer__prog { height: 2px; background: var(--gold-rule); overflow: hidden; }
.explainer__prog i { display: block; height: 100%; background: var(--gold-text); transform-origin: left; transform: scaleX(0); }
.explainer__prog i.run { transition: transform 1.8s linear; transform: scaleX(1); }
/* Controls stay reachable even when a short viewport forces the panel itself to scroll (the
   panel, not the stage) — bottom/margin-bottom mirror the panel's own bottom padding so the
   bar's paper background sits flush with the panel edge with no visible seam. */
.explainer__bar {
  position: sticky; bottom: calc(-1 * var(--s-4)); background: var(--paper);
  padding: var(--s-2) 0 var(--s-4); margin-bottom: calc(-1 * var(--s-4));
  display: flex; flex-direction: column; gap: var(--s-2); z-index: 1;
}
@media (max-width: 767px) {
  .explainer__bar { bottom: calc(-1 * var(--s-3)); padding: var(--s-2) 0 var(--s-3); margin-bottom: calc(-1 * var(--s-3)); }
}
/* One row [Zpět] [dots] [Další] — was two rows, costing a chrome row the phone/1080p
   panel could not spare, and the caption and buttons fell below the fold. */
.explainer__ctl { display: flex; align-items: center; gap: var(--s-3); }
.explainer__ctl .btn { flex: 0 0 auto; min-width: 128px; min-height: 40px; }
.explainer__ctl .btn:disabled { opacity: .35; cursor: default; }
.explainer__dots { flex: 1; display: flex; gap: 6px; justify-content: center; align-items: center; }
.explainer__dots i { width: 8px; height: 8px; border-radius: 50%; background: var(--gold-rule); }
.explainer__dots i.on { background: var(--ink); }
@media (max-width: 479px) {
  .explainer__ctl .btn { min-width: 0; flex: 1; }
  .explainer__dots { flex: 0 0 auto; padding: 0 var(--s-2); }
  /* Everything else here is a font-size/gap/padding trim, never the svg scale (that stays
     governed by fit()) — without these cuts linie packages overflowed the phone panel by
     ~110px (and, before round 1's chrome trim above the 767px stage padding was still too
     tall to keep the 0.8-floored tree inside its height budget at this width). */
  .explainer__ttl { font-size: 1.1765rem; padding: 0 40px; }
  .explainer__sub { font-size: 0.7647rem; }
  .explainer__legend { font-size: 0.7059rem; gap: 4px var(--s-3); }
  /* 5-line slot at this size (cap 0.8824rem/1.4, b 1.0588rem): 1.0588rem*1.2 + 2px +
     5*0.8824rem*1.4 ≈ 128.6px. This is the default (vývod's root caption — "Kdokoli, od
     koho začínáme: … Od výchozí osoby počítáme generace zpět.", 141 body chars, 155 with
     its heading — needs all 5). linie's captions are all shorter and fit in 4; round 1
     tried a shared 4-line slot for both kinds and it clipped vývod (cap.scrollHeight 111 vs
     clientHeight 108 at 390×844, ratio 1.028), so round 2 gives linie its own slot below via
     mount()'s static `explainer--linie`/`explainer--vyvod` kind class instead of measuring. */
  .explainer__cap { font-size: 0.8824rem; line-height: 1.4; height: calc(1.0588rem * 1.2 + 2px + 5 * 0.8824rem * 1.4); min-height: 0; }
  .explainer__cap b { font-size: 1.0588rem; }
  /* linie-only 4-line slot: 1.0588rem*1.2 + 2px + 4*0.8824rem*1.4 ≈ 107.6px. Closes the
     panel-scroll overflow round 1 left at 390×844 (was 14px) without touching the 0.8 scale
     floor or the tree geometry — pure chrome, and static (no measurement) since the kind
     class is written once by mount(), not derived from any particular caption's text. */
  .explainer--linie .explainer__cap { height: calc(1.0588rem * 1.2 + 2px + 4 * 0.8824rem * 1.4); }
  .explainer__stage { padding: 6px; }
  .explainer__bar { padding-top: 4px; }
}
.explainer__foot { min-height: 48px; display: flex; justify-content: center; }

/* SVG parts */
.explainer .lbl { font-family: var(--font-sans); font-size: 11px; fill: var(--muted); }
.explainer .lbl.on { fill: var(--ink); font-weight: 600; }
.explainer .yr { font-family: var(--font-serif); font-size: 12px; fill: var(--gold-text); }
.explainer .who { font-family: var(--font-sans); font-size: 9px; font-weight: 600; fill: var(--ink); }
.explainer .box { fill: var(--paper); stroke: var(--ink); stroke-width: 1.2; }
.explainer .box.start { fill: none; stroke: var(--ink); stroke-width: 1.5; }
.explainer .man { fill: var(--man); stroke: var(--man-line); }
.explainer .woman { fill: var(--woman); stroke: var(--woman-line); }
.explainer .box.dim { fill: none; stroke: #b3ab97; stroke-dasharray: 3 3; }
.explainer .glyph { fill: var(--paper); }
.explainer .ln { stroke: var(--ink); stroke-width: 1.2; fill: none; }
.explainer .ln.dim { stroke: #b3ab97; stroke-dasharray: 3 3; }

/* Reveal choreography: lines climb in three beats, boxes rise 8px from the centre outward, then labels. */
.explainer .g .box, .explainer .g .lbl, .explainer .g .yr, .explainer .g .who {
  transition: opacity .26s cubic-bezier(.23, 1, .32, 1), transform .3s cubic-bezier(.23, 1, .32, 1);
  transform-box: fill-box; transform: translateY(0);
}
.explainer .g.hid .box, .explainer .g.hid .lbl, .explainer .g.hid .yr, .explainer .g.hid .who { opacity: 0; transform: translateY(8px); transition: none; }
.explainer .g .ln:not(.dim) { transition: stroke-dashoffset .16s cubic-bezier(.23, 1, .32, 1), opacity .1s; stroke-dasharray: 1; stroke-dashoffset: 0; }
.explainer .g .ln.s2 { transition-delay: .14s; }
.explainer .g .ln.s3 { transition-delay: .26s; }
.explainer .g.hid .ln { transition-delay: 0s; }
.explainer .g.hid .ln:not(.dim) { stroke-dashoffset: 1; opacity: 0; transition: none; }
.explainer .g .ln.dim { transition: opacity .2s; }
.explainer .g.hid .ln.dim { opacity: 0; transition: none; }
.explainer .g .box.d1 { transition-delay: .40s; } .explainer .g .box.d2 { transition-delay: .44s; }
.explainer .g .box.d3 { transition-delay: .48s; } .explainer .g .box.d4 { transition-delay: .52s; }
.explainer .g .box.d5 { transition-delay: .56s; } .explainer .g .box.d6 { transition-delay: .60s; }
.explainer .g .box.d7 { transition-delay: .64s; } .explainer .g .box.d8 { transition-delay: .68s; }
.explainer .g .lbl, .explainer .g .yr, .explainer .g .who { transition-delay: .74s; }
.explainer .g.hid .box, .explainer .g.hid .lbl, .explainer .g.hid .yr, .explainer .g.hid .who { transition-delay: 0s; }

/* ===== 20. Jak to funguje ===== */
.steps { display: grid; gap: var(--s-6); position: relative; }
.step { position: relative; padding-left: 54px; }
/* Continuous 2px ink line: one segment per step, from this dot's centre to the next dot. */
.step:not(:last-child)::before {
  content: ""; position: absolute; left: 20px; top: 19px; bottom: calc(-1 * var(--s-6));
  width: 2px; background: var(--green-rule);
}
.step__num {
  position: absolute; left: 0; top: 0;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--ink); color: var(--cream);
  border: 6px solid var(--paper); /* the ring: the line visibly passes behind the dot */
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 0.8824rem; font-weight: 600; line-height: 1;
}
.section--alt .step__num { border-color: var(--paper-2); }
.step__title { font-family: var(--font-serif); font-size: 1.1765rem; line-height: 1.3; font-weight: 500; margin: 8px 0 var(--s-2); }
.step__text { font-size: 1rem; line-height: 1.5; color: var(--ink-2); margin: 0; }
@media (min-width: 768px) {
  .steps { grid-template-columns: repeat(4, 1fr); gap: var(--s-8); }
  .step { padding-left: 0; padding-top: 54px; }
  .step:not(:last-child)::before { left: 40px; right: calc(-1 * var(--s-8)); top: 18px; bottom: auto; width: auto; height: 2px; }
  .step__title { margin-top: 0; }
}

/* ===== 21. Kdo za tím stojí ===== */
.about { display: flex; flex-direction: column; gap: var(--s-8); }
.about__body { max-width: 34rem; }
.about__text { max-width: 58ch; font-size: 1rem; line-height: 1.55; color: var(--cream); opacity: .92; margin: 0; }
.about__cta { margin-top: 24px; }
.facts { display: flex; flex-direction: column; gap: var(--s-4); margin: 0; padding: 0; list-style: none; }
.facts__item { display: flex; flex-direction: column; gap: var(--s-1); padding-bottom: var(--s-4); border-bottom: 1px solid rgba(251, 246, 234, 0.15); }
.facts__item:last-child { border-bottom: 0; padding-bottom: 0; }
.facts__num { font-family: var(--font-serif); font-size: 2.3529rem; line-height: 1.1; font-weight: 500; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; color: var(--cream); }
@media (min-width: 992px) {
  .about { display: grid; grid-template-columns: 1fr auto; gap: var(--s-12); align-items: start; }
  .facts { max-width: 18rem; justify-self: end; text-align: right; }
}

/* ===== 22. Konfigurátor ===== */
.config { display: grid; gap: var(--s-6); }
.config__options .form__field { margin-bottom: var(--s-6); }
.config__options .form__label { font-weight: 600; margin-bottom: var(--s-3); }
.config__summary {
  background: var(--paper-2); border: 0; border-radius: var(--r-card); padding: var(--s-6);
}
.config__summary h3 { margin-bottom: var(--s-3); }
.config__summary-text { font-size: 0.8824rem; line-height: 1.6; color: var(--ink-2); margin-bottom: var(--s-4); }
.config__summary-text strong { color: var(--ink); }
.config__summary-label { display: block; margin-bottom: var(--s-1); }
.config__price { color: var(--gold-text); margin-bottom: var(--s-4); } /* font-size comes from the shared .price role (C2) */
.config__secondary { margin-top: var(--s-4); padding-top: var(--s-4); border-top: 1px dashed var(--gold-rule-strong); }
.config__secondary-link {
  display: block; width: fit-content; margin: 0 auto;
  background: none; border: 0; font-size: 0.7647rem; font-weight: 500; text-decoration: underline; text-underline-offset: 3px;
}
[hidden] { display: none !important; }
@media (min-width: 768px) {
  .config { grid-template-columns: 1.4fr 1fr; gap: var(--s-12); align-items: start; }
  .config__summary { position: sticky; top: 96px; }
}
@media (max-width: 479px) {
  .seg { flex-direction: column; }
  /* Stacked: round outer corners, square inner ones, overlap the shared border. */
  .seg__btn:first-child { border-radius: var(--r-btn) var(--r-btn) 0 0; }
  .seg__btn + .seg__btn { margin-left: 0; margin-top: -1.5px; }
  .seg__btn:last-child { border-radius: 0 0 var(--r-btn) var(--r-btn); }
}

/* ===== 23. Časté dotazy ===== */
.faq { max-width: 760px; }
.faq-item { border-top: 1px solid var(--gold-rule); }
.faq-item:last-child { border-bottom: 1px solid var(--gold-rule); }
.faq-q {
  position: relative; list-style: none; cursor: pointer;
  padding: var(--s-4) 2.5rem var(--s-4) 0; min-height: 56px;
  font-family: var(--font-serif); font-size: 1.1176rem; line-height: 1.35; font-weight: 500;
}
.faq-q::-webkit-details-marker { display: none; }
.faq-q::after {
  content: "+"; position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; display: flex; align-items: center; justify-content: center;
  font-family: var(--font-sans); font-size: 1.3rem; font-weight: 400; line-height: 1; color: var(--ink);
}
.faq-item[open] .faq-q::after { content: "−"; }
.faq-item[open] { background: none; }
.faq-a { padding: 0 2.5rem var(--s-4) 0; font-size: 0.9706rem; line-height: 1.55; color: var(--ink-2); }
.faq-a p { margin: 0; }
/* Desktop: heading column left, questions right (owner round 2026-09-23). Keeps the band, so the
   stretch between the green band and the green footer still alternates, but gives it a shape the
   ceník band (full-width card grid) never has: no surfaces, one ruled list beside its heading. */
@media (min-width: 992px) {
  .faq-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.75fr); column-gap: var(--s-12); align-items: start; }
  .faq-layout .section-head { margin-bottom: 0; }
}

/* ===== 24. Kontakt ===== */
.contact { display: grid; gap: var(--s-8); }
.form--contact .btn, .wpcf7-form .btn { margin-top: var(--s-2); }
.gdpr-consent { display: flex; align-items: flex-start; gap: var(--s-3); min-height: 44px; padding: var(--s-2) 0; margin: 0 0 var(--s-4); font-size: 0.8824rem; line-height: 1.45; }
.gdpr-consent input { flex: 0 0 auto; width: 24px; height: 24px; margin: 0; accent-color: var(--ink); cursor: pointer; }
.gdpr-consent label { cursor: pointer; }
.gdpr-consent .wpcf7-list-item { margin: 0; }
.gdpr-consent .wpcf7-list-item label { display: flex; align-items: flex-start; gap: var(--s-3); }
.contact__phone { margin: var(--s-4) 0 0; color: var(--ink-2); }
/* Hint box text on the "Cena obsahuje" scale (owner round 2, 2026-09-23): h3 with the same s-3 gap,
   intro and items at the check-list size 0.8824rem/1.45, check marks drawn exactly like .check-list,
   bold lead words at the site's 600 in ink. */
.hints h3 { margin-bottom: var(--s-3); }
.hints p { margin-bottom: var(--s-3); font-size: 0.8824rem; line-height: 1.45; }
.hints__list li { position: relative; padding-left: 1.6em; margin-bottom: var(--s-2); font-size: 0.8824rem; line-height: 1.45; }
.hints__list li:last-child { margin-bottom: 0; }
.hints__list li::before {
  content: ""; position: absolute; left: 0; top: 0.35em; width: 0.9em; height: 0.5em;
  border-left: 2px solid var(--ink); border-bottom: 2px solid var(--ink); transform: rotate(-45deg);
}
.hints__list strong { color: var(--ink); }
@media (min-width: 768px) {
  .contact { grid-template-columns: 1.3fr 1fr; gap: var(--s-12); align-items: start; }
  /* The form visually starts at the ink of its first label, not at the label's line box (half-
     leading + accent room above "Jméno" = 6px at 18px, measured in Chrome). Dropping the aside by
     the same amount puts the hint box's top edge on that line (owner round 2, 2026-09-23). */
  .contact__aside { margin-top: 0.3333em; }
}
/* Phone: hint above the form. */
@media (max-width: 767px) { .contact__aside { order: -1; } }
#kontakt .hints { background: var(--paper-2); border: 0; border-radius: var(--r-card); padding: var(--s-4) var(--s-6); }
/* Confirmation after the konfigurátor CTA fills the message field; reserves its line. */
.kontakt-fill-feedback { min-height: 1.2em; margin: var(--s-2) 0 0; font-size: 0.8235rem; font-weight: 500; color: var(--gold-text); }
.form__input--flash { animation: kontakt-fill-flash 1.6s ease-out; }
@keyframes kontakt-fill-flash {
  from { background-color: var(--gold-rule); }
  to { background-color: #fff; }
}

/* ===== 24b. Ceník teaser inside #sluzby-a-ceny (R19c; own strip since 2026-09-23) ===== */
/* A full-width paper strip closing the ceník band, ruled in gold top and bottom: its own moment,
   not another card, and quiet (a link, no button) so it never competes with the ceník CTA above
   it. Existing palette only (owner round 2: the sage tint is gone). It is the last child of the
   section, so the section drops its bottom padding and the strip meets the next section. */
.section:has(> .poukaz-teaser) { padding-bottom: 0; }
.poukaz-teaser { background: var(--paper); border-block: 1px solid var(--gold-rule-strong); margin-top: var(--s-12); padding: var(--s-8) 0; }
/* No slide on a full-bleed band (it would open a gap against the next section); fade only. */
.poukaz-teaser.reveal { transform: none; }
.poukaz-teaser .label { margin-bottom: var(--s-2); }
/* Same h3 scale as every other sub-heading in the ceník (1.2941rem, 1.4118rem from 768px). */
.poukaz-teaser h2 { font-size: 1.2941rem; line-height: 1.2; font-weight: 500; margin-bottom: var(--s-3); }
.poukaz-teaser p:not(.label) { color: var(--ink-2); max-width: 60ch; margin: 0 0 var(--s-3); }
@media (min-width: 768px) {
  .poukaz-teaser { margin-top: 5rem; padding: 3.5rem 0; }
  .poukaz-teaser h2 { font-size: 1.4118rem; margin-bottom: 0; }
  /* Title left, sentence + link right; the sentence spans the eyebrow and title rows so the two
     columns start and end together. */
  .poukaz-teaser__inner {
    display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: var(--s-12);
    grid-template-areas: "label text" "title text" "title link"; align-items: start;
  }
  .poukaz-teaser__inner .label { grid-area: label; }
  .poukaz-teaser__inner h2 { grid-area: title; }
  .poukaz-teaser__inner p:not(.label) { grid-area: text; }
  .poukaz-teaser__inner .btn { grid-area: link; justify-self: start; }
}

/* ===== 24c. Dárkový poukaz page (D36, new) ===== */
.page-hero h1 { margin-bottom: var(--s-2); }
.poukaz-hero { display: grid; gap: 2.5rem; align-items: center; }
@media (min-width: 992px) { .poukaz-hero { grid-template-columns: minmax(0, 1fr) minmax(0, 620px); gap: 3.5rem; } }
.poukaz-hero__stack { position: relative; justify-self: center; width: min(100%, 620px); aspect-ratio: 520 / 400; }
.poukaz-hero__stack picture { position: absolute; }
.poukaz-hero__stack img { display: block; width: 100%; height: auto; }
.poukaz-hero__ad { left: 0; top: 0; width: 82%; transform: rotate(-4deg); box-shadow: 0 1px 2px rgb(31 58 46 / .1), 0 12px 30px rgb(31 58 46 / .16); }
.poukaz-hero__voucher { right: 0; bottom: 0; width: 80%; transform: rotate(2.5deg); background: #fff;
  box-shadow: 0 1px 1.5px rgb(31 58 46 / .12), 0 4px 8px rgb(31 58 46 / .08), 0 22px 44px rgb(31 58 46 / .2); }
.poukaz-price-list { display: grid; gap: var(--s-3); list-style: none; padding: 0; margin: 0 0 var(--s-4); max-width: 32rem; }
.poukaz-price-list li { display: flex; justify-content: space-between; gap: var(--s-4); padding-bottom: var(--s-3); border-bottom: 1px solid var(--gold-rule); }
.poukaz-price-list li:last-child { border-bottom: 0; padding-bottom: 0; }
.poukaz-price-list .price { font-size: 1.0588rem; color: var(--gold-text); }

/* ===== 25. Graficke page ===== */
/* Grafické hero (owner 2026-11-03): shorter, no zoom; image sits on paper, so contain is safe. */
.hero--graf .hero__bg-img { animation: none; }
@media (min-width: 992px) {
  .hero--graf { min-height: calc((100dvh - var(--header-h)) * .82); }
  .hero--graf .hero__bg-img { object-fit: contain; object-position: 100% 50%; }
}
.kniha { display: grid; gap: var(--s-6); }
.kniha__list { background: var(--paper-2); border-radius: var(--r-card); padding: var(--s-6); }
.kniha__list p:first-child { font-weight: 500; margin-bottom: var(--s-3); }
.kniha__list .small { margin: var(--s-4) 0 0; }
.kniha__video { display: block; }
.kniha__video img { aspect-ratio: 16 / 9; }
.kniha__photos li:last-child img { object-position: 100% 0; }
@media (min-width: 768px) {
  .kniha, .kniha__photos { grid-template-columns: 1fr 1.2fr; column-gap: var(--s-12); }
  .kniha { row-gap: var(--s-12); }
  .kniha__list { padding: var(--s-8) 1.75rem; }
  .kniha__photos { grid-column: 1/-1; }
  .kniha__video .gallery__item { overflow: visible; }
  .kniha__video .gallery__caption { display: block; position: relative; top: var(--s-2); height: 0; padding: 0; }
  .kniha__photos img { height: 17.5rem; }
}
.section-head .badge { margin-bottom: var(--s-3); }
#kniha-predku .badge--opt { background: var(--paper-2); }

/* ===== 26. Prose pages (privacy), 404 ===== */
.prose--policy h1 { margin-bottom: var(--s-6); }
.prose--policy h2 { font-size: 1.4118rem; font-weight: 500; margin-top: var(--s-8); padding-top: var(--s-6); border-top: 1px solid var(--gold-rule); }
.prose--policy p, .prose--policy ul { font-size: 1rem; line-height: 1.6; }
.prose--policy p:last-child { margin-top: var(--s-8); color: var(--muted); }
.privacy-policy .entry-content > * { max-width: 70ch; }
.error-404 { text-align: left; max-width: 60ch; padding: var(--s-16) 0; }
.error-404 h1 { margin-bottom: var(--s-4); }
.error-404 .container { text-align: left; }
.error-404-search { margin-top: var(--s-8); }
.error-404-search form { display: flex; gap: var(--s-2); flex-wrap: wrap; }
.error-404-search input[type="search"] { flex: 1; min-height: 48px; padding: var(--s-3) var(--s-4); border: 1.5px solid var(--green-rule); border-radius: var(--r-input); background: #fff; }
.error-404-search input[type="submit"], .error-404-search button { min-height: 48px; padding: 0 var(--s-4); border: 1.5px solid var(--ink); color: var(--ink); background: transparent; border-radius: var(--r-btn); font-weight: 600; }

/* ===== 27. Page, blog, 404 (theme templates; preview renders the blog as clanky.html + clanek-ukazka.html) ===== */
.post-meta { margin-bottom: var(--s-2); color: var(--muted); }
.post-meta time { font: inherit; }
.post-list { display: grid; gap: 24px; grid-template-columns: 1fr; }
/* archive.php puts .post-list inside .container.prose, whose `> *` 70ch cap would squeeze the
   2/3-column card grid into one prose column (first seen on the preview render, 2026-09-18). */
.prose > .post-list { max-width: none; }
/* single.php wraps the article in .post-single, not .section, so it carries the same vertical
   rhythm itself (first seen on the preview render, 2026-09-18). */
.post-single { padding: var(--s-12) 0; }
@media (min-width: 768px) { .post-single { padding: 5rem 0; } }
@media (min-width: 768px) { .post-list { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1200px) { .post-list { grid-template-columns: repeat(3, 1fr); } }
/* Card: cream surface, gold hairline, thumbnail flush at the top, body padded 24px. Flex column
   so "Číst dál" pins to the bottom and every card in a row ends level (owner 2026-09-22). */
.post-card { position: relative; display: flex; flex-direction: column; background: var(--card); border: 1px solid var(--gold-rule); border-radius: var(--r-card); overflow: hidden; transition: border-color .2s ease-out; }
.post-card:hover, .post-card:focus-within { border-color: var(--gold-rule-strong); }
/* theme/index.php (generic fallback template) renders .post-card articles as direct
   children of .container.prose with no wrapper; without this the cards touch (B1). */
.prose > .post-card + .post-card { margin-top: 24px; }
/* …and those cards carry no .post-card__body, so they need the padding on the card itself. */
.post-card:not(:has(.post-card__body)) { padding: 24px; }
.post-card__body { display: flex; flex-direction: column; flex: 1; padding: 24px; }
/* Thumbnail runs edge to edge at the top; the card's overflow: hidden rounds its top corners. */
.post-card__media { display: block; width: 100%; max-width: none; aspect-ratio: 3 / 2; object-fit: cover; }
/* No featured image: paper panel with the faint tree mark cropped out of the logo. */
.post-card__media--empty { display: grid; place-items: center; background: var(--paper-2); }
.post-card__media--empty::before { content: ""; width: 72px; aspect-ratio: 577.19 / 599.94; background-image: url("../img/tree-mark.svg"); background-position: center; background-size: contain; background-repeat: no-repeat; opacity: .35; }
/* text-wrap: balance and no-common-ligatures come from the h1–h4 base rule. */
.post-card-title { font-size: 1.4118rem; line-height: 1.2; font-weight: 500; margin-bottom: var(--s-2); }
.post-card-title a { color: var(--ink); text-decoration: none; }
/* The title link covers the whole card, so the card is one hit target; .post-more sits above the
   cover so it keeps its own tab stop and focus ring (owner 2026-09-22). */
.post-card-title a::after { content: ""; position: absolute; inset: 0; }
.post-card-title a:hover, .post-card:hover .post-card-title a, .post-card:focus-within .post-card-title a { text-decoration: underline; text-decoration-color: var(--gold-rule-strong); }
.post-excerpt p { margin-bottom: 0; color: var(--ink-2); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.post-more { position: relative; z-index: 1; align-self: start; margin-top: auto; padding-top: var(--s-3); }
.pagination .nav-links { display: flex; justify-content: space-between; gap: var(--s-3); margin-top: var(--s-8); font-size: 0.8824rem; }
.pagination .nav-links .page-numbers { display: inline-flex; align-items: center; justify-content: center; min-height: 40px; padding: 0 20px; border: 1.5px solid var(--ink); border-radius: var(--r-btn); color: var(--ink); text-decoration: none; font-family: var(--font-sans); font-weight: 600; }
.pagination .nav-links .page-numbers:hover { background: rgba(31, 58, 46, 0.06); }
.pagination .nav-links .page-numbers.current { background: var(--ink); color: var(--cream); border-color: var(--ink); }
.page-links { margin-top: var(--s-6); font-size: 0.8824rem; }
.post-title { margin: var(--s-6) 0 var(--s-6); } /* top s-6 (collapses with .post-meta): same háček clearance as .section-head .label + h1 */
.post-hero { margin-bottom: var(--s-8); }
.post-hero-img { width: 100%; max-height: 60vh; object-fit: cover; border-radius: var(--r-card); }
.post-body > * { max-width: 70ch; }
.post-body h2 { margin-top: var(--s-8); }
.post-body img { border-radius: var(--r-card); }
.post-body blockquote { margin: var(--s-6) 0; padding-left: var(--s-4); border-left: 2px solid var(--gold); color: var(--ink-2); }
.post-author { margin-top: var(--s-12); padding-top: var(--s-4); border-top: 1px solid var(--gold-rule); color: var(--ink-2); font-size: 0.8824rem; }
.post-nav { display: flex; justify-content: space-between; gap: var(--s-4); margin-top: var(--s-8); padding-top: var(--s-6); border-top: 1px solid var(--gold-rule); color: var(--ink-2); font-size: 0.8824rem; }
.post-nav a { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-sans); font-weight: 600; color: var(--ink); text-decoration: none; }
.post-nav a:hover { text-decoration: underline; text-decoration-color: var(--gold-rule-strong); text-underline-offset: 3px; }
.post-nav-prev a::before { content: "←"; transition: transform .2s ease-out; }
.post-nav-prev a:hover::before { transform: translateX(-3px); }
.post-nav-next a::after { content: "→"; transition: transform .2s ease-out; }
.post-nav-next a:hover::after { transform: translateX(3px); }
