---
name: obsidian-cinema
description: Turn a brief into a polished single-file audio product landing page, starting from a verified template with 10 bundled images and offline Bodoni Moda and Instrument Sans fonts. The validator flags leftover sample content, dead links, broken images and, in a browser, dead controls.
version: 0.1.1
delivery: download-only
category: web
---

# Obsidian Cinema

You are turning a brief into one finished HTML page, and you do it by editing a template that already works instead of writing markup from scratch. Keep the look of the shipped template: type set in Bodoni Moda and Instrument Sans on #070708 surfaces.

Everything structural is already in `assets/template.html`: design tokens, layout, the router, every interactive part and the responsive rules. Your job is content, data and images.

## Example

`assets/template.html` is the worked example. Open it in a browser to see the finished page filled with made-up content (0 routed views, 10 image slots). It is the starting point, not a finished result: every name, number and sentence in it is made up.

## Delivery

Download-only. The skill runs in your own Agent or in a local terminal, and no key is needed: the scripts here never call a model or reach the network. Images come from `assets/images/` or from the Agent's own image tool.

## Workflow

1. **Collect the brief.** Ask for what the page must say, as a short checklist: who it is for, the single promise, the proof (numbers, names, quotes the user can stand behind), the calls to action and their real destinations. Fill any gap with plausible wording, and keep a list of every fact you made up so you can hand it back at the end.
2. **Pick the page language.** `en` or `zh-CN`, English unless the user asks otherwise. The choice drives `<html lang>`, the copy, the validator flag `--site-lang` and the font stack (see Language).
3. **Make a work folder.** Copy `assets/template.html` to `work/src.html`. Copy `assets/images/` to `work/images/`. Copy `assets/fonts/` to `work/fonts/`. Never edit files inside the skill folder itself. Commands below write `scripts/...` and `work/...` as relative paths: run them from a folder where both resolve, or spell out the full path of the skill's `scripts/` folder.
4. **Edit content and data.** Rewrite headings, paragraphs, labels, link targets, `alt` text and `aria-label` values. Most of the copy is plain markup; the repeated lists live in a few script constants, so replace their entries instead of hunting through markup:

   - `SPECS`: A list of 6 entries, each with group, rows.
   - `PROFILES`: A list of 13 entries.
   - `ROOMS`: A list of 4 entries, each with id, city, address, hours, closed, slots.
   - `SITE`: An object with 5 entries, keys: brand, product, cta, dispatch, contactLead.
   - `FINISHES`: A list of 4 entries.
   - `COUNTRIES`: A list of 21 entries.
   - `ARTICLES`: An object with 3 entries, keys: woven-driver, quiet-room, forty-minutes.
   - `POLICIES`: An object with 4 entries, keys: shipping, warranty, privacy, terms.
   - `ICON`: An object with 5 entries, keys: check, alert, pin, clock, arrow.
   - `OCL_SCENES`: An object with 5 entries, keys: haze, drift, ember, aurora, ridge.


   Interface strings also hide inside the script: date and number formats, toast and form-error messages, labels that change on click ("Show 3 more"), plural endings, and any product screens the script draws. After the markup is done, search the script for quoted English sentences and for `toLocaleDateString` or `toLocaleString` calls.

   Replace every item of the sample identity: `Ondelle Nocturne`. Warnings (not errors) also point at first names, initials and other words that may belong to the sample, such as `Ondelle`; check each one. Some of these names are also part of image file names and slugs; when you change one, rename the matching file in `work/images/` as well, or the single-file build stops on a missing file. Every link needs a real destination: the template may contain placeholder links (`href="#"`, or profile links that only show a notice in a preview), so give each a real URL or remove it. When the brief has no URL yet, use an `example.com` address and say so in your reply; the validator then only warns (`placeholder-domain`). Delete the instruction comments the template carries (those that start with `REPLACE`), because the validator treats them as leftovers. Remove sections the brief does not need together with their menu links and styles. If the user supplies brand colours or fonts, re-theme through the template's colour tokens (its CSS custom properties, in both themes where there are two) and keep the layout, sections and motion as they are. A heading font may only be switched to another font bundled in `assets/fonts/`. Never link a font from another site. Keep the ids listed in `assets/validate.config.json` (`requiredIds`); the template scripts look them up. If the brief really drops a whole view, copy that file to `work/validate.config.json`, delete that view's ids from `requiredIds`, and pass `--config work/validate.config.json` to the validator.
5. **Handle images.** Slots are listed in `references/image-plan.md`. The shipped files are neutral placeholders or images generated with this skill for a fictional example brief; replace every one the page shows. Generate each replacement with your image tool at the stated size, or use photos the user supplies, check the result by eye, and keep the file name pattern the markup expects. When you have neither, ask the user for images, remove sections that would show a placeholder prominently, and list every remaining placeholder in your reply. Never link to an image on another site.
6. **Build one file.** Run `node scripts/inline-assets.mjs work/src.html work/index.html`. It embeds images and fonts as data URIs and stops on a missing or damaged file.
7. **Validate.** Run `node scripts/validate.mjs work/index.html --mode site --site-lang <en|zh-CN>` and repeat until it exits 0. The exit code is 1 while any error remains. Add `--lang zh-CN` to get messages in Chinese (a Windows console that is not UTF-8 shows them garbled: run `chcp 65001` first) and `--out work/report` for `report.json` plus HTML reports.
8. **Look at it in a browser (optional, recommended).** Add `--browser --screenshot work/shots`. A headless Chrome or Edge opens the page, clicks the controls, walks the routes and writes screenshots; open the screenshots and judge them yourself. Exit code 3 means no browser was found.
9. **Report back.** Say what you drafted versus what the user supplied, list placeholder and generated images, and give the path of `work/index.html`.

## Language

- Set `<html lang="en">` or `<html lang="zh-CN">` to match the copy, and run the validator with the same `--site-lang`.
- For `zh-CN`, translate visible text, `alt`, `aria-label`, `placeholder`, form errors and the `<title>`. Put a CJK family in every `font-family` stack, for example `"PingFang SC", "Noto Sans SC", "Microsoft YaHei"`, before the generic fallback.
- Chinese copy does not need Latin-style letter spacing or all-caps; remove `text-transform: uppercase` and positive `letter-spacing` where they sit on translated text.
- The validator warns (`lang-mixed`) about English sentences it can see on a `zh-CN` page. Short words and strings assembled in the script ("All", "2 posts") slip through, so open every route and read it.
- `--lang` only changes the language of validator messages and reports. It never changes the page.

## Rules

- The finished page is a single self-contained file: no remote scripts, fonts, images or stylesheets, no network calls, no `alert` or `window.open`.
- Icons are inline SVG. Do not use emoji or dingbat characters.
- Do not invent real people, customers, certifications, awards or legal claims. State only what the user confirmed, and label generated portraits as illustrations.
- Never put credentials or tokens in the page, in logs or in the report.

## Failure boundaries

- The validator checks structure, leftovers, assets and (with `--browser`) basic behaviour. It cannot judge taste, copy quality or whether a claim is true.
- Dead-control detection is heuristic. A control whose effect is invisible in the page (copying to the clipboard, for instance) shows up as dead; see `references/validation.md` for how the template handles that.
- `--browser` needs a local Chrome or Edge. Without one, the static checks still run.
- Large image sets can push the file past the 5 MB soft limit (8 MB hard limit). Use fewer or smaller images.

## FAQ

- **Can I use the template inside a framework project?** Yes, as a visual and behavioural reference. The scripts in this skill only validate standalone HTML files.
- **Why does the validator fail on words I did not write?** Those are leftovers of the sample content. Replace them, or remove the section they sit in.
- **Which Node version?** 18 or newer for the static checks; `--browser` also works on 18 because it drives Chrome through a small local server.

## Files

- `assets/template.html`: the working template (source of truth for markup, CSS and script).
- `assets/images/`: 10 slots holding example images we generated; replace every one the page shows.
- `assets/fonts/`: bundled variable fonts with their OFL licence.
- `assets/validate.config.json`: sample identity, required ids, route names and documented exceptions for the validator.
- `assets/agent-mode.json`: generator marker and template checksum.
- `references/style-guide.md`: tokens, type, surfaces, components and voice.
- `references/sections.md`: every view and section with its id.
- `references/motion.md`: what moves, how fast, and how reduced motion is handled.
- `references/image-plan.md`: image slots, sizes and how to replace them.
- `references/validation.md`: every validator rule with its default severity.
- `references/third-party-notices.md`: font licences and image notes.
- `scripts/validate.mjs`, `scripts/inline-assets.mjs`, `scripts/lib/`: the checks and the single-file builder (zero dependencies).