Commit graph

12 commits

Author SHA1 Message Date
Marc Chan
1c7233ef10
fix(landing-page): speed up landing-page CI builds (#2734)
* fix(landing-page): speed up landing-page CI builds

* fix(landing-page): disable dev-only landing caches

Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode)

* fix(landing-page): reuse previews across CI runs

* fix(landing-page): hash shared preview dependencies

Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode)

* fix(landing-page): skip missing preview html reads

Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode)

* fix(landing-page): rerun previews on cache hits

Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode)

* fix(ci): repair landing-page workflow cache keys
2026-05-23 00:30:31 +08:00
ashleyashli
558fedd207
fix(landing): wire GA4 rollout config (#2615)
Co-authored-by: ashley li <ashleyli@ashleydeMacBook-Air-2.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-22 14:56:58 +08:00
Jane
439f071cb0
feat(landing-page): replicate #2469 SEO content with deploy + regression fixes (#2605)
* chore(landing-page): bring PR #2469 content wholesale onto post-revert main

Step 1 of replicating @pftom's #2469 work without the deploy-blocking
issues that forced #2603. This commit copies the full \`apps/landing-page/\`
diff from #2469's HEAD (`9d2a4f1`) onto current main verbatim — every
i18n bundle, every page rewrite, every \`[locale]/\` wrapper. Subsequent
commits on this branch then surgically restore the SEO fixes that
#2469 silently regressed and configure the sitemap to survive the
Cloudflare Pages 25 MiB limit, so deploy is healthy when this lands.

What's in this commit
- Tom's i18n bundle: \`i18n.ts\` (5377 lines), \`home-page-i18n.ts\`,
  \`info-page-i18n.ts\`, \`landing-ui-i18n.ts\`, \`content-i18n.ts\`
  (~10K lines total of locale data)
- 18 landing-page locales: en, zh, zh-tw, ja, ko, de, fr, ru, es,
  pt-br, it, vi, pl, id, nl, ar, tr, uk
- All existing pages rewritten to consume the new i18n bundle
- Full \`[locale]/<route>/\` wrapper tree for every catalog page
- \`plugin-registry.ts\` rewrite, \`catalog.ts\` adjustments
- \`astro.config.ts\` route + sitemap reconfiguration
- \`public/_headers\`, \`public/_redirects\`, \`public/favicon.svg\` adds
- \`_components/locale-switcher-script.astro\` add

What's intentionally NOT done in this commit (handled in follow-ups
on this same branch):
- Restore brand mark 44px + rounded corners (was lost from #2588)
- Restore HA SoftwareApplication \`alternateName\` array (was lost from #2566)
- Restore HA \`url\` canonical pointing at the landing page (was lost from #2586)
- Restore Product/Library/Tutorials/Blog nav grouping (was lost from #2588)
- Restore catalog-card padding 24px (was lost from #2600)
- Configure sitemap to filter \`[locale]/\` routes so the generated XML
  stays under 25 MiB and Cloudflare Pages accepts the deploy
- Add \`/zh-CN/* → /zh/*\` redirects for backwards-compatibility with
  any externally-linked OD-canonical locale URLs

Validation so far
- \`pnpm --filter @open-design/landing-page typecheck\` — 0 errors

* fix(landing-page): unblock deploy + restore SEO regressions on top of #2469

Step 2 of replicating @pftom's #2469. The previous commit on this
branch brings #2469's content wholesale; this commit applies the
surgical fixes that make the result actually deploy and preserves
the SEO improvements that #2469 silently regressed.

Fix 1 — sitemap stays under Cloudflare Pages 25 MiB upload limit
- `astro.config.ts` `filter` now drops every `/{locale}/...` route
  so the sitemap only emits canonical English URLs.
- Locale variants are still discoverable via the
  `<xhtml:link rel="alternate" hreflang="...">` annotations the
  `namespaces.xhtml: true` option emits inside each canonical entry.
  This is Google's recommended pattern for a multi-language site.
- Verified: post-fix `out/sitemap-0.xml` = 179 KB (was 38.4 MiB
  on the prior attempt that forced #2603's revert).

Fix 2 — header brand block restored to the polished version
- Logo `width/height` 36 → 44 (matches PR #2588's brand-mark refresh
  for visual weight against the new black speech-bubble glyph)
- `.brand-meta` block ("Studio Nº 01 · Berlin / Open / Earth") removed
  from the header bar; the same editorial flourish still lives on the
  rotated `.side-rail .rail-text` pseudo-elements at page edges.

Fix 3 — header nav grouped into Library + standalone Tutorials/Blog
- Skills / Systems / Templates / Craft are now children of a Library
  dropdown (matches PR #2588's grouping). Each row keeps its count
  badge inline; the trigger highlights when any of the four facet
  pages is active.
- Tutorials and Blog stay as standalone top-row items (PR #2588's
  original decision after Joey's review on the Learn dropdown).
- Contact removed from the header — it was a same-page anchor that
  the footer already surfaces.
- Hardcoded "Library" / "Tutorials" labels match the brand-name
  pattern: unlocalized across all 18 landing-page locales.

Fix 4 — HA SoftwareApplication entity canonicalized on the LP again
- `alternateName` is back to an explicit array of real query
  variants `["html anything", "html-anything", "htmlanything",
  "HTML Anything Editor", "The agentic HTML editor"]`. #2469
  re-routed it through `copy.schemaAlternateName` which dropped
  the literal alias declarations Google needs for spaced-vs-
  hyphenated-vs-joined matching. (Restores PR #2566.)
- `url` flips back from `HA_URL` (the GitHub repo) to the LP URL
  itself, matching the `BreadcrumbList` block on the same page.
  GitHub repo lives in `sameAs` as a peer surface. (Restores PR
  #2586. Without this, Google credits the GitHub repo as canonical
  for the entity, which is the opposite of what this surface
  exists for.)

Fix 5 — catalog-card horizontal padding unified at 24 px
- featured-card 22 → 24, template-card 20 → 24,
  system-card 18 → 24, source-card 28 → 24.
- For template-card, also moved horizontal padding into the group
  rule exclusively so future siblings join without re-asserting
  margin shorthands. (Restores PR #2600.)

Fix 6 — `_redirects` for the locale-code rename
- This bundle uses `zh` / `zh-tw` / `pt-br` / `es` (the codes Tom's
  i18n.ts ships). The previous OD landing-page used `zh-CN` /
  `zh-TW` / `pt-BR` / `es-ES`. Externally-indexed and inbound-linked
  URLs against the old prefixes now 301 to the new canonical.

Validation
- `pnpm --filter @open-design/landing-page typecheck` — 0 errors
- `pnpm --filter @open-design/landing-page build` — completed
  successfully; 18,204 pages built; sitemap-0.xml is 179 KB
  (well under the 25 MiB Cloudflare Pages limit).

* docs: promote 'open-source alternative to Claude Design' to README H1

Brings the missing README and .gitignore changes from #2469 that the
first wholesale-checkout in this branch missed (the auto-pulled diff
scope was filtered to apps/landing-page/ initially).

What
- Every README.*.md (13 locale variants) now leads with the
  "open-source alternative to Claude Design" tagline as a subtitle to
  the project name in the H1 / first paragraph. This was @pftom's
  brand-positioning commit (`ee851dc`) on the original #2469 branch.
- `.gitignore` adds `growth/**` to keep growth-research scratch out of
  the repo.

Why
- The README is one of the highest-PageRank surfaces a GitHub project
  exposes to Google. Promoting the "alternative to Claude Design"
  framing into the H1/subtitle position makes the project surface for
  exactly the query the SEO work in this PR is trying to capture.
- Without this commit, the replicated #2469 in this branch would still
  rank against the previous H1 ("Open Design") on GitHub crawls,
  letting the SEO win at the LP fall short on the GitHub surface.

This is a strict subset of #2469's content — pure docs, no code,
no behavior change beyond what GitHub renders on the repo overview.

---------

Co-authored-by: Joey-nexu <joeylee12629@gmail.com>
2026-05-22 00:59:11 +08:00
Jane
eefaf4504a
Revert "Enhance landing page with SEO-focused content and FAQ section (#2469)" (#2603)
This reverts commit 26ee030b4c.

Co-authored-by: Joey-nexu <joeylee12629@gmail.com>
2026-05-22 00:23:37 +08:00
Tom Huang
26ee030b4c
Enhance landing page with SEO-focused content and FAQ section (#2469)
* Enhance landing page with SEO-focused content and FAQ section

- Updated `.gitignore` to include growth directory.
- Modified `astro.config.ts` to prioritize high-intent landing pages for SEO.
- Added new FAQ styles and layout in `globals.css` for better user experience.
- Implemented FAQ section in `page.tsx`, ensuring it aligns with structured data requirements.
- Created dedicated pages for agents and alternatives to Claude Design, enhancing SEO and user navigation.
- Introduced comparison page for evaluating Open Design against competitors.
- Added favicon links component for consistent branding across all pages.

* Add SVG favicon and update favicon links for improved branding

* Enhance landing page with official source pillars for improved branding and navigation

- Added five canonical "official source" pillars to the homepage, reinforcing key links: official site, GitHub repository, releases, documentation, and Discord community.
- Updated URLs for releases, issues, documentation, and license to streamline access and improve user experience.

* Add locale support and enhance landing page with language switcher

- Introduced locale management with a new i18n module, defining multiple languages for the landing page.
- Implemented a locale switcher in the topbar and header, allowing users to select their preferred language.
- Updated global styles for the locale selector and adjusted layout for better responsiveness.
- Enhanced SEO by ensuring localized content is served based on user selection.
- Added a script for automatic locale detection and persistence in local storage.

* Implement localized routing and enhance navigation with href utility

- Added `stripLocaleFromPath` and `localizedHref` functions to manage locale-based URL paths.
- Updated `localePath` to normalize paths based on the detected locale.
- Refactored links in the header, footer, and main page components to utilize the new `localizedHref` function for improved navigation.
- Introduced locale-aware routing for new pages, ensuring consistent user experience across different languages.
- Enhanced SEO with alternate links for localized content in the sub-page layout.

* Update header component to use new logo format

- Replaced favicon image with a new logo in WebP format for improved performance and quality.
- Ensured consistent branding across the landing page with the updated logo.

* Enhance landing page with localization and new UI components

- Introduced a comprehensive localization schema for content management, allowing for multilingual support across various sections.
- Updated the blog and collection schemas to include internationalization (i18n) fields for better content localization.
- Implemented a new official source strip for improved navigation and branding, linking to key resources like the official site and documentation.
- Enhanced the locale switcher functionality, allowing users to select their preferred language with improved UX.
- Updated styles for the locale switcher and added new components for better responsiveness and accessibility.
- Refactored existing components to utilize localized URLs, ensuring a consistent user experience across different languages.

* Implement comprehensive localization and enhance landing page UI

- Introduced new localization features, including `EXTRA_LOCALIZED_HOME_BODY_COPY` and `EXTRA_LOCALIZED_LANDING_UI_COPY`, to support multilingual content across the landing page.
- Updated `astro.config.ts` to integrate internationalization (i18n) settings for the sitemap, improving SEO for localized content.
- Created new files for home page and info page internationalization, defining structured content for various languages.
- Enhanced the locale switcher functionality with improved UX, allowing users to easily select their preferred language.
- Refactored existing components to utilize localized content and URLs, ensuring a consistent experience across different languages.
- Made CSS adjustments for better responsiveness and accessibility in the UI components.

* Enhance landing page with new design templates and localization improvements

- Added support for design templates in the content management system, allowing for better organization and access to design resources.
- Implemented comprehensive localization for blog topics, enhancing multilingual support across various sections of the landing page.
- Updated the header component to include new product menu items, improving navigation and user experience.
- Refactored CSS for improved responsiveness and accessibility, including a new sticky chrome bar for better navigation.
- Enhanced the locale switcher functionality, ensuring a seamless experience for users selecting their preferred language.

* docs(readme): promote 'open-source alternative to Claude Design' tagline to subtitle across locales
2026-05-21 23:40:58 +08:00
Eli-tangerine
c37c691d82
[codex] Add landing page Google Analytics (#2582)
* Add Claude-style design system workflow

* Merge design system workflow into main

* Restore design system workflow UI styles

* Fix design system setup scrolling

* Fix design system setup connector button

* Preserve connector auth link after popup block

* Simplify connected GitHub setup state

* Open generated design system workspace project

* Summarize design system auto prompt in chat

* Add bounded GitHub connector design intake

* Prefer path-scoped GitHub intake tools

* Restore branch GitHub design context intake

* Restore design system review workspace

* Restore design system manager tab

* Let design system workflow routes own details

* Open editable design systems as projects

* Restore design system workspace coverage

* Fix bounded GitHub connector intake

* Hide design system review while generating

* Suppress design system generation questions

* Constrain GitHub design intake to bounded command

* Tolerate oversized GitHub metadata during intake

* Rebuild daemon CLI when sources change

* Fallback when GitHub connector snapshots are rate limited

* Allow GitHub intake without Composio

* Use native GitHub auth for design intake

* Remove design system review group heading

* Improve design system extraction evidence

* Align design system scaffold with Claude output

* Add evidence inventory for design system intake

* Add local design system evidence intake

* Add design system package audit gate

* Allow auditing Claude Design reference packages

* Audit design system package content quality

* Migrate legacy design system artifacts

* Clean migrated design system artifacts

* Require modular design system UI kits

* Reject thin design system UI kits

* Prioritize core design evidence intake

* Require role-based design system UI kits

* Clean stale design system manifest references

* Require representative preserved design assets

* Warn on generic design system visuals

* Enforce design system quality warnings

* Audit connected design system UI kits

* Require mounted design system UI kits

* Require composed design system app shells

* Require runnable JSX design system kits

* Require browser globals for design system components

* Infer design system names from source URLs

* Require source examples in design system packages

* Bind preserved fonts in design system tokens

* Require skill frontmatter in design system packages

* Preserve build icons in design system packages

* Require real assets in brand previews

* Require substantive source examples

* Require product overview in design system README

* Require reusable UI kit README

* Require reusable design system skill docs

* Seed Claude-style UI kit entry contract

* Preserve runtime build assets in design packages

* Audit design system packages after generation

* Audit design system first-run output

* Audit source-backed preview cards

* Align design system UI kit scaffolds

* Materialize design evidence package artifacts

* Show project chat during design system setup

* Hand off design system setup to project chat

* Auto-repair design system audit failures

* Harden design system evidence preservation

* Tighten design system package guidance

* Add targeted design system repair guidance

* Bound design system audit auto repair

* Use connector statuses in design system setup

* Audit design system preview manifests

* Require README preview manifests for design systems

* Add landing page Google Analytics

* Keep GA PR scoped to landing page

* Cover new landing routes with Google Analytics

* Load Google Analytics without static script src

---------

Co-authored-by: qiongyu1999 <2694684348@qq.com>
2026-05-21 20:38:09 +08:00
ashleyashli
86dafa9be8
feat(landing): add 19-locale URL routing with full home translations (#2408)
* feat(landing): add 19-locale URL routing with full home translations

Adds locale-prefixed routes (/zh-CN/, /ja/, /de/, …) for 18 non-default
locales while keeping English as the only unprefixed canonical. Generates
proper hreflang + og:locale, points hreflang="en" / x-default at the
unprefixed canonical, and serves localized RSS and plugin search JSON
under each prefix.

Adds a visible language switcher (globe pill + native names) on every
page, replacing the small topbar dropdown. Native-name menu, current
locale marked aria-current, closes on outside click / Escape, only one
open at a time.

Adds app/_lib/home-copy.ts as the source of truth for marketing copy
on the landing page, with full translations for zh-CN, zh-TW, ja, ko,
de, fr, es-ES, pt-BR. Remaining locales (it, pl, hu, ru, uk, tr, ar, fa,
th, id) fall back to English for marketing copy while still getting
fully localized chrome.

Extracts the IntersectionObserver reveal + GitHub stats + wire ticker
script into _components/home-enhancer.astro so localized homepages
animate in the same way as the canonical home.

- New: app/_lib/i18n.ts, app/_lib/home-copy.ts
- New: app/_components/home-enhancer.astro, locale-switcher-enhancer.astro
- New: app/pages/[locale]/{index,[...path]}.astro, blog/rss.xml.ts,
  plugins/search.json.ts

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(landing): bound localized routing to listing pages only

Detail pages (skills/<slug>, blog/<id>, systems/<slug>, templates/<slug>,
craft/<slug>, plugins/<slug>) no longer fan out across 18 prefixed
locales — they stay at their canonical English URLs. Localized chrome
on listing pages links straight to those English detail URLs.

Generated page count drops from ~6,000+ to ~1,800 and the landing-page
CI build returns to ~50s. Localized homes, listings, and filter index
pages (skills/mode/*, skills/scenario/*, systems/category/*) are all
still produced per locale.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: ashley li <ashleyli@ashleydeMacBook-Air-2.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-21 11:36:15 +08:00
ashleyashli
e4d6d4e805
fix(landing): keep template preview lookup stable in CI (#2412)
Resolve generated preview thumbnails from both workspace-root and package-root
build layouts so Astro production builds can see the images created by the
landing preview step. A later merge restored the source-relative lookup, which
made /templates render 111 cards with placeholder thumbs despite the PNG files
being deployed.

Co-authored-by: ashley li <ashleyli@ashleydeMacBook-Air-2.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 18:48:02 +08:00
ashleyashli
96b6db14c2
feat(landing): rebuild /templates/ catalog from design-templates (#2369)
Some checks failed
ci / Detect CI change scopes (push) Successful in 1s
landing-page-ci / Validate landing page (push) Failing after 2s
landing-page-deploy / Deploy landing page (push) Has been skipped
nix-check / build (push) Failing after 2s
ci / Preflight (push) Failing after 1s
ci / Core package tests (push) Failing after 1s
ci / Tools workspace tests (push) Failing after 1s
ci / Daemon workspace tests (1/2) (push) Failing after 1s
ci / Daemon workspace tests (2/2) (push) Failing after 1s
ci / Web workspace tests (push) Failing after 1s
ci / E2E vitest (push) Failing after 1s
ci / Playwright critical (starters) (push) Failing after 1s
ci / Playwright critical (core) (push) Failing after 1s
ci / Build workspaces (push) Failing after 1s
ci / App workspace tests (push) Failing after 0s
ci / Validate workspace (push) Failing after 0s
ci / Runtime trace (push) Has been skipped
Source the public templates page from `design-templates/*/SKILL.md` so
the catalog reflects the renderable template registry (111 entries with
mode, platform, and scenario metadata) instead of the previous handful
of live-artifact + skill-mode shims. Render per-template thumbnails by
shooting each design template's `example.html`, surface mode/platform/
scenario chips on cards and detail pages, and bump the preview
navigation timeout so heavier examples no longer flake under
concurrency.

Co-authored-by: ashley li <ashleyli@ashleydeMacBook-Air-2.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 14:29:44 +08:00
Yuhao Chen
2e1dd497aa
fix(landing): expose blog RSS feed alias (#1859) 2026-05-16 21:52:11 +08:00
ashleyashli
e3c7c3c611
fix(landing): unify blog chrome and star counts (#1811)
* fix(landing): unify blog chrome and stars

Ensure blog and catalog pages share the same header/footer behavior, with safe GitHub star fallbacks and RSS discovery for the refreshed blog.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(nix): update pnpm dependency hash

Keep Nix fixed-output dependency hashes aligned with the landing page lockfile changes.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: ashley li <ashleyli@ashleydeMacBook-Air-2.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-15 16:56:19 +08:00
Joey-nexu
5077a1cd38
feat(landing-page): split catalog into per-facet pages + auto-deploy on content changes (#1158)
* feat(landing-page): split catalog into per-facet pages + auto-deploy on content changes

Convert the single-page landing into a content-driven multi-page site
sourced directly from the canonical Markdown bundles in the repo root,
and close the deploy loop so contributor edits go live without manual
follow-up.

## What's new

- `/skills/`, `/systems/`, `/craft/`, `/templates/` index + detail
  pages, generated from `skills/<slug>/SKILL.md`,
  `design-systems/<slug>/DESIGN.md`, `craft/*.md`, and
  `templates/live-artifacts/<slug>/README.md` via Astro content
  collections (`app/content.config.ts`). No mirroring of content into
  the landing-page package — `glob` re-scans on every build.
- Faceted sub-routes generated from frontmatter:
    - `/skills/mode/<slug>/`     — 8 pages (deck, prototype, image, …)
    - `/skills/scenario/<slug>/` — 18 pages after alias collapse
    - `/systems/category/<slug>/` — 21 pages
  Each page owns its own `<title>`, meta description, and
  `CollectionPage` JSON-LD; chips on the parent index pages are now
  real anchors that link to these facet routes.
- Updated top-bar nav (`_components/header.tsx`) to point at the new
  internal routes with live counts pulled from the catalog. Counts in
  the homepage hero meta description likewise driven by
  `getCatalogCounts()` so they never drift.
- Per-skill / per-template thumbnails. A Playwright generator
  (`scripts/generate-previews.ts`) walks every `example.html` and
  `templates/live-artifacts/<slug>/index.html`, screenshots them at
  1440×900@2x, and writes PNGs to `public/previews/`. The catalog
  data layer auto-detects presence and degrades gracefully when an
  artifact has no renderable HTML.

## Plumbing the auto-update loop

- `landing-page-deploy.yml` and `landing-page-ci.yml` now trigger on
  changes under `skills/`, `design-systems/`, `craft/`, and
  `templates/`. Without this, a contributor adding a new SKILL.md to
  `main` would silently skip the deploy and the published site would
  fall behind.
- Both workflows now install Playwright Chromium (cached by version)
  and run `pnpm previews` before `astro build`, so generated
  thumbnails ship in `out/previews/` automatically. Preview generation
  is `continue-on-error: true` — a single broken example.html should
  not block the deploy of the rest of the catalog.
- `apps/landing-page/public/previews/` is gitignored: the directory
  is owned by CI and would otherwise add ~70MB of binary churn to the
  repo on every regeneration.

## Tag canonicalization

- `app/_lib/catalog.ts` adds a small per-scope alias table so
  authoring drift like `od.scenario: operation` vs `operations`, or
  `live` vs `live-artifacts`, collapses to a single canonical route
  instead of leaking two near-empty pages. Mode and category alias
  tables are scaffolded but currently empty.

## Validation

- `pnpm --filter @open-design/landing-page typecheck` — 0 errors,
  0 warnings, 0 hints across 25 Astro files
- `pnpm --filter @open-design/landing-page build` — 341 pages built
  (1 home + 8 mode + 18 scenario + 21 category + N detail pages +
  sitemap + RSS), zero external JS, ≥16 Cloudflare-resized hero
  image URLs intact

## Why this matters

After merge, any push to `main` that adds, removes, or edits a skill,
design system, craft principle, or live-artifact template
automatically triggers a fresh build that:

1. picks up the new Markdown via the content-collection glob,
2. regenerates thumbnails for any matching example.html,
3. emits new sitemap entries and JSON-LD,
4. and ships to Cloudflare Pages — no landing-page-side change
   required.

* fix(landing-page): address review feedback on PR #1158

Five fixes from the review pass — none change scope, all close the
"contradictory totals" / "stale data" / "silent CI failure" gaps the
reviewers flagged.

## Hero / catalog claims now read live counts everywhere

`apps/landing-page/app/page.tsx` previously hardcoded `31` skills and
`72` systems in the hero copy and stat rings, while the nav and meta
description had already moved to `getCatalogCounts()`. After this PR
every visible "X skills / Y systems" claim — hero lead, hero stat
rings, capabilities cards body copy, labs section meta + filter pills,
selected-work fractions, the labs CTA, and the footer Library — reads
from a single `counts` prop. `Header` and `Page` now both require
`counts` (no optional fallback) so a future caller can never silently
publish stale numbers.

The labs-section filter pills also stop being decorative buttons:
they now link to the actual `/skills/mode/<slug>/` and `/skills/`
catalog routes the new multi-page architecture exposes.

## Craft README no longer publishes

`apps/landing-page/app/_lib/catalog.ts` filtered out `e.id !== 'README'`,
but Astro normalizes `craft/README.md`'s id to lowercase `readme`, so
the published site shipped `/craft/readme/` as a public craft principle
and the nav badge counted 12 instead of 11. Compare case-insensitively
(`e.id.toLowerCase() !== 'readme'`) so any future README casing is
also filtered out. Verified locally: `apps/landing-page/out/craft/`
now contains exactly 11 entries.

## Preview URL preserves actual file extension

`listPreviews()` was already discovering `.png`, `.webp`, `.jpg`, and
`.jpeg`, but `previewUrlFor()` always emitted `.png`, so a future
sharp/webp post-processor (or a manually committed template asset)
would mark the record as available while the rendered `<img src>`
404'd. Switched the structure from `Set<slug>` to `Map<slug, filename>`
and emit the actual on-disk filename verbatim.

## Preview script: per-artifact soft, systemic hard

Previously any single failed `example.html` capture exited the script
non-zero, which forced both workflows to mark the entire preview step
`continue-on-error: true`. That blanket tolerance also masked
systemic generator failures — a chromium launch that never finds the
browser binary would silently ship a deploy with zero thumbnails.

`scripts/generate-previews.ts` now distinguishes:

- per-artifact failures → logged and skipped, exit 0 (catalog
  degrades gracefully for those skills),
- discoverJobs / chromium.launch / 100%-failure run → exit 1
  (systemic, must fail the build).

Both workflows drop their `continue-on-error: true` flags so a real
problem actually surfaces.

## AGENTS.md reflects the multi-page architecture

`apps/landing-page/AGENTS.md` previously declared the landing page
single-route ("Not multi-page. There is exactly one route ('/')").
That guidance is now wrong — there are six top-level route groups
(`/`, `/skills/`, `/systems/`, `/craft/`, `/templates/`, plus their
facet variants). Updated to describe content-collection sourcing, the
no-mirror rule, the auto-deploy workflow contract, and the
"never hardcode catalog claims" boundary.

## Validation

- `pnpm --filter @open-design/landing-page typecheck` — 0 errors,
  0 warnings, 0 hints across 25 Astro files
- `pnpm --filter @open-design/landing-page build` — 340 pages built
  (was 341 before the README filter; the README route is now
  correctly absent), live counts visible in the built `out/index.html`:
  `driven by 125 composable skills and 149 brand-grade design systems`
- Verified `out/craft/` no longer contains `readme/`
- Verified preview URLs resolve to the actual on-disk filename via
  the regenerated catalog index page

* fix(landing-page): clean up live-artifact template name + summary parsing

Address @mrcfps's follow-up review on `0715d8c`. The
`shapeLiveArtifactTemplate()` parser was passing the README's H1
verbatim (literal backticks intact) and using the first non-empty
post-H1 line as the summary, even when that line was the
`> Category: **Live Artifacts**` editorial blockquote. Result:
`/templates/live-otd-operations-brief/` was shipping a
`<meta name="description" content=">">` and a card title with raw
Markdown noise — a regression for both SEO snippets and the
templates catalog at-a-glance scan.

## Two new shared helpers

- `stripMarkdownInline()` — strip backticks, asterisks, and link
  wrappers so `# \`otd-operations-brief\` · live-artifact template`
  becomes `otd-operations-brief · live-artifact template` before any
  further trimming.
- `extractFirstProseParagraph()` — walk the body after the H1 and
  skip blockquotes (`>`), list markers, table rows, fenced code, and
  HR rules. Stop at the first contiguous prose paragraph and pass it
  through `stripMarkdownInline()` so the result is human-readable.

Both helpers live next to `titleizeSlug()` and are used by
`shapeCraft()` and `shapeLiveArtifactTemplate()` so they share one
implementation.

## Live-artifact title boilerplate trim

Live-artifact READMEs commonly title themselves
`# \`<slug>\` · live-artifact template`. After stripping the inline
backticks the trailing `· live-artifact template` is redundant
("Templates" already groups them) and adds a wide noisy suffix on
catalog cards. Removed it via a narrow regex tail-strip.

## Result on the existing fixture

Verified locally for `templates/live-artifacts/otd-operations-brief/`:

- before: `<title>\`otd-operations-brief\` · live-artifact template …</title>`,
  `<meta name="description" content=">">`
- after:  `<title>otd-operations-brief — Open Design template</title>`,
  `<meta name="description" content="A drop-in html_template_v1
  live-artifact template for an editorial On-Time Delivery brief.
  It ships:">`

Typecheck 0/0/0, build 340 pages.

---------

Co-authored-by: Joey <joey@cursor.so>
Co-authored-by: Joey-nexu <236967869+joeylee12629-star@users.noreply.github.com>
2026-05-12 19:24:50 +08:00