# public-site-pages Specification ## Purpose Define public routes, editorial home, catalog pages, institutional/error pages, and contact placeholder for the marketing site. ## Requirements ### Requirement: Public routes serve published content without authentication The system SHALL expose the public routes of SPEC §5.1: `home` (`/`), `services.index` (`/servicos`), `portfolio.index` (`/portfolio`), `portfolio.show` (`/portfolio/{slug}`), `about` (`/sobre`), `contact` (`/contato`) and `privacy` (`/privacidade`). Every public route MUST respond without authentication and MUST NOT expose unpublished content, internal fields, or internal notes (SPEC §19). #### Scenario: Guest reaches every public route - **WHEN** an unauthenticated visitor requests any public route - **THEN** the response status MUST be 200 - **AND** no redirect to `/admin/login` MUST occur #### Scenario: Unpublished content is invisible - **GIVEN** a service, portfolio case, or testimonial with `published_at` null - **WHEN** a visitor loads the corresponding public page - **THEN** the record MUST NOT appear in the rendered output #### Scenario: Unpublished case detail returns 404 - **GIVEN** a portfolio case saved as draft - **WHEN** a visitor requests `/portfolio/{slug}` for that case - **THEN** the response status MUST be 404 #### Scenario: Published case detail becomes reachable - **GIVEN** a portfolio case saved as draft - **WHEN** an admin fills the required fields and publishes the case - **THEN** `/portfolio/{slug}` MUST respond 200 - **AND** the case MUST appear in the `/portfolio` listing ### Requirement: Home renders the editorial structure from CMS content The home page SHALL render, in order: header/navigation, hero, manifesto, featured services summary, featured portfolio selection, working method (four steps), testimonials, Amare positioning/profile, final contact CTA, and footer with contact, social links and legal links (WEB-01). Hero copy, brand name, manifesto, method and principles MUST come from `site_settings` (with editorial defaults when optional fields are empty); services, cases and testimonials MUST come from published records. The home MUST follow the Heritage Editorial composition: asymmetric spreads and tonal fields on desktop, with portfolio images in alternating editorial proportions, and a linear complete sequence on mobile rather than rounded card grids. #### Scenario: Published content is displayed in configured order - **GIVEN** published services, cases and testimonials exist - **WHEN** a visitor loads the home - **THEN** the published content MUST be displayed following the `sort_order` and featured flags - **AND** the hero MUST show the values stored in `site_settings` - **AND** the manifesto, method and positioning sections MUST be present - **AND** the portfolio section MUST use an olive tonal field with editorial image proportions #### Scenario: CTA leads to the contact placeholder page - **WHEN** a visitor activates the primary or final CTA on the home - **THEN** the visitor MUST be taken to the `contact` route - **AND** no lead record MUST be created #### Scenario: Empty catalog sections are omitted - **GIVEN** no published services, cases or testimonials - **WHEN** a visitor loads the home - **THEN** the response MUST be 200 - **AND** the services, portfolio and testimonials sections MUST be omitted instead of rendering empty containers - **AND** hero, manifesto, method, positioning and final CTA MUST still render #### Scenario: Home has no console errors - **WHEN** the home is loaded in a real browser at desktop and mobile viewports - **THEN** the browser console MUST contain no JavaScript errors ### Requirement: Listing and detail pages exist for catalog content The system SHALL render a services listing (WEB-02) and a portfolio listing plus case detail (WEB-03) using the Heritage Editorial visual language. The case detail MUST present summary, event type, optional city/venue/date, challenge, solution, optional result, cover image and the ordered gallery. Portfolio listings and galleries MUST use alternating editorial image proportions on desktop while retaining DOM order and a single-column readable sequence on mobile. #### Scenario: Services listing renders editorial sections with published modalities - **WHEN** a visitor loads `/servicos` - **THEN** the page MUST present the two vertentes (Amare Casamentos and Amare Corporate) with CTAs to their sections - **AND** every published wedding modality MUST be rendered in `sort_order` with tag, name, subtitle, summary and scope - **AND** a quick-read comparison of the modalities MUST use each modality's `compare_heading` and `compare_summary` - **AND** unpublished modalities MUST NOT be rendered - **AND** the listing MUST use the public editorial layout (not an unrelated visual system) #### Scenario: Gallery respects stored order - **GIVEN** a published case with multiple gallery images - **WHEN** a visitor loads the case detail - **THEN** the images MUST be rendered ordered by `sort_order` - **AND** desktop presentation MUST alternate editorial image proportions without changing that order #### Scenario: Listings paginate open-ended growth - **WHEN** the number of published cases exceeds the page size - **THEN** `/portfolio` MUST paginate instead of rendering all records ### Requirement: Institutional and error pages have brand identity The system SHALL provide the Sobre and Política de privacidade pages and branded error pages (WEB-07) using the Heritage Editorial public layout, including the brand mark when available. Contact, privacy and error surfaces MUST remain sober tonal layouts without decorative photography. The 404 page MUST use the public layout, and the 500 page MUST NOT expose stack traces or internal details when `APP_DEBUG` is false. #### Scenario: Unknown URL renders branded 404 - **WHEN** a visitor requests a non-existent public URL - **THEN** the response status MUST be 404 - **AND** the page MUST use the public layout and offer navigation back to the home #### Scenario: Server error hides internals in production - **GIVEN** `APP_DEBUG` is false - **WHEN** an unhandled exception occurs on a public route - **THEN** the response MUST be a generic branded error page - **AND** MUST NOT contain a stack trace, file path, or environment variable ### Requirement: Contact page presents contact data as briefing placeholder The `contact` route SHALL render the contact page using `site_settings` (e-mail, phone, city, social links) so the home CTA has a valid destination before the briefing form exists. The page MUST NOT create leads and MUST NOT submit a functional briefing form in this change. #### Scenario: Contact page shows configured contact data - **WHEN** a visitor loads `/contato` - **THEN** the e-mail and phone stored in `site_settings` MUST be displayed - **AND** no lead record MUST be created ### Requirement: Public pages avoid N+1 queries Public pages SHALL load related content with explicit eager loading through dedicated read Queries in the Application layer. Rendering a page MUST NOT issue one query per related record (SPEC §19). #### Scenario: Case detail loads gallery in bounded queries - **WHEN** a case detail page with many gallery images is rendered - **THEN** the gallery MUST be loaded with eager loading - **AND** the query count MUST NOT grow with the number of images ### Requirement: Public header exposes brand mark and responsive navigation The public layout SHALL render the Amare brand mark (faceted-heart logo lockup or configured logo), primary route navigation, and a contact CTA. On narrow viewports the navigation MUST be operable via a disclosure control with accessible name and `aria-expanded` state. #### Scenario: Desktop header shows navigation and CTA - **WHEN** a visitor loads any public page at a desktop viewport - **THEN** the header MUST include brand mark, links to home/services/portfolio/about/contact, and a contact CTA #### Scenario: Mobile menu toggles accessibly - **WHEN** a visitor activates the menu button on a narrow viewport - **THEN** the primary navigation MUST become available - **AND** the control MUST expose an updated `aria-expanded` value - **AND** activating a navigation link MUST close the menu ### Requirement: Demonstrative photography is labeled until authorized assets exist When public pages render illustrative/demo photography that is not an authorized Amare asset, the system SHALL mark that imagery as demonstrative in visible copy or accessible labeling so visitors are not misled. #### Scenario: Portfolio demo imagery is disclosed - **WHEN** the home or portfolio renders placeholder photography - **THEN** a visible note or equivalent disclosure MUST indicate the imagery is illustrative pending authorized assets ### Requirement: Visual public and error pages expose the shared motion contract The system SHALL apply the shared progressive opening and reveal contract to home, services, portfolio index/detail, about, contact, privacy, and branded 404/419/429/500/503 pages. The contract MUST NOT change page copy, content ordering, route behavior, or structural layout. #### Scenario: Institutional page uses shared opening - **WHEN** a visitor loads `/sobre`, `/contato`, or `/privacidade` - **THEN** the page MUST expose the shared page opening hook and section reveal hooks #### Scenario: Error page remains branded and progressively enhanced - **WHEN** Laravel renders a branded 404, 419, 429, 500, or 503 response - **THEN** the page MUST expose the shared opening hook - **AND** all error guidance and navigation MUST remain immediately usable without enhancement