docs(06): add brand assets & iconography contract to UI-SPEC
Appends a new "Brand Assets & Iconography" section covering the glyph+wordmark mark concept, SVG source-of-truth files, raster export pipeline, full favicon set (SVG + ICO + index.html gaps), maskable safe-zone spec, in-app logo usage surfaces, and a complete asset manifest table. All existing UI-SPEC sections preserved verbatim.
This commit is contained in:
@@ -317,6 +317,138 @@ All new surfaces must meet:
|
||||
|
||||
---
|
||||
|
||||
## Brand Assets & Iconography
|
||||
|
||||
Source: D-BRAND-01, D-BRAND-02 (locked user decisions, 2026-06-10).
|
||||
In-app UI icons remain lucide-react — this section covers only the brand mark, app icons, and favicons.
|
||||
|
||||
### Mark: Glyph + Wordmark
|
||||
|
||||
**Concept (D-BRAND-01):** Two overlapping rounded shapes — circles or rounded rectangles — suggesting two members sharing a space (the family) or two overlapping calendar tiles. The overlap region is the accent color at full opacity; each outer shape is the accent color at reduced opacity (≈60%). The wordmark "FamilySync" sits to the right of the glyph in the lockup variant; the glyph alone is the source for all raster icons.
|
||||
|
||||
**Geometry / construction:**
|
||||
- Two circles, each 40px diameter on a 64px × 64px artboard (SVG viewBox="0 0 64 64").
|
||||
- Circle 1 center: (24, 32). Circle 2 center: (40, 32).
|
||||
- Overlap: the intersection region formed by both paths.
|
||||
- Rendering: use two `<circle>` elements with `fill-opacity="0.6"` for the individual shapes, then a `<clipPath>`-intersected shape (or a third overlapping path) at `fill-opacity="1"` for the overlap highlight.
|
||||
- Wordmark: "FamilySync" set in the system-ui stack at 18px/600 in the lockup; the glyph and wordmark baseline-align.
|
||||
|
||||
**Color usage:**
|
||||
|
||||
| Surface | Glyph fill | Wordmark fill |
|
||||
|---------|-----------|---------------|
|
||||
| Light background (#FFFFFF) | #4A90D9 (accent) | #111318 (--color-text-primary) |
|
||||
| Dark background (≥50% dark) | #FFFFFF | #FFFFFF |
|
||||
| Monochrome (print / favicon .ico) | currentColor (#111318 on light, #FFFFFF on dark) — single flat shape, no opacity split |
|
||||
|
||||
**Clear space:** Minimum clear space = 1× the glyph diameter (64px on the 64px artboard, i.e. one full glyph-width on all four sides at actual render size).
|
||||
|
||||
**Minimum size:**
|
||||
- Glyph-only: 24px × 24px rendered (below this, detail is lost; use the monochrome flat variant).
|
||||
- Glyph + wordmark lockup: 120px wide minimum.
|
||||
|
||||
**Monochrome fallback:** A single filled shape representing both circles merged (union path), no opacity split. Used for favicon.ico and any single-color context.
|
||||
|
||||
### SVG Source-of-Truth Files
|
||||
|
||||
| File | Contents | Used as source for |
|
||||
|------|----------|--------------------|
|
||||
| `apps/pwa/src/assets/logo-glyph.svg` | Glyph only, viewBox="0 0 64 64", color-variable fills (`currentColor` + CSS custom property override) | All raster icon exports; in-app glyph-only placements |
|
||||
| `apps/pwa/src/assets/logo-lockup.svg` | Glyph + "FamilySync" wordmark, viewBox="0 0 240 64" | Auth splash, header lockup (if present) |
|
||||
| `apps/pwa/src/assets/logo-monochrome.svg` | Flat union-path glyph, single fill, viewBox="0 0 64 64" | favicon.ico source layer |
|
||||
|
||||
All SVG files: no embedded raster data, no `<image>` elements, path-only. Minified with no comments before commit.
|
||||
|
||||
### Raster Export Pipeline
|
||||
|
||||
Source: `apps/pwa/src/assets/logo-glyph.svg` (light-mode fill: #4A90D9 shapes on transparent background).
|
||||
|
||||
Export tool: any SVG-to-PNG renderer that preserves alpha (e.g. `sharp`, `Inkscape --export-png`, or `resvg`). A build-time script at `apps/pwa/scripts/export-icons.ts` (or equivalent Makefile target) must produce the full output list below from the SVG source — no manually-placed PNGs.
|
||||
|
||||
**Output list:**
|
||||
|
||||
| Output file | Size (px) | Format | Notes |
|
||||
|-------------|-----------|--------|-------|
|
||||
| `apps/pwa/public/icon-192.png` | 192×192 | PNG, RGBA | PWA manifest `any` icon |
|
||||
| `apps/pwa/public/icon-512.png` | 512×512 | PNG, RGBA | PWA manifest `any` icon |
|
||||
| `apps/pwa/public/icon-512-maskable.png` | 512×512 | PNG, RGBA | PWA manifest `maskable` icon — glyph centered in safe zone (see below) |
|
||||
| `apps/pwa/public/apple-touch-icon.png` | 180×180 | PNG, RGB (no alpha), white background | iOS home screen; Apple ignores alpha |
|
||||
| `apps/pwa/public/favicon-16.png` | 16×16 | PNG | favicon.ico source layer |
|
||||
| `apps/pwa/public/favicon-32.png` | 32×32 | PNG | favicon.ico source layer |
|
||||
| `apps/pwa/public/favicon-48.png` | 48×48 | PNG | favicon.ico source layer |
|
||||
| `apps/pwa/public/favicon.svg` | — | SVG (copy of logo-glyph.svg) | Modern browsers; referenced as `<link rel="icon" type="image/svg+xml">` |
|
||||
| `apps/pwa/public/favicon.ico` | 16+32+48 multi-res | ICO | Legacy browsers; bundle the three PNG layers into a single .ico using `png-to-ico` or equivalent |
|
||||
|
||||
Replace the three existing placeholder files (`icon-192.png`, `icon-512.png`, `apple-touch-icon.png`) with the real exports. The script must be idempotent (re-running overwrites all outputs).
|
||||
|
||||
### Maskable Safe Zone
|
||||
|
||||
The maskable icon specification requires the primary visual to fit within the center 80% of the canvas (the "safe zone"). For a 512×512 canvas, the safe zone is the inner 409×409 px centered region. The glyph export for `icon-512-maskable.png` must:
|
||||
- Scale the glyph to fit within 409×409 (≈80% of 512).
|
||||
- Center it on the 512×512 canvas.
|
||||
- Fill the outer 10% bleed area with the PWA `background_color` (#FFFFFF) so masked shapes (squircle, circle) show a clean white surround rather than transparency artifacts.
|
||||
|
||||
Update `vite.config.ts` manifest `icons` array to reference `icon-512-maskable.png` for the `maskable` purpose entry (separate file from the `any` 512px icon):
|
||||
|
||||
```ts
|
||||
{ src: '/icon-192.png', sizes: '192x192', type: 'image/png' },
|
||||
{ src: '/icon-512.png', sizes: '512x512', type: 'image/png' },
|
||||
{ src: '/icon-512-maskable.png', sizes: '512x512', type: 'image/png', purpose: 'maskable' },
|
||||
```
|
||||
|
||||
### Favicon Set — index.html Changes
|
||||
|
||||
Current state: `index.html` has only `<link rel="apple-touch-icon">` and no `<link rel="icon">`. This is a gap.
|
||||
|
||||
Add the following tags inside `<head>`, after the existing `apple-touch-icon` line:
|
||||
|
||||
```html
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||
```
|
||||
|
||||
Keep the existing tags unchanged:
|
||||
|
||||
```html
|
||||
<meta name="theme-color" content="#4A90D9" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||
<meta name="apple-mobile-web-app-title" content="FamilySync" />
|
||||
```
|
||||
|
||||
Browser resolution order: SVG favicon first (Chrome 80+, Firefox 41+, Safari 12+), ICO fallback for IE/legacy. No `favicon-32.png` link needed in HTML — the ICO multi-res bundle covers the same use case and reduces link clutter.
|
||||
|
||||
### In-App Logo Usage
|
||||
|
||||
| Surface | Variant | Size | Placement |
|
||||
|---------|---------|------|-----------|
|
||||
| Auth splash (Surface 1) | Glyph + wordmark lockup (`logo-lockup.svg`) | 120px wide (auto height ~32px) | Centered above the spinner stack; 24px gap below lockup, then spinner |
|
||||
| Session-expired interstitial (Surface 2) | Glyph only (`logo-glyph.svg`) | 32×32px | Centered above spinner; same vertical stack as auth splash |
|
||||
| App header / nav bar (if present) | Glyph only (`logo-glyph.svg`) | 24×24px | Leading slot of the top nav bar, 16px from left edge, vertically centered |
|
||||
| PWA install prompt / about screen | Glyph + wordmark lockup | 160px wide | Centered |
|
||||
|
||||
Spacing tokens used: 24px gap (`--space-6`) between lockup and spinner on auth splash; 16px left inset (`--space-4`) for header placement. These are drawn from the established 8-point scale.
|
||||
|
||||
Color: render SVGs using CSS `color` inheritance where possible so light/dark mode automatically applies the correct fill. Set `fill="currentColor"` on all path elements in the SVG source; parent container sets `color: var(--color-text-primary)` (light) or `color: #FFFFFF` (dark overlay contexts such as auth splash over `--color-surface` — use `--color-text-primary` here since the background is white).
|
||||
|
||||
### Asset Manifest
|
||||
|
||||
| File path | Format | Size(s) | Purpose | Referenced in |
|
||||
|-----------|--------|---------|---------|---------------|
|
||||
| `apps/pwa/src/assets/logo-glyph.svg` | SVG | 64×64 viewBox | SVG source of truth — glyph only | Export script, in-app `<img>` or inline SVG |
|
||||
| `apps/pwa/src/assets/logo-lockup.svg` | SVG | 240×64 viewBox | SVG source of truth — glyph + wordmark | Auth splash, install prompt |
|
||||
| `apps/pwa/src/assets/logo-monochrome.svg` | SVG | 64×64 viewBox | Monochrome union-path variant | favicon.ico source |
|
||||
| `apps/pwa/public/favicon.svg` | SVG | — | Modern browser favicon | `<link rel="icon" type="image/svg+xml">` in index.html |
|
||||
| `apps/pwa/public/favicon.ico` | ICO | 16+32+48 multi-res | Legacy browser favicon | `<link rel="icon" type="image/x-icon">` in index.html |
|
||||
| `apps/pwa/public/icon-192.png` | PNG (RGBA) | 192×192 | PWA manifest any icon | vite.config.ts manifest `icons` |
|
||||
| `apps/pwa/public/icon-512.png` | PNG (RGBA) | 512×512 | PWA manifest any icon | vite.config.ts manifest `icons` |
|
||||
| `apps/pwa/public/icon-512-maskable.png` | PNG (RGBA) | 512×512 | PWA manifest maskable icon | vite.config.ts manifest `icons` |
|
||||
| `apps/pwa/public/apple-touch-icon.png` | PNG (RGB, white bg) | 180×180 | iOS home screen icon | `<link rel="apple-touch-icon">` in index.html |
|
||||
| `apps/pwa/scripts/export-icons.ts` | TypeScript | — | Build-time raster export pipeline | `make icons` or equivalent |
|
||||
|
||||
---
|
||||
|
||||
## Registry Safety
|
||||
|
||||
| Registry | Blocks Used | Safety Gate |
|
||||
|
||||
Reference in New Issue
Block a user