apiVersion: capsule.dev/v0.1 kind: Capsule name: yingjieli-public-site version: 1.0.0 type: subsystem domain: yingjieli.site maintainers: - name: Quake email: quake0day@gmail.com purpose: summary: | The public, read-only frontend of yingjieliartist.com. Renders the hero, biography, masonry gallery of works, exhibitions, and contact sections, plus a keyboard / touch-friendly lightbox. Pulls all content at runtime from /api/data and all images from /api/img/. owns: - index.html (markup, SEO meta, OpenGraph) - "assets/styles.css (design system: Fraunces + Inter Tight, paper palette)" - assets/app.js (masonry layout + lightbox + nav scroll) - robots.txt + sitemap.xml - the visual contract of the site (typography, palette, motion) does_not_own: - content data (consumes GET /api/data; never mutates it) - image bytes (consumes /api/img/; never uploads) - authentication (never reads or sets the yl_admin cookie) - admin UI (separate capsule) interfaces: provides: - kind: http_api name: site-root entrypoint: src/index.html requires: - kind: http_api name: data-read from_capsule: yingjieli-content-store - kind: http_api name: image-serve from_capsule: yingjieli-image-store dependencies: capsules: - name: yingjieli-content-store version: ">=1.0.0 <2.0.0" - name: yingjieli-image-store version: ">=1.0.0 <2.0.0" runtime: - cloudflare-pages: "*" agent: summary_for_ai: | Read-only frontend. All content fetched from /api/data on load; page is built from that JSON, not data embedded in HTML. If you add a new section, you also need a new field in content-store's DEFAULT_DATA and a new card in the admin UI. avoid: - Hard-coding content (artwork lists, bios) in HTML. - Importing jQuery or any heavy framework — the site is 0-dep JS by design. verification: health_checks: - id: index-html-present command: node -e "require('fs').statSync('src/index.html')" - id: app-js-present command: node -e "require('fs').statSync('src/assets/app.js')" invariants: - The public site never mutates content (no PUT/POST/DELETE in app.js). - The public site never reads the yl_admin cookie. x-reconstruct: install: install.json