/* 10.9.2026 — na žiadosť "pouzi tento font na kazdy text": Plus Jakarta
   Sans nahradilo predošlú dvojicu Fraunces (nadpisy)/Inter (bežný text)
   všade, nie len pridané popri nich. Fraunces mala optickú os (opsz),
   ktorú Plus Jakarta Sans nemá — komentáre pri jednotlivých nadpisoch,
   čo tú os pripínali, sú neškodné (nepodporovaná os v font-variation-
   settings sa ticho ignoruje), zámerne nezmazané kus po kuse naprieč
   súborom. */
/* 17.9.2026 — písmo sa už NEŤAHÁ z fonts.googleapis.com. Dovtedy šla
   každému návštevníkovi IP adresa Googlu (zásady ochrany údajov to museli
   priznávať — bola to jediná tretia strana v celej appke) a prehliadač
   musel pred vykreslením textu nadviazať spojenie s dvoma ďalšími
   doménami. Súbory sú odteraz v static/fonts/ (vyrába tools_fetch_font.py,
   licencia SIL OFL 1.1) a načítava ich <link> v šablóne PRED týmto
   súborom — @import by sa sťahoval až po dočítaní tohto CSS, čiže
   sériovo, nie súbežne. */

/* Motív "Cool Taupe" (predvolený, svetlý) — bare :root, platí keď OS nemá
   tmavý режим A používateľ si cez #theme-toggle-btn (viď script.js)
   nevynútil explicitnú voľbu. Neutrálna sivohnedá namiesto čistej bielej
   (zadaním požadované "vyhýbajúci sa ostrej čistej bielej"). */
:root {
  --bg: #DDDCD7;
  --surface: #F3F2EE;
  --surface-alt: #F7F6F3;
  --border: #D7D6CF;
  --border-strong: #C6C5BC;
  --ink: #2F2F2A;
  --muted: #6E6D63;
  /* 10.9.2026 — na žiadosť "trošku výraznejšia zelená, ale nie moc",
     potom "zelenšiu ešte môžeš o kúsok zvýšiť": #1F7A52 (H154 S59 L30)
     → #1C925F (H154 S68 L34) → #17A165 (H154 S75 L36). Rovnaký odtieň
     v oboch krokoch, len sýtejšia a o kúsok svetlejšia, nech nepôsobí
     "jemne zelenkavo" na malých plochách (okraje, text) oproti taupe
     podkladu. */
  --primary: #17A165;
  --primary-dark: #0F7649;
  --primary-soft: #DDF3E8;
  --accent: #E1552A;
  --accent-soft: #FCE9E1;
  --gold: #C0912F;
  --gold-soft: #FAF1DC;
  --danger: #B3421F;
  --danger-soft: #FBEAEA;
  --danger-border: #E2A5A5;

  --radius-sm: 10px;
  --radius-md: 16px;
  --radius-lg: 22px;
  --radius-card: 18px;
  --shadow-xs: 0 1px 2px rgba(45, 42, 32, 0.06);
  --shadow-sm: 0 2px 10px rgba(45, 42, 32, 0.07);
  --shadow-md: 0 10px 28px rgba(45, 42, 32, 0.11);
  --shadow-lg: 0 24px 56px rgba(45, 42, 32, 0.18);
  --header-bg: rgba(243, 242, 238, 0.82);

  color-scheme: light;
}

/* Motív "Dark Mode" — platí buď podľa OS preferencie (media query nižšie,
   len keď používateľ neprepol explicitne na Cool Taupe), alebo natvrdo
   cez data-theme="dark" na <html> (viď applyThemePreference v script.js). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #10120F;
    --surface: #191C17;
    --surface-alt: #1F221C;
    --border: #2B2F26;
    --border-strong: #3A3F33;
    --ink: #ECEEE6;
    --muted: #9AA28E;
    --primary: #3FCB8C;
    --primary-dark: #2E9E6C;
    --primary-soft: #17281E;
    --accent: #FF8657;
    --accent-soft: #2D1C12;
    --gold: #E3BB6C;
    --gold-soft: #2A2314;
    --danger: #FF9B87;
    --danger-soft: #2C1815;
    --danger-border: #4A2622;

    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
    --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.35);
    --shadow-md: 0 10px 28px rgba(0, 0, 0, 0.42);
    --shadow-lg: 0 24px 56px rgba(0, 0, 0, 0.55);
    --header-bg: rgba(16, 18, 15, 0.72);

    color-scheme: dark;
  }
}
/* Explicitné prepnutie na Dark Mode — rovnaké hodnoty ako media query
   vyššie, len bez závislosti na OS preferencii (vyhráva nad ňou). */
:root[data-theme="dark"] {
  --bg: #10120F;
  --surface: #191C17;
  --surface-alt: #1F221C;
  --border: #2B2F26;
  --border-strong: #3A3F33;
  --ink: #ECEEE6;
  --muted: #9AA28E;
  --primary: #3FCB8C;
  --primary-dark: #2E9E6C;
  --primary-soft: #17281E;
  --accent: #FF8657;
  --accent-soft: #2D1C12;
  --gold: #E3BB6C;
  --gold-soft: #2A2314;
  --danger: #FF9B87;
  --danger-soft: #2C1815;
  --danger-border: #4A2622;

  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-sm: 0 2px 10px rgba(0, 0, 0, 0.35);
  --shadow-md: 0 10px 28px rgba(0, 0, 0, 0.42);
  --shadow-lg: 0 24px 56px rgba(0, 0, 0, 0.55);
  --header-bg: rgba(16, 18, 15, 0.72);

  color-scheme: dark;
}
/* Explicitné prepnutie na Cool Taupe — rovnaké hodnoty ako bare :root
   vyššie, len bez závislosti na OS preferencii (vyhráva nad tmavým OS). */
:root[data-theme="light"] {
  --bg: #DDDCD7;
  --surface: #F3F2EE;
  --surface-alt: #F7F6F3;
  --border: #D7D6CF;
  --border-strong: #C6C5BC;
  --ink: #2F2F2A;
  --muted: #6E6D63;
  --primary: #17A165;
  --primary-dark: #0F7649;
  --primary-soft: #DDF3E8;
  --accent: #E1552A;
  --accent-soft: #FCE9E1;
  --gold: #C0912F;
  --gold-soft: #FAF1DC;
  --danger: #B3421F;
  --danger-soft: #FBEAEA;
  --danger-border: #E2A5A5;

  --shadow-xs: 0 1px 2px rgba(45, 42, 32, 0.06);
  --shadow-sm: 0 2px 10px rgba(45, 42, 32, 0.07);
  --shadow-md: 0 10px 28px rgba(45, 42, 32, 0.11);
  --shadow-lg: 0 24px 56px rgba(45, 42, 32, 0.18);
  --header-bg: rgba(243, 242, 238, 0.82);

  color-scheme: light;
}

/* ======================================================================
   POVRCHY — hierarchia textúry (5.9.2026)
   ======================================================================
   Bodkovaná textúra + zelenkastý prechod boli DOSLOVA ROVNAKÉ na 12
   plochách naraz: hero, hlavička, panely obchodov/kategórií/zliav,
   katalóg receptov — ale aj na KARTÁCH vnútri tých panelov. Keď má
   všetko rovnakú váhu, nič nevynikne: stránka sa čítala ako jedno
   súvislé béžové pole s ledva viditeľnými obdĺžnikmi a textúra prestala
   byť podpisom, stala sa šumom.

   Pravidlo, ktoré to nahrádza: textúra patrí NÁDOBE, nikdy nie veciam
   v nej.
     --dots/--wash            plná sila, LEN hero (téza stránky)
     --dots-quiet               panely — rovnaký rodokmeň, o polovicu tichší
     --wash-quiet                panely — rovnaká sila ako --wash (10.9.2026,
                                  zjednotené pre konzistentnú viditeľnosť
                                  oranžovej/zelenej), líši sa len uhlom
     --card-face              karty vnútri panelov — plocho, bez bodiek

   Všetko sa mieša z --ink/--surface/--primary cez color-mix, takže to
   platí v oboch motívoch bez duplicitných deklarácií. Custom properties
   sa dosadzujú až pri použití, takže prepnutie motívu ich prepočíta samo
   — preto stačia raz, mimo blokov jednotlivých motívov. */
:root {
  --dots: radial-gradient(circle, color-mix(in srgb, var(--ink) 5%, transparent) 1.4px, transparent 1.4px);
  --dots-quiet: radial-gradient(circle, color-mix(in srgb, var(--ink) 2.5%, transparent) 1.2px, transparent 1.2px);
  /* 10.9.2026 — na žiadosť "ten zelený prechod je z bielej, skús spraviť
     ten zelený prechod na pozadí z ľahko oranžovej, aby to ladilo aj s
     logom": predtým čistý --surface (0%) → zelenkavý --surface (100%).
     Logo je dvojfarebné (Food oranžová / Hack zelená), takže teraz
     prechod ide OD jemne oranžovej K zelenej.
     Pôvodne malo --wash-quiet polovičnú silu miešania (6 % oproti 12 %
     na hero) — po tejto zmene sa ale na paneloch cez nepriehľadné karty
     presvitalo tak nerovnomerne, že oranžová/zelená pôsobila na
     rôznych miestach stránky nekonzistentne ("niekde viac vidieť,
     niekde menej"). Na žiadosť zjednotené: --wash aj --wash-quiet majú
     teraz rovnakú 12 % intenzitu, líšia sa už len uhlom prechodu
     (hero 135°, panely 160°). */
  --wash: linear-gradient(135deg, color-mix(in srgb, var(--surface) 88%, var(--accent) 12%) 0%, color-mix(in srgb, var(--surface) 88%, var(--primary) 12%) 100%);
  --wash-quiet: linear-gradient(160deg, color-mix(in srgb, var(--surface) 88%, var(--accent) 12%) 0%, color-mix(in srgb, var(--surface) 88%, var(--primary) 12%) 100%);
  /* Karty si nechávajú "jemne zelené" pozadie (výslovná žiadosť z
     3.9.2026), len bez bodiek — pri 141px dlaždici bol raster 22px už
     len zrno, nie textúra. */
  --card-face: color-mix(in srgb, var(--surface-alt) 95%, var(--primary) 5%);
  /* Svetlá hrana navrchu panelu. Predtým natvrdo rgba(255,255,255,0.4),
     čo v tmavom motíve kreslilo cez tmavý panel takmer bielu linku. */
  --edge-hi: color-mix(in srgb, var(--surface-alt) 60%, transparent);
}

* { box-sizing: border-box; }

/* 10.9.2026 — na žiadosť "ked mam obrazovku na 100% zoom (klasicke
   prehliadanie), tak mi to pripada cele moc obrovske. Potrebujem to
   globalne znizit na 85%": appka má stovky pevných px hodnôt (fonty,
   padding, medzery), takže "zmenši o 15%" prepočtom každej jednej by
   bolo krehké a ľahko sa rozíde pri budúcich úpravách. `zoom` škáluje
   CELÚ vykreslenú stránku (fonty, obrázky, medzery, layout) presne tak,
   ako keby si používateľ dal Ctrl+- v prehliadači — jediná deklarácia
   namiesto prepočítavania stoviek hodnôt, žiadne rozbité pomery. */
html { scroll-behavior: smooth; zoom: 0.85; }

/* Jednotný krúžok pri navigácii klávesnicou. :where() má nulovú
   špecificitu, takže prvky s vlastným focus štýlom (globálne hľadanie,
   rozpočtové inputy) si ho aj naďalej prebijú. */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* Appka mala vypnutú len jednu animáciu (prechod obrazoviek). Karty sa
   pritom hýbu na hover, zľavy pulzujú, panely sa vysúvajú — pri
   nastavení "obmedziť pohyb" má stíchnuť všetko. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

body {
  margin: 0;
  font-family: 'Plus Jakarta Sans', system-ui, sans-serif;
  background: var(--bg);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { font-family: 'Plus Jakarta Sans', serif; margin: 0; }

::selection { background: var(--primary-soft); color: var(--primary-dark); }

/* ---------- Topbar ---------- */

/* Header bez vlastného pozadia — pláva na spoločnom var(--bg) z <body>,
   presne ako priestor medzi .store-showcase a .category-showcase nižšie.
   Jediné biele miesto je .topbar-card (viď nižšie) a ostatné panely. */
.topbar {
  position: static;
  background: transparent;
}
/* Rovnaký "rámik šírky" ako .layout (max-width/margin/padding) — aby sa
   .topbar-card zarovnala ĽAVO AJ PRAVO presne na tú istú šírku ako
   .store-showcase/.category-showcase pod ňou (tie sú deti .layout,
   header je mimo neho, takže potrebuje vlastnú kópiu tých istých
   rozmerov). */
.topbar-container {
  max-width: 1180px;
  margin: 20px auto 0;
  padding: 0 24px;
}
/* Biely kontajner pre logo + dve samostatné akčné ikony po stranách
   (28.8.2026 — predtým zoskupené v jednej "pill" vpravo, teraz
   rozdelené: prepínač motívu vľavo hore, košík vpravo hore, na
   žiadosť). position:relative + logo s position:absolute (centrované
   cez left:50%/transform) namiesto trojstĺpcového flexu — logo tak
   zostáva PRESNE uprostred kontajnera bez ohľadu na šírku bočných
   tlačidiel, tie sa prirodzene rozídu do rohov cez
   justify-content:space-between. */
.topbar-card {
  position: relative;
  min-height: 208px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 26px;
  /* Rovnaká jemná textúra (bodky + zelenkastý prechod) ako
     .store-showcase/.category-showcase/.panel nižšie — pozri
     .category-showcase pre podrobné zdôvodnenie hodnôt. */
  background-image: var(--dots-quiet), var(--wash-quiet);
  background-size: 22px 22px, 100% 100%;
  background-position: 0 0, 0 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}
/* Logo bez vlastnej "card" plochy (28.8.2026 — predošlá biela
   card-in-card odstránená na žiadosť) — sedí priamo na jemne zelenkasto
   tónovanej textúre .topbar-card pod ním. Wrapper ostáva len kvôli
   centrovaniu (position:absolute/translate, nezávislé od šírky pravej
   skupiny ikon), žiadne pozadie/tieň/padding navyše. */
.topbar-logo-card {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
/* 28.8.2026 — podtitulok "Vaše zľavy do hrnca" bol predtým napečený
   priamo v obrázku loga (nešlo upraviť textovo) — logo.png/logo-dark.png
   orezané o tento riadok, nový text je teraz skutočný HTML (ľahko
   upraviteľný, čitateľný pre čítačky obrazovky). */
/* 28.8.2026 — na žiadosť používateľa "modernejšie" — Fraunces (serifové
   písmo, použité na nadpisy/editoriálny tón inde v appke) tu pôsobilo
   skôr klasicky/vintage. Rovnaký sans-serif ako zvyšok appky (Inter),
   VEĽKÉ PÍSMENÁ + rozostup namiesto tučného serifu — bežný "moderný SaaS"
   vzhľad pre krátky slogan pod logom. */
.topbar-tagline {
  margin: 6px 0 0;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 14.5px;
  font-weight: 700;
  color: var(--ink);
  text-transform: uppercase;
  letter-spacing: 0.14em;
}
/* Dve verzie loga (rovnaký tvar/alfa kanál, len farba textu) — svetlá
   tmavozelená verzia (logo.png) pre svetlý motív, takmer biela verzia
   (logo-dark.png, vygenerovaná z rovnakej alfy) pre tmavý motív, aby
   mal nápis dosť kontrastu na tmavom pozadí namiesto pôvodnej tmavo-
   zelenej takmer nečitateľnej na takmer čiernom pozadí. Rovnaká výška
   na oboch (obe z rovnakého zdroja, identický pomer strán), aby pri
   prepnutí motívu nedošlo k poskočeniu layoutu. 176px = pôvodných
   160px zväčšené o 10% na žiadosť.*/
.topbar-logo {
  height: 176px;
  width: auto;
}
.topbar-logo-dark { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .topbar-logo-light { display: none; }
  :root:not([data-theme="light"]) .topbar-logo-dark { display: block; }
}
:root[data-theme="dark"] .topbar-logo-light { display: none; }
:root[data-theme="dark"] .topbar-logo-dark { display: block; }

/* 2.9.2026 — na žiadosť používateľa (mockup redizajnu): kompaktná
   varianta hlavičky pre index.html (sidebar shell) — vyhľadávanie priamo
   v riadku s logom, oveľa menšie logo než pôvodná (176px vysoká,
   absolútne centrovaná) verzia. ZÁMERNE len modifikátor (.topbar-card
   samotná ostáva nezmenená) — /basket-clean a /roadmap naďalej používajú
   pôvodnú veľkú hero-štýl hlavičku, tá sa touto zmenou nedotýka. */
.topbar-card.topbar-card-compact {
  min-height: auto;
  padding: 12px 22px;
  gap: 20px;
}
.topbar-card.topbar-card-compact .topbar-logo-card {
  position: static;
  transform: none;
  flex: 0 0 auto;
}
/* 2.9.2026 — logo.svg/logo-dark.svg prekreslené na vodorovný lockup
   (ikona + "FoodHack" vedľa seba, nie nápis pod ikonou ako predtým) —
   nový pomer strán (viewBox 470x190, širší/nižší než pôvodný 300x240)
   dovoľuje väčšiu výšku bez toho, aby logo bolo neúmerne široké.
   Ďalšie zväčšenie (63px → 84px) na žiadosť. */
/* 7.9.2026 — na žiadosť zmenšené z 84px. Logo bolo 6x vyššie než
   navigácia pod ním, čiže vec, na ktorú sa len pozeráš, dominovala nad
   vecou, na ktorú klikáš. Menšie logo uvoľnilo miesto pre karty sekcií
   bez toho, aby hlavička narástla. */
.topbar-card.topbar-card-compact .topbar-logo {
  height: 58px;
}
.topbar-card.topbar-card-compact .global-search-bar {
  flex: 1 1 auto;
  /* 3.9.2026 — na žiadosť: rozšírené (460px → 680px), nech je v
     dropdowne dosť miesta na CELÝ názov produktu bez orezania (viď
     .global-search-result-name nižšie). */
  max-width: 680px;
  margin: 0 auto;
  padding: 0;
}
.topbar-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
}
.topbar-card.topbar-card-compact .theme-toggle-btn,
.topbar-card.topbar-card-compact .tracked-cart-btn {
  align-self: center;
}
.topbar-card.topbar-card-compact .theme-toggle-btn { width: 34px; height: 34px; font-size: 19.5px; }
.topbar-card.topbar-card-compact .tracked-cart-btn { width: 44px; height: 44px; font-size: 26.5px; }

/* 2.9.2026 — "fake it till you make it": vizuálny avatar placeholder
   podľa mockupu, nech je vidno, čo appka bude potrebovať doriešiť
   (prihlásenie/registrácia). ZÁMERNE nevedie nikam skryto/naprázdno —
   klik vedie na existujúci "Čoskoro" stub (rovnaký vzor ako Obchody/
   Recepty/Obľúbené/Nastavenia v sidebari), žiadne predstierané
   prihlásenie. */
.user-avatar-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  align-self: center;
  padding: 5px 10px 5px 5px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}
.user-avatar-btn:hover { background: var(--surface-alt); border-color: var(--muted); }
.user-avatar-circle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: 18.5px;
  line-height: 1;
}
.user-avatar-chevron { font-size: 12.5px; color: var(--muted); line-height: 1; }
@media (max-width: 700px) {
  .topbar-card.topbar-card-compact { flex-wrap: wrap; }
  .topbar-card.topbar-card-compact .global-search-bar { order: 3; flex-basis: 100%; max-width: none; margin: 6px 0 0; }
}

/* Prepínač motívu (ľavý horný roh) a košík so sledovanými (pravý horný
   roh) — samostatné tlačidlá. Klik na košík otvorí .tracked-modal
   (výsuvný panel), klik na prepínač motívu volá applyThemePreference()
   v script.js. */
.theme-toggle-btn,
.tracked-cart-btn {
  position: relative;
  flex: 0 0 auto;
  /* .topbar-card je vysoká (kvôli veľkému logu v strede) a má
     align-items:center — bez tohto by obe tlačidlá viseli uprostred
     výšky karty namiesto v rohu. flex-start ich pripne k hornému
     okraju (spolu s paddingom karty), skutočne "do rohu". */
  align-self: flex-start;
  border: none;
  border-radius: 50%;
  background: transparent;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 0.15s ease, background-color 0.15s ease;
}
/* Bez vlastného pozadia (na žiadosť, zhodne s košíkom) — jedna ikonka,
   ktorá sama prepína medzi 🌙 (tmavý motív) a ☀️ (svetlý), viď
   setThemeIcon() v script.js. */
.theme-toggle-btn {
  width: 40px;
  height: 40px;
  font-size: 25.5px;
}
.theme-toggle-btn:hover { transform: scale(1.1); }
.theme-toggle-btn:active { transform: scale(0.96); }
/* Košík — na žiadosť BEZ vlastného kruhového pozadia (samotná ikonka
   priamo na textúre hlavičky), ešte väčší než predošlá "pill" verzia.
   Klikateľnosť zostáva (cursor:pointer + reálny <button>), spätnú
   väzbu dáva len jemné zväčšenie na hover/active, nie farba pozadia. */
.tracked-cart-btn {
  width: 78px;
  height: 78px;
  font-size: 48.5px;
}
.tracked-cart-btn:hover { transform: scale(1.08); }
.tracked-cart-btn:active { transform: scale(0.96); }
.tracked-cart-count {
  position: absolute;
  top: -2px;
  right: -2px;
  min-width: 26px;
  height: 26px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 15px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 0 0 2px var(--surface);
}

/* ---------- Sledované položky — výsuvný panel (drawer) ----------
   Predtým stály natrvalo v pravom sidebari vedľa kategórií (zaberali
   ~30% šírky aj keď boli prázdne) — presunuté do drawera otváraného
   ikonkou košíka, aby kategórie dostali celú šírku. Backdrop + panel sú
   position:fixed nezávisle od .layout, takže sa nepočítajú do jeho flow
   (žiadny vplyv na výšku/šírku zvyšku stránky, keď sú zatvorené). */
.tracked-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 90;
  opacity: 1;
  transition: opacity 0.22s ease;
}
.tracked-modal-backdrop.hidden { opacity: 0; pointer-events: none; }

.tracked-modal {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(440px, 100vw);
  background: var(--surface);
  border-left: 1px solid var(--border);
  box-shadow: var(--shadow-lg);
  z-index: 91;
  display: flex;
  flex-direction: column;
  transform: translateX(0);
  transition: transform 0.24s ease;
}
.tracked-modal.hidden { transform: translateX(100%); }
.tracked-modal-head {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--border);
}
.tracked-modal-head h2 { font-size: 20.5px; font-weight: 600; letter-spacing: -0.01em; }
.tracked-modal-head-actions { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }
.tracked-modal-close {
  width: 32px;
  height: 32px;
  border: none;
  border-radius: 50%;
  background: var(--surface-alt);
  color: var(--muted);
  font-size: 17px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.tracked-modal-close:hover { background: var(--border); color: var(--ink); }
.tracked-modal-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 20px;
}
@media (max-width: 600px) {
  .tracked-modal { width: 100vw; }
}

/* ---------- App shell: vodorovný sidebar pod vyhľadávaním + "Domov" dashboard ----------
   2.9.2026, na žiadosť používateľa — mockup vygenerovaný cez ChatGPT.
   3.9.2026 — na žiadosť: sidebar presunutý z ľavého zvislého pásu do
   vodorovného pásu HNEĎ POD topbarom (nad .app-shell v HTML), všetky
   položky vždy viditeľné vedľa seba (žiadne hover-reveal, žiadne
   schovávanie popiskov). .app-shell teraz obaľuje LEN .main-content
   (predtým flex-rodič pre sidebar+main-content vedľa seba) — nechaný
   ako wrapper (nie zrušený úplne), nech .main-content .layout override
   nižšie zostane funkčný bez ďalších zmien.
   Sidebar prepína medzi 4 existujúcimi/novými .app-screen sekciami cez
   switchSidebarView() v script.js — Obchody/Recepty/Obľúbené/Nastavenia
   zámerne vedú na spoločný "Čoskoro" stub (žiadna predstieraná
   funkčnosť, viď komentár v script.js). */
.app-shell {
  max-width: 1180px;
  margin: 0 auto;
  padding: 0 24px;
}
/* Rovnaký "rámik šírky" ako .topbar-container/.app-shell — vodorovný pás
   sedí presne pod vyhľadávacím pruhom, zarovnaný na tú istú ľavú/pravú
   hranu. Bez vlastnej "card" plochy (rovnaký minimalistický princíp ako
   predtým), len tenká spodná čiara ako vizuálne oddelenie od obsahu. */
.sidebar {
  max-width: 1180px;
  margin: 14px auto 20px;
  padding: 0 24px 10px;
  border-bottom: 1px solid var(--border);
}
/* 3.9.2026 — na žiadosť: vycentrované do stredu (predtým zarovnané
   vľavo) a vrátené na "hover" typ — v pokoji len ikony, popisok danej
   položky sa ukáže až pri prejdení myšou nad ňu (rovnaký princíp ako
   pôvodný zvislý sidebar pred presunom navrch, len teraz per-položka
   namiesto pre celý pás naraz). */
.sidebar-nav {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 6px;
  overflow-x: auto;
}
/* 7.9.2026 — z ikoniek sa stali KARTY SEKCIÍ, na žiadosť: "potrebujem,
   aby bolo jasné, že keď tam človek klikne, nájde recepty, prípadne
   obľúbené potraviny".

   Predtým to bolo päť rovnakých 28px štvorčekov: popisok mal v pokoji
   max-width:0 a odhaľoval sa až pri prejdení myšou (3.9.2026). Na
   dotykovom displeji sa teda NEUKÁZAL NIKDY — a appka o nákupoch sa
   používa hlavne na telefóne. Zmerané pred zmenou: šírka popisku 0 px
   pri všetkých piatich položkách.

   Pravidlo, ktoré to nahrádza: položka musí odpovedať na "čo tam
   nájdem?" PRED kliknutím a BEZ hoveru. Preto má každá dva riadky —
   názov (kam idem) a živé číslo (prečo tam ísť). */
.sidebar-link {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 9px;
  flex: 0 0 auto;
  min-width: 0;
  padding: 8px 14px;
  border: 1px solid transparent;
  background: transparent;
  border-radius: var(--radius-md);
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 15px;
  font-weight: 500;
  color: var(--muted);
  cursor: pointer;
  white-space: nowrap;
  text-align: left;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.sidebar-link-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.2;
  min-width: 0;
}
/* Živé číslo pod názvom. Toto je ten skutočný rozdiel oproti holému
   popisku: "Recepty" povie KAM ideš, "381 z akcií" povie, že sa tam
   oplatí ísť. Čísla appka aj tak už počíta. */
.sidebar-link-meta {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  /* Miesto sa drží aj keď číslo ešte nedorazilo (katalóg sa dopočítava
     na pozadí) — inak by hlavička po načítaní poskočila. */
  min-height: 13px;
}
.sidebar-link.active .sidebar-link-meta { color: var(--primary-dark); }
.sidebar-link:hover { background: var(--surface-alt); color: var(--ink); border-color: var(--border); }
.sidebar-link.active {
  background: var(--primary-soft);
  border-color: color-mix(in srgb, var(--primary) 35%, transparent);
  color: var(--primary-dark);
  font-weight: 600;
}
.sidebar-link-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  color: var(--muted);
}
.sidebar-link-icon svg { width: 22px; height: 22px; }
.sidebar-link.active .sidebar-link-icon { color: var(--primary); }
/* Popisok schovaný v pokoji (max-width:0, nie display:none, nech
   transition funguje) — objaví sa len keď je myš NAD KONKRÉTNOU
   položkou (nie nad celým pásom). */
.sidebar-link-label {
  font-size: 15px;
  font-weight: 600;
  color: inherit;
  white-space: nowrap;
}
/* Odznak Obľúbených ostáva VŽDY viditeľný (aj bez hoveru) — na rozdiel
   od popisku ide o funkčnú informáciu (koľko mám obľúbených), nie len
   dekoráciu, viď .sidebar-badge nižšie. */
/* Odznak počtu Obľúbených (viď updateFavoritesBadge() v script.js) —
   malý červený "pill" hneď za popiskom, ukáže sa len keď je > 0.
   Srdiečko samo tiež zosčervenie (.has-favorites nižšie), nech je
   "mám niečo obľúbené" jasné na prvý pohľad aj bez čítania čísla. */
.sidebar-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  /* Vlastný odsad od ikony NEZÁVISLE od .sidebar-link gap (ten je 0 v
     pokoji, kým sa položka nehoveruje) — odznak je vždy viditeľný, musí
     mať teda vždy aj svoj priestor od ikony. */
  margin-left: 4px;
  border-radius: 999px;
  /* Rovnaká farba ako aktívne (obľúbené) srdiečko na karte produktu
     (.favorite-btn.active vyššie) — jeden vizuálny jazyk pre "obľúbené"
     naprieč appkou. */
  background: var(--accent);
  color: #fff;
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1;
}
.sidebar-link-favorites.has-favorites .sidebar-link-icon { color: var(--accent); }
.sidebar-link-favorites.has-favorites .sidebar-link-icon svg { fill: var(--accent); }

.main-content { min-width: 0; }
/* .app-shell už dáva 24px bočný odsah (viď vyššie) — bez tohto by sa
   .layout vlastný padding pripočítal navyše (zdvojený odsah). Scoped LEN
   na .main-content potomka — /basket-clean tiež používa .layout (mimo
   .main-content), tam ostáva pôvodný padding nezmenený. */
.main-content .layout { padding: 0; }

@media (max-width: 760px) {
  .app-shell { padding: 0 16px; }
  .sidebar { padding: 0 16px 8px; margin: 10px auto 12px; }
  .sidebar-nav { gap: 2px; }
  .sidebar-link { padding: 8px 12px; gap: 6px; }
}

/* ---------- Domov: hero + CTA banner ----------
   2.9.2026 — "to chcem mat 1:1 s tymto" (používateľ poslal referenčný
   mockup priamo). Prestavané zámerne DOSLOVNE podľa jeho štruktúry:
   biele/takmer biele pozadie bez rámu (nie card s bodkovanou textúrou
   ako predtým), dvojfarebný nadpis (čierna + zelená druhá riadka),
   sekundárny "Ako to funguje?" odkaz vedľa CTA, telefón s "kartou
   receptu" a plávajúcimi produktovými fotkami s % odznakmi navôkol.
   Plávajúce fotky (brokolica/paradajky/jogurt) sú REÁLNE fotky z
   product_images_clean/lidl/ (appka fotobanku produktov už má — presnejšie
   než emoji), receptová fotka v karte ostáva ikona/emoji (appka nemá
   fotografie k receptom, viď local_recipe_db.py `"image": None`). */
/* 2.9.2026 — "do jedného rámu na šírku": text a ilustrácia späť v
   JEDNOM riadku vedľa seba (nie stackované na výšku), CELÝ tento riadok
   je teraz JEDEN rám v rovnakom vizuálnom jazyku ako .category-showcase
   (bodkovaná textúra, rám, tieň) a rovnakej šírky ako tá sekcia —
   presne ako na referenčnom obrázku (text vľavo, telefón/zľavy vpravo,
   spolu v jednej "karte" bez viditeľnej hranice medzi nimi). */
/* 2.9.2026 — späť na rovnakú bodkovanú/zelenkastú textúru ako
   .category-showcase/.store-showcase (na žiadosť: "jednotné" so
   zvyškom Domov obrazovky). Predošlý dôvod na plochú bielu farbu (švík
   okolo veľkej bielej plochy telefónu) je s NOVÝM obrázkom (menší,
   detailnejší telefón obklopený farebnými surovinami, nie jedna veľká
   biela karta) oveľa menej výrazný — vizuálna jednotnosť teraz váži
   viac. */
/* 2.9.2026 — späť na DVE samostatné karty (na žiadosť: "rozdel tú
   spojenú bublinu, nech je vidno rozdiel, ale nech to nie je taký
   veľký rozdiel ako predtým") — .dashboard-hero-combo je teraz len
   layout obal (žiadne vlastné pozadie/rám), medzera medzi kartami len
   ~0.5cm (19px), nie pôvodných 40px. */
/* 3.9.2026, na žiadosť — medzera PRED "Prehľadávaj podľa kategórie"
   bola nápadne väčšia než medzera VNÚTRI kombo (hero → riadok
   obchodov): žiadny vlastný margin-bottom, .dashboard-hero-combo je
   flex dieťa .app-screen.is-active (gap nižšie) — tá istá hodnota ako
   vnútorný gap tu zaručuje presne rovnaké medzery na oboch miestach
   namiesto dvoch nezávislých čísel, čo by sa museli ručne držať v sync
   (10.9.2026 — obe znížené na 12px, viď komentár pri .app-screen.is-
   active). */
/* 10.9.2026 — na žiadosť "uprav medzeri medzi kategoriami, nech je mala
   ale stale viditelna, toto je moc velke": medzera medzi panelmi tu
   bola v skutočnosti DVOJITÁ — .dashboard-hero-combo mala vlastný gap
   (20px) MEDZI panelmi, ale každý .feature-panel v nej NAVYŠE nosí
   vlastný margin-top (základné pravidlo nižšie, platí naprieč celou
   appkou) — flex gap a margin sa nekolabujú, takže sa oba sčítali
   (20 + pôvodných 18 = 38px). Riešenie: panely vnútri combo majú
   margin-top vynulovaný (nižšie, .dashboard-hero-combo > .feature-panel)
   a CELÁ medzera ide len cez gap — rovnaká hodnota ako znížený globálny
   margin-top (12px), nech je rytmus rovnaký aj mimo combo (napr. medzi
   "Kde nakupuješ" a "Najväčšie zľavy dňa", ktorá je mimo combo). */
.dashboard-hero-combo {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.dashboard-hero-combo > .feature-panel { margin-top: 0; }
/* 10.9.2026 — na žiadosť "to Zľavy, ktoré varia za vás by som normálne
   dal von z toho podkladu", doplnené "potrebujem aj ten obrazok
   vytiahnut z podkladu. dam to vedla seba a upravim si velkost": hero
   predtým bol textúrovaná karta (bodky+wash pozadie, rám, tieň) s
   textom aj obrázkom vnútri. Teraz je to len PRIEHĽADNÝ flex riadok —
   žiadne pozadie/rám/tieň, text a obrázok sedia priamo na pozadí
   stránky, vedľa seba. Presnú veľkosť/pozíciu obrázka si používateľ
   dolaďuje sám cez živý editor (?hero_edit=1, --hero-img-max/-x/-y). */
/* 10.9.2026 — na žiadosť "potrebujem zarovnat tie texty aby boli v
   jednej liinii... Zlavy ktore varia za vas a to Nastav si hladanie":
   justify-content bolo center, takže text+obrázok sedeli ako
   vycentrovaný celok a nadpis nezačínal pri ľavom okraji rovnako ako
   ostatné panely nižšie (posun závisel od šírky obrázka, teda sa menil
   s každým doladením cez živý editor — nedalo sa to trvalo zarovnať
   žiadnou pevnou hodnotou). flex-start zarovná nadpis na rovnaký ľavý
   okraj ako "Nastav si hľadanie" a všetky ostatné panely, na akejkoľvek
   šírke. Ak si používateľ obrázok znova posunie/zväčší cez ?hero_edit=1,
   jeho pozícia (--hero-img-x/-y) je nezávislý transform, takže sa
   dolaďuje rovnako ako doteraz — len počiatočný bod riadku je teraz
   vľavo namiesto v strede. */
.dashboard-hero {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 18px;
  padding: 6px 8px 4px;
  overflow: visible;
}
/* 10.9.2026 — na žiadosť "potrebujem ten text zvacsit, aby to ladilo k
   tomu zvacsnemu obrazku na hero": obrázok si používateľ zväčšil cez
   ?hero_edit=1 na 520px (--hero-img-max, pôvodne 400px), takže textový
   stĺpec pri pôvodných 300px/37px vyzeral vedľa neho maličko. Stĺpec aj
   nadpis/text zväčšené v rovnakom pomere (cca +18-20 %). */
.dashboard-hero-text { flex: 0 0 360px; max-width: 360px; align-self: flex-start; }
/* 5.9.2026 — hero nadpis prešiel z Inter 800 na Fraunces.
   Appka si Fraunces sťahovala od začiatku (viď @import navrchu), ale
   používala ju len na 18px sekčné nadpisy — teda platila za písmo s
   charakterom a nasadzovala ho tam, kde ho nikto nevidí, kým NAJVÄČŠÍ
   text na stránke bol štandardný grotesk. Fraunces má optickú os
   (opsz 9..144): pri veľkom písme sama zvýši kontrast ťahov, takže
   nadpis vyzerá ako sadzba, nie ako zväčšené UI. Sedí aj obsahovo — je
   to appka o jedle a receptoch, nie dashboard. */
.dashboard-hero-title {
  font-family: 'Plus Jakarta Sans', Georgia, serif;
  /* Pripnutá optická os — viac pri .feature-title nižšie. Bez toho
     kreslí Fraunces v úzkom okne iný rez než na širokom, takže sa
     nadpis "zmení" pri zmenšení okna. */
  font-optical-sizing: none;
  font-variation-settings: 'opsz' 40;
  font-weight: 700;
  font-size: clamp(34.5px, 4.6vw, 50.5px);
  line-height: 1.05;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0 0 16px;
}
.dashboard-hero-title-accent { color: var(--primary); }
/* Rovnaká oranžová ako v logu (FoodHack), viď static/img/logo.svg. */
.dashboard-hero-title-orange { color: var(--accent); }
/* 10.9.2026 — na žiadosť "tento text prosimta zvacsit a na zaver tam
   daj nieco uderne ako napriklad 'Hackni ceny, uvar lacnejsie'": text
   zväčšený (16→18px), pridaný skutočný slogan appky (rovnaký, aký je v
   <title>/topbar) ako tučná, výraznejšia záverečná veta. */
/* 22.9.2026 na žiadosť ("sprievodné texty pod nadpismi... rovnako veľký
   font") — pôvodne 20.5px, jediné miesto v appke, kde sprievodný text
   pod nadpisom sekcie nemal veľkosť .feature-dek (15.5px, použité
   všade inde). Prvý pokus zjednotenia zmenšil TENTO text na 15.5px —
   presný opak toho, čo používateľ chcel ("nech sú všetky veľké ako
   hero, vyzeralo to super"). Správne teda .feature-dek zväčšené NA
   20.5px (nižšie), tento text ostáva pôvodný. */
.dashboard-hero-dek { font-size: 20.5px; line-height: 1.55; color: var(--muted); max-width: 46ch; margin: 0 0 22px; }
.dashboard-hero-dek strong { color: var(--ink); font-weight: 700; }

/* "Ako to funguje?" prešlo cez viacero podôb (okno na klik, krokovač v
   Hero, samostatný panel pod "Nastav si hľadanie" — viď git history).
   22.9.2026 na žiadosť "dajme to naspäť ako to bolo predtým, s tým 'i'
   a normálny hover" — návrat k PÔVODNÉMU riešeniu z 3.9.2026 (commit
   d1fd337): čisto CSS hover/focus popover, žiadny JS, jeden trigger,
   všetkých 6 bodov naraz. Ikony pri jednotlivých bodoch (pôvodne emoji)
   vynechané — appka má odvtedy pravidlo "žiadne emoji v UI" (viď git
   history, "Emoji odstran vsade"), samotné "ⓘ" na tlačidle ostáva, lebo
   si ho používateľ výslovne vyžiadal. */
.dashboard-hero-actions { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }
.dashboard-hero-howto {
  border: none;
  background: none;
  padding: 0;
  font-family: 'Inter', sans-serif;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
}
.dashboard-hero-howto:hover { color: var(--ink); }
.howto-trigger-wrap { position: relative; display: inline-flex; }
/* 22.9.2026 na žiadosť "zväčši ten hover, aby to bolo dobre čitateľné
   aj na PC aj na mobile" — širšie okno (340→460px), väčšie písmo aj
   riadkovanie a viac vzduchu medzi bodmi (predtým 12/12.5px pôsobilo
   na popovere s 6 plnými odsekmi ako drobný "papierik"). */
.howto-popover {
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 12px;
  width: 460px;
  max-width: 88vw;
  padding: 24px 26px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 60;
}
.howto-trigger-wrap:hover .howto-popover,
.howto-trigger-wrap:focus-within .howto-popover {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
}
.howto-popover-title {
  margin: 0 0 16px;
  font-family: 'Fraunces', serif;
  font-size: 20px;
  font-weight: 700;
  color: var(--ink);
}
.howto-popover-item + .howto-popover-item { margin-top: 18px; }
.howto-popover-item strong { display: block; font-size: 16px; color: var(--ink); margin-bottom: 4px; }
.howto-popover-item p { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--muted); }
/* Na úzkom mobile by vycentrovanie POD tlačidlom (to sedí niekde vľavo v
   texte) posunulo široký popover mimo obrazovku doľava — position:fixed
   viazaná na VIEWPORT, nie na malé tlačidlo, je jediný spoľahlivý
   spôsob, ako to udržať vždy v rámci obrazovky bez ohľadu na to, kde sa
   tlačidlo v texte nachádza. */
@media (max-width: 520px) {
  .howto-popover {
    position: fixed;
    left: 16px;
    right: 16px;
    top: 78px;
    width: auto;
    max-width: none;
    max-height: calc(100vh - 96px);
    overflow-y: auto;
    margin-top: 0;
    padding: 20px 20px;
  }
}

/* 2.9.2026 — používateľ trval na doslovnom 1:1 obrázku z jeho mockupu
   ("normálne nahraď to čo si vytvoril týmto"), nie na CSS/SVG
   rekonštrukcii. hero-phone-mockup.png je orezaná časť jeho vlastného
   vygenerovaného návrhu (len telefón + plávajúce zľavy, bez okolitého
   UI iných sekcií) — uložená v static/img/, biele pozadie odstránené
   (transparentné PNG), preto obrázok sedí priamo na textúre rámu bez
   vlastnej "karty v karte". */
/* 2.9.2026 — POZOR: záporný margin-bottom (pop-out efekt) tu spôsoboval
   viditeľnú chybu — pri overflow:visible + border-radius na rodičovi sa
   pravouhlý spodný okraj obrázka stretával so ZAOBLENÝM rohom karty a
   v rohu ostávala medzera, cez ktorú presvitalo pozadie STRÁNKY (nie
   karty) — presný opak "PRESNE zarovno" čo používateľ žiadal. Späť na
   0 — obrázok sedí presne na spodnej hrane paddingu, žiadny presah,
   žiadna medzera v rohu. Ilustrácia ostáva zväčšená (max-width 660px). */
/* --hero-img-max/--hero-img-x/--hero-img-y — nastavuje ich živý editor
   na /dev/hero-editor (drag = pozícia, koliesko = veľkosť), potom sa
   uložia sem natrvalo cez /api/dev/hero-editor/save. Defaulty nižšie
   platia, kým editor niečo neuloží. */
:root { --hero-img-max: 600px; --hero-img-x: 147px; --hero-img-y: 6px; }
/* flex-shrink:0 — bez toho flexbox tíško ZMENŠOVAL položku na dostupný
   priestor v riadku bez ohľadu na --hero-img-max (preto sa cez editor
   dalo "zväčšiť len o pár pixelov" — premenná sa menila, ale flex-shrink:1
   ju vzápätí sťahoval späť na to, čo sa zmestilo vedľa textového stĺpca).
   Teraz --hero-img-max naozaj platí a obrázok môže presiahnuť aj cez
   pravý okraj karty (rovnaký princíp ako pop-out vrecka dole). */
/* flex-basis JE --hero-img-max (nie samostatný max-width vedľa menšej
   basis) — grow/shrink 0/0, aby veľkosť diktovala VÝHRADNE táto
   premenná, bez ohľadu na to, koľko miesta zostáva v riadku vedľa textu
   (predošlý pokus s flex-grow rástol len po hranicu dostupného
   priestoru v riadku, nie po skutočnú hodnotu premennej). */
.dashboard-hero-art { flex: 0 0 var(--hero-img-max); align-self: flex-end; position: relative; overflow: visible; }
.hero-mockup-img {
  display: block;
  width: 100%;
  height: auto;
  transform: translate(var(--hero-img-x), var(--hero-img-y));
  filter: drop-shadow(0 16px 22px rgba(20, 20, 15, 0.16));
}
@media (max-width: 760px) {
  .dashboard-hero { flex-direction: column; align-items: stretch; padding: 12px 12px 4px; text-align: left; }
  .dashboard-hero-text { max-width: 100%; padding-bottom: 8px; }
  /* flex-direction:column tu mení hlavnú os na ZVISLÚ — flex-basis by
     inak ovplyvňoval VÝŠKU namiesto šírky (--hero-img-max je myslené
     ako šírka). flex:0 0 auto + max-width vráti kontrolu šírky späť
     samotnému obrázku (width:100% v .hero-mockup-img). */
  .dashboard-hero-art { flex: 0 0 auto; max-width: 420px; margin: 0 auto; align-self: center; }
}

/* 10.9.2026 — "Recepty podľa rozpočtu": bývalý 3. stĺpec v .dashboard-hero
   (viď git história), teraz vlastný panel s rovnakou anatómiou ako
   .feature-panel--weekly (štítok/nadpis/veta cez .feature-title/-dek,
   obsah v .feature-panel-body) — na žiadosť "toto by mala byt samostatna
   tabulka... aby to bolo prehladnejsie". Skutočnú prácu robí existujúci
   Plánovač (#budget-input/#budget-output atď.) — klik na #hero-budget-btn
   (viď script.js) len predvyplní jeho polia a prepne naň, žiadna
   paralelná/duplicitná generovacia logika. */
/* 10.9.2026 — druhé kolo: na žiadosť "daj tie moznosti pod seba:
   Varenie/Pecenie, bezlaktozove atd, Cena, Najst recepty" — vodorovný
   rad (predošlé riešenie "nevyzera to dobre vizualne", viď história
   vyššie) nahradený zvislým stĺpcom v presne tomto poradí. .feature-
   actions (predtým spoločný obal pre input+tlačidlo v jednom riadku)
   je preč — input aj tlačidlo sú teraz samostatné, každé na vlastnom
   riadku. */
/* align-items:flex-start (nie stretch) — na žiadosť "potrebujem aby to
   jak je Pecenie tak aby tam aj skoncila ta tabulka, taha sa to po
   celom backu": stretch naťahoval AJ .cook-mode (jedna súvislá pilulka
   s pozadím) na celú šírku panelu, aj keď "Varenie"/"Pečenie" text
   zaberá len zlomok — pozadie pilulky tak zbytočne "ťahalo" ďaleko za
   posledné tlačidlo. flex-start necháva každý riadok prirodzenú šírku;
   input/tlačidlo majú vlastnú width:100% (nižšie) len po svoj vlastný
   max-width, nie po celú šírku panelu. */

/* 10.9.2026 — panel "Filter" (konsolidované diétne filtre + varenie/
   pečenie, viď index.html) — rovnaký zvislý vzor ako .dashboard-hero-
   budget-body vyššie (flex-start, nie stretch, z rovnakého dôvodu:
   .cook-mode by sa inak naťahoval na celú šírku panelu). Diétne pilulky
   sú vo vlastnom riadku pod prepínačom varenie/pečenie, zalomia sa pri
   užšom okne namiesto zmenšovania.
   10.9.2026 — na žiadosť "nastavil som si to na stred... aj tie filtre
   hned pod to... iba zarovnat": predtým flex-start (zarovnané k
   ľavému okraju), teraz center — každá podsekcia (obchody/varenie-
   pečenie/diéta) je vycentrovaná ako blok, rovnako ako obchody, ktoré
   si používateľ vycentroval cez živý editor. */
.filter-panel-body { display: flex; flex-direction: column; align-items: center; gap: 18px; width: 100%; }
/* 20.9.2026 — na žiadosť "presunut hore pri ten text a neako to oddelit
   pre dobru prehladnost": filtre teraz sedia VEDĽA nadpisu/vety
   (.screen-hero-head), nie pod nimi na celú šírku — rovnaký vzor ako
   .screen-hero-panel na Obľúbených/Pláne (text vľavo, funkčný panel
   vpravo, obe v tej istej ploche .screen-hero, žiadna vnorená karta).
   Oddelenie ("prehľadnosť") rieši border-left — tenká čiara medzi textom
   a filtrami, nie ďalšie pozadie/rám (to by pôsobilo ako "dve krabice",
   presne čo appka inde zámerne nerobí, viď komentár pri
   .screen-hero-panel). Pod .screen-hero-panel breakpointom (1050px) sa
   panel zalomí pod text na celú šírku — čiara sa vtedy otočí na
   border-top (rovnaká deliaca funkcia, len vodorovne). */
.screen-hero-panel.filter-panel-side {
  flex: 0 0 380px;
  max-width: 380px;
  gap: 20px;
  border-left: 1px solid var(--border);
  padding-left: 26px;
}
.filter-panel-side .filter-subsection { align-items: flex-start; }
.filter-panel-side .planner-label,
.filter-panel-side .filter-panel-diet,
.filter-panel-side .cook-mode { justify-content: flex-start; }
@media (max-width: 1050px) {
  .screen-hero-panel.filter-panel-side {
    border-left: none;
    padding-left: 0;
    border-top: 1px solid var(--border);
    padding-top: 22px;
    margin-top: 4px;
  }
}

.filter-panel-diet { flex-wrap: wrap; gap: 8px; align-items: center; justify-content: center; }
.filter-panel-side .filter-panel-diet { align-items: center; }

/* 20.9.2026 na žiadosť "daj to na hover, do ikonka" — vysvetlenia troch
   obmedzených filtrov (Rýchle/Proteínové/Len veľké zľavy) už nie sú stály
   text pod pilulkami, ale tooltip na malej "i" ikonke hneď vedľa nich.
   CSS-only (žiadny nový JS): bublina je skrytá cez opacity/visibility a
   ukáže sa na :hover AJ :focus-visible (klávesnica/čítačka obrazovky
   dostanú ten istý obsah, nielen myš). Tlačidlo, nie span — má byť
   dosiahnuteľné Tabom, na rozdiel od čistej dekorácie. */
.info-tip {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 17px;
  height: 17px;
  padding: 0;
  border: none;
  background: none;
  color: var(--muted);
  cursor: help;
}
.info-tip:hover, .info-tip:focus-visible { color: var(--primary); }
.info-tip-icon { width: 100%; height: 100%; }
.info-tip-bubble {
  position: absolute;
  bottom: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%) translateY(4px);
  width: 240px;
  max-width: 62vw;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--ink);
  color: var(--surface);
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 12.5px;
  font-weight: 400;
  line-height: 1.45;
  text-align: left;
  box-shadow: var(--shadow-md);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 5;
}
.info-tip-bubble::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: var(--ink);
}
.info-tip:hover .info-tip-bubble,
.info-tip:focus-visible .info-tip-bubble {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0);
}
@media (max-width: 480px) {
  .info-tip-bubble { width: 200px; left: auto; right: -8px; transform: translateY(4px); }
  .info-tip-bubble::after { left: auto; right: 12px; transform: none; }
  .info-tip:hover .info-tip-bubble,
  .info-tip:focus-visible .info-tip-bubble { transform: translateY(0); }
}
/* 10.9.2026 — na žiadosť "a toto vsetko vedla seba pod tie obchody":
   Varenie/Pečenie a diétne pilulky boli dovtedy dva samostatné riadky
   pod sebou — teraz jeden vodorovný riadok, ktorý sa pri nedostatku
   miesta zalomí (flex-wrap), nie dva pevné bloky. */
.filter-controls-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px;
}

/* 10.9.2026 — na žiadosť "chcem odstranil tu tabulku... aby mali taky
   vizual ako hlavna grafika": panel "Nastav si hľadanie" stráca bento
   kartu úplne (pozadie/orámovanie/tieň/padding) — rovnaký priehľadný
   vzor ako .dashboard-hero vyššie (obsah sedí priamo na pozadí
   stránky). Nedotýka sa .feature-panel základu (ten zdieľajú ostatné
   panely, ktoré kartu majú mať), len tento jeden modifikátor ho ruší. */
.feature-panel.feature-panel--freeform {
  background-image: none;
  background-color: transparent;
  border: none;
  box-shadow: none;
  padding: 6px 8px 4px;
}

/* 10.9.2026 — na žiadosť "keby to dame do jednej kategorie... aby to
   malo zmysel a bolo to prehladne": panel "Nastav si hľadanie" zlučuje
   obchody + spôsob prípravy + diétu do JEDNÉHO panelu — bez vlastného
   labelu pri každej voľbe by to pôsobilo ako jeden neprehľadný blok.
   Label je zámerne menší a tlmenejší než feature-title (podradený
   nadpis vnútri panelu, nie ďalšia sekcia stránky). */
.filter-subsection { display: flex; flex-direction: column; align-items: center; gap: 10px; width: 100%; }
.filter-subsection-label {
  margin: 0;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--muted);
}
/* Mriežka obchodov je teraz podsekcia tohto panelu (predtým vlastný
   .feature-panel.store-showcase) — selektor cez #dashboard-store-row
   (jedinečné ID), aby fungoval nezávisle od nadradenej štruktúry a
   nezasahoval do zdieľaného .store-tiles/.store-card na obrazovke
   "Zľavy" (tie ostávajú v riadku).
   10.9.2026 — na žiadosť "obchody... vsetko vo vodorovnej polohe":
   2×2 mriežka zrušená, späť na vodorovný RAD (base .store-tiles je už
   flex row — stačí nedediť vlastný display:grid). Veľkosť kariet
   naďalej škáluje --store-row-scale (živý editor), len teraz do
   šírky/výšky vodorovného radu namiesto štvorcovej mriežky. */
/* 10.9.2026 — na žiadosť "potrebujem tie obchody este viac zvacsit a
   roztiahnut po celej dlzke riadku ktory pouzivame": max-width:640px
   predtým bránil radu vyplniť celú šírku panelu. Odstránené — rad
   (aj karty v ňom, viď nižšie flex-grow:1) sa teraz roztiahne na celú
   dostupnú šírku. */
.store-tiles--freeform {
  gap: calc(14px * var(--store-row-scale));
}
/* 10.9.2026 — na žiadosť "v sekcii Kde nakupujes mi to ukazuje stale
   odkedy dokedy tam plati ten letak. Ja by som chcel aby mi to ukazalo
   az ked ho oznacim... cistejsie a jemnejsie", doplnené po prvom pokuse
   (opacity, karta si držala pevnú výšku so skrytým odznakom) spätnou
   väzbou *"ten ramik je moc velky... ked to neni oznacene tak nech je
   ta tabulka mensia aby tam to logo 100% fitlo, a ked ho oznacim tak
   sa proste zvacsi"*: karta má teraz DVE výšky — menšiu v pokoji (logo
   bez rezervy pre odznak) a väčšiu pri `.active` (logo + odznak),
   `height` je v prechode (`transition`), takže označenie obchodu kartu
   plynulo ZVÄČŠÍ namiesto skoku. `overflow:hidden` odznak počas
   zmenšenej výšky oreže (nie je vidno, kým sa karta nezväčší). */
/* 10.9.2026 — na žiadosť "tie loga musia presne fitovat do toho ramu.
   ram je velky a logo male": pri `flex-grow:1` sa karta na širšej
   obrazovke naťahovala na celú dostupnú šírku, takže "široké" logá
   (Kaufland/Tesco, pomer strán ~4:1) mali v hornej/spodnej časti rámu
   prázdny pás (logo je width-bound, na výšku sa nedokáže dotiahnuť bez
   toho, aby pretieklo cez šírku). `flex-grow:0` drží kartu pri jej
   basis šírke bez ohľadu na okolitý voľný priestor — konzistentný
   pomer strán rámu naprieč šírkami obrazovky, namiesto toho, aby sa
   naťahoval a robil problém horší.
   10.9.2026 — DRUHÝ pokus (45→36px) bol príliš agresívny ("ty si tie
   loga este viac zmensil... potrebujem normalnu viditelnu dobru
   velkost"): 56px vracia logám normálnu čitateľnú veľkosť, rám je
   naďalej tesný okolo najširšieho loga (Kaufland/Tesco). Označenie
   teraz zväčší AJ šírku (`flex-basis`), nielen výšku — celý rám aj logo
   v ňom vizuálne narastú spolu, nie len miesto na odznak dole.
   10.9.2026 — TRETÍ pokus: "este viac zvacsit a roztiahnut po celej
   dlzke riadku" chce presný OPAK flex-grow:0 (ktorý úmyselne držal
   kartu pri pevnej šírke, viď vyššie). Riešenie oboch požiadaviek
   naraz: `flex-grow:1` (karty vyplnia celý riadok, rastú s ním) +
   `aspect-ratio` namiesto pevnej `height` — pomer strán rámu ostáva
   konštantný nech je výsledná šírka akákoľvek (rad na širšej obrazovke
   vyplní viac priestoru → karty sú širšie AJ vyššie v rovnakom pomere),
   takže logo zostáva rovnako tesne fitnuté ako predtým namiesto toho,
   aby sa znova objavil prázdny pás pri roztiahnutí. */
.store-tiles--freeform .store-card {
  flex: 1 1 calc(130px * var(--store-row-scale));
  aspect-ratio: 2.3 / 1;
  padding: 6px;
  overflow: hidden;
  transition: aspect-ratio 0.22s ease, transform 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease, border-color 0.18s ease;
}
.store-tiles--freeform .store-card.active {
  aspect-ratio: 1.85 / 1;
}
/* 10.9.2026 — na žiadosť "Daj tie obchody bez ramu. Budu v rame az ked
   ich oznacime": logo bez pozadia/tieňa v pokoji (len samotné logo
   na pozadí stránky, rovnaký princíp ako hero) — zelený prstenec
   (`.store-card.active`, existujúce pravidlo nižšie) sa objaví až po
   označení. `:not(.active)` namiesto poradia v súbore — bez neho by
   pravidlo malo rovnakú špecifickosť ako `.store-card.active` a mohlo
   by (podľa poradia v súbore) prebiť jeho farebné pozadie/prstenec pri
   označenej karte.
   18.9.2026 — na žiadosť "chcem aby Neoznacene boli v ciernom ramе":
   priehľadný rám dovtedy pôsobil ako "chýbajúci prvok", nie ako
   "neoznačené tlačidlo" — skúšané najprv s var(--ink) (čierny/biely
   podľa témy), potom na žiadosť "chcel by som aby ten ram mal taku istu
   farbu ako ked je oznaceny... cize cierna prec. ostava zelena"
   prehodené na var(--primary) — rám je ZELENÝ v oboch stavoch, líši sa
   len VÝPLŇ (žiadna tu vs. --primary-soft pri .active nižšie). Hrubší
   (2px, nie zdieľaná 1px báza) na žiadosť "chcem aby bol ten ram o
   nieco hrubsi" — báza by zmenila aj rám PRI hoveri (border-color:
   var(--border-strong) vyššie), samostatná šírka tu sa netýka ničoho
   iného. */
.store-tiles--freeform .store-card:not(.active) {
  border-width: 2px;
  border-color: var(--primary);
  background-image: none;
  background-color: transparent;
  box-shadow: none;
}
/* 10.9.2026 — na žiadosť "ked oznacim ten obchod... datum ukaze velmi
   malinky. potrebujem aby to tam bolo vyrazne tak ako predtym": karta
   medzičasom vyrástla (flex-grow:1, vypĺňa celý riadok, viď vyššie),
   ale odznak škáloval cez --store-row-scale — tá premenná odteraz
   riadi len detaily (gap/padding/badge), NIE šírku karty (tú už určuje
   flex-grow, nie scale), takže keď si používateľ cez živý editor
   znížil scale (v snahe zmenšiť kartu, ako fungovalo predtým), karta
   ostala rovnako veľká, ale odznak sa zmenšil na nečitateľných ~6px.
   Pevná veľkosť (nie násobená scale) — pri novom rozložení dáva zmysel
   len jedna, vždy čitateľná veľkosť odznaku bez ohľadu na scale. */
.store-tiles--freeform .store-card-period-badge {
  font-size: 15px;
  padding: 3px 9px;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.store-tiles--freeform .store-card.active .store-card-period-badge { opacity: 1; }
@media (max-width: 640px) {
  .store-tiles--freeform { flex-wrap: wrap; }
  .store-tiles--freeform .store-card { flex: 1 1 calc(45% - 10px); }
}

/* Typografická stupnica appky: 37 (hero) / 20 (sekcia) / 14.5 (text) /
   12 (popisky). 18px sekčný nadpis bol od 14.5px textu tak blízko, že
   hierarchia nebola vidieť; 20px ju otvorí bez toho, aby konkuroval
   hero nadpisu. Katalóg receptov si 20px prepisoval sám — teraz to platí
   všade rovnako. */
.dashboard-section-title {
  font-family: 'Plus Jakarta Sans', Georgia, serif;
  font-optical-sizing: auto;
  font-weight: 600;
  font-size: 23px;
  letter-spacing: -0.01em;
  text-wrap: balance;
  color: var(--ink);
  margin: 0 0 12px;
}

.dashboard-cta-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 16px;
  padding: 22px 28px;
  background: var(--primary-soft);
  border: 1px solid var(--primary);
  border-radius: var(--radius-lg);
}
.dashboard-cta-text h2 { font-family: 'Plus Jakarta Sans', serif; font-weight: 600; font-size: 21.5px; margin: 0 0 6px; color: var(--ink); }
.dashboard-cta-text p { margin: 0; font-size: 15.5px; color: var(--muted); max-width: 48ch; }

.coming-soon-box { text-align: center; padding: 64px 20px; }
.coming-soon-icon { font-size: 50.5px; margin: 0 0 14px; }
.coming-soon-box h2 { font-family: 'Plus Jakarta Sans', serif; font-size: 24px; margin: 0 0 8px; color: var(--ink); }
.coming-soon-box p { color: var(--muted); font-size: 16px; margin: 0 0 20px; }

/* ---------- Category showcase ----------
   Kartová mriežka s reálnou produktovou fotkou na kategóriu (žiadne
   emoji/ikony), v štýle kosik.sk — CSS grid namiesto pôvodného
   horizontálne scrollovateľného flex riadku, aby boli všetky kategórie
   viditeľné naraz (zalomené do niekoľkých riadkov), bez posúvania.
   Kontajner má biele pozadie (var(--surface) = #FFFFFF v light režime),
   karty svetlosivé (var(--surface-alt) ≈ #F1F1EA, zadaním požadované
   #f4f5f7 je prakticky identické) — v tmavom režime sa oba prirodzene
   prispôsobia zvyšku appky namiesto toho, aby ostal natvrdo biely/sivý
   blok uprostred tmavej stránky. Odkedy "Sledované položky" presunuté
   do výsuvného panela (viď .tracked-modal vyššie), je to teraz blok na
   CELÚ šírku .layout (predtým ľavých ~70 % vedľa "Sledovaných"). */

/* Výber obchodov — samostatný blok NAD kategóriami, rovnaký vizuálny
   jazyk ako .category-showcase (tá istá surface/border/radius), aby
   appka pôsobila jednotne. Zámerne KOMPAKTNÝ — bola to pôvodne vysoká
   dominantná sekcia, doladené na vzdušnejší pruh, ktorý nezaberá zbytočne
   veľa miesta. Multi-select (viď activeStores v script.js) — na rozdiel
   od kategórií tu klik na kartu filtruje HNEĎ (žiadne "Hľadať akcie"),
   lebo výber obchodu je základný rozsah, nie postupné doladenie. */
.store-showcase {
  display: flex;
  flex-direction: column;
  padding: 14px 20px;
  /* Rovnaká jemná textúra (bodky + zelenkastý prechod) ako
     .topbar-card/.category-showcase/.panel — pozri .category-showcase
     pre podrobné zdôvodnenie hodnôt. */
  background-image: var(--dots-quiet), var(--wash-quiet);
  background-size: 22px 22px, 100% 100%;
  background-position: 0 0, 0 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
/* 10.9.2026 — panel obchodov na Domov zlúčený do "Nastav si hľadanie"
   (viď #dashboard-store-row pravidlá pri .filter-subsection vyššie);
   .store-showcase.dashboard-store-row a .dashboard-store-row .store-*
   tu predtým bývalo, teraz mŕtvy kód (žiadny element už nenesie triedu
   .dashboard-store-row). */
/* Malý prepínač "Vybrať všetko" nahradil predošlú veľkú dlaždicu
   "Všetky" v mriežke (tá pri len 4 logách zbytočne rušila) — svieti
   presne vtedy, keď je activeStores prázdna (= žiadny filter, všetko
   zobrazené), rovnaký princíp ako .store-card.active nižšie.
   PREDTÝM position:absolute v rohu — pri nižších .store-card (25. 8. 2026
   zmenšenie o 25 %) sa tým prekrývalo s logom posledného obchodu (Billa).
   Teraz normálny tok (.store-showcase je flex-column), zarovnané k
   pravému okraju cez align-self, žiadne prekrytie nie je možné. Aj
   drobne zmenšené (font/padding). */
.store-select-all-btn {
  align-self: flex-end;
  margin-bottom: 10px;
  border: 1px solid var(--border);
  background: var(--surface-alt);
  color: var(--muted);
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 13px;
  font-weight: 600;
  padding: 5px 12px;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.store-select-all-btn:hover { border-color: var(--border-strong); }
.store-select-all-btn.active {
  background: var(--primary-soft);
  color: var(--primary-dark);
  border-color: var(--primary);
}

/* 28.8.2026 — na žiadosť používateľa: vegetariánsky/bezlepkový/bez
   laktózy filter dostupný priamo v rýchlom paneli (hneď pri výbere
   obchodov), nie len po scrollnutí nižšie k "Nákup" panelu. Zdieľa
   .vegetarian-toggle vzhľad (pilulka), len kompaktnejší variant a
   zostáva SYNCHRONIZOVANÝ s hlavnými prepínačmi (viď script.js) —
   jeden spoločný stav, dve miesta na ovládanie. */
.quick-diet-toggles { display: flex; flex-wrap: wrap; gap: 6px; }
.quick-diet-toggle { padding: 6px 12px; font-size: 14px; }
/* Flex (nie grid) s nowrap — presne 4 logá MUSIA ostať v jednom riadku
   bez ohľadu na šírku obrazovky, preto sa karty pri úzkom viewporte
   zmenšujú spoločne (flex-shrink) namiesto toho, aby jedna odskočila do
   ďalšieho riadku. */
.store-tiles {
  display: flex;
  flex-wrap: nowrap;
  justify-content: center;
  gap: 20px;
  /* Bez max-width stropu — karty (flex 1 1, viď .store-card) sa roztiahnu
     cez takmer celú šírku kontajnera namiesto zhluku v strede. */
  width: 100%;
}
.store-card {
  position: relative;
  flex: 1 1 220px;
  min-width: 64px;
  max-width: 300px;
  /* 112px → 128px (3.9.2026), pôvodne kvôli 3. riadku (počet zliav) na
     "Domov" karte — ten je odvtedy preč, výška ostáva, logo (flex:1 1
     auto) si jednoducho vezme zvyšný priestor namiesto toho, aby karta
     vyzerala "prázdna". */
  height: 128px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Karta si drží tón panelu pod sebou (nahlásené 27.8.2026: karta mala
     inú farbu než pozadie stále, nielen v pokojnom stave), ale BEZ
     bodiek — bodky patria nádobe, nie veciam v nej, a na 128px dlaždici
     bol 22px raster aj tak len zrno.
     10.9.2026 — na žiadosť "tie markety maju biele pozadie, chcem aby
     bolo tiez oranzovo zelene": --card-face (plochá 5% zelená) vedľa
     výraznejšieho --wash-quiet na paneli pod ňou pôsobil takmer bielo.
     Karta má teraz rovnaký diagonálny oranžovo-zelený prechod ako panel
     (--wash-quiet), len bez bodiek — odlíši ju od okolia rám+tieň. */
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background-image: var(--wash-quiet);
  padding: 8px 8px;
  cursor: pointer;
  font-family: 'Plus Jakarta Sans', sans-serif;
  transition: transform 0.18s ease, box-shadow 0.18s ease, background-color 0.18s ease, border-color 0.18s ease;
}
/* Pod kurzorom karta len "vysunie" dopredu (tieň + nadvihnutie) — farba
   pozadia ostáva rovnaká ako v pokoji, viď komentár vyššie. */
.store-card:hover {
  border-color: var(--border-strong);
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
}
.store-card:active { transform: translateY(-1px); }
/* Zelený prstenec pri aktívnom (vybranom) obchode — rovnaký vzor ako
   .category-card.active, farba var(--primary) = appka-wide "aktívne"
   zafarbenie (tlačidlo "Hľadať akcie" má rovnaký odtieň). */
.store-card.active {
  background: var(--primary-soft);
  box-shadow: 0 0 0 3px var(--primary);
}
/* Reálne logo obchodu (static/img/stores/{slug}.png, skutočne priehľadné
   pozadie — viď STORE_LOGOS v script.js). Pri zlyhaní siete/404 sa celý
   obsah nahradí SVG fallbackom (onerror v renderStoreTiles), preto CSS
   pokrýva oba prípady (img aj vnorené svg) rovnako. */
.store-card-logo-wrap {
  position: relative;
  width: 100%;
  height: 100%;
  flex: 1 1 auto;
  /* min-height:0 — bez toho flex položka v stĺpci NIKDY nezmrští pod
     "prirodzenú" veľkosť svojho obsahu (predvolené min-height:auto vo
     flexboxe). Logá majú rôzny pomer strán (Lidl/Billa vyššie než
     Kaufland/Tesco) — bez tohto si tie "vyššie" logá vynucovali vyšší
     wrap, čo tlačilo počet zliav aj dátum platnosti nižšie IBA na ich
     karte, takže badge naprieč 4 kartami nesedel v jednej vodorovnej
     línii (nahlásené 3.9.2026: "potrebujem aby boli zarovnané"). */
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* 3.9.2026 — na žiadosť: platnosť letáku presunutá SPÄŤ pod logo (dve
   krátke skúsenosti s badgom PRIAMO na logu — najprv prekrývalo text
   loga pri širokých logách, potom po oprave prekrývalo počet zliav —
   používateľ napokon chcel jednoducho "pod logo"). Normálny tok (nie
   position:absolute), priamo pod logom — rovnako na "Domov"
   (renderDashboardStoreRow) aj vo výbere obchodov (renderStoreTiles);
   počet zliav pod logom na "Domov" bol neskôr odstránený (viď nižšie).
   Farebná "pill" (nie tlmený text) ostáva, nech je to poriadne vidno. */
.store-card-period-badge {
  display: inline-flex;
  flex: 0 0 auto;
  padding: 2px 7px;
  border-radius: 5px;
  background: var(--primary-dark);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.4;
  white-space: nowrap;
  margin-top: 3px;
}
.store-card-logo-wrap img,
.store-card-logo-wrap svg {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
}
/* Karta obchodu ukazuje logo + platnosť letáku POD ním (badge, viď
   .store-card-period-badge vyššie) — rovnaký jednoduchý tvar na "Domov"
   (renderDashboardStoreRow) aj vo výbere obchodov (renderStoreTiles).
   Logo dostane zvyšný priestor (viď .store-card-logo-wrap vyššie,
   flex:1 1 auto). */
.store-card-logo-only {
  justify-content: center;
}

/* Globálny vyhľadávací bar (medzi obchodmi a kategóriami) — pill-shaped
   input inšpirovaný letákovými webmi, prispôsobený na Island UI paletu. */
.global-search-bar {
  display: flex;
  padding: 2px 0;
}
.global-search-wrap {
  position: relative;
  width: 95%;
  margin: 0 auto;
}
.global-search-form {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 20px;
  background: color-mix(in srgb, var(--surface) 90%, transparent);
  border: 1px solid var(--border);
  border-radius: 999px;
  box-shadow: var(--shadow-sm);
  transition: box-shadow 0.18s ease, border-color 0.18s ease;
}
.global-search-form:focus-within {
  border-color: color-mix(in srgb, var(--primary) 50%, var(--border));
  box-shadow: var(--shadow-md);
}
.global-search-icon {
  flex: 0 0 auto;
  font-size: 20.5px;
  color: var(--muted);
  opacity: 0.8;
}
.global-search-input {
  flex: 1;
  min-width: 0;
  border: none;
  background: transparent;
  outline: none;
  font-size: 17px;
  font-family: inherit;
  color: var(--ink);
  padding: 12px 0;
}
.global-search-input::placeholder {
  color: var(--muted);
}
.global-search-clear {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 50%;
  background: var(--surface-alt);
  color: var(--muted);
  font-size: 18.5px;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.global-search-clear:hover {
  background: var(--border);
  color: var(--ink);
}
.global-search-clear.hidden { display: none; }

/* Live autocomplete dropdown pod globálnym vyhľadávacím barom — rovnaké
   zaoblenie/tieň ako ostatné plávajúce karty appky (.product-popover). */
.global-search-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  z-index: 60;
  max-height: 420px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  padding: 6px;
}
.global-search-dropdown.hidden { display: none; }

.global-search-empty {
  padding: 14px 12px;
  font-size: 15px;
  color: var(--muted);
  text-align: center;
}

.global-search-result {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  transition: background-color 0.12s ease;
}
.global-search-result:hover,
.global-search-result:focus-visible {
  background: var(--surface-alt);
  outline: none;
}
.global-search-result + .global-search-result { margin-top: 2px; }

.global-search-result-img {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  object-fit: contain;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 4px;
  box-sizing: border-box;
}
.global-search-result-img-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 23px;
  color: var(--muted);
}
.global-search-result-img-fallback svg { width: 1em; height: 1em; }

.global-search-result-store-logo-wrap {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 2px;
  box-sizing: border-box;
}
.global-search-result-store-logo { width: 100%; height: 100%; object-fit: contain; }

.global-search-result-info {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
/* 3.9.2026 — na žiadosť: CELÝ názov produktu, nie orezaný "...".
   Zalomí sa na viac riadkov namiesto orezania (bar aj dropdown sú
   teraz dosť široké, aby to nebolo potrebné pre väčšinu názvov). */
.global-search-result-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  white-space: normal;
  overflow-wrap: break-word;
  line-height: 1.35;
}
.global-search-result-prices {
  display: flex;
  align-items: baseline;
  gap: 6px;
}
.global-search-result-prices .old-price { font-size: 13px; }
.global-search-result-prices .new-price { font-size: 16px; }

.global-search-result-badge {
  flex: 0 0 auto;
  margin-right: 0;
}

/* Rýchle pridanie do sledovaných priamo z dropdownu — bez nutnosti
   otvárať produkt. Vlastný <button> (nie div) v rámci klikateľného
   riadku, klik naň zastaví bublanie, aby sa neotvoril aj detail. */
.global-search-result-add {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  font-size: 18.5px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: transform 0.12s ease, background-color 0.15s ease;
}
.global-search-result-add:hover {
  background: color-mix(in srgb, var(--primary) 85%, black);
  transform: scale(1.08);
}
.global-search-result-add.is-tracked {
  background: var(--surface-alt);
  color: var(--primary);
  border: 1.5px solid var(--primary);
}

/* Krátky "flash" pri skoku na konkrétnu kartu z dropdownu vyhľadávania —
   nech je hneď jasné, ktorú kartu appka myslela, aj v dlhom zozname. */
@keyframes deal-card-flash {
  0%, 100% { box-shadow: var(--shadow-xs); border-color: var(--border); }
  30% { box-shadow: 0 0 0 3px var(--primary); border-color: transparent; }
}
.deal-card-flash {
  animation: deal-card-flash 1.5s ease;
}

/* Vodoznak košíka (::before, skúšané 27. 8. 2026 vo viacerých variantoch
   — stred, spodný pruh, orezaný roh) sa napokon ako nápad neosvedčil,
   vždy pôsobil ako cudzí/stratený prvok. Nahradené jemným prechodom +
   bodkovaným vzorom priamo na pozadí kontajnera (viď nižšie) — menej
   doslovné, viac "moderná appka" textúra. */
.category-showcase {
  position: relative;
  overflow: hidden;
  padding: 22px 22px 18px;
  /* Dve vrstvy pozadia naraz (čiarka = viac background-image vrstiev):
     1. Bodkovaný vzor (radial-gradient opakovaný cez background-size) —
        bodky majú len 5 % krytie (color-mix s "transparent"), takmer
        neviditeľné zblízka, len jemná textúra z odstupu.
     2. Diagonálny prechod z --surface do jemne zelenkastého tónu (miešaný
        z --surface a --primary cez color-mix, takže funguje automaticky
        aj v tmavom režime, nie len napevno zapísaná svetlá farba).
     Karty kategórií majú vlastné nepriehľadné pozadie (--surface-alt),
     takže zostávajú 100 % čitateľné bez ohľadu na túto textúru pod nimi. */
  background-image: var(--dots-quiet), var(--wash-quiet);
  background-size: 22px 22px, 100% 100%;
  background-position: 0 0, 0 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
  /* ÚMYSELNE bez max-height/overflow-y (predtým 80vh + overflow-y:auto) —
     ukázalo sa, že to NEBOLA len zriedkavá poistka pre extrémne malé
     okno, ale reálne orezávalo posledný riadok dlaždíc kategórií aj na
     bežnej výške obrazovky (~720px), keďže 6-stĺpcová mriežka pri ~20
     kategóriách potrebuje viac než 80vh. Grid sa teraz plne rozbalí a
     necháva scrollovať CELÚ stránku (main.layout), nie tento kontajner
     samostatne — presne to, čo očakáva používateľ. */
}
/* 3.9.2026 — na žiadosť: nadpis "Prehľadávaj podľa kategórie" preč
   ("zbytočné, je očividné čo appka robí"), namiesto neho tlačidlo
   "Zobraziť všetky zľavy"/"Hľadať zľavy" (rovnaký search-cta-btn ako
   inde v appke) v pravom hornom rohu sekcie. */
.category-showcase-head {
  position: relative;
  z-index: 10;
  display: flex;
  justify-content: flex-end;
  margin-bottom: 16px;
}
.category-showcase-head .search-cta-btn {
  padding: 8px 16px;
  font-size: 14.5px;
  box-shadow: none;
}

/* ---------- "Najväčšie zľavy dňa" — hero panel ----------
   3.9.2026 — na žiadosť: "zakomponuj [obrázok košíka so zľavovými
   cenovkami] presne tak ako je tá tabuľa navrchu" — DOSLOVNE rovnaký
   rám/textúra/tieň ako .dashboard-hero (skopírované, nie zdieľaná
   trieda — obe majú vlastné --*-img-max/x/y premenné cez živý editor,
   viď nižšie, takže musia byť oddelené pravidlá).
   Pôvodne obrázok/produkty vedľa seba v riadku, potom stoh, potom
   PREKRYTIE (CSS grid, obe deti v TEJ ISTEJ bunke — viď @media nižšie)
   — na žiadosť "zmenši ten zaoblený rám ... aby to nebolo zbytočne
   veľké". Živý editor (?hero_edit=1) ukladá vlastné pixelové
   pozície/mierku (--top-savings-img-* a --top-savings-products-*), tie
   sú ale odladené na ŠIROKEJ obrazovke — na úzkom mobile reálne
   rozbíjali layout (obrázok skoro celý mimo panelu, 2 z 3 produktových
   kariet vysunuté mimo viditeľnú plochu, nahlásené priamo na telefóne).
   Appka má navyše obsah orámovaný na max-width 1180px (.layout) — kým
   je okno UŽŠIE než tento strop, panel je užší než 1132px a rovnaký
   pevný pixelový posun ho preženie ešte viac (nahlásené aj pri bežných
   nezmaximalizovaných oknách notebooku, ~900-1100px). Preto ZÁKLAD
   (mobile-first, žiadny transform) je vždy bezpečný jednoduchý stoh;
   PREKRYTIE + vlastné pozície sa aplikujú AŽ od 1180px, kde je panel
   VŽDY presne 1132px široký (layout stĺpec je nad týmto prahom
   zafixovaný) — presne tam, kde boli naživo odladené, takže sa už
   nikdy nemôžu "nezmestiť". overflow:hidden nižšie je len posledná
   poistka, nie primárne riešenie. */
/* ---------- "Najväčšie zľavy dňa" — horizontálny pás top produktov
   zoradených podľa PERCENTA zľavy, viď /api/deals/top-savings.
   Rovnaká panelová textúra ako .store-showcase/.category-showcase pre
   vizuálnu jednotnosť, karty vnútri majú rovnaké "natrvalo tónované"
   pozadie ako .store-card/.category-card (nie len na hover, viď
   27.8.2026 zjednotenie). */
.top-savings-section {
  position: relative;
  padding: 18px 22px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xs);
}
.top-savings-scroll {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  overflow-y: hidden;
  padding-bottom: 6px;
  scroll-snap-type: x proximity;
}
.top-savings-card {
  scroll-snap-align: start;
  flex: 0 0 auto;
  width: 168px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--card-face);
  transition: transform 0.18s ease, box-shadow 0.18s ease, border-color 0.18s ease;
}
.top-savings-card:hover {
  border-color: var(--border-strong);
  transform: translateY(-3px);
  box-shadow: var(--shadow-md);
}
.top-savings-thumb-wrap { position: relative; }
.top-savings-thumb-wrap .global-search-result-img {
  width: 100%;
  height: 92px;
  border-radius: var(--radius-sm);
}
.top-savings-thumb-wrap .global-search-result-img-fallback { font-size: 34.5px; }
.top-savings-store-logo-wrap {
  position: absolute;
  top: 6px;
  left: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 7px;
  padding: 2px;
  box-sizing: border-box;
}
.top-savings-store-logo { width: 100%; height: 100%; object-fit: contain; }
.top-savings-add {
  position: absolute;
  bottom: 6px;
  left: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 50%;
  background: var(--primary);
  color: #fff;
  font-size: 17px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  transition: transform 0.12s ease, background-color 0.15s ease;
}
.top-savings-add:hover {
  background: color-mix(in srgb, var(--primary) 85%, black);
  transform: scale(1.08);
}
.top-savings-add.is-tracked {
  background: var(--surface-alt);
  color: var(--primary);
  border: 1.5px solid var(--primary);
}

/* 2.9.2026 — Obľúbené: srdiečko v PRAVOM DOLNOM rohu produktovej fotky
   (na .deal-card cez .deal-img-wrap, na top-savings karuseli cez
   .top-savings-thumb-wrap — oba kontajnery majú position:relative už
   nastavené). Zámerne vizuálne ODLÍŠENÉ od zeleného "+ Sledovať" (tu
   akcent/červená v .active stave), nech používateľ hneď vidí, že ide o
   inú akciu — Obľúbené a Sledované sú dve oddelené funkcie. */
.favorite-btn {
  position: absolute;
  bottom: 6px;
  right: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--muted);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: transform 0.12s ease, background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.favorite-btn:hover { transform: scale(1.1); color: var(--accent); }
.favorite-btn.active {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent);
}
.favorite-btn svg, .favorite-remove-btn svg { width: 1em; height: 1em; }
.favorite-btn.active svg { fill: currentColor; }

/* 3.9.2026 — "Uložiť recept" — na žiadosť "kazdy recept sa bude dat
   lajknut", rovnaký vizuálny jazyk ako .favorite-btn vyššie (rovnaké
   --accent tokeny), len NIE absolútne pozicované na fotke (recepty
   žiadnu miniatúru vždy nemajú) — sedí v riadku vedľa názvu receptu. */
.recipe-save-btn {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--muted);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: transform 0.12s ease, background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
/* Prázdny stav uložených receptov — zámerne tichý riadok, nie blok.
   Je to poznámka na okraji cesty k receptom, nie zastávka (viď komentár
   pri #recepty-empty v index.html). */
.recepty-empty-note {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 18px;
  color: var(--muted);
  font-size: 14px;
}
.recepty-empty-note svg { width: 1.1em; height: 1.1em; flex: 0 0 auto; }

/* 11.9.2026 — tlačidlo nesie SVG srdce (predtým textové "♥"), takže
   potrebuje tie isté dve pravidlá ako .favorite-btn pri produktoch:
   veľkosť podľa písma a výplň, keď je recept uložený. */
.recipe-save-btn svg { width: 1em; height: 1em; }
.recipe-save-btn.active svg { fill: currentColor; }
.recipe-save-btn:hover { transform: scale(1.1); color: var(--accent); }
.recipe-save-btn.active {
  background: var(--accent-soft);
  color: var(--accent);
  border-color: var(--accent);
}

/* 21.9.2026 — "+ Do plánu" vedľa srdiečka (viď recipe-cards.js:
   recipePlanBtnHtml). Rovnaký tvar/rozmer ako .recipe-save-btn, len
   primary (zelená) namiesto accent, nech sa dva rôzne významy (Obľúbené
   vs. Môj plán) dajú na prvý pohľad rozlíšiť aj bez čítania tooltipu. */
.match-recipe-actions { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }
.recipe-plan-btn {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
  transition: transform 0.12s ease, background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.recipe-plan-btn svg { width: 16px; height: 16px; }
.recipe-plan-btn:hover { transform: scale(1.1); color: var(--primary-dark); }
.recipe-plan-btn.active {
  background: var(--primary-soft);
  color: var(--primary-dark);
  border-color: var(--primary);
}

/* 2.9.2026 — "Upraviť" nahlasovací nástroj (static/image-flag.js),
   dev-gated cez ?img_flag=1 — bez tohto parametra sa tlačidlo nikdy
   nevloží do DOM, takže bežný návštevník ho nikdy neuvidí. .flag-btn
   sedí v .deal-card-header (normálny flex tok, margin-left:auto ju
   vytlačí k pravému okraju vedľa % odznaku) alebo ako malá ikonka na
   vrchu .top-savings-thumb-wrap (jediné voľné miesto — všetky 4 rohy
   miniatúry už zaberajú logo/odznak/+/srdiečko). */
.flag-btn {
  margin-left: auto;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--muted);
  font-size: 12px;
  font-weight: 600;
  padding: 3px 8px;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.flag-btn:hover { border-color: var(--danger); color: var(--danger); }
.flag-btn.flagged {
  background: var(--primary-soft);
  color: var(--primary-dark);
  border-color: var(--primary);
  cursor: default;
}
.flag-btn-thumb {
  position: absolute;
  top: 6px;
  left: 50%;
  transform: translateX(-50%);
  margin-left: 0;
  padding: 2px 7px;
  font-size: 10.5px;
}
.top-savings-name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.3;
  min-height: 2.6em;
  cursor: default;
}
/* 28.8.2026 — .product-name-hover (zdieľaná trieda pre náhľad produktu na
   hover) dáva bodkovanú spodnú čiaru, ktorá tu bola nahlásená ako
   "vyzerá ako error" — hover-náhľad ostáva funkčný (viď JS), len sa tu
   potláča čisto vizuálna bodkovaná čiara. Kombinovaný selektor (vyššia
   špecifickosť než samotné .product-name-hover), aby vyhral bez ohľadu
   na poradie pravidiel v súbore. */
.top-savings-name.product-name-hover { border-bottom: none; }
/* Percento zľavy — HLAVNÝ ťahák karty, preto priamo na obrázku (pravý
   horný roh, "pecka" nálepka — väčšie/tučné/mierne pootočené, nech
   upúta pohľad hneď). */
.top-savings-pct-badge {
  position: absolute;
  top: 6px;
  right: 6px;
  font-size: 19.5px;
  font-weight: 800;
  color: #fff;
  background: var(--danger);
  padding: 4px 9px;
  border-radius: 8px;
  letter-spacing: -0.02em;
  transform: rotate(-4deg);
  box-shadow: 0 3px 10px color-mix(in srgb, var(--danger) 55%, transparent);
  z-index: 2;
}
/* 28.8.2026 — pôvodná cena bola predtým príliš potlačená (10.5px,
   opacity 0.85) — na žiadosť používateľa je teraz čitateľnejšia,
   preberá rovnakú veľkosť/farbu ako .old-price v bežnom zozname zliav
   (14px, oranžová), aby bolo hneď vidno, z akej sumy sa šetrí, nie len
   samotnú akčnú cenu (tá je teraz vždy zelená, viď .new-price). */
.top-savings-price-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
}
.top-savings-new-price { font-size: 19.5px; line-height: 1.2; }
@media (max-width: 640px) {
  .top-savings-card { width: 140px; }
}

/* 3.9.2026 — na žiadosť ("vizuálny smog", "potrebujem mat prehladnu
   stranku", loga obchodov nižšie nechať bokom/nespájať) — sekcia už NIE
   JE vlastná "krabica" (žiadny rám/dot-textúra/tieň, viď .top-savings-
   section vyššie), splynie priamo s plochou stránky medzi hero a
   riadkom obchodov. Nadpis zjemnený na malý muted label, tlačidlo
   "Iné zľavy" bez vlastného pozadia/orámovania. Karty zostávajú
   samostatné .top-savings-card (žiadny rám/pozadie), +/♥ tlačidlá
   viditeľné až pri hoveri karty (predtým vždy vidno — pridávalo to
   4 farebné prvky na malú kartu), nech je pás v pokoji čo najtichší.
   Modifikátor (nie priama zmena základných tried), lebo .top-savings-
   card generuje aj topSavingsCardHtml() v script.js a trieda
   .favorite-btn je zdieľaná aj s hlavnou mriežkou zliav (tú NESMIE
   ovplyvniť). */
.top-savings-section--strip {
  padding: 0;
  background: none;
  border: none;
  border-radius: 0;
  box-shadow: none;
}
/* 3.9.2026 — na žiadosť odstránené vodorovné posúvanie/ťahanie (bolo
   vnímané ako "posúvač" navyše) — namiesto neho sa celá dávka sama
   vymení každých 30s (viď TOP_SAVINGS_ROTATE_MS v script.js). Len 4
   karty ("zúžime to na 4 produkty"), vycentrované namiesto zarovnania
   k ľavému okraju — žiadny scrollbar/ťahanie, wrap len ako poistka na
   veľmi úzkych šírkach. */
.top-savings-section--strip .top-savings-scroll {
  gap: 14px;
  flex-wrap: wrap;
  justify-content: center;
  overflow: visible;
  scroll-snap-type: none;
  padding-bottom: 0;
}
/* 22.9.2026 — uzatváracie CTA pod pásom zliav (viď index.html,
   top-savings-cta-wrap), rovnaká logika ako pri ostatných feature-panel
   tlačidlách; centrované, lebo pás nad ním je tiež centrovaný. Mimo
   .feature-panel--split (<900px, kde sekcia nie je mriežka) je to
   jednoducho posledný prvok pod obrázkom košíka v normálnom toku. */
.top-savings-cta-wrap { display: flex; justify-content: center; margin-top: 18px; }
/* 3.9.2026 — na žiadosť: foto/názov/cena späť v JEDNOM vizuálnom rámci
   (predtým úplne bez pozadia/orámovania — nahlásené, že to "vyzerá,
   akoby to k sebe nepatrilo"). Jemný plochý rámik (bez dot-textúry a
   bez hover-nadnesenia zo základnej .top-savings-card, tie ostávajú
   vypnuté nižšie), nech je jasné, že ide o jednu kartu, no sekcia ako
   celok stále nemá vlastný veľký rám (viď .top-savings-section--strip
   vyššie) — len 4 väčšie karty. */
/* 3.9.2026 — na žiadosť "troška to odlíšiť": zelenkastý nádych (rovnaký
   ako kategórie/obchody všade inde v appke) tu prehodený na teplý
   červený (--danger, rovnaký ako % odznak) — táto sekcia je jediná v
   appke o AKTUÁLNYCH najvýhodnejších zľavách, "hot deal" tón ju má
   odlíšiť od bežných produktových/kategóriových kariet, nie s nimi
   splývať. */
/* 10.9.2026 — na žiadosť "nechajme len v kruhu, teraz je to kruh na
   ďalšom štvorci, celé sa to bije": karta mala VLASTNÝ rám/pozadie
   (obdĺžnik so zaoblenými rohmi) OKOLO kruhového medailónu — dva
   konkurujúce si tvary na jednej ploche. Karta je teraz priehľadná,
   bez rámu aj pozadia; jediný "objekt" je samotný kruh (biely kotúč +
   tieň, viď .top-savings-thumb-wrap nižšie), text pod ním pláva voľne
   na podklade panelu, presne ako meno pod fotkou v telefóne. */
.top-savings-section--strip .top-savings-card {
  width: 200px;
  gap: 8px;
  padding: 8px 4px 4px;
  border: none;
  background: none;
  /* position:relative + z-index len na hover (nižšie) — zväčšený
     medailón (.top-savings-thumb-wrap:hover vyššie) tak spoľahlivo
     prekreslí susedné karty aj vlastný text pod sebou, nech karta stojí
     v riadku kdekoľvek. */
  position: relative;
  transition: transform 0.15s ease;
}
.top-savings-section--strip .top-savings-card:hover {
  border-color: transparent;
  transform: translateY(-3px);
  box-shadow: none;
  z-index: 5;
}
/* 3.9.2026 — na žiadosť "potrebujeme sa odlíšiť od normálnych kategórií
   a produktov": fotka v tomto páse už nie je hranatá dlaždica ako
   všade inde v appke (.category-card/.store-card/bežná .deal-card), ale
   okrúhly výrez — "medailón" na bielom kotúči s tieňom. .top-savings-
   thumb-wrap sa preto zmenšil PRESNE na rozmer kruhu (namiesto plnej
   šírky karty), nech sú naň absolútne pozicované logo obchodu aj %
   odznak napojené priamo na okraj kruhu, nie niekde v prázdnom priestore
   vedľa neho. object-fit:contain (nie cover) + biele pozadie + padding,
   nech sa produkt vždy zmestí celý, aj keď fotka nie je štvorec. */
.top-savings-section--strip .top-savings-thumb-wrap {
  width: 128px;
  height: 128px;
  margin: 0 auto 8px;
  /* 21.9.2026 na žiadosť: medailón sa pri hoveri zväčší (nižšie) —
     rastie od SPODNÉHO okraja (nie od stredu), nech rastie hlavne
     smerom hore, nie cez meno/cenu pod ním. position:relative + z-index
     ho pri raste dostane NAD susedné karty aj vlastný text pod sebou
     (position:static by inak nešlo prekresliť nad okolie). */
  position: relative;
  transform-origin: 50% 100%;
  transition: transform 0.2s cubic-bezier(.2, .8, .2, 1);
}
/* Zväčšenie o 55 % — celý medailón (fotka + logo obchodu + % odznak)
   rastie ako jeden celok, nech logo aj odznak zostanú presne napojené
   na okraj kruhu aj zväčšené. */
.top-savings-section--strip .top-savings-card:hover .top-savings-thumb-wrap {
  transform: scale(1.55);
  z-index: 4;
}
.top-savings-section--strip .top-savings-thumb-wrap .global-search-result-img {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  object-fit: contain;
  /* 10.9.2026 — na žiadosť "ten biely kruh daj ako cerveny kruh -
     akoze extra lacne": rovnaká --danger ako % odznak, nech medailón
     sám osebe signalizuje "výhodná cena", nie len nálepka v rohu. */
  background: var(--danger);
  border: 3px solid var(--surface);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.18);
  padding: 12px;
}
.top-savings-section--strip .top-savings-thumb-wrap .global-search-result-img-fallback { font-size: 46px; }
/* 21.9.2026 na žiadosť ("takto tam nič nevidím") — logo obchodu bolo
   24px kotúčik splývajúci s bielym okrajom medailónu. Zväčšené, VYSUNUTÉ
   mimo okraj kruhu (záporný posun, rovnaký princíp ako % odznak
   oproti) a s vlastným výrazným tieňom, nech je čitateľné na prvý
   pohľad aj bez hoveru — nie len jemný odznak v rohu fotky. */
.top-savings-section--strip .top-savings-store-logo-wrap {
  width: 36px;
  height: 36px;
  top: -6px;
  left: -6px;
  border-radius: 10px;
  border: 2px solid var(--surface);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
  padding: 4px;
}
/* % odznak zámerne PRESAHUJE cez okraj kruhu (záporný posun) — pôsobí
   ako nálepka nalepená na medailón, nie len text v rohu fotky, plus
   biely "ring" (box-shadow druhá vrstva) ho oddelí od pozadia karty aj
   keď sedí čiastočne mimo fotku. */
.top-savings-section--strip .top-savings-pct-badge {
  font-size: 22px;
  font-weight: 900;
  padding: 5px 11px;
  border-radius: 9px;
  top: -8px;
  right: -8px;
  box-shadow: 0 5px 14px color-mix(in srgb, var(--danger) 65%, transparent), 0 0 0 3px var(--surface);
}
/* Text bol zarovnaný naľavo (dedený z bežnej hranatej karty) — bez
   rámu okolo karty (viď vyššie) to pod VYCENTROVANÝM kruhom vyzeralo
   krivo, meno aj cena teraz sedia na strede pod medailónom. */
.top-savings-section--strip .top-savings-name { font-size: 15px; font-weight: 500; min-height: 2.2em; text-align: center; }
.top-savings-section--strip .top-savings-price-row { align-items: center; }
.top-savings-section--strip .top-savings-old-price { font-size: 14px; }
.top-savings-section--strip .top-savings-new-price { font-size: 19.5px; }
/* +/♥ tlačidlá schované v pokoji — ostanú viditeľné len keď už niečo
   znamenajú (produkt je sledovaný/obľúbený), inak sa ukážu až na
   hover karty. pointer-events:none v pokoji, nech neprekážajú klikom
   na samotnú kartu/fotku pod nimi. */
.top-savings-section--strip .top-savings-add,
.top-savings-section--strip .favorite-btn {
  width: 20px;
  height: 20px;
  font-size: 12.5px;
  opacity: 0;
  pointer-events: none;
}
.top-savings-section--strip .top-savings-add { bottom: 4px; left: 4px; }
.top-savings-section--strip .favorite-btn { bottom: 4px; right: 4px; }
.top-savings-section--strip .top-savings-card:hover .top-savings-add,
.top-savings-section--strip .top-savings-card:hover .favorite-btn,
.top-savings-section--strip .top-savings-add.is-tracked,
.top-savings-section--strip .favorite-btn.active {
  opacity: 1;
  pointer-events: auto;
}
/* 3.9.2026 — pri 3 kartách (znížené zo 4, "ten štvrtý čo je na spodku
   zmizne") sa na užšom mobile 2 zmestia do prvého riadku a 3. spadne
   samostatne na druhý — flex-wrap + justify-content:center (viď vyššie)
   ju tam vycentruje samú, takže netreba vynucovať mriežku ako predtým
   pri 4 kartách. Karty zväčšené na 200px ("produkty dominantné"), na
   úzkom mobile sa preto zmenšia späť, nech sa 2 v rade zmestia. */
@media (max-width: 460px) {
  .top-savings-section--strip .top-savings-card { width: 160px; }
  .top-savings-section--strip .top-savings-thumb-wrap { width: 104px; height: 104px; }
  .top-savings-section--strip .top-savings-store-logo-wrap { width: 30px; height: 30px; top: -5px; left: -5px; }
}

.category-tiles {
  position: relative;
  z-index: 10;
  display: grid;
  /* Presne 7 stĺpcov na desktop — pri 21 kategóriách vyjde presne
     3 riadky, aby sa celá sekcia zmestila na frontpage bez nutnosti
     scrollovať. Na užšom viewporte (media query nižšie) sa vracia na
     auto-fit, nech sa stĺpce prirodzene preskupia namiesto zošúverenia. */
  /* 15.9.2026 — 16 dlaždíc (zlúčené malé kategórie) = 2 plné riadky po 8. */
  grid-template-columns: repeat(8, 1fr);
  gap: 10px;
}
@media (max-width: 900px) {
  .category-tiles {
    grid-template-columns: repeat(auto-fit, minmax(82px, 1fr));
  }
}

/* 3.9.2026, na žiadosť — pôvodné fotky (+ bodkovaná textúra pod nimi)
   "sa nehodia na web z roku 2026", nahradené plochou minimalistickou
   dlaždicou: kruhová ikona (CATEGORY_ICONS — tie isté emoji, čo predtým
   slúžili len ako núdzový fallback pri chýbajúcej fotke, viď script.js)
   namiesto fotky, žiadna dot-textúra/gradient na karte, počet ako tichý
   text pod popiskom namiesto farebného odznaku v rohu. */
.category-card {
  /* Pevná výška (rovnaké riadky), šírku už určuje grid stĺpec (auto-fill
     + minmax vyššie) namiesto predošlej pevnej šírky 110px pre flex
     riadok. 132px → 166px (3.9.2026, na žiadosť: "texty nie je dobre
     vidieť" + väčší obrázok pri viacerých kategóriách) — dosť miesta aj
     pre .category-card-icon--boost (viď nižšie), karty bez zväčšenia
     tak majú trochu voľného priestoru dole namiesto orezania.
     166px → 141px (3.9.2026, na žiadosť "zmenši kategórie produktov o
     15%") — rozmery/fonty nižšie prepočítané rovnakým pomerom.
     141px → 162px (18.9.2026, na žiadosť "toto chcem trochu vacsie, o
     15%") — rovnaký princíp, opačný smer.
     162px → 194px (18.9.2026, "sprav to tak aby sa tam zmestil nazov
     tej kategorie" — po zväčšení písma trojslovné názvy ako "Oleje,
     omáčky a korenie"/"Slané snacky a orechy" potrebovali 3 riadky
     namiesto 2, .category-card-label clamp nižšie zvýšený na 3, výška
     karty dorovnaná na najvyšší reálny obsah — zmerané naživo, viď
     komentár pri labeli). */
  width: 100%;
  height: 194px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* 10.9.2026 — na žiadosť "vycentruj to aj s textom aj obrazkom tak,
     aby tam nebolo zbytocne vela volneho miesta": jednoslovné názvy
     (Alkohol, Mäso, Pečivo...) nevyplnili celú pevnú výšku 141px
     (rezervovanú pre dvojslovné názvy na 2 riadky) a voľný priestor sa
     hromadil dole (flex-start bolo predtým default). justify-content:
     center rozloží ho rovnomerne hore aj dole namiesto jednej medzery
     pod popiskom — dvojslovné názvy naďalej sedia presne (141px im
     stačí na 2 riadky + fotku, nič sa neoreže). */
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  /* 3.9.2026 — na žiadosť: "take iste farebne pozadie ako markety, take
     jemne zelene". Zelenkavý tón teda ostáva a je rovnaký ako pri
     .store-card, ale bez bodkovanej textúry: pri 141px dlaždici z nej
     nebola textúra, len zrno, a rovnaké bodky na karte AJ na paneli pod
     ňou zmazali rozdiel medzi nimi. */
  background: var(--card-face);
  padding: 11px 6px 9px;
  cursor: pointer;
  font-family: 'Plus Jakarta Sans', sans-serif;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
/* Jemnejší hover než predtým (shadow-sm/-2px, nie shadow-lg/-3px) —
   ladí s tichším, menej "kričiacim" tónom zvyšku Domov stránky. */
.category-card:hover {
  border-color: color-mix(in srgb, var(--primary) 45%, var(--border));
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
}
.category-card:active { transform: translateY(0); }

/* 3.9.2026, druhé kolo ("moc cropnuté", "nech to pekne ladí s tým, čo
   tam už je") — object-fit:contain namiesto cover (celá fotka vidieť,
   nič sa neorezáva) a ŽIADNE vlastné pozadie: fotky majú teraz reálne
   priehľadné pozadie (odstránené pri generovaní náhľadu, viď
   CATEGORY_TILE_IMAGES v script.js), takže bez farebného rámu pod nimi
   splynú priamo s plochou karty. Vyššie (90px, predtým 56px) — fotky
   po tesnom orezaní na obsah majú rôzny pomer strán (naprieč kategóriami
   cca 0.6-1.7), contain do nízkeho pásu by ich zbytočne zmenšil. */
.category-card-icon {
  width: 100%;
  height: 86px;
  flex: 0 0 86px;
  margin-bottom: 7px;
  color: var(--muted);
  display: flex;
  align-items: center;
  justify-content: center;
  /* visible (nie hidden) — .category-card-photo--boost nižšie potrebuje
     mierne pretiecť cez okraj boxu bez orezania rohov. */
  overflow: visible;
}
.category-card-icon svg { width: 22px; height: 22px; }
.category-card-photo { width: 100%; height: 100%; object-fit: contain; }
/* 3.9.2026 — na žiadosť zväčšené len pri kategóriách, kde fotka (po
   object-fit:contain) vychádzala nápadne menšia než ostatné. Mierne
   transform (nie zväčšenie celého rámu — to by rozbilo jednotnú výšku
   riadkov v mriežke), zbytok kategórií ostáva bez zmeny.
   1.22 → 1.1 (na žiadosť: "obrazky v kategorii maso a alkohol trosku
   zmensi aby sa nedotykali stran ramu") — .category-card-photo má
   width/height:100% (element vypĺňa CELÝ rám vždy, object-fit len
   kreslí OBSAH menší dnu), takže transform:scale škáluje celý 100 %
   rám, nie len viditeľnú fotku — pri 1.22 to pretekalo cez okraj karty
   pri VŠETKÝCH boostnutých kategóriách rovnako (nielen pri Mäse a
   Alkohole, len tam si to používateľ všimol), 1.1 necháva bezpečnú
   rezervu do paddingu (viď .category-card padding vyššie). */
.category-card-photo--boost { transform: scale(1.1); }
/* Zväčšená fotka potrebuje väčší odsad zdola, inak zasahuje do
   popisku — bez tohto by category-card-photo--boost prekrývalo text
   (nahlásené naživo pri pôvodnom 1.22, pri 1.1 už netreba toľko, ale
   rezerva ostáva). */
.category-card-icon--boost { margin-bottom: 13px; }

/* Len "Všetky" (a dočasne "Ryža a obilniny", kým nepríde fotka bez
   vodoznaku) ostáva pri SVG ikone — tá bez vlastného pozadia pôsobila
   "nahá", preto má (len ona) späť jemný kruh pod sebou. */
.category-card-icon--svg {
  width: 41px;
  height: 41px;
  flex: 0 0 41px;
  margin: 0 auto 7px;
  border-radius: 50%;
  background: var(--surface-alt);
}
.category-card.active .category-card-icon { color: var(--primary-dark); }

/* 3.9.2026 — na žiadosť: "texty nie je dobre vidieť" + "zvýrazniť
   čiernou tučnou farbou" — väčší font, 700 (nie 600). var(--ink) je už
   v light režime tmavá takmer-čierna (#2F2F2A, nie natvrdo #000 —
   funguje aj v tmavom režime, kde je --ink svetlá), spolu s tučnejším
   rezom pôsobí ako požadovaná "čierna tučná". */
.category-card-label {
  font-size: 13.2px;
  font-weight: 700;
  color: var(--ink);
  text-align: center;
  line-height: 1.25;
  display: -webkit-box;
  /* 2 → 3 (18.9.2026, "sprav to tak aby sa tam zmestil nazov tej
     kategorie") — pri väčšom písme (13.2px, 18.9.2026 skôr) sa
     trojslovné názvy ("Oleje, omáčky a korenie", "Slané snacky a
     orechy") nezmestili na 2 riadky a posledné slovo úplne zmizlo
     (line-clamp ho odrezal). .category-card výška vyššie dorovnaná na
     194px, nech je pre 3 riadky dosť miesta aj s odznakom počtu pod
     nimi. */
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Počet akcií pre danú kategóriu — predtým farebný odznak v rohu (cez
   fotku potreboval silný kontrast/tieň, viď git história); ako plochý
   text pod popiskom to už nepotrebuje, reaguje naživo na výber
   obchodov rovnako ako predtým (viď renderCategoryTiles v script.js). */
.category-card-count {
  font-size: 12px;
  font-weight: 500;
  color: var(--muted);
  margin-top: 2px;
}
.category-card.active .category-card-count { color: var(--primary-dark); }

/* Aktívna kategória: silno odlíšená farebným prstencom + jemne
   zafarbeným pozadím namiesto klasického border (karty inak zámerne bez
   orámovania). */
.category-card.active {
  background: var(--primary-soft);
  border-color: var(--primary);
  box-shadow: 0 0 0 2px var(--primary);
}

/* ---------- Layout ----------
   Bloky pod sebou na celú šírku: výber obchodov, kategórie, Zľavy
   (výsledky), Nákup na rozpočet/týždenný plán. "Sledované položky" už
   nie je blok v tomto stĺpci — je to výsuvný panel (.tracked-modal),
   otváraný ikonkou košíka v hlavičke, viď vyššie. */

.layout {
  max-width: 1180px;
  margin: 28px auto;
  padding: 0 24px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

/* ---------- Dvojkrokový flow: "Výber" (obchody+kategórie) -> "Výsledky"
   (zľavy+nákup), viď #screen-select / #screen-results v index.html a
   goToResults()/backToSelect() v script.js. Skryté cez display:none (nie
   odstránené z DOM), takže existujúci JS stav (activeStores/activeCategories,
   renderDeals...) ostáva nedotknutý pri prepínaní. */
.app-screen { display: none; }
.app-screen.is-active {
  display: flex;
  flex-direction: column;
  /* 10.9.2026 — 20px → 12px, zosúladené s .dashboard-hero-combo (viď
     komentár tam) — rovnaký dôvod: panel priamo v .app-screen (napr.
     .feature-panel--savings) mal navyše vlastný margin-top, takže sa
     medzera pred ním sčítala na 32px namiesto zamýšľaných 20px, zatiaľ
     čo medzery vnútri combo boli len 20px — nekonzistentné aj príliš
     veľké súčasne. Priami .feature-panel potomkovia majú margin-top
     vynulovaný (nižšie), celú medzeru dáva len tento gap. */
  gap: 12px;
  animation: screen-fade-in 0.35s cubic-bezier(.2, .8, .2, 1);
}
.app-screen.is-active > .feature-panel { margin-top: 0; }
@keyframes screen-fade-in {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  .app-screen.is-active { animation: none; }
}

/* Zámerne NIE sticky/fixed — predtým lepené na spodok viewportu
   prekrývalo (a vizuálne "orezávalo") posledný riadok dlaždíc kategórií
   pri scrollovaní. Normálny tok dokumentu, čisto pod plne rozbalenou
   mriežkou, nikdy nič neprekrýva. */
.search-cta-bar {
  display: flex;
  justify-content: center;
  padding: 22px 24px 4px;
}
.search-cta-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  border: none;
  background: var(--primary);
  color: #fff;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 17px;
  font-weight: 700;
  padding: 14px 26px;
  border-radius: 999px;
  cursor: pointer;
  box-shadow: var(--shadow-lg);
  transition: transform 0.15s ease, background-color 0.2s ease;
}
.search-cta-btn:hover { background: var(--primary-dark); transform: translateY(-1px); }
.search-cta-btn:active { transform: translateY(0); }
.search-cta-badge {
  background: rgba(255, 255, 255, 0.22);
  padding: 3px 11px;
  border-radius: 999px;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}

/* Horný pruh obrazovky "Výsledky" — návrat na výber + textové zhrnutie
   aktuálne zvolených obchodov/kategórií. */
.results-topbar {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}
.back-to-select-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  border: 1px solid var(--border);
  background: var(--surface-alt);
  color: var(--ink);
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 15.5px;
  font-weight: 600;
  padding: 9px 15px;
  border-radius: 999px;
  cursor: pointer;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.back-to-select-btn:hover { border-color: var(--border-strong); transform: translateX(-2px); }
.results-summary { margin: 0; color: var(--muted); font-size: 15px; }
/* 24.9.2026 — vyhľadávací filter (#search-input) je v DOM skrytý, takže
   po hľadaní z hlavičky nebolo vidno, že zoznam zliav je zúžený, ani ako
   ho zrušiť. Štítok s × ho ukazuje a jedným klikom maže. */
.results-search-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--border-strong);
  background: var(--surface);
  color: var(--ink);
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 15px;
  font-weight: 600;
  padding: 7px 8px 7px 14px;
  border-radius: 999px;
  cursor: pointer;
  max-width: 100%;
}
.results-search-chip-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--surface-alt);
  font-size: 17px;
  line-height: 1;
}
.results-search-chip:hover .results-search-chip-x { background: var(--danger); color: #fff; }

.budget-controls { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 16px; }

.budget-input-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 7px 14px;
  background: var(--surface-alt);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.budget-input-wrap:focus-within { border-color: var(--primary); box-shadow: 0 0 0 4px var(--primary-soft); }
.budget-input-wrap input {
  border: none;
  background: none;
  width: 80px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
}
.budget-input-wrap input:focus { outline: none; }
.budget-currency { color: var(--muted); font-weight: 600; }

.budget-table-wrap { max-height: 420px; }

/* 28.8.2026 — na žiadosť používateľa: diétne filtre (vegetariánsky/
   bezlepkový/bez laktózy/proteínový/mäsový) boli predtým nenápadné malé
   checkboxy splývajúce s pozadím ("už tam sú, ale nie je to dobre
   vidieť") — teraz výrazné farebné "pilulky" s vlastným nadpisom sekcie,
   rovnaký vizuálny jazyk ako odznaky inde v appke (napr.
   .match-recipe-badge/.top-savings-pct-badge). */
.diet-toggles-heading {
  font-size: 15px;
  font-weight: 700;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 16px 0 8px;
}
/* 3.9.2026 — prepínač "Varenie / Pečenie". Zámerne NEVYZERÁ ako diétne
   pilulky vedľa: je to VOĽBA REŽIMU (vždy je zvolená práve jedna
   možnosť), nie ďalší nezávislý filter — preto segmentový prepínač so
   spoločným rámom, nie samostatné checkboxy. */
/* 10.9.2026 — na žiadosť redizajnu "Segmentované Prepínače... aktívna
   možnosť funguje ako posuvná biela karta s jemným tieňom": predtým
   každé tlačidlo dostalo FARBU priamo (background:var(--primary)) pri
   prepnutí — teraz jeden spoločný "thumb" (biela karta) POSÚVA sa medzi
   dvoma pozíciami cez transform (plynulé, nie okamžitá zmena farby).
   Thumb vkladá initCookModeThumbs() v script.js (MutationObserver na
   zmenu .is-active triedy) — funguje naprieč VŠETKÝMI existujúcimi
   .cook-mode výskytmi v appke (9 miest), nie len tromi z požiadavky,
   lebo zdieľajú tú istú triedu a bez thumbu by vyzerali rozbité. */
.cook-mode { position: relative; display: inline-flex; padding: 3px; margin: 0 0 10px; background: var(--surface-alt); border: 1px solid var(--border); border-radius: 999px; }
.cook-mode-thumb {
  position: absolute;
  top: 3px;
  left: 3px;
  bottom: 3px;
  width: calc(50% - 3px);
  background: var(--surface);
  border-radius: 999px;
  box-shadow: var(--shadow-sm);
  transition: transform 0.25s cubic-bezier(0.22, 0.8, 0.32, 1);
  pointer-events: none;
  z-index: 0;
}
.cook-mode--second-active .cook-mode-thumb { transform: translateX(100%); }
.cook-mode-btn {
  position: relative;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  background: none;
  padding: 7px 16px;
  border-radius: 999px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 15px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.2s ease;
}
.cook-mode-btn:hover { color: var(--ink); }
.cook-mode-btn.is-active { color: var(--primary-dark); }
/* 10.9.2026 — na žiadosť "Tieto emoji sa mi vobec nepacia... vlozit
   neake minimalisticke": emoji (🍳🧁🥕🌾🥛💪🥩) nahradené jednoduchými
   linkovými SVG ikonami v rovnakom vizuálnom jazyku ako `.sidebar-link-
   icon` (stroke="currentColor", stroke-width 1.8) — farba ikony tak
   automaticky sleduje farbu textu (aktívny/neaktívny/hover stav), bez
   ďalšieho CSS. */
.pill-icon { width: 16px; height: 16px; flex-shrink: 0; }
/* 10.9.2026 — na žiadosť "Emoji odstran vsade": zvyšné emoji naprieč
   appkou (vyhľadávanie, dark mode prepínač, košík, avatar, koš, ✕,
   varovania, howto ikony, "coming soon", porovnanie cien atď.)
   nahradené rovnakým SVG jazykom ako .pill-icon vyššie. Na rozdiel od
   .pill-icon (pevných 16px pre pilulky v jednom kontexte) je táto
   trieda univerzálna — `1em` škáluje s font-size okolia (rôzne
   kontexty majú rôzne veľkosti: 15px popup ikona, 50px "coming soon",
   22px avatar...), takže netreba samostatné pravidlo pre každé miesto.
   `vertical-align` sedí v bežnom textovom toku (napr. .diet-warning),
   `flex-shrink:0` sedí vo flex kontextoch (napr. .screen-hero-point-icon)
   — obe naraz neškodia, len jedno z nich sa v danom layoute uplatní. */
.inline-icon { width: 1em; height: 1em; vertical-align: -0.15em; flex-shrink: 0; }
.diet-toggles { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 4px; }

/* 10.9.2026 — redizajn "Moderný Slider pre Výber Rozpočtu": nahrádza
   statický number input v "Recepty podľa rozpočtu"/"Nákup na celý
   týždeň" (viď index.html, #hero-budget-input/#entry-weekly-budget).
   JS (setupBudgetSlider v script.js) nastavuje na .budget-range inline
   background (lineárny 2-farebný gradient podľa % hodnoty) — track
   pseudo-elementy nižšie sú preto priehľadné, aby cez ne presvital
   práve tento gradient namiesto natívneho jednofarebného tracku. */
.budget-slider-group { display: flex; flex-direction: column; gap: 12px; width: 100%; max-width: 340px; }
.budget-slider-row { display: flex; align-items: center; gap: 14px; }
.budget-range {
  flex: 1 1 auto;
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 8px;
  border-radius: 999px;
  background: var(--border);
  outline: none;
  cursor: pointer;
}
.budget-range::-webkit-slider-runnable-track { height: 8px; border-radius: 999px; background: transparent; }
.budget-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  margin-top: -7px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--surface);
  border: 3px solid var(--primary);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform 0.15s ease;
}
.budget-range::-webkit-slider-thumb:hover { transform: scale(1.12); }
.budget-range::-moz-range-track { height: 8px; border-radius: 999px; background: transparent; }
.budget-range::-moz-range-progress { height: 8px; border-radius: 999px; background: var(--primary); }
.budget-range::-moz-range-thumb {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--surface);
  border: 3px solid var(--primary);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: transform 0.15s ease;
}
.budget-range::-moz-range-thumb:hover { transform: scale(1.12); }
.budget-value-box {
  flex: 0 0 auto;
  min-width: 68px;
  box-sizing: border-box;
  text-align: center;
  padding: 8px 12px;
  border-radius: 14px;
  background: var(--primary-soft);
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 800;
  font-size: 20px;
  color: var(--primary-dark);
  font-variant-numeric: tabular-nums;
  transition: background-color 0.2s ease;
}
.budget-quick-chips { display: flex; gap: 8px; flex-wrap: wrap; }
.budget-chip {
  border: 1.5px solid var(--border);
  background: var(--surface);
  color: var(--muted);
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 600;
  font-size: 13px;
  padding: 6px 13px;
  border-radius: 999px;
  cursor: pointer;
  transition: all 0.2s ease;
}
.budget-chip:hover { border-color: var(--primary); color: var(--ink); transform: translateY(-1px); }
.budget-chip.is-active { background: var(--primary); border-color: var(--primary); color: #fff; }
/* ======================================================================
   KARTA "NAPLÁNUJ SI JEDLÁ" (16.9.2026, prerobené 18.9.2026)
   ----------------------------------------------------------------------
   Zlúčenie kariet "Recepty podľa rozpočtu" a "Nákup na celý týždeň" —
   viď index.html. 18.9.2026: voľba počtu dní (1-7) preč, karta drží len
   rozpočet — appka si počet jedál odvodí sama.
   ====================================================================== */
.planner-panel-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 18px;
}

.planner-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  font-weight: 600;
  color: var(--muted);
}
/* 20.9.2026 na žiadosť — ikonka pred názvom skupiny filtrov (sekcia
   Filtre), rovnaký vizuálny jazyk ako .pill-icon v samotných pilulkách,
   len o čosi menšia (13px label, nie 15px pilulka). */
.planner-label-icon { width: 14px; height: 14px; flex-shrink: 0; }

/* Koľko jedál a koľko na deň — jediné číslo v karte, ktoré sa dá s
   niečím porovnať (obed v práci, donáška), preto v tmavom texte. */
.planner-summary {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  min-height: 20px;
}

/* 10.9.2026 — redizajn "Pill Badges/Chips": štvorcový natívny checkbox
   (predtým viditeľný vedľa textu, viď accent-color pravidlo nižšie)
   je teraz vizuálne skrytý (nie display:none — ten by rozbil focus/
   klávesnicu a čítačky obrazovky), namiesto neho celá pilulka reaguje
   na :has(input:checked) a fajka (::before) sa PLYNULE "vysunie" zľava
   (width 0→auto), nie len naskočí. */
.vegetarian-toggle {
  display: flex;
  align-items: center;
  gap: 7px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  padding: 8px 14px;
  border: 1.5px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  cursor: pointer;
  user-select: none;
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease, transform 0.08s ease;
}
.vegetarian-toggle::before {
  content: '✓';
  display: inline-block;
  width: 0;
  font-weight: 800;
  overflow: hidden;
  opacity: 0;
  transition: width 0.2s ease, opacity 0.15s ease, margin 0.2s ease;
}
.vegetarian-toggle:hover { border-color: var(--primary); transform: translateY(-1px); }
.vegetarian-toggle:has(input:checked) {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.vegetarian-toggle:has(input:checked)::before { width: 1em; opacity: 1; }
.diet-toggles .vegetarian-toggle { margin: 0; }
/* Natívny checkbox ostáva funkčný (klik/klávesnica/screen reader), len
   vizuálne mimo tok — nie display:none/visibility:hidden (obe by ho
   vyradili z prístupnosti aj focus poradia). */
.vegetarian-toggle input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip: rect(0 0 0 0);
  overflow: hidden;
  white-space: nowrap;
}

.diet-warning {
  font-size: 14px;
  color: var(--danger);
  background: var(--danger-soft);
  border: 1px solid var(--danger-border);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  margin: 8px 0 4px;
  line-height: 1.5;
}

.panel {
  /* Rovnaká jemná textúra (bodky + zelenkastý prechod) ako
     .topbar-card/.store-showcase/.category-showcase — pozri
     .category-showcase pre podrobné zdôvodnenie hodnôt. */
  background-image: var(--dots-quiet), var(--wash-quiet);
  background-size: 22px 22px, 100% 100%;
  background-position: 0 0, 0 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 22px;
  box-shadow: var(--shadow-sm);
}

.panel-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  gap: 12px;
  flex-wrap: wrap;
}
.panel-head h2 { font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }

/* ---------- Filters ---------- */

.filters { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 4px; }

/* 3.9.2026 — na žiadosť: kompaktná kópia mriežky kategórií (rovnaké
   dlaždice ako na Domov, viď renderCategoryTiles v script.js) priamo
   na obrazovke "Zľavy", nahrádza skrytý dropdown #category-filter —
   "aby som si to tam mohol kedtak znovu vyklikat" bez návratu na
   predošlú obrazovku. flex-basis:100 %, lebo .panel-head je flex riadok
   (nadpis "Zľavy" + toto) — vlastný riadok pod nadpisom, nie vedľa
   neho. Výrazne menšie než na Domov (11 stĺpcov, malé ikony/text) —
   tu ide o rýchly prepínač, nie o hlavnú vizuálnu sekciu. Boost
   (.category-card-photo--boost) vypnutý — škálovanie bolo doladené pre
   väčší rám na Domov, v tomto malom kontexte netestované/riskantné. */
.category-tiles--compact {
  flex-basis: 100%;
  display: grid;
  grid-template-columns: repeat(11, 1fr);
  gap: 7px;
  margin-top: 2px;
}
@media (max-width: 900px) {
  .category-tiles--compact { grid-template-columns: repeat(auto-fill, minmax(56px, 1fr)); }
}

/* 12.9.2026 — obrazovka výsledkov: zoznam zliav vľavo, kategórie ako
   bočný panel vpravo (na žiadosť "kategórie daj napravo pod seba, v
   dvojrade"). Predtým boli vodorovne nad zoznamom a tlačili karty pod
   okraj. */
.deals-split {
  display: grid;
  grid-template-columns: 240px 1fr;   /* kategórie vľavo, zoznam vpravo */
  gap: 22px;
  align-items: start;   /* nech sticky bočný panel funguje (inak grid natiahne položku na plnú výšku) */
}
.deals-main { min-width: 0; }   /* karty nesmú nafúknuť pravý stĺpec nad 1fr */
.deals-side {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 14px;
}
.deals-side-title {
  margin: 0 0 10px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}
/* V úzkom bočnom paneli dva stĺpce dlaždíc namiesto 11. */
.category-tiles--side { grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 0; }

@media (max-width: 900px) {
  .deals-split { grid-template-columns: 1fr; }
  /* Kategórie sú v HTML prvé, takže na jednom stĺpci vyjdú hore, zoznam
     pod nimi — netreba order. */
  .deals-side { position: static; }
  .category-tiles--side { grid-template-columns: repeat(auto-fill, minmax(56px, 1fr)); }
}
/* 3.9.2026 — na žiadosť o ~15% väčšie ("o malicko zvacsi") — obsah
   dlaždice (ikona/text) škálovaný ×1.15, stĺpce ostávajú 11 (nemení sa
   počet riadkov mriežky), rastie len to, čo je v každej bunke vidieť. */
/* 10.9.2026 — na žiadosť "vygenerovalo mi to a tie kategorie mam v
   takomto neprecitatelnom stave": dvojslovné názvy (napr. "Mliečne
   výrobky", "Omáčky a korenie") sa pri pevnej výške 85px + line-clamp:1
   orezávali TVRDO uprostred slova/frázy bez "…" — vyzeralo to ako
   pokazený text, nie skrátený popisok. min-height namiesto height (rastie
   podľa obsahu, CSS Grid aj tak zarovná celý riadok na najvyššiu
   dlaždicu) + line-clamp:2 + ellipsis nižšie: krátke názvy ostanú na
   jednom riadku ako predtým, dlhšie sa zalomia čitateľne na dva riadky
   namiesto orezania. */
.category-tiles--compact .category-card {
  min-height: 85px;
  padding: 7px 4px 6px;
  border-radius: calc(var(--radius-md) - 2px);
}
.category-tiles--compact .category-card:hover { transform: none; box-shadow: none; }
.category-tiles--compact .category-card-icon,
.category-tiles--compact .category-card-icon--boost {
  height: 48px;
  flex: 0 0 48px;
  margin-bottom: 3px;
}
.category-tiles--compact .category-card-icon--svg {
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  margin: 0 auto 3px;
}
.category-tiles--compact .category-card-icon svg { width: 15px; height: 15px; }
.category-tiles--compact .category-card-photo--boost { transform: none; }
.category-tiles--compact .category-card-label {
  font-size: 10px;
  -webkit-line-clamp: 2;
}
.category-tiles--compact .category-card-count { font-size: 9px; margin-top: 1px; }

.store-inspiration-note {
  font-size: 14.5px;
  color: var(--muted);
  margin-top: 10px;
}
.store-inspiration-note a { color: var(--primary-dark); text-decoration: none; border-bottom: 1px dotted var(--border-strong); }
.store-inspiration-note a:hover { color: var(--primary); border-color: var(--primary); }

.search-input {
  width: 100%;
  flex-basis: 100%;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 10px 16px 10px 38px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 15.5px;
  color: var(--ink);
  background-color: var(--surface-alt);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236C7062' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 13px center;
  transition: border-color 0.15s ease, box-shadow 0.15s ease, background-color 0.15s ease;
}
.search-input::placeholder { color: var(--muted); }
.search-input:focus {
  outline: none;
  border-color: var(--primary);
  background-color: var(--surface);
  box-shadow: 0 0 0 4px var(--primary-soft);
}

select#timing-filter, select#store-filter, select#category-filter {
  appearance: none;
  -webkit-appearance: none;
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 7px 30px 7px 14px;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 15px;
  color: var(--ink);
  background-color: var(--surface-alt);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236C7062' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
select#timing-filter:hover, select#store-filter:hover, select#category-filter:hover { border-color: var(--border-strong); }
select#timing-filter:focus, select#store-filter:focus, select#category-filter:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 4px var(--primary-soft);
}

/* ---------- Deals list ---------- */

/* 12.9.2026 — zoznam zliav je presne taký vysoký ako bočný panel
   kategórií vedľa neho a zvyšok scrolluje vnútri. Bez tejto výšky by buď
   zostávala pod ním prázdna medzera (keď je kariet málo), alebo by
   stránka narástla na desaťtisíce px (keď ich je veľa, 1110). Konkrétnu
   výšku dopĺňa JS (syncDealsListHeight) podľa reálnej výšky panela; toto
   je len záložný strop, keby JS nezbehol. Na mobile (pod 900 px) sa
   max-height ruší — tam sú kategórie nad zoznamom, medzera nevzniká. */
/* 13.9.2026 nahlásené: priblížená karta (.deal-card:hover, scale(1.3))
   sa pri kartách v prvom stĺpci orezávala presne na hranici s bočným
   panelom kategórií — vyzeralo to, akoby ju kategórie prekrývali.
   Príčina nebola z-index (ten je v poriadku), ale overflow: keď má box
   nastavené overflow-y: auto, prehliadač MU AJ overflow-x automaticky
   zmení z "visible" na "auto" (CSS špecifikácia to vyžaduje), takže
   čokoľvek pretečie vodorovne sa odreže na hrane boxu. Riešenie:
   rezervovaný priestor VĽAVO (padding + kompenzujúci záporný margin)
   väčší než maximálne možné pretečenie karty pri 1.3× zväčšení — karta
   sa tak zmestí celá, bez zásahu do rozloženia v pokojovom stave
   (padding presne kompenzuje margin). Zámerne len vľavo: táto rezerva
   sa "požičia" z medzery ku kategóriám (vnútri .deals-split, nikdy
   nepresiahne .layout), kým vpravo by rovnaký trik bez poistky vedel
   za určitých šírok okna spôsobiť vodorovný scrollbar celej appky
   (skúšané, vrátené — bezpečnejšie je nechať pravú stranu, ako bola). */
.deals-list {
  display: flex;
  flex-direction: column;
  gap: 24px;
  max-height: 80vh;
  overflow-y: auto;
  padding: 0 6px 0 48px;
  margin: 0 -6px 0 -48px;
}
.deals-list::-webkit-scrollbar { width: 8px; }
.deals-list::-webkit-scrollbar-track { background: transparent; }
.deals-list::-webkit-scrollbar-thumb { background: var(--border-strong); border-radius: 999px; }

.category-group { display: flex; flex-direction: column; gap: 10px; }

.category-heading {
  font-size: 16.5px;
  font-weight: 600;
  color: var(--primary-dark);
  border-bottom: 1px solid var(--border);
  padding-bottom: 8px;
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: 8px;
}
.category-count {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
  background: var(--surface-alt);
  border-radius: 999px;
  padding: 1px 8px;
}

/* Responzívna mriežka (nie 1 stĺpec) — pri viacerých zvolených
   kategóriách naraz appka predtým vypisovala desiatky kariet pod sebou
   v jednom stĺpci (nekonečný scroll). auto-fill + minmax dá pri bežnej
   šírke panela 3-4 karty vedľa seba, menej na užšom viewporte. */
.category-cards {
  display: grid;
  /* 18.9.2026 — na žiadosť "zvacsi tie zlavy o dalsich 15%" (karty
     produktov v zozname): 170px → 196px, rozmery/fonty na karte nižšie
     prepočítané rovnakým pomerom (rovnaký princíp ako .category-card). */
  grid-template-columns: repeat(auto-fill, minmax(196px, 1fr));
  gap: 12px;
}

.hint { font-size: 15px; color: var(--muted); margin: 0 0 12px; line-height: 1.5; }
/* 18.9.2026 — text-tlačidlo uprostred vety (napr. odkaz na Filtre z
   katalógu receptov) — vyzerá ako bežný odkaz, ale ide cez [data-view]
   namiesto <a href>, lebo appka je jedna stránka bez viacerých URL. */
.link-btn {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  font: inherit;
  color: var(--primary);
  text-decoration: underline;
  cursor: pointer;
}

.kcal-badge { font-size: 12.5px; color: var(--gold); font-weight: 600; white-space: nowrap; }

.verify-link {
  font-size: 13px;
  color: var(--muted);
  text-decoration: none;
  border-bottom: 1px dotted var(--border-strong);
  white-space: nowrap;
}
.verify-link:hover { color: var(--primary); border-color: var(--primary); }

/* Karta zľavy je odkedy je .category-cards mriežka (vyššie) užšia než
   predtým (bola to jediná položka širokého 1-stĺpcového zoznamu) —
   preto je teraz zvislý stĺpec (info hore, cena, tlačidlo dole) namiesto
   pôvodného širokého riadku (info vľavo / cena vpravo / tlačidlo úplne
   vpravo), ktorý by sa do ~200-260px stĺpca mriežky nezmestil. */
.deal-card {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 11.5px;
  box-shadow: var(--shadow-xs);
  transition: box-shadow 0.18s ease, border-color 0.18s ease, transform 0.18s ease, background-color 0.18s ease;
}
/* Výrazné priblíženie karty pod kurzorom — rovnaký vzor ako
   .category-card/.store-card vyššie (position:relative + z-index nad
   susednými kartami mriežky, aby priblížená karta prekryla okolie). */
.deal-card:hover { box-shadow: var(--shadow-md); border-color: var(--border-strong); transform: scale(1.3); z-index: 20; }
.deal-card:active { transform: scale(1.25); }
.deal-card.tracked { background: var(--primary-soft); border-color: var(--primary); }
.deal-card.upcoming { border-style: dashed; opacity: 0.82; }

/* Hlavička karty — obchod + zľavový odznak vždy na rovnakom mieste, nad
   názvom, jednotná naprieč všetkými obchodmi (predtým bol .deal-store
   zamiešaný priamo medzi textom, čo pri niektorých kartách posúvalo
   zvyšok obsahu). */
.deal-card-header {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}

/* Logo obchodu v hlavičke karty (nahradilo textový štítok s názvom
   obchodu) — na prvý pohľad jasné, odkiaľ produkt je, aj v mriežke kde
   sú karty z rôznych reťazcov pomiešané. Logá sú skutočne priehľadné PNG
   (viď STORE_LOGOS/renderStoreTiles), preto rovnaký var(--surface) chip
   ako zvyšok appky namiesto natvrdo bieleho podkladu. */
.deal-store-logo-wrap {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 25px;
  max-width: 78px;
  padding: 2px 9px;
  box-sizing: border-box;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 999px;
}
.deal-store-logo-wrap img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

/* Produktový obrázok natvrdo na karte (nie za hoverom). Box je VŽDY
   vyrenderovaný (aj bez fotky, viď fallback SVG nižšie) — predtým sa pri
   chýbajúcom obrázku celý .deal-img-wrap vynechal, takže karty s a bez
   fotky mali inú výšku/štruktúru.

   Jednotný rámik (pozadie + zaoblenie + padding) pre VŠETKY zdroje
   obrázka — zmenené 24. 8. 2026, keď sa karty začali plniť aj surovými
   letákovými dlaždicami (`image`, pôvodné farebné pozadie obchodu,
   rôzny pomer strán) popri čistých rembg PNG (`image_clean`, skutočná
   priehľadnosť). Predtým bol box zámerne bez pozadia, aby čisté PNG
   "splynuli" s kartou — pri miešaní oboch zdrojov v jednej mriežke to
   ale vyzeralo nesúrodo (raz obrázok pláva voľne, raz má vlastné pestré
   pozadie tesne pri okraji karty). Jeden spoločný neutrálny rámik okolo
   KAŽDÉHO obrázka (nezávisle od zdroja/pomeru strán) zjednotí mriežku —
   rovnaký princíp ako fotokartičky v bežných e-shopoch. */
.deal-img-wrap {
  position: relative;
  width: 100%;
  height: 167px;
  flex: 0 0 167px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 11.5px;
  box-sizing: border-box;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--border-strong);
}
.deal-img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  border-radius: calc(var(--radius-sm) - 4px);
}
.deal-img-wrap svg { flex: 0 0 auto; }

/* Štítok na ilustračnej fotke kategórie (žiadna fotka konkrétneho
   produktu ešte nie je spracovaná, viď isGenericImg v renderDeals) —
   aby si používateľ fotku nepomýlil so skutočným produktom. */
.deal-img-generic-tag {
  position: absolute;
  left: 6px;
  bottom: 6px;
  font-size: 12.6px;
  font-weight: 700;
  color: var(--muted);
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 2px 8px;
  border-radius: 999px;
  letter-spacing: 0.01em;
}

/* Spodná časť karty (dátum/kcal, cena, tlačidlo) — margin-top: auto ju
   pripne na dno karty bez ohľadu na dĺžku názvu (ten má fixnú výšku
   nižšie) alebo prítomnosť days-left odznaku, takže tlačidlá "+ Sledovať"
   naprieč riadkom mriežky sedia vodorovne na rovnakej úrovni. */
.deal-card-footer {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Dátum platnosti schovaný pod decentný tag namiesto dlhého inline textu
   ("platí YYYY-MM-DD – YYYY-MM-DD") — informácia zostáva dostupná, len
   nepôsobí ako hlavný obsah karty (tú úlohu má názov produktu a cena). */
.date-tag {
  display: inline-block;
  font-size: 13.8px;
  font-weight: 600;
  color: var(--muted);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 1px 9px;
  /* Bez nowrap — v úzkej karte mriežky (viď .category-cards) by dlhší
     dátumový rozsah pretiekol cez okraj karty namiesto zalomenia. */
  max-width: 100%;
  box-sizing: border-box;
}

.discount-badge {
  display: inline-block;
  font-size: 13.8px;
  font-weight: 700;
  color: #fff;
  background: var(--accent);
  padding: 2px 8px;
  border-radius: 999px;
  margin-right: 6px;
  letter-spacing: 0.01em;
}
.upcoming-badge {
  display: inline-block;
  font-size: 13.2px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #fff;
  background: var(--muted);
  padding: 2px 8px;
  border-radius: 999px;
  margin-right: 6px;
}

.days-left-badge {
  display: inline-block;
  margin-top: 5px;
  font-size: 16px;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: 999px;
  letter-spacing: 0.01em;
}
.days-left-normal { color: var(--muted); background: var(--surface-alt); }
.days-left-soon { color: var(--gold); background: rgba(192, 145, 47, 0.14); }
.days-left-urgent { color: #fff; background: var(--danger); }
.days-left-ended { color: var(--danger); background: var(--danger-soft); border: 1px solid var(--danger-border); }

.deal-info { min-width: 0; }
/* Fixná výška na presne 2 riadky (line-height * 2), zarovnané nahor —
   krátke aj dlhé názvy zaberajú rovnaký priestor, takže obrázok a spodná
   časť karty (footer) sú naprieč celým riadkom mriežky vždy na rovnakej
   výške bez ohľadu na dĺžku názvu produktu. */
.deal-name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-weight: 600;
  font-size: 19px;
  line-height: 1.3;
  min-height: calc(1.3em * 2);
  letter-spacing: -0.003em;
}
.deal-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; font-size: 16px; color: var(--muted); }
.deal-store {
  display: inline-block;
  font-size: 13.8px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--primary-dark);
  background: var(--primary-soft);
  padding: 2px 9px;
  border-radius: 999px;
  margin-right: 6px;
}

/* Bez nowrap — pri dlhšom texte jednotky (napr. "0.7 l 1 darčekové
   balenie") by v úzkej karte mriežky pretiekol cez okraj. */
.deal-price { text-align: left; }
/* Tlačidlo "+ Sledovať" na spodku zvislej karty roztiahnuté na celú
   šírku (bežný vzor pre CTA na spodku produktovej karty v gridoch),
   scoped len na .deal-card — .track-btn sa inde (item-card, dropdowny)
   správa ako predtým, kompaktný pill. */
.deal-card .track-btn { align-self: stretch; text-align: center; }
/* 28.8.2026 — na žiadosť používateľa: pôvodná (preškrtnutá) cena má
   teraz farbu, akú predtým mala akčná cena (var(--accent), oranžová) —
   výraznejšia než predošlá sivá, a o čosi väčšia (12.5px -> 14px), aby
   bolo poriadne vidno, z akej sumy sa šetrí. Akčná cena je teraz VŽDY
   zelená (var(--primary)) naprieč celou appkou — jednoznačný signál
   "toto je tá výhodná cena", zjednotené s tým, ako už predtým fungovala
   len v .deal-price/.item-card-price (viď komentár nižšie, teraz už
   len redundantný, no neškodný duplicitný zápis tej istej farby). */
.old-price { text-decoration: line-through; color: var(--accent); font-size: 18.4px; }
.new-price { color: var(--primary); font-weight: 700; font-size: 21.3px; letter-spacing: -0.01em; }

/* 11.9.2026 — cena za kilo/liter/kus (unit_price.py). Zámerne TICHÁ, pod
   cenou balenia: cena, ktorú naozaj zaplatíš, je tá veľká; toto je
   pomôcka na porovnanie dvoch rôzne veľkých balení. Normalizuje sa na
   kilo a liter, teda na to isté, čo má obchod na regálovej cenovke. */
.unit-price {
  margin-top: 2px;
  font-size: 13.8px;
  font-weight: 600;
  color: var(--muted);
  cursor: help;
}
.plan-shop-unit-price { color: var(--ink); font-weight: 600; }

/* 11.9.2026 — uložený plán mohol prežiť obnovu letáku. Ceny po platnosti
   sa nesmú tváriť ako platné (viď planExpiredItems v script.js). */
.plan-stale {
  margin: 0 0 16px;
  padding: 12px 14px;
  border-radius: var(--radius-md);
  background: var(--accent-soft);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.5;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 30%, transparent);
}
.plan-shop-item.is-expired { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--danger) 45%, transparent); }
.plan-shop-item.is-expired .plan-shop-price strong { text-decoration: line-through; color: var(--muted); }
.plan-shop-expired {
  margin-top: 3px;
  font-size: 11.5px;
  font-weight: 700;
  color: var(--danger);
}

/* Cifry rovnakej šírky. Inter má predvolene proporcionálne číslice, takže
   "1.79 €" a "4.99 €" mali rôznu dĺžku a ceny pod sebou v mriežke zliav
   sa vizuálne kývali. Celá appka je o porovnávaní čísel — tie majú stáť
   v stĺpci. */
.old-price,
.new-price,
.deal-price,
.category-card-count,
.top-savings-old-price,
.top-savings-new-price,
.item-card-price {
  font-variant-numeric: tabular-nums;
}

/* Konečná cena je hlavný dôvod, prečo si niekto kartu otvorí — v karte
   zľavy aj v riadkoch nákupného zoznamu (.item-card-price) je preto
   zámerne väčšia, tučnejšia a ZELENÁ (namiesto akcentovej oranžovej
   inde v appke), aby okamžite pútala pozornosť pred menej dôležitými
   detailmi (obchod, dátum platnosti, kategória). */
.deal-price .new-price,
.item-card-price {
  color: var(--primary);
  font-weight: 800;
  font-size: 24px;
  letter-spacing: -0.015em;
}
/* 12.9.2026 — akčná cena na karte zľavy zmenšená o 10 % (24 → 21,6 px) na
   žiadosť "tá cena je obrovská". Len karta zľavy; .item-card-price
   (nákupný zoznam) ostáva.
   21.6px → 24.8px (18.9.2026, "zvacsi tie zlavy o dalsich 15%" — celá
   karta zľavy o 15 % väčšia, táto špecifickejšia pravidlo prebíja base
   .new-price vyššie a musí sa škálovať zvlášť). */
.deal-price .new-price { font-size: 24.8px; }

.track-btn {
  border: none;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: 14.5px;
  font-weight: 600;
  padding: 8px 16px;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease, transform 0.12s ease;
}
.track-btn:hover { background: var(--primary); color: #fff; box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.track-btn:active { transform: translateY(0) scale(0.96); }
.track-btn.active { background: var(--primary); color: #fff; }
.track-btn.active:hover { background: var(--primary-dark); }

/* ---------- Hover náhľad produktu (fotka + popis) ----------
   Nahradilo staršie .deal-image-preview (malý obrázok pri hoveri celej
   karty) — teraz je hover cielený presne na názov produktu (.product-name-hover),
   funguje rovnako v hlavnom zozname, nákupe na rozpočet aj sledovaných
   položkách, a ukazuje aj popis/nutríciu, nie len fotku. */
.product-name-hover {
  cursor: help;
  border-bottom: 1px dotted var(--muted);
}

/* 3.9.2026 — na žiadosť o 25% menší ("velmi velke ked na produkt idem
   s kurzorom") — celý popover aj jeho vnútorný obsah škálované ×0.75. */
.product-popover {
  position: fixed;
  z-index: 200;
  width: 195px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.12s ease;
}
.product-popover.visible { opacity: 1; visibility: visible; }

.product-popover-img-wrap {
  width: 100%;
  height: 112px;
  background: var(--surface-alt);
  display: flex;
  align-items: center;
  justify-content: center;
}
.product-popover-img { width: 100%; height: 100%; object-fit: contain; padding: 8px; }
.product-popover-placeholder { font-size: 45px; color: var(--muted); }
.product-popover-placeholder svg { width: 1em; height: 1em; }

.product-popover-body { padding: 9px 11px 11px; }
.product-popover-name { font-weight: 700; font-size: 12px; line-height: 1.35; margin-bottom: 3px; }
.product-popover-meta { font-size: 10px; color: var(--muted); margin-bottom: 6px; }
.product-popover-price { display: flex; align-items: baseline; gap: 6px; margin-bottom: 3px; }
/* .old-price/.new-price/.discount-badge sú zdieľané triedy (rovnaké aj
   na bežnej karte zľavy) — v tomto menšom popovere by ich základná
   veľkosť (14/16/10.5px) pôsobila neprimerane veľká, preto scoped
   prepis len tu, nie zásah do základných tried. */
.product-popover-price .old-price { font-size: 12px; }
.product-popover-price .new-price { font-size: 14px; }
.product-popover-price .discount-badge { font-size: 9px; padding: 1.5px 5px; margin-right: 4px; }
.product-popover-valid { font-size: 9px; color: var(--muted); margin-bottom: 5px; }
.product-popover-nutrition { font-size: 10px; color: var(--ink); line-height: 1.6; margin-bottom: 5px; }
.product-popover-badges { font-size: 10px; color: var(--primary-dark); }
.product-popover-noimg-hint { font-size: 9px; color: var(--muted); font-style: italic; margin-top: 3px; }

/* ---------- Buttons ---------- */

.btn-primary {
  background: var(--primary);
  color: #fff;
  border: none;
  padding: 10px 20px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 15px;
  cursor: pointer;
  box-shadow: var(--shadow-xs);
  transition: background-color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
}
.btn-primary:hover { background: var(--primary-dark); box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.btn-primary:active { transform: translateY(0); }
.btn-primary:disabled { opacity: 0.55; cursor: default; transform: none; box-shadow: none; }

.btn-clear-tracked {
  background: transparent;
  color: var(--danger);
  border: 1.5px solid var(--danger-border);
  padding: 6px 14px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.15s ease, transform 0.08s ease;
}
.btn-clear-tracked:hover { background: var(--danger-soft); }
.btn-clear-tracked:active { transform: scale(0.96); }

.hidden { display: none !important; }

.plan-tabs { display: flex; gap: 6px; margin-bottom: 16px; border-bottom: 1px solid var(--border); }
.plan-tab {
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  padding: 8px 4px 10px;
  margin-right: 18px;
  font-size: 16px;
  font-weight: 600;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.plan-tab:hover { color: var(--ink); }
.plan-tab.active { color: var(--primary-dark); border-bottom-color: var(--primary); }

.weekly-summary { font-size: 16px; margin-bottom: 16px; color: var(--ink); }
.weekly-summary strong { color: var(--accent); }

.weekly-meals { display: flex; flex-direction: column; gap: 10px; margin-bottom: 22px; }
.weekly-meal-card {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
  background: var(--surface);
}
.weekly-meal-title-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.weekly-meal-title { font-family: 'Plus Jakarta Sans', serif; font-weight: 600; font-size: 17px; margin-bottom: 4px; }
.weekly-meal-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }
.weekly-meal-source { font-size: 12px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 6px; }
.weekly-meal-source a { color: var(--primary-dark); text-decoration: none; border-bottom: 1px dotted var(--border-strong); }
.weekly-meal-source a:hover { color: var(--primary); border-color: var(--primary); }
.weekly-meal-tag {
  font-size: 12px;
  font-weight: 600;
  color: var(--primary-dark);
  background: var(--primary-soft);
  padding: 2px 8px;
  border-radius: 999px;
}
.weekly-meal-ingredients { font-size: 14.5px; color: var(--muted); }
.weekly-meal-steps {
  margin: 8px 0 0;
  padding-left: 18px;
  font-size: 15px;
  color: var(--ink);
  display: none;
}
.weekly-meal-card.expanded .weekly-meal-steps { display: block; }
.weekly-meal-steps li { margin-bottom: 6px; line-height: 1.5; }
.weekly-meal-toggle {
  background: none;
  border: none;
  color: var(--primary-dark);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  padding: 4px 0 0;
}

.weekly-shopping-store { font-family: 'Plus Jakarta Sans', serif; font-weight: 600; font-size: 16px; margin: 16px 0 8px; }
.weekly-shopping-store:first-of-type { margin-top: 0; }
.weekly-unmatched { font-size: 14.5px; color: var(--muted); margin-top: 8px; }

/* ---------- Odporúčané recepty (top N naraz, match-rate zoradené) ----------
   21.9.2026 na žiadosť ("nech je to výstavná kniha, toto je naše gro")
   — karta dostala nový vizuál (farebný hero pás s ikonou, viď nižšie).
   Mriežka o viacerých stĺpcoch (vyskúšaná v ten istý deň) sa ale
   nahlásila ako neprehľadná — appka sa vrátila na jeden stĺpec pod
   sebou (pôvodné usporiadanie), len s týmto novým vizuálom kariet. */
.match-recipes-list {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-top: 14px;
}
.match-recipe-card {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
  background: var(--surface);
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.match-recipe-card:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-sm);
  border-color: var(--border-strong);
}
.match-recipe-head { margin-bottom: 6px; }
.match-recipe-head-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.match-recipe-title-row { display: flex; align-items: flex-start; gap: 10px; min-width: 0; }
.match-recipe-title { font-family: 'Plus Jakarta Sans', serif; font-weight: 600; font-size: 17px; margin-bottom: 4px; }
.match-recipe-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
/* 21.9.2026 — vyskúšaný veľký farebný "hero" pás (miesto na fotku, ktorú
   appka nemá) sa v ten istý deň nahlásil ako zbytočne roztiahnutý. Späť
   na kompaktnú okrúhlu "avatar" ikonu vedľa názvu (pôvodné rozloženie
   z 13.9.2026), len s bohatšou paletou — farba+ikona podľa
   recipe.categories (recipe_category.py cez recipeCategoryVisual v
   recipe-cards.js) namiesto pôvodných troch (varenie/pečenie/vegetariánsky). */
.recipe-type-icon {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}
.recipe-type-icon .inline-icon { width: 18px; height: 18px; }
.recipe-type-icon--cook,
.recipe-type-icon--soup,
.recipe-type-icon--chicken { background: var(--gold-soft); color: var(--gold); }
.recipe-type-icon--baking,
.recipe-type-icon--pasta,
.recipe-type-icon--pork { background: var(--accent-soft); color: var(--accent); }
.recipe-type-icon--veg,
.recipe-type-icon--salad,
.recipe-type-icon--fish { background: var(--primary-soft); color: var(--primary-dark); }
.recipe-type-icon--beef { background: var(--danger-soft); color: var(--danger); }
.match-recipe-source {
  font-size: 12px;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.match-recipe-badge {
  font-size: 12px;
  font-weight: 600;
  color: var(--primary-dark);
  background: var(--primary-soft);
  padding: 2px 8px;
  border-radius: 999px;
}
.match-recipe-body { display: none; margin-top: 8px; }
.match-recipe-card.expanded .match-recipe-body { display: block; }
.match-recipe-toggle {
  background: none;
  border: none;
  color: var(--primary-dark);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  padding: 6px 0 0;
}

/* ---------- Tracked summary / table ---------- */

.tracked-summary { font-size: 15px; color: var(--ink); margin-bottom: 14px; min-height: 18px; line-height: 1.6; }

.price-total { font-size: 15.5px; color: var(--ink); }
.price-total strong { color: var(--accent); font-size: 18.5px; }

.price-saved-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 10px;
  padding: 12px 16px;
  background: color-mix(in srgb, var(--primary) 14%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--primary) 35%, transparent);
  border-radius: var(--radius-md);
}
.price-saved-icon { font-size: 27.5px; line-height: 1; }
.price-saved-text { display: flex; flex-direction: column; gap: 2px; }
.price-saved-amount { font-size: 22px; font-weight: 800; color: var(--primary); line-height: 1.15; }
.price-saved-sub { font-size: 14px; color: var(--muted); }
.price-saved-note { margin-top: 6px; font-size: 12.5px; color: var(--muted); }

/* 22.9.2026 — banner na Domov zrkadliaci reálnu úsporu zo Sledovaných
   položiek (viď index.html, home-tracked-banner) — rovnaký vizuálny
   jazyk ako .price-saved-banner vyššie (ten istý zelený odtieň = tá
   istá informácia, len na inom mieste appky), ale ako vodorovný riadok
   s tlačidlom vpravo namiesto stĺpca vnútri užšieho panelu. */
.home-tracked-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 16px 22px;
  background: color-mix(in srgb, var(--primary) 14%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--primary) 35%, transparent);
  border-radius: var(--radius-lg);
}
.home-tracked-banner-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.home-tracked-banner-amount { font-size: 22px; font-weight: 800; color: var(--primary); line-height: 1.15; }
.home-tracked-banner-sub { font-size: 14px; color: var(--muted); }

/* 12.9.2026 — "N položiek kúpiš inde lacnejšie" v sledovanom nákupe
   (cross_store.py). Jantárový tip, nie zelená pochvala ako úspora —
   je to výzva zvážiť iný obchod, nie hotová dobrá správa. */
.tracked-cheaper {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 10px;
  padding: 11px 14px;
  background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--danger) 28%, transparent);
  border-radius: var(--radius-md);
}
.tracked-cheaper .inline-icon { width: 18px; height: 18px; flex: 0 0 auto; margin-top: 1px; color: color-mix(in srgb, var(--danger) 80%, var(--ink)); }
.tracked-cheaper-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.tracked-cheaper-text strong { font-size: 14px; color: var(--ink); }
.tracked-cheaper-list { font-size: 12.5px; color: var(--muted); line-height: 1.4; }

.budget-track-all-btn { display: block; margin: 0 0 14px; }

.tracked-table-wrap { max-height: 340px; overflow-y: auto; margin-bottom: 18px; padding-right: 4px; }

/* ---------- Nákupný zoznam ako karty (Sledované položky / Nákup na
   rozpočet / Týždenný plán) — nahradilo pôvodné <table>, rovnaký vizuálny
   jazyk ako .deal-card vyššie (zaoblenie, jemný tieň/okraj), len
   kompaktnejšie (jeden riadok na položku). ---------- */
.item-card-list { display: flex; flex-direction: column; gap: 8px; }
.item-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 10px 14px;
  transition: box-shadow 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
.item-card:hover { box-shadow: var(--shadow-sm); border-color: var(--border-strong); transform: translateY(-1px); }
.item-card-main { flex: 1; min-width: 0; }
.item-card-name { font-weight: 600; font-size: 15.5px; letter-spacing: -0.003em; }
.item-card-meta { font-size: 13px; color: var(--muted); margin-top: 3px; line-height: 1.5; }
.item-card-price { white-space: nowrap; text-align: right; min-width: 60px; }
/* "Vyhodiť z nákupu" — malé nenápadné ✕ vedľa track-btn, viditeľnejšie
   až na hover (nechce pôsobiť ako hlavná akcia karty, tou zostáva
   sledovanie). */
.budget-remove-item-btn {
  flex: 0 0 auto;
  width: 24px;
  height: 24px;
  border: none;
  border-radius: 50%;
  background: transparent;
  color: var(--muted);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.budget-remove-item-btn:hover { background: var(--danger-soft); color: var(--danger); }
.item-card-actions { display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }

/* 10.9.2026 — Nákup na rozpočet: na žiadosť "tie suroviny mi to kludne
   moze dat vedla seba aj s obrazkami" — zoznam surovín TOHTO JEDNÉHO
   miesta (výsledok budget-basket) je teraz responzívna mriežka kariet s
   fotkou namiesto úzkych riadkov pod sebou (predtým "vsetko do riadkov,
   neprehľadné"). Zdieľané .item-card/.item-card-list (Sledované
   položky, Týždenný plán) ostávajú bezo zmeny — táto verzia je scoped
   cez --grid modifikátor, nie globálna zmena spoločnej komponenty. */
.item-card-list--grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(148px, 1fr));
  gap: 10px;
}
.item-card--grid {
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  text-align: left;
  padding: 10px;
}
.item-card-img-wrap { width: 100%; height: 96px; display: flex; align-items: center; justify-content: center; }
.item-card-img-wrap .global-search-result-img,
.item-card-img-wrap .global-search-result-img-fallback { width: 100%; height: 96px; font-size: 34.5px; }
.item-card--grid .item-card-main { flex: initial; width: 100%; }
.item-card--grid .item-card-price { width: 100%; text-align: left; font-weight: 600; color: var(--ink); }
.item-card--grid .item-card-actions { width: 100%; justify-content: space-between; }
.item-card--grid .budget-track-btn { flex: 1 1 auto; padding: 6px 10px; font-size: 13px; text-align: center; }
@media (max-width: 480px) {
  .item-card-list--grid { grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); }
}

.match-recipes-heading {
  font-size: 16px;
  font-weight: 600;
  color: var(--muted);
  margin: 18px 0 10px;
}

.tracked-qty-cell { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.qty-btn {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--ink);
  width: 22px;
  height: 22px;
  line-height: 1;
  border-radius: 999px;
  cursor: pointer;
  font-size: 16px;
  font-weight: 600;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.qty-btn:hover:not(:disabled) { background: var(--primary-soft); border-color: var(--primary); color: var(--primary-dark); }
.qty-btn:disabled { opacity: 0.35; cursor: default; }
.qty-value { min-width: 16px; text-align: center; font-weight: 600; font-size: 15px; }

.tracked-nutrition { font-size: 13px; color: var(--muted); margin-top: 3px; line-height: 1.6; }
.tracked-nutrition strong { color: var(--primary-dark); }
.tracked-nutrition-missing { font-style: italic; }
.tracked-nutrition-total {
  font-size: 14.5px;
  color: var(--ink);
  background: var(--surface-alt);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  margin-top: 4px;
  line-height: 1.7;
}
.tracked-nutrition-total strong { color: var(--accent); }

.untrack-btn {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--muted);
  width: 26px;
  height: 26px;
  line-height: 1;
  border-radius: 999px;
  cursor: pointer;
  font-size: 17px;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.untrack-btn:hover { background: var(--danger-soft); border-color: var(--danger-border); color: var(--danger); }

.nutrition-summary {
  font-size: 15px;
  color: var(--ink);
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 10px 14px;
  margin: 12px 0;
  line-height: 1.6;
}
.hint-inline { display: block; color: var(--muted); font-size: 13px; margin-top: 2px; }

/* ---------- Recipe card ---------- */

.recipe-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 18px;
  background: var(--surface-alt);
}
.recipe-image {
  display: block;
  width: 100%;
  max-height: 200px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  margin-bottom: 12px;
}
.recipe-title-row { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.recipe-title { font-size: 20.5px; font-weight: 600; margin: 0 0 4px; letter-spacing: -0.01em; }
.recipe-source { font-size: 12.5px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 12px; }
.recipe-source a { color: var(--primary-dark); text-decoration: none; border-bottom: 1px dotted var(--border-strong); }
.recipe-source a:hover { color: var(--primary); border-color: var(--primary); }
.recipe-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 10px; }
.recipe-tag {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--primary-dark);
  background: var(--primary-soft);
  padding: 3px 10px;
  border-radius: 999px;
}
.recipe-nutrition { font-size: 15px; color: var(--ink); margin-bottom: 12px; }
.recipe-nutrition strong { color: var(--accent); }
.recipe-subheading { font-family: 'Plus Jakarta Sans', serif; font-size: 16.5px; font-weight: 600; color: var(--primary-dark); margin: 16px 0 8px; }
.recipe-subheading:first-of-type { margin-top: 4px; }
.recipe-ingredients { margin: 0; padding-left: 18px; font-size: 15.5px; color: var(--ink); }
.recipe-ingredients li { margin-bottom: 4px; }
.recipe-missing { margin: 0; padding-left: 18px; font-size: 15.5px; color: var(--muted); }
.recipe-pantry { margin: 0; padding-left: 18px; font-size: 15.5px; color: var(--muted); font-style: italic; }
.recipe-pantry li { margin-bottom: 4px; }
.recipe-steps { margin: 0; padding-left: 18px; font-size: 15.5px; color: var(--ink); }
.recipe-steps li { margin-bottom: 8px; line-height: 1.55; }
.recipe-external-cta {
  display: block;
  text-align: center;
  margin-top: 16px;
  padding: 12px 18px;
  border-radius: 12px;
  background: var(--primary);
  color: #fff;
  font-weight: 600;
  font-size: 16px;
  text-decoration: none;
  transition: background-color 0.15s ease, transform 0.08s ease;
}
.recipe-external-cta:hover { background: var(--primary-dark); }
.recipe-external-cta:active { transform: scale(0.98); }

/* ---------- Misc ---------- */

.error-box {
  background: var(--danger-soft);
  border: 1px solid var(--danger-border);
  color: var(--danger);
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  font-size: 15px;
}

.footer {
  color: var(--muted);
  font-size: 14px;
  padding: 28px 20px 36px;
  border-top: 1px solid var(--border);
  margin-top: 40px;
}

/* 16.9.2026 — pätička nesie právne vyhlásenia (nezávislosť od reťazcov,
   informatívny charakter cien). Text je dlhší než pôvodné "Lokálny
   prototyp", preto ZAROVNANÝ VĽAVO a v úzkom stĺpci: vycentrované
   viacriadkové odstavce sa čítajú ťažko, lebo každý riadok začína inde.
   Menšie písmo než telo stránky — je to doplnok, nie obsah. */
.footer-inner {
  max-width: 720px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.footer-inner p {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.6;
}

/* Cez .footer-inner, nie samostatne — inak by ho prebilo pravidlo
   `.footer-inner p` vyššie (rovnaká váha, ale neskôr v súbore). */
.footer-inner .footer-brand {
  color: var(--ink);
  font-weight: 600;
  font-size: 14px;
}

/* Riadok odkazov úplne naspodku — rovnaká trojica, akú majú slovenské
   zľavové weby (Kupino.sk, Letákomat.sk): podmienky, ochrana údajov,
   kontakt. Zalamuje sa, aby sa zmestil aj na 360 px širokom telefóne. */
.footer-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
  margin-top: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  font-size: 12.5px;
}

.footer-links a {
  color: var(--muted);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.footer-links a:hover,
.footer-links a:focus-visible {
  color: var(--ink);
}

/* Na širokej obrazovke copyright vľavo a odkazy vpravo; na telefóne by
   to isté `auto` roztrhlo prvý riadok veľkou dierou, tak nech odkazy
   plynú hneď za ním a zalomia sa prirodzene. */
@media (min-width: 761px) {
  .footer-copy { margin-right: auto; }
}

/* Na dotykovom displeji sú odkazy v pätičke inak vysoké len 16 px —
   rovnaký dôvod, prečo má zvyšok ovládania v bloku (pointer: coarse)
   aspoň 36 px. Zvislý padding namiesto väčšieho písma, nech riadok
   opticky ostane doplnkom. */
@media (pointer: coarse) {
  .footer-links a {
    padding: 9px 0;
  }
}

/* ======================================================================
   PRÁVNE STRÁNKY — Podmienky, Ochrana údajov, Kontakt (16.9.2026)
   ----------------------------------------------------------------------
   Samostatné stránky mimo jednostránkovej appky (templates/legal_base.html).
   Zámerne bez sidebaru a bez spodnej lišty menu — je to text na čítanie,
   nie obrazovka na ovládanie; jediná cesta späť je odkaz v hlavičke.

   Šírka stĺpca ~68 znakov: dlhší riadok sa pri súvislom texte číta
   horšie, oko stráca začiatok ďalšieho riadka.
   ====================================================================== */
.legal-body {
  background: var(--bg);
  color: var(--ink);
  min-height: 100vh;
}

.legal-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  max-width: 760px;
  margin: 0 auto;
  padding: 20px 20px 0;
}

/* .topbar-logo má v základe 176px (veľká hlavička pôvodného rozloženia);
   tu treba veľkosť ako v kompaktnej hlavičke appky.

   ZÁMERNE len `height` — `display: block` tu bolo a zobrazovalo OBE
   verzie loga naraz: prebilo `.topbar-logo-dark { display: none; }`
   (nižšia váha selektora), ktoré prepína svetlú a tmavú verziu. */
.legal-topbar .topbar-logo {
  height: 40px;
}

.legal-back {
  color: var(--muted);
  text-decoration: none;
  font-size: 14px;
  font-weight: 600;
  padding: 8px 0;
}

.legal-back:hover,
.legal-back:focus-visible {
  color: var(--ink);
}

.legal-page {
  max-width: 680px;
  margin: 0 auto;
  padding: 28px 20px 8px;
}

.legal-eyebrow {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--primary);
}

.legal-page h1 {
  font-size: 30px;
  line-height: 1.2;
  text-wrap: balance;
  margin: 0;
}

.legal-updated {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--muted);
}

.legal-lead {
  margin: 22px 0 0;
  font-size: 16px;
  line-height: 1.65;
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}

.legal-page h2 {
  font-size: 17px;
  line-height: 1.35;
  margin: 30px 0 0;
}

.legal-page p {
  margin: 10px 0 0;
  font-size: 14.5px;
  line-height: 1.7;
  color: var(--ink);
}

.legal-page a {
  color: var(--primary-dark);
}

/* Zoznam odkazov na chybovej stránke (404/500) — jediné miesto, kde
   právnu škrupinu používa aj nie-právna stránka. */
.legal-list {
  margin: 10px 0 0;
  padding-left: 20px;
  font-size: 14.5px;
  line-height: 1.7;
}

.legal-list li { margin-top: 6px; }

/* Odsek, ktorý má čitateľ naozaj nájsť — výzva držiteľom práv, aby sa
   ozvali. Odlíšený linkou, nie ďalšou kartou: kariet je na stránke dosť. */
.legal-note {
  border-left: 3px solid var(--primary);
  padding-left: 14px;
}

.legal-ref {
  color: var(--muted);
  white-space: nowrap;
}

.legal-page .legal-contact {
  font-size: 18px;
  font-weight: 600;
}

@media (max-width: 760px) {
  .legal-page h1 { font-size: 25px; }
  .legal-page { padding-top: 20px; }
}

/* ======================================================================
   SEO STRÁNKY OBCHODOV A KATEGÓRIÍ (24.9.2026) — /kaufland, /tesco,
   /billa, /lidl, /akcie/<kategoria>. Zdieľajú škrupinu s .legal-page
   (rovnaká šírka stĺpca, rovnaká hlavička), tento blok pridáva len
   zoznam akcií a prekliky medzi stránkami navyše.
   ====================================================================== */
.seo-page { max-width: 760px; }

.seo-crosslinks {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  margin: 18px 0 0;
}

.seo-crosslinks a {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--muted);
  text-decoration: none;
  padding: 4px 0;
  border-bottom: 2px solid transparent;
}

.seo-crosslinks a:hover,
.seo-crosslinks a:focus-visible {
  color: var(--ink);
}

.seo-crosslinks a.active {
  color: var(--primary-dark);
  border-bottom-color: var(--primary);
}

.seo-count {
  margin: 18px 0 0;
  font-size: 13px;
  color: var(--muted);
}

.seo-deal-list {
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
  border-top: 1px solid var(--border);
}

.seo-deal-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}

.seo-deal-main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.seo-deal-name {
  font-size: 14.5px;
  font-weight: 600;
  color: var(--ink);
}

.seo-deal-meta {
  font-size: 12.5px;
  color: var(--muted);
}

.seo-deal-price {
  display: flex;
  align-items: baseline;
  gap: 8px;
  flex-shrink: 0;
  white-space: nowrap;
}

.seo-deal-old {
  font-size: 12.5px;
  color: var(--muted);
  text-decoration: line-through;
}

.seo-deal-new {
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
}

.seo-deal-pct {
  font-size: 12px;
  font-weight: 700;
  color: var(--accent);
  background: var(--accent-soft);
  border-radius: 999px;
  padding: 2px 8px;
}

.seo-cta {
  margin: 22px 0 0;
  padding: 16px 18px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  font-size: 14.5px;
  line-height: 1.6;
}

.seo-cta a {
  font-weight: 700;
  color: var(--primary-dark);
}

@media (max-width: 760px) {
  .seo-deal-item { flex-wrap: wrap; }
}

/* ======================================================================
   KATALÓG RECEPTOV — obrazovka "Recepty"
   ======================================================================
   5.9.2026, prepísané na žiadosť: "sprav to krajšie, prehľadnejšie,
   modernejšie... chcem, aby to vizuálne nadviazalo na úvodný frontpage".

   Predošlá verzia rástla po častiach a používala natvrdo zapísané farby
   mimo palety (#16a34a, #2563eb) — preto pôsobila ako cudzí ostrovček.
   Táto sekcia preto:
     - preberá PODPIS frontpage: bodkovaná textúra + diagonálny prechod,
       --radius-lg, jemný rám (rovnaký recept ako .category-showcase),
     - používa VÝHRADNE tokeny palety, takže tmavý režim funguje sám,
     - "sledované" je ZLATÉ (--gold): zelená je v celej appke výzva
       "pridaj si to", zlatá znamená "toto už máš" a je z tej istej
       rodiny farieb (predtým tam bola cudzia modrá).
   ====================================================================== */

.recipe-catalog {
  position: relative;
  overflow: hidden;
  margin-top: 28px;
  padding: 22px 22px 20px;
  background-image: var(--dots-quiet), var(--wash-quiet);
  background-size: 22px 22px, 100% 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
.recipe-catalog .dashboard-section-title { font-size: 23px; margin-bottom: 4px; }
.recipe-catalog > .hint { margin: 0 0 16px; max-width: 62ch; line-height: 1.5; }

.recipe-catalog-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}
.recipe-catalog-search { flex: 1 1 18rem; min-width: 0; }
.recipe-catalog-search input {
  width: 100%;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-alt);
  color: var(--ink);
  font-family: inherit;
  font-size: 15.5px;
  box-shadow: var(--shadow-xs);
}
.recipe-catalog-search input::placeholder { color: var(--muted); }
.recipe-catalog-search input:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}

/* Obchody a zoradenie tvoria JEDEN panel filtrov, nie tri nesúvisiace pásy. */
/* 21.9.2026 na žiadosť ("prehľadnejšie") — predtým JEDEN flex-wrap riadok,
   takže tri odlišné skupiny (typ jedla/obchod/zoradenie) plávali za sebou
   bez viditeľnej hranice, rozdelené len tým, kde náhodou padol zalom
   riadku. Teraz explicitný stĺpec, každá skupina vlastný riadok s
   jemnou deliacou čiarou nad sebou (okrem prvej) — rovnaký princíp ako
   .sidebar pod topbarom ("tenká spodná čiara ako vizuálne oddelenie"). */
.recipe-catalog-filters {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px;
  margin-bottom: 14px;
  background: color-mix(in srgb, var(--surface-alt) 78%, transparent);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
}
.recipe-catalog-filter-group {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}
.recipe-catalog-filter-group:first-child { padding-top: 0; border-top: none; }
/* 13.9.2026 — VŠETKY-VEĽKÝMI + rozostrené písmená čítalo ako
   formulárový štítok ("JEDEN OBCHOD:"), presne dojem "manuálu", ktorý
   používateľ nahlásil. Bežná veľkosť písmen + o kúsok tmavšia farba —
   ostáva to popisok, len už nekričí ako nadpis sekcie formulára. */
.recipe-catalog-stores-label {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  margin-right: 2px;
}

/* Dlaždice obchodov — zmenšená obdoba .category-card z frontpage. */
.catalog-store-tiles { display: flex; flex-wrap: wrap; gap: 8px; }
.catalog-store-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  min-width: 74px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-alt);
  color: inherit;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.catalog-store-tile img { height: 20px; width: auto; max-width: 58px; object-fit: contain; }
.catalog-store-all { font-size: 22px; line-height: 20px; }
.catalog-store-name { font-size: 12px; font-weight: 600; color: var(--muted); }
.catalog-store-tile:hover {
  transform: translateY(-2px);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-sm);
}
.catalog-store-tile.is-active {
  border-color: var(--primary);
  background: var(--primary-soft);
  box-shadow: var(--shadow-xs);
}
.catalog-store-tile.is-active .catalog-store-name { color: var(--primary-dark); }

.catalog-sort-btn, .catalog-diet-btn {
  padding: 5px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-alt);
  color: var(--muted);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
.catalog-sort-btn:hover, .catalog-diet-btn:hover { color: var(--ink); border-color: var(--border-strong); }
.catalog-sort-btn.is-active { background: var(--primary); border-color: var(--primary); color: #fff; }
/* 13.9.2026 — diétne tlačidlá dostali ikonu (viď index.html), na rozdiel
   od čisto textového zoradenia potrebujú flex, aby ikona sedela na
   riadku s textom rovnako ako pri .cook-mode-btn. */
.catalog-diet-btn { display: inline-flex; align-items: center; gap: 6px; }
/* "Zrušiť filtre" nie je ďalší filter, tak nevyzerá ako pilulka filtra —
   tichý textový odkaz s krížikom, aby sa nemiešal do skupín nad ním. */
.catalog-reset-btn {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: auto;
  padding: 5px 10px;
  border: none;
  border-radius: 999px;
  background: none;
  color: var(--muted);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.15s ease, background-color 0.15s ease;
}
.catalog-reset-btn:hover { color: var(--danger); background: var(--danger-soft); }
/* 13.9.2026 — diétne filtre sú prepínače (dajú sa kombinovať), nie
   skupina s jedným aktívnym ako zoradenie — vlastná (zelenkavá, nie
   plná --primary) farba aktívneho stavu, aby vizuálne nepôsobili ako
   "vybral si TENTO jeden spôsob zoradenia". */
.catalog-diet-btn.is-active { background: var(--primary-soft); border-color: var(--primary); color: var(--primary-dark); }

.recipe-catalog-summary {
  margin: 0 0 12px;
  font-size: 14px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

/* 21.9.2026 — predtým vlastný flex-column list len pre katalóg (#id
   prebíjalo .match-recipes-list grid vyššie zámerne, kým bol katalóg
   jediné miesto s veľa kartami). Katalóg dostáva TEN ISTÝ grid ako
   zvyšok appky (Obľúbené recepty) — jeden vizuálny jazyk, viď vyššie. */
#recipe-catalog-grid .match-recipe-card { background: var(--surface-alt); box-shadow: var(--shadow-xs); }
#recipe-catalog-grid .match-recipe-card:hover { box-shadow: var(--shadow-sm); }
#recipe-catalog-grid .match-recipe-title { font-size: 18px; }
/* Zdieľaný odznak "N surovín zo zliav" hovorí to isté ako .catalog-badge,
   len menej presne (bez celkového počtu) — v katalógu je zbytočný. */
#recipe-catalog-grid .match-recipe-badge { display: none; }

.catalog-badge,
.catalog-price,
.catalog-saving,
.catalog-steps {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.catalog-badge { background: var(--primary-soft); color: var(--primary-dark); }
.catalog-price { background: color-mix(in srgb, var(--ink) 8%, transparent); color: var(--ink); }
.catalog-saving { background: var(--accent-soft); color: var(--danger); }

/* 11.9.2026 — "postup v appke" vs "postup na zdroji". Zámerne TICHÝ pár
   odznakov (obrys, nie výplň): nesie to informáciu, nie dôležitosť —
   kričať má cena a úspora, toto má len odpovedať na otázku "budem
   musieť klikať preč?" skôr, než človek kartu vôbec otvorí. */
.catalog-steps {
  font-weight: 600;
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--border-strong);
}
.catalog-steps--local { color: var(--primary-dark); box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 45%, transparent); }
.catalog-steps--external { color: var(--muted); }

.recipe-missing li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 14px;
  padding: 7px 0;
  border-bottom: 1px solid color-mix(in srgb, var(--border) 55%, transparent);
}
.recipe-missing li:last-child { border-bottom: 0; }
.missing-ingredient-name { flex: 1 1 12rem; min-width: 0; color: var(--ink); }
.missing-ingredient-none { font-size: 13px; color: var(--muted); font-style: italic; }

.missing-ingredient-suggestion {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 7px;
  margin: 0;
  padding: 4px 6px 4px 11px;
  border-radius: 999px;
  background: var(--primary-soft);
  font-size: 14px;
  color: var(--ink);
  transition: background-color 0.15s ease, box-shadow 0.15s ease;
}
.missing-suggestion-meta { color: var(--muted); white-space: nowrap; }
.missing-suggestion-track-btn {
  background: var(--primary);
  color: #fff;
  border: none;
  padding: 3px 11px;
  border-radius: 999px;
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 700;
  cursor: pointer;
  transition: background-color 0.15s ease;
}
.missing-suggestion-track-btn:hover { background: var(--primary-dark); }

/* SLEDOVANÉ = ZLATÉ. Zelená je v celej appke výzva "pridaj si to", takže
   zelené potvrdenie zelenej výzvy sa nedalo rozoznať (nahlásené 5.9.2026).
   Zlatá je z tej istej palety a znamená "toto už máš". */
.missing-ingredient-suggestion.is-tracked {
  background: var(--gold-soft);
  box-shadow: inset 0 0 0 1.5px var(--gold);
}
.missing-ingredient-suggestion.is-tracked strong { color: var(--gold); }
.missing-suggestion-track-btn.active { background: var(--gold); }
.missing-suggestion-track-btn.active:hover { background: var(--danger); }

.recipe-track-all-btn {
  display: block;
  width: 100%;
  margin: 0 0 14px;
  padding: 10px 14px;
  border: 1.5px solid var(--primary);
  border-radius: var(--radius-md);
  background: var(--surface);
  color: var(--primary-dark);
  font-family: inherit;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.recipe-track-all-btn:hover { background: var(--primary-soft); }
.recipe-track-all-btn.active { background: var(--gold); border-color: var(--gold); color: #fff; }
.recipe-track-all-btn.active:hover { background: var(--danger); border-color: var(--danger); }

.recipe-catalog-pager {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 5px;
  margin-top: 20px;
}
.catalog-page-btn {
  min-width: 34px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
  color: var(--ink);
  font-family: inherit;
  font-size: 14.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.catalog-page-btn:hover:not(:disabled) { border-color: var(--primary); }
.catalog-page-btn.is-active { background: var(--primary); border-color: var(--primary); color: #fff; }
.catalog-page-btn:disabled { opacity: 0.35; cursor: default; }
.catalog-page-gap { padding: 0 2px; color: var(--muted); }

@media (max-width: 720px) {
  .recipe-catalog { padding: 18px 14px 16px; }
  .recipe-catalog-filters { flex-direction: column; align-items: flex-start; gap: 10px; }
  .catalog-store-tile { min-width: 64px; padding: 7px 8px; }
}

/* ======================================================================
   OBĽÚBENÉ — vec, ktorá prežije výmenu letáku (6.9.2026)
   ======================================================================
   Obrazovka má teraz dva stavy na položku: "je v akcii" (bežná karta
   zľavy) a "čaká" (vec nie je v ponuke — ukáže sa zapamätaná cena a
   podobné veci v podobnej cene). Čakajúca položka je zámerne TICHŠIA
   než tá v akcii: používateľ sem chodí kvôli tomu, čo sa dá kúpiť
   teraz, nie kvôli zoznamu toho, čo kúpiť nejde. */

/* 20.9.2026 — na žiadosť "vymysli to nejako aby to dávalo zmysel a bolo
   to oveľa prehľadnejšie... lajknuté produkty tam ostávajú aj s
   obrázkom, a keď skončí zľava, tak sa zafarbia na sivo a ukážu
   alternatívu": predošlá verzia mala DVA úplne odlišné tvary v tom istom
   zozname (plná .deal-card pre "v akcii" vs malý riadok pre "čaká") a
   navyše jeden stĺpec na celú výšku stránky (pôvodný dôvod — vodorovný
   pás náhrad pri čakajúcej položke, viď staršia poznámka — už neplatí,
   odkedy sú náhrady kompaktné .favorite-alt-mini, nie plné karty).
   Teraz je to skutočná MRIEŽKA rovnako veľkých riadkov: každý riadok má
   fotku, meno, cenu/dátum a srdiečko v tom istom rozložení — farebná
   fotka + zelená cena, keď je vec v akcii, sivá fotka + náhrady, keď nie
   je. Jeden vizuálny jazyk, žiadne dve rôzne "izby". */
/* 20.9.2026 na žiadosť "zväčši o 10%" (druhé kolo, po +20% predtým) —
   rozmery nižšie sú znova × 1.1 oproti predošlým hodnotám. */
#favorites-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(352px, 1fr));
  align-items: start;
  gap: 13px;
}
@media (max-width: 680px) {
  #favorites-grid { grid-template-columns: 1fr; }
}

/* 20.9.2026 — na žiadosť "nepáči sa mi, že je to zelené, vyzerá to, že
   sa s tým dá niečo ďalej robiť": zelený rám/pozadie bol omylom PRESNE
   ten istý vizuálny jazyk ako .deal-card.tracked (skutočne "sledované,
   klikni na akciu" stav inde v appke) — položka v akcii tu je len
   INFORMÁCIA, nie akcia, preto obe teraz vyzerajú rovnako neutrálne
   (biela karta), rozdiel nesie už len farba ceny/fotky.
   Hover-priblíženie je rovnaký vzor ako .deal-card:hover pri bežnom
   prezeraní zliav (scale 1.3, z-index nad susedmi) — na žiadosť "nech sa
   to pri nabehnutí zväčší, ako keď prezerám zľavnené produkty". */
.favorite-row {
  position: relative;
  display: flex;
  align-items: center;
  gap: 13px;
  padding: 11px 15px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  min-width: 0;
  transition: box-shadow 0.18s ease, border-color 0.18s ease, transform 0.18s ease;
}
.favorite-row:hover { box-shadow: var(--shadow-md); border-color: var(--border-strong); transform: scale(1.3); z-index: 20; }

/* 14.9.2026 — Obľúbené strážia akcie: čo sa do akcie dostalo od minulej
   návštevy. Farba --accent (oranžová), nie zelená "v akcii" — ide o
   upozornenie na zmenu, nie o bežný stav. Odznak sedí v rohu riadku
   namiesto vlastného riadku navyše — v kompaktnom riadku by ho stĺpcová
   výška nemala kam dať. */
.favorite-row.is-new-sale { border-color: var(--accent); }
.favorite-new-badge {
  position: absolute;
  top: -9px;
  left: 11px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 10px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
}
.fav-news {
  margin: 14px 0 0;
  padding: 10px 14px;
  max-width: 62ch;
  border-radius: var(--radius-md);
  background: var(--accent-soft);
  color: var(--ink);
  font-size: 15px;
  line-height: 1.45;
}
.fav-news strong { color: var(--accent); }
.fav-news:empty { display: none; }
.sidebar-link-favorites.has-sale-news .sidebar-link-meta,
.section-nav-panel .sidebar-link-favorites.has-sale-news .sidebar-link-meta { color: var(--accent); font-weight: 700; }

/* ---- Zdieľané medzi .is-in-sale a .is-waiting (fotka/meno/dátum) ---- */
.favorite-thumb {
  position: relative;
  flex: 0 0 58px;
  width: 58px;
  height: 58px;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  border-radius: var(--radius-sm);
  background: var(--surface-alt);
  color: var(--muted);
}
.favorite-thumb-img { width: 100%; height: 100%; object-fit: cover; }
/* Sivá = appka to práve nevie kúpiť v akcii — tá istá fotka farebne
   "ožije" hneď, ako sa vec vráti do akcie. */
.favorite-row.is-waiting .favorite-thumb-img { filter: grayscale(1); opacity: 0.85; }
.favorite-thumb-badge {
  position: absolute;
  bottom: 0;
  right: 0;
  padding: 1px 4px;
  border-radius: 5px 0 0 0;
  background: var(--danger);
  color: #fff;
  font-size: 11.5px;
  font-weight: 700;
}
.favorite-info {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.favorite-name {
  display: block;
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.3;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.favorite-meta {
  display: block;
  font-size: 13.5px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.favorite-price {
  flex: 0 0 auto;
  font-size: 16.5px;
  font-weight: 700;
  color: var(--primary-dark);
  font-variant-numeric: tabular-nums;
}
/* Srdiečko: .favorite-btn (položka V akcii, má id — rovnaké tlačidlo ako
   na bežnej karte zľavy, tu len zbavené position:absolute) a
   .favorite-remove-btn (položka MIMO akcie, nemá id, odoberá podľa mena)
   zdieľajú tu ten istý vzhľad. */
.favorite-row .favorite-btn,
.favorite-remove-btn {
  position: static;
  flex: 0 0 auto;
  width: auto;
  height: auto;
  border: none;
  background: none;
  padding: 2px;
  font-size: 21px;
  line-height: 1;
  color: var(--accent);
  cursor: pointer;
  transition: color 0.15s ease, transform 0.15s ease;
}
.favorite-row .favorite-btn:hover,
.favorite-remove-btn:hover { color: var(--danger); transform: scale(1.12); background: none; }
.favorite-row .favorite-btn svg,
.favorite-remove-btn svg { width: 1em; height: 1em; fill: currentColor; }

/* ---- Len .is-waiting: náhrady sa ukážu AŽ na hover ----
   20.9.2026 na žiadosť "keď to nie je v zľave, nech mi ten hover ukáže aj
   alternatívy": predtým bol pás náhrad vždy viditeľný vedľa riadku (preto
   musela byť čakajúca položka v mriežke širšia, cez 2 stĺpce) — teraz je
   to "vyskakovacia" karta POD riadkom, v pokoji neviditeľná a mimo toku
   (position:absolute), takže čakajúca položka je v pokoji rovnako úzka
   ako položka v akcii (jeden stĺpec mriežky). Zdieľa z-index s hover
   priblížením riadku vyššie, aby sedela nad susednými riadkami mriežky. */
.favorite-alts {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-md);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.15s ease, transform 0.15s ease, visibility 0.15s;
  pointer-events: none;
  z-index: 21;
}
.favorite-row.is-waiting:hover .favorite-alts {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  pointer-events: auto;
}
.favorite-alts-title {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
/* Náhrady sú krátky vodorovný rad (najviac MAX_ALTERNATIVES = 3, viď
   favorites.py) — sú to návrhy, nie hlavný obsah, tak nemajú naťahovať
   stránku do výšky.
   23.9.2026 na žiadosť "na alternatívach skoro nič nevidím, pri hover nech
   sa zväčší": nadpis je teraz NAD radom (nie vedľa neho — zaberal tretinu
   šírky), dlaždice sú väčšie a dlaždica pod myšou sa zväčší (scale) aj s
   celým názvom. Rad nemá overflow (tri dlaždice sa vždy zmestia), takže
   zväčšená dlaždica sa neorezáva a nie je tu ani posuvník. */
.favorite-alts-row {
  display: flex;
  gap: 8px;
  min-width: 0;
}
.favorite-alt-mini {
  flex: 0 1 88px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 4px 2px 6px;
  border-radius: var(--radius-sm);
  text-align: center;
  cursor: default;
  transform-origin: center 35%;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
}
.favorite-alt-mini:first-child { transform-origin: left 35%; }
.favorite-alt-mini:last-child { transform-origin: right 35%; }
.favorite-alt-mini:hover {
  transform: scale(1.75);
  position: relative;
  z-index: 2;
  background: var(--surface);
  box-shadow: var(--shadow-md);
}
.favorite-alt-mini:hover .favorite-alt-mini-name {
  display: block;
  -webkit-line-clamp: unset;
  overflow: visible;
}
.favorite-alt-mini-img-wrap {
  position: relative;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: var(--surface-alt);
}
.favorite-alt-mini-img { width: 100%; height: 100%; object-fit: cover; }
.favorite-alt-mini-img-wrap svg { width: 28px; height: 28px; margin: 14px; color: var(--muted); }
.favorite-alt-mini-badge {
  position: absolute;
  top: 0;
  right: 0;
  padding: 1px 4px;
  border-radius: 0 0 0 5px;
  background: var(--danger);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.4;
}
.favorite-alt-mini-name {
  font-size: 12.5px;
  line-height: 1.25;
  color: var(--ink);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.favorite-alt-mini-price {
  font-size: 13.5px;
  font-weight: 700;
  color: var(--primary-dark);
}
.favorite-alts-none {
  margin: 0;
  font-size: 14.5px;
  color: var(--muted);
  font-style: italic;
}

@media (max-width: 520px) {
  /* .favorite-alts je teraz vyskakovacia karta (position:absolute), nie
     riadkový sused — na dotykových displejoch bez spoľahlivého :hover ju
     appka radšej ukáže vždy, nech sa dá k náhradám dostať aj tam. */
  .favorite-row.is-waiting { flex-wrap: wrap; }
  .favorite-alts {
    position: static;
    opacity: 1;
    visibility: visible;
    transform: none;
    pointer-events: auto;
    flex: 1 1 100%;
    margin-top: 8px;
    box-shadow: none;
    border-color: var(--border);
  }
}

/* ======================================================================
   HISTÓRIA CIEN na karte zľavy (6.9.2026)
   ======================================================================
   Jediné číslo v appke, ktoré nepochádza z letáku, ale z toho, čo appka
   sama videla. Preto má vlastný, tichý vzhľad — nesúperí s veľkým
   percentom zľavy v rohu, len ho dopĺňa o kontext, ktorý obchod
   neposkytne. */

.price-history {
  display: inline-flex;
  /* Karta je flex stĺpec — bez tohto by sa odznak roztiahol na jej celú
     šírku a pôsobil ako pruh, nie ako štítok. */
  align-self: flex-start;
  align-items: center;
  gap: 4px;
  margin: 4px 0 2px;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  cursor: help;
}
/* Najlepšia videná cena je jediná dobrá správa, tak dostane zlatú —
   rovnaký token ako "sledované", teda "toto je pre teba dôležité". */
.price-history.is-best { background: var(--gold-soft); color: var(--gold); }
/* "Bolo lacnejšie" je varovanie, nie chyba — jemná, nie krvavá. */
.price-history.was-cheaper {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  color: var(--muted);
}

/* 12.9.2026 — porovnanie ceny naprieč obchodmi (cross_store.py). Rovnaká
   tvaroslovná rodina ako .price-history (štítok pod názvom), aby karta
   nemala tri rôzne jazyky odznakov. */
.price-compare {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 4px;
  margin: 0 0 2px;
  padding: 3px 9px;
  /* Menej zaoblené než .price-history pill — na úzkej karte sa text môže
     zalomiť na dva riadky a pill s 999px by potom vyzeral rozbito. */
  border-radius: 9px;
  max-width: 100%;
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.3;
  font-variant-numeric: tabular-nums;
  cursor: help;
}
.price-compare .inline-icon { width: 14px; height: 14px; flex: 0 0 auto; }
/* Najlacnejšie = dobrá správa, tichá zelená (rovnaký token ako "v akcii"
   odznaky). Nie krikľavá — je to potvrdenie, nie hlavný obsah karty. */
.price-compare.is-cheapest { background: var(--primary-soft); color: var(--primary-dark); }
/* Lacnejšie inde = tip kam ísť. Jemný jantár — stojí za pozornosť, ale
   nie je to chyba tohto produktu. */
.price-compare.cheaper-elsewhere {
  background: var(--accent-soft);
  color: color-mix(in srgb, var(--danger) 80%, var(--ink));
}


/* ======================================================================
   NAVIGÁCIA SEKCIÍ — vlastný panel pod hlavičkou (7.9.2026)
   ======================================================================
   Na žiadosť: *"spravil by som pod to ďalšiu takú zaoblenú tabuľku a
   dáme to tam... nepáči sa mi ani dizajn tých kategórií, malo by to byť
   trochu viac userfriendly, viac moderne."*

   Predtým to bol rad 28px ikoniek vtesnaný pod logo v hlavičke, kde
   popisky boli schované za hover — na dotykovom displeji sa teda
   neukázali nikdy. Vo vlastnom paneli má navigácia celú šírku layoutu,
   takže z položiek môžu byť skutočné karty: ikona v mäkkom kruhu, názov
   a pod ním živé číslo.

   Panel má rovnaký rodokmeň ako ostatné plochy appky (tichá textúra,
   --radius-lg, jemný rám), aby nepôsobil ako cudzí prvok. */
.section-nav-panel {
  max-width: 1180px;
  margin: 0 auto 4px;
  padding: 10px 12px;
  background-image: var(--dots-quiet), var(--wash-quiet);
  background-size: 22px 22px, 100% 100%;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
}
/* Vnútorný okraj kopíruje .layout (24px), aby karty lícovali s obsahom
   pod panelom. */
@media (min-width: 760px) {
  .section-nav-panel { padding: 12px 24px; }
}

.section-nav-panel .sidebar-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  justify-content: flex-start;
  overflow: visible;
}

.section-nav-panel .sidebar-link {
  flex: 1 1 150px;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 11px;
  min-width: 0;
  padding: 11px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  /* Rovnaké jemne zelenkavé pozadie ako dlaždice obchodov a kategórií
     (--card-face) — na žiadosť, aby navigácia nepôsobila ako cudzí prvok
     s vlastnou farbou. */
  background: var(--card-face);
  box-shadow: var(--shadow-xs);
  text-align: left;
  transition: transform 0.15s ease, box-shadow 0.15s ease,
              border-color 0.15s ease, background-color 0.15s ease;
}
.section-nav-panel .sidebar-link:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: var(--border-strong);
}
.section-nav-panel .sidebar-link:active { transform: translateY(0); }

/* Ikona v mäkkom kruhu — rovnaký jazyk ako dlaždice kategórií na
   úvodnej obrazovke, takže navigácia pôsobí ako súčasť appky, nie ako
   lišta odniekiaľ inde. */
.section-nav-panel .sidebar-link-icon {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 5%, transparent);
  color: var(--muted);
  transition: background-color 0.15s ease, color 0.15s ease;
}
.section-nav-panel .sidebar-link-icon svg { width: 20px; height: 20px; }
.section-nav-panel .sidebar-link-label { font-size: 16px; font-weight: 600; color: var(--ink); }
.section-nav-panel .sidebar-link-meta { font-size: 12.5px; margin-top: 1px; }

/* Aktívna sekcia: plný zelený kruh a zafarbená karta — na prvý pohľad
   vidno, kde práve si. */
.section-nav-panel .sidebar-link.active {
  background: var(--primary-soft);
  border-color: color-mix(in srgb, var(--primary) 45%, transparent);
}
.section-nav-panel .sidebar-link.active .sidebar-link-icon {
  background: var(--primary);
  color: #fff;
}
.section-nav-panel .sidebar-link.active .sidebar-link-label { color: var(--primary-dark); }
.section-nav-panel .sidebar-link.active .sidebar-link-meta { color: var(--primary-dark); }

/* Obľúbené: keď niečo máš, srdiečko zosčervenie aj bez čítania čísla. */
.section-nav-panel .sidebar-link-favorites.has-favorites .sidebar-link-icon {
  background: var(--accent-soft);
  color: var(--accent);
}
.section-nav-panel .sidebar-link-favorites.has-favorites .sidebar-link-icon svg { fill: var(--accent); }

/* Na úzkom displeji dve karty vedľa seba namiesto štyroch — text
   zostane čitateľný a nič sa neodreže. */
@media (max-width: 620px) {
  .section-nav-panel .sidebar-link { flex: 1 1 calc(50% - 4px); padding: 10px 12px; gap: 9px; }
  .section-nav-panel .sidebar-link-icon { width: 34px; height: 34px; }
  .section-nav-panel .sidebar-link-label { font-size: 15px; }
}


/* ======================================================================
   ÚVOD SEKCIE — "screen hero" (7.9.2026)
   ======================================================================
   Na žiadosť: *"potrebujem vytvoriť podobný dizajn ako je na front page.
   Keď kliknem napríklad na kategóriu Obľúbené, aby som mal pekný front
   end s tým, že tam bude vysvetlené, načo slúži táto stránka."*

   Predtým mala každá sekcia len nadpis a jeden riadok textu nad veľkým
   prázdnom — pri prázdnych Obľúbených to pôsobilo ako nedokončená
   stránka. Teraz má každá (Zľavy, Recepty, Obľúbené) vlastný úvod, ktorý
   POVIE, načo tá obrazovka je a čo z nej má používateľ.

   Podpis je zhodný s .dashboard-hero na úvodnej stránke — plná bodkovaná
   textúra + diagonálny prechod, --radius-lg, --shadow-md — aby sekcia
   pôsobila ako pokračovanie úvodnej stránky, nie ako iná appka. */
.screen-hero {
  display: flex;
  flex-wrap: wrap;
  gap: 28px;
  align-items: flex-start;
  padding: 26px 28px;
  background-image: var(--dots), var(--wash);
  background-size: 22px 22px, 100% 100%;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md), inset 0 1px 0 var(--edge-hi);
}
.screen-hero-head { flex: 1 1 260px; max-width: 400px; min-width: 0; }
/* 15.9.2026 — Zľavy majú v úvode už len nadpis a vetu (bez bodov a panela). */
#screen-select .screen-hero { padding-block: 20px; }
#screen-select .screen-hero-head { max-width: 640px; }

/* 18.9.2026 na žiadosť "chcem vsade tu istu velkost pisma ako tu"
   (ukázané na hlavnom hero Domov) — rovnaká sadzba AJ VEĽKOSŤ ako
   .dashboard-hero-title/-dek, nie o stupeň menšia. Predtým zámerne
   menšia ("je to podnadpis sekcie, nie titulka celej appky"), teraz
   zjednotené na žiadosť používateľa — platí pre všetky obrazovky s
   .screen-hero (Zľavy/Filtre/Obľúbené/Plán). */
.screen-hero-title {
  font-family: 'Plus Jakarta Sans', Georgia, serif;
  /* 7.9.2026, na žiadosť *"použi taký istý font ako si použil hore"*:
     je to tá istá Fraunces, ale má optickú os (opsz 9..144) a pri
     `optical-sizing: auto` ju prehlíiadač viazše na font-size — pri 28px
     kreslí jemnejší, kontrastnejší rez než hlavný nadpis pri 37px, takže to
     vyzerá ako iný font. Os je preto pripnutá na displejovú hodnotu:
     rovnaký rez ako .dashboard-hero-title, len menší. */
  font-optical-sizing: none;
  font-variation-settings: 'opsz' 40, 'wght' 700;
  font-weight: 700;
  font-size: clamp(34.5px, 4.6vw, 50.5px);
  line-height: 1.05;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0 0 16px;
}
.screen-hero-dek {
  margin: 0;
  font-size: 20.5px;
  line-height: 1.55;
  color: var(--muted);
  max-width: 46ch;
}
.screen-hero-dek strong { color: var(--ink); font-weight: 600; }
.screen-hero-actions { margin-top: 16px; }

/* 18.9.2026 — hlavička "Zľavy" je jediná zo .screen-hero obrazoviek s
   obrázkom (Filtre/Obľúbené/Plán ostávajú čisto textové), preto je toto
   scoped na #screen-select, nie zmena zdieľanej .screen-hero triedy.
   --zlavy-img-max/x/y namiesto pevnej šírky — na žiadosť "pridaj
   moznost upravit velkost a poziciu toho obrazku" (?hero_edit=1, cieľ
   "zlavy" v hero-editor.js/app.py), rovnaký vzor ako ostatné editovateľné
   obrázky (--art-w = šírka, x/y = translate). */
:root { --zlavy-img-max: 600px; --zlavy-img-x: 7px; --zlavy-img-y: -4px; }
#screen-select .screen-hero-head { max-width: 420px; }
.zlavy-hero-art { flex: 0 0 auto; width: var(--zlavy-img-max); align-self: center; }
.zlavy-hero-img {
  display: block;
  width: 100%;
  height: auto;
  transform: translate(var(--zlavy-img-x), var(--zlavy-img-y));
}
@media (max-width: 640px) {
  .zlavy-hero-art { display: none; }
}

/* Živá ukážka 3 zliav hneď pod hlavičkou (rovnaký princíp ako sekcia
   "Recepty" na Domov — najprv dôkaz hodnoty, potom nástroj na
   filtrovanie). Karty zdieľajú .top-savings-scroll/.top-savings-card,
   žiadny nový komponent netreba.
   18.9.2026 — SCHOVANÉ na žiadosť "zatial sa mi to tam nehodi, potom je
   to tam take prekombinovane... nechcem aby bol uzivatel prestimulovany
   milion informaciami": appka to nemaže (možno sa vráti), len skryje —
   loadZlavyTeaser() aj HTML ostávajú funkčné, len bez viditeľného cieľa. */
.zlavy-teaser { margin-top: 20px; }
.zlavy-teaser .top-savings-scroll { overflow-x: visible; flex-wrap: wrap; }

/* Tri body "čo z toho mám". Zámerne zoznam, nie odstavec — používateľ to
   preletí očami za dve sekundy. */
.screen-hero-points {
  flex: 1 1 280px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
  min-width: 0;
}
.screen-hero-point {
  display: flex;
  align-items: flex-start;
  gap: 11px;
  padding: 11px 13px;
  background: var(--card-face);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-xs);
}
.screen-hero-point-icon {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--ink) 5%, transparent);
  font-size: 17px;
  line-height: 1;
}
.screen-hero-point-text { min-width: 0; font-size: 14.5px; line-height: 1.45; color: var(--muted); }
.screen-hero-point-text strong {
  display: block;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  margin-bottom: 1px;
}

@media (max-width: 720px) {
  .screen-hero { padding: 20px 16px; gap: 18px; }
  .screen-hero-point { padding: 9px 11px; }
  .screen-hero-point-icon { width: 26px; height: 26px; font-size: 15px; }
}

/* --- Pracovný panel v hero sekcie -------------------------------------
   7.9.2026, na žiadosť: *"Potrebujem to spraviť tak interaktívne ako je tá
   hlavná page na úvodnej stránke. Vyzerá to proste dobre."*

   Úvodná stránka má hero z troch stĺpcov: text — grafika — WIDGET, ktorý
   naozaj niečo robí (.dashboard-hero-budget). Sekcie mali dovtedy len text
   + tri body, teda čítanie bez konania. Tretí stĺpec je preto ten istý vzor:
   ovládanie toho, čo je na obrazovke pod ním.

   18.9.2026 — na žiadosť "zluc to do jednej kategorie, aby to nevyzeralo
   takto oddelene... normalny, pekny vizual" (screenshot Receptov: biela
   zaoblená karta s tieňom plávajúca na farebnom pozadí .screen-hero
   pôsobila ako "dve krabice", nie jeden celok). Panel dovtedy mal VLASTNÉ
   pozadie/rám/tieň (--surface-alt karta v karte) — odstránené, panel je
   teraz len obsahová zóna v tej istej ploche ako text vľavo. Rozlíšenie
   "tu sa klikne" od "tu sa číta" (pôvodný zámer nižšie) preberá farebné
   tlačidlo (.screen-hero-panel-btn) a zvýraznené číslo samé — netreba naň
   celý nested card. Zdieľané s Obľúbené aj Plán, overené naživo na
   všetkých troch. */
.screen-hero-panel {
  flex: 0 0 296px;
  max-width: 296px;
  min-width: 0;
  align-self: flex-start;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
/* O stupeň menší než .screen-hero-title vľavo — panel je nástroj vedľa
   nadpisu, nie druhý nadpis. */
.screen-hero-panel-title {
  font-family: 'Plus Jakarta Sans', Georgia, serif;
  /* 7.9.2026, na žiadosť *"použi taký istý font ako si použil hore"*:
     je to tá istá Fraunces, ale má optickú os (opsz 9..144) a pri
     `optical-sizing: auto` ju prehlíiadač viazše na font-size — pri 28px
     kreslí jemnejší, kontrastnejší rez než hlavný nadpis pri 37px, takže to
     vyzerá ako iný font. Os je preto pripnutá na displejovú hodnotu:
     rovnaký rez ako .dashboard-hero-title, len menší. */
  font-optical-sizing: none;
  font-variation-settings: 'opsz' 40, 'wght' 700;
  font-weight: 700;
  font-size: clamp(22px, 2.3vw, 27.5px);
  line-height: 1.06;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0;
}
.screen-hero-panel-dek {
  margin: -4px 0 0;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--muted);
}
.screen-hero-panel-btn {
  width: 100%;
  justify-content: center;
  margin-top: auto;
}
.screen-hero-panel-btn-count { font-variant-numeric: tabular-nums; opacity: 0.75; }

/* 14.9.2026 — hero panel Receptov prestal duplikovať filtre (viď
   index.html) a ukazuje ŽIVÝ výsledok toho, čo je nastavené dole.
   Číslo je hlavný hrdina panela, preto je veľké a v akcentovej farbe. */
.hero-recepty-stat { display: flex; align-items: baseline; gap: 8px; margin-top: 2px; }
.hero-recepty-stat-num {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-weight: 800;
  font-size: 40px;
  line-height: 1;
  color: var(--primary-dark);
  font-variant-numeric: tabular-nums;
}
.hero-recepty-stat-unit { font-size: 15px; font-weight: 600; color: var(--muted); }
.hero-recepty-active {
  margin: -6px 0 0;
  font-size: 13.5px;
  line-height: 1.45;
  color: var(--muted);
}
.hero-recepty-random-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  width: 100%;
  padding: 8px 14px;
  border: 1px dashed var(--border-strong);
  border-radius: 999px;
  background: none;
  color: var(--muted);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background-color 0.15s ease;
}
.hero-recepty-random-btn:hover:not(:disabled) {
  color: var(--primary-dark);
  border-color: var(--primary);
  background: var(--primary-soft);
}
.hero-recepty-random-btn:disabled { opacity: 0.45; cursor: default; }

/* Vylosovanú kartu treba na sekundu ukázať prstom — inak sa po
   preskrolovaní nedá rozoznať od ostatných jedenástich. */
.match-recipe-card.is-surprise {
  animation: surprise-pulse 1.8s ease-out;
}
@keyframes surprise-pulse {
  0%, 100% { box-shadow: var(--shadow-xs); }
  15%, 60% { box-shadow: 0 0 0 3px var(--primary-soft), var(--shadow-sm); }
}
@media (prefers-reduced-motion: reduce) {
  .match-recipe-card.is-surprise { animation: none; box-shadow: 0 0 0 3px var(--primary-soft); }
}
.screen-hero-panel-stat {
  margin: 0;
  font-size: 14px;
  line-height: 1.45;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.screen-hero-panel-stat strong { color: var(--ink); font-weight: 600; }

/* Vyhľadávanie — rovnaká pilulka ako .dashboard-hero-budget-input-wrap na
   úvodnej stránke, len s ikonou namiesto meny. */
.screen-hero-search-wrap {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 7px 13px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.screen-hero-search-wrap:focus-within { border-color: var(--primary); box-shadow: 0 0 0 4px var(--primary-soft); }
.screen-hero-search-icon { font-size: 14px; line-height: 1; opacity: 0.65; }
.screen-hero-search-wrap input {
  flex: 1 1 auto;
  min-width: 0;
  border: none;
  background: none;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 15px;
  color: var(--ink);
}
.screen-hero-search-wrap input:focus { outline: none; }

/* Dlaždice obchodov (Recepty) — .catalog-store-tile je nižšia karta, sem
   sa zmestí päť v dvoch riadkoch bez zmenšovania. */
.screen-hero-store-chips.catalog-store-tiles {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.screen-hero-store-chips .catalog-store-tile { flex: 0 0 auto; }

/* Živé čísla nad zoznamom obľúbených. */
.screen-hero-stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}
.screen-hero-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 9px 4px;
  background: var(--card-face);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  text-align: center;
}
.screen-hero-stat-num {
  font-family: 'Plus Jakarta Sans', Georgia, serif;
  font-weight: 700;
  font-size: 22px;
  line-height: 1;
  color: var(--primary);
  font-variant-numeric: tabular-nums;
}
.screen-hero-stat-label { font-size: 12px; line-height: 1.2; color: var(--muted); }

.screen-hero-switch {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 11px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  font-size: 14.5px;
  line-height: 1.35;
  color: var(--ink);
  cursor: pointer;
}
.screen-hero-switch input { accent-color: var(--primary); flex: 0 0 auto; cursor: pointer; }
.screen-hero-switch.is-disabled { opacity: 0.5; cursor: not-allowed; }
.screen-hero-switch.is-disabled input { cursor: not-allowed; }

/* Pod 1050px sa panel prestane vmestiť ako tretí stĺpec vedľa textu aj
   bodov — dostane celú šírku a ostane pod nimi (rovnaké správanie ako
   .dashboard-hero-budget na úvodnej stránke pod 1170px). */
@media (max-width: 1050px) {
  .screen-hero-panel { flex: 1 1 100%; max-width: 100%; }
  .screen-hero-panel-btn { margin-top: 4px; }
}

/* --weekly-title-scale/x/y — piaty cieľ živého editora (?hero_edit=1,
   blokový typ ako riadok akciových produktov): posun a mierka nadpisu
   karty. transform nemení tok stránky, takže pri väčšej mierke sa nadpis
   môže priblížiť k textu pod sebou — to je vlastnosť, nie chyba: ide o
   nástroj na doladenie, nie o responzívne pravidlo.
   10.9.2026 — pravidlo bolo na VŠEOBECNEJ triede .feature-title, takže
   ladenie tohto jedného nadpisu posúvalo/škálovalo AJ "Kde nakupuješ" aj
   "Najväčšie zľavy dňa" naraz (obe tiež .feature-title). Zúžené na
   konkrétne ID nadpisu, ktoré editor cieli (#weekly-panel-title, viď
   elSelector v hero-editor.js). */
:root { --weekly-title-scale: 1.0; --weekly-title-x: 0px; --weekly-title-y: 0px; }
#weekly-panel-title {
  transform: translate(var(--weekly-title-x), var(--weekly-title-y)) scale(var(--weekly-title-scale));
  transform-origin: left center;
}

/* --store-row-scale/x/y — šiesty cieľ živého editora (10.9.2026, na
   žiadosť "vyrob mi v edit page moznost aby som vedel s nimi hybat a
   upravit aj velkost" pri dlaždiciach "Kde nakupuješ").
   10.9.2026 — PÔVODNE `transform: scale()` (rovnaký vzor ako
   #weekly-panel-title/akciové produkty vyššie), ale transform je čisto
   vizuálny — nemení skutočný layout box, takže zväčšené logá vizuálne
   PRESAHOVALI cez pozadie vlastnej karty aj cez okraj panelu (nahlásené:
   "ked budem upravovat velkost, potrebujem aby sa zvacsovala aj tá
   background tabulka pod tym... vytrca z tabulky"). Namiesto scale() sa
   --store-row-scale teraz násobí do SKUTOČNEJ šírky/výšky karty (nižšie,
   .store-card) — reálny reflow, takže pozadie/rám/zaoblenie karty rastie
   spolu s logom, nie len logo samotné. Ľavý textový stĺpec (flex:1 1
   auto, môže sa zmenšiť) uvoľní miesto automaticky. translate zostáva
   cez transform (pozícia nemení layout, len posun).
   10.9.2026 — --store-row-x/-y RESETOVANÉ na 0 (boli -48px/2px):
   používateľ si ich doladil, keď mriežka sedela VEDĽA textu v dvoch
   stĺpcoch (posun kompenzoval to súradenie). Po zlúčení do panelu
   "Nastav si hľadanie" je mriežka vlastná zvislá podsekcia bez
   susedného textového stĺpca — rovnaký posun tam už spôsoboval
   orezanie/pretŕčanie mimo panelu (najviac vidno na mobile). --store-
   row-scale (veľkosť) ostáva nezmenené, doladiť pozíciu odznova ide
   cez ten istý živý editor (?hero_edit=1), ak bude treba.
   10.9.2026 — --store-row-x/-y ZNOVA RESETOVANÉ na 0 (boli 292px/-29px):
   používateľ si cez editor doladil posun "od oka" tak, aby mriežka
   vyzerala vycentrovaná ("nastavil som si to na stred") — nahradené
   skutočným centrovaním (.filter-panel-body/.filter-subsection teraz
   align-items:center, viď vyššie), ktoré funguje na akejkoľvek šírke
   a rovnako centruje aj filtre pod tým. Ručný pixelový posun by sa s
   týmto sčítal (posun NAVYŠE k už vycentrovanému riadku) a rozbil by
   zarovnanie namiesto opravy. --store-row-scale zvýšené o 20 % (1.75 →
   2.1) na žiadosť "potrebujem aj tie obchody zvacsit, aspon o 20%". */
:root { --store-row-scale: 0.4; --store-row-x: 0px; --store-row-y: 0px; }
#dashboard-store-row {
  transform: translate(var(--store-row-x), var(--store-row-y));
}

/* Grafika je svetlá fotografia bez priehľadnosti, takže v tmavom motíve
   svieti ako biely obdĺžnik na tmavej karte. Stlmenie + jemný rám ju
   posadí do plochy namiesto toho, aby z nej vyskakovala. Rovnaký zápis
   ako inde v súbore: media query pre systémový tmavý motív aj [data-theme],
   nech vyhrá aj ručné prepnutie. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .feature-panel-art--bleed {
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 22%, transparent);
  }
  :root:not([data-theme="light"]) .feature-panel-art--bleed img { filter: brightness(0.86) saturate(0.95); }
}
:root[data-theme="dark"] .feature-panel-art--bleed {
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 22%, transparent);
}
:root[data-theme="dark"] .feature-panel-art--bleed img { filter: brightness(0.86) saturate(0.95); }

/* Deň nad názvom jedla v týždennom pláne (8.9.2026). Zámerne tichý
   štítok, nie nadpis — nesie poradie, nie dôležitosť; názov jedla musí
   ostať to prvé, čo oko chytí. */
.weekly-meal-day {
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--primary);
  margin-bottom: 4px;
}

/* ======================================================================
   PANELY ÚVODNEJ OBRAZOVKY (8.9.2026)
   ----------------------------------------------------------------------
   Na žiadosť: *"potrebujem, aby celá tá frontpage ladila k sebe, všetky
   podkategórie. Predstav si, že si hlavný architekt tejto stránky."*

   Predtým mal každý blok vlastné pravidlá: hero tri stĺpce s grafikou,
   rad obchodov holé logá bez jediného slova, karta týždňa vlastnú
   veľkosť nadpisu a obrázok nalepený vedľa textu, "Najväčšie zľavy dňa"
   nadpis VYPÁLENÝ v obrázku. Štyri bloky, štyri jazyky — preto to
   pôsobilo "halabala", nie kvôli jednej škaredej karte.

   Odteraz má KAŽDÝ panel tú istú anatómiu, vždy v tomto poradí:

       štítok (feature-eyebrow)    o čom to je, jedno-dve slová
       nadpis (feature-title)      dvojfarebná Fraunces ako v hero
       veta   (feature-dek)        načo mi to je
       obsah  (feature-panel-body) ovládanie / dlaždice / produkty

   Grafika (ak je) sedí VPRAVO pritlačená na okraj panelu cez celú výšku,
   nie ako obdĺžnik nalepený vedľa textu. Panel má overflow:hidden, takže
   obrázok sa oreže rámom a nikdy nerozbije šírku stránky.
   ====================================================================== */
.feature-panel {
  position: relative;
  overflow: hidden;
  margin-top: 12px;
  padding: 26px 30px;
  background-image: var(--dots-quiet), var(--wash-quiet);
  background-size: 22px 22px, 100% 100%;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm), inset 0 1px 0 var(--edge-hi);
}

/* Štítok. Ten istý prvok začína aj hlavný hero, takže sa systém ohlási
   hneď navrchu stránky a nevyzerá ako pravidlo vymyslené až v polovici. */
.feature-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 12px;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

/* O stupeň menší než hlavný nadpis stránky — panel je kapitola, nie
   titulka. Pripnutá optická os, aby to bol ten istý rez ako v hero
   (viď blok o Fraunces vyššie). */
.feature-title {
  font-family: 'Plus Jakarta Sans', Georgia, serif;
  font-optical-sizing: none;
  font-variation-settings: 'opsz' 40, 'wght' 700;
  font-weight: 700;
  font-size: clamp(25.5px, 2.88vw, 33.5px);
  line-height: 1.07;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0 0 10px;
}
/* 22.9.2026 na žiadosť — zväčšené z 15.5px na 20.5px, nech sedí s
   .dashboard-hero-dek (jediný ozajstný rozdiel v celej appke medzi
   "sprievodný text pod nadpisom" na rôznych miestach). */
.feature-dek {
  margin: 0;
  font-size: 20.5px;
  line-height: 1.55;
  color: var(--muted);
  max-width: 46ch;
}
.feature-dek strong { color: var(--ink); font-weight: 600; }
.feature-panel-head { position: relative; z-index: 1; }
.feature-panel-body { position: relative; z-index: 1; margin-top: 18px; }

/* Panel s grafikou: text a obsah dostanú ľavú polovicu, grafika pravú.
   Percento (nie pevné px), nech sa pomer drží pri každej šírke okna. */
/* Šírka textu sa odvodzuje OD ŠÍRKY GRAFIKY, nie pevným percentom —
   inak sa pás produktov v paneli "Najväčšie zľavy dňa" zalomil do dvoch
   radov (612 px na tri 200px karty nestačilo) a panel narástol na 697 px.
   Takto stačí zmeniť --art-w (aj z editora) a text sa prispôsobí sám. */
.feature-panel--art { --art-w: 40%; }
.feature-panel--planner { --art-w: var(--weekly-img-max); }
.feature-panel--savings { --art-w: var(--top-savings-img-max); }
.feature-panel--recepty { --art-w: var(--recepty-img-max); }
.feature-panel--art > .feature-panel-head,
.feature-panel--art > .feature-panel-body { max-width: calc(100% - var(--art-w) - 26px); }

/* 21.9.2026 na žiadosť ("krizuje to vrch tabulky") — zväčšený medailón
   pri hoveri (.top-savings-card:hover .top-savings-thumb-wrap vyššie)
   rástol o desiatky pixelov nahor a narážal na orezanie zdedené z
   .feature-panel (overflow:hidden — kvôli zaobleným rohom/textúre).
   Práve TENTO panel potrebuje medailón vidieť CELÝ aj mimo svojich
   hraníc; .feature-panel-art (ilustrácia vpravo) má teraz vlastné
   orezanie (viď vyššie), takže tu sa nič iné nerozleje. */
.feature-panel.feature-panel--savings { overflow: visible; }
/* Medailón po zväčšení zasahuje aj do priestoru hlavičky panela
   (nadpis/veta/prepínače) nad ním — .feature-panel-head aj
   .feature-panel-body majú rovnaký z-index:1 (viď nižšie), takže sa bez
   tohto pravidla prekresľovali NEPREDVÍDATEĽNE (v praxi hlavička nad
   medailónom, presný opak toho, čo potrebujeme). Telo tohto panela
   dostáva vyšší z-index, nech medailón vždy vyhrá. */
.feature-panel--savings > .feature-panel-body { z-index: 2; }

.feature-panel-art {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: var(--art-w, 40%);
  max-width: none;
  pointer-events: none;
  /* 21.9.2026 — NEMÁ vlastné overflow:hidden (skúšané a zrušené v ten
     istý deň): táto ilustrácia je zámerne posunutá mimo svoj rámec
     (--top-savings-img-x/-y nižšie, napr. -32px doľava) — vlastné
     orezanie jej presne TENTO presah odrezávalo ("obrázok divne
     orezaný"). Panely, kde .feature-panel-art žije, sa aj tak orezávajú
     vďaka .feature-panel { overflow: hidden } (base pravidlo) — jediná
     výnimka je .feature-panel--savings (overflow:visible kvôli hover-
     zväčšeniu medailónu vyššie), a práve TAM potrebuje táto grafika
     svoj presah vidieť celý. */
}
.feature-panel-art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  object-position: center right;
  /* Obal má pointer-events:none (dekorácia nemá zavadzať bežnému
     prehliadaniu), ale živý editor (?hero_edit=1, static/hero-editor.js)
     potrebuje na SAMOTNOM obrázku pointerdown/move/up na ťahanie — bez
     tohto by fungovalo len koliesko (zoom cez wheel event, ten funguje
     aj cez pointer-events:none), ale nie posun myšou. pointer-events sa
     dedí, no potomok si ho vie prepísať späť na auto aj keď je predok
     "none" — mimo editora to nič nemení, nič pod obrázkom nie je. */
  pointer-events: auto;
}

/* Grafika BEZ priehľadného pozadia (týždenný plán — jej podklad sa z
   rastra vyrezať nedá, papier notesa má tú istú farbu ako pozadie, viď
   rozbor v README). Rieši sa to inak: obrázok vyplní celý pravý stĺpec
   až po okraj panelu a zľava sa VYTRÁCA maskou, takže nemá viditeľnú
   hranu a nečíta sa ako nalepená fotka. */
.feature-panel-art--bleed img {
  object-fit: cover;
  object-position: left center;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 26%);
  mask-image: linear-gradient(to right, transparent 0, #000 26%);
}

/* 10.9.2026 — grafika na ĽAVEJ strane panelu. Na žiadosť *"neako sa mi
   vizualne nepozdava to, ze obe grafiky su na tej istej strane"*: hero,
   "Recepty podľa rozpočtu" aj "Nákup na celý týždeň" mali všetky text
   vľavo a grafiku vpravo, takže na pravom okraji vznikla súvislá stena
   a tri panely pod sebou mali identický rytmus. Horšie: grafika rozpočtu
   aj týždňa je zelený košík so zeleninou — priamo nad sebou sa čítali
   ako jeden obrázok dvakrát. Striedaním strán sa dostanú po diagonále.

   Zámerne VARIANT, nie výnimka pre jeden panel — ďalší panel s grafikou
   sa striedania chytí pridaním jednej triedy. Zrkadlí sa všetko, čo má
   stranovosť: stĺpec, odsadenie textu, orientácia masky aj znamienko
   posunu z editora (bez neho by grafika liezla von z panelu). */
.feature-panel--art-left > .feature-panel-art {
  left: 0;
  right: auto;
}
.feature-panel--art-left > .feature-panel-head,
.feature-panel--art-left > .feature-panel-body {
  margin-left: calc(var(--art-w) + 26px);
}
.feature-panel--art-left .feature-panel-art img { object-position: center left; }
.feature-panel--art-left .feature-panel-art--bleed img {
  object-position: right center;
  -webkit-mask-image: linear-gradient(to left, transparent 0, #000 26%);
  mask-image: linear-gradient(to left, transparent 0, #000 26%);
}

/* Editor (?hero_edit=1) ladí šírku stĺpca a posun obrázka v ňom.
   --*-img-max je odteraz ŠÍRKA PRAVÉHO STĹPCA (nie max-width obrázka ako
   v starom rozložení), x/y posúvajú obrázok v ňom. Hodnoty z predošlého
   rozloženia sa zahodili — boli doladené na prekryv, ktorý už neexistuje. */
:root { --weekly-img-max: 700px; --weekly-img-x: 8px; --weekly-img-y: -1px; }
:root { --top-savings-img-max: 340px; --top-savings-img-x: -31px; --top-savings-img-y: -1px; }
:root { --top-savings-products-scale: 1.25; --top-savings-products-x: -24px; --top-savings-products-y: -8px; }
:root { --recepty-img-max: 660px; --recepty-img-x: -1px; --recepty-img-y: -22px; }
/* Posun z editora sa pri ľavej grafike zrkadlí — "38 px od svojho okraja
   dnu" má na oboch stranách znamenať to isté, inak by ten istý editor
   posúval jeden panel dnu a druhý von. */
.entry-card-art img { transform: translate(var(--weekly-img-x), var(--weekly-img-y)); }
/* 15.9.2026 — obrázok týždňa je v <picture> (mobilná verzia bez pozadia).
   display:contents nechá <img> správať sa ako priame dieťa rámu, takže
   pravidlá pre výšku/orez na desktope platia ako predtým. */
.feature-panel-art picture { display: contents; }
.feature-panel--art-left .entry-card-art img {
  transform: translate(calc(-1 * var(--weekly-img-x)), var(--weekly-img-y));
}
.top-savings-hero-art img { transform: translate(var(--top-savings-img-x), var(--top-savings-img-y)); }
.recepty-hero-art img { transform: translate(var(--recepty-img-x), var(--recepty-img-y)); }

/* Ovládanie panelu (rozpočet + tlačidlo). */
.feature-actions { display: flex; gap: 10px; align-items: stretch; flex-wrap: wrap; }
.feature-input-wrap {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 108px;
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-alt);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.feature-input-wrap:focus-within { border-color: var(--primary); box-shadow: 0 0 0 4px var(--primary-soft); }
.feature-input-wrap input {
  width: 100%;
  min-width: 0;
  border: none;
  background: none;
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 17px;
  font-weight: 600;
  color: var(--ink);
}
.feature-input-wrap input:focus { outline: none; }
.feature-input-suffix { color: var(--muted); font-weight: 600; font-size: 15px; }
.feature-btn { flex: 0 1 auto; justify-content: center; }

/* 10.9.2026 — panel obchodov ("Kde nakupuješ") zlúčený do "Nastav si
   hľadanie" ako podsekcia (#dashboard-store-row grid + .store-card
   veľkosť, viď .filter-subsection vyššie) — .feature-panel.store-
   showcase tu predtým bývalo, teraz mŕtvy kód, keďže žiadny element už
   nenesie obe triedy naraz. */

/* Rozdelený variant — text CEZ CELÚ ŠÍRKU navrchu, pod ním riadok s
   obrázkom VĽAVO a obsahom VPRAVO (10.9.2026, na žiadosť "Najväčšie
   zľavy dňa chcem obrázok naľavo a produkty napravo" + "potrebujem, aby
   ten text bol NAD tými zľavami" — teda nie vedľa obrázka v úzkom
   stĺpci ako pri ostatných paneloch, ale nad CELÝM riadkom obrázok+
   produkty). CSS Grid namiesto position:absolute, lebo art aj body sú
   v HTML SÚRODENCI (nie jeden vnorený v druhom) — grid ich vie posadiť
   do dvoch riadkov bez zmeny značkovania: 1. riadok head cez oba
   stĺpce, 2. riadok art | body. Predošlý pokus (position:absolute cez
   celú výšku PANELU) bol dôvod, prečo sa to "nedalo cez editor" — ten
   mení len posun/mierku OBRÁZKA V RÁMCI stĺpca, nie poradie stĺpcov;
   to je layout, nie panning. */
.feature-panel--split {
  display: grid;
  grid-template-columns: var(--art-w) minmax(0, 1fr);
  grid-template-rows: auto auto auto;
  column-gap: 26px;
  row-gap: 14px;
}
/* 22.9.2026 — uzatváracie CTA pod "Najväčšie zľavy" (viď index.html,
   top-savings-cta-wrap), VLASTNÝ riadok mriežky cez obe stĺpce (art aj
   dlaždice), nie súčasť .feature-panel-body — ten má transform:scale
   naladený editorom len pre dlaždice (viď --top-savings-products-scale
   vyššie), ktorý by tlačidlo tiež zväčšil a posunul. */
.feature-panel--split .top-savings-cta-wrap { grid-column: 1 / -1; grid-row: 3; }
.feature-panel--split .feature-panel-head {
  grid-column: 1 / -1;
  grid-row: 1;
  max-width: 60ch;
  margin: 0;
}
/* 10.9.2026 — na žiadosť "pridaj tam moznost zmenit zlavy aj bez toho aby
   sme museli cakat na automatiku": pás v "Najväčšie zľavy dňa" sa dovtedy
   menil LEN sám, cez 30s časovač (TOP_SAVINGS_ROTATE_MS v script.js) —
   žiadny manuálny spôsob nebol v DOM vôbec. Šípka vpravo od nadpisu volá
   ten istý loadNextTopSavings() (existoval už, len nemal tlačidlo) a
   reštartuje časovač, nech po ručnom kliku hneď nenasleduje aj
   automatický tik. */
.top-savings-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.top-savings-head-text { min-width: 0; }
.top-savings-refresh-btn {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin-top: 2px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--surface);
  color: var(--primary);
  cursor: pointer;
  box-shadow: var(--shadow-xs);
  transition: transform 0.15s ease, background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}
.top-savings-refresh-btn svg { width: 19px; height: 19px; transition: transform 0.2s ease; }
.top-savings-refresh-btn:hover {
  background: var(--primary);
  color: #fff;
  border-color: var(--primary);
  box-shadow: var(--shadow-md);
}
.top-savings-refresh-btn:hover svg { transform: translateX(2px); }
.top-savings-refresh-btn:active { transform: scale(0.92); }
/* Krátke otočenie pri kliku — vizuálne potvrdenie, že sa naozaj vymenila
   dávka, nie len tichá výmena kariet pod tichým tlačidlom. Trieda sa
   pridá/odoberie v script.js po dokončení fetchu. */
.top-savings-refresh-btn.is-spinning svg { animation: top-savings-refresh-spin 0.5s ease; }
@keyframes top-savings-refresh-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(180deg); }
}
@media (max-width: 480px) {
  .top-savings-refresh-btn { width: 34px; height: 34px; }
  .top-savings-refresh-btn svg { width: 16px; height: 16px; }
}
.feature-panel--split .feature-panel-body {
  grid-column: 2;
  grid-row: 2;
  max-width: 100%;
  margin: 0;
  /* --top-savings-products-scale/x/y — editor (?hero_edit=1, cieľ
     "top_savings_products") drobno dolaďuje posun/mierku RIADKU
     PRODUKTOV v jeho grid bunke. 10.9.2026 nahlásené: "číslo v paneli
     sa mení, ale fotky sa nehýbu" — pravidlo, čo tieto premenné
     aplikovalo cez transform, mierilo na .top-savings-hero-panel
     .top-savings-section--strip (stará trieda spred dnešnej prestavby
     na grid layout `--split`, viď README "Editor pozícií"). Trieda už
     v HTML neexistuje, takže sa CELÉ pravidlo prestalo uplatňovať —
     premenná sa síce menila (žiadny JS chyba), len ju nemal kto
     vykresliť. Predošlé hodnoty (219px/-4px/1.05, neskôr 12px/-36px)
     boli doladené pre STARÝ layout, kde sa obrázok a produkty
     PREKRÝVALI v tej istej grid bunke — v novom `--split` layoute majú
     vlastné oddelené bunky, takže default je späť na neutrálnych
     0px/0px/1 (viď :root nižšie). */
  transform: translate(var(--top-savings-products-x), var(--top-savings-products-y)) scale(var(--top-savings-products-scale));
  transform-origin: center top;
}
.feature-panel--split .feature-panel-art {
  grid-column: 1;
  grid-row: 2;
  position: relative;
  top: auto; right: auto; bottom: auto; left: auto;
  width: auto;
  min-height: 200px;
}
@media (max-width: 900px) {
  /* Pod 900px prejde na jeden stĺpec — poradie zo zdrojového kódu
     (head, body, art) je rovnaké ako pri ostatných paneloch, takže sa
     obrázok správa konzistentne (pás pod obsahom) aj tu. */
  .feature-panel--split { display: block; }
  .feature-panel--split .feature-panel-head { max-width: 100%; }
}

/* 21.9.2026 — ODSTRÁNENÉ: `.feature-panel--art .top-savings-scroll {
   overflow-x: auto; }`. Pozostatok z čias, keď sa pás dal posúvať do
   strán (viď .top-savings-section--strip .top-savings-scroll vyššie,
   3.9.2026 "na žiadosť odstránené vodorovné posúvanie/ťahanie" —
   nahradené auto-otáčaním). Toto pravidlo malo VYŠŠIU prioritu v poradí
   v súbore než `overflow: visible` v --strip variante, takže naďalej
   tichšo orezávalo obsah — nenápadné, kým nebolo čo cez okraj pretiecť.
   Nahlásené: hover-zväčšenie medailónu (.top-savings-thumb-wrap vyššie)
   sa cezeň orezávalo napriek tomu, že .feature-panel aj samotný --strip
   variant už mali overflow:visible nastavené správne. */

@media (max-width: 900px) {
  /* Grafika prestane byť stĺpcom a stane sa pásom pod obsahom — v úzkom
     okne by inak zabrala polovicu šírky textu. */
  .feature-panel { padding: 20px 18px; }
  .feature-panel--art > .feature-panel-head,
  .feature-panel--art > .feature-panel-body { max-width: 100%; }
  /* Striedanie strán je vec širokého okna. Tu je grafika pás POD obsahom
     (poradie v HTML: head, body, art), takže odsadenie textu, ktoré jej
     robilo miesto vedľa, musí padnúť — inak by text ostal odtlačený od
     ľavého okraja o šírku stĺpca, ktorý už neexistuje. */
  .feature-panel--art-left > .feature-panel-head,
  .feature-panel--art-left > .feature-panel-body { margin-left: 0; }
  .feature-panel-art {
    position: static;
    width: 100%;
    height: 168px;
    margin-top: 16px;
  }
  .feature-panel-art img { object-position: center; }
  .feature-panel-art--bleed img {
    object-fit: cover;
    object-position: center;
    -webkit-mask-image: none;
    mask-image: none;
    border-radius: var(--radius-card);
  }
  .feature-input-wrap { flex: 1 1 100%; }
  .feature-btn { flex: 1 1 100%; }
}

/* ======================================================================
   KOSTRA PRI NAČÍTAVANÍ (8.9.2026)
   ----------------------------------------------------------------------
   Prvé postavenie katalógu receptov po výmene letáku trvá ~7 s (potom
   ~0,3 s z cache). Dovtedy tam visel riadok "Načítavam recepty…" — text,
   ktorý nepovie, ako dlho ani čo príde. Kostra ukáže TVAR toho, čo sa
   načítava, takže stránka nevyzerá zaseknuto a obsah do nej potom
   nenaskočí, ale doplní sa.

   Trblietanie beží cez @keyframes, takže ho globálne pravidlo pre
   prefers-reduced-motion (viď hore v súbore) vypne samo. */
@keyframes skeleton-shimmer {
  from { background-position: 100% 0; }
  to   { background-position: -100% 0; }
}
.skeleton-line,
.skeleton-thumb {
  background-image: linear-gradient(
    90deg,
    color-mix(in srgb, var(--ink) 7%, transparent) 0%,
    color-mix(in srgb, var(--ink) 3%, transparent) 50%,
    color-mix(in srgb, var(--ink) 7%, transparent) 100%
  );
  background-size: 200% 100%;
  animation: skeleton-shimmer 1.5s ease-in-out infinite;
}
.skeleton-card {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 14px 16px;
  background: var(--surface);
}
.skeleton-line { height: 11px; border-radius: 999px; }
.skeleton-line + .skeleton-line { margin-top: 9px; }
/* Šírky sú zámerne nerovnaké — rovnako dlhé pruhy vyzerajú ako tabuľka,
   nie ako text, ktorý sa práve načítava. */
.skeleton-line--title { height: 14px; width: 62%; margin-bottom: 12px; }
.skeleton-line--short { width: 38%; }
.skeleton-line--mid { width: 74%; }

/* Kostra pásu "Najväčšie zľavy dňa" — kopíruje medailón + dva riadky. */
.skeleton-tile { flex: 0 0 auto; width: 200px; text-align: center; }
.skeleton-thumb {
  width: 128px;
  height: 128px;
  border-radius: 50%;
  margin: 0 auto 12px;
}
.skeleton-tile .skeleton-line { margin-left: auto; margin-right: auto; }


/* ======================================================================
   PLÁN JEDÁL NA ROZPOČET (10.9.2026)
   ----------------------------------------------------------------------
   Spoločný vizuál pre "Recepty podľa rozpočtu" aj "Nákup na celý týždeň"
   (jeden renderer v script.js, jeden engine v meal_planner.py). Cieľ,
   ktorý si používateľ vypýtal: "aby to bolo pekne vizualne a aby to bolo
   aj prehladne" — teda tri jasné vrstvy:
     1. hlavička = koľko z rozpočtu je minutých (číslo + pásik),
     2. deň po dni = čo sa varí, z čoho a ako,
     3. nákupný zoznam = čo reálne hodiť do košíka, po obchodoch.
   ====================================================================== */

.plan { display: flex; flex-direction: column; gap: 18px; }

.plan-loading {
  padding: 22px;
  text-align: center;
  color: var(--muted);
  font-weight: 600;
}

/* --- hlavička: rozpočet a fakty ------------------------------------- */
.plan-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background-image: var(--wash-quiet);
  box-shadow: var(--shadow-sm);
}
.plan-spend { flex: 1 1 260px; min-width: 0; }
.plan-spend-row { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.plan-spend-num {
  font-size: 30px;
  font-weight: 800;
  color: var(--primary-dark);
  font-variant-numeric: tabular-nums;
}
.plan-spend-of { font-size: 14.5px; color: var(--muted); }
/* Pásik je zámerne tenký a bez animácie — nesie jedinú informáciu
   (koľko z rozpočtu je preč), nemá súťažiť s číslom nad ním. */
.plan-bar {
  margin: 10px 0 6px;
  height: 8px;
  border-radius: 999px;
  background: var(--border);
  overflow: hidden;
}
.plan-bar span { display: block; height: 100%; background: var(--primary); border-radius: 999px; }
.plan-spend-rest { font-size: 13px; color: var(--muted); }
.plan-facts { display: flex; flex-wrap: wrap; gap: 8px; }
.plan-fact {
  padding: 7px 13px;
  border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--border);
  font-size: 13.5px;
  color: var(--muted);
}
.plan-fact strong { color: var(--ink); }
.plan-fact--save { background: var(--primary-soft); border-color: transparent; color: var(--primary-dark); }
.plan-fact--save strong { color: var(--primary-dark); }
.plan-fact--share { background: var(--gold-soft); border-color: transparent; color: var(--gold); }
.plan-progress-save { color: var(--primary-dark); }

/* 14.9.2026 — "Posledná šanca" na Domov. Odpočet je jediný "živý" prvok
   panela, preto má vlastný tvar (pilulka s pulzujúcou bodkou) a farbu
   --danger, tú istú ako % odznak na kartách. */
/* 15.9.2026 — "Posledná šanca" je režim panela Najväčšie zľavy. */
.top-savings-modes { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 14px; }
.top-savings-mode { display: inline-flex; align-items: center; }
.top-savings-mode-count { font-variant-numeric: tabular-nums; }
.ending-countdown {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 14px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--danger) 13%, transparent);
  color: var(--danger);
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ending-countdown:empty { display: none; }
.ending-countdown::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: currentColor;
  animation: ending-pulse 1.6s ease-in-out infinite;
}
@keyframes ending-pulse { 50% { opacity: 0.25; } }
@media (prefers-reduced-motion: reduce) {
  .ending-countdown::before { animation: none; }
}
.ending-day {
  align-self: center;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--muted);
}
.ending-day--urgent { color: var(--danger); }
.ending-day--soon { color: var(--gold); }


.plan-note {
  margin: 0;
  padding: 12px 16px;
  border-radius: var(--radius-md);
  background: var(--gold-soft);
  color: var(--gold);
  font-size: 14px;
}

/* --- deň po dni ------------------------------------------------------ */
/* 11.9.2026 — týždeň je POSTUPNOSŤ, nie mriežka: jeden riadok na deň,
   Po zhora nadol. Predtým to bola mriežka plných kariet (300px stĺpce),
   v ktorej sedem dní zabralo 1 380 px a siedmy deň ostal sám v rade.
   Rozbor v script.js nad planDayCardHtml. */
.plan-days {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.plan-day {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  overflow: hidden;
}
/* Zbalený riadok: deň má pevnú šírku, nech názvy jedál začínajú pod
   sebou a týždeň sa dá prebehnúť očami v jednom stĺpci. */
.plan-day-head {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 13px 16px;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.plan-day-head:hover { background: var(--surface-alt); }
.plan-day-name {
  flex: 0 0 92px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--primary-dark);
}
.plan-day-title {
  flex: 1 1 auto;
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  line-height: 1.3;
  min-width: 0;
}
.plan-day-tags { flex: 0 0 auto; }
.plan-day-tags .plan-day-badges { margin-bottom: 0; }
.plan-day-cost {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-size: 15px;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}
/* Cena za porciu pod cenou dňa — jediné číslo, ktoré sa dá porovnať s
   obedom v práci alebo donáškou. */
.plan-day-portion { font-size: 11.5px; font-weight: 600; color: var(--muted); }
.plan-fact--portion strong { color: var(--primary-dark); }
.plan-day-chev {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  color: var(--muted);
  transition: transform 0.15s ease;
}
.plan-day-head[aria-expanded="true"] .plan-day-chev { transform: rotate(180deg); }
.plan-day-head[aria-expanded="true"] { border-bottom: 1px solid var(--border); }
.plan-day-body { padding: 14px 16px 16px; }
.plan-day-meta { margin: 0 0 10px; font-size: 12.5px; color: var(--muted); }
.plan-day-badges { display: flex; flex-wrap: wrap; gap: 6px; }
.plan-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  border-radius: 999px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: 12px;
  font-weight: 600;
}

/* Suroviny: každý riadok povie NAJPRV čo treba (gramáž + názov) a až
   POTOM z čoho to appka kúpi. Bez druhého riadku by používateľ nevedel,
   či "Kuracie prsia" znamenajú akciu za 3,19 € alebo nákup naslepo. */
.plan-ings { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.plan-ing { font-size: 14px; }
.plan-ing-line { display: flex; align-items: baseline; gap: 7px; flex-wrap: wrap; }
.plan-ing-amount {
  min-width: 62px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.plan-ing-name { color: var(--ink); font-weight: 600; }
.plan-ing-tag {
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  font-size: 11.5px;
  color: var(--muted);
}
.plan-ing-product {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 3px 0 0 62px;
  font-size: 12.5px;
  color: var(--muted);
}
.plan-ing-product-name { color: var(--ink); }
.plan-ing-store {
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  font-size: 11px;
}
.plan-ing-price { font-weight: 700; color: var(--primary-dark); font-variant-numeric: tabular-nums; }
.plan-ing-shared {
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--gold-soft);
  color: var(--gold);
  font-size: 11px;
  font-weight: 600;
}

/* 11.9.2026 — postup mal vlastné druhé rozbalenie (<details>). Odkedy sa
   rozbaľuje celý deň, bolo by to klikanie dvakrát za tým istým: keď si
   deň otvoril, postup chceš vidieť. Zostal len nadpis. */
.plan-steps-title {
  margin: 14px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--border);
  font-size: 13px;
  font-weight: 700;
  color: var(--primary-dark);
}
.plan-steps-list { margin: 10px 0 0; padding-left: 20px; display: flex; flex-direction: column; gap: 7px; }
.plan-steps-list li { font-size: 13.5px; line-height: 1.5; color: var(--ink); }
/* 14.9.2026 — jedlo z veľkej databázy nemá postup v appke, odkáže naň. */
.plan-external-link {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 14px 0 0;
  padding: 10px 14px;
  border-radius: 999px;
  background: var(--primary);
  color: #fff;
  font-size: 14px;
  font-weight: 700;
  text-decoration: none;
  transition: background-color 0.15s ease;
}
.plan-external-link:hover { background: var(--primary-dark); }

/* --- nákupný zoznam -------------------------------------------------- */
.plan-shop {
  padding: 18px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background-image: var(--wash-quiet);
  box-shadow: var(--shadow-sm);
}
.plan-shop-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.plan-shop-title { margin: 0; font-size: 20px; font-weight: 700; }
.plan-track-all-btn { flex: 0 0 auto; }
/* 11.9.2026 — obchod je hlavné delenie nákupu (do Lidla ideš raz, nie
   pri každom oddelení). Hlavička je preto výraznejšia než predtým: logo,
   názov, počet položiek a suma za tento obchod — človek podľa nej vie,
   čo ho v ktorom obchode čaká, ešte než začne čítať položky. */
.plan-shop-store { margin-top: 20px; }
.plan-shop-store:first-child { margin-top: 0; }
.plan-shop-store-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 10px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
  font-size: 16px;
  font-weight: 700;
}
.plan-shop-store-head-logo {
  width: 30px;
  height: 30px;
  object-fit: contain;
  flex: 0 0 auto;
}
.plan-shop-store-head-meta {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--muted);
}
.plan-shop-store-head-sum {
  margin-left: auto;
  color: var(--primary-dark);
  font-variant-numeric: tabular-nums;
}
/* ---------- Tlač plánu (11.9.2026) ----------------------------------
   Ctrl+P na obrazovke plánu dovtedy vytlačilo celú appku aj s bočným
   menu, vyhľadávaním a tlačidlami. Papierový zoznam je pritom v obchode
   to najspoľahlivejšie, čo existuje — nevybije sa a nezhasne.
   Vytlačí sa preto len plán: dni a nákup, na bielom, bez ovládania. */
@media print {
  html { zoom: 1; }                 /* globálne 0.85 patrí na obrazovku, nie na papier */
  body { background: #fff; }
  .topbar, .sidebar-nav, .section-nav-panel, .footer, .tracked-modal,
  .plan-hero-actions, .plan-again-btn, .plan-shop-actions,
  .plan-progress-reset, .plan-track-btn, .plan-buy-btn,
  .recipe-track-all-btn { display: none !important; }
  /* Na papieri nemá zmysel nič skrývať — dni sa vytlačia rozbalené aj
     tie, ktoré má človek na obrazovke zbalené. */
  .plan-day-body[hidden] { display: block !important; }
  .plan-day-chev { display: none; }
  .plan-day, .plan-shop-item, .plan-shop-store { break-inside: avoid; }
  .plan-shop-items { grid-template-columns: repeat(2, 1fr); }
  .plan-shop-item { border-color: #bbb; }
  .plan-shop-item.is-bought { opacity: 1; }   /* odškrtnuté nech je čitateľné aj v tlači */
  .plan-progress-bar { border: 1px solid #bbb; }
  a[href]::after { content: ""; }             /* žiadne vypisovanie URL za odkazmi */
}

/* ---------- Odškrtávanie nákupu v obchode (11.9.2026) --------------
   Zoznam sa nepoužíva doma pri stole, ale v obchode s vozíkom v jednej
   ruke. Terč je preto celá karta, nie len štvorček, a stav musí byť
   čitateľný pri letmom pohľade z dĺžky ruky. */
.plan-shop-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

.plan-progress { margin-bottom: 14px; }
.plan-progress-bar {
  height: 6px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--ink) 10%, transparent);
  overflow: hidden;
}
.plan-progress-bar span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--primary);
  transition: width 0.25s ease;
}
.plan-progress-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: 7px;
}
.plan-progress-label { font-size: 13.5px; color: var(--muted); }
.plan-progress-label strong { color: var(--ink); font-variant-numeric: tabular-nums; }
.plan-progress-reset {
  flex: 0 0 auto;
  border: 0;
  background: transparent;
  padding: 0;
  color: var(--muted);
  font-size: 12.5px;
  text-decoration: underline;
  cursor: pointer;
}
.plan-progress-reset:hover { color: var(--ink); }

/* Odškrtávacie tlačidlo — prázdny krúžok, po označení plná fajka. */
.plan-buy-btn {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 2px solid var(--border-strong);
  border-radius: 50%;
  background: var(--surface);
  color: transparent;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.plan-buy-btn svg { width: 15px; height: 15px; }
.plan-shop-item:hover .plan-buy-btn { border-color: var(--primary); color: color-mix(in srgb, var(--primary) 35%, transparent); }
.plan-buy-btn[aria-pressed="true"] {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

.plan-shop-item { cursor: pointer; transition: opacity 0.15s ease, background-color 0.15s ease; }
/* Kúpené sa nestráca (v obchode si to chceš vedieť skontrolovať), len
   ustúpi: preškrtnutý názov a stlmená karta. */
.plan-shop-item.is-bought { opacity: 0.5; background: var(--surface-alt); }
.plan-shop-item.is-bought .plan-shop-name { text-decoration: line-through; }
.plan-shop-store.is-complete .plan-shop-store-head { opacity: 0.55; }
.plan-shop-store-head-meta.is-complete { color: var(--primary-dark); }

/* Nákup bol jeden dlhý stĺpec (19 položiek na 1 504 px, najvyššia
   sekcia stránky). Teraz sú položky vedľa seba a v rámci obchodu
   zoradené podľa oddelení (PLAN_AISLE_ORDER v script.js) — mäso pri
   mäse, mliečne pri mliečnych. minmax(330px) drží riadok čitateľný: na
   širokom okne vyjdú tri stĺpce, na užšom dva, na mobile jeden. */
/* Logo obchodu v rohu fotky produktu (na žiadosť "aby bolo jasné, kde ho
   treba kúpiť") — rovnaký vzor ako .deal-store-logo-wrap na kartách
   zliav. Odkedy je hlavné delenie obchod, je to skôr potvrdenie než
   jediný zdroj tej informácie. */
.plan-shop-store-logo-wrap {
  position: absolute;
  top: -4px;
  left: -4px;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 4px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 9px;
  box-shadow: var(--shadow-xs);
  font-size: 9px;
  font-weight: 700;
  overflow: hidden;
}
.plan-shop-store-logo { width: 100%; height: 100%; object-fit: contain; }
/* 11.9.2026 — karty zväčšené na žiadosť "zväčši to, aby to bolo lepšie
   vidieť": širší stĺpec, väčšia fotka aj názov. Pri 280px stĺpci sa
   dlhý názov lámal na tri riadky a fotka 40px bola v mriežke stratená. */
.plan-shop-items {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(370px, 1fr));
  gap: 10px;
  align-items: stretch;
}
.plan-shop-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface);
}
/* 11.9.2026 — fotka zväčšená na žiadosť "potrebujem tie obrázky zväčšiť
   v tých produktoch". 56 -> 84 px: produkt sa dá rozoznať v regáli bez
   čítania názvu, čo je pri nákupe hlavná vec.
   Stĺpec mriežky sa kvôli tomu musel rozšíriť (320 -> 370 px, teda z
   troch stĺpcov na dva). Namerané, prečo: pri troch stĺpcoch ostalo
   vedľa 84px fotky málo miesta na text, názvy aj štítky sa lámali a
   karta narástla zo 78 na 170-199 px — sekcia tak vyšla vyššia (1 323
   px) než pri dvoch širokých stĺpcoch (1 237 px), kde karta ostáva na
   92 px. Širšie karty sú navyše presne to, o čo v požiadavke išlo. */
.plan-shop-img {
  position: relative;   /* kotva pre logo obchodu v rohu */
  flex: 0 0 auto;
  width: 104px;
  height: 104px;
  display: flex;
  align-items: center;
  justify-content: center;
}
/* Bodkovaná linka pod názvom je inde afordancia hoveru, ale v nákupe
   pretínala každý riadok a používateľ ju nahlásil ako rušivú. */
.plan-shop-name.product-name-hover { border-bottom: none; }
.plan-shop-img img { max-width: 100%; max-height: 100%; object-fit: contain; }
.plan-shop-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.plan-shop-name { font-size: 15px; font-weight: 600; line-height: 1.3; }
.plan-shop-unit { font-size: 12px; color: var(--muted); }
.plan-shop-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.plan-shop-chip {
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--primary-soft);
  color: var(--primary-dark);
  font-size: 11px;
  font-weight: 600;
}
.plan-shop-price {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-variant-numeric: tabular-nums;
}
.plan-shop-price strong { font-size: 15px; color: var(--ink); }
.plan-shop-old { font-size: 11.5px; color: var(--muted); text-decoration: line-through; }

.plan-home {
  margin: 16px 0 0;
  padding: 12px 14px;
  border-radius: var(--radius-md);
  background: var(--surface-alt);
  border: 1px dashed var(--border-strong);
  font-size: 13.5px;
  color: var(--muted);
  line-height: 1.5;
}
.plan-home strong { color: var(--ink); }

.plan-again-btn { align-self: flex-start; }

@media (max-width: 560px) {
  /* .plan-days je odteraz zvislý zoznam, jeden stĺpec má už zo svojej
     podstaty — tu sa rieši len zbalený riadok, ktorý sa na úzkom
     displeji do jedného riadku nezmestí. Deň a cena ostanú hore oproti
     sebe, názov jedla a diétne štítky sa zalomia pod ne (nie skryjú —
     nikde inde na karte už nie sú). */
  .plan-day-head { flex-wrap: wrap; gap: 6px 10px; padding: 11px 13px; }
  .plan-day-name { flex: 1 1 auto; }
  .plan-day-title { flex: 1 1 100%; order: 3; font-size: 15px; }
  .plan-day-tags { flex: 1 1 100%; order: 4; }
  .plan-day-body { padding: 12px 13px 14px; }
  .plan-ing-product { margin-left: 0; }
  .plan-spend-num { font-size: 26px; }
}


/* --- vlastná obrazovka hotového plánu (10.9.2026) --------------------
   Na žiadosť "po vygenerovani ukazovalo iba tie produkty co mi to
   vygenerovalo + tie recepty z nich" a "nech to vyzera podobne ako
   hlavna stranka". Preto tu nie je nový vizuálny jazyk: hlavička je tá
   istá .screen-hero ako na Obľúbených/Zľavách, len jej pravý panel
   nesie peniaze namiesto štatistík. */
/* Na rozdiel od ostatných obrazoviek má táto hlavička len dva stĺpce
   (nadpis + peniaze), nie tri — bez space-between by panel visel v
   strede a vpravo by ostala prázdna tretina. */
.plan-hero { margin-bottom: 14px; justify-content: space-between; }
.plan-hero .screen-hero-head { max-width: 520px; }
.plan-hero-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.plan-secondary-btn {
  border: 1.5px solid var(--border-strong);
  background: var(--surface);
  color: var(--ink);
  font-family: 'Plus Jakarta Sans', sans-serif;
  font-size: 14.5px;
  font-weight: 600;
  padding: 9px 18px;
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.08s ease;
}
.plan-secondary-btn:hover { border-color: var(--primary); background: var(--primary-soft); }
.plan-secondary-btn:active { transform: translateY(1px); }

/* Panel s peniazmi: rovnaký rám ako .screen-hero-panel inde, len obsah
   je súhrn plánu (číslo + pásik + fakty). */
.plan-hero-panel .plan-spend { flex: 0 0 auto; width: 100%; }
.plan-hero-panel .plan-facts { margin-top: 4px; }
.plan-hero-panel .plan-fact { background: var(--surface); }

/* Sekcie pod hlavičkou — "Čo budeš variť" / "Čo kúpiť". Nadpis je ten
   istý stupeň ako .feature-title na Domov, aby stránka pôsobila ako
   pokračovanie úvodnej, nie ako iná appka. */
.plan-section { margin: 0; }
.plan-section-title {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 12px;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.01em;
}
.plan-shop .plan-section-title { margin-bottom: 0; }

#view-plan .plan { gap: 22px; }

/* ======================================================================
   MOBIL — iPhone 13 a podobné telefóny (15.9.2026)
   ----------------------------------------------------------------------
   Na žiadosť "mám iPhone 13, uprav mobilné zobrazenie, aby bolo pekné ako
   na PC" + "celé to pretestuj na mobilných telefónoch". Namerané pri
   390×844 (iPhone 13) pred úpravou:
   - dokument široký 426 px pri displeji 390 px → stránka sa dala posúvať
     do boku (obrázok telefónu posunutý editorom o +70 px, obrázok košíka
     o −46 px, pás Najväčších zliav zväčšený na 120 % a posunutý);
   - zoznam zliav so záporným ľavým okrajom (−48 px) a vlastným vnoreným
     posúvaním na 80 % výšky obrazovky;
   - tlačidlá 16–29 px (srdiečko 22, uloženie receptu 24, rozpočtové
     sumy 25, Varenie/Pečenie 28) a text 9–10,5 px — k tomu globálne
     html { zoom: 0.85 }, ktoré je zmenšenie pre desktop.
   ====================================================================== */
@media (max-width: 760px) {
  /* 0.85 je desktopové zmenšenie; na telefóne robilo z 12px textu 10px. */
  html { zoom: 1; }

  /* Posuny z editora obrázkov sú nastavené pre široký layout vedľa textu.
     Na telefóne je obrázok pod textom a posun ho tlačil za okraj. */
  .hero-mockup-img,
  .feature-panel-art img,
  .top-savings-hero-art img,
  .entry-card-art-img { transform: none; }
  .dashboard-hero-art { max-width: 100%; }
  .feature-panel--split .feature-panel-body { transform: none; }

  /* Zoznam zliav tečie so stránkou — vnorené posúvanie na telefóne
     "zamkne" prst v zozname a stránka pod ním sa nedá posunúť. */
  .deals-list { max-height: none; overflow: visible; padding: 0; margin: 0; }
  .price-history { white-space: normal; max-width: 100%; }

  .category-card-label { font-size: 14px; }
  .category-card-count { font-size: 14px; }
  /* Bočné kategórie vo výsledkoch majú vlastné (silnejšie) pravidlo 10/9 px. */
  .category-tiles--compact .category-card-label { font-size: 12px; }
  .category-tiles--compact .category-card-count { font-size: 11.5px; }

  /* Nákupný zoznam plánu: stĺpce mali minimum 370 px pri 316 px miesta,
     položky pretekali o 17 px a plán sa dal posúvať do boku. */
  .plan-shop-items { grid-template-columns: minmax(0, 1fr); }
  /* V jednom riadku ostávalo názvu 85 px ("Bravčová / krkovička / bez
     kosti" po slove pod sebou). Dva riadky: vľavo odškrtnutie a fotka,
     vpravo hore názov cez celú šírku, dole cena a sledovanie. */
  .plan-shop-item {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    align-items: center;
    column-gap: 10px;
    row-gap: 6px;
    padding: 10px 11px;
  }
  .plan-shop-item > .plan-buy-btn { grid-column: 1; grid-row: 1 / span 2; }
  .plan-shop-item > .plan-shop-img { grid-column: 2; grid-row: 1 / span 2; width: 64px; height: 64px; }
  .plan-shop-item > .plan-shop-main { grid-column: 3 / span 2; grid-row: 1; min-width: 0; }
  .plan-shop-item > .plan-shop-price {
    grid-column: 3;
    grid-row: 2;
    justify-self: start;
    flex-direction: row;
    align-items: baseline;
    gap: 6px;
  }
  .plan-shop-item > .plan-track-btn { grid-column: 4; grid-row: 2; }
  .plan-shop-chip { font-size: 12px; }

  /* Najväčšie zľavy — nahlásené z iPhonu: "nepáči sa mi, že sú tak pod
     sebou". Karty mali pevnú šírku 160 px, dve sa do ~316 px nezmestili,
     takže každá bola na vlastnom riadku. Teraz tri kompaktné vedľa seba. */
  .top-savings-section--strip .top-savings-scroll {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px 8px;
  }
  .top-savings-section--strip .top-savings-card { width: auto; min-width: 0; gap: 4px; padding: 8px 0 0; }
  .top-savings-section--strip .top-savings-thumb-wrap { width: 78px; height: 78px; margin: 0 auto 4px; }
  .top-savings-section--strip .top-savings-thumb-wrap .global-search-result-img-fallback { font-size: 30px; }
  .top-savings-section--strip .top-savings-store-logo-wrap { width: 24px; height: 24px; border-radius: 6px; }
  .top-savings-section--strip .top-savings-pct-badge {
    font-size: 13px;
    padding: 3px 6px;
    border-radius: 7px;
    top: -6px;
    right: -8px;
  }
  .top-savings-section--strip .top-savings-name {
    font-size: 12.5px;
    line-height: 1.25;
    min-height: 2.5em;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .top-savings-section--strip .ending-day { font-size: 11.5px; }
  .top-savings-section--strip .top-savings-price-row { flex-direction: column; gap: 0; }
  .top-savings-section--strip .top-savings-old-price { font-size: 11.5px; }
  .top-savings-section--strip .top-savings-new-price { font-size: 16px; }
  .feature-panel .top-savings-section--strip .top-savings-add,
  .feature-panel .top-savings-section--strip .favorite-btn { width: 30px; height: 30px; font-size: 13px; }
  /* 15.9.2026 z iPhonu: "obrázok pri Najväčších zľavách tam vôbec
     nepasuje" — na mobile skrytý, karty zliav stačia. */
  .feature-panel--savings .top-savings-hero-art { display: none; }

  /* Obchody — z iPhonu: "dátum pod obchodmi, aby bolo jasne vidieť".
     Namerané: štyri dlaždice 64–71 px vedľa seba, štítok dátumu 80–105 px
     sa do nich nezmestil a bol orezaný ("0.9. – 16.9"). Pravidlo na
     zalomenie do dvoch stĺpcov existovalo, ale neskoršie
     `.store-tiles { flex-wrap: nowrap }` ho prebíjalo. Mriežka 2×2. */
  .store-tiles,
  .store-tiles.store-tiles--freeform {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
  }
  .store-tiles .store-card,
  .store-tiles--freeform .store-card,
  .store-tiles--freeform .store-card.active {
    flex: none;
    width: auto;
    min-width: 0;
    max-width: none;
    height: 84px;
    aspect-ratio: auto;
    padding: 8px;
  }
  .store-tiles .store-card-period-badge,
  .store-tiles--freeform .store-card-period-badge { font-size: 13px; padding: 2px 8px; }

  /* Nákup na celý týždeň — nahlásené: "je moc vidieť, že to má pozadie
     na ďalšom pozadí". Obrázok bol orezaný do obdĺžnika so zaoblenými
     rohmi (v tmavom motíve aj s rámikom), jeho vlastné svetlé pozadie
     tak pôsobilo ako druhá karta. Teraz celý, bez rámu, okraje sa
     vytrácajú do panela. */
  :root .feature-panel .feature-panel-art--bleed { height: auto; box-shadow: none; background: none; }
  .feature-panel-art--bleed img,
  .feature-panel--art-left .feature-panel-art--bleed img {
    width: 100%;
    height: auto;
    object-fit: contain;
    border-radius: 0;
    /* Vyblednutie + multiply na skutočnom iPhone (Safari v Messengeri)
       nezabralo — pozadie fotky stále presvitalo. Na mobile sa preto
       načíta verzia s priehľadným pozadím (<picture> v index.html),
       ktorá žiadnu masku ani miešanie nepotrebuje. */
    -webkit-mask-image: none;
    mask-image: none;
    mix-blend-mode: normal;
    filter: none;
  }
  :root .feature-panel .feature-panel-art--bleed picture { display: block; }

  /* Hlavička — nahlásené zo skutočného iPhonu: bola na TRI riadky (logo,
     pod ním ikony, pod nimi hľadanie) a ikony motívu a košíka boli
     systémovo modré (Safari farbí <button> bez vlastnej farby). Logo a
     ikony teraz v jednom riadku, hľadanie pod nimi. */
  .topbar-card.topbar-card-compact { flex-wrap: wrap; gap: 8px 10px; padding: 10px 14px 12px; }
  .topbar-card.topbar-card-compact .topbar-logo { height: 40px; }
  .topbar-card.topbar-card-compact .topbar-actions { margin-left: auto; gap: 2px; }
  .topbar-card.topbar-card-compact .global-search-bar { order: 3; flex-basis: 100%; max-width: none; margin: 2px 0 0; }
  .theme-toggle-btn,
  .tracked-cart-btn { color: var(--ink); }
  .topbar-card.topbar-card-compact .tracked-cart-btn { width: 44px; height: 44px; font-size: 24px; }
  .user-avatar-btn { padding: 4px 8px 4px 4px; }

  /* Menu ako spodná lišta aplikácie — päť veľkých kariet navrchu zaberalo
     tretinu displeja a "28 položiek zostáva" vytekalo z karty. Počty sa
     v lište neukazujú; novú akciu v Obľúbených hlási oranžová bodka. */
  .section-nav-panel {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    max-width: none;
    margin: 0;
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
    border: 0;
    border-top: 1px solid var(--border);
    border-radius: 0;
    background: var(--surface);
    background-image: none;
    box-shadow: 0 -6px 20px rgba(20, 20, 15, 0.08);
  }
  .section-nav-panel .sidebar-nav { flex-wrap: nowrap; gap: 0; justify-content: space-around; }
  .section-nav-panel .sidebar-link {
    flex: 1 1 0;
    flex-direction: column;
    gap: 3px;
    min-height: 52px;
    padding: 4px 2px;
    border: 0;
    background: none;
    box-shadow: none;
  }
  .section-nav-panel .sidebar-link:hover,
  .section-nav-panel .sidebar-link.active { background: none; border: 0; box-shadow: none; transform: none; }
  .section-nav-panel .sidebar-link-icon { position: relative; width: 40px; height: 28px; border-radius: 999px; background: none; }
  .section-nav-panel .sidebar-link.active .sidebar-link-icon { background: var(--primary-soft); color: var(--primary-dark); }
  .section-nav-panel .sidebar-link-text { align-items: center; }
  /* 12 px (nie 11) — Android test: aj na 360 px sa "Obľúbené" zmestí. */
  .section-nav-panel .sidebar-link-label { font-size: 12px; font-weight: 600; color: var(--muted); white-space: nowrap; }
  .section-nav-panel .sidebar-link.active .sidebar-link-label { color: var(--primary-dark); }
  .section-nav-panel .sidebar-link-meta { display: none; }
  .section-nav-panel .sidebar-link-favorites.has-sale-news .sidebar-link-icon::after {
    content: "";
    position: absolute;
    top: 1px;
    right: 7px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 0 2px var(--surface);
  }
  body { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
}

@media (pointer: coarse) {
  .plan-buy-btn { width: 36px; height: 36px; }
}

/* Dotykové obrazovky (prst, nie myš): ovládacie prvky aspoň ~36–44 px,
   Apple odporúča 44 px. Na PC s myšou sa nič nemení. */
@media (pointer: coarse) {
  .theme-toggle-btn { width: 44px; height: 44px; }
  .favorite-btn { width: 36px; height: 36px; font-size: 17px; }
  .recipe-save-btn { width: 40px; height: 40px; }
  .budget-chip { min-height: 38px; padding: 8px 15px; }
  .cook-mode-btn { min-height: 38px; }
  .catalog-sort-btn,
  .catalog-diet-btn { min-height: 38px; }
  .store-select-all-btn { min-height: 36px; padding: 7px 14px; }
  .track-btn { min-height: 38px; }
  .verify-link { display: inline-block; padding: 8px 0; }
  .match-recipe-toggle { padding: 10px 0; }
  #fav-only-sale { width: 20px; height: 20px; }

  /* +/♥ v Najväčších zľavách sa ukazovali až po prejdení myšou — na
     telefóne myš nie je, takže sa na ne nedalo kliknúť vôbec. */
  .top-savings-section--strip .top-savings-add,
  .top-savings-section--strip .favorite-btn {
    opacity: 1;
    pointer-events: auto;
    width: 34px;
    height: 34px;
    font-size: 15px;
  }
}
