## Context `WeddingPackage` já cobre cards ordenados + CTA WhatsApp/briefing (change `restructure-home-weddings-corporate`, capability ainda só no delta completo). Campos atuais: `name`, `level`, `summary`, `scope_items` (json), `cta_label`, `sort_order`, `published_at`. Sem slug, sem corpo de detalhe, sem imagens. Portfólio (`portfolio.show`, `FindPublishedPortfolioCaseBySlug`, PageMeta, sitemap) é o padrão de detalhe a espelhar. Mock visual: `/home/manoelfreitas/Downloads/amare-assessoria-completa.html`. Tokens: `DESIGN.md` / `resources/css/tokens.css` (Heritage Editorial) — não Cormorant/Inter do HTML estático. ## Goals / Non-Goals **Goals:** - Detalhe CMS-driven `/pacotes/{slug}` para as 3 modalidades, publish-gated. - Composição mock → tokens do projeto (olive accent, EB Garamond via stack existente, bg cream). - CTA final = mesmo canal contextual dos cards (`wa.me` ou `/briefing?servico_interesse=`). - SEO mínimo: meta por registro, canonical, OG image (hero ou default), entrada no sitemap. - Admin Filament editável sem deploy de copy. **Non-Goals:** - Rota índice `/pacotes`; substituir cards da home; WhatsApp Business API; preços; multi-idioma; Livewire público; gallery multi-imagem além de hero + audience. ## Decisions ### Estender `WeddingPackage`, não criar modelo novo Uma entidade comercial já existe e é o que home/serviços já consomem. Detalhe é projeção do mesmo agregado. Modelo paralelo geraria sync de publicação/slug e viola YAGNI. ### Slug único + publicação por `published_at` Igual portfólio: URL estável, scope `published()`, query Application `FindPublishedWeddingPackageBySlug`. Draft/inexistente → 404 HTTP, sem vazar campos internos. ### Campos de detalhe (additive) | Campo | Uso | |-------|-----| | `slug` | string unique | | `eyebrow` | ex. "Assessoria" | | `title_line` | parte romana do H1 | | `title_emphasis` | parte itálica do H1 | | `hero_lead` | parágrafo do hero | | `hero_image_path` / `hero_image_alt` | foto hero | | `benefits` | jsonb `[{icon_key,label}]` — faixa escura | | `included_items` | jsonb `[{icon_key,title,description}]` — grid 3 col | | `audience_heading` | default editorial se vazio ok | | `audience_intro` | texto | | `audience_points` | jsonb `string[]` checklist | | `audience_image_path` / `audience_image_alt` | foto 50/50 | | `final_cta_heading` / `final_cta_body` | bloco final | | `meta_title` / `meta_description` | SEO opcional | Manter `summary` + `scope_items` para cards. Não migrar cards para `included_items` neste ciclo. ### Catálogo fechado de ícones (`PackageIconCatalog`) Select Filament → `icon_key` string. Map PHP/Blade para SVGs inline (ou partials). Sem upload de SVG arbitrário (XSS/ops). Chaves mínimas cobrem mock (ex.: calendar, checklist, users, map, heart, spark — nomes estáveis kebab). ### Hero de pacote vs `photo-hero` genérico Mock exige H1 bipartido (linha + ênfase itálica), divisor vertical, CTA outline no hero e foto. Preferir componente dedicado `x-public.package-hero` (ou estender `photo-hero` só se API ficar genérica sem branching feio). Seções: `package-benefits`, `package-included`, `package-audience`, reutilizar `final-cta` se encaixar. ### CTA WhatsApp Reutilizar VO/helper já usado nos cards (digits de `SiteSetting.whatsapp_number`, mensagem com nome da modalidade). Mesma regra de fallback briefing. Não duplicar lógica de normalização. ### Links a partir dos cards Card: título/área → `route('packages.show', $package)` quando slug presente; botão CTA continua WhatsApp/briefing. Sem quebrar testes de CTA existentes. ### Imagens `PublicImageUploadRules` + disk público existente + `x-media.image`. Paths nullable; se hero ausente, layout degrada (omitir slot de imagem). ### Camada Application - `FindPublishedWeddingPackageBySlug` - Estender `GetSitemapEntries` com slugs de pacotes publicados - PageMeta no controller (espelhar PortfolioCaseController) Sem repository genérico / BaseAction. ## Risks / Trade-offs - [Capability `wedding-packages` ainda não está em `openspec/specs/`] → delta ADDED nesta change; ao arquivar, consolidar com requirements de cards do change completo ou arquivar ambos em ordem. - [Copy das 3 modalidades incompleta] → seeder: Essenza = mock; Conduzione/Grand Jour estrutura paralela adaptada; admin pode editar. - [Ícones insuficientes no catálogo] → adicionar chave no map + opção Filament; sem free-text SVG. - [Cards sem slug durante migrate] → migration backfill slug a partir do name; seeder garante os 3 oficiais. - [Duplicação visual mock vs tokens] → testes de tokens existentes + asserts de classes/roles; não copiar hex do HTML. ## Migration Plan 1. Deploy migration additive + código + assets Blade juntos. 2. Rodar seeder/update das 3 modalidades (slug + detalhe). 3. Verificar `/pacotes/essenza` (etc.), 404 draft, sitemap, CTA WA. 4. Rollback: remover rota/views; colunas additive podem permanecer; unpublish pacotes se necessário. ## Open Questions - Nenhuma bloqueante (decisões de produto já confirmadas: detalhe-only, extend model, 3 modalidades, WA CTA). - WEB-ID dedicado a package detail: não existe no SPEC; rastrear via WEB-02 + padrão WEB-03 até SPEC ganhar ID explícito.