# Pubmat Template System

A reusable set of social-media "pubmat" templates for **SavrPass**. You edit plain HTML files, preview them in a browser, and export them to PNG or PDF.

- **14 templates** (see the gallery: open `index.html`)
- **Photo background** option on 12 of them, plus a horizontal two-row split and a company-avatar persona template
- **7 sizes** each: 1080×1080, 1080×1350, 1080×1920, 1200×675, 1200×627, 1280×720, 1000×1500
- **Light and dark themes** for every template
- **One brand file** (`config/brand.css`). Change it once and every template follows.
- **Export scripts** for PNG (1x and 2x) and PDF at the exact canvas size
- No frameworks and no build step. Everything runs offline, including the bundled fonts.

```
pubmat-system/
├── index.html              ← gallery: browse, filter, preview, download
├── templates/              ← 14 templates, one HTML file each
├── config/
│   ├── brand.css           ← brand colours, fonts, logo (edit this)
│   ├── savrpass-logo.png   ← logo used by every template
│   ├── savrpass-mark.png   ← default company avatar (persona template)
│   └── fonts/              ← Anton + Inter (SIL Open Font License)
├── export/
│   ├── export-png.js
│   ├── export-pdf.js
│   └── lib.js              ← shared export code
├── docs/                   ← you are here
└── package.json            ← only needed for the export scripts
```

---

## 1. Choose a template

| You want to… | Use |
|---|---|
| Pair a message with one photo, stat or visual | **Two-column grid** |
| Let a real photo carry the post | **Image overlay** (scrim or floating card) |
| Keep the photo clean, with text in its own band above or below | **Horizontal split** |
| Speak as the brand: reminders, tips, replies, jokes | **Persona post** (company avatar) |
| Announce a launch, feature or new partner | **Announcement** |
| Invite people to something with a date | **Event invitation** |
| Share a partner's words | **Quote / testimonial** |
| Make one number land | **Statistic callout** |
| Show the product and the price | **Product promo** |
| Promote a Facebook Live or webinar | **Webinar / live** |
| Fill a role | **Hiring / recruitment** |
| Teach something (carousel cover + inside slides) | **Educational tip** |
| Run an offer with a deadline | **Sale / discount** |
| Give a saveable step list | **Checklist / how-to** |

**Any template on a photo:** switch **Background → Photo** in the toolbar (or add `&bg=photo` to the URL) and set `--bg-image: url("../photos/your-photo.jpg");` in that template's `<style>`. A flat Navy scrim (or white on the light theme) sits over the photo, so every text colour stays readable on any image. Change its strength with `--bg-scrim-dark` / `--bg-scrim-light`, but don't go below 0.86 or contrast can fail on bright photos.

Rule of thumb: **one message per post**. If you need two templates for one idea, make it a carousel.

## 2. Edit brand variables

Open `config/brand.css`. The block at the top controls everything:

```css
--brand-primary:    #1D3FD6;  /* Cobalt: headline highlight, buttons */
--brand-secondary:  #0B1A3F;  /* Navy: dark backgrounds, scrims */
--brand-accent:     #E3262F;  /* Red: one highlight per post */
--brand-text:       #0F172A;
--brand-background: #FFFFFF;
--cta-color:        #1D3FD6;
--font-heading: ...;
--font-body: ...;
--logo-url: url("../config/savrpass-logo.png");
```

- **Logo:** replace `config/savrpass-logo.png` (keep the file name), or point `--logo-url` at a new file. If the shape changes, update `--logo-ratio` (width / height). On dark backgrounds the logo automatically sits on a white pill.
- **Fonts:** system fonts are the default, so nothing downloads. To use the SavrPass brand fonts (Anton headlines in caps, Inter body), swap in the two commented `--font-*` lines. You can preview them first with the **Fonts** switch in any template's toolbar.
- **Dark-theme colours** (Coral `#FF4D57`, Sky `#7EA2FF`) are listed under "Supporting palette". They are the versions of red and blue that pass contrast on Navy.

## 3. Company avatar (persona)

The persona template "posts" in the brand's own voice in three layouts: a social-post card, an avatar with a speech bubble, and a chat thread where the avatar replies to a client.

- The avatar is set **once** for every post in `config/brand.css`: `--persona-image: url("../config/savrpass-mark.png");`. When the mascot is ready, point this at its file.
- For a full-bleed character or photo avatar, also set `--avatar-fit: cover; --avatar-pad: 0;` in the template. The default `contain` with padding suits the logo mark.
- Change the display name and handle in the HTML (`SavrPass`, `@SavrPass · Cebu`).
- Keep one consistent voice: friendly, local, Bisaya/Taglish-first. Don't add fake likes, comment counts or platform verified badges.

## 4. Replace copy and images

Open a template in a text editor. All the copy sits inside `<div id="canvas">`.

- Anything in **[square brackets]** is a placeholder. Replace it before posting.
- Keep to each template's copy limits. They're listed in the comment at the top of every file and on the gallery card.

**Images.** Each image slot looks like this:

```html
<figure class="pm-media tc-img" data-var="--hero-image"><img alt="Describe the photo">…</figure>
```

You can fill it two ways:
1. Put the path in the `<img>`: `<img src="../photos/salon.jpg" alt="Stylist finishing a client's hair">`
2. Or set the CSS variable in the template's `<style>`: `--hero-image: url("../photos/salon.jpg");`

Move the subject away from the text with `--img-pos` (for example `center 20%` or `right top`). If there's no image, or it fails to load, you get a solid brand-colour fallback with a label. Hide the labels with the **Image labels** toggle or `?labels=0`.

**Image overlay extras** are set in the `<style>` block of `image-overlay.html`:

| Variable | What it does |
|---|---|
| `--overlay-image` | Background photo URL |
| `--overlay-rgb` | Scrim colour as `R G B` (default Navy `11 26 63`) |
| `--overlay-opacity` | Scrim strength where the text sits (keep it ≥ 0.85 for contrast) |
| `--gradient-strength` | How far up the canvas the scrim reaches |
| `--text-align`, `--text-width` | Alignment and width of the text block (60% of the canvas) |

## 5. Preview in a browser

Double-click `index.html`, or open any file in `templates/`. The toolbar has:

- **Size:** all 7 canvases
- **Theme:** light or dark
- **Template options**, such as layout (55/45, 60/40, stacked; text top/photo top/card), visual (image or stat panel), text position, text share, cobalt band, persona layout, or carousel cover/inside slide
- **Background:** solid colour or photo
- **Fonts:** system or brand
- **Safe area:** shows the central 80% that critical content must stay inside
- **Print / Save PDF**

Settings are saved in the URL, so you can bookmark a variant, for example:
`templates/two-column-grid.html?size=1080x1920&variant=dark&layout=stacked&visual=stat`

> Tip: some browsers limit local files. If the fonts or logo don't load, run a tiny local server in the folder (`python -m http.server`) and open `http://localhost:8000`.

## 6. Export PNG and PDF

### With Node.js (recommended)

One-time setup, in the `pubmat-system` folder:

```bash
npm install
npx playwright install chromium
```

Then:

```bash
# PNG at 1x and 2x
node export/export-png.js templates/two-column-grid.html 1080x1350

# PDF at the exact canvas size
node export/export-pdf.js templates/image-overlay.html 1080x1350

# Every template × 1080×1080, 1080×1350, 1080×1920 × light + dark
node export/export-png.js --all
node export/export-pdf.js --all

# More control
node export/export-png.js templates/image-overlay.html 1080x1920 --variant=dark --layout=top
node export/export-png.js --all --sizes=all --scales=2
node export/export-png.js templates/checklist-howto.html 1080x1350 --fonts=brand
```

Files land in `exports/png/<template>/` and `exports/pdf/<template>/`, named `template_size_theme@2x.png`. Already have Chrome and don't want to download Chromium? Add `--chrome="/path/to/chrome"`.

### Without Node.js

**From the browser:** open the template, set size and theme, click **Print / Save PDF**. Choose *Save as PDF*, *Margins: None*, tick *Background graphics*. The page size is set for you.

**From the command line with Chrome:** add `?export=1&size=WxH` to the file URL.

```bash
# macOS
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --headless=new --hide-scrollbars \
  --window-size=1080,1350 --virtual-time-budget=3000 --screenshot=post.png \
  "file:///Users/you/pubmat-system/templates/sale-discount.html?export=1&size=1080x1350"

# Windows (PowerShell)
& "C:\Program Files\Google\Chrome\Application\chrome.exe" --headless=new --no-pdf-header-footer `
  --virtual-time-budget=3000 --print-to-pdf=post.pdf `
  "file:///C:/pubmat-system/templates/sale-discount.html?export=1&size=1080x1350"
```

Match `--window-size` to the `size` value for screenshots. Add `--force-device-scale-factor=2` for 2x.

## 7. Add a new template

1. Copy the closest existing template in `templates/` and rename it, for example `templates/partner-welcome.html`.
2. Update the comment block at the top: name, best use, hierarchy, copy rules.
3. Change the markup inside `<div id="canvas">`. Build on the shared classes: `pm-safe`, `pm-eyebrow`, `pm-h1`, `pm-h2`, `pm-body`, `pm-small`, `pm-cta`, `pm-badge`, `pm-logo`, `pm-media`, `pm-hl`, `pm-mark`.
4. Size everything in canvas units. In CSS, `calc(var(--u) * 30)` means 30px on a 1080px canvas, and it scales for other sizes. Use `[data-shape="landscape"]`, `"square"`, `"portrait"` and `"story"` selectors to adapt the layout.
5. Use theme tokens (`--bg`, `--fg`, `--muted`, `--surface`, `--hl`, `--cta-bg`…), never raw hex values, so light/dark and re-branding keep working.
6. To add toolbar options, edit `window.PM.controls` near the bottom of the file. Each option becomes a `data-*` attribute on the canvas that your CSS can target.
7. Add a card for it to `index.html` (copy an existing `<article class="card">`).
8. Check every size with **Safe area** turned on, then run the accessibility checklist below.

## 8. Accessibility checklist

- [ ] Text contrast meets WCAG AA: 4.5:1 for body text, 3:1 for text ≥ 24px bold. The built-in pairs are listed in `style-guide.md`.
- [ ] Never use red text on Navy. Use Coral (`--brand-accent-on-dark`) instead.
- [ ] On photos, text sits on the scrim, never on a busy area or a face. Keep `--overlay-opacity` ≥ 0.85.
- [ ] Headline ≥ 24px and body ≥ 16px at 1080px width. The templates start well above this, so don't shrink them.
- [ ] Critical content stays inside the safe area. Check with the toggle.
- [ ] Colour is never the only signal. Highlights also change weight, size or position.
- [ ] Every real photo gets meaningful `alt` text.
- [ ] When posting, paste the post's key text into the caption and write image alt text in Facebook/Instagram's accessibility field.
- [ ] Bisaya/Taglish lines are wrapped in `<span lang="ceb">` or `lang="fil"` where practical.

## 9. Trend-reference workflow

To stay current without copying anyone, collect references, label them, extract the patterns, and design originals. The full method is in `docs/trend-reference.md`.

---

**Fonts:** Anton and Inter are © their authors, licensed under the SIL Open Font License 1.1 (see `config/fonts/`).
