<?xml version="1.0" encoding="UTF-8"?>
<!--
  Hand-maintained against app.routes.ts (and, for the two course-details
  pages, core/course-detail-pages.ts): this is a pure client-side SPA with
  no server-side route registry to generate this from, so whoever adds or
  removes a public route there should mirror it here too. Deliberately
  excludes:
    * `/home`: redirects to `/`, would just read as duplicate content.
    * everything under `/admin`: private, also blocked in robots.txt.
    * `/sprawdz-siebie/test`: the timed reading-test flow itself; a real
      page, but an interactive tool rather than a landing page, so there's
      nothing worth sending search traffic to directly.
    * the wildcard 404 route: not a real page.
  `/sprawdz-siebie` is listed even though it's gated behind the
  "sprawdzSiebie" feature flag (see FeatureFlagService): every flag defaults
  to enabled, and a disabled flag just soft-redirects a crawler back to `/`
  rather than erroring.

  URL FORMAT (2026-09, on the szybkieczytanie-web.antonio25698.workers.dev ->
  szybkieczytanie.lodz.pl domain move): every <loc> below uses the
  `/#/route` hash-fragment form, matching SeoService's own canonical/og:url
  generation (`${origin}/#${url}`, see that file's comment) -- NOT the
  bare `/route` form this file used to list. That wasn't just a style choice:
  this app runs `withHashLocation()` (app.config.ts), and Cloudflare serves
  index.html for every unknown path (wrangler.jsonc's
  `not_found_handling: single-page-application`) -- so a crawler that
  requests a bare `/oferta` gets index.html with an *empty* hash, which
  Angular's router resolves to the HOME route, not Oferta. Confirmed against
  the real dev server, and independently corroborated by
  docs/content-source-map.md's own routing note ("navigate to /#/oferta,
  not /oferta, or the router won't pick up the route"). Every bare-path
  <loc> this file used to list was therefore advertising a URL that silently
  serves the homepage instead of the page it claims to -- fixed here, not
  just re-domained.

  Known, unresolved limitation (flagged, not silently worked around): a `#`
  fragment is not a distinct resource per URL semantics -- browsers, and by
  most accounts Google's own canonicalization, treat `/#/oferta` as an
  in-page fragment of `/`, not a separate page. Googlebot does execute JS
  and can in principle render and index the fragment-specific content, but
  there's no guarantee it treats N different hash-fragment URLs as N
  distinct indexable pages rather than collapsing them toward the root.
  These URLs are still the most honest ones to publish (they're the actual
  working, content-correct address for each page -- unlike the bare-path
  form, which is provably wrong), but the real, durable fix is dropping
  `withHashLocation()` for path-based routing; see TODO.md's SEO section for
  the full writeup and why that's a separate decision, not folded in here.

  Update the domain below everywhere it appears (here, robots.txt's Sitemap
  line, src/index.html's static og:url/og:image) if the site ever moves off
  szybkieczytanie.lodz.pl too -- see wrangler.jsonc's own comment, and note
  its list is itself incomplete (missing CLAUDE.md, docs/content-source-map.md,
  email-templates/, per TODO.md's SEO section).
-->
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://szybkieczytanie.lodz.pl/#/</loc>
    <changefreq>weekly</changefreq>
    <priority>1.0</priority>
  </url>
  <url>
    <loc>https://szybkieczytanie.lodz.pl/#/oferta</loc>
    <changefreq>weekly</changefreq>
    <priority>0.9</priority>
  </url>
  <url>
    <loc>https://szybkieczytanie.lodz.pl/#/terminarz</loc>
    <changefreq>weekly</changefreq>
    <priority>0.9</priority>
  </url>
  <url>
    <loc>https://szybkieczytanie.lodz.pl/#/aktualnosci</loc>
    <changefreq>weekly</changefreq>
    <priority>0.8</priority>
  </url>
  <url>
    <loc>https://szybkieczytanie.lodz.pl/#/metodyka</loc>
    <changefreq>monthly</changefreq>
    <priority>0.7</priority>
  </url>
  <url>
    <loc>https://szybkieczytanie.lodz.pl/#/kursy/czytanie-dla-mlodziezy-doroslych</loc>
    <changefreq>monthly</changefreq>
    <priority>0.7</priority>
  </url>
  <url>
    <loc>https://szybkieczytanie.lodz.pl/#/kursy/czytanie-dla-mlodziezy-doroslych-wakacyjny</loc>
    <changefreq>monthly</changefreq>
    <priority>0.7</priority>
  </url>
  <url>
    <loc>https://szybkieczytanie.lodz.pl/#/czytanie-dla-dzieci</loc>
    <changefreq>monthly</changefreq>
    <priority>0.7</priority>
  </url>
  <url>
    <loc>https://szybkieczytanie.lodz.pl/#/kontakt</loc>
    <changefreq>monthly</changefreq>
    <priority>0.6</priority>
  </url>
  <url>
    <loc>https://szybkieczytanie.lodz.pl/#/sprawdz-siebie</loc>
    <changefreq>monthly</changefreq>
    <priority>0.6</priority>
  </url>
  <url>
    <loc>https://szybkieczytanie.lodz.pl/#/zespol</loc>
    <changefreq>monthly</changefreq>
    <priority>0.5</priority>
  </url>
  <url>
    <loc>https://szybkieczytanie.lodz.pl/#/polityka-prywatnosci</loc>
    <changefreq>yearly</changefreq>
    <priority>0.3</priority>
  </url>
</urlset>
