# Cloudflare Pages redirects.
#
# Blog slug changes must add explicit redirects here so Google and
# inbound links do not see a 404. The CI guard accepts either:
#
#   /blog/old-slug/ /blog/new-slug/ 301
#   /blog/old-slug/ /blog/ 301
#
# Keep this file committed even when empty; it documents the contract.

/sitemap.xml /sitemap-index.xml 301

# AMR wallet lives under `/amr`. Social auth callbacks from the wallet can
# return to locale-prefixed `/wallet` paths (for example `/zh/wallet`) after a
# logout/register flow; keep those callbacks on the wallet surface instead of
# falling through to the marketing site.
# Keep locale-prefixed entries in sync with `app/i18n.ts:LANDING_LOCALES`.
# Do not replace them with `/:locale/wallet`: that would also match
# `/amr/wallet` and redirect the wallet URL to itself.
/wallet          /amr/wallet  302
/wallet/         /amr/wallet  302
/en/wallet       /amr/wallet  302
/en/wallet/      /amr/wallet  302
/zh/wallet       /amr/wallet  302
/zh/wallet/      /amr/wallet  302
/ja/wallet       /amr/wallet  302
/ja/wallet/      /amr/wallet  302
/ko/wallet       /amr/wallet  302
/ko/wallet/      /amr/wallet  302
/de/wallet       /amr/wallet  302
/de/wallet/      /amr/wallet  302
/fr/wallet       /amr/wallet  302
/fr/wallet/      /amr/wallet  302
/ru/wallet       /amr/wallet  302
/ru/wallet/      /amr/wallet  302
/es/wallet       /amr/wallet  302
/es/wallet/      /amr/wallet  302
/pt-br/wallet    /amr/wallet  302
/pt-br/wallet/   /amr/wallet  302
/it/wallet       /amr/wallet  302
/it/wallet/      /amr/wallet  302
/tr/wallet       /amr/wallet  302
/tr/wallet/      /amr/wallet  302

# Locale-code migration: the previous OD landing-page stack used BCP-47
# region-qualified codes (zh-CN, zh-TW, pt-BR, es-ES) whereas the
# current bundle adopts the simpler codes the @astrojs/sitemap plugin
# and most CDN tooling default to (zh, zh-tw, pt-br, es). Anything
# Google or external links resolved against the old prefixes still
# arrives — these 301s send them to the new canonical URL with the
# rest of the path preserved.
/zh-CN/*  /zh/:splat     301
/zh-TW/*  /zh-tw/:splat  301
/pt-BR/*  /pt-br/:splat  301
/es-ES/*  /es/:splat     301

# Legacy locales (`fa`, `hu`, `th`) live in the old `_lib/i18n.ts:LOCALES`
# list but are not in the modern `LANDING_LOCALES` set the new
# `/{locale}/plugins/...` short-code wrappers are built from. The legacy
# catch-all (`pages/[locale]/[...path].astro`) used to render a
# placeholder for `/<legacy>/plugins/...`; the catch-all dropped
# `'plugins'` from its path list when the new wrappers shipped, so
# those URLs would 404 without a redirect. Send them to the canonical
# (English) `/plugins/...` until the legacy locale set is retired
# entirely.

# ─────────────────────────────────────────────────────────────────────
# Catalog migration: legacy /skills /systems /templates -> /plugins/*
# The old Astro generators were removed; these 301s preserve inbound
# links and SEO equity. Cloudflare matches first rule wins, so order is:
# faceted/specific -> detail prefixes -> bare index -> locale variants.
# trailingSlash:'always', so every source and target ends in '/'.
# ─────────────────────────────────────────────────────────────────────

# Faceted pages have no new equivalent -> degrade to the section landing.
/skills/mode/*       /plugins/skills/    301
/skills/scenario/*   /plugins/skills/    301
/systems/category/*  /plugins/systems/   301

# Systems detail: design-system-<folder> is the uniform new slug.
# These 8 folders have no new detail page -> degrade (must precede splat).
/systems/cisco/  /plugins/systems/  301
/systems/hud/  /plugins/systems/  301
/systems/loom/  /plugins/systems/  301
/systems/perplexity/  /plugins/systems/  301
/systems/slack/  /plugins/systems/  301
/systems/trading-terminal/  /plugins/systems/  301
/systems/webex/  /plugins/systems/  301
/systems/wechat/  /plugins/systems/  301
/systems/*  /plugins/design-system-:splat  301

# Templates detail: example-<folder> is the uniform new slug.
/templates/live-otd-operations-brief/  /plugins/templates/  301
/templates/*  /plugins/example-:splat  301

# Skills detail: only these 27 have a new artifact-template equivalent.
# 'replicate' collides with design-system-replicate -> force the section.
/skills/replicate/  /plugins/skills/  301
/skills/article-magazine/  /plugins/example-article-magazine/  301
/skills/card-twitter/  /plugins/example-card-twitter/  301
/skills/card-xiaohongshu/  /plugins/example-card-xiaohongshu/  301
/skills/data-report/  /plugins/example-data-report/  301
/skills/deck-guizang-editorial/  /plugins/example-deck-guizang-editorial/  301
/skills/deck-open-slide-canvas/  /plugins/example-deck-open-slide-canvas/  301
/skills/deck-swiss-international/  /plugins/example-deck-swiss-international/  301
/skills/design-brief/  /plugins/example-design-brief/  301
/skills/doc-kami-parchment/  /plugins/example-doc-kami-parchment/  301
/skills/frame-data-chart-nyt/  /plugins/example-frame-data-chart-nyt/  301
/skills/frame-flowchart-sticky/  /plugins/example-frame-flowchart-sticky/  301
/skills/frame-glitch-title/  /plugins/example-frame-glitch-title/  301
/skills/frame-light-leak-cinema/  /plugins/example-frame-light-leak-cinema/  301
/skills/frame-liquid-bg-hero/  /plugins/example-frame-liquid-bg-hero/  301
/skills/frame-logo-outro/  /plugins/example-frame-logo-outro/  301
/skills/frame-macos-notification/  /plugins/example-frame-macos-notification/  301
/skills/hatch-pet/  /plugins/example-hatch-pet/  301
/skills/mockup-device-3d/  /plugins/example-mockup-device-3d/  301
/skills/poster-hero/  /plugins/example-poster-hero/  301
/skills/ppt-keynote/  /plugins/example-ppt-keynote/  301
/skills/pptx-html-fidelity-audit/  /plugins/example-pptx-html-fidelity-audit/  301
/skills/resume-modern/  /plugins/example-resume-modern/  301
/skills/social-reddit-card/  /plugins/example-social-reddit-card/  301
/skills/social-spotify-card/  /plugins/example-social-spotify-card/  301
/skills/social-x-post-card/  /plugins/example-social-x-post-card/  301
/skills/vfx-text-cursor/  /plugins/example-vfx-text-cursor/  301
/skills/video-hyperframes/  /plugins/example-video-hyperframes/  301
# Remaining ~110 instruction-only skills have no detail page -> section.
/skills/*  /plugins/skills/  301

# Bare catalog index pages (least specific -> last).
/skills/     /plugins/skills/     301
/systems/    /plugins/systems/    301
/templates/  /plugins/templates/  301

# Agent detail route migration: the per-agent pages moved from
# `/agents/<slug>/` to `/agents/<slug>-design/` (design keyword in the URL) and
# the old Astro generators were removed. These 301s preserve any inbound links
# / SEO equity for the old paths, at the root and under every locale prefix.
# trailingSlash:'always', so every source and target ends in '/'.
/agents/codex/        /agents/codex-design/        301
/agents/cursor/       /agents/cursor-design/       301
/agents/claude-code/  /agents/claude-code-design/  301
/agents/opencode/     /agents/opencode-design/     301
/:locale/agents/codex/        /:locale/agents/codex-design/        301
/:locale/agents/cursor/       /:locale/agents/cursor-design/       301
/:locale/agents/claude-code/  /:locale/agents/claude-code-design/  301
/:locale/agents/opencode/     /:locale/agents/opencode-design/     301

# ---------------------------------------------------------------------------
# Retired marketing locales (2026-06 GSC review) -> fold to English (or /zh for
# Chinese variants). MUST precede the generic /:loc/* catalog rules below so a
# retired locale folds to English, not to its own (now non-existent) /plugins/
# pages. Their /wallet callbacks fold via /:splat -> /wallet -> /amr/wallet, so
# no per-locale wallet rule is needed.
# ---------------------------------------------------------------------------
/zh-tw/* /zh/:splat 301
/zh-tw   /zh/       301
/zh-cn/* /zh/:splat 301
/zh-cn   /zh/       301
/vi/* /:splat 301
/vi   /      301
/pl/* /:splat 301
/pl   /      301
/id/* /:splat 301
/id   /      301
/nl/* /:splat 301
/nl   /      301
/ar/* /:splat 301
/ar   /      301
/uk/* /:splat 301
/uk   /      301
/fa/* /:splat 301
/fa   /      301
/hu/* /:splat 301
/hu   /      301
/th/* /:splat 301
/th   /      301

# ---------------------------------------------------------------------------
# Kept-locale legacy catalog redirects, consolidated with a :loc placeholder.
# The per-locale expansion (11 locales x several paths) pushed the file past
# Cloudflare Pages' total-rule cap, silently dropping the tail -- the retired
# catch-alls above 404'd instead of redirecting. One placeholder rule per path
# keeps the file well under the cap. Retired locales are handled above (first
# match wins), so these only ever match a kept locale.
#
# IMPORTANT: do NOT add a generic `/:loc/plugins/*` fold here. On this project
# `_redirects` takes precedence over static assets, and the localized plugin
# hub pages (`/<loc>/plugins/`, `/<loc>/plugins/{skills,systems,templates}/`)
# are real static files that must keep serving 200. A `/:loc/plugins/*` rule
# would shadow them and 301 the hubs to English. Localized plugin DETAIL pages
# are not generated and 404 (unchanged from production); retired-locale plugin
# paths still fold to English via the `/<retired>/* -> /:splat` rules above.
# The /skills /systems /templates legacy listings below are NOT static (their
# generators were removed), so folding them is safe.
#
# The same `plugins` collision bites the per-section folds, not just the
# `/:loc/plugins/*` shape warned against above: `:loc` matches the literal
# segment `plugins`, so `/plugins/{skills,systems,templates}/` binds
# `:loc=plugins` and 301s to `/plugins/plugins/{...}/` (404). Guard the real
# English hub pages with a 200 rewrite FIRST so the folds never see them
# (first match wins). `/plugins/craft/` has no fold below, so it needs none.
# ---------------------------------------------------------------------------
/plugins/skills/*     /plugins/skills/:splat     200
/plugins/systems/*    /plugins/systems/:splat    200
/plugins/templates/*  /plugins/templates/:splat  200
/:loc/skills/*     /:loc/plugins/skills/     301
/:loc/systems/*    /:loc/plugins/systems/    301
/:loc/templates/*  /:loc/plugins/templates/  301

# Mistral Vibe CLI moved from /agents/vibe-design/ to /agents/vibe-cli-design/ so the
# exact-match 'vibe design' concept URL serves the informational blog instead of a
# product page. 301 the old agent URL (all locales) to the what-is-vibe-design guide.
/agents/vibe-design/  /blog/what-is-vibe-design/  301
/agents/vibe-design  /blog/what-is-vibe-design/  301
/en/agents/vibe-design/  /en/blog/what-is-vibe-design/  301
/en/agents/vibe-design  /en/blog/what-is-vibe-design/  301
/zh/agents/vibe-design/  /zh/blog/what-is-vibe-design/  301
/zh/agents/vibe-design  /zh/blog/what-is-vibe-design/  301
/zh-tw/agents/vibe-design/  /zh-tw/blog/what-is-vibe-design/  301
/zh-tw/agents/vibe-design  /zh-tw/blog/what-is-vibe-design/  301
/ja/agents/vibe-design/  /ja/blog/what-is-vibe-design/  301
/ja/agents/vibe-design  /ja/blog/what-is-vibe-design/  301
/ko/agents/vibe-design/  /ko/blog/what-is-vibe-design/  301
/ko/agents/vibe-design  /ko/blog/what-is-vibe-design/  301
/de/agents/vibe-design/  /de/blog/what-is-vibe-design/  301
/de/agents/vibe-design  /de/blog/what-is-vibe-design/  301
/fr/agents/vibe-design/  /fr/blog/what-is-vibe-design/  301
/fr/agents/vibe-design  /fr/blog/what-is-vibe-design/  301
/ru/agents/vibe-design/  /ru/blog/what-is-vibe-design/  301
/ru/agents/vibe-design  /ru/blog/what-is-vibe-design/  301
/es/agents/vibe-design/  /es/blog/what-is-vibe-design/  301
/es/agents/vibe-design  /es/blog/what-is-vibe-design/  301
/pt-br/agents/vibe-design/  /pt-br/blog/what-is-vibe-design/  301
/pt-br/agents/vibe-design  /pt-br/blog/what-is-vibe-design/  301
/it/agents/vibe-design/  /it/blog/what-is-vibe-design/  301
/it/agents/vibe-design  /it/blog/what-is-vibe-design/  301
/vi/agents/vibe-design/  /vi/blog/what-is-vibe-design/  301
/vi/agents/vibe-design  /vi/blog/what-is-vibe-design/  301
/pl/agents/vibe-design/  /pl/blog/what-is-vibe-design/  301
/pl/agents/vibe-design  /pl/blog/what-is-vibe-design/  301
/id/agents/vibe-design/  /id/blog/what-is-vibe-design/  301
/id/agents/vibe-design  /id/blog/what-is-vibe-design/  301
/nl/agents/vibe-design/  /nl/blog/what-is-vibe-design/  301
/nl/agents/vibe-design  /nl/blog/what-is-vibe-design/  301
/ar/agents/vibe-design/  /ar/blog/what-is-vibe-design/  301
/ar/agents/vibe-design  /ar/blog/what-is-vibe-design/  301
/tr/agents/vibe-design/  /tr/blog/what-is-vibe-design/  301
/tr/agents/vibe-design  /tr/blog/what-is-vibe-design/  301
/uk/agents/vibe-design/  /uk/blog/what-is-vibe-design/  301
/uk/agents/vibe-design  /uk/blog/what-is-vibe-design/  301
