|
| 1 | +# Website Asset Generation |
| 2 | + |
| 3 | +This document explains the tooling and workflow for generating raster image assets for the SpecOps website. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +The SpecOps website (`docs/index.html`) uses high-quality SVG source files for branding and social media assets. To maximize compatibility across browsers, social platforms, and devices, we generate PNG raster versions using a Node.js build script. |
| 8 | + |
| 9 | +## Source Files |
| 10 | + |
| 11 | +The following SVG files serve as the source of truth for all website graphics: |
| 12 | + |
| 13 | +- `docs/favicon.svg` — Primary favicon with gradient branding |
| 14 | +- `docs/safari-pinned-tab.svg` — Monochrome icon for Safari pinned tabs |
| 15 | +- `docs/og-image.svg` — Social media share card (1200×630) |
| 16 | + |
| 17 | +## Generated Assets |
| 18 | + |
| 19 | +Running the build script produces the following PNG files: |
| 20 | + |
| 21 | +| File | Dimensions | Purpose | |
| 22 | +|------|------------|---------| |
| 23 | +| `docs/favicon-16.png` | 16×16 | Browser tab icon (legacy) | |
| 24 | +| `docs/favicon-32.png` | 32×32 | Browser tab icon (retina) | |
| 25 | +| `docs/icon-180.png` | 180×180 | Apple touch icon (iOS home screen) | |
| 26 | +| `docs/og-image.png` | 1200×630 | Open Graph / Twitter Card image | |
| 27 | + |
| 28 | +## Prerequisites |
| 29 | + |
| 30 | +- Node.js 16+ (includes npm) |
| 31 | +- The `sharp` library (installed automatically via `npm install`) |
| 32 | + |
| 33 | +## Building Assets |
| 34 | + |
| 35 | +### First-time setup |
| 36 | + |
| 37 | +```bash |
| 38 | +npm install |
| 39 | +``` |
| 40 | + |
| 41 | +This installs the `sharp` image processing library as a dev dependency. |
| 42 | + |
| 43 | +### Generate PNG assets |
| 44 | + |
| 45 | +```bash |
| 46 | +npm run build:assets |
| 47 | +``` |
| 48 | + |
| 49 | +This executes `scripts/gen-assets.js`, which: |
| 50 | +1. Reads SVG source files from `docs/` |
| 51 | +2. Rasterizes them at high density for crisp output |
| 52 | +3. Applies maximum PNG compression (level 9) |
| 53 | +4. Writes output files to `docs/` |
| 54 | + |
| 55 | +**When to regenerate:** |
| 56 | +- After editing any SVG source file |
| 57 | +- When deploying the website to production |
| 58 | +- Before committing changes that affect branding |
| 59 | + |
| 60 | +## The Build Script |
| 61 | + |
| 62 | +`scripts/gen-assets.js` uses the [sharp](https://sharp.pixelplumbing.com/) library to convert SVGs to PNGs. Key implementation details: |
| 63 | + |
| 64 | +- **High-density rendering** — Uses 512 DPI for small icons to prevent blurriness |
| 65 | +- **Progressive optimization** — Maximum compression for smaller file sizes |
| 66 | +- **Automated directory creation** — Creates output directories if missing |
| 67 | +- **Error handling** — Exits with code 1 on failure for CI/CD compatibility |
| 68 | + |
| 69 | +## Integration with HTML |
| 70 | + |
| 71 | +The generated PNG assets are referenced in `docs/index.html`: |
| 72 | + |
| 73 | +```html |
| 74 | +<!-- Multi-format favicon stack --> |
| 75 | +<link rel="icon" type="image/svg+xml" href="./favicon.svg"> |
| 76 | +<link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png"> |
| 77 | +<link rel="icon" type="image/png" sizes="16x16" href="./favicon-16.png"> |
| 78 | + |
| 79 | +<!-- iOS home screen icon --> |
| 80 | +<link rel="apple-touch-icon" sizes="180x180" href="./icon-180.png"> |
| 81 | + |
| 82 | +<!-- Social media preview --> |
| 83 | +<meta property="og:image" content="./og-image.png"> |
| 84 | +<meta name="twitter:image" content="./og-image.png"> |
| 85 | +``` |
| 86 | + |
| 87 | +This approach provides: |
| 88 | +- Modern browsers get crisp SVG favicons |
| 89 | +- Legacy browsers fall back to PNG |
| 90 | +- Social platforms always receive optimized raster images |
| 91 | +- iOS devices get proper home screen icons |
| 92 | + |
| 93 | +## Troubleshooting |
| 94 | + |
| 95 | +**"Cannot find module 'sharp'"** |
| 96 | +Run `npm install` to install dependencies. |
| 97 | + |
| 98 | +**"Asset generation failed: ENOENT"** |
| 99 | +Ensure all SVG source files exist in `docs/` before running the build script. |
| 100 | + |
| 101 | +**Output images look blurry** |
| 102 | +Check that the density parameter in `gen-assets.js` is set sufficiently high (currently 512 for favicons, 144 for OG image). |
| 103 | + |
| 104 | +## Future Enhancements |
| 105 | + |
| 106 | +Potential improvements to the asset pipeline: |
| 107 | + |
| 108 | +- **Dark mode variant** — Generate alternate OG image for `prefers-color-scheme: dark` |
| 109 | +- **ICO bundle** — Create multi-resolution `.ico` file for maximum legacy support |
| 110 | +- **Automated optimization** — Add `oxipng` or `pngquant` for further size reduction |
| 111 | +- **CI integration** — Run asset generation automatically on pre-commit hooks |
| 112 | +- **PWA manifest** — Generate `manifest.json` with icon references for installability |
| 113 | + |
| 114 | +## Related Documentation |
| 115 | + |
| 116 | +- [README.md](README.md) — Project overview and philosophy |
| 117 | +- [CONTRIBUTING.md](CONTRIBUTING.md) — Contribution guidelines |
| 118 | +- [package.json](package.json) — Build scripts and dependencies |
0 commit comments