# Slate — Stage 1 (Sessions 1 + 2 + 3a)

A lean, modular PHP application shell with WordPress-style plugins.
This package is the **Stage 1 foundation** plus the full plugin
management UI, Users + Roles CRUD, expanded Settings, and a basic
Contact Forms builder.

## What works

- ✅ Two-step `install.php` wizard
- ✅ Premium admin shell — dark sidebar with section labels, light
  off-white canvas, blue accent, mobile bottom tab bar
- ✅ Admin login + dashboard
- ✅ **Card-row data lists** replace traditional tables everywhere
- ✅ **Full plugin management** (Session 2): ZIP upload, activate,
  deactivate, uninstall, with cross-filesystem safe staging
- ✅ **`bin/package-plugin.php`** CLI packager
- ✅ **Users CRUD** (Session 3a): create, edit, delete admin users,
  password reset; self-protection guards (no demote/suspend/delete
  yourself, can't demote the last Super Admin)
- ✅ **Roles editor** (Session 3a): create/edit/delete roles with
  grouped permission cards. Super Admin role (id=1) read-only.
  Permissions sourced from core list ∪ active plugin manifests —
  plugins declaring new permissions become visible automatically
- ✅ **Settings expanded** (Session 3a): General (site name,
  language), Branding (accent color + logo upload), Business details
  (name, email, phone, address, hours), Email/SMTP (with password
  encryption), test-email button. Each card has its own Save button
- ✅ **Contact Forms basic builder** (Session 3a): create forms with
  text/email/tel/url/textarea/select fields, manage status
  (draft/published/archived), view submissions list. Field syntax
  is `type|name|label|required` per line — drag-drop UI ships later
- ✅ Hook system, AuditLog, Mailer, encrypted secrets
- ✅ Hello World plugin demonstrates every contract point
- ✅ 59-test end-to-end smoke test passing

## Design language

Slate uses a dark-sidebar / light-canvas theme. Off-white canvas
(`#F5F4F1`), white cards on 1px hairline borders (no halo shadow),
near-black sidebar (`#0E1117`), blue accent (`#2563EB`) reserved
for primary actions and active states. Typography is DM Sans
(body), Syne (display headings), DM Mono (code) — loaded from
Google Fonts. 12px card radius, 44px minimum tap targets on
mobile, backdrop-blurred topbar.

Sidebar nav items are organised into uppercase section labels
(OVERVIEW, CONTENT, SYSTEM by default) via a `group` field; plugins
register their own groups (e.g. SHOP).

**Data lists use the card-row pattern, not HTML tables.** Each row
is a card showing avatar + title + meta + status badge; tapping
expands it to reveal a labeled key/value grid with optional
actions. One row open at a time. No horizontal scrollbars, ever.
Plugins get this pattern free via the `slate_data_row()` helper.

Detail pages (orders, submissions, settings with helpful metadata)
use the right-rail layout — `slate_page_layout('with-aside')` opens
a CSS grid with a 320px aside next to the main column. The aside
hosts `.aside-card` blocks containing `.kv-list` (label/value pairs
with hairline dividers) and `.audit-trail` (vertical timeline)
components.

All design tokens and component classes are documented in
`docs/PLUGIN-API.md` §15 — plugins should re-use these classes
rather than introducing parallel CSS.

## Responsive layout

- **Desktop (≥768px):** Sidebar on the left, topbar across, main
  content area, no tab bar.
- **Mobile (<768px):** Topbar across, main content full-width,
  bottom tab bar pinned to the viewport. First 4 nav items live in
  the tab bar; the rest open in a slide-up "More" sheet.

Vanilla CSS Grid + a single `@media (min-width: 768px)` breakpoint.
No build step, no framework.

## What's NOT in this build (coming next)

- **Session 3:** Users + Roles CRUD with permission editor;
  Settings with branding, business details, SMTP; Contact Forms
  drag-and-drop builder; customer portal (login, register,
  dashboard).
- **Stage 2+:** Booking plugin, Products plugin, Passes,
  Membership, etc. — each is a ZIP uploaded through the manager
  built in Session 2.

## File structure

```
slate/
├── .env.example          Copy to .env (install.php does this)
├── .htaccess             Apache config
├── config.php            Bootstrap
├── install.php           Two-step install wizard
│
├── admin/                Admin interface
│   ├── index.php           Dashboard
│   ├── login.php           Premium login
│   ├── logout.php
│   ├── plugins.php         FULL plugin manager (Session 2)
│   ├── users.php           Read-only preview (Session 3: CRUD)
│   ├── roles.php           Read-only preview (Session 3: editor)
│   ├── contact_forms.php   Stub (Session 3: builder)
│   ├── settings.php        Basic editable (Session 3: full)
│   └── partials/
│       ├── header.php      Sidebar + topbar + tab bar shell
│       └── footer.php      Mobile sheet + queued plugin scripts
│
├── bin/
│   └── package-plugin.php  CLI packager (NEW in Session 2)
│
├── customer/             Customer portal (Session 3)
├── api/                  API endpoints (plugins add them)
├── templates/            Email/page templates
├── uploads/              File uploads
│
├── db/
│   └── schema.sql        11 core tables
│
├── docs/
│   └── PLUGIN-API.md     ← Read before writing any plugin
│
├── includes/             Core PHP classes
│
├── lang/en.php
│
└── plugins/
    ├── _dist/                          NEW in Session 2
    │   └── hello-world-v1.0.0.zip      Pre-built upload-ready ZIP
    └── hello-world/                    Source of the example plugin
```

## To deploy

1. Upload the contents to your web root.
2. Visit `/install.php`. Step 1: DB credentials + app URL.
   Step 2: admin name, email, password (8+ chars).
3. After install, log in. The dashboard shows quick stats.
4. Go to **Plugins**. You'll see an upload form with a "Download
   example plugin" link.
5. Download the example, then re-upload it through the form —
   that's the round-trip test. You should see Hello World in the
   installed-plugins list. Click Activate; refresh; you'll see
   "Hello World" appear in the sidebar.

## Packaging your own plugin

```bash
php bin/package-plugin.php plugins/my-plugin
# → plugins/my-plugin-v1.0.0.zip

# Or write into the shipped-dist folder:
php bin/package-plugin.php plugins/my-plugin --dist
```

The script validates the manifest + SQL before zipping, so a ZIP
that passes the packager is guaranteed to pass installation.

## Requirements

- PHP 8.1+
- MySQL/MariaDB 5.7+
- PHP extensions: `pdo_mysql`, `mbstring`, `zip`, `openssl`, `fileinfo`
- Apache (.htaccess assumes `mod_headers`, `mod_deflate`); nginx
  needs equivalent config.

## Browser support

Modern CSS (Grid, custom properties, backdrop-filter). Current
Chrome, Safari, Firefox, Edge. iOS Safari 15+ and Android
Chrome 90+ are first-class. IE11 is not supported.

## License

(To be confirmed.)
