/* ===========================================================================
   MUDr. Helena Singerová — visual system
   Palette rebuilt 2026-08-25 (second pass).

   WHY IT CHANGED. The first pass was warm cream + serif + terracotta and opened
   every page with a near-black band — hero, seven pageheads, a consultation
   band and the footer. Read end to end it was a dark site for a doctor, which
   is the opposite of how clinics actually present. It was also, precisely, the
   most common look an AI produces regardless of subject.

   THE PALETTE IS SAMPLED, NOT PICKED. Her three operating-theatre frames are
   overwhelmingly cool blue-grey (hue 197-210) at 80-96% luminance; the wall
   behind her portrait is warm sand at hue 36. So: white ground, one clinical
   blue accent carrying every link and marker, sand as the single warm band.
   Every pair in use clears WCAG AA.

   NO DARK GROUNDS, AND NOTHING DARKENED. The hero photograph is bright at every
   point (56-81% luminance), so text over it needed a scrim — and the scrim was
   what made the page read dark. Hero and footer are splits instead: photograph
   in its own column at its own brightness, type on white beside it. The page
   opens and closes on the same picture.

   NO ROUNDED PILLS. A 999px radius on a row of small tags is the most
   recognisable generated tell on a page like this. There is no border-radius
   anywhere in this file.

   NO MONOSPACE. It was here for "data" -- prices, years, anaesthesia codes --
   and that reasoning is wrong for this site: a plastic surgeon's price is not
   a build artefact, and a typewriter face made every list read like one. The
   numbers keep tabular figures in the READING face, so columns still line up
   and a number still reads as a number.
   =========================================================================== */

/* --- typefaces ---------------------------------------------------------- */
/* Self-hosted deliberately: a Google Fonts <link> on her own domain hands every
   visitor's IP to a third party before she can ask their consent. latin-ext is
   a separate file with its own unicode-range — without it every ě š č ř ž ů
   falls back to another face mid-word. */

@font-face {
  font-family: "Newsreader";
  src: url("../fonts/newsreader-normal-latin.f94a697b1650.woff2") format("woff2");
  font-weight: 200 600; font-style: normal; font-display: swap;
  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";
  src: url("../fonts/newsreader-normal-latin-ext.2e01db0610b1.woff2") format("woff2");
  font-weight: 200 600; font-style: normal; font-display: swap;
  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: "Newsreader";
  src: url("../fonts/newsreader-italic-latin.219cf117c93d.woff2") format("woff2");
  font-weight: 200 600; font-style: italic; font-display: swap;
  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";
  src: url("../fonts/newsreader-italic-latin-ext.368108c0f8f5.woff2") format("woff2");
  font-weight: 200 600; font-style: italic; font-display: swap;
  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: "Plex Sans";
  src: url("../fonts/ibm-plex-sans-normal-latin.b2c9031d9fd6.woff2") format("woff2");
  font-weight: 400 600; font-display: swap;
  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: "Plex Sans";
  src: url("../fonts/ibm-plex-sans-normal-latin-ext.f0e2925b3fa6.woff2") format("woff2");
  font-weight: 400 600; font-display: swap;
  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;
}
/* --- tokens -------------------------------------------------------------- */

:root {
  /* Sampled from her own photographs, not chosen off a palette. The three
     operating-theatre frames are overwhelmingly cool blue-grey at 80-96%
     luminance (hue 197-210); the portrait wall behind her is warm sand at
     hue 36. So: white ground, one clinical blue accent, sand as the quiet
     warm note. The previous cream-and-terracotta scheme read as dark and
     heavy for a doctor — every interior page opened with a near-black band. */
  --paper:      #ffffff;
  --mist:       #f1f6f9;   /* cool light ground — bands, pageheads */
  --mist-2:     #e2edf3;   /* one step down: panels inside a mist band */
  --sand:       #f6efe6;   /* the warm note, from the wall behind her */

  --blue:       #1b6c8f;   /* her accent: 5.85:1 on white, 5.85:1 white-on-it */
  --blue-deep:  #12536f;   /* hover and any white-on-blue that must reach AAA */
  --blue-soft:  #cfe3ec;   /* tints, rules, chart fills */

  --ink:        #17262f;   /* darkest text and headings — no longer a ground */
  --text:       #17262f;
  --text-soft:  #4e6069;
  --text-faint: #86959e;
  --line:       #dae5eb;

  /* Kept because a photographic band still needs light type on top of it.
     Nothing uses these as a flat page background any more. */
  --on-dark:      #ffffff;
  --on-dark-soft: #dbe6ec;

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

  --gutter: clamp(1.25rem, 5vw, 4.5rem);
  --shell: 84rem;

  --step: clamp(3.5rem, 8vw, 7rem);   /* vertical rhythm between sections */
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--text);
  font: 400 1rem/1.7 var(--sans);
  font-synthesis-weight: none;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
main { flex: 1 0 auto; }

img { max-width: 100%; display: block; }
a { color: var(--blue); }

::selection { background: var(--blue); color: #fff; }

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--ink); color: var(--on-dark); padding: 0.9rem 1.4rem;
  font-size: 0.875rem;
}
.skip-link:focus { left: 0; }

:where(a, button, input, textarea, select, summary):focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
}

/* --- shared type ---------------------------------------------------------- */

.eyebrow {
  margin: 0;
  font-family: var(--sans);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--blue);
}
/* Was the light-on-dark variant. The pageheads are light now, so it is
   the accent colour — the class name is kept because eight templates use it. */
.eyebrow--dark { color: var(--blue); }

.display {
  font-family: var(--display);
  font-weight: 300;
  line-height: 1.04;
  letter-spacing: -0.015em;
  margin: 0;
  text-wrap: balance;
}
.display em { font-style: italic; font-weight: 300; }

.lede {
  font-size: clamp(1.0625rem, 1.4vw, 1.1875rem);
  line-height: 1.68;
  color: var(--text-soft);
  max-width: 38rem;
  margin: 0;
}

.shell { max-width: var(--shell); margin-inline: auto; padding-inline: var(--gutter); }

/* --- header ----------------------------------------------------------------
   Two tiers, because one row of six grey links with nothing else in it reads as
   dead. The accent strip gives the page its one piece of saturated colour and
   carries the language switcher, which as four small grey letters was
   effectively invisible. The navigation row below behaves like tabs: each item
   owns the full height of the bar and marks itself with a rule flush to the
   bottom edge, so the current page is obvious without a colour change.

   Only the navigation row is sticky. The strip scrolls away — it is an
   introduction, not something to carry down 20 000 characters of poucení. */

.masthead {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255, 255, 255, 0.94);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
}
.masthead__inner {
  max-width: var(--shell); margin-inline: auto;
  padding-inline: var(--gutter);
  display: flex; align-items: stretch; gap: clamp(1rem, 2.5vw, 2.5rem);
}

/* The brand block gets two lines so it has the presence a logo lockup would
   have. She has no mark, and inventing one for a real person's practice is not
   a decision to make in a stylesheet. */
.wordmark {
  display: flex; align-items: center; gap: 0.75rem;
  margin-right: auto; text-decoration: none; padding-block: 0.75rem;
}
/* Her monogram beside the name (2026-09-09). Sized to the two text lines, not
   larger: the mark is a signature next to her name, not a billboard. */
.wordmark__mark { width: 2.75rem; height: 2.75rem; flex: none; display: block; }
.wordmark__text { display: flex; flex-direction: column; justify-content: center; gap: 0.15rem; }
.site-footer__brand { display: inline-flex; align-items: center; gap: 0.5rem; }
.site-footer__brand img { width: 1.375rem; height: 1.375rem; opacity: 0.85; }
.wordmark__name {
  font-family: var(--display); font-weight: 400; font-size: 1.1875rem;
  letter-spacing: 0.005em; color: var(--ink); white-space: nowrap; line-height: 1.1;
}
/* The display italic, not the mono. This line is a subtitle to her name, and
   the rule at the top of this file is that mono is for DATA — prices, years,
   anaesthesia codes — not for decoration. It also sets narrower than the
   tracked uppercase it replaces, which gives the German header back the room
   it was short of. */
.wordmark__role {
  font-family: var(--display); font-style: italic;
  font-size: 0.9375rem; font-weight: 400;
  letter-spacing: 0.005em; text-transform: none;
  color: var(--text-soft);
  white-space: nowrap;
}

.nav { display: flex; align-items: stretch; gap: clamp(0.25rem, 1.2vw, 1.25rem); }
.nav a {
  display: flex; align-items: center;
  /* German breaks "Vorher und nachher" across two lines otherwise, which
     doubles the height of the bar and reads as two menu items. */
  white-space: nowrap;
  padding: 0 0.35rem;
  font-size: 0.9375rem; color: var(--text-soft); text-decoration: none;
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s;
}
.nav a:hover { color: var(--blue); border-bottom-color: var(--blue-soft); }
.nav [aria-current="page"] { color: var(--ink); border-bottom-color: var(--blue); }

.cta__short { display: none; }

.masthead__cta {
  align-self: center;
  padding: 0.6rem 1.1rem;
  font-size: 0.8125rem;
  white-space: nowrap;
}

/* --- the phone menu --------------------------------------------------------
   Wide: the disclosure is not a box at all. `display: contents` drops both it
   and its panel out of the layout, so `.nav` and `.masthead__cta` are still
   direct flex children of the bar and nothing about the desktop header
   changes. The panel also stops obeying the closed <details>, which is what
   we want up here — it is always shown. */
.menu, .menu__panel { display: contents; }
.menu__toggle { display: none; }
/* `display: contents` is NOT enough to show a closed <details>' content.
   Firefox and WebKit hide it with `display: none` in their UA sheet, which the
   line above overrides — but Chrome hides it with `content-visibility: hidden`
   on ::details-content, and no `display` can beat that. The result was a
   desktop header with no navigation at all in Chrome, while the nav element
   still existed, still computed `display: flex`, and still reported its links
   as visible — which is why checking the toggle and the bar height missed it.
   Only the nav's WIDTH showed it: 0px. */
.menu::details-content { content-visibility: visible; display: contents; }
/* The nav and the booking button live inside the disclosure, the language
   picker does not, so the DOM now runs wordmark, picker, nav, button. On a
   wide screen the bar should read the way it always has — wordmark, nav,
   picker, button — and `order` says so without moving anything in the markup
   (which would put the picker inside the phone menu). Above 75rem only: below
   that the nav drops to its own full-width row and already orders itself. */
@media (min-width: 75.0625rem) {
  .nav { order: 1; }
  .langpick { order: 2; }
  .masthead__cta { order: 3; }
}

/* Language: a <details> disclosure. Four bare codes in a row were unreadable as
   a control — nobody recognises "cs en de it" as something to click. */
.langpick { position: relative; align-self: center; }
.langpick > summary {
  display: flex; align-items: center; gap: 0.4rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--line);
  font-family: var(--sans); font-size: 0.75rem; letter-spacing: 0.06em;
  color: var(--text-soft); cursor: pointer; list-style: none;
  user-select: none;
}
.langpick > summary::-webkit-details-marker { display: none; }
.langpick > summary:hover { border-color: var(--blue); color: var(--blue); }
.langpick__caret {
  width: 0; height: 0;
  border-left: 4px solid transparent; border-right: 4px solid transparent;
  border-top: 4px solid currentColor;
  transition: transform 0.15s;
}
.langpick[open] > summary { border-color: var(--blue); color: var(--blue); }
.langpick[open] .langpick__caret { transform: rotate(180deg); }
.langpick__menu {
  position: absolute; top: calc(100% + 0.35rem); right: 0; z-index: 120;
  min-width: 11rem; margin: 0; padding: 0.3rem; list-style: none;
  background: var(--paper); border: 1px solid var(--line);
  box-shadow: 0 12px 28px rgba(23, 38, 47, 0.13);
}
.langpick__menu a {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.5rem 0.6rem;
  font-size: 0.875rem; color: var(--text); text-decoration: none;
}
.langpick__menu a:hover { background: var(--mist); color: var(--blue); }
.langpick__menu [aria-current="true"] { color: var(--blue); font-weight: 500; }
.langpick__code {
  font-family: var(--sans); font-size: 0.75rem; letter-spacing: 0.04em;
  color: var(--text-faint); min-width: 1.6rem;
}
.langpick__menu [aria-current="true"] .langpick__code { color: var(--blue); }

/* The practice line is the first thing to give up horizontal room. German
   ("Plastische und ästhetische Chirurgie · Prag") makes the brand block 309px
   wide, which pushed the nav off the right edge at 1200px while Czech was fine
   — the kind of overflow that only exists in one language. */
/* The practice line is the first thing to give up horizontal room. Tried
   lowering this to 75rem and then 80rem once the italic made it ~54px
   narrower than the tracked mono — German still overflowed at 1281px,
   because the binding constraint there is the six-item nav, not the
   tagline. 82rem is the measured safe threshold. */
@media (max-width: 82rem) { .wordmark__role { display: none; } }

/* 75rem, not 68: German and Italian still overflowed at 1100px once the nav
   had six items. The breakpoint is set by the longest language, not by Czech. */
@media (max-width: 62rem) {
  /* Phone: the bar is the wordmark, the language picker and the button that
     opens everything else. */
  .menu { display: block; position: relative; }
  .menu { align-self: center; }
  /* The same box as the language picker beside it — same padding, same rule,
     same transparent face — so the two controls are the same height and sit
     on the same line. They were 37px at y=4 and 44px at y=0, which is what
     made the pair look wrong. Deriving the height rather than setting one
     keeps them matched if the picker ever changes. */
  .menu__toggle {
    display: flex; align-items: center; justify-content: center;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--line);
    color: var(--text-soft);
    cursor: pointer; list-style: none; user-select: none;
    transition: border-color 0.2s ease, color 0.2s ease;
  }
  .menu__toggle:hover,
  .menu[open] .menu__toggle { border-color: var(--blue); color: var(--blue); }
  .menu__toggle::-webkit-details-marker { display: none; }
  /* A 1.3rem-tall box the same height as the picker's text line, with the
     middle bar painted as a background rather than being the box itself —
     that is what lets the box set the height instead of the bar. */
  .menu__bars {
    position: relative; display: block; width: 1.15rem; height: 1.3rem;
    background: linear-gradient(currentColor, currentColor) center / 100% 2px no-repeat;
    color: var(--ink);
    transition: background-image 0.28s ease;
  }
  .menu__toggle:hover .menu__bars,
  .menu[open] .menu__bars { color: var(--blue); }
  .menu__bars::before, .menu__bars::after {
    content: ""; position: absolute; left: 0;
    width: 100%; height: 2px; top: calc(50% - 1px);
    background: currentColor;
    /* Slower and eased. At 0.18s linear the bars snapped into the cross hard
       enough to read as a glitch rather than a movement. */
    transition: transform 0.28s cubic-bezier(0.22, 0.61, 0.36, 1);
  }
  .menu__bars::before { transform: translateY(-6px); }
  .menu__bars::after  { transform: translateY(6px); }
  /* Open: the bars become a cross, so the control says how to close itself. */
  .menu[open] .menu__bars { background-image: none; }
  .menu[open] .menu__bars::before { transform: rotate(45deg); }
  .menu[open] .menu__bars::after  { transform: rotate(-45deg); }

  /* An explicit `display` on the panel overrides the UA rule that hides a
     closed <details>' children, so the menu would hang open permanently.
     Say it ourselves. */
  .menu:not([open]) .menu__panel { display: none; }
  .menu__panel {
    display: block;
    position: absolute; right: 0; top: calc(100% + 0.55rem);
    z-index: 120;
    min-width: min(17rem, calc(100vw - 2.5rem));
    /* Plain white, and the same treatment as the language picker's menu right
       beside it — same ground, same rule, same shadow. Two dropdowns opening
       off the same bar should not be two different materials. */
    background: var(--paper);
    border: 1px solid var(--line);
    box-shadow: 0 12px 28px rgba(23, 38, 47, 0.13);
    padding: 0.5rem;
    /* Eased in rather than appearing. <details> has no transition of its own,
       so the movement lives on the panel and runs once, on open. */
    animation: menu-open 0.26s cubic-bezier(0.22, 0.61, 0.36, 1) both;
    transform-origin: top right;
  }
  @keyframes menu-open {
    from { opacity: 0; transform: translateY(-0.5rem) scale(0.985); }
    to   { opacity: 1; transform: none; }
  }
  .menu__panel .nav {
    display: flex; flex-direction: column; align-items: stretch;
    gap: 0; width: auto; overflow: visible; mask-image: none;
  }
  .menu__panel .nav a {
    padding: 0.85rem 0.9rem; font-size: 1rem; white-space: normal;
    border-bottom: 1px solid var(--line);
    transition: background 0.18s ease, color 0.18s ease;
  }
  .menu__panel .nav a:last-of-type { border-bottom: 0; }
  .menu__panel .nav a:hover,
  .menu__panel .nav a[aria-current="page"] { background: var(--mist); color: var(--blue); }
  /* Marek: the booking button goes all the way to the bottom of the menu. */
  .menu__panel .masthead__cta {
    display: flex; justify-content: center;
    margin: 0.5rem 0.25rem 0.25rem; padding: 0.8rem 1.1rem; font-size: 0.9375rem;
  }
  .menu__panel .cta__short { display: none; }
  .menu__panel .cta__full { display: inline; }
}

/* After the menu block on purpose. An override for reduced motion has to come
   LATER in the file than the animation it cancels — the first attempt sat up
   near the top with the scroll-behavior reset, where the panel's own
   `animation` simply won and the movement still ran. */
@media (prefers-reduced-motion: reduce) {
  .menu__panel { animation: none; }
  .menu__bars, .menu__bars::before, .menu__bars::after { transition: none; }
}

@media (max-width: 75rem) and (min-width: 62.0625rem) {
  .masthead__inner { flex-wrap: wrap; padding-bottom: 0.5rem; }
  .wordmark { padding-block: 0.75rem; }
  /* Fade the trailing edge so a half-visible "Kontakt" reads as more to
     scroll rather than as clipped text. */
  .nav {
    order: 3; width: 100%; overflow-x: auto; scrollbar-width: none;
    padding-bottom: 0.35rem;
    mask-image: linear-gradient(to right, #000 calc(100% - 2rem), transparent);
  }
  .nav::-webkit-scrollbar { display: none; }
  .nav a { padding-block: 0.5rem; white-space: nowrap; }
  .masthead__cta { align-self: center; }
}
@media (max-width: 30rem) {
  /* The brand and the booking button must share a row — stacked they made the
     sticky header 204px tall on a 390px phone, a fifth of the viewport gone
     before any content. The practice line goes; the page title says it anyway. */
  .masthead__cta { padding: 0.5rem 0.7rem; font-size: 0.75rem; }
  .masthead__cta .btn__arrow { display: none; }
  .cta__full { display: none; }
  .cta__short { display: inline; }
  .wordmark { padding-block: 0.6rem; }
  .wordmark__name { font-size: 0.9375rem; white-space: nowrap; }
  .wordmark__role { display: none; }
  .masthead__inner { gap: 0.5rem; padding-bottom: 0.35rem; }
  .nav a { font-size: 0.875rem; }
}

/* --- hero: photograph beside the type, not underneath it -------------------
   The enhanced frame is bright everywhere (56-81% luminance), so any text laid
   over it needs a scrim to be legible — and the scrim is what made the page
   read dark. Splitting the hero removes the need entirely: the photograph runs
   full-bleed to one edge at its own brightness, the type sits on white. */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  background: var(--paper);
  min-height: min(76vh, 640px);
}
.hero__inner {
  display: flex; flex-direction: column; justify-content: center;
  /* Align the type to the same left edge as .shell on every other page, while
     the column itself stays half the viewport. */
  padding: clamp(3rem, 6vw, 5rem) clamp(1.75rem, 3.5vw, 3.5rem)
           clamp(3rem, 6vw, 5rem)
           calc(max(0px, (100vw - var(--shell)) / 2) + var(--gutter));
}
.hero__media {
  background-image: image-set(url("../img/hero-operating.676900cceee2.webp") type("image/webp"),
                              url("../img/hero-operating.ba77ccb890d7.jpg") type("image/jpeg"));
  background-size: cover;
  /* Headroom above the cap: at 42% the frame cut the top of her head. */
  background-position: 60% 32%;
  min-height: 20rem;
}
.hero__name {
  font-size: clamp(2.5rem, 5.2vw, 4.5rem);
  color: var(--ink);
  margin: 1.25rem 0 0;
}
.hero__role {
  display: block;
  font-family: var(--sans);
  font-size: clamp(0.8125rem, 1.1vw, 0.9375rem);
  font-weight: 400;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--blue);
  margin-top: 1.4rem;
}
.hero__facts {
  /* A grid, not a wrapping flex row: three facts that break 2+1 read as a
     layout accident. Equal columns keep them on one line and let the labels
     wrap inside their own cell if they must. */
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 clamp(1rem, 2vw, 1.75rem);
  margin-top: clamp(2rem, 4vw, 2.75rem);
  padding-top: 1.5rem;
  border-top: 1px solid var(--line);
}
/* min-width:0 because a grid item's default min-width:auto refuses to shrink
   below its longest word, and German has "GROSSBRITANNIEN" set in uppercase
   with letter-spacing — 6px of page overflow at 360px, in one language. */
.fact { padding-block: 0.35rem; min-width: 0; }
.fact__value {
  display: block; font-family: var(--display); font-size: 1.625rem;
  color: var(--blue); font-variant-numeric: tabular-nums;
}
.fact__label {
  display: block; font-size: 0.6875rem; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--text-soft); margin-top: 0.3rem;
  line-height: 1.35; overflow-wrap: anywhere;
}
@media (max-width: 54rem) {
  .hero { grid-template-columns: 1fr; min-height: 0; }
  .hero__media { order: -1; aspect-ratio: 16 / 10; min-height: 0; }
  .hero__inner { padding: clamp(2.25rem, 7vw, 3.5rem) var(--gutter); }
}

/* --- section scaffolding -------------------------------------------------- */

.band { padding-block: var(--step); }

/* The consultation band was the one full-width dark block left on the home
   page. Sand keeps it distinct from the mist bands without going dark. */
.band--sand { background: var(--sand); }
.band--mist { background: var(--mist); }

/* Left-aligned inside its shell, never centred: .shell centres itself, so a
   narrower max-width on the SAME element would centre the heading and leave it
   out of step with the full-bleed rows below. */
.section__head { max-width: 46rem; margin: 0 0 clamp(2.25rem, 4vw, 3.25rem); }
.section__title {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(1.875rem, 3.6vw, 2.75rem);
  line-height: 1.1; letter-spacing: -0.012em; margin: 1rem 0 1.25rem;
  color: var(--ink); text-wrap: balance;
}

/* --- THE SIGNATURE: paired split ------------------------------------------
   Two panels, one hairline, a label riding the divider. Used for the category
   rows, the procedure detail and the before/after pairs — the same shape her
   work has. */

/* --- home: the picker -----------------------------------------------------
   Her body as the index. Three panels around a cut-out figure, each tied to
   the region it concerns.

   THE REGION NUMBERS ARE MEASURED, NOT GUESSED. From the alpha channel of
   silueta.png — the SECOND figure, 2026-09-17: the first had legs too short
   for her body ("Helča Jr." noticed), this one is 438x1500, ratio 3.425 —
   face 34–67% wide down to the chin at 13%, arms part from the torso at 33%,
   waist narrowest at 40%, hips widest at 53%, knees at 72%.
   Replace the photograph and these have to be measured again.

   Layout mirrors the reference: face top right, chest middle left, body
   bottom right, figure spanning all three rows down the middle. */

.silhouette {
  /* ONE source for the figure's size. The cut-out is 435x1498 (ratio 3.444;
     served at 2x, 870x2996 — tools/prepare_silhouette.py makes it), so
     the panels' offsets below can be written as fractions of her height and
     stay on the right part of her body at every width. Narrower than the
     first figure's 28vw/26rem: she is taller for her width now, and this
     keeps the section the height it was (~1260px at the cap). */
  --fig-w: clamp(12rem, 25vw, 23rem);
  --fig-h: calc(var(--fig-w) * 3.444);
  display: grid;
  /* Bounded side columns, not 1fr: at 1fr the panels were flung to the shell
     edges and the figure floated alone in a lake of whitespace. */
  grid-template-columns: minmax(0, 20rem) auto minmax(0, 20rem);
  /* Two rows, both starting at her head. Before this the three PANELS sized
     the rows (500 + 412 + 391px) and she was centred in the middle of them,
     so "Prsa" began at 37% of her height (the abdomen) and "Tělo" at 75%
     (the knees) — Marek, 2026-09-09, the day he presented the site. Now the
     first row is at least 52% of her height, which puts "Tělo" at the hips,
     and "Prsa" is pushed down to the breast by its own margin. */
  grid-template-rows: minmax(calc(var(--fig-h) * 0.47), auto) auto;
  grid-template-areas: "chest fig face"
                       "chest fig body";
  justify-content: center;
  align-items: start;
  column-gap: clamp(1.25rem, 2.5vw, 2.5rem);
  row-gap: clamp(1rem, 2vw, 1.5rem);
}
/* The figure is 30% larger than the panels' column budget allows inside the
   reading shell, so this one section spans the shell's gutter as well. Only
   above the stacking breakpoint — below it the panels would sit flush against
   the edge of the screen. */
/* 62.0625rem, not 62rem: the stacking query is max-width:62rem, so at
   exactly 992px BOTH applied — the stacked panels got the negative margin
   and sat flush against the edge of the screen. */
@media (min-width: 62.0625rem) {
  .silhouette { margin-inline: calc(-1 * var(--gutter)); }
}

.silhouette__figure {
  grid-area: fig;
  position: relative;
  /* The PNG is cropped to her outline, so this width is the width of the
     BODY. In the uncropped file she filled only 48% of the box, which is why
     a 634px element rendered a 306px woman adrift in empty air. */
  width: var(--fig-w);
  justify-self: center;
}
.silhouette__img { width: 100%; height: auto; display: block; }

/* Placement of the three panels. Keyed on the category key, which is also what
   names the banner images — if a key ever changes both break together and
   loudly, rather than one of them drifting quietly. */
[data-panel="oblicej"] { grid-area: face; }
[data-panel="prsa"]    { grid-area: chest; margin-top: calc(var(--fig-h) * 0.24); }
[data-panel="telo"]    { grid-area: body; }

/* --- the highlight -------------------------------------------------------- */
/* The cut-out used as a mask over a flat fill, clipped to one region, so the
   wash follows her outline instead of being a rectangle over a body. */
.silhouette__wash {
  position: absolute; inset: 0;
  background: var(--blue);
  /* TWO masks intersected: her outline, and a soft ellipse over the region.
     The outline alone gave a hard-edged block — at chest height her arms and
     torso fill the whole region, so a rectangular clip read as a rectangle
     laid on the picture. The ellipse makes it a glow that fades into her. */
  -webkit-mask-image: url("../img/silueta.0b67d351787d.webp"),
    radial-gradient(ellipse var(--rx) var(--ry) at var(--cx) var(--cy),
                    #000 42%, rgba(0,0,0,0.55) 66%, transparent 82%);
          mask-image: url("../img/silueta.0b67d351787d.webp"),
    radial-gradient(ellipse var(--rx) var(--ry) at var(--cx) var(--cy),
                    #000 42%, rgba(0,0,0,0.55) 66%, transparent 82%);
  -webkit-mask-size: 100% 100%, 100% 100%;
          mask-size: 100% 100%, 100% 100%;
  -webkit-mask-repeat: no-repeat, no-repeat;
          mask-repeat: no-repeat, no-repeat;
  -webkit-mask-composite: source-in;
          mask-composite: intersect;
  opacity: 0;
  transition: opacity 0.28s ease;
  pointer-events: none;
}
/* Ellipse centre and radii per region, from the measured anatomy. */
[data-wash="oblicej"] { --cx: 50.3%; --cy: 6.5%;  --rx: 24%;   --ry: 8.5%; }
[data-wash="prsa"]    { --cx: 50.5%; --cy: 28.5%; --rx: 46%;   --ry: 8%; }
[data-wash="telo"]    { --cx: 50.5%; --cy: 50%;   --rx: 58%;   --ry: 20%; }
/* 0.45, not 0.55: over a face the stronger wash read as a bruise. */
.silhouette.is-active [data-wash].is-on { opacity: 0.45; }

/* --- the markers ---------------------------------------------------------- */

/* The anchor is a small square hit area centred on the measured point, with
   the dot centred inside it and the label OUTSIDE. Translating the whole
   dot-plus-label row by -50% centred the row, not the dot, which put the
   marker on her eye instead of at her temple. */
.hotspot {
  position: absolute;
  display: block;
  width: 2.4rem; height: 2.4rem;
  transform: translate(-50%, -50%);
  text-decoration: none;
}
/* Beside the panels a click on her body goes nowhere — the panel is already
   there — so no pointer hand: only the procedures in the lists are links
   (Kuba, 2026-09-17). On a phone the tap scrolls to the panel, so it stays. */
@media (min-width: 62.0625rem) { .hotspot { cursor: default; } }
[data-region="oblicej"] { left: 66%;   top: 6%; }
[data-region="prsa"]    { left: 25%;   top: 28%; }
[data-region="telo"]    { left: 84%;   top: 46.5%; }

.hotspot__dot {
  position: absolute; left: 50%; top: 50%;
  width: 0.85rem; height: 0.85rem;
  margin: -0.425rem 0 0 -0.425rem;
  background: var(--paper);
  border: 2px solid var(--blue);
  border-radius: 50%;          /* the one round thing on the site: it is a pin */
  transition: transform 0.2s, background 0.2s;
}
.hotspot__dot::after {
  content: ""; position: absolute; inset: -0.55rem;
  border: 1px solid var(--blue); border-radius: 50%;
  opacity: 0; transform: scale(0.6);
  transition: opacity 0.28s, transform 0.28s;
}
.hotspot__name {
  position: absolute; top: 50%; left: calc(100% - 0.3rem);
  transform: translateY(-50%);
  font-family: var(--sans); font-size: 0.6875rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--text-soft);
  background: rgba(255, 255, 255, 0.88);
  padding: 0.15rem 0.35rem;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 0.2s;
}
/* The chest panel is on the left, so its label reads outward that way too. */
[data-region="prsa"] .hotspot__name { left: auto; right: calc(100% - 0.3rem); }

.hotspot:hover .hotspot__dot,
.hotspot:focus-visible .hotspot__dot,
.hotspot.is-on .hotspot__dot { background: var(--blue); transform: scale(1.2); }
.hotspot:hover .hotspot__dot::after,
.hotspot:focus-visible .hotspot__dot::after,
.hotspot.is-on .hotspot__dot::after { opacity: 1; transform: scale(1); }
.hotspot:hover .hotspot__name,
.hotspot:focus-visible .hotspot__name,
.hotspot.is-on .hotspot__name { opacity: 1; }

/* --- the panels ----------------------------------------------------------- */

.pick {
  border-top: 2px solid var(--line);
  padding-top: 1.1rem;
  transition: border-color 0.25s;
}
/* Dim the others ONLY while a region is actually engaged. Keyed on
   .has-focus, not .is-active: dimming whenever the script had merely run
   left all three panels at 55% in the resting state — which is the state
   almost every visitor sees. */
.silhouette .pick { transition: opacity 0.25s, border-color 0.25s; }
.silhouette.has-focus .pick { opacity: 0.5; }
.silhouette.has-focus .pick.is-on { opacity: 1; border-top-color: var(--blue); }
.pick__title {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(1.375rem, 2.4vw, 1.75rem);
  line-height: 1.15; margin: 0 0 0.5rem; color: var(--ink);
}
.pick__text {
  margin: 0 0 0.9rem; color: var(--text-soft);
  font-size: 0.9375rem; line-height: 1.55;
}
.pick__list { list-style: none; margin: 0; padding: 0; }
.pick__list li { border-top: 1px solid var(--line); }
.pick__list li:last-child { border-bottom: 1px solid var(--line); }
.pick__list a {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.55rem 0.15rem;
  color: var(--text); text-decoration: none; font-size: 0.9375rem;
  transition: color 0.15s, padding-left 0.15s;
}
.pick__list a:hover { color: var(--blue); padding-left: 0.5rem; }
.pick__arrow { color: var(--blue-soft); transition: transform 0.15s, color 0.15s; }
.pick__list a:hover .pick__arrow { color: var(--blue); transform: translateX(3px); }

@media (max-width: 62rem) {
  /* Not enough width to put panels beside her. The figure becomes the section's
     opening image and the panels stack under it; the hotspots still work and
     scroll to the right panel. */
  .silhouette {
    grid-template-columns: 1fr;
    grid-template-rows: auto;
    grid-template-areas: "fig" "face" "chest" "body";
  }
  [data-panel="prsa"] { margin-top: 0; }
  .silhouette__figure { width: min(11rem, 42vw); }
  /* The no-JavaScript path still jumps to the anchor, so keep the heading
     clear of the sticky header there too. */
  .pick { scroll-margin-top: 5rem; }
  .hotspot__name { opacity: 1; transform: none; }
  .silhouette.has-focus .pick { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .silhouette__wash, .hotspot__dot, .hotspot__dot::after, .hotspot__name, .pick {
    transition: none;
  }
}

/* --- home: who is doing this ---------------------------------------------- */

.aboutstrip {
  display: grid; gap: clamp(1.75rem, 4vw, 3.5rem);
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  align-items: center;
}
.aboutstrip__media img { width: 100%; height: auto; }
.aboutstrip .lede { margin-top: 1rem; }
.aboutstrip .hero__facts { margin-top: 1.75rem; }
@media (max-width: 54rem) { .aboutstrip { grid-template-columns: 1fr; } }

/* --- home: Transformace ----------------------------------------------------
   One card per category. The pair is a WIPE, not two frames side by side:
   side by side the eye has to hop between them and align the faces itself.

   The tints are the palette's own three grounds rather than three invented
   brand colours — mist, sand, and the accent tint — so the row reads as a set
   without turning into a paint chart. */

/* Gaps are tight so a little more of the width lands inside the photographs,
   while the row still lines up with the rest of the page. */
.tcards {
  display: grid; gap: clamp(0.75rem, 1.4vw, 1.25rem);
  /* min(22rem, 100%) — a bare 22rem minimum is wider than a 360px phone's
     content box, so the track refused to shrink and the page scrolled. */
  grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
}
@media (min-width: 62.0625rem) {
  /* The shell's gutter, not the whole viewport: edge-to-edge broke this row's
     alignment with every other section on the page. The extra width for the
     photographs comes from the tighter gaps above instead. */
  .tcards { margin-inline: calc(-1 * var(--gutter)); }
}
.tcard {
  display: flex; flex-direction: column;
  background: var(--paper);
  border: 1px solid var(--line);
  overflow: hidden;
}
.tcard--oblicej { background: var(--paper); }
.tcard--prsa    { background: var(--sand); border-color: #e8dccd; }
.tcard--telo    { background: var(--blue-soft); border-color: #b9d6e4; }

/* --- the pair ------------------------------------------------------------- */

/* Both transparent so the CARD's tint shows through as matting around the
   4:3 photograph. A background on the grid itself painted the mist grey
   behind every photo, including on the sand and blue cards. */
/* Stacked, not side by side. Two photographs across a card three-up in the
   row gave each one half the card — 216px. Stacked, each gets the whole
   card width, which is exactly double. */
.tpair { display: grid; grid-template-columns: 1fr; gap: 1px; background: var(--line); }
.tpair__side { position: relative; display: grid; background: transparent; }
/* No divider: a rule between them ran on through the matting above and
   below the photographs, where there is nothing to divide. */
/* The photographs are 640x480; the box follows them, so nothing is cropped and
   there are no matted bars. */
.tpair__side img {
  display: block; width: 100%; height: auto;
  aspect-ratio: 4 / 3; object-fit: contain;
}

/* --- the card body -------------------------------------------------------- */

.tcard__body {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 0.15rem;
  padding: clamp(1rem, 2vw, 1.35rem);
}
.tcard__name {
  font-family: var(--sans); font-weight: 600;
  font-size: 1.5rem; line-height: 1.1; letter-spacing: -0.02em;
  margin: 0; color: var(--ink);
}
.tcard__link {
  margin-top: 0.7rem;
  font-size: 0.9375rem; font-weight: 500;
  color: var(--blue); text-decoration: none;
}
.tcard__link:hover { text-decoration: underline; }

.section__head--center { max-width: 44rem; margin-inline: auto; text-align: center; }

/* --- Zákroky: downloads ---------------------------------------------------
   Warm, not technical. No bordered cards, no monospace, no uppercase file
   extension in a chip — that read as a build-artefact list. The document's own
   name in the reading face, and beneath it what will open, in the body font.
   The row itself is the affordance: a warm wash on hover and a quiet arrow. */

.prep { margin-top: clamp(3rem, 6vw, 5rem); }
.prep__head { margin-bottom: clamp(0.75rem, 1.5vw, 1.25rem); }
.prep__head .section__title { margin: 0; font-size: clamp(1.5rem, 2.8vw, 2rem); }

.dl {
  list-style: none; margin: 0 0 1.75rem; padding: 0;
  display: grid; gap: 0;
  grid-template-columns: repeat(auto-fit, minmax(min(22rem, 100%), 1fr));
  column-gap: clamp(1.5rem, 3vw, 3rem);
}
.dl__link {
  display: flex; align-items: center; gap: 1.25rem;
  padding: 1rem 1rem 1rem 0.25rem;
  border-bottom: 1px solid var(--line);
  text-decoration: none; color: var(--text);
  transition: background 0.18s, padding-left 0.18s;
}
.dl__link:hover {
  background: var(--sand);
  padding-left: 0.9rem;
}
.dl__body { min-width: 0; display: grid; gap: 0.2rem; }
.dl__name {
  font-family: var(--display); font-weight: 400;
  font-size: 1.125rem; line-height: 1.3; color: var(--ink);
  overflow-wrap: anywhere;
}
.dl__link:hover .dl__name { color: var(--blue); }
.dl__meta {
  font-size: 0.875rem; color: var(--text-soft);
}
.dl__icon {
  flex: none; margin-left: auto;
  width: 1.35rem; height: 1.35rem; color: var(--blue);
  transition: transform 0.18s;
}
.dl__link:hover .dl__icon { transform: translateY(2px); }
.dl__icon svg { width: 100%; height: 100%; display: block; }

/* --- Zákroky: the price list as alternating rows -------------------------- */

.zig {
  display: grid; align-items: center;
  gap: clamp(1.5rem, 4vw, 3.5rem);
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}
.zig:last-child { margin-bottom: 0; }
.zig--flip .zig__media { order: 2; }
.zig__media img { width: 100%; height: auto; display: block; }
.zig__name {
  font-family: var(--sans); font-weight: 600;
  font-size: clamp(1.5rem, 2.8vw, 2rem); line-height: 1.1;
  letter-spacing: -0.02em; margin: 0 0 1rem; color: var(--ink);
}

.pricelist { list-style: none; margin: 0; padding: 0; }
.pricelist li { border-top: 1px solid var(--line); }
.pricelist li:last-child { border-bottom: 1px solid var(--line); }
.pricelist a {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1.25rem; padding: 0.95rem 0.15rem;
  color: var(--text); text-decoration: none;
  transition: color 0.15s, padding-left 0.15s;
}
.pricelist a:hover { color: var(--blue); padding-left: 0.4rem; }
/* The reading face, at reading size. Monospace at 12px turned her price list
   into a spreadsheet; these are the words a person is choosing between. */
.pricelist__name {
  font-family: var(--display); font-weight: 400;
  font-size: 1.1875rem; line-height: 1.3;
  min-width: 0; overflow-wrap: anywhere;
}
.pricelist__meta { display: flex; align-items: baseline; gap: 0.7rem; flex: none; }
/* This list wanted a warmer mark than the rest of the site had; that treatment
   is now the default in `.anaes`, so only the lighter colour is left. */
.pricelist .anaes { color: var(--text-faint); }

.pricelist__from {
  font-family: var(--display); font-size: 1.0625rem; color: var(--text-soft);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

@media (max-width: 54rem) {
  .zig { grid-template-columns: 1fr; }
  .zig--flip .zig__media { order: 0; }
}

/* --- Zákroky: the enquiry panel -------------------------------------------
   Sand rather than the cool mist, no outline around the panel, and fields that
   are ruled underneath rather than boxed. A grid of hard-bordered rectangles is
   what made this look like a form on an insurance portal. */

.askpanel {
  display: grid; gap: clamp(1.75rem, 4vw, 4rem);
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  align-items: start;
  background: var(--sand);
  padding: clamp(1.75rem, 4.5vw, 3.5rem);
}
.askpanel__intro .section__title { margin: 0 0 1rem; font-size: clamp(1.75rem, 3.2vw, 2.25rem); }
.askpanel__portrait {
  display: block; width: 100%; height: auto;
  margin-top: clamp(1.5rem, 3vw, 2.25rem);
}

/* Ruled fields, on the sand itself — a white box inside a warm panel reads as
   a control pasted onto the page rather than part of it. */
.askpanel .form { max-width: none; gap: 1.35rem; }
.askpanel .field__label {
  font-size: 0.875rem; font-weight: 400; color: var(--text-soft);
}
.askpanel .field__input {
  padding: 0.55rem 0.15rem;
  border: 0; border-bottom: 1px solid #ddcfbe;
  background: transparent;
  font-size: 1rem;
  transition: border-color 0.15s;
}
.askpanel .field__input:focus,
.askpanel .field__input:focus-visible {
  outline: none; border-bottom-color: var(--blue); border-bottom-width: 2px;
  padding-bottom: calc(0.55rem - 1px);
}
.askpanel textarea.field__input { border: 1px solid #ddcfbe; padding: 0.7rem 0.85rem; }
.askpanel textarea.field__input:focus,
.askpanel textarea.field__input:focus-visible { border-color: var(--blue); padding-bottom: 0.7rem; }
.askpanel .field--check { margin-top: 0.35rem; }

/* Kontakt reuses the enquiry panel, with her details where Zákroky puts the
   portrait. Headings match the operation headings elsewhere: reading face, in
   the accent, over a rule. */
.reach { margin-top: clamp(1.75rem, 3.5vw, 2.5rem); }
.reach__title {
  margin: 0 0 0.9rem;
  font-family: var(--display); font-weight: 400;
  font-size: 1.25rem; line-height: 1.2; color: var(--blue);
  padding-bottom: 0.5rem; border-bottom: 1px solid #ddcfbe;
}
.reach__note { margin: 0; color: var(--text-soft); line-height: 1.6; }

@media (max-width: 54rem) { .askpanel { grid-template-columns: 1fr; } }


/* --- home: video ---------------------------------------------------------- */
/* The poster is ours and the iframe is written in only on click, so a visitor
   who never presses play makes no request to Google at all. */

.videos {
  display: grid; gap: clamp(1.5rem, 3vw, 2.5rem);
  grid-template-columns: repeat(auto-fit, minmax(min(19rem, 100%), 1fr));
}
.video { margin: 0; }
.video__poster {
  position: relative; display: block; width: 100%; padding: 0;
  border: 1px solid var(--line); background: var(--mist);
  cursor: pointer; overflow: hidden;
}
.video__poster img { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
/* The triangle needs a ground of its own: both posters are light, and a white
   arrow with only a drop-shadow disappeared into them. */
.video__play {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: 4.5rem; height: 4.5rem;
  background: rgba(27, 108, 143, 0.92);
  transition: transform 0.18s, background 0.18s;
}
.video__play::after {
  content: ""; position: absolute; left: 56%; top: 50%; transform: translate(-50%, -50%);
  width: 0; height: 0;
  border-top: 0.7rem solid transparent; border-bottom: 0.7rem solid transparent;
  border-left: 1.15rem solid #fff;
}
.video__poster:hover .video__play {
  transform: translate(-50%, -50%) scale(1.08);
  background: var(--blue-deep);
}
.video__cta {
  position: absolute; left: 0; bottom: 0;
  padding: 0.5rem 0.9rem;
  background: var(--blue); color: #fff;
  font-family: var(--sans); font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.09em; text-transform: uppercase;
}
.video__caption {
  margin-top: 0.8rem; color: var(--text);
  font-size: 0.9375rem; line-height: 1.5;
}
.video__note {
  display: block; margin-top: 0.2rem;
  color: var(--text-faint); font-size: 0.8125rem;
}
.video__frame { width: 100%; aspect-ratio: 16 / 9; border: 1px solid var(--line); }

.btns--center { justify-content: center; margin-top: clamp(2rem, 4vw, 3rem); }

/* --- home: the closing band ------------------------------------------------
   Was a heading, a paragraph and two buttons flush left — structurally the same
   as every other band on the page, so the one place a visitor is meant to act
   looked like more reading. Centred, with the action on its own line and the
   three ways to reach her below a rule. */

/* The home page's ending is this block AND the footer: the links and the
   copyright sit inside it, so the page closes once instead of twice. */
/* The photograph is the last thing in this block, so the block itself ends
   flush with it — .band's 7rem bottom left a strip of sand under the photo.
   The breathing room goes on the shell, above the band, instead. */
/* The clinic entrance behind the whole block.
   
   MEASURED AGAINST THE REFERENCE, not eyeballed. On plastikapraha.cz the
   background under the heading has a luminance standard deviation of 1.2 — it
   is a flat field, and that is the whole reason its text is readable. Ours was
   10.1: the staircase, railings and hedges ran straight through the copy.
   Contrast ratio said AAA and the section was still unreadable, because
   contrast ratio measures colour difference and not visual noise.

   Two things fix it. The file is pre-blurred and flattened (Gaussian 14,
   brightness 1.40, contrast 0.42), and the tint is a vertical ramp rather than
   a flat 50%: heavy across the middle where every line of text sits, light at
   the top and bottom edges so the photograph is still plainly a photograph.
   Measured result: std 1.24 behind the text, 8.1 at the edges. */
.talk {
  /* The muted placeholder grey is built for a flat white page; over this
     band it measured 2.63:1. Darkened here only — still visibly secondary,
     but readable. */
  --text-faint: #5b6a73;
  flex-shrink: 0;
  font-size: 0.875rem;
  color: var(--text);
  padding-bottom: clamp(2.5rem, 5vw, 4rem);
  /* Flat sand, no photograph — Marek's call, and the band is better for it.
     There was a clinic frame behind this under a wash; at any wash light
     enough to see it, body copy over the dark staircase in the middle fell to
     3-4:1, and at a wash heavy enough to read on, the picture was "absolutely
     nothing besides few shades". A band that has to choose between showing
     its photograph and being readable should not have one.

     The colour is `--sand` via `.band--sand` on the element — the same
     #f6efe6 the enquiry forms use, so the ending reads as the same material
     as the form it is asking you to fill in. Nothing to set here. */
  padding-block: clamp(2.5rem, 5vw, 4rem);
}
.talk .site-footer__grid {
  margin-top: clamp(2.5rem, 5vw, 3.5rem);
  padding-top: clamp(2.5rem, 5vw, 3.5rem);
  border-top: 1px solid var(--line);
  text-align: left;
}
.talk .site-footer__base { border-top-color: var(--line); }

/* Kontakt renders this band without its call to action, so the rule that used
   to separate the links FROM that call has nothing above it, and the band's
   full top padding becomes a stretch of empty tint. */
.talk--bare { padding-top: clamp(2rem, 4vw, 3rem); }
.talk--bare .site-footer__grid { margin-top: 0; padding-top: 0; border-top: 0; }


.site-footer__note { margin: 0.9rem 0 0; }

.talk__head { max-width: 44rem; margin: 0 auto; text-align: center; }
/* Same face as the footer column headings below it — the light display serif
   read as a magazine standfirst rather than as the page's call to action. */
.talk .section__title {
  font-family: var(--sans); font-weight: 600;
  font-size: clamp(1.875rem, 3.4vw, 2.5rem);
  letter-spacing: -0.02em;
  margin: 0 0 1.25rem;
}
.talk__head .lede { margin-inline: auto; }
.talk__actions {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 0.85rem 1.1rem;
  margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
}
.talk__or { color: var(--text-soft); font-size: 0.9375rem; }
.js-mail { display: inline-flex; align-items: center; gap: 0.55rem; }
.mailicon { flex: none; }
.direct__mail { color: var(--blue); text-decoration: none; }
.direct__mail:hover .js-mail__text { text-decoration: underline; }
.talk__phone { font-variant-numeric: tabular-nums; }
/* A placeholder must look like one. A plausible-looking number on a live
   surgeon's site gets dialled. */
.talk__phone.is-pending {
  color: var(--text-faint); border-style: dashed; cursor: default;
  background: transparent;
}
.is-pending { color: var(--text-faint); }

/* Her phone and e-mail, at the size of something you are meant to use rather
   than of a field label: the number in the reading face, the word above it in
   the body font instead of monospaced capitals. */
.direct { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.1rem; }
.direct li { display: grid; gap: 0.15rem; overflow-wrap: anywhere; }
.direct__label { font-size: 0.875rem; color: var(--text-soft); }
.direct a, .direct .is-pending {
  font-family: var(--display); font-size: 1.25rem; line-height: 1.3;
  color: var(--ink); text-decoration: none;
}
.direct a:hover { color: var(--blue); text-decoration: underline; }




.chips { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 1.6rem 0 0; padding: 0; list-style: none; }
/* Squared, not pill-shaped. A 999px radius on a row of small tags is the
   single most recognisable "generated" tell on a page like this. */
.chip {
  font-size: 0.8125rem; line-height: 1.4;
  padding: 0.4rem 0.75rem;
  border: 1px solid var(--line);
  color: var(--text-soft);
  background: var(--paper);
}
.band--mist .chip { background: var(--paper); }

@media (max-width: 54rem) {
}

/* --- buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; gap: 0.55rem;
  padding: 0.85rem 1.6rem;
  font-size: 0.875rem; font-weight: 500;
  text-decoration: none;
  border: 1px solid transparent;
  transition: background 0.18s, color 0.18s, border-color 0.18s;
}
.btn--primary { background: var(--blue); color: #fff; }
.btn--primary:hover { background: #8f4f31; color: #fff; }
.btn--ghost { border-color: var(--line); color: var(--ink); background: transparent; }
.btn--ghost:hover { border-color: var(--blue); color: var(--blue); }
/* No dark grounds left; kept as the quiet secondary next to btn--primary. */
.btn--on-dark { border-color: var(--line); color: var(--text); background: var(--paper); }
.btn--on-dark:hover { border-color: var(--blue); color: var(--blue); }
.btn__arrow { transition: transform 0.18s; }
.btn:hover .btn__arrow { transform: translateX(3px); }

.btns { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2rem; }

/* --- data: prices, anaesthesia -------------------------------------------- */

/* The mark reads beside her prices and beside body text, so it is set in the
   reading face with a sand-warm rule -- monospace with wide tracking made every
   price list look like a spreadsheet, which is the one thing this site must
   not feel like. */
.anaes {
  flex: none;
  display: inline-block;
  padding: 0.18rem 0.5rem;
  border: 1px solid #ddcfbe;
  color: var(--text-soft);
  font-family: var(--sans);
  font-size: 0.75rem;
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: help;
  white-space: nowrap;
}
.anaes--static { cursor: default; }

.prices { list-style: none; margin: 0; padding: 0; }
.price {
  display: grid;
  /* The mark's column is reserved, not sized to content: "Implantáty" carries
     no anaesthesia, and with an `auto` third column that row's price slid a
     gap-plus-a-chip to the right of every price above it. */
  grid-template-columns: minmax(0, 1fr) auto var(--anaes-col, 2.9rem);
  gap: 0.4rem 1.25rem;
  align-items: baseline;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--line);
}
.price .anaes { justify-self: end; }
.price:last-child { border-bottom: none; }
.price__label {
  min-width: 0; overflow-wrap: anywhere;
  font-family: var(--display); font-size: 1.0625rem; line-height: 1.35;
}
.price__note { display: block; font-family: var(--sans); font-size: 0.8125rem; color: var(--text-faint); margin-top: 0.2rem; }
/* Tabular figures in the reading face: the numbers still align down the column,
   without the typewriter. */
.price__figures {
  display: flex; gap: 0.7rem; align-items: baseline; white-space: nowrap;
  font-family: var(--display); font-variant-numeric: tabular-nums;
}
/* Quieter than the figure it qualifies, but the same face and baseline, so it
   reads as part of the price rather than as a label stuck in front of it. */
.price__from { font-size: 0.9375rem; color: var(--text-soft); }
.price__czk { font-size: 1.1875rem; color: var(--ink); }
.price__eur { font-size: 0.875rem; color: var(--text-faint); }

@media (max-width: 34rem) {
  .price { grid-template-columns: minmax(0, 1fr) auto; }
  .price__figures { grid-column: 1 / -1; }
  .anaes { grid-column: 2; grid-row: 1; }
}

/* --- motion: one orchestrated reveal, nothing scattered ------------------- */

.reveal { opacity: 0; transform: translateY(18px); }
.is-in .reveal,
.reveal.is-in { opacity: 1; transform: none; transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.22, 1, 0.36, 1); }
.reveal:nth-child(2) { transition-delay: 0.06s; }
.reveal:nth-child(3) { transition-delay: 0.12s; }
.reveal:nth-child(4) { transition-delay: 0.18s; }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .btn__arrow, .pick__list a, .pick__arrow, .video__play { transition: none; }
}

/* --- footer ----------------------------------------------------------------
   Her photograph beside the links, mirroring the hero — the page opens with the
   picture on the right and closes with it on the right. Two earlier attempts
   failed for the same reason: it is a tight portrait, so a full-width band
   slices it across the eyes at every height under ~600px, and laying it behind
   the type under a white veil turned it into a ghost. Given a column it keeps
   its composition. */

.site-footer__grid {
  display: grid; gap: 2rem clamp(1.5rem, 3vw, 3rem);
  grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
}
/* Plain sans, heavy, and clearly larger than the links it covers. Went from
   mono uppercase at 11px (read as a form label) through display italic (read
   as decoration) to this: the heading has to outrank its own list, and the
   list is 15px.

   flex-start, not center: "Before your consultation" wraps in the narrower
   plain-footer column, and a centred icon then floats between the two lines. */
.site-footer__grid h2 {
  display: flex; align-items: flex-start; gap: 0.6rem;
  font-family: var(--sans); font-style: normal; font-weight: 600;
  font-size: 1.75rem; line-height: 1.15;
  letter-spacing: -0.01em; text-transform: none; color: var(--ink);
  margin: 0 0 0.35rem;   /* min-height below already provides the air */
  /* Two lines reserved. At this size "Before your consultation" and
     "Prima della consulenza" wrap while the other two do not, which
     started the three lists at three different heights. */
  min-height: 2.3em;
}
.site-footer__icon {
  flex: none; width: 1.6rem; height: 1.6rem;
  margin-top: 0.12em;         /* sits on the first line, not above it */
  color: var(--blue);
}
.site-footer__icon svg { width: 100%; height: 100%; display: block; }
.site-footer__grid ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.site-footer__grid a, .site-footer__base a { color: var(--text); text-decoration: none; }
.site-footer__grid a:hover, .site-footer__base a:hover { color: var(--blue); text-decoration: underline; }
.site-footer__legal {
  margin: clamp(2rem, 4vw, 3rem) 0 0; font-size: 0.8125rem; line-height: 1.6; color: var(--text-soft);
}
.site-footer__legal a { color: var(--text); }
.prose--legal h3 { font-family: var(--display); font-weight: 300; font-size: 1.375rem; margin: 2rem 0 0.75rem; }
.prose--legal p { max-width: 42rem; }
.site-footer__base {
  margin-top: clamp(2rem, 4vw, 3rem); padding-top: 1.5rem;
  border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 0.75rem 2rem;
  font-size: 0.8125rem; color: var(--text-soft);
}
.site-footer__base .mm { margin-left: auto; }
.site-footer__base .mm a { color: var(--text); }


/* --- interior page scaffolding -------------------------------------------- */
/* Every interior page used to open with a near-black band. Seven pages of that
   is what made the site read dark; the same job — giving the sticky header
   something to sit against so no page starts with a bare H1 — is done by a
   light band and a hairline. */

.pagehead {
  background: var(--mist);
  color: var(--text);
  border-bottom: 1px solid var(--line);
  padding-block: clamp(2.5rem, 5vw, 4rem);
}
.pagehead__inner { max-width: var(--shell); margin-inline: auto; padding-inline: var(--gutter); }

/* O mně opens on the operating photograph, full width. The crop is deliberate:
   every band above y~60% shows the back of a surgical cap rather than her, and
   the composition only reads from the eyes down. The left ~40% of the frame is
   plain wall at 68% luminance, which is where the title sits.

   The wash is white, not black — it lifts the ground under the type instead of
   darkening the picture, which is the whole point of this palette. */
.pagehead--photo {
  position: relative;
  display: flex; align-items: center;
  min-height: clamp(13rem, 24vw, 20rem);
  background-image: image-set(url("../img/hero-operating.676900cceee2.webp") type("image/webp"),
                              url("../img/hero-operating.ba77ccb890d7.jpg") type("image/jpeg"));
  background-size: cover;
  background-position: 60% 70%;
}
.pagehead--photo::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to right,
              rgba(255,255,255,0.90) 0%,
              rgba(255,255,255,0.72) 32%,
              rgba(255,255,255,0) 60%);
}
/* Zákroky uses the abdominal marking photograph — the same frame that banners
   the Tělo procedures. Its left third is soft white bedding, which is where
   the title sits, so it needs a lighter wash than the operating shot does. */
/* Each procedure's gallery opens on its category's photograph — the same frame
   that heads that category on the index and banners its procedure pages. */
.pagehead--cat-oblicej {
  background-image: image-set(url("../img/zakroky/kategorie-oblicej.6e77782b5237.webp") type("image/webp"),
                              url("../img/zakroky/kategorie-oblicej.d12b5c7546b6.jpg") type("image/jpeg"));
  background-position: center 50%;
}
.pagehead--cat-prsa {
  background-image: image-set(url("../img/zakroky/kategorie-prsa.5f34ade0bf22.webp") type("image/webp"),
                              url("../img/zakroky/kategorie-prsa.d761dda7d44b.jpg") type("image/jpeg"));
  background-position: center 50%;
}
.pagehead--cat-telo {
  background-image: image-set(url("../img/zakroky/kategorie-telo.c37021e1e46d.webp") type("image/webp"),
                              url("../img/zakroky/kategorie-telo.5f33c877c271.jpg") type("image/jpeg"));
  background-position: center 55%;
}
/* The "Popis zákroku" link sat in the accent on an accent-washed header and
   was unreadable. Dark ink with a rule under it reads on any of the three. */
.pagehead__links {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 0.75rem 1.75rem; margin-top: 1.4rem;
}
.pagehead__back {
  display: inline-flex; align-items: center; gap: 0.4rem;
  color: var(--text-soft); text-decoration: none;
}
.pagehead__back:hover { color: var(--blue); }

.pagehead__link {
  display: inline-flex; align-items: center; gap: 0.4rem;
  color: var(--ink); text-decoration: none;
  border-bottom: 1px solid var(--ink);
  padding-bottom: 1px;
}
.pagehead__link:hover { color: var(--blue); border-bottom-color: var(--blue); }

/* Před a po opens on the implant frame that banners the Prsa procedures. */
.pagehead--predpo {
  background-image: image-set(url("../img/zakroky/kategorie-prsa.5f34ade0bf22.webp") type("image/webp"),
                              url("../img/zakroky/kategorie-prsa.d761dda7d44b.jpg") type("image/jpeg"));
  background-position: center 50%;
}

.pagehead--zakroky {
  background-image: image-set(url("../img/zakroky/kategorie-telo.c37021e1e46d.webp") type("image/webp"),
                              url("../img/zakroky/kategorie-telo.5f33c877c271.jpg") type("image/jpeg"));
  background-position: center 55%;
}

/* Her own frame for this page: papers being gone through at the counter, with
   a clean pale wall filling the left third — which is exactly where the title
   and its wash sit. */
.pagehead--dokumenty {
  background-image: image-set(url("../img/dokumenty.aabcea96f222.webp") type("image/webp"),
                              url("../img/dokumenty.c4c35f831bce.jpg") type("image/jpeg"));
  background-position: center 42%;
}

/* Its companion frame, shot the same way: notes being taken at the desk, pale
   wall on the left. */
.pagehead--kontakt {
  background-image: image-set(url("../img/kontakt.d3b2168a3069.webp") type("image/webp"),
                              url("../img/kontakt.903cc5bc7b68.jpg") type("image/jpeg"));
  background-position: center 45%;
}


/* Positioned, so it paints above the absolutely-positioned wash. Without this
   the wash covers the heading it exists to support. */
.pagehead--photo .pagehead__inner { position: relative; width: 100%; }

@media (max-width: 46rem) {
  /* Too narrow to lay type on the picture: the eyebrow alone spans 75% of the
     frame, so the wash would have to cover almost all of it and the photograph
     turns into a ghost. The band goes above the title instead — the picture
     stays crisp and the type gets a clean ground. */
  .pagehead--photo {
    display: block;
    background-image: none;
    background-color: var(--mist);
    min-height: 0;
    padding-top: 0;
  }
  .pagehead--photo::before {
    position: static;
    display: block;
    height: 9.5rem;
    margin-bottom: clamp(1.25rem, 5vw, 2rem);
    background: image-set(url("../img/hero-operating.676900cceee2.webp") type("image/webp"),
                          url("../img/hero-operating.ba77ccb890d7.jpg") type("image/jpeg"))
                center 70% / cover no-repeat;
  }
  /* Below the breakpoint the photograph moves into ::before, so a variant that
     only overrides the element's own background-image silently reverts to the
     operating shot here. */
  .pagehead--zakroky::before {
    background: image-set(url("../img/zakroky/kategorie-telo.c37021e1e46d.webp") type("image/webp"),
                          url("../img/zakroky/kategorie-telo.5f33c877c271.jpg") type("image/jpeg"))
                center 55% / cover no-repeat;
  }
  .pagehead--predpo::before {
    background: image-set(url("../img/zakroky/kategorie-prsa.5f34ade0bf22.webp") type("image/webp"),
                          url("../img/zakroky/kategorie-prsa.d761dda7d44b.jpg") type("image/jpeg"))
                center 50% / cover no-repeat;
  }
  .pagehead--cat-oblicej::before {
    background: image-set(url("../img/zakroky/kategorie-oblicej.6e77782b5237.webp") type("image/webp"),
                          url("../img/zakroky/kategorie-oblicej.d12b5c7546b6.jpg") type("image/jpeg"))
                center 50% / cover no-repeat;
  }
  .pagehead--cat-prsa::before {
    background: image-set(url("../img/zakroky/kategorie-prsa.5f34ade0bf22.webp") type("image/webp"),
                          url("../img/zakroky/kategorie-prsa.d761dda7d44b.jpg") type("image/jpeg"))
                center 50% / cover no-repeat;
  }
  .pagehead--cat-telo::before {
    background: image-set(url("../img/zakroky/kategorie-telo.c37021e1e46d.webp") type("image/webp"),
                          url("../img/zakroky/kategorie-telo.5f33c877c271.jpg") type("image/jpeg"))
                center 55% / cover no-repeat;
  }
  .pagehead--dokumenty::before {
    background: image-set(url("../img/dokumenty.aabcea96f222.webp") type("image/webp"),
                          url("../img/dokumenty.c4c35f831bce.jpg") type("image/jpeg"))
                center 42% / cover no-repeat;
  }
  .pagehead--kontakt::before {
    background: image-set(url("../img/kontakt.d3b2168a3069.webp") type("image/webp"),
                          url("../img/kontakt.903cc5bc7b68.jpg") type("image/jpeg"))
                center 45% / cover no-repeat;
  }
}
.pagehead__title {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(2.25rem, 5.5vw, 3.75rem);
  line-height: 1.06; letter-spacing: -0.018em;
  color: var(--ink); margin: 1.1rem 0 0; text-wrap: balance;
}
.pagehead .lede { color: var(--text-soft); margin-top: 1.4rem; }
/* Was --blue-soft, a light tint from when this band was near-black. On the
   light pagehead — and worse, over a photograph — it was invisible. */
.pagehead a { color: var(--blue); }
.crumb { color: var(--text-soft); text-decoration: none; }
.crumb:hover { color: var(--blue); text-decoration: underline; }

.body-band { padding-block: var(--step); }

/* Body copy is near-black. The soft grey is for captions and metadata; using
   it for the article itself made several thousand words of her writing harder
   to read than it needs to be. */
.prose p { margin: 0 0 1.25rem; line-height: 1.8; color: var(--text); max-width: 42rem; }
.prose p:last-child { margin-bottom: 0; }
.prose p:first-of-type { font-size: 1.0625rem; }

/* The boxed panel and the sticky rail are gone: Kontakt was the last page
   using either, and its details now sit inside the warm enquiry panel rather
   than in two bordered boxes floating beside the form. */

/* --- record rows: the index of procedures / documents --------------------- */

/* --- Dokumenty ------------------------------------------------------------

   Her own grouping, flowing down two columns. A group heading is the blue
   accent over a rule, matching the operation headings on the Ceník. */

.docs { padding-block: clamp(2.75rem, 6vw, 4.75rem); }
.docgroup { break-inside: avoid; margin-bottom: clamp(2rem, 4vw, 3.25rem); }
.docgroup__name {
  margin: 0 0 0.75rem;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.375rem, 2vw, 1.625rem); line-height: 1.2;
  letter-spacing: -0.01em; color: var(--blue);
  padding-bottom: 0.6rem; border-bottom: 1px solid var(--line);
}
/* Inside a column the list is one item wide — the two columns are the page's,
   not the list's, and letting `.dl` split again gave four cramped columns. */
.docgroup .dl { grid-template-columns: minmax(0, 1fr); margin-bottom: 0; }

/* The document list is `.dl` everywhere now — the reading face with "Dokument
   Word · 20 kB" under the name. `.records` was the same list set in monospace
   with a bordered language chip, which is how a build tool lists artefacts. */

.group { margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.group__name {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(1.5rem, 3vw, 2rem); line-height: 1.15;
  margin: 0 0 1.25rem; color: var(--ink);
}

/* --- Před a po: one grid, a column per category ----------------------------
   Three independent columns only ever aligned by accident — Obličej ran to
   3019px, Prsa to 2773 and Tělo to 1459, so they stopped at three different
   depths. A single grid with the category as the column and the position as
   the row makes every row share a baseline; a short category leaves empty
   cells, which reads as a grid rather than as stranded columns.

   The three accents are one family, not three brands: her clinical blue, a
   clay taken from the sand ground, and a sage. Each clears AA on white and
   carries white text on itself (5.85 / 5.78 / 5.64). */

.bagrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: clamp(2.5rem, 6vw, 5rem);
  row-gap: clamp(2.5rem, 5vw, 3.5rem);
  align-items: start;
}
.c1 { grid-column: 1; }
.c2 { grid-column: 2; }
.c3 { grid-column: 3; }
.r1 { grid-row: 1; } .r2 { grid-row: 2; } .r3 { grid-row: 3; } .r4 { grid-row: 4; }
.r5 { grid-row: 5; } .r6 { grid-row: 6; } .r7 { grid-row: 7; } .r8 { grid-row: 8; }

/* A hairline down each gutter, spanning every row, so the separation holds
   where one category has run out of procedures and the others have not. */
.bagrid__rail {
  /* The rows here are implicit, so `1 / -1` counts explicit lines only and
     collapses the rail to the header row -- but a fixed `span 20` is worse: it
     CREATES the missing rows, and thirteen empty ones left 822px of blank page
     below the last card. The count comes from the view instead, so the rail
     spans exactly the rows that exist. */
  grid-row: 1 / span var(--barows, 8); align-self: stretch;
  pointer-events: none;
}
.bagrid__rail.c2, .bagrid__rail.c3 {
  border-left: 1px solid var(--line);
  margin-left: calc(-1 * clamp(1.25rem, 3vw, 2.5rem));
}
.bagrid__rail.c1 { display: none; }

:where(.bacol--oblicej, .bacol--prsa, .bacol--telo) { --cat: var(--blue); }
.bacol--oblicej { --cat: #1b6c8f; }
.bacol--prsa    { --cat: #96534a; }
.bacol--telo    { --cat: #46705a; }

.bahead { position: relative; isolation: isolate; overflow: hidden; }
.bahead img {
  display: block; width: 100%;
  height: clamp(7rem, 12vw, 10rem); object-fit: cover; object-position: center 55%;
}
.bahead::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to right,
              color-mix(in srgb, var(--cat) 82%, transparent) 0%,
              color-mix(in srgb, var(--cat) 46%, transparent) 55%,
              color-mix(in srgb, var(--cat) 8%, transparent) 100%);
}
/* "Prsa" was white type on a nearly white photograph and the implant shot is
   framed so wide that the middle banner LOOKED smaller than its neighbours,
   though all three boxes are identical (Kuba, 2026-09-17). A stronger wash in
   the category colour makes every name a heading; the breast photograph is
   zoomed to the same visual weight as the other two. */
.bahead::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: color-mix(in srgb, var(--cat) 38%, transparent);
}
.bahead img { position: relative; }
.bacol--prsa.bahead img { transform: scale(1.75); transform-origin: 62% 46%; }
.bahead__name {
  position: absolute; left: clamp(1rem, 2.2vw, 1.6rem); bottom: clamp(0.7rem, 1.6vw, 1.1rem);
  z-index: 1; margin: 0;
  font-family: var(--display); font-weight: 300;
  font-size: clamp(2rem, 3.6vw, 2.75rem); line-height: 1.05;
  letter-spacing: -0.015em; color: #fff;
  text-shadow: 0 1px 14px rgba(23, 38, 47, 0.45);
}

.baitem { display: grid; gap: 0.45rem; align-content: start; }
.baitem__name {
  margin: 0;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.5rem, 2.4vw, 1.875rem); line-height: 1.15;
  letter-spacing: -0.01em;
}
.baitem__name a { color: var(--cat); text-decoration: none; }
.baitem__name a:hover { text-decoration: underline; }
.baitem__aside {
  font-size: 0.875rem; color: var(--text-soft); text-decoration: none; justify-self: start;
}
.baitem__aside:hover { color: var(--cat); text-decoration: underline; }
.baitem__pair {
  display: grid; grid-template-columns: 1fr; gap: 2px;
  background: var(--line); margin-top: 0.5rem;
}
.baitem__pair img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }
.baitem__cta {
  justify-content: center; margin-top: 0.5rem;
  background: var(--cat); border-color: var(--cat); color: #fff;
}
.baitem__cta:hover { background: var(--ink); border-color: var(--ink); }

@media (max-width: 62rem) {
  /* One column. The explicit placement classes are undone by a later rule of
     equal specificity, so no !important is needed.

     Do NOT write the class names as a glob here: an earlier version of this
     comment said ".c" star "/.r" star, and that slash-star-slash CLOSED THE
     COMMENT two words in. Everything after it parsed as garbage, which ate the
     grid-template-columns line below -- so Před a po never stacked on a phone
     and rendered as three 90px columns on an iPhone. */
  .bagrid { grid-template-columns: 1fr; }
  .bagrid > * { grid-column: 1; grid-row: auto; }
  .bagrid__rail { display: none; }
  .bahead { margin-top: 1.5rem; }
}

/* --- gallery -------------------------------------------------------------- */

.tabs { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: clamp(2rem, 4vw, 3rem); }
.tabs__tab {
  padding: 0.55rem 1.1rem; border: 1px solid var(--line);
  font-size: 0.875rem; color: var(--text); text-decoration: none;
}
.tabs__tab:hover { border-color: var(--blue); color: var(--blue); }

.gcards {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: clamp(1.25rem, 2.5vw, 2rem);
}
.gcard { min-width: 0; }
.gcard__link { display: block; text-decoration: none; color: var(--text); }
.gcard__figure { display: block; overflow: hidden; background: var(--mist); border: 1px solid var(--line); }
.gcard__figure img {
  width: 100%; aspect-ratio: 4 / 5; object-fit: cover;
  transition: transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}
.gcard__link:hover .gcard__figure img { transform: scale(1.04); }
.gcard__name {
  display: block; margin-top: 0.85rem;
  font-family: var(--display); font-size: 1.0625rem; line-height: 1.3;
  overflow-wrap: anywhere;
}
.gcard__link:hover .gcard__name { color: var(--blue); }
.gcard__count {
  display: block; margin-top: 0.25rem;
  font-family: var(--sans); font-size: 0.8125rem; color: var(--text-faint);
}
.gcard__aside { font-size: 0.8125rem; color: var(--text-faint); text-decoration: none; }
.gcard__aside:hover { color: var(--blue); }

/* Before/after: the paired split at its smallest, with the divider labelled. */
.pairs {
  /* Each half was rendering ~188px wide -- too small to read a result in.
     28rem is half again as wide; min() keeps it from overflowing a 320px
     phone, where one pair per row is the right answer anyway. */
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(28rem, 100%), 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
/* No frame around the pair and no tinted panel behind it. A bordered card
   with a grey strip under the photographs read as a UI component; these are
   photographs, and they should sit on the page like photographs. */
.pair { margin: 0; background: transparent; }
/* Sections inside one procedure's gallery (her grouping, 2026-09-09). */
.pairs-section + .pairs-section { margin-top: clamp(2.5rem, 5vw, 4rem); }
.pairs-section__title {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(1.375rem, 2.6vw, 1.75rem); line-height: 1.15;
  margin: 0 0 1.1rem; padding-bottom: 0.6rem; border-bottom: 1px solid var(--line); color: var(--ink);
}
.pair__images { display: grid; grid-template-columns: 1fr 1fr; position: relative; }
.pair__images {
  gap: 2px; background: var(--line);   /* a hairline between the halves */
}
.pair__side { background: var(--paper); }
/* Her gallery photographs are 4:3 landscape (640x480, some 1000x750). A 4:5
   portrait box with object-fit:cover threw away 40% of the width — on a
   blepharoplasty gallery that removed half of each face. contain, so a
   differently-shaped frame letterboxes instead of losing the subject. */
.pair__side img {
  width: 100%; height: auto;
  aspect-ratio: 4 / 3; object-fit: contain;
}
.pair__zoom { display: block; cursor: zoom-in; }
.pair__zoom:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }

/* --- lightbox ------------------------------------------------------------- */

.zoom {
  border: 0; padding: 0; background: transparent;
  max-width: 100vw; max-height: 100vh;
  width: 100%; height: 100%;
  overflow: hidden;
}
.zoom::backdrop { background: rgba(23, 38, 47, 0.88); }
/* Both halves at once, each as large as it can be without cropping. The pair
   is the unit — a lightbox showing one half shows a photograph, not a result. */
.zoom__pair {
  position: absolute; inset: 0;
  display: grid; grid-template-columns: 1fr 1fr;
  align-content: center; justify-items: center;
  gap: clamp(0.5rem, 1.5vw, 1.25rem);
  padding: clamp(1rem, 3vw, 2.5rem);
}
.zoom__side {
  margin: 0; display: grid; gap: 0.5rem;
  justify-items: center; align-content: start;
  width: 100%;
}
/* Both halves the same displayed size. Left to size themselves, a 640px scan
   and a 1000px one came out at different widths side by side and the pair read
   as mismatched rather than as one result. */
.zoom__side img {
  display: block; width: 100%; height: auto;
  max-height: 80vh; object-fit: contain;
}
.zoom__side figcaption {
  font-size: 0.8125rem; letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.82);
}
@media (max-width: 46rem) {
  .zoom__pair { grid-template-columns: 1fr; }
  .zoom__side img { max-height: 38vh; }
}

.zoom__close {
  position: absolute; top: 1rem; right: 1rem; z-index: 2;
  width: 2.75rem; height: 2.75rem;
  display: grid; place-items: center;
  background: rgba(255, 255, 255, 0.92); color: var(--ink);
  border: 0; font-size: 1.5rem; line-height: 1; cursor: pointer;
}
.zoom__close:hover { background: #fff; color: var(--blue); }

/* No "Pred"/"Po" captions: the left-then-right order is the convention, and
   the alt text carries it for anyone who cannot see the photographs. */
.pair figcaption { padding: 0.75rem 0.9rem; font-size: 0.8125rem; color: var(--text-faint); }

/* --- notices, empty states, forms ---------------------------------------- */

.notice {
  padding: 1rem 1.25rem; border-left: 3px solid var(--blue);
  background: var(--mist); font-size: 0.9375rem; color: var(--text-soft);
  margin: 0 0 2rem;
}
.notice--warn { border-left-color: #8a6d1f; background: #fbf4de; color: var(--text); }

.empty {
  border: 1px solid var(--line); background: var(--mist);
  padding: clamp(2rem, 5vw, 3rem); max-width: 44rem;
}
.empty__title { font-family: var(--display); font-weight: 300; font-size: 1.625rem; margin: 0 0 0.8rem; }
.empty p { margin: 0 0 1rem; color: var(--text-soft); line-height: 1.7; }
.empty p:last-child { margin-bottom: 0; }

.form { display: grid; gap: 1.1rem; max-width: 34rem; }
.field { display: grid; gap: 0.4rem; }
.field__label { font-size: 0.8125rem; font-weight: 500; }
.field__input {
  width: 100%; padding: 0.8rem 0.95rem;
  border: 1px solid var(--line); background: var(--paper);
  font: 400 0.9375rem/1.5 var(--sans); color: var(--text);
}
.field__input:focus-visible { border-color: var(--blue); }
.field__error { margin: 0; font-size: 0.8125rem; color: #9a3b2f; }
.field--check { gap: 0.5rem; }
.field__check { display: flex; gap: 0.65rem; align-items: flex-start; font-size: 0.875rem; line-height: 1.55; color: var(--text-soft); }
.field__check input { margin-top: 0.25rem; flex: none; }
.form__errors {
  padding: 0.9rem 1.15rem; border-left: 3px solid #9a3b2f; background: #fbf1ef;
  font-size: 0.9375rem;
}
.form__errors ul { margin: 0; padding-left: 1.1rem; }

/* --- legend (anaesthesia key) --------------------------------------------- */

.legend { border: 0; background: var(--sand); padding: 1.5rem 1.6rem 1.7rem; margin-bottom: clamp(2.5rem, 5vw, 3.5rem); }
.legend__title { font-family: var(--sans); font-size: 1rem; font-weight: 600; letter-spacing: -0.01em; text-transform: none; color: var(--ink); margin: 0 0 1rem; }
.legend__list { margin: 0; display: grid; gap: 0.7rem; }
.legend__row { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 0.9rem; align-items: baseline; }
.legend__row dt { margin: 0; }
.legend__row dd { margin: 0; font-size: 0.9375rem; line-height: 1.55; color: var(--text-soft); }
.legend__row dd b { color: var(--text); font-weight: 500; }

/* --- Ceník ------------------------------------------------------------------

   Structure instead of a table. Each part of the body opens on its own
   photograph — the same three frames that head it on Zákroky and Před a po —
   and its operations run underneath in two columns. White and sand alternate
   so three long lists do not read as one.

   Deliberately NOT cards: a border around each of thirty operations put the
   spreadsheet straight back. Spacing separates them; the only colour is the
   category accent on the operation's name, and the photograph above it. */

/* The masthead and the anaesthesia bar both sit above the page, so a jump to
   #prsa has to clear them or it lands under both. */
.cenik { --rule: var(--line); padding-block: clamp(2.75rem, 6vw, 4.75rem); scroll-margin-top: 9rem; }
.cenik--warm { --rule: #e5d9c9; }

/* The category name alone, over a rule. The accent is carried by the name, so
   the section still reads as its own part of the body without a picture. */
.cathead {
  padding-bottom: clamp(1rem, 2vw, 1.5rem);
  border-bottom: 1px solid var(--rule);
  margin-bottom: clamp(1.75rem, 3.5vw, 2.75rem);
}
.cathead__name {
  margin: 0;
  font-family: var(--display); font-weight: 300;
  font-size: clamp(2.25rem, 4.5vw, 3.5rem); line-height: 1;
  letter-spacing: -0.02em; color: var(--cat);
}

/* Multi-column, NOT a grid. A grid row is as tall as its tallest cell, so a
   one-row block ("Modelace prsou") placed beside a four-row one ("Zvětšení
   prsou") left a hole three price rows deep above "Mužská prsa". Columns flow
   and balance instead, so a short block is followed immediately by the next. */
.pcols {
  columns: 2;
  column-gap: clamp(2.5rem, 5vw, 4.5rem);
  /* Each block carries a bottom margin to separate it from the next; the last
     one in each column has nothing below it, so the margin becomes dead space
     at the foot of the section. Pull it back off. */
  margin-bottom: calc(-1 * clamp(2rem, 4vw, 3.25rem));
}
.pblock {
  break-inside: avoid;
  margin-bottom: clamp(2rem, 4vw, 3.25rem);
}
@media (max-width: 54rem) { .pcols { columns: 1; } }
.pblock__name {
  margin: 0 0 0.5rem;
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.375rem, 2vw, 1.625rem); line-height: 1.2;
  letter-spacing: -0.01em;
}
.pblock__name a { color: var(--cat); text-decoration: none; }
.pblock__name a:hover { text-decoration: underline; }
/* The rule follows the ground: the cool --line disappears on sand. */
.pblock .prices { border-top: 1px solid var(--rule); }
.pblock .price { border-bottom: 1px solid var(--rule); }
.pblock .price:last-child { border-bottom: 1px solid var(--rule); }

/* The closing band ends on its button, so `.section__head`'s bottom margin has
   nothing to separate it from and just deepens the gap before the footer. */
.cenik-close .section__head { margin-bottom: 0; }
.cenik-close .btns { margin-top: 2rem; }

.price-group { margin-bottom: 2rem; }
.price-group__name { font-family: var(--display); font-size: 1.1875rem; font-weight: 400; margin: 0 0 0.4rem; }
.price-group__name a { color: var(--ink); text-decoration: none; }
.price-group__name a:hover { color: var(--blue); }

/* Shown only when we are falling back to every language because hers is not
   complete — so it has to read as information, not as a build tag. */
.dl__lang {
  font-family: var(--sans); font-size: 0.75rem; letter-spacing: 0.01em;
  color: var(--text-soft); border: 1px solid #ddcfbe; padding: 0.1rem 0.4rem;
}

/* --- timeline (O mně) ------------------------------------------------------ */

.timeline { margin: 0; }
.timeline__row {
  display: grid; grid-template-columns: minmax(7rem, 10rem) minmax(0, 1fr);
  gap: 0.35rem 1.75rem; padding: 0.85rem 0; border-bottom: 1px solid var(--line);
}
.timeline__row:last-child { border-bottom: none; }
.timeline__year {
  margin: 0; font-family: var(--display); font-size: 0.9375rem; color: var(--text-soft);
  font-variant-numeric: tabular-nums; min-width: 0; overflow-wrap: anywhere;
}
.timeline__what { margin: 0; min-width: 0; overflow-wrap: anywhere; color: var(--text-soft); line-height: 1.65; }
@media (max-width: 40rem) { .timeline__row { grid-template-columns: 1fr; gap: 0.2rem; } }

/* --- O mně: three columns ---------------------------------------------------
   Portrait and contact | her biography | the CV record. The biography is the
   reading column, so it takes 1fr and the two rails are bounded — a CV entry
   like "2005–2006, 2014–dosud" must not be allowed to set the page's rhythm.
   The rails collapse before the prose does: at 75rem the CV drops under the
   biography, at 60rem everything stacks. */
.about {
  display: grid;
  align-items: start;
  gap: clamp(2rem, 4vw, 4rem);
  /* The rail is sized for the picture it now holds. It used to be 30.5rem to
     give the WIDE portrait some presence, which made the photograph column
     488px — exactly as wide as the biography beside it, and two thirds of
     those pixels were empty wall. With the tight crop the rail needs half
     that, and the measure it hands back takes the bio to its 42rem cap. */
  grid-template-columns: minmax(12rem, 19rem) minmax(0, 1fr) minmax(12rem, 16rem);
  grid-template-areas: "rail bio cv";
}
@media (min-width: 62.0625rem) {
  /* Break out of the shell's gutter — but only by as much free space as there
     is BESIDE the shell. At 1280px the shell already touches the viewport, so
     a full-gutter breakout put her portrait at x=0, glued to the screen edge
     (Marek's laptop, 2026-09-09). 100vw − shell is the free space; below the
     shell's width it is negative and max() clamps it to no breakout at all. */
  .about { margin-inline: calc(-1 * min(var(--gutter), max(0px, (100vw - var(--shell)) / 2))); }
}

.about__rail { grid-area: rail; position: sticky; top: 5.5rem; display: grid; gap: 1.25rem; }
/* The rail is sticky, so it must FIT the viewport or its bottom — the
   consultation button — is simply never visible. 542px of rail below a
   5.5rem offset needs a 630px viewport; a laptop with browser chrome has
   less. Cap the portrait against the viewport height (caption + gap +
   button ≈ 11rem), keeping its 3:4 shape by letting the width follow. */
.about__rail .portrait img { max-height: calc(100vh - 5.5rem - 11rem); width: auto; max-width: 100%; }
@media (max-height: 34rem) { .about__rail { position: static; } }
.about__bio  { grid-area: bio; }
.about__cv   { grid-area: cv; }

@media (max-width: 75rem) {
  /* The rail keeps its column and spans both rows, so her portrait stays
     beside the text she wrote rather than floating above the CV. */
  .about {
    grid-template-columns: minmax(13rem, 16rem) minmax(0, 1fr);
    grid-template-areas: "rail bio" "rail cv";
  }
}
@media (max-width: 60rem) {
  .about { grid-template-columns: 1fr; grid-template-areas: "rail" "bio" "cv"; }
  .about__rail { position: static; }
  /* Stacked, the rail is the full column, and a 3:4 portrait at full width is
     a metre of face before a word of her writing — 810x1079 at a 900px
     viewport. The wide crop used to hide this by being half as tall. */
  .about__rail .portrait { max-width: 20rem; }
}

/* .prose caps the measure at 42rem and that cap stays: in the three-column
   layout the column is narrower than the cap anyway, and once the CV drops
   below at 75rem the bio would otherwise stretch to ~100 characters a line. */
.about__cta { justify-self: start; }

/* CV rail: the section headings and rows are reference material and must not
   compete with the biography beside them. A viewport media query cannot do
   this — the column is narrow at 1440px too, which is exactly when .timeline's
   two-column year/description grid pinches the description to a few words. */
.group--compact { margin-bottom: clamp(1.75rem, 3vw, 2.5rem); }
.group__name--rail { font-size: 1.125rem; letter-spacing: 0.01em; margin-bottom: 0.75rem; }
.timeline--stacked .timeline__row { grid-template-columns: 1fr; gap: 0.2rem; padding: 0.65rem 0; }
.timeline--stacked .timeline__what { font-size: 0.9375rem; line-height: 1.55; }
/* Memberships: a list of names, set as a list. The pill treatment made seven
   society names look like filter tags on a shop, and the rounded ends were the
   most generated-looking thing on the page. Hairline rules and a small square
   marker in the accent instead. */
.societies-group { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.societies {
  list-style: none; margin: 1.1rem 0 0; padding: 0;
  columns: 2; column-gap: clamp(1.5rem, 3vw, 2.5rem);
}
.societies li {
  break-inside: avoid;
  position: relative;
  padding: 0.62rem 0 0.62rem 1.15rem;
  border-top: 1px solid var(--line);
  color: var(--text-soft);
  font-size: 0.9375rem; line-height: 1.5;
}
.societies li::before {
  content: ""; position: absolute; left: 0; top: 1.08rem;
  width: 5px; height: 5px; background: var(--blue);
}
@media (max-width: 46rem) { .societies { columns: 1; } }

/* Where she operates: three clinics, set like the memberships — hairline
   rules, the small square marker — never cards, never pills, never a map. */
.venues-group { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.venues {
  list-style: none; margin: 1.1rem 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 clamp(1.5rem, 3vw, 2.5rem);
}
.venue {
  position: relative; display: flex; flex-direction: column; gap: 0.15rem;
  padding: 0.75rem 0 0.9rem 1.15rem;
  border-top: 1px solid var(--line);
  font-size: 0.9375rem; line-height: 1.5;
}
.venue::before {
  content: ""; position: absolute; left: 0; top: 1.2rem;
  width: 5px; height: 5px; background: var(--blue);
}
.venue__name { color: var(--ink); font-weight: 500; text-decoration: none; }
.venue__name:hover, .venue__name:focus-visible { color: var(--blue); text-decoration: underline; }
.venue__address { color: var(--text-soft); }
.venue__since { color: var(--text-soft); font-size: 0.8125rem; }
.venues__note { margin: 1rem 0 0; color: var(--text-soft); font-size: 0.9375rem; line-height: 1.55; }
@media (max-width: 46rem) { .venues { grid-template-columns: 1fr; } }

.panel__text { margin: 0; color: var(--text-soft); font-size: 0.9375rem; }

.portrait { margin: 0; }
.portrait img {
  width: 100%;
  /* height:auto is load-bearing. <img width height> maps to a CSS
     presentational hint, so setting only width leaves the height hint in
     force: her 3:2 portrait was drawn into an 800px-tall box and smeared
     1.8x vertically. Author styles beat the width hint but nothing was
     overriding the height one. */
  height: auto;
  border: 1px solid var(--line);
}
.portrait figcaption { margin-top: 0.8rem; font-family: var(--display); font-size: 1rem; color: var(--text); }
.portrait figcaption span { display: block; font-family: var(--sans); font-size: 0.8125rem; color: var(--text-faint); margin-top: 0.15rem; }

/* A chip that is a link. The societies list on O mně uses plain chips and must
   stay plain — same shape, different content. */
.chip--link { text-decoration: none; transition: border-color 0.15s, color 0.15s; }
.chip--link:hover { border-color: var(--blue); color: var(--blue); }
.chips li { display: flex; }

/* A group following prose or another group needs air above it; without this
   "Cena" sits directly on the last line of her description. */
.prose + .group,
.group + .group { margin-top: clamp(2.5rem, 5vw, 3.75rem); }

/* The imported information sheet: her own poučení, several thousand words.
   Long-form reading needs a measure and headings that break the wall of text. */
.prose--lead p:first-of-type { font-size: 1.125rem; color: var(--text); }
.sheet { margin-top: clamp(2rem, 4vw, 3rem); }
.sheet h3 {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.25rem, 2.4vw, 1.5rem); line-height: 1.2;
  color: var(--ink); margin: 2.25rem 0 0.9rem;
}
.sheet h3:first-child { margin-top: 0; }
.sheet p { max-width: none; }

/* --- article layout: full width, no rail ----------------------------------
   The procedure page is a long read — several thousand words of her own
   writing. It gets the whole page, a wide measure and a banner, rather than a
   thin column beside a sidebar. The things that were in the rail (price,
   documents, links) are sections in the flow instead. */

.article { max-width: 68rem; margin-inline: auto; padding-inline: var(--gutter); }
.article .prose p { max-width: none; }

.banner {
  position: relative;
  height: clamp(16rem, 34vw, 26rem);
  overflow: hidden;
  background: var(--mist);
}
.banner img { width: 100%; height: 100%; object-fit: cover; }
/* The reference cuts its banner on a diagonal. Same idea, shallower angle —
   it stops the photograph ending on a hard horizontal rule. */
.banner::after {
  content: "";
  position: absolute; left: 0; right: 0; bottom: -1px;
  height: clamp(2rem, 5vw, 4.5rem);
  background: var(--paper);
  clip-path: polygon(0 100%, 100% 0, 100% 100%);
}

.article__intro { padding-block: clamp(1.75rem, 4vw, 2.75rem) clamp(1rem, 2vw, 1.5rem); }
.article__title {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(2rem, 5vw, 3.25rem); line-height: 1.06;
  letter-spacing: -0.018em; margin: 0.9rem 0 0; color: var(--ink);
  text-wrap: balance;
}
.article__standfirst {
  margin: 1.5rem 0 0; font-size: clamp(1.0625rem, 1.5vw, 1.25rem);
  line-height: 1.6; color: var(--text); font-weight: 500; max-width: 46rem;
}

/* --- wide article + section reader ---------------------------------------
   The procedure page uses most of the screen. A 68rem centred column wasted
   half a desktop on a page whose whole job is dense reference reading. */

.wide { max-width: 106rem; margin-inline: auto; padding-inline: var(--gutter); }

.reader {
  display: grid;
  grid-template-columns: minmax(15rem, 20rem) minmax(0, 1fr);
  gap: clamp(1.5rem, 3vw, 3rem);
  align-items: start;
  padding-bottom: clamp(3rem, 6vw, 5rem);
}

.reader__nav { position: sticky; top: 5.5rem; }
.reader__nav .reader__navtitle { margin-top: 0; }
.reader__navtitle {
  font-family: var(--sans); font-size: 0.8125rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--blue);
  margin: 0 0 1.1rem;
}
.reader__list { list-style: none; margin: 0; padding: 0; counter-reset: chapter; }
.reader__list li { counter-increment: chapter; }
.reader__list a {
  display: grid; grid-template-columns: 2rem minmax(0, 1fr);
  gap: 0.55rem; align-items: baseline;
  padding: 0.85rem 0.7rem 0.85rem 0;
  border-bottom: 1px solid var(--line);
  color: var(--text-soft); text-decoration: none;
  font-size: 1.0625rem; line-height: 1.45;
  transition: color 0.15s, background 0.15s, padding-left 0.15s;
}
.reader__list a::before {
  content: counter(chapter, decimal-leading-zero);
  font-family: var(--display); font-size: 0.875rem; color: var(--text-faint);
  font-variant-numeric: tabular-nums;
}
.reader__list a:hover { color: var(--ink); background: var(--mist); padding-left: 0.5rem; }
.reader__list a[aria-current="true"] { color: var(--ink); font-weight: 500; }
.reader__list a[aria-current="true"]::before { color: var(--blue); }
.reader__list a[aria-current="true"] { border-bottom-color: var(--blue); }



.chapter { min-width: 0; }
.chapter__title {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(1.625rem, 3vw, 2.25rem); line-height: 1.12;
  letter-spacing: -0.012em; color: var(--ink); margin: 0 0 1.5rem;
}
/* No multi-column. It balanced badly — the second column ran longer than the
   first — and reading a column that forces you to scroll back up to continue is
   worse than a slightly wider measure. A single column with a capped measure and
   figures floated into it reads the way an article should. */
.chapter .sheet { max-width: 62rem; }
.chapter .sheet p { max-width: none; }

.figure { margin: 0 0 1.25rem; }
.figure img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  background: var(--mist);
}
.figure figcaption { margin-top: 0.5rem; font-size: 0.8125rem; color: var(--text-faint); }

/* Floated so her writing wraps around the illustration it describes. */
/* Every figure inside the sheet floats into the text, always on the same side.
   Styled off the ELEMENT, not a class: clean_richtext strips class attributes
   from stored HTML, so a .figure--float selector would never match anything
   that came out of the database.

   Alternating sides read as accidental rather than rhythmic, and it left the
   reader hunting for where the text continued. */
.chapter .sheet figure {
  margin: 0 0 1.25rem;
}
.chapter .sheet figure img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  background: var(--mist);
}
@media (min-width: 46rem) {
  .chapter .sheet figure {
    float: right;
    /* Narrower than before: with the nav on one side and her portrait on the
       other, a 38% figure left the text column too thin to read. */
    width: min(17rem, 32%);
    margin: 0.35rem 0 1.5rem 2rem;
    shape-outside: margin-box;
  }
}
/* A before/after pair at the end of a sheet (Marek, 2026-09-21: "před vlevo,
   po vpravo"): one figure holding two images. Structure-selected for the same
   reason as above — no class survives the sanitizer. */
.chapter .sheet figure:has(> img + img) {
  float: none;
  clear: both;
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin: 1.75rem 0 2rem;
  shape-outside: none;
}
.chapter .sheet figure:has(> img + img) figcaption {
  grid-column: 1 / -1;
  font-size: 0.85rem;
  color: var(--ink-soft, #5a6570);
}
/* Stop a float from escaping its section and colliding with the next heading. */
.chapter::after { content: ""; display: table; clear: both; }

/* Without JS every chapter is visible in order. The script adds this class. */
.reader--enhanced .chapter { display: none; }
.reader--enhanced .chapter.is-current { display: block; }

@media (max-width: 60rem) {
  .reader { grid-template-columns: 1fr; }
  .reader__nav { position: static; }
  .chapter .sheet { columns: auto; }
}

/* --- surgeon card beside the opening text -------------------------------- */

/* The whole article is one grid: intro top-left, content directly beneath it,
   and her portrait in a right-hand column that spans BOTH rows. Keeping the
   portrait inside the header made the header as tall as the taller column, so
   a short intro left a band of dead space above the content. */
.wide {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(13rem, 16rem);
  column-gap: clamp(1.75rem, 3.5vw, 3rem);
  align-items: start;
}
.article__intro { grid-column: 1; grid-row: 1; min-width: 0; }
.surgeon { grid-column: 2; grid-row: 1 / span 2; position: sticky; top: 5.5rem; }
.wide > .reader { grid-column: 1; grid-row: 2; }

@media (max-width: 70rem) {
  .wide { grid-template-columns: 1fr; }
  .article__intro, .surgeon, .wide > .reader { grid-column: 1; grid-row: auto; }
  .surgeon { position: static; max-width: 20rem; }
}

.surgeon { display: grid; gap: 0.4rem; }
.surgeon__photo {
  width: 100%;
  height: auto;
  border: 1px solid var(--line);
  background: var(--mist);
}
.surgeon__name {
  margin: 0.75rem 0 0;
  font-family: var(--display);
  font-size: 1.0625rem;
  line-height: 1.25;
  color: var(--ink);
}
.surgeon__role {
  margin: 0;
  font-family: var(--sans);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.surgeon__cta { margin-top: 0.9rem; justify-content: center; text-align: center; }

@media (max-width: 60rem) {
  .article__head { grid-template-columns: 1fr; }
  /* Photo first on a phone would push the title below the fold, so the text
     keeps its place and the card follows it. */
  .surgeon { max-width: 20rem; }
}

/* The note above a sheet that exists only in Czech (six Italian operations she
   never wrote). Quiet, not an error: the text below it is still useful, and a
   browser's translate offer works on it because the block carries lang="cs". */
.sheet-lang {
  max-width: 62ch;
  margin: 0 0 1.5rem;
  padding: 0.75rem 1rem;
  border-left: 3px solid var(--line);
  background: var(--sand-soft, #f6efe6);
  color: var(--text-soft);
  font-size: 0.95rem;
}
