## MODIFIED Requirements ### Requirement: Every public page emits title, description and canonical The system SHALL render a unique ``, a `<meta name="description">` and a `<link rel="canonical">` on every public route (SPEC §6.6, §19). Portfolio cases and wedding modalities MUST use `meta_title`/`meta_description` when filled and fall back to title/name and summary/hero lead otherwise. Pages without page-level metadata MUST fall back to `default_meta_title` and `default_meta_description` from `site_settings`. #### Scenario: Page-level metadata overrides defaults - **GIVEN** a published case with `meta_title` and `meta_description` filled - **WHEN** a visitor loads the case detail - **THEN** the rendered title and description MUST use the case values #### Scenario: Wedding modality metadata overrides defaults - **GIVEN** a published wedding modality with `meta_title` and `meta_description` filled - **WHEN** a visitor loads `/pacotes/{slug}` - **THEN** the rendered title and description MUST use the modality values #### Scenario: Missing metadata falls back to site defaults - **GIVEN** a published case without `meta_title` - **WHEN** a visitor loads the case detail - **THEN** the rendered title MUST be derived from the case title - **AND** the description MUST fall back to the case summary or the site default #### Scenario: Canonical points to the absolute route URL - **WHEN** any public page is rendered - **THEN** the canonical URL MUST be the absolute URL of that route without query parameters ### Requirement: Open Graph metadata is emitted for sharing The system SHALL emit Open Graph tags (`og:title`, `og:description`, `og:type`, `og:url`, `og:image`) on public pages. The image MUST use the page cover/hero image when available and `default_og_image_path` from `site_settings` otherwise. #### Scenario: Case detail uses its cover as OG image - **GIVEN** a published case with a cover image - **WHEN** the case detail is rendered - **THEN** `og:image` MUST reference the case cover image URL #### Scenario: Wedding modality detail uses hero as OG image - **GIVEN** a published wedding modality with a hero image - **WHEN** `/pacotes/{slug}` is rendered - **THEN** `og:image` MUST reference the modality hero image URL #### Scenario: Pages without cover use the default OG image - **WHEN** a page without its own image is rendered - **THEN** `og:image` MUST reference `default_og_image_path` ### Requirement: Sitemap and robots are served by the application The system SHALL serve `/sitemap.xml` listing the home, institutional routes, the services listing, the portfolio listing, every published case slug, and every published wedding modality slug with its last modification date. `/robots.txt` MUST be served by an application route referencing the sitemap URL. #### Scenario: Sitemap contains only published slugs - **GIVEN** one published case and one draft case - **WHEN** `/sitemap.xml` is requested - **THEN** the response MUST include the published slug - **AND** MUST NOT include the draft slug #### Scenario: Sitemap contains published wedding modality slugs - **GIVEN** one published wedding modality and one draft wedding modality - **WHEN** `/sitemap.xml` is requested - **THEN** the response MUST include `/pacotes/{published-slug}` - **AND** MUST NOT include the draft modality slug #### Scenario: Newly published case enters the sitemap - **WHEN** an admin publishes a case - **THEN** the case slug MUST appear in `/sitemap.xml` on the next request #### Scenario: Newly published wedding modality enters the sitemap - **WHEN** an admin publishes a wedding modality - **THEN** the modality package URL MUST appear in `/sitemap.xml` on the next request #### Scenario: Robots references the sitemap - **WHEN** `/robots.txt` is requested - **THEN** the response MUST be `text/plain` - **AND** MUST contain the absolute `/sitemap.xml` URL