Dárkovník

Dárkovník

Chytrý rodinný seznam přání a dárků bez zklamání, duplicit a nechtěných překvapení.

v1.83.1 5567bc6 Nasazeno: 2026-11-03 06:48:49 UTC production
25
Splněných dárků
98
Aktivních přání
15
Seznamů přání
10
Uživatelů

Klíčové principy Dárkovníku

Pravidla, na kterých celá aplikace stojí a díky kterým funguje.

Režim překvapení

Vlastník seznamu ani jeho spoluvlastníci nikdy nevidí, kdo dárek zamluvil ani zda je koupený. Radost pod stromečkem nebo na narozeninové oslavě tak zůstává stoprocentní.

Spoluvlastnictví seznamů

Ideální pro rodiče dětí – oba mohou seznam společně spravovat a přidávat nápady na dárky, ale sami si na něm dárky nezamlouvají.

Veřejný odkaz bez registrace

Každý seznam lze bezpečně nasdílet tajným odkazem. Babička nebo dědeček si mohou přání prohlédnout i zamluvit přímo bez nutnosti registrace.

Více měn & přepočet na Kč

Podpora pro CZK, EUR, USD i GBP s automatickým orientačním přepočtem na české koruny přímo v přehledu dárků.

Dárkovník ve vašem telefonu (PWA)

Dárkovník můžete používat jako plnohodnotnou mobilní aplikaci přímo z plochy.

Apple iOS (iPhone / iPad)

Otevřete Dárkovník v prohlížeči Safari, klikněte na tlačítko Sdílet (čtvereček se šipkou nahoru) a vyberte možnost Přidat na plochu.

Google Android

Otevřete Dárkovník v prohlížeči Chrome, klepněte na menu se třemi tečkami vpravo nahoře a zvolte Nainstalovat aplikaci (nebo Přidat na plochu).

Zpětná vazba & Kód

Aplikace se neustále vyvíjí. Váš názor pomáhá Dárkovník vylepšovat.

Máte nápad na novou funkci nebo jste narazili na chybu? Rádi vaše podněty zapracujeme.

Přihlaste se pro odeslání zpětné vazby
Zdrojový kód projektu: GitHub

Použité technologie

Python 3.12 Django 5.2 PostgreSQL Bootstrap 5 HTMX WebPush Docker

Historie verzí a vydání

Přehled všech vylepšení a oprav aplikace.

Všechna vydání na GitHubu

  • Podnět #82 (UX vylepšení): Výběr oslavenců v modálním okně oslavy vázaný na skupinu:
    • Modální okno pro vytvoření rodinné oslavy nově otevírá transferový výběr oslavenců prázdný s výzvou „Nejprve vyberte skupinu výše pro zobrazení jejích členů“, čímž odpadá dřívější matoucí předvyplnění členy náhodné první skupiny.
    • Po zvolení skupiny z rozbalovací nabídky se asynchronně přes AJAX načtou pouze relevantní členové a spravované dětské profily dané skupiny s indikátorem načítání.
    • Zajištěno správné zobrazení a zachování vybraných oslavenců při editaci existující oslavy i při opětovném odeslání nevalidního formuláře.
  • Automatizované testy & verifikace:
    • Rozšířen unit test test_celebration_form_group_dynamic_filtering v darkovnik/tests.py ověřující prázdný stav při inicializaci, dynamické naplnění querysetů po volbě skupiny, správné zpracování na POSTu a funkčnost AJAX endpointu.
    • Aktualizován a rozšířen Playwright E2E test test_celebration_dual_list_picker v tests_e2e/scenarios/test_calendar_and_celebrations.py pro ověření uživatelského toku (prázdná výchozí nabídka -> výběr skupiny -> přesun oslavenců tlačítky a klikáním).

  • Podnět #66 & #82: Celostránkový kalendář událostí a měsíční agenda (/calendar/):
    • Vytvořena nová dedikovaná stránka kalendáře s měsíčním stránkováním, přehlednou denní agendou a alternativním zobrazením na měsíční mřížce (Grid).
    • Harmonizace záhlaví stránky dle standardního kánonu (layouts/base_simple.html a .page-hero-card) s responzivními akčními tlačítky.
    • Přepínače zobrazení (Agenda / Mřížka) a rychlé filtry typu události sjednoceny do segmentovaných ovladačů (.segmented-control) shodných se zbytkem aplikace.
    • Do kalendáře jsou agregovány všechny klíčové události: narozeniny členů rodinných skupin a dětí (s výpočtem věku), jmeniny (svátky), plánované společné oslavy i tradiční Vánoce (24. prosince).
    • Zpřehlednění a sjednocení hierarchie událostí: v nadpisu se zobrazuje výhradně jméno osoby / název oslavy, každá událost má jediný čistý štítek typu a doplňující informace (např. věk, odpočet, čas, místo či spravovaný profil) jsou umístěny v sekundární metadatové řádce bez vizuálního zahlcení štítky.
    • Souhrnná počítadla událostí v záhlaví jsou formátována dle designového kánonu (Counters Canon): badge bg-body text-body-secondary border rounded-pill px-3 py-1.5 small fw-normal s optimálním odsazením ikony a textu.
  • Podpora českých jmenin (svátků) a nezávislost na roku:
    • Implementována kompletní databáze českého kalendáře jmen pro všech 365 dní v roce s automatickým párováním křestních jmen uživatelů a spravovaných profilů.
    • Vestavěná podpora pro české zdrobněliny a přezdívky (např. Filípek -> Filip (26. 5.), Honza -> Jan (24. 6.), Kubík -> Jakub (25. 7.), Anička -> Anna (26. 7.) apod.).
    • Vytvořen dedikovaný formulářový widget a pole NameDayFormField pro zadávání data svátku bez závislosti na roku – uživatel volí pouze den a měsíc bez matoucího kalendářního roku narození.
  • Plánování rodinných oslav (CelebrationEvent):
    • Vytvořen nový datový model CelebrationEvent pro plánování rodinných a přátelských oslav v rámci společné skupiny (název, datum konání, volitelný čas začátku, místo konání, program a podrobnosti v Markdownu, přiřazení oslavenci z řad uživatelů i spravovaných dětských profilů).
    • V modálním okně tvorby a editace oslavy implementován intuitivní dvousloupcový transferový selektor (Dual-list Transfer Selector) namísto nepraktického výběru se stisknutou klávesou Ctrl. Dospělí členové i spravované dětské profily jsou sjednoceny v jednom seznamu s označením dětí, tlačítky Vybrat vše / Zrušit výběr a dynamickým filtrováním při změně skupiny.
    • Vytvořen pohled na detail oslavy (/celebrations/<pk>/) s odpočtem dní, zobrazením místa, času, přehledem oslavenců a sekcí přání oslavenců využívající komponentu dlaždic z přehledu Přání ostatních (_shared_wishlist_tile.html) s náhledy dárků, cenami, štítky a striktním dodržením Surprise Mode.
    • Kompletní obsluha vytváření, editace a mazání oslav přes standardizovaná modální okna dědící z darkovnik/layouts/base_modal.html včetně dynamického filtrování členů podle vybrané skupiny přes AJAX.
  • Export do kalendářů (iCal & Google Kalendář):
    • Generování standardního iCalendar (.ics) streamu na /calendar/export.ics s respektováním filtru skupiny a typu události pro snadný import do Apple Kalendáře, Outlooku a dalších aplikací.
    • Tlačítko pro přímé přidání události do Google Kalendáře na jeden klik z detailu oslavy; do popisu události v Google Kalendáři i iCal exportu je automaticky vložen přímý odkaz na detail oslavy v Dárkovníku.
  • Integrace do navigace a Dashboardu:
    • Do levého postranního panelu (_sidebar.html) i mobilního vysouvacího menu (_mobile_nav.html) přidána nová položka Kalendář s ikonou bi-calendar3.
    • Widget na Dashboardu rozšířen a přejmenován na Nadcházející události – zobrazuje chronologicky agregovaný přehled narozenin, svátků i rodinných oslav pro nejbližších 30 dní se sjednocenými štítky událostí a proklikem „Zobrazit celý kalendář“.
  • Automatizované testy & verifikace:
    • V darkovnik/tests.py vytvořena a rozšířena testovací sada CalendarAndCelebrationTests (13 unit testů) ověřující detekci jmenin, výpočet svátků, model CelebrationEvent, oprávnění k oslavám, XSS sanitizaci, zobrazení kalendáře, filtry, iCal export, funkci get_upcoming_events i integraci seznamů přání v detailu oslavy.
    • Vytvořen a rozšířen Playwright E2E scénář tests_e2e/scenarios/test_calendar_and_celebrations.py (3 scénáře) ověřující průchod uživatele z dashboardu do kalendáře, interakci s dvousloupcovým selektorem oslavenců, seznam přání na detailu oslavy a smazání události v reálném prohlížeči.

  • DevOps oprava: Bezpečné ořezání uvozovek v bash skriptech:
    • V scripts/backup.sh a scripts/restore.sh nahrazen náchylný sed výraz s vnořenými uvozovkami za čistou expanzi parametrů bash. Odstraněna syntaktická chyba syntax error near unexpected token 'done', která bránila spuštění skriptu na produkčním serveru.
    • Zjednodušena rotace záloh v scripts/backup.sh na přímé volání find ... -delete.

  • DevOps & Bezpečnost dat: Skripty pro zálohy a disaster recovery:
    • Vytvořen produkční zálohovací skript scripts/backup.sh pro automatizované zálohování PostgreSQL databáze a uživatelských médií (media_volume). Skript načítá konfiguraci z .env, bezpečně vytváří komprimované .sql.gz dumpy a .tar.gz archivy médií přes neinteraktivní docker compose exec -T, automaticky provádí rotaci a mazání záloh starších než 14 dní a podporuje tichý režim -q pro spouštění v cronu.
    • Vytvořen skript pro obnovu scripts/restore.sh, který umožňuje bezpečný a idempotentní restore databáze i médií s ochranným potvrzovacím dialogem, vyčištěním schématu a kontrolou integrity gzip/tar archivů.
    • Zajištěno vynucení unixových konců řádků (LF) pro shell skripty v .gitattributes a ignorování složky záloh a archivů v .gitignore.
    • V DEPLOYMENT.md kompletně přepracována sekce 5. Automated Backups & Disaster Recovery s podrobným návodem na nastavení nočního cronu, doporučenou retencí, manuálním testováním a strategiemi pro off-site replikaci (Wedos snapshoty, rsync/rclone).

  • Podnět #90: Hybridní řazení kategorií (počet přání v menu vs. abeceda ve filtru):
    • V rozbalovacích nabídkách (Detail skupiny, Přání ostatních, Detail sdílené kategorie) jsou kategorie řazeny sestupně podle počtu aktivních přání (-item_count), při shodném počtu přání abecedně bez ohledu na velikost písmen (Lower("name")). Nejrelevantnější kategorie s největším obsahem jsou tak ihned po ruce.
    • Ve formulářovém výběru filtru (<select name="category"> v Přáních ostatních) jsou kategorie seřazeny striktně abecedně od A do Z case-insensitively (Lower("name")), což zajišťuje přirozené a rychlé vyhledání hodnoty a eliminuje dřívější řazení malých písmen až za velká.
  • Automatizované testy & verifikace:
    • V darkovnik/tests.py doplněn unit test test_hybrid_category_sorting do sady SharedCategoryDetailTests, který ověřuje obě nezávislé řadicí sekvence (dropdown vs. filter select) na reálných datech s různou velikostí písmen.

  • Podnět #90 (Fáze 3): Počty přání v rozbalovacích seznamech kategorií a filtrace:
    • V rozbalovacích nabídkách kategorií na Detailu skupiny (group_detail.html), v Přáních ostatních (shared_wishlists.html) a na Detailu sdílené kategorie (shared_category_detail.html) jsou nyní u každé kategorie zobrazeny aktuální počty přání v daném pohledu.
    • Počty jsou formátovány jako decentní neutrální pilulky dle designového kánonu (Counters Canon): badge bg-body text-body-secondary border rounded-pill px-2 py-0.5 small fw-normal.
    • Ve filtrovacím formuláři <select name="category"> v Přáních ostatních je počet přání zobrazen v závorce: {{ cat.name }} ({{ cat.item_count }}).
    • Kategorie, které v daném kontextu (skupina, množina sdílených seznamů) neobsahují žádná aktivní přání (item_count == 0), jsou z výpisu automaticky skryty, aby nezahlcovaly uživatele prázdnými odkazy.
  • Perzistence rozbalovacího tlačítka a přívětivý prázdný stav:
    • Tlačítko rozbalovacího seznamu „Dle kategorií“ zůstává v záhlaví trvale viditelné na desktopu i v mobilním rozhraní, čímž se předchází matoucímu mizení ovládacích prvků.
    • Pokud žádné sdílené přání v aktuálním kontextu nemá přiřazenou kategorii, rozkliknutí tlačítka zobrazí přívětivou neaktivní položku „Zatím žádná přání s kategorií“.
  • Optimalizace výkonu a ochrana Surprise Mode:
    • Výpočet počtu položek probíhá na databázové úrovni v jediném SQL dotazu pomocí Count("items", filter=item_filter, distinct=True) bez rizika N+1 dotazů.
    • Agregace striktně dodržuje pravidla Surprise Mode: nikdy nezapočítává vlastní položky uživatele, položky ze seznamů se spoluvlastnictvím (co_owners), tajné nápady (is_secret_idea=True) ani již obdržené dárky (is_received=True).
  • Automatizované testy & verifikace:
    • Rozšířena testovací sada SharedCategoryDetailTests v darkovnik/tests.py o ověření počtů položek item_count, skrytí prázdných kategorií, filtrace podle skupiny i trvalé přítomnosti dropdownu s prázdným stavem.
    • Aktualizován Playwright E2E test tests_e2e/scenarios/test_menu_and_shared_wishlists.py s kontrolou renderování počítadla u kategorie v reálném prohlížeči.

  • Podnět #90 (Fáze 2): Přání ostatních rozdělená dle kategorií:
    • Vytvořen nový specializovaný pohled SharedCategoryDetailView dostupný na /wishlists/shared/kategorie/<category_pk>/ umožňující projít všechna přání dané kategorie napříč všemi sdílenými seznamy rodiny a přátel.
    • Do horní lišty akcí v sekci Přání ostatních (shared_wishlists.html) přidáno dropdown tlačítko „Dle kategorií“ s přímými odkazy do jednotlivých kategorií a zachováním aktuálního filtru skupiny (?group=...).
    • Na stránce kategorie je k dispozici přehledné záhlaví, rychlé přepínání mezi kategoriemi i skupinami, tlačítko pro návrat zpět s uchováním filtrů a přepínač režimů zobrazení (Seznam / Kompaktní) ukládaný do session.
  • Architektonická unifikace (BaseCategoryItemsView):
    • Vytvořen nový modul darkovnik/views/category_views.py s bázovou třídou BaseCategoryItemsView, která zapouzdřuje filtrování podle kategorie, dotazování, řazení, stránkování, přípravu dat a ochranu Surprise Mode.
    • Původní GroupCategoryDetailView z group_views.py zredukován a adaptován na novou bázi (odstraněna duplicitní logika). Pro plnou zpětnou kompatibilitu zůstává dostupný i import z group_views.
    • Filtrování v SharedCategoryDetailView je připraveno jak pro skupiny (?group=<id>), tak pro libovolnou podmnožinu uživatelů či profilů (?users=<id1,id2>), což otevírá cestu pro budoucí modul oslav a filtraci oslavenců.
  • Vylepšení seskupování dárků pro spravované profily:
    • Ve view_utils.py v pomocné funkci group_items_by_owner_and_wishlist i v šablonových wrapperech opraveno určování osoby tak, aby dárky z dětských a spravovaných profilů (ManagedProfile) byly primárně seskupeny pod jménem a profilem dítěte, nikoliv pod účtem rodiče.
    • Zajištěno bezpečné řazení i zobrazení bez ohledu na to, zda je entitou User nebo ManagedProfile.
  • Surprise Mode Invarianty:
    • Vlastní položky uživatele, položky ze seznamů, kde je uživatel spoluvlastníkem (co_owners), tajné nápady (is_secret_idea=True) i již koupené dárky (is_received=True) jsou ze sdílených výpisů striktně vyloučeny.
  • Automatizované testy & verifikace:
    • V darkovnik/tests.py vytvořena nová testovací sada SharedCategoryDetailTests (8 unit testů) pokrývající autorizaci, Surprise Mode, filtry dle skupiny i uživatelů, seskupení spravovaných profilů, HTMX přepínání a dropdown odkazy.
    • V tests_e2e/scenarios/test_menu_and_shared_wishlists.py rozšířen Playwright E2E test o kompletní průchod z Přání ostatních přes dropdown kategorií do detailu kategorie a návrat zpět.

  • Oprava mezery v administraci:
    • V šabloně darkovnik/templates/darkovnik/admin/dashboard.html opravena nadbytečná mezera v tlačítku „Klasický Django Admin“, způsobená nevhodnou kombinací mezer v textovém uzlu a flexboxového layoutu d-flex gap-2.
  • Podnět #91: Ikonka a status bar badge pro Web Push notifikace:
    • Vytvořena čistá monochromatická alpha maska push-badge-96x96.png pro stavovou lištu Androidu (eliminuje plný bílý čtvereček způsobený dřívějším použitím plnobarevného faviconu).
    • Vytvořena moderní 192×192 px brandová ikona push-icon-192x192.png s fialovým gradientem, dárkem a zlatou stuhou na transparentním pozadí pro tělo notifikací.
    • Zaktualizován Service Worker (sw.js) na verzi cache darkovnik-pwa-v3, přednačítání assetů a výchozí hodnoty push notifikací.
    • Helper send_safe_user_notification v webpush_utils.py automaticky doplňuje novou ikonu a badge do všech odesílaných payloadů.
  • Podnět #89: Redesign hlavičky karet členů na detailu skupiny:
    • V komponentě _person_wishlists_card.html vizuálně i hierarchicky odděleny sdílené seznamy od celkového počtu přání.
    • Názvy sdílených seznamů jsou prezentovány jako decentní štítky s ikonou bi-card-checklist a ořezem dlouhých názvů (text-truncate).
    • Přidán vertikální oddělovač (vr) a čítač přání sjednocen do decentního neutrálního kánonu badge bg-body text-body-secondary border rounded-pill fw-normal s obrysovou ikonou bi-gift (shodně jako na dlaždicích v Přáních ostatních).
  • Kánon pro neutrální počítadla (Counters Canon):
    • Do DESIGN.md, docs/DESIGN_SYSTEM.md, vzorkovníku na /styleguide/, AGENTS.md a skillu darkovnik-designer zavedeno striktní designové pravidlo zakazující stylizovat numerická počítadla (dárky, položky, seznamy) pomocí bg-primary-subtle či křiklavých barev (které v Bootstrapu vytvářely kolize světle modrého podkladu s barevnými uživatelskými akcenty) a definující jednotný nerušivý kánon.
  • Podnět #90 (Fáze 1): Sbalitelné filtry v Přáních ostatních:
    • V shared_wishlists.html byl rozměrný formulář filtrů převeden do sbalitelného bloku (#sharedWishlistsFilterCollapse).
    • Výchozí zobrazení je kompaktní a čisté; v horní liště akcí přibylo pilulkové tlačítko „Filtry“.
    • Při aktivním vyhledávání nebo zvoleném filtru se blok automaticky otevře a tlačítko zobrazí indikátor „Aktivní“.
  • Automatizované testy & verifikace:
    • Nová testovací sada FeedbackBatchOctober28Tests v darkovnik/tests.py ověřující eliminaci mezery v admin tlačítku, sbalitelný filtr, stylování odznaků a výchozí Web Push ikony.
    • Rozšířen Playwright E2E test test_menu_and_shared_wishlists.py o interaktivní ověření rozbalování/sbalování filtrů a zobrazení v detailu skupiny.

  • Podnět #83: Dárky mimo přání („Tajné nápady“ dárců):
    • Zavedena možnost pro návštěvníky a dárce přímo v detailu wishlistu oslavence zaevidovat tajný nápad na dárek mimo oficiální seznam přání pro koordinaci nákupů v rodině a prevenci duplicit.
    • Nová sekce „Tajné nápady pro oslavence“ (_secret_items_section.html) je začleněna na konec seznamu a stylizována jako nativní kategorie s jemným fialovým akcentem, ikonou bi-incognito a poznámkou v .card.bg-body-tertiary namísto rušivého banneru či počítadla.
    • Položky tajných nápadů využívají standardní řádky _generic_list_item_wrapper.html i kompaktní _generic_condensed_item_wrapper.html, takže plně respektují globální přepínač pohledů (Seznam / Kompaktní výpis).
    • Informace o autorovi tipu byla přesunuta z nadpisu dolů do metadat karty (Navrhl(a): [Jméno]), tělo dárku tak zůstává 100% čisté a identické s běžnými přáními.
    • Správa položky (úprava, smazání) je pro autora integrována přímo do standardního kontextového menu se třemi tečkami (_item_actions_include.html) bez nadbytečných oddělovačů, a pro ostatní návštěvníky je prázdné menu skryto.
  • Surprise Mode Invariant & Obousměrné notifikace dárců:
    • Striktní izolace na úrovni databázových dotazů: tajné položky (is_secret_idea=True) jsou důsledně odfiltrovány ze všech výpisů pro vlastníka i jeho spoluvlastníky.
    • Počítadla aktivních položek (active_item_count), statistiky na dashboardu i odznaky na dlaždicích zcela vylučují tajné nápady.
    • Izolace časového razítka wishlistu (updated_at): signály WishlistItem při uložení či smazání tajného tipu nemění wishlist.updated_at, čímž je zamezeno prozrazení aktivity oslavenci přes nápis „Naposledy upraveno: před chvílí“.
    • Obousměrné notifikace pro ostatní dárce: při rezervaci i zrušení rezervace tajného tipu se doručí in-app notifikace (a web push) všem ostatním dárcům ze sdílených skupin. Oslavenec ani spoluvlastníci notifikaci nikdy neobdrží (NotificationManager.visible_for_user), a událost se nezapisuje do společné zdi Activity.
    • Zabezpečení detailních a AJAX endpointů: pokusy o přímý přístup k tajnému nápadu ze strany správce seznamu končí chybou 403 Forbidden nebo 404 Not Found.
  • Formuláře a interakce pro dárce:
    • Modální okna _secret_item_add_modal.html, _secret_item_edit_modal.html a _secret_item_delete_modal.html dědící z darkovnik/layouts/base_modal.html.
    • Volitelný switch „Rovnou si tento dárek zamlouvám“ zarovnaný v boxu s konzistentním odsazením automaticky vytvoří rezervaci při uložení tipu.
    • Autor tajného tipu (suggested_by) může svůj nápad kdykoliv upravit nebo smazat, ostatní dárci si jej mohou pouze zamluvit či zrušit svou rezervaci.
  • Automatizované testy & verifikace:
    • Nová Django unit testovací sada SecretGiftIdeasTests v darkovnik/tests.py (9 testů) pokrývající práva vytváření, auto-claim, ochranu Surprise Mode pro vlastníka i spoluvlastníky, počítadla, neměnnost wishlist.updated_at, obousměrné notifikace dárců a potlačení signálů Activity.
    • Nový Playwright E2E scénář tests_e2e/scenarios/test_secret_gift_ideas.py ověřující kompletní multi-user flow (Bára přidá nápad -> přepne na kompaktní výpis -> Cecil vidí položku i autora v metadatech -> Anna ani Petr v DOMu nemají sekci ani položku).

  • Kompaktní dlaždicový pohled na Přání ostatních (#81):
    • Zavedena nová unifikovaná komponenta _shared_wishlist_tile.html pro prezentaci sdílených seznamů v responzivní mřížce (1 col mobil, 2 cols tablet, 3 cols desktop).
    • Každá dlaždice přehledně zobrazuje avatara a jméno vlastníka či spravovaného profilu (včetně odznaku), počet aktivních přání, název seznamu s proklikem (stretched-link), popis, štítky kategorií a elegantní náhledový box 2–3 dárků s cenami.
    • Zápatí dlaždice obsahuje klikatelné štítky sdílených skupin a relativní čas poslední úpravy.
  • Segmentovaný přepínač zobrazení (Segmented Control):
    • V záhlaví stránky /prani-ostatnich/ byl přidán přepínač mezi režimem [ 🗂️ Dlaždice ] (výchozí) a [ 👥 Dle osob ] (původní akordeonové seskupení).
    • Volba uživatele se ukládá do session (shared_wishlists_view_preference), takže si aplikace pamatuje preferovaný pohled i po odchodu a návratu.
    • Filtry (vyhledávání, výběr skupiny, kategorie) a formulář plně zachovávají aktuálně zvolený režim zobrazení.
    • Kontextové tlačítko „Sbalit vše / Rozbalit vše“ se inteligentně zobrazuje pouze v režimu osob.
  • Aktualizace Design systému & Living Styleguide:
    • Nová komponenta _shared_wishlist_tile.html byla zdokumentována v DESIGN.md, docs/DESIGN_SYSTEM.md a začleněna do skillu darkovnik-designer.
    • Do živé vzorkovny /styleguide/ přidána nová sekce 11. Dlaždice sdíleného seznamu s interaktivní ukázkou komponenty a vzorovým kódem pro šablony.
  • Automatizované testy:
    • Doplněna testovací sada SharedWishlistsTilesViewTests v darkovnik/tests.py testující výchozí režim dlaždic, přepnutí na akordeon osob, perzistenci volby v session, sanitizaci neplatných parametrů a zobrazení ve styleguide.
    • Aktualizován a rozšířen Playwright E2E test test_menu_and_shared_wishlists.py, ověřující interaktivní přepínání pohledů v reálném prohlížeči.

  • Redesign sekce Web Push notifikací v profilu:
    • Karta nastavení push notifikací v profile_edit.html přestylována do moderní podoby podle DESIGN.md s ikonou zvonku v avataru, srozumitelným popisem a stavovým odznakem.
    • Tlačítka pro správu odběru a testovací notifikaci sjednocena do vyhrazeného řádku akcí.
    • Přepsána šablona templates/webpush_button.html tak, aby vykreslovala pouze tlačítko odběru bez vloženého <div id="webpush-message">, které narušovalo rozložení tlačítek.
    • Zpětná vazba #webpush-message a #test-webpush-feedback přesunuta pod tlačítka jako čistý flex alert s ikonou a automatickým mizením po 5 sekundách (webpush.js).
  • Plynulé vrácení dárku do seznamu bez reloadu stránky:
    • Pohled unreceive_gift_view v wishlist_views.py rozšířen o podporu AJAXu (X-Requested-With: XMLHttpRequest), vracející strukturovaný JSON {success, receipt_pk, item_pk, item_name, message}.
    • Ve skriptu wishlist_detail.js doplněna AJAX obsluha formuláře #unreceiveItemForm s indikátorem načítání, zavřením modálu, toastovou notifikací a plynulou animací odstranění řádku dárku ze stránky /obdrzene-darky/.
  • Konec zalamování a překrývání přepínačů v administraci webu:
    • V šabloně admin/dashboard.html nahrazen původní plovoucí formulářový přepínač za moderní flexboxovou kartu (p-3 bg-body-tertiary rounded-4 border) s jasným rozdělením na název nalevo a přepínač napravo (justify-content-between).
    • V custom.css definováno explicitní zarovnání a rozměry pro .form-switch-lg s width: auto !important a nulovým odsazením při .ps-0.
  • Cache-Busting & PWA Service Worker Cache:
    • Povýšena cache v Service Workeru (sw.js) z darkovnik-pwa-v1 na darkovnik-pwa-v2, což vynucuje automatické smazání zastaralé mezipaměti v prohlížečích uživatelů.
    • Verze statických souborů custom.css a wishlist_detail.js povýšena na ?v=15 a global_scripts.js na ?v=5 napříč všemi šablonami.
  • Automatizované testy:
    • Doplněn Django unit test test_unreceive_regular_item_ajax_success v darkovnik/tests.py ověřující AJAX vrácení položky.
    • Doplněn Playwright E2E test test_ajax_unreceive_item_smooth_removal v tests_e2e/scenarios/test_sorting_and_ui.py ověřující otevření modálu, odeslání přes AJAX, toastové oznámení a odstranění z DOM.

  • Plynulé označení dárku za obdržený bez odrolování (#85):
    • Přidána AJAX podpora pro endpoint mark_item_received_view (X-Requested-With: XMLHttpRequest).
    • Formulář #markAsReceivedForm v modálu se odesílá na pozadí, modál se automaticky uzavře a položka se z přehledu plynule odanimuje (opacity / scale / remove).
    • Doplněna neinvazivní toastová notifikace v pravém dolním rohu obrazovky (#darkovnikToastContainer), která informuje o úspěšném přesunutí položky bez změny vertikální pozice scrollování a bez rušivého reloadu stránky.
  • Resilience a samočisticí diagnostika Web Push (#87):
    • Vytvořen bezpečnostní modul darkovnik/utils/webpush_utils.py s funkcí send_safe_user_notification.
    • Každé zařízení uživatele je obsluhováno v izolovaném bloku – selhání jednoho koncového bodu (např. starý telefon) již neblokuje doručení na ostatní aktivní zařízení.
    • Implementováno automatické promazávání mrtvých/expirovaných subskripcí: při návratovém kódu HTTP 404 (Not Found), HTTP 410 (Gone) nebo chybě NotRegistered / InvalidRegistration je neplatný záznam z databáze odstraněn.
    • Zpřesněna diagnostika tlačítka „Odeslat testovací notifikaci“ v profilu – místo generické chybové hlášky vrací přesný důvod selhání a počet vyčištěných neaktivních zařízení.
    • Modul byl propsán do signálů (signals.py), správy požadavků (admin_views.py), podpory (support_views.py) i uvolnění rezervací (item_views.py).
  • Opravy UI a typografie (#79, #80, #86):
    • #79: Popisek akčního tlačítka na kartě osoby v Přáních ostatních (_person_wishlists_card.html) byl sjednocen na srozumitelné „Obdržené dárky“ (místo matoucího „Dárky“).
    • #80: Rozšířeny volby Markdown parseru o cuddled-lists v render_safe_markdown (text_utils.py). Odrážky (* i -) začínající bezprostředně pod odstavcem bez prázdného řádku se nyní správně vykreslují jako formátovaný seznam <ul><li>.
    • #86: Opravena velikost přepínačů .form-switch.form-switch-lg v custom.css. Rozměry a odsazení byly přesunuty ze společného wrapperu přímo na .form-check-input, čímž bylo odstraněno nechtěné zalamování a vertikální přetékání textu popisků v administraci webu.
  • Automatizované testy:
    • Doplněna testovací sada FeedbackBatchOctober26Tests v darkovnik/tests.py pokrývající cuddled-lists, AJAX označení dárku za obdržený (včetně trvalých položek) a promazávání expirovaných push subskripcí.
    • Doplněn Playwright E2E test test_ajax_mark_item_as_received_smooth_removal v tests_e2e/scenarios/test_sorting_and_ui.py.

  • Aktualizace produkčních závislostí:
    • psycopg2-binary povýšen z 2.9.10 na 2.9.13 (opravy chyb v parseru poškozených PostgreSQL intervalů, int64 polí a bytea; podpora pro PostgreSQL 18).
    • gunicorn povýšen z 23.0.0 na 26.2.0 (podpora cleartext HTTP/2, bezpečnostní hardening hlaviček a WSGI environu; ověřena kompatibilita v Dockeru).
    • requests povýšen z 2.32.3 na 2.34.2 (vestavěné typové anotace, oprava proxy bypass a duplicitních lomítek v URI).
    • pywebpush spodní hranice zpřesněna z >=2.3.0 na >=2.5.0 (metody status_code a retry_after na WebPushException).
  • Úklid vývojových nástrojů & CI:
    • Odstraněna redundantní závislost black z requirements-dev.txt, pyproject.toml a .github/workflows/ci.yml. Formátování i linting kompletně pokrývá rychlejší ruff.
    • Zjednodušeno workflow vydávání verzí na 1 PR a opraveno kódování diakritiky v PowerShellu v AGENTS.md.

  • Bezpečnost & ochrana Surprise Mode:
    • Implementována robustní ochrana proti SSRF a DoS při stahování metadat e-shopů a obrázků (validate_public_url, safe_requests_get, MAX_REDIRECTS = 4, MAX_HTML_BYTES = 2MB, MAX_IMAGE_BYTES = 10MB).
    • Ochrana proti Decompression Bomb (Pixel Flood) útokům (Image.MAX_IMAGE_PIXELS = 25M) a automatické odstraňování EXIF metadat ze všech nahrávaných obrázků (avatary, dárky, přílohy zpětné vazby).
    • Ochrana proti XSS escapováním uživatelského vstupu v template filtru highlight_search.
    • Zabezpečení Surprise Mode ve stavových zprávách při označení dárku za obdržený/vrácený a skrytí stavu rezervací na veřejných odkazech pro vlastníky a spoluvlastníky.
    • Ochrana soukromí: výběr spoluvlastníků a spolusprávců byl omezen výhradně na uživatele ze společných skupin s nápovědným tooltipem; opravena autorizační podmínka v detailu uživatele.
    • Hardening konfigurace: DEBUG=False ve výchozím nastavení, PostgreSQL port navázán výhradně na 127.0.0.1:5433, zakázán autoindex pro /static/ v Nginxu a doplněny limity velikosti requestů.
  • Výkon, N+1 dotazy & databázové indexy:
    • Odstraněny N+1 databázové dotazy v šablonovém filtru get_user_claim (využití v paměti přednačtených claims.all()).
    • Eliminovány redundantní dotazy v metodách modelů Wishlist.can_user_manage, ManagedProfile.can_user_manage a Group.get_categorized_wishlists.
    • Optimalizován pohled Přání ostatních (SharedWishlistsView) a agregované počítání aktivních položek u narozenin v kalendáři.
    • Řazení položek, sérií i kategorií v AJAX endpointech převedeno na hromadný bulk_update.
    • Přidány databázové indexy na klíčová pole modelů Wishlist, WishlistItem, Notification, Activity, UserFeedback a FeedbackMessage (migrace 0052).
  • Design System, Dark Mode & UI konzistence:
    • Odstraněno ~165 výskytů zakázané třídy text-muted a nahrazeno za sémantickou text-body-secondary.
    • Statické povrchy bg-light, bg-white a barva text-dark nahrazeny za adaptivní bg-body-tertiary, bg-body a text-body.
    • Všechna modální okna sjednocena na bázi layouts/base_modal.html.
    • Stavový odznak „Obdrženo“ (status="received") sjednocen na zelenou barvu v celé aplikaci.
    • Tlačítka rezervací sjednocena na ikony košíku (bi-cart-plus, bi-cart-x, bi-cart-fill) a propsána do DESIGN.md i /styleguide/.
  • Čistota kódu, odstranění mrtvého kódu & DRY:
    • Odstraněny nepoužívané knihovny django-crispy-forms a crispy-bootstrap5.
    • Smazány zastaralé soubory: darkovnik/views.py, nepotřebné dílčí šablony (_wishlist_header.html, _series_display_section.html), jednorázové skripty v scripts/, datadump.json, test_e2e_db.sqlite3 a staré statické soubory (sw.js, default_avatar_old.png).
    • Archiv zpětné vazby family-demo-feedback.md přesunut do dedikované složky feedback/.
    • Vyčleněny znovupoužitelné moduly darkovnik/utils/text_utils.py a darkovnik/utils/image_utils.py.
    • Čistý úbytek kódu: -2 504 řádků.
  • Post-Mortem & Systémová dokumentace:
    • Zjištěná pravidla bezpečnosti, výkonu a UI zanesena do AGENTS.md, .agents/skills/darkovnik-designer/SKILL.md, DESIGN.md, docs/DESIGN_SYSTEM.md, docs/ARCHITECTURE.md a README.md.
  • Automatizované testy:
    • Přidána nová testovací sada ComprehensiveAuditSecurityAndRefactorTests v darkovnik/tests.py (všech 295 unit testů a 13 Playwright E2E scénářů prochází).

  • Task-based reorganizace navigace (Podněty #75, #76):
    • Zjednodušeno uspořádání hlavního menu do intuitivní čtyřpoložkové hierarchie podle frekvence a toku úloh uživatele:
      1. ⭐ Můj seznam – přímý 1-click přístup do vlastního primárního seznamu přání (přejmenováno z matoucího „Moje přání“).
      2. 🎁 Přání ostatních – agregovaný přehled dárků a přání rodiny a přátel.
      3. 📑 Správa seznamů – rozcestník pro všechny vlastní seznamy, archiv Odložených položek a zakládání nových seznamů.
      4. 👥 Skupiny – správa sdílecích skupin.
    • Změna byla promítnuta jak do desktopového postranního panelu (_sidebar.html), tak do mobilního navigačního šuplíku (_mobile_nav.html).
  • Agregovaný přehled „Přání ostatních“ (Podnět #75):
    • Vytvořen nový pohled SharedWishlistsView (/shared-wishlists/) sdružující všechny seznamy sdílené s přihlášeným uživatelem.
    • Seznamy jsou uspořádány přehledně podle jednotlivých osob (včetně spravovaných a virtuálních profilů).
    • K dispozici je filtr podle konkrétních sdílených skupin a globální tlačítko pro sbalení/rozbalení všech karet najednou.
  • Unifikovaná komponenta karet osob a jejich seznamů (Podnět #76):
    • Vytvořena znovupoužitelná šablona _person_wishlists_card.html, která sjednotila dosud rozdílné pohledy v detailu skupiny (group_detail.html) a v Přáních ostatních.
    • Ve skupinách jsou karty ve výchozím stavu úsporně sbalené, v Přáních ostatních rozbalené.
    • Karty podporují plynulou CSS rotaci indikačního chevronu, náhledy položek s ikonou a cenou dárku (🎁 Kolo (12 000 CZK)), odznaky počtu položek a kategorie, zobrazení narozenin, správců a rychlý proklik na historii obdržených dárků.
    • Do vzorkovny (styleguide.html) přidána interaktivní sekce 10 demonstrující živou komponentu.
  • Řazení seznamů přání na stránce Správa seznamů (Podnět #58):
    • Do pohledu WishlistListView přidán rozbalovací volič řazení: podle poslední aktivity, podle názvu (A–Z), podle počtu aktivních přání a podle data vytvoření.
    • Zvolená preference řazení se perzistentně ukládá do uživatelské session.
  • Notifikace o uvolnění rezervace dárku (Podnět #77):
    • Při zrušení rezervace na seznamu sdíleném se skupinou je členům skupiny odeslána Web Push i perzistentní notifikace s informací, že dárek je opět volný k zamluvení.
    • Z historie nedávné aktivity (Activity) byly odstraněny matoucí zprávy o zrušení rezervace, aby nedocházelo ke zbytečnému zmatení uživatelů.
  • Opravy stability a robustnosti:
    • Ošetřena vlastnost is_public v modulu calendar_utils.py pro bezchybný výpočet nadcházejících narozenin.
    • V signálu create_or_update_user_profile zajištěno automatické vytvoření a označení výchozího aktivního seznamu jako primárního pro každého nového uživatele.
    • Ze šablony group_detail.html odstraněn zastaralý JavaScript manipulující s třídami ikon, který způsoboval protisměrnou rotaci chevronu při rozbalování karty.
  • Automatizované testy:
    • Do darkovnik/tests.py přidána testovací sada MenuRedesignAndSharedWishlistsTests pokrývající agregaci seznamů, filtrování skupin, řazení a notifikace.
    • Vytvořen nový Playwright E2E scénář tests_e2e/scenarios/test_menu_and_shared_wishlists.py ověřující průchod novým menu, interaktivitu akordeonů a přepínání záložek.

  • Hierarchie akcí návštěvníka na cizím wishlistu (Podnět #74):
    • Tlačítko „Zamluvit“ (resp. „Zrušit“ u vlastní rezervace nebo „Splním!“ u trvalých přání) je nyní hlavní a dominantní akcí na řádku dárku jak na mobilu, tak na desktopu.
    • Akce „Kopírovat do mého seznamu“ byla přesunuta do třítečkového rozbalovacího menu (...), což plně sjednocuje chování s modálním oknem detailu položky i se zobrazením pro vlastníka seznamu.
    • Na mobilních zařízeních formulář s tlačítkem „Zamluvit“ vyplňuje celou šířku řádku vedle 44px dotykového tlačítka nabídky, což návštěvníkovi poskytuje jasné a nezaměnitelné primární CTA.
  • Widget nadcházejících narozenin na Dashboardu (Podnět #66 – Fáze 1):
    • Vytvořen dedikovaný modul darkovnik/calendar_utils.py pro spolehlivý výpočet nejbližších narozenin (včetně bezpečného ošetření narozených 29. února v nepřestupných letech), českých tvarů odpočtu („Dnes! 🎉“, „Zítra“, „Pozítří“, „za X dní“) a věku oslavence.
    • Na Dashboardu (dashboard.html) do pravého sloupce přidán widget „Nadcházející narozeniny“, který agreguje členy sdílených skupin, spravované profily (např. děti) i přihlášeného uživatele na 30 dní dopředu s přímým proklikem na jejich seznam přání.
    • Implementována metoda Wishlist.get_absolute_url() pro standardizované a robustní odkazování na seznamy přání napříč moduly.
  • Automatizované testy (Unit + Playwright E2E):
    • Do darkovnik/tests.py doplněna testovací sada Podnet74AndBirthdayCalendarTests (výpočty dnů, přestupný rok, věk, filtrování skupin a integrace do pohledu).
    • Vytvořen nový Playwright E2E scénář tests_e2e/scenarios/test_visitor_actions_and_birthdays.py pokrývající chování akcí návštěvníka na mobilním i desktopovém viewportu a zobrazení narozeninového widgetu s proklikem na přání.

  • Zjednodušení popisků a zrušení tlačítka „Zobrazit více“ (Podnět #69):
    • Zrušeno nadbytečné tlačítko „Zobrazit více / méně“ u karet dárků v _item_list_row.html. Přání si zachovávají kompaktní třířádkový řez, přičemž plný text a všechny podrobnosti se zobrazují přímo v modálním okně detailu položky.
  • Přímá dostupnost historie oznámení (Podnět #70):
    • V desktopovém sidebaru (_sidebar.html) i mobilním menu (_mobile_nav.html) nahrazen problematický dropdown přímým navigačním odkazem na /notifications/ s odznakem nepřečtených zpráv.
    • V notifikačním dropdownu v navbaru na mobilu je odkaz na kompletní historii (/notifications/) dostupný vždy (i při 0 nových zprávách).
  • Přejmenování titulku úvodního panelu (Podnět #71):
    • Titulek stránky v dashboard_views.py změněn z „Můj Dárkovník Panel“ na přirozený a výstižný „Přehled“ (<title>Přehled | Dárkovník</title>).
  • Deep linking a automatické otevření modálu dárku (Podnět #72):
    • Do obalu položek v seznamech (_generic_list_item_wrapper.html a _item_condensed_row.html) doplněny kotevní identifikátory id="item-{{ item.pk }}".
    • V models.py doplněno připojování kotevního hashe #item-<pk> do odkazů v nedávné aktivitě (Activity.related_url) a notifikacích (Notification.get_absolute_url()).
    • V wishlist_detail.js odstraněna duplicita modálu a implementováno spolehlivé otevření modálu přes bootstrap.Modal.getOrCreateInstance: po prescrollování a rozbalení případně sbalené kategorie se po usazení layoutu automaticky otevře modální okno detailu položky.
  • Zřetelnější vizuální odlišení stavů rezervací pro návštěvníky (Podnět #73):
    • Vlastní rezervace: Dárek zamluvený přihlášeným uživatelem je výrazně odlišen zeleným rámečkem a podbarvením .item-card-claimed-by-me.border-success.border-2 spolu s novým odznakem „Zamluveno vámi“ (v plné kartě i zhuštěném řádku).
    • Cizí rezervace: Dárky zarezervované jinými uživateli jsou periferně ztlumeny třídou .item-card-claimed-by-other (opacita 0.72 s plynulým zesvětlením na hoveru) a označeny štítkem „Zamluveno: [Jméno]“, což usnadňuje orientaci v dosud volných přáních.
    • Surprise Mode invariant: Vlastník seznamu ani spoluvlastníci žádná zvýraznění rezervací nevidí – režim překvapení je striktně zachován.

  • Spravované profily a dětské seznamy přání (Podnět #50, #42):
    • Model ManagedProfile: evidence virtuálních profilů (jméno, datum narození, avatar) se zakladatelem (created_by) a spolusprávci (co_managers, např. oba rodiče). Připraveno pole claimed_user pro budoucí osamostatnění dítěte na plnohodnotný účet.
    • Spoluspráva profilů: všichni správci mají plný přístup ke správě seznamů a úpravě profilu dítěte.
    • Řízená výjimka ze Surprise Mode: správci na spravovaném seznamu vidí rezervace od příbuzných, aby se předešlo duplicitním nákupům v rodině. Ostatní příbuzní vidí standardní Surprise Mode.
    • Obousměrná rezervace pro správce („Koupím já“): rodiče mohou přímo na spravovaném seznamu dárky rezervovat a označit jako koupené pro ostatní členy rodiny.
    • Sjednocený výpis členů skupiny: spravované profily jsou plnohodnotně integrovány do akordeonu členů skupiny, seřazeny abecedně a označeny štítkem Spravovaný profil.
    • Tradiční potvrzovací modály: přidání i odebrání profilu ze skupiny a smazání profilu využívají standardní modální dialogy aplikace.
    • Volitelné datum narození pro všechny uživatele: rozšíření modelu UserProfile o pole birth_date.
  • Autoritativní specifikace DESIGN.md (#41):
    • Zavedení standardizované specifikace DESIGN.md pro konzistentní tvorbu designu a komponent v externích nástrojích a AI agentech.

  • Oprava sdílení a zobrazení skupin spoluvlastníkem (#68):
    • Opraveno předávání vlastníka (owner) do WishlistForm při úpravě seznamu spoluvlastníkem ve WishlistUpdateView a doplněn fallback na self.instance.owner přímo ve formuláři, díky čemuž spoluvlastník vidí a může spravovat skupiny sdílení vlastníka.
    • Do kontextu šablony při nevalidním formuláři (form_invalid / HTTP 400) doplněna chybějící proměnná wishlist_owner_username, čímž se předešlo selhání renderování modálu.
    • V global_scripts.js ošetřena re-inicializace chipů a multiselectu skupin (initGroupSharingChips) po dynamickém přepsání obsahu modálu validační chybou.
  • Perzistentní notifikace pro správce při registraci uživatele (#67):
    • V signálu notify_admins_on_new_registration doplněna tvorba perzistentních záznamů Notification pro všechny administrátory a personál (is_staff i is_superuser), takže upozornění na nově registrovaného uživatele čekajícího na schválení zůstává trvale dostupné v administrační liště.
    • Opraven klíč názvu v payloadu Web Push (title místo head) a prodlouženo TTL notifikace na 86 400 sekund (24 hodin).
    • V Service Workeru (sw.js) doplněn zpětně kompatibilní fallback data.title || data.head.
  • Zamezení nechtěného auto-výběru série při kliknutí mimo pole (#65):
    • Z konfigurace Select2 pro výběr sérií v wishlist_detail.js odstraněna volba selectOnClose: true, která způsobovala nežádoucí automatický výběr první nalezené série při pouhém zavření nabídky nebo kliknutí vedle a bránila smazání série z dárku.
  • Zařazení podnětu do roadmapy (#66):
    • Do aktivního backlogu v docs/ROADMAP.md přidán návrh na kalendář narozenin, jmenin, Vánoc a termínů oslav s widgetem na Dashboardu a možností exportu do iCal (.ics).
  • Architektonické principy a frontendové standardy:
    • Do docs/ARCHITECTURE.md zakotven princip perzistence notifikací (databázový model Notification jako autoritativní zdroj pravdy, Web Push jako pouhý transportní kanál) a pravidla pro AJAX modální formuláře (parita kontextu při form_invalid, re-inicializace komponent).
    • Do vývojového skillu darkovnik-designer doplněn životní cyklus AJAX modálů a zákaz selectOnClose: true u volitelných polí.

  • Oprava přepínače priority hvězdičky a formulářového modálu (#57):
    • Opravena chyba validace v WishlistItemForm.clean(), která při editaci položky s existujícím zrcadleným obrázkem vyvolávala falešnou chybu „Nahrajte soubor nebo zadejte URL, ne obojí“.
    • Při chybě validace formuláře v editačním modálu se modál nyní automaticky znovu otevře se zobrazením validačních chyb místo tichého selhání.
  • Primární seznam přání vždy na prvním místě (#58):
    • Ve WishlistListView i v JSON endpointu pro modál kopírování dárků (ajax_get_my_wishlists) je primární seznam přání uživatele vždy prioritně zařazen na první pozici před ostatními seznamy řazenými dle data vytvoření.
  • Oprava HTTP 405 při vracení obdrženého daru (#59):
    • V wishlist_detail.js doplněna obsluha modálu #unreceiveItemModal a předávání URL endpointu urls.itemUnreceiveBase, čímž byla odstraněna chyba HTTP 405 Method Not Allowed na /received-gifts/.
  • Spolehlivé ukládání kategorií a sérií na mobilních klávesnicích (#60):
    • Konfigurace Select2 rozšířena o selectOnClose: true, zachycení rozepsaného textu při select2:closing, ošetření klávesy Enter při select2:open a záchranu neuložených tagů před odesláním formuláře.
  • Responzivní úpravy Centra podpory a detailu tiketu (#63):
    • Na mobilních displejích pod 576px zkráceny popisky záložek v Centru podpory („Fronta“, „Moje podněty“) a nastaveno flex-nowrap, aby se záložky nezalamovaly pod sebe.
    • Horní navigační lišta v detailu tiketu upravena na responzivní zkrácené popisky tlačítek akcí („Zpět“, „Vyřešit“, ikony bez textu pro export a administraci), aby se vešla do jednoho řádku.
  • Odstranění nesouladu počtu tiketů ve frontě personálu (#64):
    • Do nabídky filtrů v Centru podpory přidán filtr „K vyřízení“ s červeným odznakem přesně odpovídajícím počtu podnětů vyžadujících pozornost personálu (staff_attention_count), čímž se vyjasnil rozdíl oproti filtru „Otevřené“.
    • Na modelu UserFeedback přidány metody needs_attention_for_admin() a needs_attention_for_user().
  • Textové popisky pro editaci popisu kategorie a série na desktopu:
    • U tlačítek pro editaci poznámky kategorie (_category_header.html) a úpravu série (_unified_item_list_display.html) doplněn responzivní textový popisek „Upravit popis“ pro obrazovky sm a větší (d-none d-sm-inline), čímž byl sjednocen vzhled se sousedními tlačítky „Přidat do kategorie“ a „Přidat do série“. Na mobilu zůstává zachována úsporná kompaktní ikonka.

  • Centrum podpory a správa tiketů pro uživatele (#51):
    • Vytvořena dedikovaná stránka /podpora/ (SupportCenterView) s přehledem všech odeslaných hlášení a podnětů přihlášeného uživatele.
    • Zobrazení souhrnných počítadel (všechny, otevřené, vyřešené) a dynamického filtrování pomocí pill tlačítek.
    • Karty podnětů zobrazují typ (chyba, nápad, dotaz), stav (nové, v řešení, vyřešeno), počet zpráv v diskuzi, indikátor přílohy a pulzující badge při nepřečtené odpovědi od personálu.
  • Oboustranná konverzační vlákna (FeedbackMessage):
    • Zaveden model FeedbackMessage pro vedení diskuzního vlákna mezi autorem podnětu a administrátory.
    • Detail tiketu /podpora/<id>/ (SupportTicketDetailView) s moderním chatovým rozhraním a vizuálním odlišením personálu (Tým Dárkovníku) a běžného uživatele.
    • Striktní bezpečnostní kontrola: tikety jsou soukromé, přístupné výhradně autorovi a personálu (is_staff / is_superuser), neautorizovaný přístup je odmítnut kódem 403.
    • Možnost uživatele jedním kliknutím označit podnět jako vyřešený nebo znovu otevřít.
    • Automatické znovuotevření: pokud uživatel napíše novou odpověď do vyřešeného tiketu, podnět se automaticky přepne do stavu „V řešení“.
  • Oboustranné Web Push a interní notifikace:
    • Model Notification rozšířen o vazbu related_feedback s přímým přesměrováním do detailu konverzace v get_absolute_url().
    • Pokud personál odpoví uživateli, uživateli je doručena interní notifikace i Web Push do mobilu/prohlížeče.
    • Pokud uživatel reaguje na podnět, personál obdrží notifikaci a Web Push upozornění.
    • Automatické označování zpráv jako přečtené při otevření detailu tiketu.
  • Podpora snímků obrazovky (Ctrl+V) a diagnostika zařízení:
    • Modál zpětné vazby i formulář v detailu tiketu podporují přikládání obrázků/screenshotů i bleskové vložení ze schránky pomocí klávesové zkratky Ctrl+V s okamžitým náhledem.
    • Automatické zaznamenání technické diagnostiky klienta (viewport, rozlišení obrazovky, dark mode, user agent) v poli UserFeedback.device_info pro snazší reprodukci chyb.
  • Integrace do administračního dashboardu a AI exporty:
    • Administrační dashboard (CustomAdminDashboardView) rozšířen o rozbalovací náhled konverzačních vláken a formulář pro přímou odpověď personálu přes AJAX bez opuštění moderace.
    • Zobrazení přiložených screenshotů a diagnostiky zařízení přímo na kartě podnětu.
    • Exporty do Markdownu i JSONu (feedback_utils.py) obohaceny o kompletní historii konverzace, diagnostiku a URL příloh pro maximální kontext při triage a analýze pomocí AI asistentů.
  • Hybridní nalezitelnost v navigaci:
    • V bočním postranním panelu i mobilním vysouvacím menu přidán přímý odkaz „Zpětná vazba a podpora“ s živým červeným odznakem nepřečtených odpovědí od administrátorů.
    • V profilu uživatele (/profile/edit/) vytvořena dedikovaná informační karta pro rychlý přechod do Centra podpory nebo odeslání nového hlášení.
  • Automatizované testy:
    • Vytvořena testovací třída SupportCenterAndConversationsTests (6 testů) pokrývající přehled v Centru podpory, přístupová práva a soukromí tiketů, oboustranný tok zpráv a notifikací, automatické znovuotevření při odpovědi, upload screenshotů s diagnostikou i generování rozšířených AI exportů.

  • Plochý režim wishlistu bez kategorií (#44):
    • Přidána volba show_categories na modelu Wishlist (výchozí True), konfigurovatelná v modálním okně úpravy seznamu (_wishlist_form_content.html).
    • Pokud je vypnuto, detail seznamu (jak pro přihlášeného správce, tak pro veřejné návštěvníky) vykresluje všechny položky v jednom souvislém seznamu bez hlaviček kategorií, přičemž bloky sérií (ItemSeries) zůstávají vizuálně i funkčně zachovány.
  • Vlastní pořadí kategorií na seznamu přání (#24):
    • Vytvořen model WishlistCategoryConfig pro ukládání pořadí a konfigurace kategorií specificky pro každý seznam přání.
    • Režim úpravy pořadí (reorderModeBar) rozšířen o podporu přetahování celých sekcí kategorií (.sortable-category-section) pomocí SortableJS a dotykových šipek (▲/▼), přičemž sekce „Nekategorizované“ zůstává trvale ukotvena na konci seznamu.
    • Přidán zabezpečený AJAX endpoint /ajax/reorder-categories/ ukládající nové pořadí kategorií pro vlastníka a spoluvlastníky seznamu.
  • Konfigurovatelná sekce preferencí a poznámek (#38):
    • Přidána pole show_preferences (výchozí True) a preferences_title na modelu Wishlist.
    • Vlastník nebo spoluvlastník může sekci preferencí zcela skrýt nebo jí nastavit vlastní název (např. „Důležité velikosti a oblíbené značky“) s bezpečným fallbackem na výchozí „Obecné preference a poznámky“.
  • Obecné poznámky pro kategorie a série s podporou Markdownu (#36):
    • Kategoriím lze na konkrétním seznamu přiřadit obecnou poznámku (WishlistCategoryConfig.note), která se zobrazuje v záhlaví kategorie a edituje se přes rychlé modální okno (#editCategoryNoteModal) s nápovědou pro Markdown syntaxi.
    • Model ItemSeries rozšířen o pole description s metodou get_description_html(). Správci mohou sérii upravit přímo z jejího záhlaví přes tlačítko tužky a modální okno (#editSeriesModal).
    • Popisky kategorií i sérií se dynamicky aktualizují přes AJAX bez nutnosti reloadu stránky.
  • Pamatování sbalení kategorií v prohlížeči (UX):
    • Stav sbalení/rozbalení každé kategorie se nyní ukládá do localStorage (klíč darkovnik_cat_collapse_<wishlist_id>_<cat_id>), stejně jako u sekce preferencí. Při návratu na seznam zůstávají sbalené kategorie sbalené.
  • Automatizované testy:
    • Vytvořena komplexní testovací třída WishlistCategoriesAndDetailTests (6 testů) pokrývající plochý režim, viditelnost a vlastní titulek preferencí, změnu pořadí kategorií, poznámky ke kategoriím a sériím s Markdownem i kontrolu přístupových práv (vlastník, spoluvlastník, neautorizovaný uživatel).

  • Koncept primárního (výchozího) seznamu přání (#55):
    • Přidána vazba UserProfile.primary_wishlist s bezpečným fallbackem na nejstarší aktivní seznam uživatele (UserProfile.get_primary_wishlist()).
    • Možnost nastavit primární seznam přímo z přehledu seznamů (hvězdička), z detailu seznamu, v modálním okně úpravy seznamu (WishlistForm.set_as_primary) i v profilu uživatele (UserProfileEditForm.primary_wishlist).
    • Implementován endpoint a rychlý odkaz /wishlists/my-primary/, který automaticky přesměruje na detail primárního seznamu.
  • Redesign přehledu seznamů přání na responzivní mřížku karet (#55):
    • Přehled /wishlists/ přepracován do moderního card gridu s vizuálním odlišením primárního seznamu (zlatý odznak a hvězdička).
    • Karty zobrazují statistiky aktivních i splněných přání (s přísným dodržením invariantu Surprise Mode – vlastník vidí pouze přání jím označená jako obdržená).
    • Přidán překryvný avatar stack spoluvlastníků s počítadlem přebývajících uživatelů a rychlé akce (otevřít, upravit, smazat).
  • Nový Dashboard s prominentním Hero widgetem (#48):
    • Horní část dashboardu nyní dominuje „Hero widget“ pro primární seznam přání: obsahuje souhrnné statistiky, rychlá tlačítka pro otevření či přidání přání a vizuální pás miniatur s cenami a prioritami.
    • Ostatní seznamy přání jsou přehledně umístěny v kompaktní mřížce karet pod Hero widgetem.
    • Zachován přehled nových přání od přátel z propojených skupin.
  • Zjednodušení navigace a chytré předvybírání:
    • Do postranního panelu i mobilního navigačního menu přidán přímý skok „Moje přání“ vedle „Všechny seznamy“.
    • Modální okno rychlého přidání přání (quickAddItemModal) automaticky předvybírá primární seznam uživatele.
  • Automatizované testy:
    • Vytvořena komplexní testovací třída PrimaryWishlistAndDashboardTests (8 testů) ověřující fallback primárního seznamu, POST a AJAX nastavení, oprávnění (zákaz nastavení cizího seznamu), přesměrování /wishlists/my-primary/, vykreslení nového přehledu seznamů a Hero widgetu na dashboardu.

  • Zprovoznění zobrazení položek a přepínače v odkladišti (#52):
    • Opraveno předávání položek do unifikované komponenty _unified_item_list_display.html (items_not_in_series=archived_items), kde dříve chyběl parametr a odkladiště vždy zobrazovalo prázdný stav.
    • V ItemPoolView zavedena obsluha aktivního pohledu current_view, identifikátoru cíle target_id a HTMX odpověď přes nově vytvořený partial _item_pool_partial.html s out-of-band aktualizací přepínače.
    • Do item_pool.html doplněno načítání skriptu wishlist_detail.js pro plnou funkčnost modálních oken obnovení a smazání položek.
  • Automatické otevírání odkazů z Markdown preferencí v novém okně (#56):
    • Do konfigurace procesoru markdown2 v Wishlist.get_general_preferences_html() přidáno rozšíření target-blank-links. Všechny odkazy v obecných preferencích seznamu se nyní otevírají v novém panelu (target="_blank") s bezpečným rel="nofollow noopener".
  • Asistence a auto-formátování odrážek při psaní Markdownu (#54):
    • Do global_scripts.js implementován znovupoužitelný handler initMarkdownAutoListAssist naslouchající na klávesu Enter v Markdown textareyích.
    • Automaticky pokračuje v odrážkových seznamech (-, *), číslovaných seznamech (1. -> 2.) a úkolových checkboch (- [ ]) se zachováním odsazení.
    • Stisk klávesy Enter na prázdné odrážce seznam automaticky ukončí a odrážku smaže.
  • Třídění podnětů (Triage):
    • Podnět #55 (atraktivnější mřížka přehledu seznamů a koncept primárního seznamu) zapsán a rozpracován v docs/ROADMAP.md.
  • Automatizované testy:
    • Vytvořena testovací třída FeedbackBatchPoolAndMarkdownTests (4 testy) ověřující zobrazení archivovaných položek v odkladišti, prázdný stav, HTMX přepínání pohledů a generování target="_blank" pro Markdown odkazy.

  • Kontextový export a kopírování pro AI (#53):
    • Exportní rozbalovací nabídka v administraci nyní dynamicky přizpůsobuje první volbu aktivnímu filtru stavu (Nové podněty, Podněty v řešení, Vyřešené podněty).
    • Tlačítko „Kopírovat pro AI“ respektuje právě vybraný stav v záložkách (např. při přepnutí na „V řešení“ zkopíruje pouze rozpracované podněty).
    • Přidána podpora pro rozsah scope=resolved (Vyřešené podněty) do backendového exportéru i formátovače Markdownu.
    • Zpětná kompatibilita a možnost exportovat „Všechny podněty“ i kombinované „Aktivní podněty (nové + v řešení)“ zůstávají zachovány.
  • Automatizované testy:
    • Rozšířena testovací třída FeedbackWorkflowFiltersTests o ověření exportu vyřešených podnětů a dynamických odkazů v administraci dle aktivního filtru.

  • Filtrování zpětné vazby dle stavů v administraci (#53):
    • Přidána dedikovaná záložka a filtr pro stav V řešení (?status_filter=in_progress#feedback-section) s dynamickým počitadlem rozpracovaných podnětů.
    • Původní záložka „Aktivní“ přejmenována na Nové (?status_filter=new#feedback-section) a nastavena jako výchozí pohled, který zobrazuje čistě nově nahlášené a neřešené podněty.
    • Zachována plná zpětná kompatibilita pro parametr ?status_filter=active, který i nadále sdružuje nové i rozpracované tikety.
  • Plynulé přechody mezi stavy v UI administrace:
    • Na kartách podnětů v záložce „Nové“ lze podnět posunout do „V řešení“ i rovnou označit jako „Vyřešeno“.
    • U rozpracovaných podnětů („V řešení“) doplněna možnost označit za „Vyřešeno“ nebo vrátit „Do nových“.
    • AJAX endpoint ajax_update_feedback_status nyní v odpovědi vrací i previous_status, díky čemuž se dynamicky a přesně aktualizují odznaky s počty na všech záložkách i v záhlaví.
    • Změna stavu plynule odebere kartu z neplatného filtru (s animací fade-out) nebo aktualizuje její odznak a akční tlačítka přímo na místě bez nutnosti reloadu stránky.
  • Rozšíření exportu podnětů:
    • Endpoint admin_export_feedback i formátovač feedback_utils.py rozšířeny o podporu rozsahů scope=new a scope=in_progress pro Markdown i JSON formát.
  • Automatizované testy:
    • Vytvořena testovací třída FeedbackWorkflowFiltersTests ověřující výchozí filtr new, filtry in_progress, resolved, all, zpětnou kompatibilitu active, návrat previous_status z AJAXu a export nových i rozpracovaných podnětů.

  • Zabezpečení madel řazení sérií pro cizí návštěvníky (#49):
    • V šabloně _unified_item_list_display.html zabaleno madlo .handle-series, ikona bi-grip-vertical i třída .sortable-series do autorizační kontroly pro vlastníka a spoluvlastníky seznamu. Běžní návštěvníci již nemají možnost se sérií manipulovat.
  • Vycentrování ikony plus u kategorií v mobilním zobrazení (#47):
    • V šablonách _category_header.html a _unified_item_list_display.html nahrazen statický pravý margin me-1 responzivním me-sm-1 a tlačítko doplněno o flex centrování, čímž je zaručeno dokonalé zarovnání ikony při skrytí textu na mobilních zařízeních.
  • Oprava přetékání dlouhých textů v kompaktním seznamu (#45):
    • Do custom.css doplněna chybějící pomocná třída .min-w-0 a flexibilní kontejner řádku v _item_condensed_row.html upraven pro korektní smršťování. Dlouhé texty se nyní spolehlivě zkracují elipsou (text-truncate) a plný text je dostupný přes nativní tooltip title.
  • Zprovoznění přepínání zobrazení (Seznam / Kompaktní) v přehledech a kategoriích (#43):
    • V GroupCategoryDetailView i v UserActivityBaseView (rezervace, nákupy, darované a obdržené dárky) doplněny chybějící šablony řádků (item_list_row_wrapper_template, item_condensed_row_wrapper_template) a hlavičkové prefixy do kontextu pohledů.
    • Do _grouped_item_list_partial.html zaveden out-of-band swap (hx-swap-oob) pro ovládací tlačítka view-toggle-buttons, což zajišťuje okamžitou synchronizaci aktivního stavu přepínače po kliknutí.
  • Vyjasnění sekce nově přidaných přání na dashboardu (#48):
    • Karusel v dashboard.html přejmenován z matoucího „Inspirace od přátel“ na srozumitelné „Nová přání od přátel“ s vysvětlujícím podtitulkem „Nedávno přidaná přání ve vašich společných skupinách“.
  • Automatizované testy:
    • Přidána dedikovaná testovací třída FeedbackBatchTriage20260928Tests (6 testů) pokrývající oprávnění řazení sérií, responzivní tlačítko kategorie, HTMX přepínání zobrazení na kategorii i aktivitách a aktualizovaný nadpis na dashboardu.

  • Zavedení štíhlého kořenového kontraktu AGENTS.md:
    • Nahrazení robustního GEMINI.md standardizovaným a lehkým souborem AGENTS.md v souladu se standardem project-bootstrap.
    • Přesné vymezení příkazů toolchainu (Docker testy, migrace, linter přes uvx), doménových invariantů (Surprise Mode, spoluvlastníci, čeština) a git workflow.
  • Extrakce specializovaných skillů (Progressive Disclosure):
    • Vytvořen dedikovaný projektový skill .agents/skills/darkovnik-triage/SKILL.md pro systematické vyhodnocování a třídění zpětné vazby.
    • Aktualizován skill .agents/skills/darkovnik-designer/SKILL.md pro práci s novým kontraktem AGENTS.md.
  • Zabezpečení a čistota repozitáře:
    • Rozšířen .gitignore o masky .env.*, *.pem, *.key.
    • Vyčištěny zastaralé kořenové soubory scratch.py a djlint_report.txt.
  • CI/CD Deployment:
    • Automatické nasazení na VPS v deploy.yml rozšířeno o triggerování na releasové tagy v*.

  • Pokročilá extrakce metadat (JSON-LD Schema.org & OpenGraph) (#42):
    • Vytvořen samostatný robustní modul darkovnik/utils/metadata.py pro extrakci strukturovaných dat z e-shopů.
    • Podpora schema.org/Product v JSON-LD (application/ld+json), včetně struktur @graph, extrakce čistého názvu (eliminace SEO balastu jako | Alza.cz), nabídky (offers -> price, priceCurrency) s podporou měn (CZK, EUR, USD, GBP).
    • Vícestupňový fallback na OpenGraph (og:title, og:image, og:price:amount, og:price:currency), Twitter Cards (twitter:image, twitter:title) a textové cenové regexy.
    • Zpracování kandidátních obrázků (image_candidates): inteligentní filtrace SVG ikon, trackerů, log a rozměrů menších než 80px, normalizace relativních URL na absolutní.
  • Interaktivní výběr obrázků a asistence v modalu přání (#41):
    • Vytvořena znovupoužitelná šablona _item_metadata_fetcher.html zařazená do modalu přidání (_item_form_modal.html), dynamického obsahu přidání (_item_add_form_content.html) i úpravy přání (_item_edit_form_content.html).
    • Karta živého náhledu: Zobrazení vybraného obrázku produktu s tlačítky pro rychlé oříznutí přes Cropper 1:1 a odebrání obrázku.
    • Pás miniatur (Thumbnail Strip): Horizontálně posuvný pás nalezených fotek z e-shopu. Kliknutím na jakoukoliv miniaturu se okamžitě přepne aktivní obrázek a propíše do formuláře.
    • Asistence pro chráněné e-shopy (např. Alza.cz): Automatické rozpoznání Cloudflare bot ochrany / HTTP 403 a zobrazení přívětivého asistenčního boxu s návodem na ruční zkopírování názvu a bleskové vložení obrázku.
  • Vkládání obrázků ze schránky (Ctrl+V) a Drag & Drop:
    • Odkudkoliv v otevřeném modalu přání lze stisknout Ctrl+V se zkopírovaným obrázkem z libovolného webu – obrázek se okamžitě načte do náhledu a připraví k uložení přes DataTransfer.
    • Podpora přetažení obrázku myší (Drag & Drop) přímo do náhledové zóny s vizuálním indikátorem.
  • Zrcadlení a optimalizace obrázků na serveru (Mirroring):
    • V metodě WishlistItem.save() se při uložení externího odkazu na obrázek (image_url) soubor bezpečně stáhne, optimalizuje přes Pillow (max 1200x1200px JPEG) a uloží lokálně do image_upload. Tím je zaručeno, že obrázek dárku nikdy nezmizí ani při vymazání e-shopem či blokaci hotlinkingu.
  • Automatizované testy:
    • Přidána dedikovaná testovací třída URLMetadataAndImagePickerTests (9 unit testů) pokrývající parsování JSON-LD, kandidátní obrázky, detekci Cloudflare, zmenšování přes Pillow, AJAX view a modelové zrcadlení. Všech 209 integračních testů prochází.

  • Sjednocení tlačítka pro výběr kategorie v detailu skupiny (#39):
    • Tlačítko dropdown-toggle pro výběr kategorií v group_detail.html doplněno o třídu rounded-pill px-3 (překonání globální výjimky :not(.dropdown-toggle) v custom.css), takže vizuálně ladí se všemi sousedními akčními tlačítky.
    • Zpřehledněna komunikace: popisek změněn z vágního „Kategorie“ na konkrétní „Přání dle kategorií“ s vysvětlujícím tooltipem title="Zobrazit přání členů rozdělená podle kategorií".
    • Položky v dropdownu doplněny o ikonku bi-tag a adaptivní ohraničení border border-secondary-subtle.
  • Redesign a vyčištění bloku veřejného sdílení obdržených dárků (#40):
    • Odstraněno nehezké dvojité vnořené podbarvení (bg-body-secondary border border-secondary-subtle) z _public_gift_link_management.html.
    • Blok v received_gifts_list.html a profile_edit.html přestylován na čistou moderní kartu se stínem, zaoblením rounded-4 a sémantickou hlavičkou s ikonou bi-share.
    • Input group sjednocen na plnou standardní výšku a čisté napojení (stejný vzor jako v modalu úpravy přání).
    • V custom.css doplněno pravidlo pro symetrický rádius 1rem pro .input-group > .form-control:first-child a .form-select:first-child, aby tlačítka na konci nepůsobila jako asymetrická „polopilulka“.
    • Funkce copyToClipboard() v global_scripts.js obohacena o vizuální inline feedback (změna na zelené „Zkopírováno!“ na 2 sekundy) namísto obtěžujícího systémového alert().
  • Automatizované testy:
    • Do testovací sady přidána nová třída FeedbackBatch58Tests ověřující pilulkový tvar tlačítka kategorií a čistý input-group veřejného odkazu. Všech 200 integračních testů prochází.

  • Oprava URL Metadata Fetcheru v modalech pro přidání a úpravu přání:
    • V šablonách _item_add_form_content.html, _item_edit_form_content.html a _item_form_modal.html byl nahrazen starý d-flex kontejner s bg-light-subtle sjednocenou .input-group a sémantickým pozadím .bg-body-tertiary.rounded-3.border.
    • Odstraněna vizuální vada rozpadlých zaoblení pilulky a mezery mezi polem a akčním tlačítkem (dle specifikace vzorkovny /styleguide/).
    • Opraveno vyhledávání rodičovské .input-group v wishlist_detail.js pro dynamické vkládání indikátoru načítání metadat.
  • Plošná migrace na _avatar.html:
    • Dashboard (dashboard.html): Karusel Inspirace od přátel, karta Nezapomeňte koupit i časová osa Nedávná aktivita nyní používají typizovaný _avatar.html (velikost sm).
    • Detail skupiny (group_detail.html): Seznam členů v akordeonu migrován na _avatar.html (velikost md) s parametrem group=group pro automatickou resoluci skupinové přezdívky.
    • Administrace podnětů (admin/dashboard.html): Karty zpětné vazby migrovány na _avatar.html (velikost sm).
    • Uživatelé (user_list.html): Karty v přehledu ostatních uživatelů migrovány na _avatar.html (velikost lg).
    • Navigace (_sidebar.html, _mobile_nav.html): Avatar přihlášeného uživatele v patičce sidebaru a v hlavičce mobilního menu migrován na _avatar.html.
    • Záhlaví seznamů (_wishlist_header.html, wishlist_detail.html): Avatar stack vlastníka a spoluvlastníků sjednocen přes _avatar.html s třídou avatar-stack-item.
    • Modál přidání člena do skupiny (_group_add_member_modal.html): Seznam výběru uživatelů migrován na _avatar.html.
  • Plošná migrace na _badge_priority.html a _badge_status.html:
    • Nahrazeny ruční <span> odznaky s nekontrastními barvami (bg-info text-dark, bg-warning text-dark, bg-secondary) v _item_condensed_row.html, _item_detail_content.html, dashboard.html a wishlist_list.html za sémantické komponenty.
    • Garance 100% kontrastu a souladu s WCAG AA v tmavém i světlém režimu díky adaptivním třídám -subtle / -emphasis.
  • Plošná migrace na _empty_state.html:
    • Komponenta _empty_state.html rozšířena o volitelný parametr action_extra_attrs umožňující bezpečné předávání HTML/HTMX atributů (např. hx-get, hx-target).
    • Holé texty a alert-info rámečky nahrazeny reprezentativním prázdným stavem s ikonou v kruhu a CTA tlačítky na:
      • Dashboardu (Moje seznamy, Moje skupiny, Časová osa nedávné aktivity).
      • Seznamu přání (wishlist_list.html) i seznamu skupin (group_list.html).
      • Centrálních položkových pohledech (_wishlist_detail_items.html, _unified_item_list_display.html, _grouped_item_list_partial.html).
      • Seznamu notifikací (notification_list.html), kde byla navíc odstraněna nevhodná třída bg-light-subtle.
      • Seznamu uživatelů (user_list.html) a detailu skupiny bez dalších členů (group_detail.html).
      • Administraci zpětné vazby (admin/dashboard.html) při zachování selektoru pro JS dynamiku.
  • Automatizované testy:
    • Do StyleguideAndDesignSystemTests v darkovnik/tests.py přidány testy pro action_extra_attrs v _empty_state.html a ověření .input-group struktury a adaptivního pozadí v modalech přání. Všech 9 testů prošlo úspěšně.

  • Komplexní grafický manuál (docs/DESIGN_SYSTEM.md):
    • Detailní specifikace vizuálního jazyka Dárkovníku: principy čistého rozhraní, nativní podpora Dark/Light módu s WCAG AA kontrastem, tokeny barev, typografická stupnice Bootstrap 5.
    • Přesná definice tvarů, rádiusů (pilulková tlačítka, měkké karty 1.25rem) a sémantických stínů pro oba režimy.
    • Závazný ikonografický kánon pro přiřazení Bootstrap ikon k jednotlivým entitám a uživatelským akcím.
  • Živá vzorkovna komponent (Living Styleguide - /styleguide/):
    • Vytvořeno dedikované view StyleguideView a responzivní šablona styleguide.html.
    • Přístup řízen přes is_staff nebo DEBUG=True, odkaz zařazen do boční i mobilní navigace.
    • Interaktivní živý přepínač režimů (Světlý / Tmavý) pro okamžité vizuální testování a porovnávání kontrastů v reálném čase.
    • Interaktivní ukázky barev, typografie, pilulkových tlačítek, segmented control filtrů, avatarů, odznaků, plných i zkrácených karet dárků, formulářových prvků, prázdných stavů i tabulky ikon.
  • Znovupoužitelné mikro-komponenty (darkovnik/templates/darkovnik/includes/components/):
    • _avatar.html: Jednotný avatar s 5stupňovou velikostní škálou (xs, sm, md, lg, xl), fallbackem na bezpečné URL / iniciálu a adaptivním ohraničením.
    • _badge_priority.html: Unifikovaný odznak pro prioritní (hvězdičková) přání s volitelným popiskem.
    • _badge_status.html: Sémantické stavové odznáčky (rezervováno, koupeno, trvalé, obdrženo, odložené, spoluvlastněné) s jemným podbarvením a garancí čitelnosti v tmavém režimu.
    • _empty_state.html: Standardizovaný kontejner prázdného stavu s ikonou v kruhu, nadpisem, popiskem a primárním/sekundárním akčním tlačítkem.
  • Úpravy stylů & CSS čištění (custom.css, _sidebar.html):
    • Zavedeny standardizované CSS utility pro avatary (.avatar, .avatar-xs až .avatar-xl), prázdné stavy (.empty-state-*) a ukázkové bloky vzorkovny.
    • Přesunuty inline styly desktopové navigace <aside> do třídy .sidebar-nav v custom.css.
  • Projektová pravidla a architektura (GEMINI.md, docs/ARCHITECTURE.md):
    • Pravidla rozšířena o požadavek přednostního využívání typizovaných komponent a dodržování ikonografického kánonu.
    • Architektura doplněna o novou vrstvu komponent a styleguide view.
  • Oprava spojených tlačítek ve vstupních skupinách (.input-group):
    • Vyřešen konflikt mezi globálním pilulkovým pravidlem pro tlačítka (border-radius: 50rem !important) a vstupními poli v .input-group.
    • Definována harmonická pravidla pro .input-group > .btn a .input-group-text s vnějším rádiusem 1rem !important a plochými vnitřními spoji.
    • Ošetřena tlačítka načítání metadat z URL, kopírování veřejných odkazů a výběru měny v modálech i na celém webu.
  • Automatizované testy:
    • Do tests.py přidána testovací sada StyleguideAndDesignSystemTests ověřující oprávnění pro staff/DEBUG, blokování pro běžné uživatele v produkci a správné renderování všech nově vytvořených šablonových komponent.

  • Karusel „Inspirace od přátel“ na dashboardu:
    • V dashboard_views.py upraven queryset recently_added_items: položky na seznamech, kde je uživatel spoluvlastníkem (wishlist__co_owners=user), nebo které uživatel sám přidal (added_by=user), jsou nyní řádně vyloučeny.
    • V šabloně dashboard.html nahrazen natvrdo použitý avatar a jméno vlastníka seznamu dynamickým autorem: {% with adder=item.added_by|default:item.wishlist.owner %}.
    • Okraj avataru byl upraven z nepružného border-white na adaptivní sémantickou třídu border-body (respektující světlý i tmavý režim).
  • Karta „Nezapomeňte koupit“ na dashboardu:
    • V dashboard.html u rezervovaných položek ze sdíleného seznamu se nově zobrazuje avatar a popisek osoby, která si věc skutečně přála (claim.item.added_by|default:claim.item.wishlist.owner), nikoliv genericky vlastník seznamu.
    • V dashboard_views.py doplněna prefetch optimalizace item__added_by a item__added_by__profile.
  • Důsledná ochrana Režimu překvapení (Surprise Mode) pro spoluvlastníky:
    • Notifikace (signals.py): V signálu create_notifications_from_activity doplněno přeskočení rozesílání notifikace o rezervaci (new_claim) i pro všechny spoluvlastníky seznamu (wishlist.co_owners). Spoluvlastníci tak již nedostávají spoilery o tom, kdo na jejich sdíleném seznamu co zamluvil.
    • Aktivita na dashboardu (dashboard_views.py): V cyklu aktivit se zprávy new_claim nyní spolehlivě filtrují pryč nejen pro vlastníka, ale i pro spoluvlastníky (user in wishlist.co_owners.all()).
    • Uživatelská oznámení (user_views.py): V UserNotificationsView.get_queryset() rozšířeno vyloučení zpráv o rezervacích i na položky, kde je přihlášený uživatel spoluvlastníkem seznamu.
    • Kompaktní řádek položky (_item_condensed_row.html): Doplněna podmínka request.user not in wishlist.co_owners.all, aby se spoluvlastníkům v kompaktním režimu nezobrazoval odznak „Zamluveno“.
  • Zobrazení kategorií skupin a seskupování dat:
    • Ve view_utils.py v pomocné funkci group_items_by_owner_and_wishlist() opraveno určování autora z pevného wishlist.owner na getattr(wishlist_item, "added_by", None) or wishlist_item.wishlist.owner.
    • V šabloně _grouped_item_section_renderer.html nahrazen surový {{ user_obj.username }} za {{ user_obj|display_name }}.
    • V _item_list_row.html upraven popisek přeje si ... na skutečného autora přání (wisher=item.added_by|default:wishlist.owner).
    • V GroupCategoryDetailView.get_queryset() přidáno načítání added_by a souvisejících profilů pro prevenci N+1 dotazů.
  • Detail položky (Modál):
    • V _item_detail_content.html v sekci časových razítek a metadat doplněno explicitní zobrazení, kdo položku přidal (• Přidal/a: vy / • Přidal/a: Jméno).
  • Archivace a obnova položek spoluvlastníkem:
    • V archive_item_view se archivovaná položka ukládá do odkladiště (item_pool) toho uživatele, který položku přidal (item.added_by or owner), namísto automatického uložení k vlastníkovi seznamu.
    • V restore_item_view umožněna obnova položky z odkladiště i do sdílených seznamů, kde je uživatel spoluvlastníkem (Q(owner=owner) | Q(co_owners=owner)).
  • Zpřesnění a neutralizace notifikačních zpráv:
    • V models.py v Activity.get_activity_html se u new_claim uplatňuje claim.item.added_by or claim.item.wishlist.owner.
    • V signals.py při smazání položky a v item_views.py při úpravě položky nahrazeny zavádějící zprávy formátu Vlastník ({owner.username}) smazal/upravil... neutrálními, lokalizovanými zprávami uvádějícími název seznamu.
  • Automatizované testy:
    • Do CoOwnerAndOrderingFeedbackTests doplněna komplexní sada testů:
      1. Ověření správného avatara/jména v karuselu Inspirace a vyloučení vlastních položek i položek sdíleného seznamu.
      2. Ověření zobrazení added_by jako obdarovaného v „Nezapomeňte koupit“.
      3. Ověření ochrany Surprise Mode pro spoluvlastníky (žádné notifikace, skrytí v aktivitách, skrytí badge v kompaktním pohledu).
      4. Ověření seskupování a popisků v detailu kategorie skupiny podle added_by.
      5. Ověření zobrazení autora v modálu detailu přání.
      6. Ověření přesunu do správného odkladiště při archivaci a obnovy do sdíleného seznamu spoluvlastníkem.

  • Sjednocení terminologie (Přihlašovací jméno vs. Zobrazované jméno):
    • V celé aplikaci (přihlašovací stránka login.html, registrační stránka signup.html, formulář editace profilu profile_edit.html) byl pojem „Uživatelské jméno“ konzistentně nahrazen jednoznačným termínem „Přihlašovací jméno“.
    • Tím je odstraněna nejednoznačnost mezi technickým, unikátním login identifikátorem a volitelným zobrazovaným jménem, pod kterým uživatele vidí ostatní členové komunity a skupin.
  • Zobrazované jméno přímo v registračním formuláři:
    • Do CustomUserCreationForm přidáno nepovinné pole display_name s vysvětlující nápovědou a názorným placeholderem (např. Děda Pepa).
    • Pole jsou seřazena intuitivně: Přihlašovací jméno (username) → Zobrazované jméno (display_name) → E-mail → Heslo → Potvrzení hesla.
    • V metodě save() formuláře se zadané zobrazované jméno po vytvoření uživatele automaticky uloží do navázaného UserProfile. Pokud pole uživatel nevyplní, funguje přirozený fallback na přihlašovací jméno.
  • Modernizace a zpřesnění šablon:
    • V signup.html doplněna podpora pro vykreslení HTML atributu placeholder ze zadaných widgetů. Karta a tlačítko registrace byly designově sladěny s přihlašovací kartou v login.html (Bootstrap 5 sémantické třídy rounded-4, bg-body-tertiary, atd.).
    • V administrátorském přehledu (dashboard.html) se u čekajících uživatelů nyní zobrazuje jak zobrazované jméno, tak přihlašovací jméno (@username).
    • V notifikačních e-mailech správci o nové registraci je nově uváděn formát Zobrazované jméno (@přihlašovací_jméno).
  • Automatizované testy:
    • V SignUpViewTests rozšířeny unit testy o ověření popisků, placeholderů a uložení zobrazovaného jména do profilu při úspěšné registraci i ověření zobrazení „Přihlašovací jméno“ na přihlašovací stránce.

  • #37 & #35: Oprava náhodného přehazování pořadí položek a vystřelování sérií na začátek:
    • V WishlistDetailView a PublicWishlistDetailView opraven queryset z původního order_by("category__name", "name") na order_by("category__name", "order", "-priority", "name"). Původní abecední řazení zcela ignorovalo modelové pole order a znehodnocovalo ruční i automatické uspořádání.
    • Implementována nová pomocná funkce group_items_by_category_and_series(). Namísto dřívějšího rozdělení na samostatné skupiny items_in_series (které se v šabloně vykreslovaly vždy jako první a tlačily všechny série nahoru) a items_not_in_series skládá sjednocený seznam elements, kde jsou série a samostatné položky přirozeně prokládány přesně podle jejich skutečného pořadí order.
    • V šabloně _unified_item_list_display.html přepracováno vykreslování podle elements pro seznamový i kompaktní pohled.
  • #33: Avatar Stack pro sdílené seznamy se spoluvlastníky:
    • V wishlist_detail.html (hero card) a _wishlist_header.html (sticky hlavička) nahrazen samostatný avatar vlastníka komponentou Avatar Stack, která zobrazuje jak avatar vlastníka (s titulkem a označením vlastníka), tak avatary všech spoluvlastníků (co_owners).
    • V custom.css definovány adaptivní třídy .avatar-stack a .avatar-stack-item s rámečkem border: 2px solid var(--bs-body-bg), který perfektně ladí s motivem ve světlém i tmavém režimu.
  • #34: Rychlé tlačítko pro přidání položky přímo do existující série nebo kategorie:
    • Do záhlaví každé série v seznamovém i kompaktním zobrazení přidáno tlačítko + Přidat do série s atributy data-prefill-series a data-prefill-category.
    • Do záhlaví kategorií v _category_header.html přidáno tlačítko + Přidat do kategorie s atributem data-prefill-category.
    • V wishlist_detail.js doplněna obsluha události show.bs.modal na #addItemModal, která automaticky předvyplní Select2 widgety pro kategorii a sérii podle kliknutého tlačítka (a při otevření běžným tlačítkem je korektně vyčistí).
    • V WishlistItemForm i obou create/update view rozšířen queryset pro sérii tak, aby spoluvlastníci na sdíleném seznamu viděli a mohli vybírat i série vytvořené vlastníkem seznamu či použité v daném seznamu.
    • V režimu úpravy pořadí (.reorder-mode-active) jsou tato tlačítka automaticky skryta, aby nepřekážela ovládacím prvkům pro přesun.
  • Feedback #1: Notifikace při přidání přání spoluvlastníkem do sdíleného seznamu:
    • Do modelu WishlistItem přidáno pole added_by = ForeignKey(User, null=True, blank=True, ...).
    • Vytvořena databázová migrace 0045_wishlistitem_added_by.
    • V darkovnik/signals.py upraven signál create_activity_on_new_item, kde je aktér určen jako item.added_by or item.wishlist.owner.
    • Spoluvlastník, který položku přidal, již nedostává zavádějící notifikaci o své vlastní akci a vlastník seznamu je naopak řádně notifikován o přidání nového přání s uvedením jména spoluvlastníka.
  • Feedback #2: Oprávnění spoluvlastníka v detailu položky (zamluvení vs. správa):
    • V ajax_views.get_item_detail_html i WishlistItemDetailView doplněna kontrola spoluvlastnictví (user_is_manager).
    • V _item_detail_content.html nahrazena původní podmínka request.user == wishlist.owner kontrolou user_is_manager.
    • Spoluvlastník má nyní plná práva na správu a editaci přání a je mu skryto návštěvnické tlačítko „Zamluvit toto přání“ (které spoluvlastník dle pravidel nesmí používat).
  • #36: Zaevidování obecných poznámek pro série / kategorie do Roadmapy:
    • Podnět detailně zaevidován do docs/ROADMAP.md jako budoucí architektonické rozšíření.
  • Automatizované testy:
    • Do darkovnik/tests.py přidána testovací třída CoOwnerAndOrderingFeedbackTests s 5 komplexními unit testy pokrývajícími added_by a notifikace, oprávnění v detailu položky, prokládané řazení sérií a položek, avatar stack i vykreslení předvyplňovacích tlačítek.
    • Kompletní testovací sada (180 testů) úspěšně prošla v Dockeru.

  • #32: Sjednocení barevného schématu veřejného odkazu na dárky v profilu:
    • V _public_gift_link_management.html nahrazen původní blok alert alert-info border-0 se žlutým tlačítkem za standardní sémantický kontejner bg-body-secondary border border-secondary-subtle rounded-3 p-3.
    • Tlačítka pro kopírování i přegenerování sjednocena na btn-outline-secondary. Vzhled je nyní v obou motivech (světlém i tmavém) zcela konzistentní a bez nepatřičného tyrkysového či žlutého zabarvení.
  • #22: Nezávislé rozbalování uživatelských sekcí v kategorii skupiny:
    • V _grouped_item_section_renderer.html odstraněn atribut data-bs-parent="#accordion-{{ id_suffix }}".
    • Všechny sekce uživatelů lze nyní nezávisle rozbalovat i sbalovat bez toho, aby otevření jednoho uživatele automaticky skrylo ostatní.
  • #23: Eliminace probliknutí a animovaného zavírání „obecných preferencí a poznámek“:
    • V wishlist_detail.html přidán inline skript bezprostředně za #preferencesCollapse, který ještě před vykreslením (paint) zkontroluje stav v localStorage a při stavu hidden odebere třídu .show a nastaví ikonu na bi-chevron-down.
    • V wishlist_detail.js nahrazeno volání animovaného collapseInstance.hide() za přímé synchronní nastavení tříd a ARIA atributů, čímž bylo zcela odstraněno vizuální rozevření a následné zavření při přenačtení stránky a filtrování.
  • #30: Zachování pozice (scroll focus) při přepínání filtrů v administraci:
    • V dashboard.html přidána kotva id="feedback-section" k nadpisu sekce zpětné vazby a odkazy záložek filtrů upraveny na ?status_filter=active#feedback-section (včetně resolved a all).
    • Uživatel po přepnutí filtru zůstává zaměřený na sekci zpětné vazby a neodroluje na začátek stránky.
  • #31: Okamžité plynulé skrytí karty podnětu po vyřešení:
    • V dashboard.html rozšířena JavaScript obsluha attachFeedbackListeners: pokud se administrátor nachází v záložce „Aktivní“, karta vyřešeného podnětu se plynule odanimuje (fade out / scale down) a odstraní z DOMu, sníží se aktivní počítadlo, navýší vyřešené a v případě vyčerpání všech položek se zobrazí prázdný stav. Obdobně to funguje při znovuotevření ze záložky „Vyřešené“.
  • #29: Sjednocení barvy ikonky zpětné vazby v navigaci:
    • V _sidebar.html i _mobile_nav.html změněna třída ikonky bi-chat-heart z poutavého text-primary na text-secondary (a v profilovém dropdownu na text-muted), v plném souladu s ostatními položkami menu.
  • #24: Zaevidování požadavku na vlastní pořadí kategorií:
    • Podnět zaevidován do docs/ROADMAP.md jako plánovaná architektura vyžadující model pořadí, migraci a UI pro drag & drop / posun.

  • #25: Oprava neviditelné hvězdičky ve filtru seznamu přání:
    • V _priority_filter_buttons.html nahrazena nechtěná třída btn-warning text-dark za standardní sémantiku segmented controlu: aktivní tlačítko nese třídu active (btn-star-filter).
    • V custom.css přidán výrazný žlutý záblesk/stín pro aktivní hvězdičku (.segmented-control .btn-star-filter.active i) a upraven box-shadow pro tmavý režim. Hvězdička je nyní v obou motivech nádherně zářivá a zřetelně vybraná.
  • #26: Sjednocení barevného schématu tlačítka instalace aplikace (PWA):
    • V _sidebar.html nahrazen nesourodý blok bg-primary-subtle s modrým textem za elegantní a konzistentní zaoblené tlačítko btn btn-outline-primary w-100 rounded-pill py-2, které přesně ladí s mobilní variantou v _mobile_nav.html a zachovává vysoký kontrast v tmavém i světlém režimu.
  • #27: Kompletní oprava inicializace, synchronizace a náhledu barvy zvýraznění (Pickr):
    • Oprava inicializace barvy profilu: Odhalen a opraven interní bug v knihovně @simonwep/pickr, kdy konstruktor přednastavuje interní barvu na černou (_color = w()), což způsobovalo, že operátor ?? t.default v animačním rámci nikdy nespadl do předané konfigurace a Pickr při načtení stránky vždy přepsal barvu na #000000. V obsluze události init je nyní explicitně voláno instance.setColor(initialColor); instance.applyColor(); (případně setColor(null) pro výchozí/nenastavenou barvu).
    • Průběžná synchronizace hodnoty: Do Pickr napojeny listenery na události change, swatchselect, save a clear. Zvolená barva se do formulářového pole propisuje okamžitě při výběru odstínu či vzorku, takže změna spolehlivě proběhne i při uložení hlavním tlačítkem stránky bez nutnosti klikat na vnitřní tlačítko „Uložit“ v popoveru.
    • Ochrana proti 9-znakovému hexu (#RRGGBB vs #RRGGBBAA): Metoda color.toHEXA().toString() vracela 9-místný řetězec včetně průhlednosti, což v PostgreSQL končilo pádem DataError: value too long for type character varying(7). V šabloně i backendové validační metodě UserProfileEditForm.clean_accent_color je hodnota striktně normalizována a zkrácena na platný 7-znakový formát #RRGGBB.
    • Odstranění nechtěné konverze z HTML5 <input type="color">: Widget pole byl upraven z type="color" (který dle specifikace HTML5 vynucuje #000000 při prázdné hodnotě) na type="text" uvnitř skrytého obalu, což umožňuje korektně odeslat a uložit prázdnou barvu (reset do výchozího stavu).
    • Vyladění stylů tlačítka .pcr-button v obou režimech: Tlačítko získalo plně kruhový tvar s border-radius: 50rem, overflow: hidden, jemný adaptivní rámeček var(--bs-border-color), vypnutí zpožďující tranzice zamezující probliknutí šachovnice a decentní poloprůhledné pozadí pro prázdný stav (.clear) ve světlém i tmavém motivu.
  • Projektová pravidla & Triage:
    • Do GEMINI.md zavedeno nové trvalé pravidlo pro rozpoznávání a třídění uživatelské zpětné vazby (Triage: co hned vs. co do roadmapy).
  • Automatizované testy:
    • Přidána nová testovací třída ProfileAccentColorTests (4 testy: zkrácení 9-znakového hexu na 7 znaků, uložení prázdné barvy jako None, validace neplatného formátu a ověření vykreslení formuláře bez type="color").
    • Testovací sada DarkModeAuditTests (6 testů) i kompletní testovací sada aplikace (167 testů) úspěšně prošla v Dockeru.

  • Hromadný výběr a export ticketů v administraci (/administrace/):
    • U každé karty podnětu zpětné vazby přidán checkbox pro označení položky a vizuální indikátor vybrané karty (zvýraznění pomocí var(--bs-primary) v obou režimech).
    • Vytvořena přehledná hromadná lišta (Batch toolbar) nad seznamem podnětů s volbou „Vybrat vše“, dynamickým počítadlem vybraných položek (Vybráno: X), tlačítkem „Kopírovat výběr pro AI“, rozbalovací nabídkou „Exportovat výběr“ (.md a .json) a tlačítkem „Zrušit“.
  • Okamžité živé vyhledávání / filtrování podle klíčových slov:
    • Přímo nad seznam podnětů přidáno vyhledávací pole umožňující bleskové fulltextové filtrování (podle zprávy, autora, URL i interních poznámek).
    • Volba „Vybrat vše“ inteligentně respektuje aktivní filtr a zaškrtává pouze zobrazené výsledky vyhledávání (např. zadáním výrazu „darkmode“ a kliknutím na „Vybrat vše“ lze okamžitě vybrat a exportovat všechny tickety k danému tématu).
  • Backendové rozšíření exportního endpointu:
    • V darkovnik/views/admin_views.py upraven view export_feedback s podporou parametru ids (z GET i POST, ve formátu seznamu i čárkami oddělených hodnot).
    • V darkovnik/feedback_utils.py přidána podpora pro rozsah scope="selected" / scope="vyber" s hlavičkou „Vybrané podněty“ a generováním názvu souboru darkovnik-feedback-vyber-....
    • Zachována plná podpora pro přímé stažení souboru (download=1) i pro 1-klikové zkopírování formátovaného Markdownu pro AI asistenta do schránky (download=0).
  • CSS & Tmavý režim:
    • Do custom.css doplněny sémantické třídy .feedback-item-card.feedback-card-selected a .feedback-select-checkbox bez použití inline stylů. Plně ověřen vysoký kontrast ve světlém i tmavém motivu.
  • Automatizované testy:
    • Do darkovnik/tests.py přidána testovací třída FeedbackBatchExportTests pokrývající export vybraných ID do Markdownu i JSONu, AJAX kopírování, kontrolu oprávnění a vykreslení ovládacích prvků v šabloně.

  • Odstranění nečitelného tmavého textu (text-dark, link-dark):
    • V šabloně oznámení (notification_list.html) opraveno nepřečtené oznámení na text-body fw-bold (namísto černého textu na tmavě modrém pozadí).
    • Na hlavní nástěnce (dashboard.html) odstraněn text-dark z odkazů „Inspirace od přátel“, z nadpisů karet seznamů přání, skupin a textu zpráv v časové ose nedávné aktivity.
    • V seznamech přání (wishlist_list.html), skupinách (group_list.html) a detailu skupiny (group_detail.html) nahrazen link-dark adaptivní třídou link-body-emphasis.
  • Eliminace oslňujících bílých ploch a sjednocení na adaptivní sémantiku (bg-body-*):
    • V přehledu ostatních uživatelů (user_list.html) odstraněn „zebra“ efekt nahrazením bg-light v hlavičce za bg-body-tertiary a bg-white v patičce za bg-transparent. Jména uživatelů v hlavičkách karet jsou nyní v obou režimech dokonale čitelná s vysokým kontrastem.
    • V detailu skupiny (group_detail.html) změněn box s náhledem položek sdíleného seznamu z bg-white na bg-body, čímž byl odstraněn konflikt s text-muted a zajištěn plný kontrast.
    • Na nástěnce (dashboard.html) nahrazen bg-white v patičce widgetu „Nezapomeňte koupit“ i v hlavičce časové osy za bg-transparent. Bubliny a spojovací linka aktivity adaptovány na bg-body-tertiary a bg-secondary-subtle.
    • Prázdné stavy (empty states) na nástěnce, v přehledu seznamů, skupin i v administraci sjednoceny na bg-body-tertiary s novou utilitou .border-dashed.
    • V boxu veřejného odkazu profilu (_public_gift_link_management.html) odstraněn bg-light z alert-info.
    • V řádcích položek (_item_list_row.html) a modálu detailu (_item_detail_content.html) nahrazeny badge bg-light za adaptivní badge bg-secondary-subtle text-secondary-emphasis border.
  • Dark Mode podpora pro komponenty třetích stran v custom.css:
    • Select2 Dropdowny: Přidána kompletní sada pravidel pro [data-bs-theme="dark"] .select2-container--bootstrap-5 – adaptivní tmavé pozadí výběrových polí, rozbalovacích nabídek, vyhledávacího pole, hover/selected položek a štítků s křížkem.
    • Pickr (Color Picker): Do custom.css přidány styly pro .pcr-app v tmavém režimu (tmavé pozadí popoveru, tmavá vstupní pole pro HEX/RGB kód a kontrastní akční tlačítka).
    • Priority Borders & Co-owners: Přidány tmavé varianty indikátorů priorit (.priority-border-high a .priority-border-low) a jemné ohraničení pro .co-owner-chip.
  • Zavedení projektového pravidla pro /learn:
    • Do GEMINI.md začleněna nová závazná pravidla pro vývoj a povinnost vizuální kontroly v obou režimech (světlém i tmavém) při jakýchkoliv budoucích úpravách UI.

  • Ergonomie tlačítek pro posun položek v kartovém i kondenzovaném zobrazení:
    • Zvětšena klikací / dotyková plocha tlačítek pro posun nahoru a dolů (▲ / ▼) na 38 × 36 px v kartovém zobrazení a 32 × 30 px v kondenzovaném pohledu.
    • Tlačítka jsou oddělena zřetelnou mezerou (gap-2), mají zaoblené rohy a jejich celková výška přesně ladí s výškou náhledu obrázku dárku (80 × 80 px) bez nežádoucího roztažení nebo deformace karty.
    • Zvětšeny vnitřní ikony šipek na fs-5 pro pohodlné a spolehlivé ovládání prstem na mobilních zařízeních i myší na počítači.
  • Sjednocení priority na symbol hvězdičky (⭐) napříč aplikací:
    • Odznaky na přáních: Odstraněn text „Priorita“ / „Vyšší priorita“ z kartového zobrazení (_item_list_row.html), kondenzovaného řádku (_item_condensed_row.html) i modálního detailu dárku (_item_detail_content.html). Ponechána čistá zlatá hvězdička s tooltipem Přání s hvězdičkou.
    • Filtr priorit: V liště ovládacích prvků (_priority_filter_buttons.html) zredukována tlačítka na intuitivní přepínač o 2 volbách: „Vše“ a „⭐“ (odstraněna nepotřebná možnost „Běžná“). Kontejner ovládacích prvků přizpůsoben tak, aby se filtr i tlačítka akcí na mobilech přehledně vešly do jednoho řádku.
    • Formuláře pro přidání a úpravu přání: Výběrové pole (select dropdown) nahrazeno moderním přepínačem (switch card): ⭐ Označit hvězdičkou s nápovědným textem vysvětlujícím význam hvězdičky pro dárce („Položky s hvězdičkou budou v seznamu zvýrazněné, aby dárci snadno poznali vaše největší přání.“).
    • V darkovnik/forms.py implementován robustní StarPriorityField zajišťující obousměrnou kompatibilitu stávajících hodnot priority (Item.Priority.HIGHER = 3, NORMAL = 2).
  • Backend & Automatizované testy:
    • Přidána testovací sada StarPriorityTests ověřující zpracování formulářů s hvězdičkou a filtrování podle priority.
    • Všechny automatizované testy úspěšně ověřeny.

  • #16: Zavedení mobilního Režimu řazení (Varianta A):
    • V hlavičce seznamu přání přidáno pro správce tlačítko s ikonou řazení (bi-arrow-down-up), které přepíná stránku do dedikovaného Režimu úpravy pořadí.
    • V režimu řazení se zobrazí přehledná sticky lišta s tlačítkem „Hotovo“, položky získají zřetelná dotyková madla a rychlá tlačítka posunu nahoru/dolů (▲ / ▼) pro okamžitý posun o jednu pozici bez nutnosti tahání.
    • Vypnuto nechtěné otevírání modálních oken detailu dárku během řazení; plovoucí tlačítko FAB je dočasně skryto.
    • V běžném mobilním režimu zůstávají položky čisté, bez rušivých madel, se 100% plynulým nativním scrollováním bez jakýchkoliv záseků.
  • Oprava drag & drop v kondenzovaném pohledu na desktopu:
    • V šabloně _item_condensed_row.html refaktorován řádek z odkazu <a> na standardní <div>.
    • Madlo .handle a nové ovládací prvky vyjmuty z klikací oblasti otevírající detail dárku, čímž byl odstraněn konflikt se SortableJS filtrem i nechtěné otevírání modálního okna při pokusu o tažení.
    • Odstraněno redundantní dvojité zanoření třídy .sortable-item-list v šabloně _item_display_section.html.
  • Sjednocení chování v JavaScriptu & CSS:
    • V sortable.js nahrazena nespolehlivá detekce dotyku explicitními madly (handle: '.handle-series, .handle, .reorder-touch-handle').
    • Přidána obsluha pro přesun elementů v DOM s automatickým ukládáním pořadí do databáze přes AJAX a dynamickým zakazováním krajních šipek posunu.
    • V custom.css doplněny responzivní styly pro sticky lištu, zobrazení tlačítek posunu v aktivním režimu a vizuální odlišení stavů přetahování (.sortable-ghost, .sortable-chosen).
  • Backend & Automatizované testy:
    • Do darkovnik/tests.py přidána nová testovací třída ItemReorderTests testující oprávnění vlastníka, spoluvlastníka, odmítnutí cizího uživatele a validaci databáze (154 testů v projektu úspěšně prošlo).

  • Triáž podnětů & přesun komplexních úkolů do roadmapy:
    • Podnět #16 (přeuspořádání přání na mobilu v kondenzovaném zobrazení) a komplexní část podnětu #17 (systémový audit tmavého režimu napříč aplikací) byly analyzovány a zaevidovány do docs/ROADMAP.md k budoucímu koncepčnímu řešení.
  • #21: Oprava ukládání interní poznámky administrátora:
    • V dashboard.html opravena chybějící proměnná CSRF tokenu v obsluze tlačítka .btn-save-feedback-notes, která způsobovala JavaScriptovou chybu ReferenceError a blokovala ukládání.
  • #20: Oprava šířky a vodorovného posunu v administraci:
    • V dashboard.html nahrazen gutter g-5 (jehož záporný okraj -1.5rem přesahoval padding kontejneru na mobilech) vyváženým row g-4 gy-4.
    • Doplněny responzivní třídy col-12 col-lg-8 a col-12 col-lg-4 zaručující korektní zobrazení na všech šířkách displeje.
  • #19: Oprava chyby 500 při zobrazení kategorie ve skupině:
    • V šabloně group_category_detail.html odstraněno chybné vložení modálu _item_form_modal.html, který vyžadoval instanci konkrétního wishlistu a způsoboval pád na NoReverseMatch u URL item_create.
    • V šabloně _item_form_modal.html doplněna defenzivní podmínka {% if wishlist.pk %} pro prevenci pádu při absenci wishlistu v kontextu.
  • #18: Odstranění nadbytečného slova „Odkazy“ v detailu přání:
    • V modálním okně _item_detail_content.html odstraněn nadpis <h5>Odkazy:</h5> před odznaky odkazů, čímž se ušetřilo vertikální místo.
  • #15: Zřetelné zobrazení informace o vyšší prioritě:
    • V kartovém zobrazení (_item_list_row.html), v kondenzovaném řádku (_item_condensed_row.html) i v modálním detailu dárku (_item_detail_content.html) přidán zřetelný odznak se žlutou hvězdičkou Vyšší priorita / Priorita.
  • #13: Zobrazovací jméno při přidávání člena do skupiny:
    • V modálním okně _group_add_member_modal.html nahrazeno prosté uživatelské jméno filtrem {{ user_obj|display_name }} s doplňkovým zobrazením (@uživatelské_jméno), pokud se liší.
  • #17: Rychlé opravy kontrastu na profilu v tmavém režimu:
    • Na stránce úpravy profilu (profile_edit.html) nahrazeny fixní světlé třídy (bg-light, link-dark) responzivními třídami Bootstrap 5 (bg-body-secondary, text-body).
  • Automatizované testy:
    • Do testovací sady přidány testy GroupCategoryDetailViewTest (ověření HTTP 200, šablony a obsahu) a FeedbackAdminNotesAjaxTest (ověření AJAX uložení interní poznámky).

  • Přechod na sémantické verzování (SemVer) & sledování verzí:
    • Vytvořen pomocný modul darkovnik/version.py pro bezpečné a rychlé zjišťování verze, commit SHA, data sestavení a prostředí (produkce/vývoj).
    • Implementován Django management command python manage.py generate_build_info [--app-version <tag>] [--commit-sha <sha>], který generuje soubor build_info.json.
    • Integrace do GitHub Actions CI/CD (.github/workflows/deploy.yml): automatické vygenerování informací o commitu a verzi přímo při nasazení na produkční VPS.
  • Interaktivní a bezpečný Changelog parser:
    • Vytvořen modul darkovnik/changelog_utils.py, který dynamicky parsuje docs/CHANGELOG.md jako jediný zdroj pravdy bez nutnosti duplicitních zápisů.
    • Využívá markdown2 a bleach pro převod do bezpečného HTML s automatickým cachováním dle mtime souboru.
  • Nová stránka „O aplikaci & novinky“ (/o-aplikaci/):
    • Implementováno responzivní view about_view a šablona about.html přístupná přihlášeným i anonymním uživatelům.
    • Hlavička: Odznáčky aktuální verze, commit SHA s proklikem na GitHub, datum nasazení a indikátor prostředí.
    • Komunitní statistiky: Přehledné anonymizované počitadlo splněných dárků, aktivních přání, seznamů a uživatelů.
    • Záložka O Dárkovníku & Nápověda: Klíčové principy (režim překvapení, spoluvlastnictví, veřejné odkazy), návod na instalaci PWA do telefonu (iOS Safari, Android Chrome), výzva k odeslání zpětné vazby s napojením na feedback modal a přehled technologií.
    • Záložka Historie verzí: Akordeon s chronologickým přehledem všech verzí z changelogu.
    • Záložka Systém: Diskrétní diagnostická karta pro správce (is_staff) se stavem serveru, verzemi Pythonu/Djanga, databází a WebPush.
  • Navigace & globální kontext:
    • Vytvořen kontextový procesor app_version_info, který zpřístupňuje APP_VERSION ve všech šablonách.
    • Odkazy na verzi a stránku „O aplikaci“ přidány do desktopového sidebaru, uživatelského menu, mobilního offcanvas menu a patičky.
  • Automatizované testy:
    • Vytvořena testovací sada AboutAndVersioningTests ověřující přístupnost pro anonymy i přihlášené, staff diagnostiku, parsování changelogu, helper verzování, kontextový procesor a command generate_build_info.

  • #11: Oprava mazání seznamu přání:
    • Modální okno #deleteWishlistModal přesunuto do globální šablony base.html, aby bylo dostupné na všech stránkách bez ohledu na kontext.
    • V global_scripts.js sjednocen event listener pro show.bs.modal na #deleteWishlistModal, který spolehlivě nastavuje dynamickou action URL formuláře a doplňuje správný název mazaného seznamu do #deleteWishlistName.
  • #7: Sdílení wishlistu do skupin na mobilních zařízeních:
    • V šabloně _wishlist_share_modal.html doplněna sekce „Sdílet do mých skupin“ se zaškrtávacími políčky a tlačítkem „Uložit sdílení“.
    • Vytvořen nový backend AJAX endpoint ajax_update_wishlist_groups (/wishlist/<id>/share-groups/) s validací oprávnění vlastníka/spoluvlastníka.
    • Tlačítko sdílení v hlavičce detailu seznamu zpřístupněno pro všechny správce seznamu (user_is_manager).
  • #2: Oprava zakládání skupiny:
    • V _group_form_content.html opraven atribut formuláře na <form hx-post="{{ action_url|default:request.path }}" ...>.
    • V ajax_views.py i group_views.py explicitně předávána action_url (darkovnik:group_create a darkovnik:group_edit), což zabraňuje chybnému odesílání POST požadavku na GET endpoint pro načítání modálu.
  • #12: Přehlednější administrace zpětné vazby & interní poznámky:
    • Na dashboardu administrace přidány záložky filtrů stavu: Aktivní (výchozí), Vyřešené a Všechny s počitadly.
    • Zaveden kompaktnější design karet podnětů a rozbalovací sekce pro interní administrátorské poznámky (admin_notes).
    • Vytvořen AJAX endpoint ajax_update_feedback_notes (/ajax/admin/feedback/<id>/notes/) s tlačítkem „Uložit poznámku“ přímo na kartě tiketu.
  • #10: Odstranění modrého pruhu v PWA a vylepšení zobrazení:
    • V base.html nahrazena fixní modrá theme-color meta značka adaptivními hodnotami s media queries prefers-color-scheme: #f8f9fa pro světlý a #212529 pro tmavý režim.
    • V manifestu PWA (pwa_views.py) sjednocena theme_color na #f8f9fa.
  • #9: Tlačítko uložení profilu ve spodní části stránky:
    • Do profile_edit.html přidáno primární tlačítko „Uložit změny“ také na konec formuláře pod nastavení notifikací.
  • #8: Lokalizace WebPush do češtiny:
    • Ve statickém skriptu webpush.js přeloženy všechny výchozí texty tlačítek a stavů do češtiny.
    • V šabloně profile_edit.html doplněny lokalizované texty pro všechny stavy odběru push notifikací.
  • #5: Zmírnění podmínek pro heslo:
    • V settings.py upraven AUTH_PASSWORD_VALIDATORS: nastavena minimální délka hesla na 6 znaků a odstraněny přísné validátory (UserAttributeSimilarityValidator a CommonPasswordValidator).
  • #4: Skrytí sekce nezařazených dárků, pokud je prázdná:
    • V _wishlist_detail_items.html upravena podmínka zobrazení nezařazených položek tak, aby testovala reálnou existenci položek (items_without_category.items_in_series nebo items_without_category.items_not_in_series), nikoliv pouhou existenci slovníku.
  • #3: Úprava uvítání na nástěnce:
    • Na dashboardu (dashboard.html) upraven text uvítání z „Vítejte zpět, [jméno]!“ na univerzální „Vítejte, [jméno]!“.
  • #1: Volba měny a automatický přepočet cen na Kč:
    • Do modelu WishlistItem přidáno pole currency s volbami CZK (Kč), EUR (€), USD ($), GBP (£) s výchozí hodnotou CZK.
    • Implementovány metody currency_symbol, get_approx_price_czk() s orientačními kurzy (EUR ~ 25,2 Kč, USD ~ 23,5 Kč, GBP ~ 29,5 Kč) a get_price_display().
    • Formulář WishlistItemForm i šablony _item_add_form_content.html a _item_edit_form_content.html upraveny na kompaktní input-group s výběrem měny vedle ceny.
    • Přizpůsobeno zobrazení v kartách dárků na dashboardu, v řádcích seznamu i v modálním detailu dárku.
    • Endpoint pro načítání metadat z URL (fetch_url_metadata_view) i kopírování dárků rozšířeny o automatickou detekci a zachování měny.
  • Automatizované testy:
    • Vytvořena testovací sada FeedbackBatch1Tests ověřující měny, kurzy, formátování cen, sdílení wishlistu do skupin, filtrování a poznámky v administraci, nastavení validátorů hesel a action URL pro zakládání skupiny.

  • Oprava odesílání zpětné vazby v modálním okně:
    • V _feedback_modal.html doplněna chybějící deklarace proměnné submitBtn (document.getElementById('feedbackSubmitBtn')), jejíž absence způsobovala ReferenceError a blokovala odeslání požadavku přes AJAX.
    • Doplněna hlavička X-CSRFToken a ochrana proti vícenásobnému odeslání (disabled stav během odesílání).
  • Export zpětné vazby z administrace (Web UI):
    • Do záhlaví sekce Zpětná vazba od uživatelů na nástěnce administrace (dashboard.html) přidáno:
      • Tlačítko „Kopírovat pro AI“ (1 klik): okamžitě zkopíruje všechny aktivní podněty k řešení naformátované jako Markdown checklist (- [ ]) do systémové schránky pro přímé vložení do AI konverzace (s vizuální odezvou o zkopírování).
      • Rozbalovací nabídka „Exportovat“: stažení souborů Markdown (.md pro aktivní nebo všechny) a JSON (.json).
    • U každé karty podnětu přidáno kompaktní tlačítko pro rychlé zkopírování konkrétního tiketu do Markdownu.
  • Backend endpoint a pomocné moduly:
    • Vytvořen modul darkovnik/feedback_utils.py s funkcemi format_feedbacks_markdown, format_single_feedback_markdown a feedback_to_dict.
    • V admin_views.py implementován endpoint export_feedback (/administrace/feedback/export/) s podporou formátů (md, json), rozsahů (active, all) a přímého stažení či AJAX odpovědi.
  • Django Management Command (export_feedback):
    • Implementován příkaz python manage.py export_feedback [--format md|json] [--scope active|all] [--output cesta/k/souboru] umožňující export podnětů přímo z terminálu nebo Dockeru do repozitáře (např. docs/FEEDBACK.md).
  • Automatizované testy:
    • V FeedbackTests doplněny testy pro ověření stažení Markdownu, JSONu, AJAX schránky, jednotlivých podnětů, oprávnění administrátora a spuštění management commandu.

  • Sjednocení velikosti akčních tlačítek a menu [⋮] na kartě přání na PC:
    • V custom.css zavedena desktopová pravidla (@media (min-width: 768px)) pro .item-list-actions .btn:
      • Všechna tlačítka mají sjednocenou, ergonomickou a proporčně vyváženou výšku 36 px (min-height: 36px, font-weight: 500, font-size: 0.875rem, vnitřní odsazení 0 0.9rem).
      • Třítečkové tlačítko dropdown menu [ ⋮ ] (.btn-icon-touch) bylo na desktopu přesně přizpůsobeno na 36 × 36 px (odstraněn disproporční 44px mobilní rozměr způsobující vertikální vyboulení).
    • V base.html povýšena verze stylů na custom.css?v=8 pro spolehlivý cache busting.
  • Optimální využití horizontálního prostoru na PC (Společný spodní řádek):
    • V _item_list_row.html byly datum a stavové štítky (Vaše, Zamluveno: ..., Archivováno) sloučeny s blokem akčních tlačítek do společného spodního řádku s jemnou linkou (border-top border-light-subtle):
      • Vlevo dole: Časové razítko vytvoření/úpravy + stavový odznak.
      • Vpravo dole (ms-auto): Harmonická tlačítka akcí ([ ✔ Dostal/a ], [ ✏ Upravit ], [ ⋮ ] či akce návštěvníka).
    • Ušetřen celý jeden vertikální řádek (~35–40 px) výšky na každé kartě přání – obsah je kompaktnější a lépe přehledný bez zbytečného prázdného místa na pravé straně.
    • Mobilní rozložení (< md) s plnošířkovou spodní lištou a 44px touch targets zůstává 100% zachováno.

  • Odkazy na produkt v modálu pro přidávání a editaci přání (Symetrické Input Groupy - Varianta 1):
    • Implementováno plně symetrické uspořádání řádků pro zadávání odkazů ve formulářových šablonách (_item_form_modal.html, _item_update_modal.html, _item_add_form_content.html, _item_edit_form_content.html):
      • Obě textová pole (URL odkazu i Popisek) mají identickou výšku (48 px), šířku, vnitřní odsazení (0.75rem 1.25rem) i velikost písma (0.95rem) a zaoblený levý okraj (border-radius: 1rem 0 0 1rem).
      • Obě funkční tlačítka ([ ↻ ] pro načtení metadat a [ 🗑 ] pro smazání odkazu) mají identické rozměry (50 × 48 px), ikony o velikosti fs-5 a zaoblený pravý okraj (border-radius: 0 1rem 1rem 0). Jsou umístěna přímo napravo od svých vstupů s perfektním vertikálním lícováním.
      • Každý odkaz je orámován čistou zaoblenou kartou (rounded-4 border bg-body-tertiary p-2).
      • Třídy definovány výhradně v custom.css (.link-input-group) bez jakýchkoliv inline stylů; verze CSS povýšena na custom.css?v=5.
    • Oprava v wishlist_detail.js:
      • Doplněna chybějící složená závorka v obsluze addFormsetRow, která způsobovala syntaktickou chybu při běhu skriptu.
      • Událost kliknutí pro dynamické přidání odkazů (#add-link-form-add a #add-link-form-edit) upravena na .closest() pro spolehlivou reakci při kliknutí na ikonu nebo text uvnitř tlačítka.
      • Verze skriptu povýšena na wishlist_detail.js?v=8.
  • Přemístění tlačítek sdílení a menu v hlavičce seznamu (Top-Right Actions):
    • V wishlist_detail.html (přes nový hero_header blok v base_detail.html) byla tlačítka [ 🔗 Sdílet ] a menu správy [ ⋮ ] přesunuta do 1. řádku vpravo nahoru vedle avatara a jména vlastníka.
    • Název seznamu (<h1>) pod nimi získal 100% šířku řádku, což zcela odstranilo nežádoucí zalamování názvu a odskakování tří teček.
  • Kompaktní inline tagy na kartách přání:
    • V _item_list_row.html byly stavové štítky (Vaše, Zamluveno: ..., Archivováno) přesunuty na stejný řádek vedle časového razítka s flex wrapem (gap-2).
    • Ušetřeno cca 35 px vertikálního prostoru na každé kartě při zachování plné čitelnosti a adaptibility pro dlouhá zobrazovaná jména.
  • Sjednocení akčních tlačítek v detailu přání (_item_detail_content.html):
    • Vlastník: Primární tlačítko [ ✔ Dostal/a ] nahoře; druhý řádek tvoří [ ✏ Upravit položku ] a třítečkový dropdown [ ⋮ ] (Kopírovat položku, Archivovat položku, Smazat položku).
    • Návštěvník: Plnošířkové primární tlačítko rezervace ([ 🛒 Zamluvit toto přání ], [ ❌ Zrušit rezervaci ], [ ❤️ Splním toto přání! ] nebo badge Zamluveno) doplněné o menu [ ⋮ ] s akcí Kopírovat do mého seznamu.
    • Zavedena plná podpora výběru cílového seznamu přes #copyItemTargetModal a kopírování pro návštěvníky.
  • Diagnostika konzolové výjimky (startTime / reportAllChanges):
    • Identifikována příčina chyby hlášené při přepínání zobrazení: způsobeno klientským rozšířením prohlížeče (Web Vitals / Performance Monitor) sledujícím DOM elementy po HTMX výměně. Aplikace Dárkovník je po funkční stránce zcela čistá.

  • Plnošířková spodní lišta akcí položek (Varianta A):
    • Na mobilních zařízeních (< md) byla akční tlačítka položek přání (_item_list_row.html) přesunuta do plnošířkového spodního řádku karty s jemnou dělicí linkou.
    • Tlačítka [ ✔ Dostal/a ] a [ ✏ Upravit ] sdílejí prostor rovnoměrně (flex 50/50, min. výška 44 px) a kompaktní třítečkový dropdown [ ⋮ ] je umístěn vedle nich na tomtéž řádku. Odstraněno nežádoucí odskakování tří teček na osamocený řádek.
  • Skrytí madla a přetahování dlouhým stiskem (Long-press Reordering):
    • Na mobilních zařízeních bylo z karet položek (_item_list_row.html i _item_condensed_row.html) skryto madlo pro uchopení (bi-list ikona), čímž se ušetřilo ~36 px horizontální šířky pro obsah přání. Na desktopu zůstává madlo zachováno.
    • V sortable.js byla pro dotyková zařízení implementována podpora dlouhého stisku (300 ms zpoždění, práh pohybu 5 px, aby nedocházelo ke kolizi s běžným posunem stránky).
    • Přidána CSS animace zatřesení/zavrtění (itemWobble) spolu s výraznějším stínem (.sortable-chosen), která uživateli dává okamžitou hmatovou/vizuální odezvu, že je položka připravena k přesunu.
  • Oprava přetékání ovládací lišty seznamu (Control Bar):
    • V wishlist_detail.html byla ovládací lišta přestavěna na adaptivní dvousloupcový/dvouřádkový layout:
      • Na mobilních zařízeních je přepínač priorit rozprostřen na celou šířku (w-100, rovnoměrně rozdělená tlačítka Vše, Vyšší, Běžná) a přepínač zobrazení (Seznam / Kompaktní) spolu s lupou vyhledávání tvoří samostatný pravostranně zarovnaný řádek pod ním.
      • Na desktopu (≥ md) zůstávají ovládací prvky v jediné čisté liště.
    • Tím bylo zcela vyřešeno přetékání ovládací lišty doleva mimo viewport a ořezávání tlačítka Vše na displejích s šířkou 360–390 px.
    • V custom.css doplněna responzivní utility třída @media (min-width: 768px) { .w-md-auto { width: auto !important; } }.
  • Zarovnání a sjednocení odsazení napříč aplikací:
    • V base.html upraveno horizontální odsazení mobilního kontejneru z px-4 (24 px) na px-3 (16 px), což lícuje s navigační lištou a uvolňuje dalších 16 px šířky pro obsah.
    • V base_detail.html a base_simple.html sjednocen vnitřní padding hlavičkových karet na p-3 p-md-4.
    • V hlavičce detailu seznamu byl opraven kontejner názvu a tlačítek: název má min-width-0 flex-grow-1 a tlačítka [ 🔗 Sdílet ] a [ ⋮ ] mají flex-nowrap, což zabraňuje nežádoucímu zalamování slov (např. Testov ací sezna m) a nechtěnému odskakování tří teček pod sdílecí tlačítko.

  • Koncepce a sjednocení napříč celou aplikací:
    • Politika zavedená ve verzi 38 byla důsledně aplikována na všechny zbývající moduly aplikace: detail skupiny, odkladiště položek, přehledy rezervovaných a zakoupených dárků, profil uživatele, seznam seznamů přání, administrační panel a všechna modální okna.
    • Všude platí jednotný vzor: Výrazné primární tlačítko s plným českým textem + kompaktní 3-tečkový dropdown [ ⋮ ] pro sekundární a destruktivní akce + dotykový cíl min. 44 px (.btn-touch, .btn-icon-touch).
  • Detail skupiny (group_detail.html):
    • Vlastník má v hlavičce primární tlačítko [ + Přidat člena ] a v menu [ ⋮ ] volby Upravit skupinu, Kategorie dárků a červeně oddělené Smazat skupinu. Běžný člen má v menu [ ⋮ ] volby Moje přezdívka, Kategorie dárků a Opustit skupinu.
    • V kartách členů je primární akcí [ 🎁 Dárky ] a doplňkové akce (Moje přezdívka, Opustit skupinu, Odebrat ze skupiny) jsou bezpečně v dropdownu [ ⋮ ].
  • Rezervované a zakoupené dárky (_item_actions_include.html):
    • U rezervovaných dárků (my-claimed-items/) je primární akcí [ 🛍 Zakoupeno ], zatímco riziková akce Zrušit rezervaci je ukryta v dropdown menu [ ⋮ ], což brání nechtěnému zrušení rezervace při posunu stránky.
    • U zakoupených dárků (my-purchased-items/) je akce Zrušit zakoupení v dropdownu [ ⋮ ].
    • V odkladišti (wishlists/pool/) je primární akcí [ ↺ Obnovit ] a Trvale smazat je v dropdownu [ ⋮ ].
  • Profil uživatele (profile_edit.html):
    • Primární akce [ 💾 Uložit změny ] má plný text i na nejužších displejích; akce Změnit heslo je dostupná v menu [ ⋮ ].
    • Přezdívky ve skupinách mají pohodlné 44px dotykové tlačítko Upravit.
  • Karty seznamů (wishlist_list.html):
    • Karty seznamů mají primární akcí [ ✏ Upravit ] a volba Smazat seznam je v dropdownu [ ⋮ ].
  • Veřejný odkaz (_public_gift_link_management.html):
    • Primární akcí je [ ↺ Přegenerovat ], destruktivní Zrušit odkaz je v dropdownu [ ⋮ ].
  • Administrace (admin/dashboard.html):
    • U neschválených uživatelů je primární akcí zelené tlačítko [ ✓ Schválit ], zamítnutí registrace je v dropdownu [ ⋮ ].
    • Oprava persistence a zobrazení přepínačů konfigurace webu: Odstraněna procesu-izolovaná LocMemCache u modelu SiteConfiguration, která způsobovala desynchronizaci stavu mezi více Gunicorn workery. Doplněny hlavičky @never_cache na dashboard a endpoint ukládání a přidán atribut autocomplete="off" na formulář a přepínače, což zabraňuje prohlížeči (např. Firefox) přepisovat čerstvý stav z DB starým stavem z historie.
  • Modální okna a potvrzovací dialogy (globální oprava):
    • Ve všech modálních oknech (base_modal.html, _item_form_modal.html, _wishlist_create_modal.html, _wishlist_update_modal.html, _wishlist_delete_modal.html, _group_add_member_modal.html, _group_delete_modal.html, _feedback_modal.html atd.) bylo odstraněno skrývání textu na mobilu (d-none d-sm-inline).
    • Tlačítka v patičkách modálů mají garantovanou minimální výšku 44 px a přehledné textové popisky s ikonami.

  • Mobilní hlavička seznamu (Varianta A):
    • Akce hlavičky na mobilních zařízeních byly zjednodušeny: primární tlačítko [ 🔗 Sdílet ] (s textem a ikonou) a kompaktní třítečkové menu [ ⋮ ] sdružující správu seznamu (Upravit seznam, Smazat seznam).
    • Tlačítko [ + Přidat přání do seznamu ] bylo přesunuto pod popis seznamu jako výrazné plnošířkové tlačítko snadno dosažitelné palcem (detail_bottom_actions blok).
  • Akční tlačítka položek (Owner i Návštěvník):
    • Vlastník: Primární pozitivní a časté akce [ ✔ Dostal/a ] a [ ✏ Upravit ] jsou přímo na řádku s plným českým popiskem a dotykovou výškou 44 px. Méně časté a destruktivní akce (Kopírovat, Archivovat, Smazat) jsou bezpečně umístěny do rozbalovacího menu [ ⋮ ], což eliminuje nechtěná kliknutí při scrollování.
    • Návštěvník: Odstraněno matoucí skrývání textu (d-none d-sm-inline). Tlačítka mají jasné textové popisky: výrazné primární [ 🎁 Zamluvit ], [ 📋 Kopírovat ], [ Zrušit ], [ Splním! ].
    • Odkladiště a Obdržené dárky: Tlačítka [ ↺ Obnovit ], [ 🗑 Trvale smazat ] a [ ↺ Vrátit ] mají rovněž viditelný text a dotykové rozměry.
  • Ergonomie a přístupnost (WCAG dotykové cíle):
    • Zavedeny třídy .btn-touch (min. výška 44 px) a .btn-icon-touch (44×44 px kruhové tlačítko).
    • Odstraněno staré vynucené smrštění a deformace tlačítek.
    • Přepínače zobrazení a filtry priorit mají doplněné aria-label a srozumitelné ikony a popisky.
    • V přehledu seznamů (wishlist_list.html) doplněn text k tlačítku + Nový seznam pro mobilní zařízení.

  • Neměnné přihlašovací jméno: Uživatelské jméno (username) slouží čistě pro přihlášení a v profilu uživatele je uzamčeno jen pro čtení (disabled=True + clean_username ochrana).
  • Globální zobrazované jméno (UserProfile.display_name): Uživatelé si mohou nastavit libovolné globální zobrazované jméno (např. „Karel Novák“).
  • Přezdívky na úrovni skupin (GroupMembership.nickname): Uživatelé si mohou zvolit specifickou přezdívku pro každou skupinu zvlášť (např. „Taťka“ v rodině, „Kája“ mezi kamarády).
  • Hierarchie rozlišení jména:
    1. Přezdívka ve skupině (GroupMembership.nickname), pokud je kontextem skupina.
    2. Globální zobrazované jméno (UserProfile.display_name).
    3. Fallback na přihlašovací jméno (User.username).
  • Šablonový filtr display_name: Sjednocené vykreslování v šablonách pomocí {{ user|display_name }} nebo {{ user|display_name:group }} napříč celou aplikací (nástěnka, položky, rezervace, historie, aktivity).
  • Data migrace (0042): Automatický převod existujících hodnot first_name a last_name z modelu User do nového pole UserProfile.display_name.
  • UI & HTMX:
    • Modální okno _group_nickname_modal.html pro rychlou editaci přezdívky přes HTMX přímo z detailu skupiny i z profilu uživatele.
    • Zobrazení přezdívky i přihlašovacího jména v kartách členů skupiny.
  • Výkonnost: Nulové N+1 dotazy v detailu skupiny – přezdívky a zobrazovaná jména se přednačítají dávkově (GroupMembership.objects.filter(group=self)).
  • Testy: Přidána komplexní testovací třída DisplayNameAndNicknameTests a aktualizovány testy profilu v darkovnik/tests.py.

  • Produkční stack: Dokončena konfigurace a spuštění na VPS s Docker Compose (Gunicorn, PostgreSQL, Nginx reverzní proxy pro statiku/média) za Caddy serverem.
  • SSL a proxy hlavičky: Vyřešena 301 redirect smyčka správným mapováním a předáváním hlavičky X-Forwarded-Proto z Caddy.
  • PWA v produkci: Ověřeno fungování SSL terminace, doručování PWA komponent (manifest.json, sw.js) a statických souborů.
  • CI/CD automatizace: Nastaven GitHub Actions workflow (deploy.yml) pro automatický deployment po pushi do repozitáře.

  • Oprava odkazu na zpětnou vazbu v menu: Odstraněn konfliktní atribut data-bs-dismiss="offcanvas" pro plynulý přechod z mobilního menu do #feedbackModal.
  • Odsazení pro plovoucí tlačítko (FAB): Přidán spodní padding (5.5rem / pb-5) do kontejneru položek na mobilu, aby FAB nepřekrýval akční tlačítka u posledních položek.
  • Dropdown notifikací na mobilu: Upravena šířka (330px, max-width calc(100vw - 2rem)) a barva textu na text-body pro plnou čitelnost v tmavém režimu.
  • Responzivní načítání metadat: Tlačítko pro automatické načtení z URL v modalech bylo upraveno pro mobilní obrazovky (flex stacking).
  • Typografie a přihlašování: Opravena česká typografie a velikost písmen na stránce login.html („Přihlásit se“, „Zaregistrovat se“) a modernizován vzhled přihlašovací karty.
  • Mobilní tlačítka na nástěnce a ve skupinách: Zajištěno zobrazení zřetelných popisků i na menších displejích.
  • Schvalování uživatelů: Zmenšena tlačítka pro schválení na mobilu (skrytý text, výrazná ikona) pro prevenci deformace řádků.

  • Web App Manifest (/manifest.json): Vytvořen dynamický manifest přes darkovnik/views/pwa_views.py:manifest_view se specifikací metadat, standalone režimu, ikon a barev motivu.
  • Kořenový Service Worker (/sw.js): Sjednocený service worker přes pwa_views.service_worker_view kombinující Web Push notifikace a offline fallback caching.
  • Offline fallback šablona: Vytvořena samostatná offline stránka darkovnik/templates/darkovnik/offline.html s vloženým inline CSS a SVG ikonami s nulovou síťovou závislostí.
  • Meta tagy a Apple ikony: Do base.html vloženy PWA hlavičky a ikony pro iOS a Android.
  • Instalační UX prompt: Do push_manager.js přidána obsluha systémové události beforeinstallprompt s tlačítky pro instalaci v bočním panelu a mobilní navigaci.

  • Model UserFeedback: Migrace 0040_userfeedback – zaznamenává typ (chyba, nápad, ostatní), text, automaticky sejmutou URL adresu stránky, stav (nový, řeší se, vyřešeno) a interní poznámky správce.
  • Modální okno zpětné vazby: _feedback_modal.html dědící z base_modal.html s AJAX odesíláním.
  • Vstupní body: Umístěno do postranního panelu, profilového menu i mobilního menu.
  • Správa ve /administrace/: Přehled zpětné vazby s kartami, rychlým počítadlem a AJAX přepínáním stavů.
  • Admin & Notifikace: Registrace v Django Adminu a odesílání Web Push notifikací personálu při podání nové vazby.

  • WebPush ošetření: Defenzivní null-check tlačítka pro odběr notifikací ve webpush.js proti chybám v konzoli na stránkách bez tohoto prvku.
  • Fallback pro rozbité obrázky: Globální zachytávač chyb obrázků v global_scripts.js automaticky nahrazující nedostupné obrázky za zástupný symbol (placeholder.png nebo default_avatar.png).
  • Autofocus a reset v Quick Add: Implementováno shown.bs.modal a hidden.bs.modal pro automatické zaostření na formulář a reset stavu.
  • Nezapomeňte koupit (Empty state): Decentní prázdný stav a odstranění inline stylů.

  • In-memory cache pro SiteConfiguration: Cachování singleton konfigurace pro snížení zátěže databáze.
  • Prefetch aktivit na nástěnce: bulk_prefetch_activities() v dashboard_views.py eliminující N+1 dotazy u GenericForeignKey.
  • Optimalizace Group.get_detail_context(): Prefetching položek a spoluvlastníků.
  • Optimalizace časových razítek wishlistů: Hromadná aktualizace updated_at v signálech.
  • Konzistence bloků šablon: Standardizace všech modalů na explicitní názvy v uzavíracích tazích {% endblock <name> %}.

  • Web Push notifikace: Integrace django-webpush a browser service workeru.
  • Upozornění admina na registraci: Automatické odeslání push notifikace personálu při registraci nového čekajícího uživatele (PendingUser).
  • Audit závislostí: Rozdělení do requirements.txt (produkce) a requirements-dev.txt (linteři a nástroje pro vývoj).
  • Refaktoring šablon: Konsolidace a extrakce společných prvků do layouts/base_*.html.
  • Produkční Docker příprava: Nastavení proměnných prostředí, docker-compose.prod.yml a Nginx konfigurace.

  • Ořezávání obrázků: Klientský ořez obrázků do čtvercového poměru 1:1 pomocí Cropper.js u avatarů i dárků.
  • Sjednocení hlaviček stránek: Zavedení jednotného stylu .page-hero-card s glassmorphism efektem.
  • Sjednocení akčních tlačítek: Tlačítka stylizována jako .segmented-control s oddělenými ikonami.

  • Levý boční panel: Nahrazení plovoucí horní lišty moderním levým panelem na desktopu.
  • Oddělení mobilní navigace: Mobilní navigace extrahována do samostatné komponenty _mobile_nav.html.
  • Širší layout: Přechod na container-fluid pro plné využití plochy monitoru.

  • Administrační rozhraní: Vlastní rozhraní pro personál dostupné přímo na /administrace/.
  • Metriky webu: Počty uživatelů, aktivních seznamů a čekajících registrací.
  • Schvalování uživatelů: Plynulé schvalování a zamítání s AJAXovým mizení řádků a dynamickou aktualizací počítadla.
  • Globální nastavení: Přepínače registrací přímo v rozhraní.

  • Moderní rozvržení 8/4 s plovoucími kartami.
  • Prioritní seznam „Nezapomeňte koupit“.
  • Kolotoč inspirace „Nedávno přidáno přáteli“.
  • Časová osa nedávné aktivity bez duplicit k inspiraci.
  • Rychlé přidání dárku („Quick Add“) s automatickým přesměrováním a načítáním metadat.

  • Plovoucí karty položek (rounded-4, shadow-sm).
  • Horizontální řada akčních tlačítek na spodní hraně každé karty.
  • Zvětšení náhledů na 100x100 s ošetřením přetékání.
  • Kompaktní zobrazení s kruhovými náhledy.
  • Obdélníková glassmorphism hlavička wishlistu.
  • Hlavičky kategorií jako jemné barevné stuhy.
  • Čistý blok pro obecné preference / poznámky.

  • Možnost přidat spoluvlastníky s plnými právy pro správu položek i seznamu.
  • Spoluvlastníci nemohou zamlouvat dárky na společném seznamu.
  • Chip-based rozhraní pro správu spoluvlastníků v modalu.
  • Zobrazení odznaku „vlastník“ a potvrzovací modální okno pro odebrání spoluvlastníka.
  • Podpora zobrazení sdílených seznamů v detailech skupin.

  • Načítání metadat z URL: Vylepšené stahování názvu, ceny a obrázku s ošetřením chyb 403 Forbidden a čištěním sledovacích parametrů.
  • Prioritizace položek: Zjednodušený systém priorit (Vysoká, Normální, Nízká) s vizuálním barevným pruhem a filtrem.
  • Surprise Mode: Zákaz spoilerů pro vlastníky – skrytí informací o tom, kdo položku zamluvil nebo koupil.
  • Kopírování položek: Možnost zkopírovat dárek do jiného vlastního seznamu bez opuštění stránky.
  • Veřejné sdílení dárků: Unikátní veřejný odkaz na obdržené dárky bez možnosti správy a s anonymizací dárců.
  • Časová razítka seznamů: Signály automaticky aktualizují updated_at wishlistu při změnách položek.