Skip to content

feat: landing consolidation phase 2 — consistency, assets, CI, and graceful degradation - #184

Merged
ulises-jeremias merged 11 commits into
mainfrom
feat/landing-consolidation-phase-2
Jul 6, 2026
Merged

ulises-jeremias merged 11 commits into
mainfrom
feat/landing-consolidation-phase-2

Conversation

@ulises-jeremias

@ulises-jeremias ulises-jeremias commented Jul 6, 2026 •

Copy link
Copy Markdown
Member

Summary

Landing consolidation second phase — 4 phases of improvements to harden landing page consistency, automate verification, and prove graceful degradation with UI extensions.

Phase 1 — Consistency Hardening

  • Feature cards: Created shared/landings/features.ts with canonical 6-card data per template. Standardized titles (Vite 8 → Vite, React 19 → React, etc.). Added 6th card to Next.js.
  • Docs links: Switched all landings from ./docs/... to /docs/.... Created docs/ dirs for remix and astro so links resolve (fixes 404s).
  • CTA: Changed all <a href> "Start editing" to <span> with <code> snippets. Fixed webext CTA path from Popup.tsx to Newtab.tsx.
  • CSS tokens: Replaced all hardcoded rgba(245,158,11,...), #f59e0b, #d97706, #0d9488 with var(--cna-*) in remix, astro, webext. Gradient uses tokens everywhere.
  • Animation: Added .cna-landing__card to stagger selector where missing. Added reduced-motion + light mode to webext popup. Next.js keyframe renamed to cna-fade-in-up.
  • Docs: Reconciled DESIGN vs GUIDE (keyframe names, shadows, fill mode, card class). Added landing guide links to RUNBOOK.
  • Dead files: Removed next.svg, vercel.svg, Welcome.astro, stray page.tsx.

Phase 2 — Asset Robustness

  • Unique gradient IDs per SVG (no collision possible). Added role=img to favicon, aria-hidden to wordmark text.
  • Created shared/assets/logo-wordmark-dark.svg with light text fill.
  • Created scripts/sync-assets.js — idempotent asset distribution from shared/assets/ to all templates.

Phase 3 — Automated Verification

  • scripts/landing-audit.js: Static checker for card count, docs paths, CTA structure, hardcoded colors, reduced-motion, light mode, animation selectors.
  • CI: validate-registry job (wires validate-templates.js), landing-audit job. Smoke-test expanded to all 7 UI templates. NPM cache, concurrency cancel, timeouts added to all workflows.
  • Visual regression: Playwright harness (scripts/landing-visual/) + landing-visual.yml workflow for dark/light/motion screenshots.
  • Docs: Updated GUIDE.md checklist to reference CI automation.

Phase 4 — Graceful Degradation

  • Tailwind v4 fix: Updated react-tailwindcss PostCSS config to use @tailwindcss/postcss (was on v3 plugin syntax with v4 package).
  • Extension isolation: Added CI job testing each UI extension (tailwind, shadcn, mui) individually against base templates.

Verification

  • node scripts/validate-templates.js — passes (pre-existing warnings for sls/backend types only)
  • node scripts/landing-audit.js — all 5 UI landings pass (6 cards, token-based CSS, correct CTA, root-absolute docs)
  • Full CI matrix expected green after merge

Summary by CodeRabbit

  • New Features

    • Added visual regression coverage for landing pages across multiple starter templates.
    • Expanded landing page content and shared template data for starter experiences.
    • Added new documentation pages for project setup, structure, performance, styling, and state management.
  • Bug Fixes

    • Standardized landing page links, feature counts, and edit prompts across templates.
    • Improved theme consistency, reduced-motion behavior, and token-based styling.
  • Chores

    • Updated CI workflows to run faster and avoid overlapping builds.
    • Added asset syncing and automated landing audits for broader template validation.

…aceful degradation

Phase 1 — Consistency Hardening:
- Standardize 6 feature cards per template in shared/landings/features.ts
- Fix version drift (Vite 8→Vite, React 19→React, Astro 7→Astro, etc.)
- Switch all docs links to root-absolute /docs/ prefix
- Create docs/ dirs for remix and astro starters (fix 404s)
- Fix 'Start editing' CTA to non-navigable <span> in all templates
- Replace all hardcoded CSS colors with --cna-* tokens
- Add --cna-amber-soft light-mode override where missing
- Add .cna-landing__card to stagger animation selectors
- Add prefers-reduced-motion + light mode to webext popup
- Reconcile DESIGN vs GUIDE docs (keyframe names, shadows, fill mode)
- Remove dead files (next.svg, vercel.svg, Welcome.astro, stray page.tsx)

Phase 2 — Asset Robustness:
- Unique gradient IDs across all SVGs (no ID collisions)
- Add role=img to favicon.svg, aria-hidden to wordmark text
- Create logo-wordmark-dark.svg variant
- Create scripts/sync-assets.js for idempotent asset distribution

Phase 3 — Automated Verification:
- Create scripts/landing-audit.js (static landing page validator)
- Wire validate-templates.js into CI (validate-registry job)
- Expand smoke-test to all 7 UI templates
- Add npm cache, concurrency cancel, timeout-minutes to all CI jobs
- Run test-combinations on PRs (not just push/main + cron)
- Create Playwright visual regression harness + CI workflow
- Update docs to reference CI automation

Phase 4 — Graceful Degradation:
- Fix react-tailwindcss PostCSS plugin (tailwindcss → @tailwindcss/postcss)
- Add extension-isolation CI job testing each UI extension individually
@coderabbitai

coderabbitai Bot commented Jul 6, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ulises-jeremias, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 9 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6bcdcf8c-4065-4138-8839-80a2a09f5293

📥 Commits

Reviewing files that changed from the base of the PR and between a810732 and 98de6c1.

📒 Files selected for processing (15)
  • .github/workflows/landing-visual.yml
  • .github/workflows/smoke-test.yml
  • .github/workflows/test-combinations.yml
  • scripts/landing-audit.js
  • scripts/landing-visual/landing.spec.ts
  • scripts/landing-visual/playwright.config.ts
  • scripts/sync-assets.js
  • templates/astro-starter/docs/PROJECT_CONFIGURATION.md.template
  • templates/astro-starter/docs/PROJECT_STRUCTURE.md.template
  • templates/astro-starter/docs/README.md
  • templates/remix-starter/app/styles/landing.css
  • templates/remix-starter/docs/PROJECT_CONFIGURATION.md.template
  • templates/remix-starter/docs/PROJECT_STRUCTURE.md.template
  • templates/remix-starter/docs/README.md
  • templates/webextension-react-vite-starter/[src]/popup/index.css
📝 Walkthrough

Walkthrough

Introduces a shared landing-page feature/docs data module, applies consistent --cna-* token-based CSS, animation naming, and CTA restructuring across all five starter templates, adds CI workflows for landing audit and visual regression testing, new per-template documentation pages, an asset-sync script, and switches the Tailwind extension to @tailwindcss/postcss.

Changes

Landing Design System and CI Automation

Layer / File(s) Summary
Shared landing feature data contract
shared/landings/features.ts
Defines Feature, DocsLink, TemplateLandingData interfaces and exports per-template landing data (reactVite, nextjs, remix, astro, webext).
Design system and guide documentation
docs/DEFAULT_LANDING_DESIGN.md, docs/DEFAULT_LANDING_GUIDE.md, docs/MAINTENANCE_RUNBOOK.md
Renames tokens to --cna-*, fixes feature-card count to 6, updates CTA/animation guidance, absolute docs paths, CI automation section, and runbook links.
Next.js starter landing updates
templates/nextjs-starter/[src]/app/page.tsx, page.tsx.template, page.module.css
Removes old page implementation and rebuilds feature/CTA content, renames fade-in-up to cna-fade-in-up, adds code styling, button wrap/gap, gradient tweak, and reduced-motion query.
React Vite starter landing updates
templates/react-vite-starter/[src]/pages/Landing.tsx.template, Landing.css
Simplifies feature entries and titles, consolidates animation selectors, and switches gradient to theme variables.
Astro starter landing updates
templates/astro-starter/src/pages/index.astro, src/components/Welcome.astro
Removes Welcome.astro, updates feature icons/docs links/CTA markup, and applies --cna-* token styling, code class, and expanded animation selectors.
Remix starter landing updates
templates/remix-starter/app/routes/_index.tsx.template, app/styles/landing.css
Updates features/docs data and CTA markup, and applies token-based amber/glow/gradient CSS and new code class.
Webextension starter landing/popup updates
templates/webextension-react-vite-starter/[src]/newtab/*, [src]/popup/*
Updates Newtab features/docs/CTA content and CSS tokens, and switches popup CSS variables/gradients with light-mode and reduced-motion media queries.
CI workflows
.github/workflows/landing-visual.yml, smoke-test.yml, test-combinations.yml
Adds landing visual regression workflow, restructures smoke-test with validate-registry/landing-audit/extension-isolation jobs, and adds concurrency/timeouts to test-combinations.
Landing audit script
scripts/landing-audit.js
Implements static per-template checks for feature count, docs links, CTA structure, and CSS token usage.
Landing visual regression tests
scripts/landing-visual/*
Adds Playwright config, package.json, and spec covering dark/light/reduced-motion screenshot scenarios.
Asset sync script and Tailwind plugin rename
scripts/sync-assets.js, extensions/react-tailwindcss/package.json, postcss.config.js.template
Adds shared-asset copy CLI and renames the Tailwind PostCSS plugin dependency/config to @tailwindcss/postcss.
New per-template documentation pages
templates/astro-starter/docs/*, templates/remix-starter/docs/*
Adds COMPONENTS_AND_STYLING, PERFORMANCE, PROJECT_CONFIGURATION, PROJECT_STRUCTURE, README, and STATE_MANAGEMENT docs.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PullRequest
  participant LandingVisualWorkflow
  participant ScaffoldedTemplate
  participant PlaywrightTests

  PullRequest->>LandingVisualWorkflow: trigger on path-filtered PR or manual dispatch
  LandingVisualWorkflow->>ScaffoldedTemplate: scaffold template and start dev server
  LandingVisualWorkflow->>ScaffoldedTemplate: wait for server readiness on configured port
  LandingVisualWorkflow->>PlaywrightTests: run tests with TEMPLATE and BASE_URL
  PlaywrightTests-->>LandingVisualWorkflow: generate screenshots
  LandingVisualWorkflow-->>PullRequest: upload screenshot artifacts
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the PR’s main themes: landing consistency, asset handling, CI verification, and graceful degradation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/landing-consolidation-phase-2

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

The actions/setup-node cache option with cache: npm requires a
package-lock.json or yarn.lock at repo root. This repo scaffolds
projects dynamically so there is no root lockfile. Remove the
option from all three workflows (smoke-test, test-combinations,
landing-visual).

Also change landing-visual from npm ci to npm install since the
test harness directory has no committed lockfile.
- Replace fragile npx wait-on with bash port-polling loop
- Add step id for conditional execution of downstream steps
- Handle scaffold failure gracefully (astro/remix pre-existing issues)
- Always upload screenshots as artifacts for inspection
…oHaveScreenshot

- Export PORT as a shell variable before using it in curl loop
- Replace toHaveScreenshot with page.screenshot (baselines not yet committed)
- Upload screenshots as artifacts for manual inspection
- Fix spec to only test the current matrix template instead of all 5
- Pass TEMPLATE env var to Playwright tests
- Remove --host flag for Next.js (unsupported)
- Make visual tests non-blocking with continue-on-error
- Add condition for nextjs-starter to avoid --host flag
- Fix critical: logo-wordmark.svg references non-existent gradient
  url(#cnaNest) → url(#cnaNestWord)
- Fix: landing-visual.yml health check now fails on timeout
- Fix: landing-visual.yml uses matrix.port (DRY, no repeated expressions)
- Fix: landing-visual.yml removes continue-on-error from test step
- Fix: smoke-test.yml simplifies SKIP_ENV_VALIDATION (dead ternary)
- Fix: landing-audit.js regex anchors to const docs only
- Fix: landing-audit.js executable bit set
- Fix: Next.js page.module.css adds flex-wrap to .button

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
templates/astro-starter/docs/PROJECT_STRUCTURE.md.template (1)

3-198: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Rewrite this guide for Astro, not Next.js.

Lines 3-198 describe Next.js App Router, route groups, and server components, but this file lives under astro-starter/docs. That mismatch will mislead users of the Astro template. Please replace the examples with Astro-specific structure, or move the document to the Next.js starter if that was the intent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/astro-starter/docs/PROJECT_STRUCTURE.md.template` around lines 3 -
198, Rewrite the PROJECT_STRUCTURE guide to match Astro instead of Next.js:
replace the App Router, route groups, server components, and Next.js-specific
examples with Astro’s directory and routing conventions, using the existing
template symbols like srcDir and projectImportPath only where they still apply.
Update the architecture overview, directory tree, principles, and example
sections so they describe Astro starter structure and imports, and ensure any
references to features/shared remain accurate for this template. If the intent
was actually Next.js, move this document to the Next.js starter instead of
keeping it in the Astro docs.
templates/remix-starter/docs/PROJECT_STRUCTURE.md.template (1)

3-198: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Rewrite this page for Remix, not Next.js.

The whole document talks about Next.js App Router, route groups, and server components, which do not apply to Remix and will mislead users of this starter. Replace it with Remix route, loader/action, and layout conventions.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/remix-starter/docs/PROJECT_STRUCTURE.md.template` around lines 3 -
198, The PROJECT_STRUCTURE document is written for Next.js App Router and should
be rewritten to describe Remix conventions instead. Update the overview and
directory examples in the template to use Remix route files, nested layouts,
loaders/actions, and shared app structure, and remove Next.js-specific terms
like route groups, server components, and App Router from the guidance. Keep the
feature-based architecture framing, but align the examples and import guidance
with Remix patterns and the symbols used in this template such as srcDir,
features/auth, and shared.
🧹 Nitpick comments (6)
.github/workflows/test-combinations.yml (1)

7-16: 🚀 Performance & Scalability | 🔵 Trivial

New pull_request trigger duplicates smoke-test.yml coverage per PR.

Running generate-combinations/test-combinations (full scaffold + install + lint + type-check + build per template) on every PR to main, in addition to smoke-test.yml's own per-template scaffold/build, meaningfully increases CI minutes per PR. Consider restricting this to paths that touch templates.json/extensions, or keeping it scheduled-only and relying on smoke-test.yml for per-PR coverage.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test-combinations.yml around lines 7 - 16, The new
pull_request trigger in the test-combinations workflow duplicates the per-PR
coverage already provided by smoke-test.yml, so remove or narrow that trigger in
the workflow definition. Update the workflow configuration to run
generate-combinations/test-combinations only on schedule or only when relevant
template files change, and keep smoke-test.yml as the per-PR coverage path.
scripts/landing-visual/playwright.config.ts (1)

17-26: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

firefox project is defined but never installed/run in CI.

CI only installs and runs the chromium project. Either wire firefox into the workflow or drop the unused project for now.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/landing-visual/playwright.config.ts` around lines 17 - 26, The
Playwright config defines a firefox project that is never used by CI, so either
remove the unused firefox entry from the projects array in the Playwright config
or update the CI workflow to install and run it alongside chromium. Use the
existing project definitions in the Playwright config as the place to make the
change, and keep the project list aligned with what the pipeline actually
executes.
.github/workflows/smoke-test.yml (1)

96-97: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Inconsistent SKIP_ENV_VALIDATION scope between jobs.

smoke-test sets SKIP_ENV_VALIDATION: 'true' for the whole "Run basic checks" step (Lines 96-97), but extension-isolation's equivalent step (Lines 142-151) only sets it inline before npm run build. Lint/type-check in extension-isolation won't see it, unlike smoke-test.

Also applies to: 142-151

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/smoke-test.yml around lines 96 - 97, The
`SKIP_ENV_VALIDATION` setting is applied inconsistently between the `smoke-test`
and `extension-isolation` workflow steps. Update the `Run basic checks` step in
`extension-isolation` to match `smoke-test` by setting `SKIP_ENV_VALIDATION:
'true'` at the step level, so `npm run lint`, `npm run type-check`, and `npm run
build` all run with the same environment; use the existing `Run basic checks`
step blocks in the workflow as the place to align this behavior.
templates/remix-starter/app/styles/landing.css (1)

87-94: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Hover lift now applies to a non-interactive CTA.

.cna-landing__button:hover (translateY lift) still fires on .cna-landing__button--primary, which per the companion Newtab.tsx.template change is now rendered as a plain <span> (non-navigable code snippet), not a link/button. Hovering an inert element with a "lift" transform signals interactivity that doesn't exist, which is a minor but real affordance mismatch.

💡 Suggested scoping fix
-.cna-landing__button:hover {
-  transform: translateY(-2px);
-}
+a.cna-landing__button:hover {
+  transform: translateY(-2px);
+}

Token swaps (--cna-glow, --cna-amber-soft), the new gap, and .cna-landing__code class otherwise look correct and match the shared design tokens confirmed in Newtab.css.

Also applies to: 105-116, 140-174, 215-225, 275-281

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/remix-starter/app/styles/landing.css` around lines 87 - 94, The
hover lift is still applied to `.cna-landing__button--primary` even though it
now renders as a non-interactive `<span>`, which creates a false affordance.
Update the hover styling in the landing CSS so the translateY lift only applies
to truly interactive button/link variants, and explicitly exclude or neutralize
`.cna-landing__button--primary` in the `.cna-landing__button:hover` rule. Use
the existing `.cna-landing__button` and `.cna-landing__button--primary`
selectors to scope the change cleanly.
templates/webextension-react-vite-starter/[src]/popup/index.css (2)

23-32: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Light-mode --popup-accent bypasses the shared token.

Unlike the dark-mode default (var(--cna-amber-soft, #fbbf24)), the light-mode override hardcodes #d97706 directly instead of using var(--cna-amber-soft, #d97706), inconsistent with the token-based approach adopted elsewhere in this PR.

♻️ Suggested fix
-    --popup-accent: `#d97706`;
+    --popup-accent: var(--cna-amber-soft, `#d97706`);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/webextension-react-vite-starter/`[src]/popup/index.css around lines
23 - 32, The light-mode `--popup-accent` override in the popup stylesheet is
hardcoding a color instead of using the shared token pattern. Update the `@media
(prefers-color-scheme: light)` block in the popup `body` styles to use
`var(--cna-amber-soft, `#d97706`)` for `--popup-accent`, matching the token-based
approach used elsewhere and keeping consistency with the dark-mode default.

7-9: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the unused token indirection in the popup styles
popup/index.css:7-9 and 18-20 only reference --cna-amber-soft, --cna-amber, --cna-teal, and --cna-glow through fallbacks. The popup document only loads its own CSS, and these tokens are defined elsewhere, so the fallback values are always what render here. Either define the tokens in the popup scope or inline the hardcoded values.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/webextension-react-vite-starter/`[src]/popup/index.css around lines
7 - 9, The popup styles are relying on fallback-only design tokens, so the
indirection in the popup CSS is effectively unused. In popup/index.css, update
the popup token definitions and any dependent button/accent styles to either
declare the needed values directly in the popup scope or replace the var(...)
fallbacks with the hardcoded colors. Use the existing popup custom properties
such as --popup-accent and --popup-button-gradient-start/end to keep the styling
centralized while removing references to external tokens like --cna-amber-soft,
--cna-amber, --cna-teal, and --cna-glow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/landing-visual.yml:
- Around line 61-67: The Scaffold test project step in the landing visual
workflow is masking failures with continue-on-error, which can let the job
finish green without running any visual tests. Remove the silent success
behavior from the scaffold step, or keep tolerance only via retries, and add an
explicit failure check after the scaffold step that fails the job when
steps.scaffold.outcome is not success so the downstream dev server and
Playwright steps cannot be skipped unnoticed.

In `@scripts/landing-audit.js`:
- Around line 136-139: The light-mode CSS audit in the landing-audit script is
using a regex in the lightModeBlock check that stops at the first closing brace,
so nested rules inside the `@media` block are not fully captured. Replace that
regex-based extraction with a balanced-brace helper such as extractBalancedBlock
(or equivalent logic in the same script) and use it when scanning the CSS so the
--cna-amber-soft override is detected anywhere within the full media block.

In `@scripts/landing-visual/landing.spec.ts`:
- Around line 10-29: The visual tests in landing.spec.ts are only writing
screenshots with page.screenshot(), so they never assert against a baseline and
cannot catch regressions. Update the dark mode, light mode, and reduced motion
tests to use Playwright snapshot assertions in the same test cases, and connect
the snapshot update behavior to Playwright’s built-in update flow instead of
relying on UPDATE_SNAPSHOTS=true. Keep the changes localized to the existing
test functions and any test:update wiring that currently drives snapshot
generation.

In `@scripts/sync-assets.js`:
- Around line 46-49: The missing-source path in sync-assets.js is only logging a
SKIP message and never increments the errors counter, so the final summary and
exit code stay successful. Update the fs.existsSync(sourceFile) branch in the
asset-sync loop to treat a missing shared asset as an error by incrementing
errors alongside the existing console.error, so the existing summary/exit logic
reflects the failure. Reference the sync-assets.js asset processing block that
checks sourceFile and the final errors-based exit path.

In `@templates/astro-starter/docs/PROJECT_CONFIGURATION.md.template`:
- Line 55: The example path in PROJECT_CONFIGURATION.md.template is inconsistent
because it changes from MyComponent to MyComponents, which can mislead readers.
Update the sample under the projectImportPath explanation so the referenced
component name is consistent between the source path and the import path
example, using the surrounding projectImportPath and srcDir examples as the
anchor.

In `@templates/astro-starter/docs/README.md`:
- Around line 3-24: The README in the Astro starter docs still references
Next.js throughout, so update the copy and links to be Astro-specific. In the
README content, replace the project description, core documentation links,
external resources, and help section entries with the corresponding Astro
documentation and support references. Use the README’s existing section
structure and update the wording so it matches the astro-starter template rather
than Next.js.

In `@templates/remix-starter/docs/PROJECT_CONFIGURATION.md.template`:
- Line 55: The import-path example in PROJECT_CONFIGURATION.md.template has a
typo: the referenced component name in the path should match the earlier
example. Update the example near the projectImportPath explanation so the path
uses MyComponent consistently, and keep the surrounding text unchanged.

In `@templates/remix-starter/docs/README.md`:
- Around line 1-3: The README in the docs folder still refers to the Next.js
Starter template, which is incorrect for the Remix starter. Update the text in
the README content to use Remix Starter terminology instead of Next.js Starter,
keeping the rest of the documentation wording aligned with the remix-starter
docs context.

---

Outside diff comments:
In `@templates/astro-starter/docs/PROJECT_STRUCTURE.md.template`:
- Around line 3-198: Rewrite the PROJECT_STRUCTURE guide to match Astro instead
of Next.js: replace the App Router, route groups, server components, and
Next.js-specific examples with Astro’s directory and routing conventions, using
the existing template symbols like srcDir and projectImportPath only where they
still apply. Update the architecture overview, directory tree, principles, and
example sections so they describe Astro starter structure and imports, and
ensure any references to features/shared remain accurate for this template. If
the intent was actually Next.js, move this document to the Next.js starter
instead of keeping it in the Astro docs.

In `@templates/remix-starter/docs/PROJECT_STRUCTURE.md.template`:
- Around line 3-198: The PROJECT_STRUCTURE document is written for Next.js App
Router and should be rewritten to describe Remix conventions instead. Update the
overview and directory examples in the template to use Remix route files, nested
layouts, loaders/actions, and shared app structure, and remove Next.js-specific
terms like route groups, server components, and App Router from the guidance.
Keep the feature-based architecture framing, but align the examples and import
guidance with Remix patterns and the symbols used in this template such as
srcDir, features/auth, and shared.

---

Nitpick comments:
In @.github/workflows/smoke-test.yml:
- Around line 96-97: The `SKIP_ENV_VALIDATION` setting is applied inconsistently
between the `smoke-test` and `extension-isolation` workflow steps. Update the
`Run basic checks` step in `extension-isolation` to match `smoke-test` by
setting `SKIP_ENV_VALIDATION: 'true'` at the step level, so `npm run lint`, `npm
run type-check`, and `npm run build` all run with the same environment; use the
existing `Run basic checks` step blocks in the workflow as the place to align
this behavior.

In @.github/workflows/test-combinations.yml:
- Around line 7-16: The new pull_request trigger in the test-combinations
workflow duplicates the per-PR coverage already provided by smoke-test.yml, so
remove or narrow that trigger in the workflow definition. Update the workflow
configuration to run generate-combinations/test-combinations only on schedule or
only when relevant template files change, and keep smoke-test.yml as the per-PR
coverage path.

In `@scripts/landing-visual/playwright.config.ts`:
- Around line 17-26: The Playwright config defines a firefox project that is
never used by CI, so either remove the unused firefox entry from the projects
array in the Playwright config or update the CI workflow to install and run it
alongside chromium. Use the existing project definitions in the Playwright
config as the place to make the change, and keep the project list aligned with
what the pipeline actually executes.

In `@templates/remix-starter/app/styles/landing.css`:
- Around line 87-94: The hover lift is still applied to
`.cna-landing__button--primary` even though it now renders as a non-interactive
`<span>`, which creates a false affordance. Update the hover styling in the
landing CSS so the translateY lift only applies to truly interactive button/link
variants, and explicitly exclude or neutralize `.cna-landing__button--primary`
in the `.cna-landing__button:hover` rule. Use the existing
`.cna-landing__button` and `.cna-landing__button--primary` selectors to scope
the change cleanly.

In `@templates/webextension-react-vite-starter/`[src]/popup/index.css:
- Around line 23-32: The light-mode `--popup-accent` override in the popup
stylesheet is hardcoding a color instead of using the shared token pattern.
Update the `@media (prefers-color-scheme: light)` block in the popup `body`
styles to use `var(--cna-amber-soft, `#d97706`)` for `--popup-accent`, matching
the token-based approach used elsewhere and keeping consistency with the
dark-mode default.
- Around line 7-9: The popup styles are relying on fallback-only design tokens,
so the indirection in the popup CSS is effectively unused. In popup/index.css,
update the popup token definitions and any dependent button/accent styles to
either declare the needed values directly in the popup scope or replace the
var(...) fallbacks with the hardcoded colors. Use the existing popup custom
properties such as --popup-accent and --popup-button-gradient-start/end to keep
the styling centralized while removing references to external tokens like
--cna-amber-soft, --cna-amber, --cna-teal, and --cna-glow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 40e9d62a-06c6-4fca-be2f-e826ee00e0b2

📥 Commits

Reviewing files that changed from the base of the PR and between dfc858c and a810732.

⛔ Files ignored due to path filters (31)
  • shared/assets/favicon.svg is excluded by !**/*.svg
  • shared/assets/logo-mark-dark.svg is excluded by !**/*.svg
  • shared/assets/logo-mark.svg is excluded by !**/*.svg
  • shared/assets/logo-wordmark-dark.svg is excluded by !**/*.svg
  • shared/assets/logo-wordmark.svg is excluded by !**/*.svg
  • templates/astro-starter/public/favicon.svg is excluded by !**/*.svg
  • templates/astro-starter/public/logo.svg is excluded by !**/*.svg
  • templates/hono-starter/public/favicon.svg is excluded by !**/*.svg
  • templates/hono-starter/public/logo.svg is excluded by !**/*.svg
  • templates/nestjs-starter/public/favicon.svg is excluded by !**/*.svg
  • templates/nestjs-starter/public/logo.svg is excluded by !**/*.svg
  • templates/nextjs-saas-ai-starter/public/favicon.svg is excluded by !**/*.svg
  • templates/nextjs-saas-ai-starter/public/logo.svg is excluded by !**/*.svg
  • templates/nextjs-saas-ai-starter/public/next.svg is excluded by !**/*.svg
  • templates/nextjs-saas-ai-starter/public/vercel.svg is excluded by !**/*.svg
  • templates/nextjs-starter/[src]/app/favicon.svg is excluded by !**/*.svg
  • templates/nextjs-starter/public/favicon.svg is excluded by !**/*.svg
  • templates/nextjs-starter/public/logo.svg is excluded by !**/*.svg
  • templates/nextjs-starter/public/next.svg is excluded by !**/*.svg
  • templates/nextjs-starter/public/vercel.svg is excluded by !**/*.svg
  • templates/react-vite-starter/public/favicon.svg is excluded by !**/*.svg
  • templates/react-vite-starter/public/logo.svg is excluded by !**/*.svg
  • templates/remix-starter/public/favicon.svg is excluded by !**/*.svg
  • templates/remix-starter/public/logo.svg is excluded by !**/*.svg
  • templates/turborepo-starter/public/favicon.svg is excluded by !**/*.svg
  • templates/turborepo-starter/public/logo.svg is excluded by !**/*.svg
  • templates/wdio-starter/public/favicon.svg is excluded by !**/*.svg
  • templates/wdio-starter/public/logo.svg is excluded by !**/*.svg
  • templates/webextension-react-vite-starter/[src]/assets/img/logo.svg is excluded by !**/*.svg
  • templates/webextension-react-vite-starter/public/favicon.svg is excluded by !**/*.svg
  • templates/webextension-react-vite-starter/public/logo.svg is excluded by !**/*.svg
📒 Files selected for processing (39)
  • .github/workflows/landing-visual.yml
  • .github/workflows/smoke-test.yml
  • .github/workflows/test-combinations.yml
  • docs/DEFAULT_LANDING_DESIGN.md
  • docs/DEFAULT_LANDING_GUIDE.md
  • docs/MAINTENANCE_RUNBOOK.md
  • extensions/react-tailwindcss/package.json
  • extensions/react-tailwindcss/postcss.config.js.template
  • scripts/landing-audit.js
  • scripts/landing-visual/landing.spec.ts
  • scripts/landing-visual/package.json
  • scripts/landing-visual/playwright.config.ts
  • scripts/sync-assets.js
  • shared/landings/features.ts
  • templates/astro-starter/docs/COMPONENTS_AND_STYLING.md
  • templates/astro-starter/docs/PERFORMANCE.md
  • templates/astro-starter/docs/PROJECT_CONFIGURATION.md.template
  • templates/astro-starter/docs/PROJECT_STRUCTURE.md.template
  • templates/astro-starter/docs/README.md
  • templates/astro-starter/docs/STATE_MANAGEMENT.md
  • templates/astro-starter/src/components/Welcome.astro
  • templates/astro-starter/src/pages/index.astro
  • templates/nextjs-starter/[src]/app/page.module.css
  • templates/nextjs-starter/[src]/app/page.tsx
  • templates/nextjs-starter/[src]/app/page.tsx.template
  • templates/react-vite-starter/[src]/pages/Landing.css
  • templates/react-vite-starter/[src]/pages/Landing.tsx.template
  • templates/remix-starter/app/routes/_index.tsx.template
  • templates/remix-starter/app/styles/landing.css
  • templates/remix-starter/docs/COMPONENTS_AND_STYLING.md
  • templates/remix-starter/docs/PERFORMANCE.md
  • templates/remix-starter/docs/PROJECT_CONFIGURATION.md.template
  • templates/remix-starter/docs/PROJECT_STRUCTURE.md.template
  • templates/remix-starter/docs/README.md
  • templates/remix-starter/docs/STATE_MANAGEMENT.md
  • templates/webextension-react-vite-starter/[src]/newtab/Newtab.css
  • templates/webextension-react-vite-starter/[src]/newtab/Newtab.tsx.template
  • templates/webextension-react-vite-starter/[src]/popup/Popup.css
  • templates/webextension-react-vite-starter/[src]/popup/index.css
💤 Files with no reviewable changes (2)
  • templates/nextjs-starter/[src]/app/page.tsx
  • templates/astro-starter/src/components/Welcome.astro

Comment on lines +61 to +67
- name: Scaffold test project
id: scaffold
continue-on-error: true
run: |
CI=true npx create-awesome-node-app visual-test-project \
-t "file://${PWD}?subdir=templates/${{ matrix.template }}"
echo "Project scaffolded"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Scaffold failures are silently swallowed, job reports success with no tests run.

continue-on-error: true on the scaffold step means its failure doesn't fail the job. Since all later steps (dev server, Playwright run, screenshot upload) are gated on steps.scaffold.outcome == 'success' and none of them run/fail in that case, the job conclusion is a false "success" — visual regression silently never executes.

🔧 Proposed fix
       - name: Scaffold test project
         id: scaffold
-        continue-on-error: true
         run: |
           CI=true npx create-awesome-node-app visual-test-project \
             -t "file://${PWD}?subdir=templates/${{ matrix.template }}"
           echo "Project scaffolded"

If scaffold flakiness needs tolerance, retry instead of masking failure, and add an explicit final step that fails the job when steps.scaffold.outcome != 'success'.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Scaffold test project
id: scaffold
continue-on-error: true
run: |
CI=true npx create-awesome-node-app visual-test-project \
-t "file://${PWD}?subdir=templates/${{ matrix.template }}"
echo "Project scaffolded"
- name: Scaffold test project
id: scaffold
run: |
CI=true npx create-awesome-node-app visual-test-project \
-t "file://${PWD}?subdir=templates/${{ matrix.template }}"
echo "Project scaffolded"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/landing-visual.yml around lines 61 - 67, The Scaffold test
project step in the landing visual workflow is masking failures with
continue-on-error, which can let the job finish green without running any visual
tests. Remove the silent success behavior from the scaffold step, or keep
tolerance only via retries, and add an explicit failure check after the scaffold
step that fails the job when steps.scaffold.outcome is not success so the
downstream dev server and Playwright steps cannot be skipped unnoticed.

Comment thread scripts/landing-audit.js Outdated
Comment on lines +136 to +139
const lightModeBlock = css.match(/@media\s*\(prefers-color-scheme:\s*light\)\s*\{([^}]*)\}/);
if (lightModeBlock && !lightModeBlock[1].includes('--cna-amber-soft')) {
error(config.name, 'Light mode block does not override --cna-amber-soft');
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

[^}]* breaks on nested CSS rules inside @media blocks.

The light-mode media block regex stops at the first }, which closes the first nested selector rule rather than the whole @media block. Any --cna-amber-soft override declared after the first nested rule is never captured, so this check can produce false positives/negatives and silently defeat the audit's purpose.

🐛 Suggested approach
-      const lightModeBlock = css.match(/@media\s*\(prefers-color-scheme:\s*light\)\s*\{([^}]*)\}/);
-      if (lightModeBlock && !lightModeBlock[1].includes('--cna-amber-soft')) {
+      const mediaStart = css.search(/@media\s*\(prefers-color-scheme:\s*light\)\s*\{/);
+      const lightModeBody = mediaStart !== -1 ? extractBalancedBlock(css, mediaStart) : null;
+      if (lightModeBody && !lightModeBody.includes('--cna-amber-soft')) {

Implement extractBalancedBlock with a brace counter to find the matching closing } instead of relying on a non-nested regex.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/landing-audit.js` around lines 136 - 139, The light-mode CSS audit in
the landing-audit script is using a regex in the lightModeBlock check that stops
at the first closing brace, so nested rules inside the `@media` block are not
fully captured. Replace that regex-based extraction with a balanced-brace helper
such as extractBalancedBlock (or equivalent logic in the same script) and use it
when scanning the CSS so the --cna-amber-soft override is detected anywhere
within the full media block.

Comment on lines +10 to +29
test('dark mode', async ({ page }) => {
await page.emulateMedia({ colorScheme: 'dark', reducedMotion: 'no-preference' });
await page.goto('/');
await page.waitForLoadState('networkidle');
await page.screenshot({ path: filename('dark'), fullPage: true });
});

test('light mode', async ({ page }) => {
await page.emulateMedia({ colorScheme: 'light', reducedMotion: 'no-preference' });
await page.goto('/');
await page.waitForLoadState('networkidle');
await page.screenshot({ path: filename('light'), fullPage: true });
});

test('reduced motion', async ({ page }) => {
await page.emulateMedia({ colorScheme: 'dark', reducedMotion: 'reduce' });
await page.goto('/');
await page.waitForLoadState('networkidle');
await page.screenshot({ path: filename('motion'), fullPage: true });
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== Files ==\n'
git ls-files scripts/landing-visual | sed 's#^`#-` #'

printf '\n== landing.spec.ts ==\n'
wc -l scripts/landing-visual/landing.spec.ts
cat -n scripts/landing-visual/landing.spec.ts

printf '\n== package.json ==\n'
wc -l scripts/landing-visual/package.json
cat -n scripts/landing-visual/package.json

printf '\n== playwright config candidates ==\n'
fd -a 'playwright.config.*' scripts/landing-visual . || true

printf '\n== search for screenshot assertions / update flag ==\n'
rg -n "toHaveScreenshot|screenshot\\(|UPDATE_SNAPSHOTS|update-snapshots|snapshot" scripts/landing-visual . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**'

Repository: Create-Node-App/cna-templates

Length of output: 4565


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== playwright.config.ts ==\n'
wc -l scripts/landing-visual/playwright.config.ts
cat -n scripts/landing-visual/playwright.config.ts

printf '\n== docs references around UPDATE_SNAPSHOTS ==\n'
sed -n '118,160p' docs/DEFAULT_LANDING_GUIDE.md | cat -n

printf '\n== search for UPDATE_SNAPSHOTS handling ==\n'
rg -n "UPDATE_SNAPSHOTS|toHaveScreenshot|expect\\(page\\)\\.toHaveScreenshot|snapshot" scripts/landing-visual docs -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**'

Repository: Create-Node-App/cna-templates

Length of output: 3577


Use screenshot assertions instead of raw file writes

scripts/landing-visual/landing.spec.ts:10-29 only calls page.screenshot(), so these tests always pass and can’t fail on a visual regression. Switch them to Playwright snapshot assertions and wire test:update to Playwright’s snapshot-update flow; UPDATE_SNAPSHOTS=true is unused as-is.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/landing-visual/landing.spec.ts` around lines 10 - 29, The visual
tests in landing.spec.ts are only writing screenshots with page.screenshot(), so
they never assert against a baseline and cannot catch regressions. Update the
dark mode, light mode, and reduced motion tests to use Playwright snapshot
assertions in the same test cases, and connect the snapshot update behavior to
Playwright’s built-in update flow instead of relying on UPDATE_SNAPSHOTS=true.
Keep the changes localized to the existing test functions and any test:update
wiring that currently drives snapshot generation.

Comment thread scripts/sync-assets.js
Comment on lines +46 to +49
if (!fs.existsSync(sourceFile)) {
console.error(` SKIP ${asset} → ${template}/${targetPath} (source not found)`);
continue;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Missing source files are logged as errors but not counted, so the script silently exits 0.

console.error is used for the SKIP message, but errors isn't incremented, so a missing shared asset never affects the final summary or exit code (Lines 67-68). In CI or automated contexts this hides a real failure mode.

🩹 Proposed fix
       if (!fs.existsSync(sourceFile)) {
         console.error(`  SKIP  ${asset} → ${template}/${targetPath} (source not found)`);
+        errors++;
         continue;
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!fs.existsSync(sourceFile)) {
console.error(` SKIP ${asset} → ${template}/${targetPath} (source not found)`);
continue;
}
if (!fs.existsSync(sourceFile)) {
console.error(` SKIP ${asset} → ${template}/${targetPath} (source not found)`);
errors++;
continue;
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/sync-assets.js` around lines 46 - 49, The missing-source path in
sync-assets.js is only logging a SKIP message and never increments the errors
counter, so the final summary and exit code stay successful. Update the
fs.existsSync(sourceFile) branch in the asset-sync loop to treat a missing
shared asset as an error by incrementing errors alongside the existing
console.error, so the existing summary/exit logic reflects the failure.
Reference the sync-assets.js asset processing block that checks sourceFile and
the final errors-based exit path.


[Paths Configuration](../tsconfig.json)

It is also possible to define multiple paths for various folders(such as `<%= projectImportPath%>components`, `<%= projectImportPath%>hooks`, etc.), but using `<%= projectImportPath%>*` works very well because it is short enough so there is no need to configure multiple paths and it differs from other dependency modules so there is no confusion in what comes from `node_modules` and what is our source folder. That means that anything in the `src` folder can be accessed via `@`, e.g some file that lives in `<%= srcDir%>/components/MyComponent` can be accessed using `<%= projectImportPath%>components/MyComponents`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the example path typo.

Line 55 switches from MyComponent to MyComponents, so the sample path is inconsistent and readers may copy a broken example.

♻️ Proposed fix
- that lives in `<%= srcDir%>/components/MyComponent` can be accessed using `<%= projectImportPath%>components/MyComponents`.
+ that lives in `<%= srcDir%>/components/MyComponent` can be accessed using `<%= projectImportPath%>components/MyComponent`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
It is also possible to define multiple paths for various folders(such as `<%= projectImportPath%>components`, `<%= projectImportPath%>hooks`, etc.), but using `<%= projectImportPath%>*` works very well because it is short enough so there is no need to configure multiple paths and it differs from other dependency modules so there is no confusion in what comes from `node_modules` and what is our source folder. That means that anything in the `src` folder can be accessed via `@`, e.g some file that lives in `<%= srcDir%>/components/MyComponent` can be accessed using `<%= projectImportPath%>components/MyComponents`.
It is also possible to define multiple paths for various folders(such as `<%= projectImportPath%>components`, `<%= projectImportPath%>hooks`, etc.), but using `<%= projectImportPath%>*` works very well because it is short enough so there is no need to configure multiple paths and it differs from other dependency modules so there is no confusion in what comes from `node_modules` and what is our source folder. That means that anything in the `src` folder can be accessed via `@`, e.g some file that lives in `<%= srcDir%>/components/MyComponent` can be accessed using `<%= projectImportPath%>components/MyComponent`.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/astro-starter/docs/PROJECT_CONFIGURATION.md.template` at line 55,
The example path in PROJECT_CONFIGURATION.md.template is inconsistent because it
changes from MyComponent to MyComponents, which can mislead readers. Update the
sample under the projectImportPath explanation so the referenced component name
is consistent between the source path and the import path example, using the
surrounding projectImportPath and srcDir examples as the anchor.

Comment thread templates/astro-starter/docs/README.md Outdated
Comment on lines +3 to +24
This folder contains detailed documentation for the Next.js Starter template. Each document focuses on a specific aspect of the project:

## Core Documentation

- [Project Configuration](./PROJECT_CONFIGURATION.md) - Setup and configuration of development tools
- [Components and Styling](./COMPONENTS_AND_STYLING.md) - Best practices for components and styling solutions
- [Performance](./PERFORMANCE.md) - Performance optimization guidelines
- [State Management](./STATE_MANAGEMENT.md) - State management patterns and recommendations

## Additional Resources

- [Next.js Documentation](https://nextjs.org/docs)
- [React Documentation](https://reactjs.org/docs/getting-started.html)
- [TypeScript Documentation](https://www.typescriptlang.org/docs/)

## Getting Help

If you need additional help or have questions:

1. Check the [Next.js GitHub Discussions](https://github.com/vercel/next.js/discussions)
2. Join the [Next.js Discord](https://discord.gg/nextjs)
3. Open an issue in this repository

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Replace the Next.js references with Astro-specific docs.

This folder is under astro-starter, but the copy and links are still Next.js-specific. That will mislead users of the Astro starter docs.

Suggested fix
- This folder contains detailed documentation for the Next.js Starter template.
+ This folder contains detailed documentation for the Astro Starter template.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/astro-starter/docs/README.md` around lines 3 - 24, The README in
the Astro starter docs still references Next.js throughout, so update the copy
and links to be Astro-specific. In the README content, replace the project
description, core documentation links, external resources, and help section
entries with the corresponding Astro documentation and support references. Use
the README’s existing section structure and update the wording so it matches the
astro-starter template rather than Next.js.


[Paths Configuration](../tsconfig.json)

It is also possible to define multiple paths for various folders(such as `<%= projectImportPath%>components`, `<%= projectImportPath%>hooks`, etc.), but using `<%= projectImportPath%>*` works very well because it is short enough so there is no need to configure multiple paths and it differs from other dependency modules so there is no confusion in what comes from `node_modules` and what is our source folder. That means that anything in the `src` folder can be accessed via `@`, e.g some file that lives in `<%= srcDir%>/components/MyComponent` can be accessed using `<%= projectImportPath%>components/MyComponents`.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix the import-path example typo.

MyComponents should be MyComponent; as written, the example path does not match the example above and will confuse readers.

Suggested fix
- ... can be accessed using `<%= projectImportPath%>components/MyComponents`.
+ ... can be accessed using `<%= projectImportPath%>components/MyComponent`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
It is also possible to define multiple paths for various folders(such as `<%= projectImportPath%>components`, `<%= projectImportPath%>hooks`, etc.), but using `<%= projectImportPath%>*` works very well because it is short enough so there is no need to configure multiple paths and it differs from other dependency modules so there is no confusion in what comes from `node_modules` and what is our source folder. That means that anything in the `src` folder can be accessed via `@`, e.g some file that lives in `<%= srcDir%>/components/MyComponent` can be accessed using `<%= projectImportPath%>components/MyComponents`.
It is also possible to define multiple paths for various folders(such as `<%= projectImportPath%>components`, `<%= projectImportPath%>hooks`, etc.), but using `<%= projectImportPath%>*` works very well because it is short enough so there is no need to configure multiple paths and it differs from other dependency modules so there is no confusion in what comes from `node_modules` and what is our source folder. That means that anything in the `src` folder can be accessed via `@`, e.g some file that lives in `<%= srcDir%>/components/MyComponent` can be accessed using `<%= projectImportPath%>components/MyComponent`.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/remix-starter/docs/PROJECT_CONFIGURATION.md.template` at line 55,
The import-path example in PROJECT_CONFIGURATION.md.template has a typo: the
referenced component name in the path should match the earlier example. Update
the example near the projectImportPath explanation so the path uses MyComponent
consistently, and keep the surrounding text unchanged.

Comment thread templates/remix-starter/docs/README.md Outdated
Comment on lines +1 to +3
# Extra Documentation

This folder contains detailed documentation for the Next.js Starter template. Each document focuses on a specific aspect of the project:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Rename the template reference to Remix.

Line 3 still says “Next.js Starter template,” but this folder is under remix-starter/docs. That label is incorrect and should be updated.

♻️ Proposed fix
- This folder contains detailed documentation for the Next.js Starter template.
+ This folder contains detailed documentation for the Remix Starter template.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Extra Documentation
This folder contains detailed documentation for the Next.js Starter template. Each document focuses on a specific aspect of the project:
# Extra Documentation
This folder contains detailed documentation for the Remix Starter template. Each document focuses on a specific aspect of the project:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@templates/remix-starter/docs/README.md` around lines 1 - 3, The README in the
docs folder still refers to the Next.js Starter template, which is incorrect for
the Remix starter. Update the text in the README content to use Remix Starter
terminology instead of Next.js Starter, keeping the rest of the documentation
wording aligned with the remix-starter docs context.

- docs: rewrite PROJECT_STRUCTURE for Astro/Remix (remove Next.js copy)
- docs: fix README links for Astro/Remix (s/Next.js/Astro|Remix/)
- docs: fix PROJECT_CONFIGURATION import path typos
- ci(landing-visual): remove continue-on-error from scaffold step
- ci(smoke-test): add SKIP_ENV_VALIDATION to extension-isolation step
- ci(test-combinations): narrow pull_request trigger to template/ext changes
- scripts(landing-audit): use balanced-brace extraction for light mode check
- scripts(landing-visual): use toHaveScreenshot assertions instead of raw screenshot
- scripts(landing-visual): remove unused firefox project, add snapshotDir
- scripts(sync-assets): increment errors on missing source file
- css(remix): scope hover lift to interactive elements only
- css(webext-popup): declare --cna-* tokens in popup scope
@ulises-jeremias
ulises-jeremias merged commit 4ae0001 into main Jul 6, 2026
31 of 33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant