[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6X7WTYKRPZACXPM16P995XG":3,"skill-same:01M6X7WTYKRPZACXPM16P995XG":103},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":31,"publishedAt":52,"linkOnly":53,"markdownContent":54,"markdownBody":55,"frontMatter":56,"refName":64,"commitSha":65,"skillDirectory":66,"forksCount":67,"repositoryHtmlUrl":68,"repositoryHomepageUrl":69,"ownerHtmlUrl":70,"ownerBlogUrl":69,"ownerDescription":71,"updatedAt":72,"install":73,"resources":86},"01M6X7WTYKRPZACXPM16P995XG","tailwind-engineer",null,"Writing or reviewing Tailwind CSS — utility-first, design tokens, no inline-style drift, responsive variants, dark mode — 'style this' or 'mach das hübsch'. Pairs with react-shadcn-ui.","event4u-app\u002Fagent-config","event4u-app","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F199339632?v=4","01M6X5TWBNCQCE1VDKT4E9KF7N","event4u.app","01M6X5TWF4HRM266RG2Q5VVH1X",19,"MIT","https:\u002F\u002Fgithub.com\u002Fevent4u-app\u002Fagent-config\u002Fblob\u002Fmain\u002Fsrc\u002Fskills\u002Ftailwind-engineer\u002FSKILL.md",[18,23,26],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000015","视觉设计",{"categoryNo":27,"categoryName":28,"taxonomyType":29,"taxonomyTypeDesc":30},"01JBSEEDCAT000000000000032","设计师","PROFESSION","适用职业",[32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],"tailwind engineer","Tailwind","engineer","responsive","dark","variants","inline","mode","with","utility","dark mode","tokens","frontend","drift","ui","shadcn","react","css","writing","design","2026-11-10 10:12:30",false,"---\nmodel_tier: medium\nname: tailwind-engineer\ndescription: \"Writing or reviewing Tailwind CSS — utility-first, design tokens, no inline-style drift, responsive variants, dark mode — 'style this' or 'mach das hübsch'. Pairs with react-shadcn-ui.\"\npersonas:\n  - frontend-engineer\ndomain: engineering\nworkspaces:\n  - engineering\npacks:\n  - engineering-base\n---\n\n# tailwind-engineer\n\n> Apply utility-first discipline. Reach for design tokens before\n> arbitrary values, compose with `@apply` only where it earns its\n> keep, and reject inline `style=` drift. The skill is the **how**\n> for any Tailwind-stack screen; pair with\n> [`existing-ui-audit`](..\u002Fexisting-ui-audit\u002FSKILL.md) for the **what\n> already exists** and [`fe-design`](..\u002Ffe-design\u002FSKILL.md) for the\n> **why**.\n\n## When to use\n\n- Writing or reviewing Tailwind classes in Blade, Livewire, or React\n  components.\n- A diff introduces inline `style=` for dynamic values, hex codes\n  not in `tailwind.config`, or `!important`.\n- Class lists balloon past ~12 utilities and the component is\n  hard to read or duplicate.\n- German triggers: \"stile mit Tailwind\", \"design tokens nutzen\",\n  \"warum nicht inline?\".\n\nDo NOT use when:\n\n- The stack is not Tailwind (vanilla CSS, CSS-in-JS, MUI) — skip.\n- The question is component shape, not styling — route to\n  [`ui-component-architect`](..\u002Fui-component-architect\u002FSKILL.md).\n- An accessibility issue is the symptom (focus ring, contrast, hit\n  area) — route to [`accessibility-auditor`](..\u002Faccessibility-auditor\u002FSKILL.md).\n\n## Procedure\n\n### 1. Resolve to design tokens first\n\nInspect `tailwind.config.{js,ts}` (or the equivalent `@theme` block)\nand identify the configured tokens. Map every requested colour,\nradius, spacing, shadow, font-size to a configured token. If the design hands you `#3B82F6`, use\n`bg-blue-500` (or the project's named token). Arbitrary values\n(`bg-[#3B82F6]`, `mt-[17px]`) are a smell — accept only with a\none-line comment naming the design source.\n\n**That paragraph is written for greenfield, and artifact-bound work inverts\nit.** When a provided finished design is the spec\n([`design-fidelity`](..\u002F..\u002Frules\u002Fdesign-fidelity.md)), `#3B82F6` is a decision\nsomebody already made and `bg-blue-500` is a guess about it. Three obligations\nfollow, and the third is the one this skill used to get wrong:\n\n1. **Do not snap.** Replacing the artifact's value with the nearest configured\n   token is the deviation the rule's Iron Law forbids — *\"NEVER SWAP … SPACING,\n   OR COLOUR\"* without explicit confirmation. An artifact-derived exact value is\n   not a smell here: it *is* the spec, and the source-naming comment the\n   paragraph above asks for is what records it.\n2. **Translate once, not per call site.** Where the artifact's literal genuinely\n   needs to live in the project's system, add **one** named project token\n   carrying that exact value and use it everywhere — one token the project owns\n   beats N approximations of the same colour. That is a token duty, not a\n   deviation: the value does not change.\n3. **Reconcile as a proposal, never autonomously.** Report each value's\n   distance to the nearest project token on the `Reconciled:` line below, and\n   let the human decide. Writing a *different* project value because the\n   difference looks small is exactly the unconfirmed swap (1) rules out — the\n   mode table at `design-fidelity.md:117-121` grants no visibility exemption,\n   and `structural` grants only the filling of a spec that is genuinely\n   **silent**, which an artifact stating `#3B82F6` is not.\n\n**Why not \"just approximate within tolerance\", which is the eventual intent:**\nthat needs a tolerance to exist. There is none — no `reconcile`, `tolerance`,\n`approximat` or `nearest` in the rule or its guideline — and both the threshold\nand whether approximation is autonomous by default are owner decisions, tracked\nas `blocker: approximation-tolerance` and `blocker: fidelity-default-flip` on\n`road-to-design-intent-conformance`. Until they land, a skill granting that\nautonomy would be re-writing the rule from underneath it.\n\nStructure, controls, grid and breakpoints are never this skill's to adjust;\nthose stay 1:1 with the artifact and belong to the rule, not to a\nutility-class decision. **Icons are out of scope here as well, and this skill\nasserts no obligation about them** — the icon system belongs to\n`icon-consistency`. An earlier revision of\nthis paragraph claimed icons \"stay 1:1 with the artifact\" with no citation of\nany kind, while putting them outside its own scope in the same sentence; the\nclaim is withdrawn rather than defended, because a clause that reached the tree\nfirst does not thereby earn an evidentiary bar for its own reversal.\n\nToken authoring (DTCG 3-layer model, CSS-var\u002FTailwind generation) lives\nin [`design-tokens`](..\u002Fdesign-tokens\u002FSKILL.md); its\n`tokens.ts validate --dir \u003Cpath>` is the **single token-discipline\nlinter** — the mechanical check behind this rule (no hardcoded hex \u002F px \u002F\nrem outside the token files). That skill ships with the `frontend-design`\npack: without it the rule above still binds and is checked by reading,\nnot by a linter. Greenfield Tailwind config: bundled\n`scripts\u002Ftailwind_config_gen.ts` (Apache-2.0-derived, pure templating)\nscaffolds `tailwind.config.{js,ts}` per framework.\n\n### 2. Compose, don't inline\n\nInline `style=\"...\"` is allowed only for **runtime-computed values**\nthe build cannot know (server-pushed colour, animated transform\ntarget). Static values inline are a regression — replace with a\nutility, an arbitrary value, or a token extension.\n\n### 3. Order classes for scan-ability\n\nGroup by axis: layout → box-model → typography → colour → state\n→ responsive. Most projects pin this with `prettier-plugin-tailwindcss`;\nif the plugin is configured, run it; if not, follow the order\nmanually. Reviewer should read intent in one pass.\n\n### 4. Extract only when duplicated ≥ 3 times\n\nThe first two repetitions of a **utility-class string** are noise; the third\nis a pattern (the utility-class row of the per-class canon,\n[`abstraction-thresholds`](..\u002F..\u002F..\u002Fdocs\u002Fguidelines\u002Fabstraction-thresholds.md)).\nExtract via:\n\n| Mechanism | When |\n|---|---|\n| Component (Blade\u002FLivewire\u002FReact) | Different content, same shell |\n| Class string constant | Same shell, different consumers in same file |\n| `@apply` in CSS | Cross-file shared visual primitive (button, badge) |\n| Tailwind plugin | Tokens or variants, not classes |\n\n`@apply` for a one-off is a regression — keep utilities inline\nuntil the third use earns extraction.\n\n### 5. Responsive + dark + state in that order\n\nClass order within an axis: base → `sm:` → `md:` → `lg:` → `xl:` →\n`dark:` → state (`hover:`, `focus:`, `disabled:`, `aria-*:`).\nMixing the order makes diffs noisy. State on top of dark on top\nof responsive matches Tailwind's cascade and reads top-down.\n\n## Output format\n\nWhen reviewing or proposing styles, return:\n\n1. Token map — every colour, spacing, radius, shadow, font-size mapped\n   to its configured token; arbitrary values flagged with the design\n   source they cite. Artifact-bound work adds a **Reconciled** block here:\n   one line per value, as `\u003Cartifact value> → \u003Ckept, or the token that\n   carries it exactly> (\u003Cdistance to the nearest project token>)`. This is\n   the destination \"report the distance\" means; without it the obligation\n   has nowhere to land and is unobservable in the deliverable.\n2. Class list — ordered (layout → box-model → typography → colour →\n   state → responsive); inline-style use justified per element.\n3. Extraction + risk call-out — component \u002F constant \u002F `@apply` \u002F none\n   with reason; risks named (arbitrary values, `!important`, dark-mode\n   gaps, non-token references).\n\nConcrete shape:\n\n```\nElement:        \u003Cselector or component name>\nToken map:      \u003Ccolour\u002Fspacing\u002Fetc → config token>\nReconciled:     \u003Cartifact value → kept or exact-carrying token, + distance>\nClass list:     \u003Cordered classes>\nInline style:   \u003Conly if runtime-computed; else \"none\">\nExtraction:     \u003Ccomponent | constant | @apply | none — reason>\nRisks:          \u003Carbitrary values, !important, dark-mode gaps>\n```\n\n## Gotcha\n\n- `space-x-*` \u002F `space-y-*` collide with `flex-wrap` and RTL — use\n  `gap-*` on the flex\u002Fgrid parent unless the design demands otherwise.\n- `dark:` variants need a token map in both modes; one-sided dark\n  styling is half a feature.\n- Arbitrary values (`mt-[17px]`) survive Tailwind upgrades but\n  break the design system; they accumulate silently. **Artifact-bound is the\n  exception, not a loophole:** a value the provided design specifies is not\n  accumulation, and step 1's three obligations decide it. An arbitrary value\n  nobody can trace to a source is still the smell this bullet is about.\n- **The carrier is CSS or a utility class; the value is the design's.** Static\n  presentation belongs in CSS \u002F tokens \u002F classes — `style=` is for what only\n  the runtime knows (a computed width, a live transform, a measured offset).\n  Porting an artifact's inline `style=` into classes is therefore expected and\n  is not a deviation, **as long as the resolved value comes out identical**.\n  Changing the carrier is free; changing the number is not.\n- `@apply` inside component CSS interacts with PurgeCSS — keep it\n  in files Tailwind scans, not in vendor CSS.\n- **Anti-AI-slop catalog.** The bullets below are the Tailwind-specific\n  manifestations of the stack-agnostic patterns in\n  [`docs\u002Fguidelines\u002Fdesign-antipatterns.md`](..\u002F..\u002F..\u002Fdocs\u002Fguidelines\u002Fdesign-antipatterns.md)\n  (C1 gradients, T7 fonts, L1\u002FL2 layout, V1 side-stripe). Pull the catalog\n  for the full list; the objective subset (contrast, font-size floor,\n  reduced-motion) is validated via `accessibility-auditor`'s checklist —\n  cite its verdict rather than eyeballing.\n- **Anti-AI-slop: gradients.** Unless audit-pinned or brief-explicit,\n  avoid the default purple-to-blue \u002F cyan-to-pink gradients on white —\n  they read as auto-generated (catalog C1\u002FC2). Reach for a single accent\n  from the token map, or a duotone built from configured tokens.\n- **Anti-AI-slop: typography.** Unless audit-pinned, avoid surfacing\n  the default as the *visible* body face — Inter as a template webfont,\n  or `font-sans` (Arial \u002F Helvetica). If `tailwind.config`\n  pins a font family, use it; if not, treat the missing token as a\n  gap to flag, not a license to ship the OS default.\n- **Anti-AI-slop: layout.** Unless audit-pinned, the centered hero +\n  3-column features + CTA stack is the AI-template tell. Break the\n  grid intentionally (asymmetric column split, overlap, diagonal\n  flow) when the brief allows; cite the design brief's `aesthetic:`\n  line if `fe-design`'s aesthetic-direction section produced one.\n\n## Taste Dials\n\nWhen `DESIGN.md` declares `## Taste Dials`, honour them: Variance → layout-family spread + asymmetry tolerance; Motion → animation budget + reduced-motion posture; Density → spacing scale + information-per-viewport. Absent → follow the design brief's inferred dials.\n\n## Security constraints\n\n`scripts\u002Ftailwind_config_gen.ts` is the only shipped script, started as:\n\n```bash\nnode \u003Cskills-root>\u002Ftailwind-engineer\u002Fscripts\u002Ftailwind_config_gen.mjs \\\n  [--framework react|vue|svelte|nextjs] [--output PATH] [--validate-only]\n```\n\n- **What it may touch** — exactly one file: `--output PATH`, or\n  `tailwind.config.ts` \u002F `.js` in the current working directory when no\n  `--output` is given. It reads nothing from the project.\n- **What it must never do** — write anywhere other than that one path,\n  reach the network, or spawn a subprocess. It does none of these.\n- **Default invocation** — **mutating**, and stated here because it is a\n  real exception rather than a comfortable one: a bare invocation writes\n  `tailwind.config.ts` into `cwd`, overwriting an existing config without\n  prompting. `--validate-only` is the read-only path — it prints the\n  generated config to stdout and writes nothing. Run `--validate-only`\n  first, and pass `--output` when the target is not the cwd default.\n  This default contradicts `skill-writing`'s \"never mutate on a bare\n  invocation\" line; it is recorded rather than silently tolerated, and\n  changing the script's default is a caller-visible behaviour change that\n  belongs in its own change, not here.\n- **Outbound** — nothing. No network access.\n\n## Do NOT\n\n- Do NOT run `tailwind_config_gen` bare in a project that already has a\n  `tailwind.config.*` — it overwrites without asking. Use\n  `--validate-only` first, then `--output` at the intended path.\n- Do NOT add `!important` to win a specificity fight; restructure\n  the cascade or extract the conflicting style.\n- Do NOT introduce a new colour outside `tailwind.config` without\n  also adding the token; one-off hex codes drift the system.\n- Do NOT use `@apply` to avoid utility verbosity inside a single\n  component — extract the component instead.\n- Do NOT ship `style=` for static values; that is a CSS regression\n  the linter will not catch.\n","# tailwind-engineer\n\n> Apply utility-first discipline. Reach for design tokens before\n> arbitrary values, compose with `@apply` only where it earns its\n> keep, and reject inline `style=` drift. The skill is the **how**\n> for any Tailwind-stack screen; pair with\n> [`existing-ui-audit`](..\u002Fexisting-ui-audit\u002FSKILL.md) for the **what\n> already exists** and [`fe-design`](..\u002Ffe-design\u002FSKILL.md) for the\n> **why**.\n\n## When to use\n\n- Writing or reviewing Tailwind classes in Blade, Livewire, or React\n  components.\n- A diff introduces inline `style=` for dynamic values, hex codes\n  not in `tailwind.config`, or `!important`.\n- Class lists balloon past ~12 utilities and the component is\n  hard to read or duplicate.\n- German triggers: \"stile mit Tailwind\", \"design tokens nutzen\",\n  \"warum nicht inline?\".\n\nDo NOT use when:\n\n- The stack is not Tailwind (vanilla CSS, CSS-in-JS, MUI) — skip.\n- The question is component shape, not styling — route to\n  [`ui-component-architect`](..\u002Fui-component-architect\u002FSKILL.md).\n- An accessibility issue is the symptom (focus ring, contrast, hit\n  area) — route to [`accessibility-auditor`](..\u002Faccessibility-auditor\u002FSKILL.md).\n\n## Procedure\n\n### 1. Resolve to design tokens first\n\nInspect `tailwind.config.{js,ts}` (or the equivalent `@theme` block)\nand identify the configured tokens. Map every requested colour,\nradius, spacing, shadow, font-size to a configured token. If the design hands you `#3B82F6`, use\n`bg-blue-500` (or the project's named token). Arbitrary values\n(`bg-[#3B82F6]`, `mt-[17px]`) are a smell — accept only with a\none-line comment naming the design source.\n\n**That paragraph is written for greenfield, and artifact-bound work inverts\nit.** When a provided finished design is the spec\n([`design-fidelity`](..\u002F..\u002Frules\u002Fdesign-fidelity.md)), `#3B82F6` is a decision\nsomebody already made and `bg-blue-500` is a guess about it. Three obligations\nfollow, and the third is the one this skill used to get wrong:\n\n1. **Do not snap.** Replacing the artifact's value with the nearest configured\n   token is the deviation the rule's Iron Law forbids — *\"NEVER SWAP … SPACING,\n   OR COLOUR\"* without explicit confirmation. An artifact-derived exact value is\n   not a smell here: it *is* the spec, and the source-naming comment the\n   paragraph above asks for is what records it.\n2. **Translate once, not per call site.** Where the artifact's literal genuinely\n   needs to live in the project's system, add **one** named project token\n   carrying that exact value and use it everywhere — one token the project owns\n   beats N approximations of the same colour. That is a token duty, not a\n   deviation: the value does not change.\n3. **Reconcile as a proposal, never autonomously.** Report each value's\n   distance to the nearest project token on the `Reconciled:` line below, and\n   let the human decide. Writing a *different* project value because the\n   difference looks small is exactly the unconfirmed swap (1) rules out — the\n   mode table at `design-fidelity.md:117-121` grants no visibility exemption,\n   and `structural` grants only the filling of a spec that is genuinely\n   **silent**, which an artifact stating `#3B82F6` is not.\n\n**Why not \"just approximate within tolerance\", which is the eventual intent:**\nthat needs a tolerance to exist. There is none — no `reconcile`, `tolerance`,\n`approximat` or `nearest` in the rule or its guideline — and both the threshold\nand whether approximation is autonomous by default are owner decisions, tracked\nas `blocker: approximation-tolerance` and `blocker: fidelity-default-flip` on\n`road-to-design-intent-conformance`. Until they land, a skill granting that\nautonomy would be re-writing the rule from underneath it.\n\nStructure, controls, grid and breakpoints are never this skill's to adjust;\nthose stay 1:1 with the artifact and belong to the rule, not to a\nutility-class decision. **Icons are out of scope here as well, and this skill\nasserts no obligation about them** — the icon system belongs to\n`icon-consistency`. An earlier revision of\nthis paragraph claimed icons \"stay 1:1 with the artifact\" with no citation of\nany kind, while putting them outside its own scope in the same sentence; the\nclaim is withdrawn rather than defended, because a clause that reached the tree\nfirst does not thereby earn an evidentiary bar for its own reversal.\n\nToken authoring (DTCG 3-layer model, CSS-var\u002FTailwind generation) lives\nin [`design-tokens`](..\u002Fdesign-tokens\u002FSKILL.md); its\n`tokens.ts validate --dir \u003Cpath>` is the **single token-discipline\nlinter** — the mechanical check behind this rule (no hardcoded hex \u002F px \u002F\nrem outside the token files). That skill ships with the `frontend-design`\npack: without it the rule above still binds and is checked by reading,\nnot by a linter. Greenfield Tailwind config: bundled\n`scripts\u002Ftailwind_config_gen.ts` (Apache-2.0-derived, pure templating)\nscaffolds `tailwind.config.{js,ts}` per framework.\n\n### 2. Compose, don't inline\n\nInline `style=\"...\"` is allowed only for **runtime-computed values**\nthe build cannot know (server-pushed colour, animated transform\ntarget). Static values inline are a regression — replace with a\nutility, an arbitrary value, or a token extension.\n\n### 3. Order classes for scan-ability\n\nGroup by axis: layout → box-model → typography → colour → state\n→ responsive. Most projects pin this with `prettier-plugin-tailwindcss`;\nif the plugin is configured, run it; if not, follow the order\nmanually. Reviewer should read intent in one pass.\n\n### 4. Extract only when duplicated ≥ 3 times\n\nThe first two repetitions of a **utility-class string** are noise; the third\nis a pattern (the utility-class row of the per-class canon,\n[`abstraction-thresholds`](..\u002F..\u002F..\u002Fdocs\u002Fguidelines\u002Fabstraction-thresholds.md)).\nExtract via:\n\n| Mechanism | When |\n|---|---|\n| Component (Blade\u002FLivewire\u002FReact) | Different content, same shell |\n| Class string constant | Same shell, different consumers in same file |\n| `@apply` in CSS | Cross-file shared visual primitive (button, badge) |\n| Tailwind plugin | Tokens or variants, not classes |\n\n`@apply` for a one-off is a regression — keep utilities inline\nuntil the third use earns extraction.\n\n### 5. Responsive + dark + state in that order\n\nClass order within an axis: base → `sm:` → `md:` → `lg:` → `xl:` →\n`dark:` → state (`hover:`, `focus:`, `disabled:`, `aria-*:`).\nMixing the order makes diffs noisy. State on top of dark on top\nof responsive matches Tailwind's cascade and reads top-down.\n\n## Output format\n\nWhen reviewing or proposing styles, return:\n\n1. Token map — every colour, spacing, radius, shadow, font-size mapped\n   to its configured token; arbitrary values flagged with the design\n   source they cite. Artifact-bound work adds a **Reconciled** block here:\n   one line per value, as `\u003Cartifact value> → \u003Ckept, or the token that\n   carries it exactly> (\u003Cdistance to the nearest project token>)`. This is\n   the destination \"report the distance\" means; without it the obligation\n   has nowhere to land and is unobservable in the deliverable.\n2. Class list — ordered (layout → box-model → typography → colour →\n   state → responsive); inline-style use justified per element.\n3. Extraction + risk call-out — component \u002F constant \u002F `@apply` \u002F none\n   with reason; risks named (arbitrary values, `!important`, dark-mode\n   gaps, non-token references).\n\nConcrete shape:\n\n```\nElement:        \u003Cselector or component name>\nToken map:      \u003Ccolour\u002Fspacing\u002Fetc → config token>\nReconciled:     \u003Cartifact value → kept or exact-carrying token, + distance>\nClass list:     \u003Cordered classes>\nInline style:   \u003Conly if runtime-computed; else \"none\">\nExtraction:     \u003Ccomponent | constant | @apply | none — reason>\nRisks:          \u003Carbitrary values, !important, dark-mode gaps>\n```\n\n## Gotcha\n\n- `space-x-*` \u002F `space-y-*` collide with `flex-wrap` and RTL — use\n  `gap-*` on the flex\u002Fgrid parent unless the design demands otherwise.\n- `dark:` variants need a token map in both modes; one-sided dark\n  styling is half a feature.\n- Arbitrary values (`mt-[17px]`) survive Tailwind upgrades but\n  break the design system; they accumulate silently. **Artifact-bound is the\n  exception, not a loophole:** a value the provided design specifies is not\n  accumulation, and step 1's three obligations decide it. An arbitrary value\n  nobody can trace to a source is still the smell this bullet is about.\n- **The carrier is CSS or a utility class; the value is the design's.** Static\n  presentation belongs in CSS \u002F tokens \u002F classes — `style=` is for what only\n  the runtime knows (a computed width, a live transform, a measured offset).\n  Porting an artifact's inline `style=` into classes is therefore expected and\n  is not a deviation, **as long as the resolved value comes out identical**.\n  Changing the carrier is free; changing the number is not.\n- `@apply` inside component CSS interacts with PurgeCSS — keep it\n  in files Tailwind scans, not in vendor CSS.\n- **Anti-AI-slop catalog.** The bullets below are the Tailwind-specific\n  manifestations of the stack-agnostic patterns in\n  [`docs\u002Fguidelines\u002Fdesign-antipatterns.md`](..\u002F..\u002F..\u002Fdocs\u002Fguidelines\u002Fdesign-antipatterns.md)\n  (C1 gradients, T7 fonts, L1\u002FL2 layout, V1 side-stripe). Pull the catalog\n  for the full list; the objective subset (contrast, font-size floor,\n  reduced-motion) is validated via `accessibility-auditor`'s checklist —\n  cite its verdict rather than eyeballing.\n- **Anti-AI-slop: gradients.** Unless audit-pinned or brief-explicit,\n  avoid the default purple-to-blue \u002F cyan-to-pink gradients on white —\n  they read as auto-generated (catalog C1\u002FC2). Reach for a single accent\n  from the token map, or a duotone built from configured tokens.\n- **Anti-AI-slop: typography.** Unless audit-pinned, avoid surfacing\n  the default as the *visible* body face — Inter as a template webfont,\n  or `font-sans` (Arial \u002F Helvetica). If `tailwind.config`\n  pins a font family, use it; if not, treat the missing token as a\n  gap to flag, not a license to ship the OS default.\n- **Anti-AI-slop: layout.** Unless audit-pinned, the centered hero +\n  3-column features + CTA stack is the AI-template tell. Break the\n  grid intentionally (asymmetric column split, overlap, diagonal\n  flow) when the brief allows; cite the design brief's `aesthetic:`\n  line if `fe-design`'s aesthetic-direction section produced one.\n\n## Taste Dials\n\nWhen `DESIGN.md` declares `## Taste Dials`, honour them: Variance → layout-family spread + asymmetry tolerance; Motion → animation budget + reduced-motion posture; Density → spacing scale + information-per-viewport. Absent → follow the design brief's inferred dials.\n\n## Security constraints\n\n`scripts\u002Ftailwind_config_gen.ts` is the only shipped script, started as:\n\n```bash\nnode \u003Cskills-root>\u002Ftailwind-engineer\u002Fscripts\u002Ftailwind_config_gen.mjs \\\n  [--framework react|vue|svelte|nextjs] [--output PATH] [--validate-only]\n```\n\n- **What it may touch** — exactly one file: `--output PATH`, or\n  `tailwind.config.ts` \u002F `.js` in the current working directory when no\n  `--output` is given. It reads nothing from the project.\n- **What it must never do** — write anywhere other than that one path,\n  reach the network, or spawn a subprocess. It does none of these.\n- **Default invocation** — **mutating**, and stated here because it is a\n  real exception rather than a comfortable one: a bare invocation writes\n  `tailwind.config.ts` into `cwd`, overwriting an existing config without\n  prompting. `--validate-only` is the read-only path — it prints the\n  generated config to stdout and writes nothing. Run `--validate-only`\n  first, and pass `--output` when the target is not the cwd default.\n  This default contradicts `skill-writing`'s \"never mutate on a bare\n  invocation\" line; it is recorded rather than silently tolerated, and\n  changing the script's default is a caller-visible behaviour change that\n  belongs in its own change, not here.\n- **Outbound** — nothing. No network access.\n\n## Do NOT\n\n- Do NOT run `tailwind_config_gen` bare in a project that already has a\n  `tailwind.config.*` — it overwrites without asking. Use\n  `--validate-only` first, then `--output` at the intended path.\n- Do NOT add `!important` to win a specificity fight; restructure\n  the cascade or extract the conflicting style.\n- Do NOT introduce a new colour outside `tailwind.config` without\n  also adding the token; one-off hex codes drift the system.\n- Do NOT use `@apply` to avoid utility verbosity inside a single\n  component — extract the component instead.\n- Do NOT ship `style=` for static values; that is a CSS regression\n  the linter will not catch.\n",{"name":5,"packs":57,"domain":59,"personas":60,"model_tier":62,"workspaces":63,"description":7},[58],"engineering-base","engineering",[61],"frontend-engineer","medium",[59],"main","12bd765ce1d800501d45dfb8232102793af01290","src\u002Fskills\u002Ftailwind-engineer",1,"https:\u002F\u002Fgithub.com\u002Fevent4u-app\u002Fagent-config","https:\u002F\u002Fevent4u.app","https:\u002F\u002Fgithub.com\u002Fevent4u-app","Your events in your hand","2026-11-13 03:25:49",{"source":8,"skillName":5,"commands":74,"prompt":84,"zipAvailable":85},[75,78,81],{"tool":76,"command":77},"npx","npx skills add event4u-app\u002Fagent-config --skill tailwind-engineer",{"tool":79,"command":80},"bunx","bunx skills add event4u-app\u002Fagent-config --skill tailwind-engineer",{"tool":82,"command":83},"pnpm","pnpm dlx skills add event4u-app\u002Fagent-config --skill tailwind-engineer","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fevent4u-app\u002Fagent-config\u002Fblob\u002Fmain\u002Fsrc\u002Fskills\u002Ftailwind-engineer\u002FSKILL.md",true,[87,93,99],{"path":88,"resourceType":89,"resourceTypeDesc":90,"sizeBytes":91,"sourceHtmlUrl":92},"evals\u002Ftriggers.json","REFERENCE","参考文档",1594,"https:\u002F\u002Fgithub.com\u002Fevent4u-app\u002Fagent-config\u002Fblob\u002Fmain\u002Fsrc\u002Fskills\u002Ftailwind-engineer\u002Fevals\u002Ftriggers.json",{"path":94,"resourceType":95,"resourceTypeDesc":96,"sizeBytes":97,"sourceHtmlUrl":98},"scripts\u002Ftailwind_config_gen.mjs","SCRIPT","脚本",14369,"https:\u002F\u002Fgithub.com\u002Fevent4u-app\u002Fagent-config\u002Fblob\u002Fmain\u002Fsrc\u002Fskills\u002Ftailwind-engineer\u002Fscripts\u002Ftailwind_config_gen.mjs",{"path":100,"resourceType":95,"resourceTypeDesc":96,"sizeBytes":101,"sourceHtmlUrl":102},"scripts\u002Ftailwind_config_gen.ts",20543,"https:\u002F\u002Fgithub.com\u002Fevent4u-app\u002Fagent-config\u002Fblob\u002Fmain\u002Fsrc\u002Fskills\u002Ftailwind-engineer\u002Fscripts\u002Ftailwind_config_gen.ts",[104,120,132,144,156,166],{"skillNo":105,"name":106,"nameZh":6,"description":107,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":113,"publishedAt":52},"01M6X84PK96XBPENXH66JCTSD1","unknown-key-fixture","Declares a key the schema does not know.","https:\u002F\u002Fgithub.com\u002Fevent4u-app\u002Fagent-config\u002Fblob\u002Fmain\u002Ftests\u002Fscripts\u002Ffixtures\u002Fbody-portable\u002Funknown-key\u002FSKILL.md",[110],{"categoryNo":111,"categoryName":112,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[114,115,116,117,118,119],"unknown key fixture","Unknown key","fixture","unknown","schema","package",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":127,"publishedAt":52},"01M6X84HW7NAHZ7GZMQ9RXK1XJ","portable-fixture","Declares only semantics the MCP-lite carrier transports whole.","https:\u002F\u002Fgithub.com\u002Fevent4u-app\u002Fagent-config\u002Fblob\u002Fmain\u002Ftests\u002Fscripts\u002Ffixtures\u002Fbody-portable\u002Fportable\u002FSKILL.md",[126],{"categoryNo":111,"categoryName":112,"taxonomyType":21,"taxonomyTypeDesc":22},[116,128,129,34,130,119,131],"portable","portable fixture","only","MCP",{"skillNo":133,"name":134,"nameZh":6,"description":135,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":136,"categories":137,"keywords":139,"publishedAt":52},"01M6X84F29FE0RGGZ1ZTFGZTX2","non-portable-fixture","Declares a runtime semantic the carrier drops.","https:\u002F\u002Fgithub.com\u002Fevent4u-app\u002Fagent-config\u002Fblob\u002Fmain\u002Ftests\u002Fscripts\u002Ffixtures\u002Fbody-portable\u002Fnon-portable\u002FSKILL.md",[138],{"categoryNo":111,"categoryName":112,"taxonomyType":21,"taxonomyTypeDesc":22},[129,140,128,116,141,142,143,119],"non portable fixture","semantic","high","runtime",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":148,"categories":149,"keywords":151,"publishedAt":52},"01M6X848F706PT9MDCX75JKJ6B","candidate-zero-width","A candidate whose prose carries an invisible joiner.","https:\u002F\u002Fgithub.com\u002Fevent4u-app\u002Fagent-config\u002Fblob\u002Fmain\u002Ftests\u002Ffixtures\u002Fskill-scout-candidates\u002Fzero-width-injection\u002FSKILL.md",[150],{"categoryNo":111,"categoryName":112,"taxonomyType":21,"taxonomyTypeDesc":22},[152,153,154,155],"candidate zero width","candidate","ZeRO","prose",{"skillNo":157,"name":158,"nameZh":6,"description":159,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":160,"categories":161,"keywords":163,"publishedAt":52},"01M6X841SSC2T31VDF41SA6DG1","candidate-disclosure-suppression","A candidate whose prose tells the agent to withhold from the user.","https:\u002F\u002Fgithub.com\u002Fevent4u-app\u002Fagent-config\u002Fblob\u002Fmain\u002Ftests\u002Ffixtures\u002Fskill-scout-candidates\u002Fdisclosure-suppression\u002FSKILL.md",[162],{"categoryNo":111,"categoryName":112,"taxonomyType":21,"taxonomyTypeDesc":22},[164,153,155,165],"candidate disclosure suppression","user",{"skillNo":167,"name":168,"nameZh":6,"description":169,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":170,"categories":171,"keywords":173,"publishedAt":52},"01M6X83TFS5AGPBPVTQNWP0BB3","candidate-dangerous-frontmatter","A candidate claiming an unscoped tool grant and a permission bypass.","https:\u002F\u002Fgithub.com\u002Fevent4u-app\u002Fagent-config\u002Fblob\u002Fmain\u002Ftests\u002Ffixtures\u002Fskill-scout-candidates\u002Fdangerous-frontmatter\u002FSKILL.md",[172],{"categoryNo":111,"categoryName":112,"taxonomyType":21,"taxonomyTypeDesc":22},[174,153,175,176,177,178],"candidate dangerous frontmatter","frontmatter","shell","permission","tool"]