# ClinicSite — Public Website + CMS

Multi-tenant public marketing website for each clinic, with a full content
management system, **5 switchable animated themes**, and per-clinic hosting by
**subdomain** or **custom domain** (just like the PWA apps). Extension of
`VetClinic`.

## What it gives a clinic
- A modern, animated, mobile-responsive website (hero, services, about, team,
  testimonials, gallery, FAQ, opening hours, stats, CTA, contact form…).
- A page builder: add / reorder / edit / duplicate sections, multiple pages,
  per-page SEO, navigation control.
- 5 themes — **Aurora, Meadow, Pulse, Heritage, Minimal** — switchable in one
  click, plus colour & font customisation.
- Media library, contact-form leads inbox, domain & SEO settings.

Admin lives under **Vet Clinic → Extensions → Website** in the ERP sidebar.

## Install
1. Enable the module (already in `modules_statuses.json`).
2. As superadmin, open `/clinic-site/install` (or use the Modules install screen).
   This migrates the `vs_*` tables, grants `clinic_site.*` permissions to the
   business Admin role, and seeds a ready-to-edit Home page.

## Permissions
`clinic_site.access_module`, `clinic_site.manage_content`, `clinic_site.manage_design`,
`clinic_site.manage_settings`.

## How hosting works
The public site is served by the **global** `ResolveTenantSite` middleware
(runs before the router) so a clinic site can own `/` of its own host without
colliding with the ERP. On ERP/admin hosts and reserved paths (`/portal`,
`/app`, `/api`, assets…) it's a fast no-op.

A host resolves to a clinic site by either:
- **Custom domain** — `cs_sites.custom_domain` matches the request host, or
- **Subdomain** — `slug.<CLINICSITE_BASE_DOMAIN>` matches `cs_sites.subdomain_slug`.

### Environment
```
CLINICSITE_BASE_DOMAIN=vetone.app          # wildcard root for *.vetone.app subdomains
CLINICSITE_ADMIN_HOSTS=erp.vetone.app      # extra hosts that must stay the ERP (APP_URL host is added automatically)
```

### DNS / server
- **Subdomains:** add a wildcard `*.vetone.app` A/CNAME record and a wildcard
  vhost that points at this Laravel app's `public/`.
- **Custom domains:** the clinic points `www`/apex at this server (see the
  in-app *Domain & SEO* page for the exact records). No vhost change needed —
  any host that isn't an admin host is matched against `custom_domain`.

### Local preview (no DNS)
Use **Preview** buttons in the CMS, or `/clinic-site/preview/{pageId?}` — it
renders the live site host-independently, and `?theme_preview=<key>` previews
another theme without applying it.

## Themes — two levels of difference
1. **Style variants** (Aurora, Meadow, Pulse, Heritage, Minimal): share the
   structure and are restyled per theme via the `theme-<key>` body class +
   `themes/<key>/style.blade.php`.
2. **Full custom layouts** (Velvet Care, Playful Care — flagged `distinct` in the
   registry and "Full layout" in the picker): a *completely different website*,
   not just colours.

### How the engine resolves views (override anything)
For the active theme, the renderer prefers a theme-specific view and falls back
to the shared one:
- **Blocks:** `themes/<key>/blocks/<type>.blade.php` → else `blocks/<type>.blade.php`
- **Header:** `themes/<key>/nav.blade.php` → else `themes/_partials/nav.blade.php`
- **Footer:** `themes/<key>/footer.blade.php` → else `themes/_partials/footer.blade.php`

So a new "different website" theme = an entry in `Support/ThemeRegistry.php`
plus a `themes/<key>/` folder with `layout.blade.php`
(`@include('clinicSite::themes._partials.document')`), `style.blade.php`, and only
the partials you want to redefine (`nav`, `footer`, `blocks/hero`,
`blocks/services`, …). Anything you don't override uses the shared, styleable
defaults. `Velvet Care` and `Playful Care` are the reference examples.
