mirror of
https://github.com/nexu-io/open-design.git
synced 2026-05-31 19:04:39 +07:00
17 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9f09d1b649
|
fix(landing-page): wire up mobile nav toggle on the homepage (#3295)
The homepage runs its own inline header enhancer instead of importing the shared header-enhancer.astro component, and that inline copy only ported the scroll-headroom and GitHub stars/version logic — it never included the hamburger toggle handler. As a result the mobile menu button rendered (and animated to an X via CSS) but clicking it did nothing on / and /<locale>/, while sub-pages that do import the shared enhancer worked fine. Port the same toggle handler into the homepage inline enhancer: click flips .is-open on header.nav (which CSS expands into the dropdown panel below 1080px), and outside-click, Escape, and any in-menu link close it, keeping aria-expanded in sync. Co-authored-by: Joey-nexu <joeylee12629@gmail.com> |
||
|
|
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> |
||
|
|
5f7d65d513
|
perf(landing): preconnect api.github.com + rAF-throttle scroll listener (#2666)
Two PSI-targeted wins (split from #2599 follow-up). 1. New `resource-hints.astro` mounted in every page's <head> declares `<link rel="preconnect" href="https://api.github.com" crossorigin>`. The inline enhancer script on /` issues 3 fetch() calls to api.github.com right after DOMContentLoaded (stars, latest release, contributors). Without preconnect each pays a full DNS + TCP + TLS handshake (~150-300ms) inline with the fetch. With preconnect those handshakes happen in parallel with HTML parse and all three share one warmed HTTP/2 connection. 2. Wrap the scroll listener's read + classList write in requestAnimationFrame. Trackpads and high-rate wheels fire scroll faster than display refresh, and every callback that hits classList triggers layout recalc. PSI was attributing ~700ms of "forced reflow" to the un-throttled version. The rAF gate collapses each burst to one DOM mutation per frame; `{ passive: true }` is preserved so the listener still doesn't block the scroll thread. Same throttling pattern mirrored to `header-enhancer.astro` (used by every sub-page) and `home-enhancer.astro` (kept in lockstep even though /` currently uses its own inline copy). Expected PSI delta: - "Preconnect to required origins" hint: cleared - "Forced reflow" diagnostic 700ms → near zero - LCP: small bonus from earlier GH fetch warm-up (~100-300ms) |
||
|
|
7f03030f3f
|
perf(landing): self-host fonts + inline critical CSS (#2599)
* perf(landing): self-host fonts + inline critical CSS
PageSpeed Insights flagged ~2.3s of render-blocking on /:
globals.css 12.9 KB external link, 160ms
fonts CSS 2.2 KB fonts.googleapis.com, 750ms
+ 4 woff2 ~1200ms each from fonts.gstatic.com
Two changes drop that whole chain:
1. Self-host fonts via @fontsource-variable/{inter,inter-tight,
playfair-display,jetbrains-mono}. Each family ships a single variable
woff2 (covers all weights we use) that Astro bundles into /_astro/*
alongside the rest of the build, served same-origin through CF Pages —
no separate TLS handshake, no Google Fonts CSS round-trip. The CSS
variable names get an extra alias in front (`'Inter Tight Variable',
'Inter Tight', ...`) so a system fallback still works if the package
ever ships under a different family name.
2. `astro.config.ts: build.inlineStylesheets: 'always'` inlines every
emitted <style> into the HTML <head> instead of emitting a separate
/_astro/*.css link. The HTML grows from ~13KB to ~28KB (gzip) but
loses one stylesheet round-trip + the entire @font-face chain that
used to gate text rendering.
Component cleanup: the `<FontStylesheet>` component (preconnect + link to
fonts.googleapis.com) is no longer needed and is deleted, removed from
all 7 places that mounted it. og.astro keeps its own font setup since
it renders to a screenshot.
Expected effect (from PageSpeed Insights "Render-blocking requests"
diagnostic on the previous build):
FCP 1.9s → ~1.2s
LCP 2.2s → ~1.5s
Verified: pnpm typecheck 0 errors, pnpm build 1853 pages 78s, preview
serves /_astro/*.woff2 as font/woff2 same-origin, 0 fonts.googleapis or
fonts.gstatic references in the built HTML.
* perf(landing): include Playfair italic + bump nix pnpm-deps hash
Two follow-ups on the self-host fonts PR:
1. globals.css imported only `@fontsource-variable/playfair-display`,
which ships @font-face for font-style: normal only. The previous
Google Fonts URL included the italic axis (`ital,wght@0,500;1,400;
...`) and several rules (.roman, .work-rule .roman, .sec-rule .roman,
plus 8 other italics across globals.css + sub-pages.css) render
Playfair italics via `font-family: var(--serif); font-style: italic`.
Without the italic face self-hosted, those would fall through to
Times New Roman italic or browser synthesis. Adding
`wght-italic.css` keeps the typography visually equivalent.
2. nix/pnpm-deps.nix uses a fixed-output derivation hash that has to
match the pnpm vendored store; adding the four fontsource packages
changed pnpm-lock.yaml so the hash has to be bumped to the value Nix
reported in CI.
Codex (Looper reviewer) flagged #1 as non-blocking.
* perf(landing): pin fontsource versions exactly per repo guard
`pnpm add` defaulted to caret ranges (`^5.2.8`) but repo guard rejects
non-exact specs ("dependency specs must be exact versions like 1.2.3 or
workspace:*"). That was the actual cause of the Preflight + Validate
workspace failures — pinning to the locked versions Codex reviewer
called out:
@fontsource-variable/inter 5.2.8
@fontsource-variable/inter-tight 5.2.7
@fontsource-variable/jetbrains-mono 5.2.8
@fontsource-variable/playfair-display 5.2.8
`pnpm guard` now passes locally (6/6 tests).
|
||
|
|
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> |
||
|
|
eefaf4504a
|
Revert "Enhance landing page with SEO-focused content and FAQ section (#2469)" (#2603)
This reverts commit
|
||
|
|
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 |
||
|
|
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> |
||
|
|
af63af3951
|
feat(landing-page): refresh brand mark and publish a real favicon.ico (#2561)
Replaces the four icon assets in `apps/landing-page/public/` with
renders of the new brand mark — black-fill speech bubble + white
pointer arrow — and adds a real multi-resolution `favicon.ico` at
the path SEO crawlers actually probe.
Why
- The brand mark was refreshed on 2026-05-21 (canonical source:
black 2988×2988 PNG of the speech-bubble + pointer logo). The
marketing site needed the matching favicon, apple-touch-icon, and
header brand mark refreshed in lockstep so the browser tab, iOS
home-screen tile, and the in-page nav glyph all line up with the
new identity.
- `/favicon.ico` did not exist on the published site. The Astro head
declares `<link rel="icon" href="/favicon.png">`, which modern
browsers honor, but a long tail of SEO crawlers, link-preview
services (Slack, Discord, third-party SEO tools), and older
clients hard-probe `/favicon.ico` regardless of the link tag. Hits
to that URL were falling through to the SPA fallback HTML
(200 with `content-type: text/html`), so those clients rendered
an empty/broken favicon. Several SEO surfaces showed an empty
black circle instead of the brand mark.
- Adding a real `favicon.ico` plus an explicit
`<link rel="icon" type="image/x-icon" href="/favicon.ico">` is
the smallest defensive fix that covers both well-behaved and
hard-probing clients.
What
- Regenerated icon assets from the new logo source:
- `favicon.ico` — multi-resolution ICO with 16/32/48/64 PNG-encoded
entries. The 16/32 entries are what browser tabs, bookmarks, and
most crawlers sample; 48/64 cover high-DPI tabs and Windows
pinned-tile sampling.
- `favicon.png` — 32×32 PNG (existing slot).
- `apple-touch-icon.png` — 180×180 PNG (existing slot, iOS
home-screen).
- `logo.webp` — 144×144 WebP, 4× the 36px logical size used by
the header brand mark for crisp retina rendering.
- Added `<link rel="icon" type="image/x-icon" href="/favicon.ico" sizes="any">`
to both `app/pages/index.astro` and the shared `sub-page-layout`
so every route under `open-design.ai` advertises the ICO. Existing
PNG and apple-touch links are preserved — modern browsers will
still pick the PNG, the ICO catches the hard-probing tail.
Surface area
- Marketing site only. No `apps/web`, `apps/daemon`, contracts, or
CLI surfaces touched.
- No new dependencies; assets generated locally from the canonical
source via `magick` + `cwebp` and committed as static files.
Validation
- `pnpm --filter @open-design/landing-page typecheck` — 0 errors.
- File integrity:
- `favicon.ico` — `MS Windows icon resource - 4 icons,
16x16, 32x32, 48x48, 64x64`
- `logo.webp` — `RIFF Web/P image, VP8 encoding, 144x144`
- Manual: `/favicon.ico` will return `image/x-icon` once deployed,
not the SPA fallback HTML it returns today.
Followup
- Once Cloudflare's edge cache rolls (or is purged), third-party
favicon caches (Google SERP, Slack link-preview) take days-to-weeks
to refresh on their own; that lag is expected and not a deploy
problem.
Co-authored-by: Joey-nexu <joeylee12629@gmail.com>
|
||
|
|
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>
|
||
|
|
7fc4362ba8
|
perf(landing): edge-cache HTML and precise-load thumbnails (#2235)
* perf(landing): edge-cache HTML and precise-load thumbnails Without `public/_headers` Cloudflare Pages serves every HTML with `cf-cache-status: DYNAMIC` so each request roundtrips to the Pages origin — observed TTFB 660–900ms from Seattle, worse from Asia. With `s-maxage=3600, stale-while-revalidate=86400` HTML stays cached at the edge between deploys (CF Pages auto-purges on every deploy so freshness is unchanged in practice), and `_astro/` hash bundles flip to `immutable` so the existing 4h+must-revalidate roundtrips go away. For thumbnails, native `loading="lazy"` is browser-decided — Chrome over-prefetches (1250–3000px), Safari fires near in-viewport. A new `<LazyImg>` Astro component and global IntersectionObserver (rootMargin 300px for images, 600px for videos) replaces all 10 site-wide `loading="lazy"` usages with precise control. Above-the-fold slots (first 4 rows, detail-page hero previews) opt into `eager` or `priority` to skip the IO roundtrip. Homepage hero LCP gets `<link rel="preload" imagesrcset>`, a 4-step `srcset` (768/1280/1920/2560) plus `fetchpriority="high"` so retina devices stop repainting from the 1024-only variant — was the P99 long tail. Verified: `pnpm guard` 6/6, `pnpm typecheck` 0 errors, `pnpm build` 865 pages 28s, generated `out/index.html` contains the preload link and 15 `data-precise-src` thumbnails, `out/plugins/index.html` has 95 precise-loaded thumbnails plus the IO script. * perf(landing): logo to webp + parallelize Google Fonts load Two HAR-validated wins on top of the edge-cache / precise-load commit: logo: 500x500 192KB PNG → 200x200 7.5KB WebP. Footer/header actually render at 36x36, so the source is 5x larger than necessary at the display size and ships RGBA PNG bytes for what reads as a flat graphic. WebP at q=85 keeps the gradient ring crisp at every DPR we care about. fonts: globals.css used `@import url(...)` for Google Fonts, which serialized HTML → CSS → fonts.googleapis.com/css2 → fonts.gstatic.com/ woff2. HAR measured 953ms for the fonts CSS plus 400–800ms per woff2 × 4 — close to 3s before text could render in the intended family, even with display=swap. Moving to `<link>` + `<link rel=preconnect>` in each page's <head> lets the fonts CSS fetch race the HTML body parse, and warms the TLS handshake to gstatic.com so woff2 requests don't pay DNS+TLS at request time. A shared `font-stylesheet.astro` keeps the four-family URL canonical across all five entry points (index, sub-page-layout, plugins/index, plugins/[slug], blog/index, blog/[slug]). og.astro already had this treatment. |
||
|
|
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> |
||
|
|
e3a848a33a
|
feat(landing-page): replace Ø wordmark with PNG logo across nav/footer/favicon (#1449)
* feat(landing-page): replace Ø wordmark with PNG logo across nav/footer/favicon Switches the brand mark from the Unicode 'Ø' glyph to the new circular gradient paper-plane PNG. Header nav and footer share the same image, and the browser tab + iOS home screen icons are regenerated from the same 500x500 source. - public/logo.png (500x500, brand source) - public/favicon.png (32x32, replaces favicon.svg) - public/apple-touch-icon.png (180x180, regenerated) - header.tsx + page.tsx footer: <span>Ø</span> -> <img src=/logo.png /> - globals.css: simplify .brand-mark (drop Ø-era border/font, add object-fit contain on child img) - index.astro: link rel=icon now points at favicon.png * fix(landing-page): apply logo + favicon swap to sub-page layout too Review on #1449 caught two cross-page consistency issues: - P1: sub-page-layout.astro still linked /favicon.svg, which this PR deletes — every Skills/Systems/Templates/Craft page would request a missing asset. Updated to /favicon.png to match index.astro. - P2: sub-page-layout.astro still rendered the Ø wordmark in its footer brand block, leaving the public site with mixed brand marks. Replaced with the same <img src=/logo.png /> wrapper pattern used on the homepage header and footer. Repo-wide grep now shows 0 favicon.svg references and 0 Ø brand-mark spans. typecheck still 25 files / 0 errors / 0 warnings. --------- Co-authored-by: Joey-nexu <236967869+joeylee12629-star@users.noreply.github.com> |
||
|
|
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>
|
||
|
|
0dfa922208
|
fix(landing-page): correct SEO canonical, add robots.txt + favicons (#1061)
The Astro `site` default was `https://open-design.dev`, but the live Cloudflare Pages deployment is bound to `open-design.ai`. As a result every `<link rel="canonical">`, `og:url`, and sitemap entry pointed at the wrong origin, and search engines saw no robots.txt or favicon at the apex. - astro.config.ts: switch the default `site` to `https://open-design.ai` and document that `OD_LANDING_SITE` stays as the preview-deploy hatch. - astro.config.ts: filter `/og/` out of the sitemap; that route is the 1200x630 OG screenshot surface and already carries `noindex`. - public/robots.txt: allow-all + Disallow `/og/` + canonical sitemap URL. - public/favicon.svg: 32x32 SVG mark mirroring the on-page `Ø` brand glyph (ink ground, paper-stroked italic ellipse, coral slash). - public/apple-touch-icon.png: 180x180 PNG rendered from the same geometry without the rounded corners (iOS applies its own mask). - index.astro: link `/favicon.svg` (`type="image/svg+xml"`) and `/apple-touch-icon.png` from the document head. Verified locally with `pnpm --filter @open-design/landing-page build`: the rendered head emits `https://open-design.ai/` for canonical and `og:url`, the sitemap contains exactly the canonical `/` URL, and the two `landing-page-deploy.yml` verification scripts (no client JS, >=16 Cloudflare resized image URLs, no local /assets/*.png) still pass. Co-authored-by: joey <joey@joeydeMacBook-Air.local> Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
aefba56a3f
|
feat(skills): open-design-landing rename, kami skills, landing OG (#428)
* feat(skills): open-design-landing rename, kami skills, landing OG - Rename editorial-collage skills to open-design-landing and -deck; refresh examples and compose script layout - Add kami-deck and kami-landing skills with HTML examples - Landing page: og.astro, index wiring, and style tweaks; package.json bump - Web i18n: German and Russian copy for renamed and new skills - Daemon test: update skill-asset-rewrite expectations for new paths - Design systems: README and atelier-zero doc touch-ups - Cross-skill SKILL.md reference updates Co-authored-by: Cursor <cursoragent@cursor.com> * docs(landing-page): document version-slot invariant and deprecation timeline Address P3 review notes on PR #428: - Note the `data-github-version` wrapper invariant (version string only) near the canonical URL block in `app/page.tsx`. - Expand the `formatVersion` helper comment in `app/pages/index.astro` with concrete `release.name` / `tag_name` example shapes for each branch of the regex fallback. - Tighten the `EditorialCollageDeckInputs` deprecation in `skills/open-design-landing-deck/schema.ts` to a specific removal version (v0.4.0) and add a "Migrating from editorial-collage-deck" section to the skill README. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) * docs(landing-page, skills): clarify version slot script and rename migrations - Describe GitHub version slots as driven by the inline enhancement script, not React hydration. - Add editorial-collage → open-design-landing migration notes; fix README link copy (Astro static landing app). - Extend deck README migration table with shared asset path renames. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(daemon): alias deprecated editorial-collage skill ids The PR renames the editorial-collage / editorial-collage-deck skills to open-design-landing / open-design-landing-deck, but the daemon persists exact skill_id strings on projects and resolves them via listSkills().find((s) => s.id === storedId). After the rename, any project saved against an old id silently composes without the intended skill prompt because the listing no longer exposes that id. Add a SKILL_ID_ALIASES map in skills.ts plus a findSkillById() helper that rewrites deprecated ids to their current canonical form, then route every server-side lookup (skill detail, example HTML, asset proxy, system-prompt composer) through it. Cover the alias map, the resolver, and end-to-end resolution against a temp skills directory with a regression test. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) * fix(kami-deck): route host od:slide messages through local go() The host bridge classifies kami-deck as class-driven because go() toggles .slide.active, but the visible slide is moved by deck.style.transform which the bridge cannot drive. Listen for od:slide messages and dispatch them through the local go() so toolbar next/prev and initialSlideIndex restore actually shift the deck. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) * fix(kami-deck): sync deck transform with host-driven .active changes The previous fix added a local od:slide listener but the host bridge in apps/web/src/runtime/srcdoc.ts also listens for the same message and calls setActive() (toggles .slide.active) without driving the deck transform. Both listeners fired, the bridge re-read the just-toggled active class, and overshot by one — and the bridge's restoreInitialSlide path could move .active without a message at all, leaving the deck on the original transform. Stop the bridge from double-handling by calling stopImmediatePropagation in the local listener (registered first because the bridge script is appended to </body>), and add a MutationObserver that pulls the deck transform onto whichever slide currently carries .active so the bridge's direct setActive calls (notably the initial-slide restore) move the deck too. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) * fix(i18n): align French content with renamed/new skills PR #434 (French localization) merged into main with French copy for the old editorial-collage / editorial-collage-deck skill ids; this branch renamed those to open-design-landing / open-design-landing-deck and added kami-deck and kami-landing. Update content.fr.ts to track the rename and add French copy for the new kami skills so the LOCALIZED_CONTENT_IDS coverage test passes once main is merged. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) * fix(open-design-landing-deck): sync deck transform with host-driven .active changes Apply the same fix that landed in skills/kami-deck/example.html (commits |
||
|
|
6c2a8ba09f
|
feat(editorial-collage): introduce Atelier Zero style landing page as… (#366)
* feat(editorial-collage): introduce Atelier Zero style landing page assets and documentation - Added new design system for Atelier Zero, including a detailed `DESIGN.md` file. - Created an `editorial-collage` skill with associated assets for a magazine-grade landing page. - Included example HTML and image assets for various sections (hero, about, capabilities, etc.). - Updated README files to guide usage and customization of the new skill and design system. - Introduced a new image generation prompt pack for consistent visual style across the landing page. * fix(i18n): cover atelier-zero design system and editorial-collage skill in German content Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) * fix(editorial-collage): align manifest with shipped assets and address PR review - Update image-manifest.json widths/heights/ratios to match the actual PNGs on disk: hero/about/cap/testimonial/cta = 1024x1024 (1:1), method-1..4 = 816x816 (1:1), lab-1..5 and work-1..2 = 768x1024 (3:4). Mirror the new dimensions in imagegen-prompts.md headings and in README.md. - Mark testimonial.png as rekey_on_brand_change so the manifest agrees with SKILL.md's "regenerate at minimum testimonial.png" guidance, and add work-1/work-2 to the rekey list in SKILL.md and README.md. - Add a Hero (I.) sec-rule and renumber every following section II..VIII in example.html so the eight sections walk sequentially I -> VIII and the page-of-008 counter starts at 001. - Delete editorial-artifact-system/ (16 duplicate PNGs + index.html + skills.md draft) — the canonical version is skills/editorial-collage/ and the duplicate had no consumer references. - DESIGN.md: spell out which dimensions of each magazine reference (Monocle/Apartamento/IDEA), document the rationale for single-accent vs multi-accent, and extend the anti-pattern list with AI-image-gen artifacts the system explicitly rejects. - SKILL.md: add italic_words validation guidance (trim, cap at 4, verb->noun rewrite, punctuation strip) and replace the broken-image fallback with an inline SVG placeholder sized to the slot's manifest aspect ratio. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) * fix(daemon): serve skill example assets via stable API route Skill example HTML such as `skills/editorial-collage/example.html` references shipped images via `./assets/*.png`. The web app loads the example into a sandboxed iframe via `srcdoc`, where relative URLs resolve against `about:srcdoc` and the PNGs render as broken images in the Examples preview. Add a `GET /api/skills/:id/assets/*` route that serves files under the skill's `assets/` directory with path-traversal guards, and rewrite `src='./assets/<file>'` / `href='./assets/<file>'` in the example response to point at that route. The disk preview keeps working because the on-disk files are unchanged. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) * feat(landing-page): add new static Next.js 16 site for Open Design marketing - Introduced a new landing page application using Next.js 16, featuring a static export setup. - Added essential files including `package.json`, `next.config.ts`, and TypeScript configuration. - Implemented global styles in `globals.css` to match the Atelier Zero design system. - Created a detailed `AGENTS.md` for module-level boundaries and purpose. - Included various image assets for the landing page, ensuring a visually cohesive experience. - Established a root layout and main page structure to support the marketing content. * style(landing-page): enhance topbar layout and improve responsiveness - Added nowrap styling to topbar elements to prevent text overflow. - Introduced media query to hide mid text in the topbar for screen widths between 1200px and 1280px. - Updated layout.tsx to suppress hydration warnings for better rendering consistency. - Removed redundant "Compiled by Open Design" text from the page component. * feat(landing-page): implement scroll-reveal animations for enhanced user experience - Added a new `RevealRoot` component to manage scroll-triggered reveal animations. - Updated `globals.css` with styles for elements using the `data-reveal` attribute, including opacity, translation, and scaling effects. - Modified `layout.tsx` to include the `RevealRoot` component for managing animations. - Enhanced `page.tsx` by adding `data-reveal` attributes to various elements for staggered reveal effects. - Implemented reduced motion support to ensure accessibility for users with motion sensitivity. * fix(landing-page): update import paths and enhance link styles - Changed the import path in `next-env.d.ts` to reference the correct routes type definition. - Enhanced `globals.css` with new styles for topbar links, work cards, and partner elements, improving hover effects and transitions. - Updated `page.tsx` to include canonical project URLs and made various links point to these URLs for better navigation and accessibility. * feat(landing-page): implement headroom-style sticky header with live GitHub star count - Introduced a new `Header` component to manage sticky navigation behavior on scroll, enhancing user experience. - Updated `globals.css` to style the sticky header, including transitions and visibility toggling based on scroll direction. - Modified `page.tsx` to replace the static header with the new `Header` component, which fetches and displays the live GitHub star count. - Ensured accessibility by providing a fallback for users who prefer reduced motion. * feat(landing-page): enhance editorial landing page with global ticker and new styles - Updated `next-env.d.ts` to reference the correct routes type definition for development. - Enhanced `globals.css` with new styles for the global ticker, including responsive design and improved overflow handling. - Introduced a new `WIRE_CITIES` and `WIRE_CONTRIBS` data structure in `page.tsx` to display a counter-scrolling marquee of cities and contributors. - Added a ghost button style for the navigation call-to-action in the header. - Updated various sections in `page.tsx` to integrate the new ticker and improve overall layout and accessibility. * refactor(landing-page): update paper texture overlay and remove multica-ai link - Enhanced comments in `globals.css` to clarify the purpose and behavior of the paper texture overlay. - Adjusted z-index of the overlay to ensure proper layering with other elements. - Removed the `multica-ai` partner link from `page.tsx` to streamline the partner section. * feat(landing-page): implement dynamic contributor marquee with GitHub integration - Added a new `Wire` component to display a counter-scrolling marquee of cities and contributors. - The contributor list is fetched live from the GitHub API, ensuring up-to-date information. - Updated `page.tsx` to integrate the `Wire` component, replacing the static contributor list with dynamic content. - Enhanced comments for clarity regarding the functionality and purpose of the global wire. * fix(i18n): add German display copy for editorial-collage-deck skill The Validate workspace test asserts that GERMAN_CONTENT_IDS.skills covers every curated skill on disk; the new editorial-collage-deck skill was missing from DE_SKILL_COPY, causing src/i18n/content.test.ts to fail. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) * feat(landing-page): migrate marketing site to Astro * perf(landing-page): remove React client runtime * perf(landing-page): serve images from Cloudflare resizing * fix(pr): address landing page review feedback --------- Co-authored-by: mrcfps <mrc@powerformer.com> |