ACSS蚀刻

gdcrosbie2026-10-27查看 1513复制 537

通过蚀刻连接器在Etch + Automatic.css站点( WordPress或Etch Studio )上应用样式合同和ACSS v4令牌规则。在编写或审阅CSS、选择ACSS令牌、命名BEM类或调试Etch中以错误或无提示方式呈现的样式时使用。涵盖CSS所在的位置(每个元素样式层与全局样式表) ,如何通过连接的构建器选项卡和Etch运行时CSS getchas读取安装生成的令牌。

Download (.md)

📘如何使用这个技能

  1. 1
    复制技能内容·点击上方「Copy SKILL.md」复制全部内容,或 Download 下载到本地
  2. 2
    打开你的 AI 客户端·支持 Claude Code、Trae、Cursor、ChatGPT、DeepSeek、Kimi 等任意 AI 助手
  3. 3
    粘贴为系统提示/知识文件·Claude Code:放入 .claude/skills/ 目录;普通对话:作为首条消息发送并说「请严格按这份技能文档执行」
  4. 4
    直接提出你的需求·AI 会按技能定义的工作流、格式和约束来处理,无需再解释背景

💡 提示:技能生效后,每次对话只需一句需求,AI 会按 SKILL.md 的流程执行。

SKILL.md13965 chars
---
name: etch-acss
description: Apply the styling contract and ACSS v4 token rules on Etch + Automatic.css sites (WordPress or Etch Studio) through the Etch Connector. Use when writing or reviewing CSS, choosing ACSS tokens, naming BEM classes or debugging styles that render incorrectly or silently no-op in Etch. Covers where CSS lives (per-element styles layer vs global stylesheets), how to read the install's generated tokens through a connected builder tab and the Etch runtime CSS gotchas.
---

# Etch + ACSS through the Etch Connector (Styling Contract & Token Resolution)

For WordPress and Etch Studio sites built with **Etch** (HTML-first builder by Digital Gravy) styled with **Automatic.css (ACSS)**, read and edited through the **Etch Connector** (`@digital-gravy/etch-connector`). Work at the code/CSS level — the per-element style layer, ACSS variable internals and CSS at-rule placement constraints. Pitch technically: show the CSS, tokens, and structure rather than explaining basics.

## 0. Connect before doing anything

**The Etch Connector is not an MCP server.** It's a local relay (ws 7331 / control http 7332)
driven over **Bash** — `curl http://127.0.0.1:7332/eval` or `etch-connector eval`. Its absence
from the MCP tool list means nothing; never conclude it's unavailable from a tool search. Check
it with `curl -s http://127.0.0.1:7332/tabs`: `{"tabs":[]}` means the relay is up but no builder
tab has registered (fix: `etch.connectAs('<name>')` in the tab console); connection refused means
the relay itself is down. Without a connected tab, say so and stop rather than guessing at the
site's tokens or styles.

For the Connector's setup, namespaces, signatures, block types and error codes, use its own
documentation and the Etch type definitions (see `references/upstream-docs.md`).

**Etch Studio vs Etch for WordPress.** Check `environment.product` in the `/tabs` response (or
`etch.environment.product`). When it is `"etch-studio"`, immediately read the host's built-in
skill: call `etch.skills.list()` to confirm it's listed under that name, then
`etch.skills.get("etch-studio")` (synchronous; it returns `undefined` if the skill is absent), and
load its references with `etch.skills.getReference("etch-studio", "<file>")` only when needed.
Skip all WordPress-only assumptions (`etch.loops`, `etch.fields`). In Studio, repeaters use `etch.dataSources` + `etch/loop`
(`target: "data('key')"`, `itemId: "item"`). Build `2026.10.16.1638` also exposes native
`etch.content`, routes/templates and `openTemplateAsync`; native content is consumed through
JavaScript `queryContent()` sources. There is no `etch.assets` API or WordPress attachment
store. Asset Manager supports saved alt metadata and numeric image IDs in this build; Image
content fields and responsive images depend on project settings. Asset URLs differ between the Studio
preview and a published Cloudflare site:
- **Published site (Cloudflare):** served at root-relative `/assets/{filename}`.
- **Studio preview (`studio.etchbuilder.io`):** served at `/{workspace}/{project}/assets/{filename}`.
- **Never use the full `https://studio.etchbuilder.io/.../assets/{filename}` URL** (which Asset
  Manager's "Copy URL" button copies): on Cloudflare it fails with **CORS errors** on `@font-face`
  and **`403 Forbidden`** on `<img>` because `studio.etchbuilder.io` is authenticated and omits
  `Access-Control-Allow-Origin: *`. For `<img src>` and ACSS Custom Fonts settings, use
  root-relative `/assets/{filename}`; for `@font-face` rules that must render in **both** Cloudflare
  and the Studio canvas without CORS errors, list both root-relative paths in `src:`:
  `src: url("/assets/font.woff2") format("woff2"), url("/{workspace}/{project}/assets/font.woff2") format("woff2");`.
- **SEO & `<head>` metadata (`etch/head`):** Without WordPress SEO plugins, document `<head>` tags
  are authored inside a root-level `etch/head` block (`type: "etch/head"`) using `etch/element`
  children (`<title>`, `<meta name="description">`, `<meta name="robots" content="noindex, nofollow">`,
  Open Graph / Twitter `<meta>`, and `<link rel="preload">` for critical `.woff2` fonts). Studio
  does **not** auto-generate a `/sitemap.xml` (omit sitemaps on `noindex` demos; for indexable sites,
  generate from `await etch.navigation.listPostsAsync()`, upload to Asset Manager as
  `/assets/sitemap.xml` + `<link rel="sitemap">`, or serve via a Cloudflare route). **Never place
  `<script type="application/ld+json">{...}</script>` inside `etch/raw-html` or `etch/text`** —
  Etch's expression parser treats the JSON `{...}` braces as template expressions (stripping the
  JSON payload to `""`) and escapes the remaining `<script>` tag as literal text in `<body>`. To
  emit JSON-LD on an indexable page, either return the JSON string from a data source expression
  (`{data('seo').jsonLd}`) or inject the `<script type="application/ld+json">` node into
  `document.head` from a block's `script.code`.

**The open builder owns the page.** It holds the document in memory and autosaves over the stored
copy, and `saveAsync()` rewrites the **entire** document (post_content + stylesheets) from that
in-memory state. Anything that changes a page's stored content outside the builder while a tab is
open on it — another tool, the WordPress editor, a REST call — is silently overwritten. Make
structural edits through the Connector, or close every tab for that page first (`/tabs` returns
`{"tabs":[]}`) and reopen afterwards. Styles and global stylesheets live in separate stores, and
writes are absolute, so pushing the full correct value re-aligns a stale tab.

## 1. The styling contract

Durable methodology — does not vary by tool.

- **Custom BEM classes:** use descriptive names (`.hero`, `.hero__title`, `.hero--compact`).
  A brand/project prefix is optional: `.acme-hero__title` is also valid. Do not require a prefix
  decision before building or automatically prefix every class. Follow explicit project
  instructions and preserve existing class names; do not rename a working build to adopt this rule.
- **Reusable components:** take the naming convention (e.g. a generic prefix such as `c-`) from
  your agent instructions or the project's existing convention; if neither sets one, ask once. Neither ACSS nor Etch requires one.
- **Check class names before creating selectors:** inspect the project's existing custom
  classes and style records before introducing a custom class. Include class tokens on existing
  blocks/components even when they have no separate style record; compare tokens, not just full
  selectors (`.hero:hover` still uses `.hero`). Cache the available inventory once per build,
  keep it updated as classes are added, and refresh it if other edits make it stale.
  If a proposed name already belongs to a different component or styling purpose, **stop before
  writing and ask the user** whether to reuse it, rename the new class, or modify the existing
  implementation. Intentional reuse, authorised updates to the same component, and expected
  ACSS class reuse (`btn--primary`, etc.) do not require another decision. Do not silently
  overwrite an unrelated style or rely on `etch.styles.create()` to resolve a duplicate.
- **CSS written with generated ACSS variables** — verify the exact property on the live install
  before using it. Token fallbacks are off for client-site builds and on for deliberately
  distributable patterns; never mix the two policies within one deliverable.
- **Attach styles to the element**, via the per-element styles layer (`etch.styles`). Not a global
  stylesheet. Not inline `style=""`.
- **Global stylesheets are for document-level at-rules only** — `@property`, `@keyframes`,
  `@font-face`, `@custom-media` (Etch has a dedicated `@custom-media` sheet type) — because the
  styles layer can't hold them. Everything else goes per-element.
  Before writing to a global sheet: **ask which sheet.** Default to a purpose-named sheet
  ("Base Reset", "Animated Hero"), never a catch-all Main.
- **Custom classes over ACSS utilities.** Standing exceptions:
  - **`btn--*`** button component classes — use directly, never restyle a button from scratch.
  - **`bg--*` section backgrounds** (`bg--ultra-light`/`light`/`dark`/`ultra-dark`) — they carry
    ACSS **Automatic Color Relationships**, so foreground adapts on scheme switches and when the
    class is swapped. Raw `background: var(--bg-*)` does not trigger them, and is correct only for
    non-contextual surfaces (cards, panels, placeholders) where you manage foreground yourself.
    *Corollary:* don't hand-assign text colours the relationships already provide — explicit colour
    tokens are for deliberate accents only. In particular, **never set `color: var(--heading-color)`
    on a heading class inside `.bg--dark` or `.bg--ultra-dark`**: ACSS sets
    `--heading-color: var(--text-dark)` on `:root` and uses
    `.bg--dark :where(h1, h2, h3, h4, h5, h6) { color: var(--relative-heading-color, inherit); }`
    (specificity `0,1,0`) rather than redefining `--heading-color` inside dark sections, so
    `color: var(--heading-color)` on `.card__title` overrides the `:where()` relationship rule and
    renders dark text on a dark surface (use `var(--relative-heading-color)` or `var(--text-light)`
    if a dark-surface card needs an explicit heading colour).
  - Fold `section--*`, `text--*`, and other utilities into custom classes as `var(--…)`
    declarations.
- CSS nesting (`&:hover`, `&::before`, `@media` inside a selector) is fine and expected.
- **Tree-shaking:** JS-added runtime classes (`.is-open`, `.is-active`) must be nested under their
  parent's existing selector, not written as top-level rules — see `references/css-and-responsive.md`.
- **CPT/taxonomy slugs are not BEM classes.** Don't derive them from a class prefix by reflex;
  check whether a CPT with that slug already exists and report it before registering a new one.

## 2. Never recall tokens from memory

Read the live install through the connected tab. Token availability varies by ACSS version and
per-site config, so there is no cross-site answer — only what this install generated:

1. **`etch.skills.getReference("acss", "tokens.md")`** — first-party, already resolved, and scoped
   to the page being edited. Its sibling references (`colors.md`, `spacing.md`, `typography.md`,
   `grids.md`, `buttons.md`, …) cover usage. Two traps: the `acss` skill's own description points
   at a non-existent `settings.md`, and writes `var(--color-primary)` where ACSS actually has no
   prefix.
2. **In Etch Studio (`environment.product === "etch-studio"`): discover the `"ACSS Framework"`
   sheet with `etch.stylesheets.list()`, then read `etch.stylesheets.get(framework.id).css`.**
   IDs are project-specific (both `"3"` and `"4"` have been seen), so never hard-code one. Stop and inspect the list if the name is missing or ambiguous. The generated
   sheet is read-only. `etch.styles.setVariable()` writes to `etch-global-variable-style`;
   verify its precedence against the framework before relying on an override (see
   [Studio cascade gotchas](references/etch-runtime-gotchas.md#etch-studio-framework-cascade-and-button-rules)).

**`etch.styles.list()` is not a token inventory.** It lists style records, not what ACSS generated.
Neither is [`references/acss-complete-reference.md`](references/acss-complete-reference.md): it
says a name is spellable in ACSS 4, not that this install generated it.

**CSS-wide keywords are not stored token text.** `--link-color: inherit` inherits the custom
property itself; it does not make a consuming `color: var(--link-color, var(--primary))` become
`color: inherit`. At the root with no inherited value, the fallback can win. Use a verified colour
token or a scoped `color: inherit` declaration on the consuming element. Worked example:
[custom-property keyword trap](references/etch-runtime-gotchas.md#css-wide-keywords-on-custom-properties).

## 3. Verify against the frontend, not the thing you just wrote

Order of authority when sources disagree:
1. **The live rendered page** — fetch it and grep the compiled CSS.
2. **Project memory** — site-specific facts, versions, in-flight work.
3. **This skill** — cross-site defaults.

**Etch ships its own reset** as `@layer etch-reset` — box-sizing, universal `margin: 0`, list
styles, media sizing, `font: inherit` on form controls, button reset. Check it before writing
any reset CSS; most hand-written resets are redundant with it.

## References

| File | When |
|---|---|
| [`references/step0-acss-config.md`](references/step0-acss-config.md) | Resolving the install's ACSS config before a build and mapping design colours/scales by role |
| [`references/acss-tokens.md`](references/acss-tokens.md) | Quick token rules & compile-time vs runtime distinction (`to-rem()`, `--white`) |
| [`references/acss-design-system.md`](references/acss-design-system.md) | ACSS v4 deep dive: colours, spacing, typography, buttons, cards, grids, icons |
| [`references/css-and-responsive.md`](references/css-and-responsive.md) | Per-element CSS authoring, tree-shaking for JS classes, `@container`/`@custom-media`, and layout recipes |
| [`references/etch-runtime-gotchas.md`](references/etch-runtime-gotchas.md) | Something renders wrong or silently no-ops in CSS |
| [`references/upstream-docs.md`](references/upstream-docs.md) | Locating official ACSS and Etch TypeScript/doc clones |
| [`references/acss-complete-reference.md`](references/acss-complete-reference.md) | Checking that a class or variable name is spellable in ACSS 4 (not that the install generated it) |
| [`scripts/gen-acss-reference.py`](scripts/gen-acss-reference.py) | Regenerating that reference from a plugin's `framework.json` after an ACSS update |
| [`../accessibility-audit/SKILL.md`](../accessibility-audit/SKILL.md) | WCAG 2.2 audit of a rendered Etch page, including ACSS contrast and focus checks |
来源:skillsdirectory

评论0

登录后参与评论

还没有评论,来抢沙发吧