/* ==========================================================================
   components.css — implementace komponent design systému
   --------------------------------------------------------------------------
   Zrcadlí design-system/atoms|molecules|organisms/*.md.
   Všechny barvy a typografie jdou přes tokens.css. Hodnota, která tady stojí
   natvrdo, musí mít komentář s odkazem do MD specu — jinak tam nemá co dělat.

   Mapování class → spec vede docs/component-registry.md.
   ========================================================================== */

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

/* ==========================================================================
   BUTTON — design-system/atoms/button.md
   ==========================================================================

   Border model (button.md → "Button — border model", ověřeno ve Figmě):
   stroke je INSIDE-aligned, vnější výška zůstává 56px ve všech stavech
   a border ujídá z vnitřního boxu. `box-sizing: border-box` + reálný
   `border-width` per stav tohle reprodukují 1:1 — proto se border NESMÍ
   přeložit na `outline` ani `box-shadow`, obojí by kreslilo vně a rozbilo
   jak geometrii, tak odsazení ikon.

   Priorita stavů (NAŠE rozhodnutí — button.md ji nedefinuje, viz
   review-backlog #4): disabled > answered > active > focus-visible > hover.
   V CSS je vynucená pořadím pravidel a `:not()` guardy níž.
   -------------------------------------------------------------------------- */

.dd-btn {
  /* Padding se váže na proměnnou, aby "padding" a "ikona je odsazená
     o padding" nebyly dvě nezávislé hodnoty — button.md na tuhle vazbu
     explicitně upozorňuje. */
  --dd-btn-padding: var(--space-16);

  /* --- anatomie: button.md → "Button — anatomie" --- */
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 56px;                     /* button.md → Height */
  padding: var(--dd-btn-padding);    /* button.md → Padding */
  border-radius: var(--radius-12);   /* button.md → Border radius */

  /* Border je vždy deklarovaný jako solid, šířku řídí varianta/stav.
     Default = 0, protože Primary/Default žádný stroke nemá (ověřeno
     na node 2499:1667). */
  border-style: solid;
  border-width: 0;

  /* Label font: button.md → "Label font" = Poppins Bold 14/22.
     Pozor, tohle NENÍ žádný styl z typography.md — nejblíž je Body3
     (14px), ale ten má line-height 18px, ne 22px. Je to vlastní
     kombinace specifická pro button, proto se nepoužije .t-* utilita. */
  font-family: var(--font-primary);
  font-size: 14px;
  line-height: 22px;
  font-weight: var(--weight-bold);
  letter-spacing: var(--letter-spacing);

  /* Content-hug: button.md → Poznámky říká, že 305px z Figmy je jen demo
     šířka labelu, ne token. Reálné tlačítko obaluje obsah. */
  width: auto;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* Vnitřní wrapper — v Figmě vrstva "Button inside".
   Drží label na střed a slouží jako pozicovací kontext pro ikony:
   jeho hrany JSOU vnitřní hrany paddingu, takže `left: 0` / `right: 0`
   na ikoně = odsazení přesně o padding, bez druhého magického čísla. */
.dd-btn__inside {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  flex-shrink: 0;
}

/* Label vyplní zbylou šířku a je na střed.
   button.md: "není tu žádná samostatná gap hodnota mezi ikonou a labelem". */
.dd-btn__label {
  flex: 1 0 0;
  min-width: 0;
  text-align: center;
  word-break: break-word;
}

/* ⚠️ ZÁPLATA MEZERY VE SPECU — viz review-backlog #25.
   button.md tvrdí dvě věci, které si u krátkého labelu odporují:
   (1) ikony jsou absolutně pozicované na hranu paddingu,
   (2) tlačítko je content-hug (305px z Figmy je jen demo šířka).
   Absolutně pozicovaná ikona je mimo flow, takže si nerezervuje místo —
   při content-hug se tlačítko zúží na šířku labelu a ikony na label
   nalezou. Ve Figmě se to neprojeví, protože všechny vzorky mají
   natvrdo 305px.

   Řešení: label si rezervuje 24px z každé strany, kde ikona je.
   24px NENÍ nové číslo — je to icon slot z button.md. Žádný gap se
   nepřidává (spec explicitně říká, že gap neexistuje).
   Na širokém tlačítku je výsledek vizuálně identický s Figmou: label je
   pořád centrovaný a rezerva je symetrická, takže se střed nehýbe. */
.dd-btn__inside:has(> .dd-btn__icon--leading) .dd-btn__label { padding-left: 24px; }
.dd-btn__inside:has(> .dd-btn__icon--trailing) .dd-btn__label { padding-right: 24px; }

/* Icon slot 24×24 — button.md → Icon size.
   Absolutní pozicování na hrany wrapperu, vertikálně vycentrované.
   `overflow: hidden` odpovídá `overflow-clip` z Figma exportu. */
.dd-btn__icon {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 24px;
  height: 24px;
  overflow: hidden;
  flex-shrink: 0;
  /* Barva ikony = barva labelu. Ověřeno v Figmě (button.md → Poznámky).
     Proto inline SVG s fill="currentColor", ne <img> — obrázek by barvu
     dědit neumí. */
  color: inherit;
}
.dd-btn__icon > svg { display: block; width: 100%; height: 100%; }

.dd-btn__icon--leading  { left: 0; }
.dd-btn__icon--trailing { right: 0; }

/* --------------------------------------------------------------------------
   BUTTON — varianty × stavy
   Zdroj: button.md → tabulka "Button — Variant × State". Ta tabulka je
   zdroj pravdy; pořadí pravidel tady kopíruje prioritu stavů výš.
   -------------------------------------------------------------------------- */

/* ---- Primary ---- */
.dd-btn--primary {
  background: var(--highlight);
  color: var(--user-bcg);
  border-width: 0;
}

/* ---- Secondary ---- */
.dd-btn--secondary {
  background: var(--white);
  color: var(--highlight);
  border-width: 2px;
  border-color: var(--highlight);
}

/* ---- Tertiary ---- */
.dd-btn--tertiary {
  background: transparent;
  color: var(--highlight);
  border-width: 0;
}

/* ---- Hover — identický napříč všemi 3 variantami ----
   button.md: "Hover a Pressed splývají napříč variantami".
   Border má SCHVÁLNĚ stejnou barvu jako pozadí — není to glow, ale
   rezervovaná geometrie, aby přechod Hover↔Focus nehýbal labelem.

   ⚠️ U Primary je tenhle stav vizuálně k nerozeznání od Default
   (known issue B2 v button.md). Reprodukuju to věrně, protože doc má
   odpovídat zdroji — ne protože je to správné UX.

   ⚠️ ZA `@media (hover: hover)` SCHVÁLNĚ. Bez toho iOS „sticky hover"
   nechá Hover viset na prvku, přes který jen projel prst — při stahování
   sheetu se buttony rozsvěcely na plnou Highlight barvu (nahlásil David
   2026-07-27). Hover JE pointer stav, na touch zařízení nemá co dělat;
   `pointer: fine` navíc vyloučí hrubý pointer (stylus, TV remote). */
@media (hover: hover) and (pointer: fine) {
  .dd-btn:not([disabled]):not([data-answered]):hover {
    background: var(--highlight);
    color: var(--user-bcg);
    border-width: 4px;
    border-color: var(--highlight);
  }
}

/* ---- Focus — přidává 4px Content obrys, zachovává barvy varianty ----
   Použit `:focus-visible`, ne `:focus`. button.md tenhle rozdíl neřeší
   (review-backlog #16), takže je to NAŠE rozhodnutí: `:focus-visible`
   nezobrazí obrys po kliknutí myší, jen při klávesové navigaci, což je
   dnešní standard. Kdyby design chtěl obrys i po kliknutí, změna je tady.

   ⚠️ known issue B1 v button.md: u Primary má tenhle obrys kontrast
   1.54:1 vůči vlastnímu fillu. Reprodukuju podle specu, neopravuju. */
.dd-btn:not([disabled]):not([data-answered]):focus-visible {
  border-width: 4px;
  border-color: var(--content);
  outline: none;   /* nahrazujeme nativní outline vlastním borderem ze specu */
}
.dd-btn--primary:not([disabled]):not([data-answered]):focus-visible {
  background: var(--highlight);
  color: var(--user-bcg);
}
.dd-btn--secondary:not([disabled]):not([data-answered]):focus-visible {
  background: var(--white);
  color: var(--highlight);
}
.dd-btn--tertiary:not([disabled]):not([data-answered]):focus-visible {
  background: transparent;
  color: var(--highlight);
}

/* ---- Pressed — jako Hover, ale BEZ borderu ----
   Splývá napříč variantami. Stojí za :hover/:focus-visible, protože
   podle naší priority stavů vyhrává nad oběma. */
.dd-btn:not([disabled]):not([data-answered]):active {
  background: var(--highlight);
  color: var(--user-bcg);
  border-width: 0;
}

/* ---- Answerred → v kódu `data-answered` ----
   Je to APLIKAČNÍ stav (uživatel už odpověděl/vybral), ne interakční —
   proto data-atribut a ne pseudo-class (review-backlog #2).
   Splývá napříč variantami: všechny 3 dostanou cream/navy look.

   Poznámka k pravopisu: varianta ve Figmě se jmenuje "Answerred"
   (dvě r). V kódu používám `data-answered`, protože zabetonovat překlep
   do API komponenty by ho šířilo dál. Vazba na zdroj je tady v komentáři
   a v docs/component-registry.md. Přejmenování ve Figmě neřeším sám. */
.dd-btn[data-answered] {
  background: var(--user-bcg);
  color: var(--content);
  border-width: 0;
}

/* ---- Disabled — absolutní priorita, poslední pravidlo ----
   Nativní `disabled` atribut (ne aria-disabled): tlačítko má být
   skutečně nefokusovatelné a neklikatelné. Nízký kontrast Disabled
   (2.35:1) je legitimní WCAG 1.4.3 výjimka pro neaktivní komponenty. */
.dd-btn[disabled] {
  cursor: not-allowed;
  pointer-events: none;
}
.dd-btn--primary[disabled] {
  background: var(--disabled);
  color: var(--white);      /* pozor: Primary/Disabled má White, ne User bcg */
  border-width: 0;
}
.dd-btn--secondary[disabled] {
  background: var(--white);
  color: var(--disabled);
  border-width: 2px;
  border-color: var(--disabled);
}
.dd-btn--tertiary[disabled] {
  background: transparent;
  color: var(--disabled);
  border-width: 0;
}

/* --------------------------------------------------------------------------
   BUTTON INLINE — button.md → "Button inline — anatomie"
   Textové/link-styl tlačítko. Bez pevné výšky a paddingu, obaluje obsah.
   Ve Hover/Pressed/Focus dostává pill (stadium) pozadí.
   -------------------------------------------------------------------------- */

.dd-btn-inline {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);      /* button.md → Layout gap. spacing.md už existuje,
                               ale sám přiznává, že to není potvrzená scale —
                               8px je tam vedený jako pozorovaná hodnota. */
  border: none;
  background: transparent;
  color: var(--highlight);
  cursor: pointer;

  /* Label font stejný jako Button: Poppins Bold 14/22. */
  font-family: var(--font-primary);
  font-size: 14px;
  line-height: 22px;
  font-weight: var(--weight-bold);
  letter-spacing: var(--letter-spacing);

  /* Pill: button.md říká "radius = height/2", ale height komponenty není
     definovaná (je content-hug). Stadium tvar je matematicky ten samý
     výsledek pro jakoukoli výšku, takže se tím obchází nedefinovaná hodnota
     místo jejího hádání (review-backlog #11). */
  border-radius: var(--radius-full);

  /* Inset se mění per stav (14px Hover / 10px Pressed+Focus).
     Default pilulku nemá vůbec → 0. */
  padding: 0;
}

.dd-btn-inline__icon {
  display: block;
  width: 24px;              /* button.md → Icon size */
  height: 24px;
  flex-shrink: 0;
  color: inherit;
}
.dd-btn-inline__icon > svg { display: block; width: 100%; height: 100%; }

/* ---- Hover: pill s insetem 14px ----
   button.md: Hover má znatelně větší inset než Pressed/Focus, ověřeno
   ze zdroje, není to překlep.
   `@media (hover: hover)` ze stejného důvodu jako u Buttonu výš. */
@media (hover: hover) and (pointer: fine) {
  .dd-btn-inline:not([disabled]):hover {
    background: var(--highlight);
    color: var(--user-bcg);
    padding: 14px;
  }
}

/* ---- Focus: pill s Highlight @ 30% ----
   ⚠️ "@ 30%" není v colors.md token (review-backlog #10) a spec neříká,
   jestli jde o alphu na fillu, nebo opacity na celém elementu. Tabulka
   v button.md uvádí text/ikonu jako plný Highlight, což by opacity na
   celém elementu zeslabila — proto to implementuju jako ALPHU NA FILLU.
   Je to odvození z tabulky, ne potvrzený fakt; při doplnění tokenu
   nahradit za var(). */
.dd-btn-inline:not([disabled]):focus-visible {
  background: color-mix(in srgb, var(--highlight) 30%, transparent);
  color: var(--highlight);
  padding: 10px;
  outline: none;
}

/* ---- Pressed: pill s insetem 10px ---- */
.dd-btn-inline:not([disabled]):active {
  background: var(--highlight);
  color: var(--user-bcg);
  padding: 10px;
}

/* ---- Disabled: bez pozadí ----
   button.md nedefinuje pro Button inline stav Answerred vůbec
   (review-backlog #19) — nedoplňuju ho, mezera ve specu se nezaplňuje
   dohadem. */
.dd-btn-inline[disabled] {
  color: var(--disabled);
  background: transparent;
  padding: 0;
  cursor: not-allowed;
  pointer-events: none;
}

/* ==========================================================================
   STAGE — kontejner obrazovky
   --------------------------------------------------------------------------
   Obrazovky v Application souboru jsou fixní kompozice 393×852 s absolutními
   pozicemi, ne flow layouty. Stage tu geometrii drží, aby se čísla ze Figmy
   dala použít přímo a nemusela se přepočítávat.

   ⚠️ 393px je REFERENČNÍ šířka Figmy, NE strop layoutu.
   Davidovo rozhodnutí (2026-07-27): na telefonu má obrazovka vyplnit plnou
   šířku — na iPhonu 17 Pro Max (440px) není důvod nechávat po stranách
   krémové pruhy. Klamp na 393px proto platí jen od 640px výš, kde už jde
   o náhled na desktopu a telefonní tvar rámce je informace sama o sobě.

   Výška je `100dvh`, ne fixních 852px. Dva důvody: (1) footer je ukotvený
   k viewportu, takže stránka nesmí scrollovat pod ním; (2) `dvh` na mobilu
   respektuje chrome prohlížeče, `vh` ne — viz komentář u `.dd-doctor-panel`.

   Prvky ukotvené k `top` zůstávají na svých souřadnicích, prvky ukotvené
   k `bottom` se drží dole.
   ========================================================================== */

.dd-stage {
  position: relative;
  width: 100%;
  min-height: 100vh;   /* fallback pro prohlížeče bez dvh */
  margin: 0 auto;
  overflow: hidden;
  font-family: var(--font-primary);
  color: var(--content);
}

@supports (height: 1dvh) {
  .dd-stage { min-height: 100dvh; }
}

/* Nad 640px už to není telefon — vrátit referenční šířku, ať je náhled
   na desktopu pořád telefonního tvaru a čísla ze Figmy platí 1:1. */
@media (min-width: 640px) {
  .dd-stage { max-width: var(--screen-width); }
}

/* ==========================================================================
   AVATAR — design-system/atoms/avatar.md
   ==========================================================================

   Border je stejně jako u Buttonu inside-aligned: vnější rozměr zůstává
   64px bez ohledu na obrys. Proto `box-sizing: border-box` a reálný
   `border`, ne `outline`.
   -------------------------------------------------------------------------- */

.dd-avatar {
  --dd-avatar-size: 64px;
  --dd-avatar-ring-width: 3px;
  --dd-avatar-ring-color: var(--white);   /* avatar.md → Default = Light #FFFFFF */

  position: relative;
  display: block;
  width: var(--dd-avatar-size);
  height: var(--dd-avatar-size);
  flex-shrink: 0;
  padding: 0;
  border: none;
  background: none;
  /* Badge musí přetékat přes hranu → avatar sám neklipuje. */
  overflow: visible;
  cursor: pointer;
}

/* Rámeček s fotkou. Musí být vlastní element, protože klipování fotky
   na radius (`overflow: hidden`) a přetékání badge (`overflow: visible`)
   nejdou na jednom elementu současně. */
.dd-avatar__frame {
  position: absolute;
  inset: 0;
  border-radius: var(--radius-16);      /* avatar.md → Border radius */
  overflow: hidden;
  background: var(--disabled-light);    /* podklad, než se fotka načte */
}

/* Obrys jako inset box-shadow, NE jako `border`. Dva důvody:
   1. avatar.md: obrys je inside-aligned a kreslí se PŘES fotku. `border`
      by fotku odsunul dovnitř, inset shadow ji překryje — to je věrnější.
   2. `border` by zmenšil padding box z 64 na 58px, a všechny procentuální
      hodnoty z Figmy (crop fotky, ukotvení badge) jsou vztažené k 64px.
      S borderem by byly systematicky o 3px vedle — což byla první verze
      téhle komponenty a projevilo se to jako badge posunutý nízko. */
.dd-avatar__frame::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 var(--dd-avatar-ring-width) var(--dd-avatar-ring-color);
  pointer-events: none;
}

.dd-avatar__photo {
  display: block;
  width: 100%;
  height: 100%;
  /* Výchozí chování. Figma u dvou ze tří avatarů používá přesně tohle
     (`object-cover size-full`); třetí má vlastní crop — viz modifikátor níž. */
  object-fit: cover;
  object-position: center;
}

/* ---- Vlastní crop ----
   Figma u některých fotek nepoužívá `cover`, ale konkrétní zoom a offset
   (u matky 191,79 % × 127,78 % při left −53,01 %, což je výrazně větší
   zoom než cover). Rozměry se zadávají inline z dat, protože jsou per
   fotka — viz mock-data.js → photoCrop.

   `object-fit: fill` je tady správně, ne chyba: procenta z Figmy poměr
   stran zachovávají (191,79/127,78 = 1,501 = poměr zdrojové fotky
   740/493), takže se nic nedeformuje. */
.dd-avatar__photo--crop {
  position: absolute;
  width: auto;
  height: auto;
  max-width: none;
  object-fit: fill;
}

/* ---- Health status ----
   avatar.md: zelený obrys je ZDRAVOTNÍ STAV, ne selection. Data-driven
   vlastnost, proto data-atribut a ne pseudo-class. */
.dd-avatar[data-health="positive"] {
  --dd-avatar-ring-color: var(--positive);
}

/* ---- Focus ----
   avatar.md: zdroj NEDEFINUJE žádný hover/pressed/focus stav.
   Tenhle obrys je NAŠE řešení, ne spec — bez něj by obrazovka byla
   klávesnicí neovladatelná. Použit `outline`, protože kreslí vně a
   nekoliduje s obrysem, který nese zdravotní stav. */
.dd-avatar:focus-visible {
  outline: 3px solid var(--content);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   AVATAR BADGE
   Ukotvení: spodní hrana avataru, vodorovně na střed.
   Souřadnice z avatar.md → Badge. Protože avatar nemá `border`, je
   `top: 100%` přesně jeho spodní hrana — žádná kompenzace není potřeba.
   -------------------------------------------------------------------------- */

.dd-avatar__badge {
  position: absolute;
  left: 50%;
  top: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;   /* badge nesmí krást klik avataru */
}

/* ---- Status dot ----
   avatar.md: viditelný fill 12px + 3px bílý obrys vně = 18px celkem.
   `border-box` (globální reset) + 18px + 3px border dá přesně 12px
   viditelného fillu. Střed 2px pod spodní hranou avataru. */
.dd-avatar__badge--dot {
  width: 18px;
  height: 18px;
  border: 3px solid var(--white);
  border-radius: var(--radius-full);
  background: var(--warning);   /* avatar.md → Status dot = Status/Warning */
  transform: translate(-50%, calc(-50% + 2px));
}

/* ---- Message badge ----
   avatar.md: 36px kruh, bg User bcg, ikona 20px v barvě Content,
   padding 8px. Střed 3px pod spodní hranou avataru. */
.dd-avatar__badge--message {
  width: 36px;
  height: 36px;
  padding: var(--space-8);
  border-radius: var(--radius-full);
  background: var(--user-bcg);
  color: var(--content);        /* ikona dědí přes currentColor */
  transform: translate(-50%, calc(-50% + 3px));
}

.dd-avatar__badge--message > svg { display: block; width: 20px; height: 20px; }

/* ==========================================================================
   USER SELECTOR — design-system/organisms/user-selector.md
   ========================================================================== */

.dd-user-selector {
  display: flex;
  align-items: center;
  gap: var(--space-18);   /* user-selector.md → Gap */
}

/* Reset, aby avatar-jako-button nevypadal jako tlačítko prohlížeče.
   Každý avatar je samostatně klikatelný — Figma export vrací celou řadu
   jako jeden <a>, ale to je artefakt prototypovacího linku, ne návrh
   (user-selector.md → Chování). */
.dd-user-selector .dd-avatar {
  appearance: none;
  -webkit-tap-highlight-color: transparent;
}

/* ==========================================================================
   LOGO — design-system/atoms/logo.md
   --------------------------------------------------------------------------
   Jeden SVG asset, ne skládačka ze tří dílů. Barvy jsou v assetu natvrdo —
   logo je vždy tříbarevné a podle stavu se nemění.
   ========================================================================== */

.dd-logo {
  display: block;
  width: 135.03px;    /* logo.md → celek na User select */
  height: 33.758px;
}
.dd-logo > img,
.dd-logo > svg { display: block; width: 100%; height: 100%; }

/* Wordmark bez marku — takhle ho používá Dr.Digital footer (logo.md). */
.dd-logo--wordmark {
  width: 92.377px;
  height: 36px;
}

/* Třetí velikost wordmarku — otevřený Doctor sheet.
   Kontejner je 96×36, ale samotný text jen 96,0389 × 21,8825 na top 7,3.
   Proto se rozměr nedává na `.dd-logo`, ale na vnitřní obrázek — jinak by
   se text roztáhl na výšku kontejneru. */
.dd-logo--wordmark-sm {
  width: 96px;
  height: 36px;
  padding-top: 7.3px;
}
.dd-logo--wordmark-sm > img {
  width: 96.0389px;
  height: 21.8825px;
}

/* ==========================================================================
   DR.DIGITAL FOOTER — design-system/organisms/doctor-footer.md
   --------------------------------------------------------------------------
   ⚠️ Barvy téhle komponenty jdou z palety obrazovky `Iddelat state`, která
   je JINÁ než paleta design systemu (findings.md → F1). Komponenta proto
   čte `--dd-footer-*` proměnné, které nastavuje obrazovka — ne globální
   tokeny. Až se paleta sjednotí, mění se jeden blok v obrazovce, ne tohle.
   ========================================================================== */

.dd-doctor-footer {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-20);        /* doctor-footer.md → Wrapper padding */
  /* Home indicator na iPhonu. `max()`, ne součet — s viditelným toolbarem
     prohlížeče je inset 0 a platí 20px ze zdroje; ve standalone režimu se
     footer zvedne nad indicator. NAŠE doplnění, zdroj safe-area neřeší
     (souvisí s findings.md → F40: chrome telefonu není produktové UI). */
  padding-bottom: max(var(--space-20), env(safe-area-inset-bottom, 0px));
}

.dd-doctor-footer__card {
  display: flex;
  flex: 1 0 0;
  min-width: 0;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-20);        /* doctor-footer.md → Karta padding */
  border-radius: var(--radius-32); /* doctor-footer.md → Karta radius */
  background: var(--dd-footer-surface);
  border: none;
  font: inherit;
  text-align: left;
  /* Karta je <button>, protože chevron signalizuje rozbalení. Že je
     klikatelná CELÁ (a ne jen chevron) je NAŠE domněnka — zdroj to
     neurčuje, viz doctor-footer.md → Otevřené otázky #2. */
  cursor: pointer;
}

.dd-doctor-footer__card:focus-visible {
  outline: 3px solid var(--dd-footer-accent);
  outline-offset: 2px;
}

/* --- Levá skupina: avatar + online tečka + wordmark --- */

.dd-doctor-footer__identity {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--space-14);            /* doctor-footer.md → Skupina gap */
  flex-shrink: 0;
}

.dd-doctor-footer__avatar {
  position: relative;
  width: 54px;                     /* doctor-footer.md → 54 × 56, nekvadratický */
  height: 56px;
  border-radius: var(--radius-12);
  overflow: hidden;
  flex-shrink: 0;
}
.dd-doctor-footer__avatar > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Online tečka. Ukotvení je vůči LEVÉ SKUPINĚ, ne vůči avataru — přesně
   jak to má zdroj (`left: 42px, top: 44px`). Proto sedí na pravém dolním
   rohu avataru a přesahuje ven.
   `border-box` (globální reset) + 24px + 4px border = 16px viditelný fill. */
.dd-doctor-footer__status-dot {
  position: absolute;
  left: 42px;
  top: 44px;
  width: 24px;
  height: 24px;
  /* Figma pozicuje 16px box a obrys kreslí vně (inset −25 %), takže
     vizuální středy si musí odpovídat: 16px box na left 42 má střed 50;
     24px box musí začínat na 38, aby měl střed taky 50. */
  margin: -4px 0 0 -4px;
  border: 4px solid var(--dd-footer-surface);
  border-radius: var(--radius-full);
  background: var(--dd-footer-status-online);
  pointer-events: none;
}

/* --- Pravá skupina: chevron --- */

.dd-doctor-footer__toggle {
  display: flex;
  align-items: center;
  height: 36px;                    /* doctor-footer.md → Kontejner výška */
  flex-shrink: 0;
  color: var(--dd-footer-accent);  /* chevron dědí přes currentColor */
}
.dd-doctor-footer__toggle > svg { display: block; width: 20px; height: 20px; }

/* ==========================================================================
   DOCTOR SHEET — otevřený stav, design-system/organisms/doctor-sheet.md
   --------------------------------------------------------------------------
   Zavřený footer a tenhle sheet jsou DVA STAVY JEDNÉ komponenty (potvrzeno
   Davidem). Přepínač je `data-state` na `.dd-doctor-panel`.
   ========================================================================== */

/* --------------------------------------------------------------------------
   PANEL — ukotvení k VIEWPORTU, ne ke stage

   ⚠️ Změna 2026-07-27 (Davidovo zadání: „footer musí být always visible").
   Předtím byl panel `absolute` uvnitř `.dd-stage`, která má fixní výšku.
   Na reálném telefonu si prohlížeč bere ~150px na URL bar a toolbar, takže
   spodek stage skončil pod foldem a z karty koukala jen horní hrana.
   `position: fixed` + `dvh` to řeší: panel sedí na spodní hraně VIDITELNÉ
   části viewportu a chrome prohlížeče ho neposouvá.

   Proč `dvh` a ne `vh`: `100vh` na iOS znamená viewport BEZ chromu, tedy
   víc, než je skutečně vidět — sheet by přetékal pořád, jen jinak.

   `pointer-events: none` na panelu: panel je 95dvh vysoký průhledný box.
   Bez tohohle by svou horní (prázdnou) částí chytal kliky určené obsahu
   obrazovky pod ním.
   -------------------------------------------------------------------------- */

.dd-doctor-panel {
  /* Zarážka „mid" — ze Figmy: sheet začíná na y = 426 v 852px framu,
     takže viditelná výška je 426px. */
  --dd-sheet-detent-mid: 426px;

  /* Zarážka „expanded" — NENÍ ze zdroje. Davidovo rozhodnutí 2026-07-27,
     zdroj definuje jedinou otevřenou pozici (doctor-sheet.md → #1, #2). */
  --dd-sheet-detent-full: 95vh;   /* fallback bez dvh */

  /* Křivka a doba animace. NENÍ to ze zdroje, zdroj má jen dva statické
     stavy; David zadal "co nejvíc smooth".

     OTEVÍRÁNÍ: rychlý rozjezd, dlouhý dojezd — tak se chovají nativní
     bottom sheety. Prvek přilétá, takže má být hned „na scéně".

     ZAVÍRÁNÍ: jiná křivka a delší čas, ne omylem. Tahle křivka
     front-loaduje pohyb — prvních 80 % cesty ujede v ~150ms. Na otevírání
     to funguje, na zavírání z plné výšky (~790px) to vypadá jako střih,
     ne jako pohyb. Nahlásil David 2026-07-27: „je to tak brutálně rychlé,
     že to skoro vypadá jako chyba." Symetrická křivka s pomalejším
     startem dá oku šanci pohyb sledovat. */
  --dd-sheet-ease: cubic-bezier(0.32, 0.72, 0, 1);
  --dd-sheet-duration: 420ms;
  --dd-sheet-ease-close: cubic-bezier(0.4, 0, 0.2, 1);
  --dd-sheet-duration-close: 560ms;

  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  margin: 0 auto;                        /* na desktopu se zúží spolu se stage */
  height: var(--dd-sheet-detent-full);
  z-index: 20;
  pointer-events: none;
}

/* Interaktivní jsou jen děti panelu, ne jeho prázdná plocha. */
.dd-doctor-panel > * { pointer-events: auto; }

@supports (height: 1dvh) {
  .dd-doctor-panel { --dd-sheet-detent-full: 95dvh; }
}

/* Stejný klamp jako `.dd-stage` — panel je `fixed`, takže šířku stage
   nedědí a musí ji zrcadlit sám. */
@media (min-width: 640px) {
  .dd-doctor-panel { max-width: var(--screen-width); }
}

/* ---- Zavřený footer: schová se, jakmile je sheet na kterékoli zarážce ----
   `visibility: hidden` je tady nutná, ne jen kosmetika. Samotné
   `pointer-events: none` + `opacity: 0` by footer schovalo před myší, ale
   NE před klávesnicí — uživatel by Tabem přistál na neviditelném tlačítku.
   Visibility ho vyřadí z tab orderu. Je odložená o dobu animace, aby se
   fade dokreslil. */
.dd-doctor-panel:not([data-state="closed"]) .dd-doctor-footer {
  opacity: 0;
  transform: translateY(24px);
  pointer-events: none;
  visibility: hidden;
  transition: opacity var(--dd-sheet-duration) var(--dd-sheet-ease),
              transform var(--dd-sheet-duration) var(--dd-sheet-ease),
              visibility 0s linear var(--dd-sheet-duration);
}
/* Tohle je stav, do kterého se footer VRACÍ, takže platí zavírací časování
   — jinak by footer naskočil dřív, než sheet sjede, a byly by na scéně oba. */
.dd-doctor-footer {
  transition: opacity var(--dd-sheet-duration-close) var(--dd-sheet-ease-close),
              transform var(--dd-sheet-duration-close) var(--dd-sheet-ease-close),
              visibility 0s;
}

/* ---- Sheet — plocha, která se animuje ----
   Sheet má VŽDY výšku plné zarážky (95dvh) a zarážky jsou offsety
   `translateY`. Důvod: conventions.md → Animace zakazuje animovat `height`
   (spouští layout a trhá). Takhle je animovaná vlastnost pořád jen
   `transform`, i když se sheet „zvětšuje".

   Kolik je vidět = 95dvh − offset:
     closed    → translateY(100%)                → 0
     mid       → translateY(95dvh − 426px)       → 426px
     expanded  → translateY(0)                   → 95dvh
   -------------------------------------------------------------------------- */
.dd-sheet {
  position: absolute;
  inset: 0;

  display: flex;
  flex-direction: column;
  overflow: hidden;                         /* klip obsahu na horní radius */

  background: var(--white);                 /* doctor-sheet.md → Background */
  border-radius: var(--radius-36) var(--radius-36) 0 0;   /* jen horní rohy */

  /* Stín vzhůru, 5 vrstev, barva User outline #FFE2AE.
     První vrstva má ve zdroji alfu 0 — nekreslí nic, ale nechávám ji,
     ať je vidět, že jsem ji nevynechal omylem. */
  box-shadow:
    0 -387px 54px   rgba(255, 226, 174, 0),
    0 -247px 49.5px rgba(255, 226, 174, 0.04),
    0 -139px 42px   rgba(255, 226, 174, 0.13),
    0 -62px  31px   rgba(255, 226, 174, 0.22),
    0 -15px  17px   rgba(255, 226, 174, 0.26);

  /* Animace jen přes `transform` — nikdy `height` ani `top`. Transform běží
     na GPU a nespouští layout; animovaná výška by trhala. */
  /* Tohle je ZAVŘENÝ stav, tedy cíl zavírací animace → zavírací časování. */
  transform: translateY(100%);
  transition: transform var(--dd-sheet-duration-close) var(--dd-sheet-ease-close),
              visibility 0s linear var(--dd-sheet-duration-close);
  visibility: hidden;
  will-change: transform;
}

/* ---- Zarážky ---- */
.dd-doctor-panel[data-state="mid"] .dd-sheet,
.dd-doctor-panel[data-state="expanded"] .dd-sheet {
  visibility: visible;
  transition: transform var(--dd-sheet-duration) var(--dd-sheet-ease),
              visibility 0s;
}
.dd-doctor-panel[data-state="mid"] .dd-sheet {
  transform: translateY(calc(var(--dd-sheet-detent-full) - var(--dd-sheet-detent-mid)));
}
.dd-doctor-panel[data-state="expanded"] .dd-sheet {
  transform: translateY(0);
}

/* ---- Návrat z navazující obrazovky: sheet je otevřený HNED ----
   Když se uživatel vrací z „K doktorovi", má být tam, kde byl — tedy
   s otevřeným sheetem. Kdyby se sheet přijetím animoval, vypadalo by to
   jako nová akce, ne jako návrat.

   Musí stát ZA pravidly zarážek výš, aby při shodné specificitě vyhrálo.
   JS třídu odebere po dvou frame, takže další přechody už animují. */
.dd-doctor-panel.is-instant .dd-sheet,
.dd-doctor-panel.is-instant .dd-doctor-footer {
  transition: none;
}

/* Během tažení prstem musí sheet sledovat pohyb 1:1 — jakákoli transition
   by mezi prst a sheet vložila latenci. JS tuhle třídu nasazuje na dobu
   gesta a `transform` nastavuje inline. */
.dd-sheet.is-dragging {
  transition: none;
  will-change: transform;
}

/* ---- Během tažení se obsah nesmí tvářit jako stisknutý ----
   Prst jede při stahování sheetu přes buttony a iOS na nich drží `:active`,
   takže se rozsvěcely na plnou Highlight barvu (nahlásil David 2026-07-27).
   Hover řeší `@media (hover: hover)` u samotné komponenty; tady zbývá press.

   Řešeno VIZUÁLNĚ, ne přes `pointer-events: none` — prvek, na kterém gesto
   začalo, drží implicitní pointer capture, a odebrání pointer-events by
   mohlo přerušit tok `pointermove`/`pointerup`. Tažení by se zaseklo
   uprostřed, což je horší vada než ta, kterou opravujeme.

   `:not([disabled])` v selektoru není dekorace — drží specificitu nad
   generickými stavovými pravidly Buttonu, aby na pořadí v souboru
   nezáleželo. */
.dd-sheet.is-dragging .dd-btn--primary:not([disabled]):active {
  background: var(--highlight);
  color: var(--user-bcg);
  border-width: 0;
}
.dd-sheet.is-dragging .dd-btn--secondary:not([disabled]):active {
  background: var(--white);
  color: var(--highlight);
  border-width: 2px;
  border-color: var(--highlight);
}
.dd-sheet.is-dragging .dd-btn--tertiary:not([disabled]):active {
  background: transparent;
  color: var(--highlight);
  border-width: 0;
}
.dd-sheet.is-dragging .dd-btn-inline:not([disabled]):active {
  background: transparent;
  color: var(--highlight);
  padding: 0;
}

@media (prefers-reduced-motion: reduce) {
  .dd-sheet, .dd-doctor-footer { transition-duration: 0.01ms; }
}

/* ---- Scroller — vnitřní scroll kontejner ----
   Oddělený od `.dd-sheet` schválně. Sheet je vysoký 95dvh vždycky (kvůli
   transform-only animaci), ale scrollovat smí jen ta část, která je
   VIDĚT — jinak by scroll viewport pokračoval pod spodní hranu obrazovky
   a obsah by mizel do neviditelna.

   Výška se proto přepíná skokem, ne animací (`height` se neanimuje —
   conventions.md). Skok není vidět: obsah je zarovnaný nahoru, takže
   změna spodní hrany scrolleru nic vizuálně nepřesune. Třídu `is-full`
   řídí JS, aby při zavírání z plné výšky obsah nezmizel dřív, než sheet
   sjede z obrazovky.

   Že scroll je vnitřní a ne stránkový poznáme ze zdroje: drag handle má
   `sticky top-0`, což má smysl jen ve vlastním scroll kontejneru. */
.dd-sheet__scroller {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: var(--dd-sheet-detent-mid);
  overflow-y: auto;
  /* Brání tomu, aby scroll na konci obsahu protekl na stránku pod ním. */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  /* Scrollbar skrytý — na telefonu žádný není a ve Figmě taky ne.
     Viditelný by ubral šířku a rozhodil geometrii. */
  scrollbar-width: none;
}
.dd-sheet__scroller::-webkit-scrollbar { display: none; }

.dd-sheet__scroller.is-full { height: var(--dd-sheet-detent-full); }

/* Na zarážce „mid" je scroll ZAMČENÝ. Pokus scrollovat sheet nejdřív
   zvětší na plnou výšku (Davidovo rozhodnutí — chování nativních iOS
   sheetů) a teprve pak se scrolluje uvnitř. Bez `touch-action: none` by
   si svislé gesto vzal prohlížeč a JS by ho nikdy neviděl. */
.dd-doctor-panel[data-state="mid"] .dd-sheet__scroller {
  overflow: hidden;
  touch-action: none;
}

/* ---- Drag handle ----
   Sticky uvnitř scroll kontejneru.
   ⚠️ Bílé pozadí je NAŠE doplnění: zdroj kontejneru žádné nedává, ale
   sticky prvek bez pozadí by nechal obsah prosvítat skrz. Bez toho to
   vypadá rozbitě. Viz doctor-sheet.md → Drag handle. */
.dd-sheet__handle-area {
  position: sticky;
  top: 0;
  z-index: 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  height: 24px;
  padding: 8px var(--space-40) 0;
  border-radius: var(--radius-36) var(--radius-36) 0 0;
  background: var(--white);
  cursor: grab;
  touch-action: none;      /* aby tažení nekradl prohlížeč */
}
.dd-sheet__handle-area:active { cursor: grabbing; }

.dd-sheet__handle {
  width: 40px;
  height: 4px;
  border-radius: var(--radius-2);
  background: var(--blue-dark);   /* doctor-sheet.md → proužek */
}

/* ---- Obsah sheetu ---- */
.dd-sheet__body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-54);                    /* gap mezi hlavními bloky */
  padding: var(--space-19) var(--space-40);
  /* ↑ 19px horní gap je ze zdroje gap mezi handle a řadou karet; protože
     handle je sticky a mimo tenhle flow, je z něj tady padding-top. */

  /* ⚠️ SPODNÍ PADDING JE ODCHYLKA OD ZDROJE (40px místo 200px).
     Zdroj má 200px, ale nikdy je nezobrazuje: sheet je ve Figmě vysoký
     1194px a přesahuje 316px za spodní hranu framu, takže těch 200px leží
     mimo viditelnou plochu. Druhá zarážka (95dvh) je odkryla a vznikl
     mrtvý bílý pruh pod poslední kartou — nahlásil David 2026-07-27.
     40px není nová hodnota, je to horizontální padding sheetu, takže
     spodní okraj drží stejný rytmus jako boky.
     `max()` se safe-area kvůli home indicatoru ve standalone režimu. */
  padding-bottom: max(var(--space-40), env(safe-area-inset-bottom, 0px));
}

/* Blok = jedna z hlavních sekcí. `isolate` + z-index kopíruje zdroj,
   i když se bloky nepřekrývají (viz doctor-sheet.md → Z-vrstvy). */
.dd-sheet__body { isolation: isolate; }
.dd-sheet__block { width: 100%; }
.dd-sheet__block--top     { z-index: 3; display: flex; flex-direction: column; gap: var(--space-29); padding-bottom: var(--space-40); }
.dd-sheet__block--active  { z-index: 2; display: flex; flex-direction: column; gap: var(--space-25); }
.dd-sheet__block--solved  { z-index: 1; display: flex; flex-direction: column; gap: var(--space-25); }

/* Vnořená skupina: identita, Primary button, trojice Secondary.
   Gap 21 platí mezi VŠEMI třemi (doctor-sheet.md → Buttony). */
.dd-sheet__group {
  display: flex;
  flex-direction: column;
  gap: var(--space-21);
}

/* Wordmark + avatar stack, gap 8. */
.dd-sheet__identity {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

/* Trojice Secondary buttonů má mezi sebou 8, ne 21. */
.dd-sheet__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.dd-sheet__section-title {
  width: 100%;
  font-family: var(--font-primary);
  font-size: var(--body3-font-size);
  line-height: var(--body3-line-height);
  font-weight: var(--body3-weight-alt);    /* Body3 highlight = SemiBold */
  color: var(--content);
  margin: 0;
}

/* ==========================================================================
   CAROUSEL — vodorovně scrollovatelná řada notification karet
   doctor-sheet.md → Řada notification karet
   ==========================================================================
   Šířka 353px = obsahová šířka sheetu (313) + 40. Řada tedy přetéká pravý
   padding až k hraně obrazovky — pozvánka ke scrollu. Potvrzeno Davidem,
   že scrolluje.
   -------------------------------------------------------------------------- */
.dd-carousel {
  /* Šířka karty na jednom místě — čte ji karta i výpočet spaceru níž. */
  --dd-carousel-card: 256px;

  align-self: flex-start;
  width: calc(100% + var(--space-40));
  display: flex;
  gap: var(--space-8);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;             /* Firefox */

  /* ---- Zakončení řady: poslední karta dojede do PRAVÉ svislice obsahu ----
     Rozhodl David 2026-07-27: odscrollovaná řada má skončit tak, že pravá
     hrana poslední karty sedí ve stejné svislici jako pravá hrana buttonů,
     a z předchozí karty zůstane peek. NENÍ to zarovnání doleva.

     Proto trailing prostor = 40px, tedy tentýž gutter jako vlevo. Řada je
     široká `100% + 40`, takže přetéká pravý padding sheetu až k hraně
     obrazovky (to je ze zdroje — pozvánka ke scrollu), ale scroll se
     zastaví o 40px dřív a obsah se vrátí do sloupce.

     `scroll-padding-right` posune snapport, takže `snap-align: end` na
     poslední kartě míří do stejné svislice. Bez toho by se karta zarovnala
     na fyzickou hranu obrazovky.

     ⚠️ Zdroj má místo toho spacer 22 × 76 a `padding-right: 36`
     (dohromady trailing 66px) — obojí dělá totéž a doc je označuje za
     redundantní. S těmi hodnotami karta skončí 66px od hrany, což není
     žádná svislice v layoutu. Viz doctor-sheet.md → Řada notification karet. */
  padding-right: var(--space-40);
  scroll-padding-right: var(--space-40);
}
.dd-carousel::-webkit-scrollbar { display: none; }
.dd-carousel > * { scroll-snap-align: start; }

/* Poslední karta se zarovnává KONCEM — jinak by její snap pozice ležela
   za koncem scrollu, byla by nedosažitelná a řada by parkovala na hodnotě
   nezarovnané k ničemu. Tohle je ta vada, kterou David nahlásil. */
.dd-carousel > .dd-notif-card:last-of-type { scroll-snap-align: end; }

/* Trailing spacer ze zdroje (22 × 76) prototyp NEPOUŽÍVÁ — trailing prostor
   řeší `padding-right` výš, protože jeho hodnota musí přesně odpovídat
   gutteru, aby poslední karta dojela do pravé svislice obsahu. Dvě nezávislé
   trailing hodnoty (spacer + padding) by se sčítaly a výsledek by v žádné
   svislici neskončil. Element se proto ani negeneruje, viz home-mother.html.
   Pravidlo tu zůstává jako záchytný bod, kdyby se spacer někdy vrátil. */
.dd-carousel__spacer { display: none; }

/* ==========================================================================
   NOTIFICATION CARD — design-system/molecules/notification-card.md
   ========================================================================== */
.dd-notif-card {
  /* Fixní šířka ze zdroje. Proměnná proto, že s ní počítá i trailing
     spacer carouselu — dvě kopie 256px by se rozešly. */
  flex: 0 0 var(--dd-carousel-card, 256px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-20);
  border-radius: var(--radius-12);
  background: var(--blue);
  color: var(--content);

  /* ⚠️ BÍLÝ stín směřující DOLŮ. Na bílém pozadí sheetu je neviditelný —
     bílá na bílé. Reprodukuju věrně, ale je to kandidát na dotaz
     (notification-card.md → Otevřené otázky #4). */
  box-shadow:
    0 215px 30px   rgba(255, 255, 255, 0.01),
    0 138px 27.5px rgba(255, 255, 255, 0.05),
    0 77px  23px   rgba(255, 255, 255, 0.18),
    0 34px  17px   rgba(255, 255, 255, 0.31),
    0 9px   9.5px  rgba(255, 255, 255, 0.36);
}

.dd-notif-card__main {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  justify-content: center;
  min-width: 0;
}

.dd-notif-card__meta {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

.dd-notif-card__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  font-family: var(--font-primary);
  font-size: var(--body3-font-size);
  line-height: var(--body3-line-height);
  color: var(--content);
  /* Zdroj má nowrap na titulu i podtitulu. Reprodukuju, ale znamená to,
     že delší jméno lékaře kartu přeteče — viz notification-card.md #3. */
  white-space: nowrap;
}
.dd-notif-card__title    { font-weight: var(--body3-weight-alt); margin: 0; }   /* SemiBold */
.dd-notif-card__subtitle { font-weight: var(--body3-weight); margin: 0; }       /* Regular */

.dd-notif-card__icon { flex-shrink: 0; width: 20px; height: 20px; color: var(--content); }
.dd-notif-card__icon > svg { display: block; width: 100%; height: 100%; }

/* ==========================================================================
   TAG — design-system/atoms/tag.md
   ========================================================================== */
.dd-tag {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  border-radius: var(--radius-4);
  background: var(--warning);   /* jediná varianta ve zdroji */
  color: var(--white);
}

/* ==========================================================================
   AVATAR STACK — design-system/molecules/avatar-stack.md
   ========================================================================== */
.dd-avatar-stack {
  position: relative;
  display: flex;
  align-items: flex-end;
  width: 100%;
}

.dd-avatar-stack__item {
  position: relative;
  flex-shrink: 0;
  width: 54px;
  height: 56px;
  margin-right: -11px;          /* překryv ze zdroje */
  border-radius: var(--radius-12);
  border: 3px solid var(--white);
  overflow: hidden;
  background: var(--disabled-light);
}
.dd-avatar-stack__item > img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* Fotky s vlastním cropem ze Figmy — rozměry se zadávají inline z dat,
   stejný princip jako u avataru v user selectoru. */
.dd-avatar-stack__item > img.is-cropped {
  position: absolute;
  width: auto;
  height: auto;
  max-width: none;
  object-fit: fill;
}

/* `position: relative` je tady nutné, ne dekorativní: dlaždice ho mají taky,
   a pozicované elementy se kreslí NAD nepozicovanými ve stejném stacking
   kontextu bez ohledu na pořadí v DOM. Bez tohohle by poslední dlaždice
   překryla čip (kterého se překryv −11px dotýká) a z „+23" by bylo vidět
   jen „23". */
.dd-avatar-stack__more {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  padding: var(--space-4);
  border-radius: var(--radius-7);    /* ano, 7 — ne 8. Viz radius.md */
  background: var(--content);
  color: var(--white);
  font-family: var(--font-primary);
  font-size: var(--body3-font-size);
  line-height: var(--body3-line-height);
  font-weight: var(--body3-weight);
  margin: 0;
}

/* Zelená tečka u PRVNÍ dlaždice. Pozice je ze zdroje absolutní v rámci
   celé řady (left 22, top 51), ne relativní k dlaždici.
   Průměr 10px + obrys → 18px celkem. Pozor: tři různé velikosti tečky
   napříč projektem (10 / 12 / 16) — viz avatar-stack.md #2. */
.dd-avatar-stack__dot {
  position: absolute;
  left: 22px;
  top: 51px;
  width: 18px;
  height: 18px;
  margin: -4px 0 0 -4px;    /* aby 10px fill měl střed tam, kde ho má zdroj */
  border: 4px solid var(--white);
  border-radius: var(--radius-full);
  background: var(--positive);
  pointer-events: none;
}

/* ==========================================================================
   CASE CARD — design-system/molecules/case-card.md
   ========================================================================== */
.dd-case-card {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: var(--space-20);
  border-radius: var(--radius-12);
  font-family: var(--font-primary);
}

.dd-case-card__name {
  font-weight: var(--weight-bold);
  font-size: 14px;
  line-height: 18px;
  margin: 0;
}

.dd-case-card__when {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-5);
  text-align: right;
  flex-shrink: 0;
}

/* ---- Varianta: aktivní ---- */
.dd-case-card--active {
  background: var(--positive);
  /* Zdroj tady používá Content jako #2B108E, jinde v témže sheetu #151D86.
     Hodnota se nastavuje z obrazovky, ať je ta nekonzistence vidět
     na jednom místě — viz findings.md → F1. */
  color: var(--dd-case-active-text, var(--content));
}
.dd-case-card--active .dd-case-card__name { white-space: nowrap; }

/* Badge "aktivní".
   🔴 Barva textu je #D400FF z ROZBITÉ REFERENCE `@obsolete/@obsolete
   Content/Copy`. colors.md tu skupinu označuje za interní placeholder pro
   rozbité reference — a tady se reálně renderuje jako magenta na bílém.
   Reprodukuju věrně a hlásím. NEOPRAVUJU.
   `left: 152px` je taky ze zdroje natvrdo, ne layout — u delšího názvu
   případu se překryjí. */
.dd-case-card__badge {
  position: absolute;
  left: 152px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-10);
  border-radius: var(--radius-8);
  background: var(--white);
  color: var(--dd-obsolete-magenta);
  font-size: var(--body3-font-size);
  line-height: var(--body3-line-height);
  font-weight: var(--body3-weight-alt);
  margin: 0;
  white-space: nowrap;
}

/* ---- Varianta: vyřešená ---- */
.dd-case-card--solved {
  background: transparent;
  border: 1px solid var(--dd-border-violet);
  color: var(--dd-case-solved-text, var(--content));
}

/* Dvě vyřešené karty ve zdroji mají RŮZNÉ velikosti datového bloku
   (14/21 vs 17/24) a různé zalamování názvu. Nevidím v tom pravidlo, takže
   to nezobecňuju do jedné třídy — obrazovka to nastavuje per karta
   utilitami .t-num-* a modifikátorem níž. Viz case-card.md → Nekonzistence. */
.dd-case-card--solved .dd-case-card__name { white-space: nowrap; }
.dd-case-card--solved.dd-case-card--wrap .dd-case-card__name {
  flex: 1 0 0;
  min-width: 0;
  white-space: normal;
}

/* ==========================================================================
   TEXT-BOX TRIM — proč to tu je

   Figma měří textové boxy na CAP-HEIGHT, ne na line-box: v exportu je u
   každého textu `[text-box-trim:trim-both] [text-box-edge:cap_alphabetic]`.
   Prakticky to znamená, že u Body2 (16/22) je "výška textu" 11px, ne 22.

   Když se paddingy ze Figmy použijí na CSS line-box, každý textový blok
   naroste o `line-height − cap-height` a celá obrazovka se rozjede. Konkrétně:
   section header vyšel 116px místo 103px, tedy o 13px.

   Alternativa by byla dopočítávat do každého paddingu kompenzaci
   `(line-height − cap-height) / 2`. To jsou magická čísla, která se rozejdou
   při každé změně fontu. Nativní `text-box` dělá totéž co Figma.

   ⚠️ SCOPOVANÉ SCHVÁLNĚ na komponenty téhle obrazovky. Nasadit trim na
   globální `.t-*` utility by rozhodilo geometrii Doctor sheetu, která je
   odměřená a odsouhlasená bez něj.

   Bez podpory (starší prohlížeče) se rozestupy o těch pár pixelů rozvolní —
   layout se nerozbije.

   ⚠️ VŽDY NA BLOK TEXTU, NIKDY NA JEDNOTLIVÉ ODSTAVCE UVNITŘ NĚJ.
   Trim řeže na cap-height a účaří, ale diakritika sedí nad cap-height
   a descendery pod účařím — dva sousedící trimnuté odstavce s nulovým
   marginem proto do sebe nalezou. Selektory níž jsou všechny
   jednoodstavcové bloky; víceodstavcový text (`__legal`, zpráva) dostává
   trim na kontejneru přes utilitu `.t-trim-block`.
   ========================================================================== */
@supports (text-box: trim-both cap alphabetic) {
  .dd-section-header__title,
  .dd-anamnesis-label,
  .dd-anamnesis__value,
  .dd-anamnesis__detail {
    text-box: trim-both cap alphabetic;
  }
}

/* ==========================================================================
   SECTION HEADER — design-system/organisms/section-header.md
   --------------------------------------------------------------------------
   Horní padding 72px NENÍ mezera pod status barem — je to hodnota komponenty.
   Prototyp status bar vynechává (F40), takže se projeví jako prázdný prostor
   nad titulkem. Tak to má zdroj.
   ========================================================================== */
.dd-section-header {
  display: flex;
  align-items: center;
  gap: var(--space-80);
  width: 100%;
  padding: var(--space-72) var(--space-40) var(--space-20);
  background: var(--white);
}

.dd-section-header__title {
  flex: 1 0 0;
  min-width: 0;
  font-family: var(--font-primary);
  font-size: var(--body2-font-size);
  line-height: var(--body2-line-height);
  font-weight: var(--body2-weight-alt);   /* Body2 highlight = SemiBold */
  color: var(--content);
  margin: 0;
  text-align: left;
}

/* Akce je Button inline bez labelu — accessible name proto musí dodat
   `aria-label`, jinak je pro screen reader prázdný (components.js to hlídá).

   ⚠️ Výška 10px není překlep. Zdroj má „Button inside" vysoký 10px a ikonu
   24 × 24 nechává symetricky PŘETÉKAT (`get_metadata`: Button 24 × 10 na
   y 72,5). Kdyby button měl výšku své ikony, celá hlavička by narostla
   ze 103 na 116px, protože je to nejvyšší prvek řádku. */
.dd-section-header__action {
  flex-shrink: 0;
  height: 10px;
}

/* ==========================================================================
   ANAMNÉZA — design-system/molecules/anamnesis-card.md
   ========================================================================== */

/* ---- Seznam otázek ----
   Gap je 0 a rozestup nese padding labelu. Není to zjednodušení, je to
   reprodukce zdroje: vyplněný label má nad sebou 40px, nevyplněný 32px
   PLUS 64px (`--messages`). Rozdíl je záměrný — nevyplněný blok je vyšší
   (otázka + dvě tlačítka) a dostává víc vzduchu.

   Pravidlo „64px před nevyplněným, pokud není první" reprodukuje oba
   krajní stavy zdroje přesně: prázdný frame (všechny nevyplněné → 64 mezi
   všemi, před prvním nic) i vyplněný frame (žádné 64). Viz spec. */
.dd-anamnesis-list {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.dd-anamnesis-item { display: flex; flex-direction: column; width: 100%; }
.dd-anamnesis-item--unfilled:not(:first-child) { margin-top: var(--messages); }

/* ---- Label ---- */
.dd-anamnesis-label {
  width: 100%;
  margin: 0;
  font-family: var(--font-primary);
  /* Nevyplněná varianta: tázací forma, Body2 highlight, Highlight barva. */
  padding: var(--space-32) var(--space-20) var(--space-20);
  font-size: var(--body2-font-size);
  line-height: var(--body2-line-height);
  font-weight: var(--body2-weight-alt);
  color: var(--highlight);
  letter-spacing: var(--letter-spacing);
}

/* Vyplněná varianta: jmenná fráze, menší, potlačená.
   14/18 s Medium vahou a ls 0,3px neodpovídá žádnému stylu z typography.md
   (Body3 je 14/18, ale Regular a bez trackingu) — je to vlastní kombinace
   téhle komponenty, proto hodnoty natvrdo s tímhle komentářem. */
.dd-anamnesis-label--filled {
  padding: var(--space-40) var(--space-20) var(--space-15);
  font-size: 14px;
  line-height: 18px;
  font-weight: var(--weight-medium);
  letter-spacing: 0.3px;
  color: var(--content-50);
}

/* ---- Karta ---- */
.dd-anamnesis {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-20);
  width: 100%;
  padding: var(--space-20);
  border-radius: var(--radius-12);
  background: var(--blue-light);
  border: none;
  font: inherit;
  text-align: left;
}

/* Obrys jako INSET box-shadow, ne `border` — stejný důvod jako u avataru
   (conventions.md): stroke je ve Figmě inside-aligned, takže nepřidává
   k vnějším rozměrům. S `border` byla každá karta o 2px vyšší než zdroj,
   protože její výška je content-driven a border se k ní přičte. */
.dd-anamnesis--filled {
  background: var(--user-bcg);
  box-shadow: inset 0 0 0 1px var(--user-outline);
  cursor: pointer;
}

.dd-anamnesis--filled:focus-visible {
  outline: 3px solid var(--highlight);
  outline-offset: 2px;
}

/* Dvojice odpovědí. Pořadí je „ne", pak „ano" — tak to má zdroj ve všech
   instancích, není to překlep jedné z nich. */
.dd-anamnesis__answers {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  width: 100%;
}
.dd-anamnesis__answers .dd-btn { width: 100%; }

/* ---- Filled element: hodnota + volitelný detail ---- */
.dd-anamnesis__value-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-10);
  width: 100%;
}

.dd-anamnesis__value {
  margin: 0;
  font-family: var(--font-primary);
  font-size: var(--body2-font-size);
  line-height: var(--body2-line-height);
  font-weight: var(--body2-weight-alt);   /* Body2 highlight = SemiBold */
  color: var(--content);
}

.dd-anamnesis__detail {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin: 0;
  /* ⚠️ Stejný trik jako u akce v hlavičce: zdroj má řádek vysoký 11px
     (= cap-height textu) a ikonu 16 × 16 nechává symetricky přetékat.
     Bez pevné výšky by řádek narostl na 16px a karta s lékem by měla
     85px místo 72. */
  height: 11px;
  font-family: var(--font-primary);
  font-size: var(--body2-font-size);
  line-height: var(--body2-line-height);
  font-weight: var(--body2-weight);       /* Regular */
  color: var(--content);
  /* Zdroj má nowrap. Znamená to, že dlouhý detail kartu přeteče — viz spec. */
  white-space: nowrap;
}

.dd-anamnesis__detail-icon {
  flex-shrink: 0;
  width: 16px;                            /* třetí velikost slotu, viz F12 */
  height: 16px;
  color: var(--content);
}
.dd-anamnesis__detail-icon > svg { display: block; width: 100%; height: 100%; }

/* ---- Pencil ----
   Absolutně na right 15 / top 13 ze zdroje, tedy mimo flow — nereaguje na
   obsah karty. Barva z exportu je Highlight.
   `pointer-events: none`, protože klikatelná je celá karta; ikona je jen
   afordance a nesmí krást klik. */
.dd-anamnesis__edit {
  position: absolute;
  right: 15px;
  top: 13px;
  width: 20px;
  height: 20px;
  color: var(--highlight);
  pointer-events: none;
}
.dd-anamnesis__edit > svg { display: block; width: 100%; height: 100%; }

/* ==========================================================================
   BLOK SOUHLASU — konec obrazovky anamnézy
   --------------------------------------------------------------------------
   144px nad blokem = 64 (`--messages`) + 80 z prázdného stavu. Vyplněný stav
   má natvrdo 144. Obě čtení dávají stejné číslo, takže tady není rozpor.
   ========================================================================== */
.dd-anamnesis-consent {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-143);
  width: 100%;
  padding-top: var(--space-144);
}

.dd-anamnesis-consent__group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 23px;                 /* ze zdroje; jediný výskyt, proto natvrdo */
  width: 100%;
}
.dd-anamnesis-consent__group .dd-btn { width: 100%; }

/* Víceodstavcový blok → trim na kontejneru (`.t-trim-block` v HTML), ne na
   odstavcích. Odstavce mezi sebou nemají margin, takže se řádky rozestupují
   line-heightem — přesně jako jeden textový node ve zdroji. */
.dd-anamnesis-consent__legal {
  width: 100%;
  margin: 0;
  font-family: var(--font-primary);
  font-size: var(--body3-font-size);
  line-height: var(--body3-line-height);
  font-weight: var(--body3-weight);
  color: var(--content);
  text-align: center;
}

/* Čtvrtá velikost wordmarku (64 × 24). F38 mluvil o třech.
   Kontejner je 64×24, ale samotný text 64,026 × 14,588 na top 4,87 —
   proto rozměr na obrázku, ne na kontejneru (stejný vzor jako --wordmark-sm). */
.dd-logo--wordmark-xs {
  width: 64px;
  height: 24px;
  padding-top: 4.87px;
}
.dd-logo--wordmark-xs > img {
  width: 64.026px;
  height: 14.588px;
}
