一键导入
frontend
Write Svelte 5 components and SvelteKit pages following the project's frontend conventions — dark theme, mobile-first, minimalist Tailwind, modern CSS.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Write Svelte 5 components and SvelteKit pages following the project's frontend conventions — dark theme, mobile-first, minimalist Tailwind, modern CSS.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Create a new Architecture Decision Record (ADR) in docs/decisions/. MUST be used whenever writing an ADR — never create ADR files manually. Picks the next sequential number, fills the template, and updates the ADR table in README.md.
Run E2E and unit tests. Supports smoke tests (quick, any DB), deterministic tests (seeded DB, full suite), unit tests, or individual test files. Also covers ad-hoc verification via Playwright MCP.
Audit the current branch for loose ends before merge or plan close — stale docs, untested defensive code, partial wiring, coverage regressions, leftover TODOs. Reports findings; does not fix. MUST be used as part of plan-mode step 4 ("Branch audit before closing"); also useful ad-hoc whenever a branch is asked to be merge-ready.
Stage and commit changes with an emoji conventional commit message. Reviews staged/unstaged diffs, suggests a message, and creates the commit.
Run linting and formatting checks on the project. Uses ESLint, Prettier, and svelte-check. Reports issues and offers to auto-fix.
Review the current session for learnings worth persisting. Prefers committed files (CLAUDE.md, skills) over memory — memory is only for personal/user-specific things.
基于 SOC 职业分类
| name | frontend |
| description | Write Svelte 5 components and SvelteKit pages following the project's frontend conventions — dark theme, mobile-first, minimalist Tailwind, modern CSS. |
| allowed-tools | Read Glob Grep Write Edit |
Help me build frontend components and pages for this SvelteKit project.
$state, $derived, $effect, $props)@theme inline CSS variablesAlways use semantic utilities, never raw Tailwind color names:
| Utility | Use for |
|---|---|
bg-canvas | Page backgrounds |
bg-surface | Cards, panels |
bg-elevated | Nav, dropdowns, modals |
border-subtle | All borders and dividers |
text-primary | Main body text |
text-secondary | Labels, captions, muted text |
text-accent | Accent text, active states |
For tier colors use CSS variables directly: style="background: var(--tier-s-bg); color: var(--tier-s-fg)".
export let, no $:, no on: event syntaxlet { prop, ...rest } = $props()onclick, onchange, etc.<style> blocks using @apply sparingly;
prefer direct Tailwind utilities in the templateresolve() inside the component/snippet
rather than requiring callers to pass pre-resolved paths. This keeps the ESLint no-navigation-without-resolve rule happy without needing suppression commentsmd: / lg: for widermax-w-6xl mx-auto px-4py-12 for sections, mt-4 / mt-8 for spacingz-50 and backdrop-blur-sm for floating UIanimate-spin, animate-pulse).<style> block only when Tailwind can't model it cleanly:
::backdrop, @starting-style, transition: ... allow-discrete::before/::after with contentgrid-template-areas@keyframes<style> block explaining which of the above applies.Prefer modern browser features directly:
color-scheme: dark on html<style> blocksbackdrop-filter for frosted-glass effectscontainer and @container queries for component-level responsiveness:has(), :is(), :where() for expressive selectorsscrollbar-color / scrollbar-width for custom scrollbarsTarget: WCAG 2.1 Level AA. Pages must read well as plain unstyled HTML.
<nav>, <main>, <section>, <table>, <ul>, <dialog>, etc.<h1>; headings must not skip levels<label> or aria-labelaria-hidden="true"combobox, menu, listbox, etc.)svelte-ignore a11y_*) without strong justification+server.ts endpointsWhen a <form> posts to a SvelteKit endpoint (no +page exists at that path — only a +server.ts), two subtleties bite:
Add data-sveltekit-reload to the form. Without it, SvelteKit's client-side router intercepts same-origin GET form submissions and tries to navigate to the URL as if it were a page. It finds no +page, throws SvelteKitError: Not found in DevTools, and the only reason the request still completes is that the browser's native form submission also fires in parallel. The attribute opts the form out of the router so the browser handles it natively.
If you flip local UI state in onsubmit, defer it with setTimeout(() => state = true, 0). Svelte 5 flushes effects from event handlers eagerly enough that setting state synchronously can unmount the form before the browser dispatches the submission, cancelling the in-flight request. The macrotask defers the re-render past the browser's submission step. Don't preventDefault() — let the browser submit natively, then swap the UI on the next tick.
This pattern shows up in download forms (the export wizard) and any other "submit form, get a file back, swap to a confirmation panel" flow.
$state from a propReading a $props() value directly inside a $state(...) initializer trips Svelte's state_referenced_locally warning ("This reference only captures the initial value of options"). The reactive read isn't tracked, so subsequent prop changes won't update the state — usually fine but the warning is real noise. Wrap the seed in untrack(() => ...) to acknowledge "I want the value at mount, not a subscription":
import { untrack } from 'svelte';
let { options } = $props();
let values = $state(untrack(() => options.map((o) => [o.id, o.default])));
Use this when the prop is a stable schema you only need at mount; if the prop genuinely changes over the component's life, restructure to $derived or a keyed {#if} instead.
style="" attributes except for dynamic CSS variable values<!-- Header --> or <!-- Score bar --> above markup that is self-evident.
Only add comments that explain why something non-obvious is done (e.g. <!-- Scrim overlay for text legibility -->)Note on animations: We like playful micro-animations that make the UX feel alive — subtle hover lifts, smooth colour transitions, gentle entrance fades. Keep durations short (150–300 ms) and prefer
transition-*utilities or CSS@keyframesin<style>blocks over JavaScript-driven animations.
$ARGUMENTS