Tasky
161 taskůKanban board se všemi tasky napříč projekty.
i18n soubory měly paritní strukturu (116ř každý) i pro nepřeložené texty. Přidal jsem 28 klíčů visitPlan.* do cs.json a propsal CS placeholder do 8 dalších locales — zachovává konvenci, Sprint 005 pak přeloží jediným průchodem.
pages collection byla prázdná. Vytvořil jsem dvě content entries: plan-navstevy.md (43ř — autem/vlakem/autobusem/parkování prózní text) a kombinovane-vstupne.md (51ř — 5 cenových tier sekcí). Markdown je flexibilnější než hardcoded i18n stringy a Sveltia CMS později pohodlně edituje.
Stránka /plan-navstevy/ neexistovala, header CTA Naplánovat návštěvu vedl na 404. Postavil jsem index.astro (215ř) s 6 sekcemi: hero, getting there + adresa/GPS dl, OSM iframe mapa s odkazy, otevírací doba, doporučená délka (3 varianty), kombinované vstupné + Colosseum CTA. OSM iframe je bez API klíče a tracker-free.
Header CTA Vstupenky i homepage pillar Kalendář akcí byly v kódu wired už od Run 003/004 přes siteConfig.ticketsUrl a localizedPath. Předtím vedly na 404 protože cíle neexistovaly — teď když /kalendar/ (Run 007) a /plan-navstevy/ (Run 008) běží, všechny CTA z homepage fungují bez editu.
Hub /kalendar/ neexistoval. Server-rendered listing s dvěma sekcemi (Co se chystá + Proběhlo), getCollection sortuje upcoming asc / past desc. Past sekce defaultně viditelná v HTML, JS po hydraci skryje (no-JS gracefully shows everything).
Filtrace neexistovala. Svelte 5 runes island ($state pro hodnoty, $derived pro hasFilters, $effect pro DOM toggle .hidden přes data-attributes na cards). Tři selecty: kategorie, měsíc, pořadatel + tlačítka reset a Zobrazit archiv. Přidává @astrojs/svelte 8.1 + svelte 5.55 do projektu.
Detail neexistoval. Vzor: zazitky/[slug].astro — getStaticPaths + render Content + EventMeta + related events (upcoming-only, slice 2). Eyebrow s kategorií místo 'Návštěva'.
Events collection byla prázdná. Stáhli jsme 3 reálné akce z zamekzdar.cz/kalendar/ (Den otevřených lesů, KoresponDance, výstava Gruzie UNESCO) a doplnili 5 dalších typických (akademie, koncert, kino, dva trhy) — celkem 8 markdownů v cs/. i18n přibylo 41 events.* klíčů × 9 lokalit (cs plné, 8× CS placeholder).
Card a meta strip pro detail. EventCard kopíruje vzor ExperienceCard, ale meta = datum + místo + kategorie badge; faded styl + Proběhlo badge pro past. EventMeta = pět položek (datum, kategorie, místo, cena od, pořadatel) v gridu.
ExperienceCard (4:3 placeholder + perex + duration/price meta) sdílený mezi hubem a related listem. ExperienceMeta (info strip pro detail) dynamicky skipuje chybějící pole.
14 i18n klíčů experiences.* do 9 jazyků (CS plné texty, 8 ostatních dostalo CS placeholder per konvence z Run 003 — Sprint 005 přeloží). PLAN.md + sprint.md + done.md hotové, smoke build 0 errors.
Vznikla CS hub stránka /zazitky/ — listing tří zážitků z content collection sorted podle order fieldu, empty state pokud žádné CS entries. Per-locale hub byl smazán kvůli Astro routing konfliktu, i18n fallback to řeší.
Detail šablona /zazitky/[slug] generuje stránku pro každý CS entry. Renderuje markdown body, hero, meta strip s délkou/cenou/sezonou/audience/locací, ticket CTA a max 2 related zážitky.
Tři CS markdown soubory (Muzeum nové generace, Herna InventoriUM, Prohlídka konventu) s rich storytellingem v luxury institutional duchu. Frontmatter podle existujícího schema — perex, audience, season, duration, price_from, ticket_url, location, order, seo.
Header neměl skip-link klíč, mobile menu mělo hardcoded aria-label, Footer obsahoval inline 'Navigace' text a chyběl IČO. Přidány klíče header.skip, header.menu.open/close, lang.switcher.label, footer.navigation/contact/directions/legal.iczo plus nav.aria.primary/footer (přidáno během /review jako fix nelokalizovaného aria-label) do 9 lokalit, 8 ne-CS jako CS placeholder do Sprintu 005.
Web měl 9 jazykových mutací bez UI přepínače mezi nimi. Nový LangSwitcher používá native HTML <details>/<summary> dropdown — žádný JS framework, built-in browser state + keyboard a screen reader podpora. Aktuální locale highlightnutý bronze s aria-current, page remap přes stripLocaleFromPath + localizedPath. Dvě varianty (desktop popout vpravo, mobile inline pod nav linky).
Navbar z Run 001 byl placeholder s hardcoded CS texty bez lang switcheru, ticket CTA ani locale propagace. Refactor: locale Props, navItems array s tKey+href přes t() lokalizaci, externí ticket CTA v bronze accent vpravo s target=_blank, integrace LangSwitcheru, lokalizované aria-labels mobile menu přes data-attrs. Mobile breakpoint posunut z md na lg, protože 7 nav linků se na md nevejde.
Footer z Run 001 měl jen 2 sloupce (brand + nav) bez kontaktů, mapy, otevírací doby ani social. Refactor na 4 sloupce: (1) brand + popis + IČO + drobný ticket button, (2) Navigace lokalizovaná, (3) Kontakt s adresou, Google Maps link, tel a mailto linky, (4) Otevírací doba (sezóna + mimosezóna) + Lucide ikony Instagram/Facebook. Bottom row copyright + year.
BaseLayout volal Navbar a Footer bez locale propu, takže vnitřek nemohl lokalizovat. Přidána import createT, instance t pro skip-link (t('header.skip') místo hardcoded 'Přeskočit na obsah'), a propagace locale do Navbaru i Footeru. Skip-link tak respektuje aktuální jazyk stránky.
Obě homepage stránky (default a [locale]) ukazovaly placeholder z Run 001. Nahrazeno kompozicí Hero → IntroSection → PillarsGrid → SantiniStory přes BaseLayout. Locale prop propagován ze stránky do každé komponenty pro createT překlady.
Run 002 nechal duplicitní font-display jako Tailwind class i jako globální h1-h4 rule. Vybrán B-variant: smazána Tailwind class z SectionHeading, globální rule v global.css zůstává jako default. Plus přidány homepage překladové klíče (hero/intro/pillars/santini) do cs.json a propagovány do 8 lokalit jako CS placeholder (strojový překlad přijde Sprint 005).
Homepage měla jen centrovaný h1 z Run 001. Hero komponenta postaví 12-col asymmetric grid: vlevo eyebrow + display heading + lede + dvě CTA (primární Plán návštěvy do bronze accent, sekundární Objevit více jako outline scroll na #intro), vpravo placeholder portrait aspect-[4/5] s diagonal stripe pattern dokud nepřijde reálná foto.
Story sekce chyběly úplně. IntroSection postaví symmetrický 2-col text blok (heading vlevo, dvě těla odstavce vpravo) s ID intro pro #intro scroll z Hero. SantiniStory postaví 12-col asymmetric s textem + CTA do historie vlevo a pull-quote v Cormorant italic v figure vpravo.
Návštěvník neměl jak skočit do hlavních sekcí. PillarsGrid přidává 4 karty v 2x2 gridu (Zážitky/Ubytování/Kalendář/Vzdělávání) s placeholder image, titulkem, perexem a CTA. Karty směřují na lokalizované cesty z siteConfig.navLinks — cílové stránky přijdou v Sprint 002 a 004.
Web měl jen Inter sans z kostry, který nepasoval na luxury institutional brief. Přidán Cormorant Garamond jako druhý font přes Astro Fonts API (--font-cormorant) s preload v BaseLayout. Inter zůstává pro tělový text, Cormorant pro nadpisy.
global.css obsahoval kostra-šablonový design system — modrý primary, dark/light toggle, glass panely, glow shadows. Přepsán na single light theme s cisterciácko-barokní paletou (canvas/paper/surface ivory + ink scale + bronze accent + rule borders) a typografií displaye/sans. Connector ke všem dalším runům.
Web bude mít desítky sekcí napříč 9 lokalitami, opakovat inline mx-auto max-w-... px-... by ravioli kód. Vytvořeny dva primitivy v src/components/ui/: Container (4 max-width hodnoty), Section (3 spacing × 3 tone). Section vědomě nevkládá automaticky Container — full-bleed sekce vyžadují explicit kompozici.
Section headery se opakují napříč webem ve stejném tvaru (eyebrow + display title + lede + decentní bronze rule). Vytvořena kompoziční komponenta SectionHeading s align left/center a as h1/h2. Jednotnost přes desítky sekcí > flexibilita; pokud zatím přijde edge case (decorative ornament), doplníme slot.
Bez vizuálního benchmarku není jak ověřit, jestli paleta a typografie ladí na pozadí Versailles/Louvre briefu. Vytvořena interní /design-system stránka s noindex,nofollow — palette swatches, typografická scale, Container a Section varianty, SectionHeading 3 ukázky. Single-scroll dev artefakt.
pnpm check 0/0/0, build OK. Sprint 002 KOMPLETNÍ: 17/17 druhů s galerií. Všechny rody tučňáků pokryté. Deploy na produkci.
magellansky: Puñihuil Chiloé 2025 QI (C.J.Sharp CC BY-SA 4.0), Saunders Falkland 2017 (A.Shiva), objímající pár (Stch2022 CC BY 4.0 — Wiki Science Competition 2025 winner).
galapazsky: Fernandina lávové skály (J.Preston CC BY 2.0 2005), plavání Isabela (A.Skujins CC BY-SA 3.0 2013), detail Galapágy 2025 (E.Leung CC BY-SA 4.0).
pnpm check 0/0/0, build OK. Sprint 002: 15/17 druhů s galerií. Zbývá Run 007e2 (magellansky + galapazsky).
zlutooky: rodina Otago (Steve CC BY-SA 2.0), pláž Otago (Bartux CC BY-SA 3.0), hnízdní bouda Penguin Place (Pseudopanax PD). Fokus na Otago — hlavní chráněná oblast.
nejmensi: Oamaru beach (Avenue CC BY-SA 3.0), Bruny Island Tasmánie (JJ Harrison CC BY-SA 3.0), pelichání Taputeranga (Kimberley Collins CC BY-SA 4.0). Pokryto NZ + AU.
brylovy: Boulders QI (Diego Delso CC BY-SA 4.0), páření (Votpuske CC BY 4.0 2023), FWS portrét (Dee Boersma PD). CR druh.
humboldtuv: Ballestas group (Dennis Jarvis CC BY-SA 2.0), kolonie Caldera Chile (Carlos Teixidor CC BY-SA 4.0 2022), Ballestas pár (Lisa Weichel CC BY 2.0). Pokryto Peru + Chile.
sclateruv: hnízdní pár Bounty (C00ch, CC BY-SA 4.0), v moři (C. Stephens), kolonie Antipodes (LawrieM, PD). Pokryje Bounty+Antipodes+moře.
pnpm check 0/0/0, build OK. Rod Eudyptes 6/6 druhů s galerií. Sprint 002: 11/17.
skalni-severni: 3× Antoine Lamielle z Amsterdam Island (TAAF), CC BY-SA 4.0. Commons kategorie postrádá chicks/swimming.
snaresky: skupina (Lin Padgham, CC BY 2.0), potápění (Brocken Inaglory, CC BY-SA 3.0), skály Southland (C. Stephens, CC BY-SA 4.0 2023).
royal: kolonie 60k Macquarie (Kimberley Collins, CC BY-SA 4.0), face close-up (Lin Padgham, CC BY 2.0), beach (M. Murphy, PD).
pnpm check 0/0/0, build OK (129 obrázků webp). Absolutní cesty dodrženy — cwd bug z 007b se neopakoval.
skalni-jizni: kolonie West Point + hopping Saunders (Liam Quinn, CC BY-SA 2.0), 2024 detail New Island (Stefan Brending, CC BY-SA 3.0 DE).
zlatovlasy: Cooper Bay v trsech trávy (Liam Quinn), Half Moon Island detail 2025 (lwolfartist), Murrell Farm (Nick). 3× CC BY/BY-SA 2.0.
pnpm check 0/0/0, build OK (86 obrázků × 4 webp widths). Fixed cwd bug (nested paths z shodných cd mezi volání). 18 files, +245 řádků.
patagonsky: Salisbury Plain adult (A. Shiva, CC BY-SA 4.0, QI), Gold Harbour mláďata (Butterfly austral, CC BY-SA 3.0), Fortuna Bay juvenile pelichání (A. Shiva, CC BY-SA 4.0, QI). Dokončuje rod Aptenodytes.
krouzkovy: skok z vody (Rob Oo, CC BY 2.0), mláďata Paulet Island (Grant.C, CC BY 2.0), 3 adultní Jižní Shetlandy (ravas51, CC BY-SA 2.0 — Featured picture, POTD 2023-11-26).
osli: kolonie Murrell Farm Falklandy (Nick, CC BY 2.0), mládě Antarktida (C. Michel, CC BY 2.0), dospělec Waterboat Point (Liam Quinn, CC BY-SA 2.0).
uzdickovy: kolonie Jižní Shetlandy (C. Michel, CC BY 2.0), dospělec s mláďaty Seal Island (NOAA PD), detail hlavy Half Moon Island (lwolfartist, CC BY 2.0).
src/pages/druhy/[slug].astro: SpeciesGallery nahrazuje inline gallery grid (-33 ř.), předává photos a galleryId=gallery-${entry.id}.
3 fotky cisarsky (Ian Duffy CC-BY 2.0, François Guerraz CC-BY-SA 3.0, Matthieu Weber PD). Frontmatter gallery + CREDITS záznamy.
pnpm check 0/0/0, typecheck 0, build OK (29 obrázků + 18 stránek), lint pouze 2 warnings v auto-generated worker-configuration.d.ts. A11y: native dialog focus trap, ESC, keyboard nav, aria-live.
MCP docs ověřeny v předchozí session (Astro 6 <script> pattern + native <dialog> + aria-live). Kontext7 quota vyčerpán v review-fázi, ale pattern byl ověřen před implementací.
SpeciesGallery.astro (105 ř.) grid+dialog, lightbox.ts (62 ř.) vanilla TS init per-section, lightbox.css (124 ř.) scoped ::backdrop + no-crop invariant.
WebFetch CS+EN Wiki + IUCN pro 3 druhy. S. demersus 2024 přeřazen z EN na CR (~19 800 dospělých). S. humboldti VU, ~23 800 dospělých. S. magellanicus LC, >1,3 mil párů. Všechny mají CS Wiki = 4 zdroje per druh. IUCN assessment IDs: 22697810/256021744, 22697817/182714418, 22697822/157428850.
Wikimedia Commons hero fotky: Bernard Gagnon CC BY-SA 4.0 (Boulders Beach 2017), Pete Cable CC BY 2.0 (Islas Ballestas Peru 2013), Diego Delso CC BY-SA 3.0 (Seno Otway Chile 2007). Uloženo do src/assets/penguins/<slug>/hero.jpg, CREDITS.md rozšířen o 3 záznamy.
src/content/species/brylovy.md (51 ř., CR, 4 zdroje), humboldtuv.md (53 ř., VU, 4 zdroje), magellansky.md (53 ř., LC, 4 zdroje). Review odchytil 2P + 2W (překlep pukliných, odstraněná diakritika pajaro-niño, zaměněné Scomberesox vs Belonidae, nutrie vs mara) — vše opraveno.
pnpm check = 0 errors / 0 warnings / 0 hints (23 files). pnpm build úspěšný, 17 /druhy/[slug] stránek prerenderováno, 17 hero obrázků optimalizováno.
Výzkum 3 druhů (Megadyptes antipodes, Eudyptula minor, Spheniscus mendiculus) přes EN Wikipedia + CS Wikipedia (existuje pro všechny 3). 4 zdroje per druh: CS + EN Wiki + IUCN + BirdLife.
3 hero fotky: Mehlführer (CC BY 2.5, Curio Bay), Jolaus (CC BY 4.0, Waipatiko), putneymark (CC BY-SA 2.0, Isabela). Záznamy v src/assets/penguins/CREDITS.md.
3 nové MD soubory v src/content/species/ (~52 radku each). V review opravena geograficka chyba (Phillip Island Victoria, ne Tasmanie). Nova lekce: typograficke uvozovky nesmi byt v YAML stringu - parse error.
pnpm check 0/0/0, pnpm typecheck 0 errors, pnpm build prerenderoval 14 druhu + /druhy index. Prvni draft mel YAML parse error kvuli typografickym uvozovkam, opraveno.
EN Wiki WebFetch 3 druhů (moseleyi/robustus/sclateri) — získány historické popisy, populace, distribuce. BirdLife factsheet má dynamický loading, tahat data z EN Wiki.
3 hero fotky z Wikimedia Commons: Brian Gratwicke (CC BY 2.0), Thomas Mattern (CC BY-SA 3.0), C00ch (CC BY-SA 4.0). Záznamy v src/assets/penguins/CREDITS.md podle existující konvence.
3 nové MD soubory v src/content/species/ (skalni-severni 46 ř., snaresky 46 ř., sclateruv 47 ř.). Všechny prošly schema validací. V /review opravena gramatická chyba sclaterovu → Sclaterovu.
pnpm check 0/0/0, pnpm typecheck 0 errors, pnpm build prerenderoval 11 druhů + /druhy index. První draft description skalní severní překročil 240 zn., zkrácen.
pnpm check/typecheck/build: 0 errors, 0 warnings, 0 hints. Build prerenderoval 8 druhů (cisarsky + 3 Pygoscelis + 4 z 006b1) + /druhy/ index + /robots.txt + /404.
WebFetch CS Wikipedia (patagonský, skalní-jižní) + EN Wikipedia (zlatovlasý, royal — CS články 404) + Commons kategorie a file pages pro metadata autor/licence/URL. BirdLife factsheet URLs ověřené patternem. Výstup: fakta pro 4 frontmattery.
Curl 2000px thumby z upload.wikimedia.org (patagonsky 838KB, skalni-jizni 592KB, zlatovlasy 585KB, royal 639KB originál). 4 záznamy v CREDITS.md:57-103 konzistentní s existující konvencí autor/licence/zdroj/originál/místo/datum/staženo/použití.
4 schema-validované MD soubory (patagonsky, skalni-jizni, zlatovlasy, royal) s YAML frontmatterem a 2 odstavci populárně-naučného textu. 4 zdroje u patagonsky/skalni-jizni, 3 u zlatovlasy/royal (CS Wiki neexistuje). Review fixy gramatické shody neutra peří/péra, distinct IUCN assessment IDs.
3x curl hero z Wikimedia Commons (Jason Auch CC BY 2.0, Liam Quinn CC BY-SA 2.0, Christopher Michel CC BY 2.0). CREDITS.md 3 nove zaznamy.
3 markdown soubory — schema-validovane frontmatery, 4 zdroje kazdy (Wiki CS+EN, IUCN, BirdLife), 2 odstavce populárně-naučného textu. YAML fix: typograficke uvozovky pro uzdickovy.
pnpm check + typecheck + build — 0/0/0. Prerendered /druhy/{cisarsky,krouzkovy,osli,uzdickovy}/ + /druhy/ index.
WebFetch 3x CS Wikipedia (P. adeliae/papua/antarcticus) — taxonomie, velikost, distribuce, dieta, lifespan, populace, IUCN, historie. IUCN blokuje WebFetch (403), BirdLife OK.
src/components/species/IucnBadge.astro (47 radku) — shared badge, status+size props, cs labels + tone maps. SpeciesCard refaktorovany na nej (43 radku).
SpeciesHero.astro (57 r), SpeciesFacts.astro (83 r s fmtRange/fmtYears cs pluralizaci), SpeciesSources.astro (58 r s Intl.DateTimeFormat cs-CZ). Vse cerpa z CollectionEntry<species>.
src/pages/druhy/[slug].astro (101 radku) — getStaticPaths satisfies GetStaticPaths, render(entry) → <Content/>, prose prose-invert prose-lg, conditional historie + galerie, zpet nav.
pnpm check + typecheck + build — vse 0/0/0. Prerendered /druhy/cisarsky/index.html.
src/components/species/SpeciesCard.astro (67 radku) — CollectionEntry<species> props, hero pres NoCropImage ratio 4/3, IUCN badge s ceskou legendou a barevnym tonem per status, line-clamp-3 popis.
src/pages/druhy/index.astro (57 radku) — prerender=true, getCollection('species') + localeCompare(cs) sort, grid 1/2/3 responzivne, empty state, count s aria-live.
pnpm check, typecheck, build — vse 0/0/0. Build prerenderoval /druhy/index.html.
Vytvoren docs/sprints/002-species/sprint.md (Druhy sprint, scope 4 runu) + run-004-druhy-index.done.md (zadani, reseni, poznamky).
src/content.config.ts (72r): defineCollection + glob loader + schema({image}) s zod v4. Fields: taxonomie, IUCN enum, size tuple, distribution/diet arrays, lifespan, hero s image() helperem, gallery?, sources min 2 (enum typu), updatedAt. Import z z astro/zod (ne astro:content — deprecated v Astro 6). Zod v4 API: z.url() misto .url().
git mv emperor-penguin-snow-hill.jpg → cisarsky/hero.jpg. Konvence per-druh adresar src/assets/penguins/<slug>/ dokumentovana v CREDITS.md. Aktualizovan import v src/pages/index.astro:6.
src/content/species/cisarsky.md (49r): tucnak cisarsky, kompletni data (velikost/vaha/IUCN NT/distribuce/dieta/lifespan), 4 ověřené zdroje (Wiki CS/EN, IUCN, BirdLife), dva paragrafy populárně-naučného textu o hnizdeni a Terra Nova expedici.
PROJECT.md — sekce Datový model druhů s povinnymi/volitelnymi poli, pravidlem min 2 sources, hero/gallery pres image() → NoCropImage, odkazem na cisarsky.md jako priklad. Doplnena konvence per-druh adresare do sekce Fotky.
Po opravě Astro 6 Zod v4 importu: pnpm build + pnpm check → 0/0/0. Build optimalizoval cisarsky/hero.jpg do WebP. Schema validace na cisarsky.md (4 zdroje) prosla.
Stazena Ian Duffy CC-BY 2.0 foto Snow Hill Island (872x1400) pres MediaWiki API. Ulozeno do src/assets/penguins/ + CREDITS.md. Pouzita na homepage s <figure> + <figcaption> + licence.
PROJECT.md — sekce Vizualni pravidla rozsirena o pripad pouziti NoCropImage s kod snippetem, utility .img-nocrop, a povinnost CREDITS.md pro kazdou fotku.
typecheck + build: 0/0/0. Build generuje WebP variantu. Playwright screenshot (1280x900 full page) potvrzuje foto cele, paleta ledova, figcaption s licenci. .gitignore: .playwright-mcp/ + *-run*.png.
global.css: :root + light sky/teal tokeny (primary #0ea5e9 dark / #0284c7 light, accent teal). .img-nocrop utility (object-fit contain, 100% rozmery).
src/components/media/NoCropImage.astro (34r): wrapper div s aspect-ratio inline style + astro:assets Image s .img-nocrop. Props src (ImageMetadata), alt povinny, ratio default 4/3, sizes, loading.
siteConfig: name pingupedia, description, url https://pingupedia.cz/, navLinks /druhy/ a /o-projektu/. astro.config.mjs: site na pingupedia.cz, Inter font zachován.
index.astro: hero 80vh s 2 paragrafy a CTA na /druhy/ + /o-projektu/. 404.astro: 'Tucnaci odplouli jinam', CTA 'Zpet na pevninu'.
Smazano: src/content/blog/, src/pages/blog/, src/pages/rss.xml.js, src/content.config.ts. Odstranen RSS link v Seo.astro:37.
README prepsan — popis projektu + tech stack + scripts. Smazany kostra docs: manual.md, step-by-step.md, create-admin.md, claude-commands.md.
pnpm typecheck + pnpm build: 0 errors, 0 warnings, 0 hints. Prerender: /, /404.html, /robots.txt.
src/lib/db.ts helper + přepsány galerie/index.astro a [...slug].astro na SSR+D1
Build + typecheck + astro check 0 errors
Album má 30 obrázků — všechny staženy v run 007
30 obrázků nahráno do R2 v run 007
src/pages/api/images/[...key].ts — R2 get + cache headers
GitHub Actions workflow .github/workflows/deploy.yml — pnpm install, build, cloudflare/wrangler-action@v3. Trigger: push to master.
pnpm typecheck (0 errors), pnpm check / astro check (0 errors, 0 warnings), pnpm build (success).
PLAN.md: run 006 [x], sprint 002 hotovo. PROJECT.md: milestone Produkce dokončen.
public/og-image.svg — 1200×630 SVG placeholder. site.ts aktualizován.
link rel=sitemap href=/sitemap-index.xml přidán do Seo.astro head.
Site URL opraven na escher.kafe.studio v astro.config.mjs. RSS link odstraněn z Seo.astro.
Schema.astro přepsán — BlogPosting nahrazen ImageGallery + VisualArtwork typy.
VisualArtwork schema na [...slug].astro via slot=head. ImageGallery na galerie/index.astro.
Amber/gold oklch accent, teplé neutrály, prose variables pro tmavé téma. global.css
Astro.url.pathname + isActive(), aria-current=page, hover na logo. Navbar.astro
Rounded-xl border + bg-card, gradient overlay, shadow-lg hover. galerie/index.astro
SVG šipka zpět, border na obrázku, separátory v metadatech. [...slug].astro
src/lib/categories.ts — categoryLabels Record + categories array s Vše. Import v obou stránkách.
Client-side filtr v index.astro — tlačítka kategorií, toggle hidden, no-results message
src/pages/galerie/[...slug].astro — getStaticPaths, render(), dl/dd metadata, back link
astro check — 0 errors, 0 warnings
src/pages/galerie/index.astro — responzivní grid 1/2/3 sloupce, řazení od nejnovějších
Schema v src/content.config.ts — z.enum pro technique (6) a category (5), glob loader, zod validace
Kategorie jako enum v schema — technique + category enums
8 děl v src/content/artworks/*.md + SVG placeholdery v public/images/artworks/
src/config/site.ts — Galerie Escher, navLinks na /galerie/
astro check — 0 errors, 0 warnings