一、④段整套同步(用户选候选 A)
- 新增 `references/stage-proto-doc/assets/产品文档模板.html`(16 KB/247 行,从备份拷、转 LF)。
- ④段 SKILL.md 换成备份 15:28 那版,并按模板口径改齐:
· 「产品文档框架」从「四块+一附录」改成**六节** —— 页面结构/功能清单/使用场景/操作流程/
跨页与界面状态/待确认与偏离;与模板同构,⛔ 不从空白页重写结构。
· 编号从 R/S/F 改成 **P 页面/S 场景/F 功能/J 二级功能**,各自唯一、按展示顺序通排。
· 保留旧版有价值的要求:每项功能补齐 做什么/入口在哪/输入边界/异常与恢复;重点功能三处标红;
横向流程图每步写清页面/功能/操作/完成判据。
· 完成标准「七节」→「六节」,自查清单同步换掉「需求」那批条目,补模板与配图两条。
· 路径 `designs/<项目>/` → `docs/pm/<项目>/ui/`(2 处)。
· 补回本机那条「每份产出文档开头都要有一张图」的引用(指向主 skill,段内不复述)。
- 主 skill 同步:四段结构表④行、④段沿革、画图小节(④段画页面结构图 + 用户路径)。
二、open-design 移到技能根(用户选候选 A)
- `git mv product-planning/references/stage-delivery/assets/open-design → open-design/`(4178 文件)。
- `.gitignore` 白名单加 `!/open-design/` —— 否则移出去就不再纳入版本控制。
- 引用改 11 处:路径形态 `assets/open-design/...` → `<技能根>/open-design/...`;
「随段携带的自带件」改称「同根技能」;「路径怎么找」那条改成自带件(段内相对路径)与
同根技能(`<技能根>/<技能名>/`)两类分开写。
- open-design 自己的 ATTRIBUTION.md 两处同步(它现在与 oil-ui-pro 同层)。
- 副作用(有益):命名闸门读数由 2063 降到 225 —— 此前它把 open-design 里 919 个第三方 md
当成规则一起扫了;现在只扫本包 23 个 md。已确认④段的 H1 与 4a/4b/4c 子步仍在检查范围内。
三、验收
- check_naming.py --ws E:/ProgramData/AIProject/contentm_agent = 通过 225 / 失败 0 / 提示 27。
- 活文件里 `assets/open-design` 残留 0;工作区 CRLF 文件 0。
354 lines
21 KiB
CSS
354 lines
21 KiB
CSS
/* ─────────────────────────────────────────────────────────────────────────
|
||
* design-systems/resend/tokens.css
|
||
*
|
||
* Structured token bindings for "Resend" — the developer-first email
|
||
* API whose marketing surface treats a pure-black canvas like a
|
||
* gallery wall and lights every container with a single, icy blue-
|
||
* tinted hairline.
|
||
*
|
||
* Brand identity in three sentences:
|
||
* 1. Void-black (#000000) canvas with near-white (#f0f0f0) ink —
|
||
* theatrical darkness; the page is the stage and content
|
||
* performs on it without competing chrome.
|
||
* 2. Frost borders (rgba(214, 235, 253, 0.19)) replace gray borders
|
||
* everywhere — every divider, button, card, and tab is a thin
|
||
* icy line on the void; depth is by border luminance, not by
|
||
* blur shadows that cannot cast against pure black.
|
||
* 3. ABC Favorit (geometric sans) for display headings with
|
||
* aggressive negative tracking, Inter for body and UI, Commit
|
||
* Mono for code — one accent at a time (here: Resend Orange
|
||
* #ff801f) so the chromatic moment lands hard against the gray.
|
||
*
|
||
* Brand-specific schema decisions (each one bends a schema convention
|
||
* to match Resend's voice rather than the cross-brand default):
|
||
*
|
||
* 1. `--bg` and `--surface` both bind to `#000000`. DESIGN.md §7 is
|
||
* explicit: "Don't lighten the background above #000000 — the
|
||
* pure black void is non-negotiable." Cards on Resend do not
|
||
* lift via fill; they read by their frost border alone. Setting
|
||
* `--surface` to the same void as `--bg` honors that rule and
|
||
* forces every card-like component to express elevation through
|
||
* `--border` / `--elev-ring`, not through tinted backgrounds.
|
||
* `--surface-warm` aliases to `--surface` because the brand has
|
||
* no warm tier — there is no second background color anywhere.
|
||
*
|
||
* 2. `--border` is `rgba(214, 235, 253, 0.19)` — the literal
|
||
* "frost border" alpha named in DESIGN.md §1 as "the signature"
|
||
* of the entire system. Binding the slot to the alpha (not a
|
||
* solid hex) lets `--elev-ring` (`0 0 0 1px var(--border)`)
|
||
* reproduce the icy line by default, and lets every component
|
||
* reach the same value via `border: 1px solid var(--border)`.
|
||
* `--border-soft` drops to `rgba(217, 237, 254, 0.145)` for
|
||
* inner row separators that should not compete with the
|
||
* container's outer frost edge.
|
||
*
|
||
* 3. `--fg` is `#f0f0f0`, not `#ffffff`. DESIGN.md §2 names this
|
||
* the "Near White" — a deliberately softened text tier that
|
||
* lets pure white (`#ffffff`) stay reserved for the maximum-
|
||
* emphasis moments DESIGN.md describes as "link highlights"
|
||
* and the white-pill CTA. The four-level foreground ramp
|
||
* (`#f0f0f0 → #a1a4a5 → #5c5c5c → #464a4d`) maps directly onto
|
||
* DESIGN.md §2's documented neutral scale (Near White, Silver,
|
||
* Mid Gray, Dark Gray) so `--fg-2` and `--meta` are
|
||
* independently bound rather than aliased.
|
||
*
|
||
* 4. `--accent` is Resend Orange (`#ff801f`, "Orange 10" in
|
||
* DESIGN.md §2). Resend's product surface uses a multi-color
|
||
* accent system (orange/green/blue/yellow/red), but the shared
|
||
* schema slot must pick one — and Orange 10 is the only entry
|
||
* DESIGN.md prefixes with "primary orange accent". The blue
|
||
* and green variants live as semantic / inline values in
|
||
* components.html; promoting any of them to a second accent
|
||
* slot would require a C-extension, which the brand contract
|
||
* defers until ≥2 brands need the same name. `--accent-on` is
|
||
* `#000000` because saturated orange against black reads best
|
||
* with black labels (DESIGN.md §4 confirms the white-pill
|
||
* pattern is for `#ffffff` solid backgrounds, not for the
|
||
* orange accent fill).
|
||
*
|
||
* 5. `--accent-hover` brightens toward white (10%) and
|
||
* `--accent-active` darkens toward black (12%) — the inverse
|
||
* of the schema's default mid-luminance pattern. On Resend's
|
||
* void canvas, a "pressed" state reads as a small recession
|
||
* into the dark, while a "lifted" hover reads as a luminance
|
||
* step up. This matches the Linear / dark-system convention
|
||
* and avoids the schema default's all-darken pattern that
|
||
* would make the orange disappear into the void on hover.
|
||
*
|
||
* 6. Semantic colors come straight from DESIGN.md §2's multi-
|
||
* color accent scale — `--success: #11ff99` (Green 4),
|
||
* `--warn: #ffc53d` (Yellow 9), `--danger: #ff2047` (Red 5).
|
||
* These are the saturated source values; components that want
|
||
* the documented "12–42% opacity" tints reach them via
|
||
* `color-mix(in oklab, var(--success), transparent 80%)` in
|
||
* situ, keeping the alpha-blend decision at the component
|
||
* layer rather than in the token slot.
|
||
*
|
||
* 7. Type scale is documented in DESIGN.md §3: 96px display,
|
||
* 56px section, 24px feature title, 20px sub-heading, 18px
|
||
* body-large, 16px body, 14px caption, 12px small. The schema
|
||
* has 8 slots; `--text-2xl` is bound to `36px` as the
|
||
* intermediate that bridges 24px (feature title) to 56px
|
||
* (section heading) — DESIGN.md does not enumerate this stop,
|
||
* but a 24 → 56 jump without a mid-tier would force every H2
|
||
* to either undershoot or overshoot. `--leading-tight: 1.0`
|
||
* matches the documented Display Hero rhythm; `--leading-body:
|
||
* 1.5` matches the documented Body / Body Large / Feature
|
||
* Title leading.
|
||
*
|
||
* 8. `--tracking-display` is `-0.05em`, derived from DESIGN.md
|
||
* §3 Section Heading (`-2.8px at 56px = -0.05em`). ABC Favorit
|
||
* compresses harder than Domaine Display (`-0.01em` at 96px),
|
||
* so binding the slot to the ABC Favorit characteristic value
|
||
* gives every display-tier element the brand's "engineered
|
||
* masthead" feel. The hero in components.html can opt back
|
||
* into the gentler Domaine tracking inline if needed.
|
||
*
|
||
* 9. `--font-display` lists ABC Favorit first, with Inter as the
|
||
* structural fallback. Inter is documented in DESIGN.md §3 as
|
||
* the body / UI font, but it shares the geometric voice well
|
||
* enough to carry display weight when ABC Favorit is not
|
||
* loaded — far better than falling through to a generic system
|
||
* sans. Domaine Display (the editorial serif hero font) is
|
||
* deliberately not in the stack: it is a paid Klim Type
|
||
* Foundry face whose absence would surface as a jarring serif
|
||
* drop. Heroes that want Domaine layer it in via
|
||
* `font-family: "Domaine Display", var(--font-display)` at the
|
||
* component level.
|
||
*
|
||
* 10. Section rhythm is generous: 120px desktop, 80px tablet, 48px
|
||
* phone. DESIGN.md §5 names "Cinematic black space" with "80–
|
||
* 120px+ vertical spacing between sections" as a defining
|
||
* property — "the black background IS the whitespace". 120px
|
||
* desktop sits at the top of that documented range.
|
||
*
|
||
* 11. `--radius-sm` is `4px` (DESIGN.md "Sharp": buttons-ghost,
|
||
* inputs); `--radius-md` is `8px` (tabs / content blocks);
|
||
* `--radius-lg` is `16px` (feature cards / images / main
|
||
* buttons); `--radius-pill` is `9999px` (primary CTAs / tags
|
||
* / badges). The 24px "Section" radius from DESIGN.md is
|
||
* component-specific (large panels) and reached inline rather
|
||
* than via the shared schema.
|
||
*
|
||
* 12. `--elev-raised` layers the documented `rgba(176, 199, 217,
|
||
* 0.145) 0 0 0 1px` ring shadow with the subtle drop from
|
||
* DESIGN.md §6 Level 2. On pure black, opaque blur shadows
|
||
* vanish — the ring carries the edge, and the soft drop adds
|
||
* just enough atmospheric tint to read as "lifted" against
|
||
* the void. Never strip the ring when overriding this token.
|
||
*
|
||
* 13. `--focus-ring` is a sharp 2px ring at `var(--accent)`, not
|
||
* the schema's 3px alpha glow. DESIGN.md §6 Level 3 documents
|
||
* a heavy 8px black focus ring that works in product context
|
||
* (against non-black surroundings); on this brand fixture the
|
||
* black canvas would swallow that ring, so we substitute the
|
||
* orange accent at 2px — sharp, engineered, legible against
|
||
* both the void and any card surface.
|
||
*
|
||
* 14. `--container-max` caps at `1200px` with generous 32px
|
||
* desktop gutters — Resend's marketing pages center contained
|
||
* content in vast dark space, treating the gutter as part of
|
||
* the gallery margin rather than as edge-bleed.
|
||
*
|
||
* Source contracts:
|
||
* - Standard token names: design-systems/_schema/tokens.schema.ts
|
||
* - A2 fallback parity: design-systems/_schema/defaults.css
|
||
* - Lint enforcement: apps/daemon/src/lint-artifact.ts
|
||
*
|
||
* Keep this file additive: never invent token names not also
|
||
* documented in DESIGN.md or the schema. ABC Favorit, Domaine
|
||
* Display, and Commit Mono are paid faces — the stacks list
|
||
* defensible OS fallbacks so artifacts render legibly even when
|
||
* the brand faces are not loaded.
|
||
* ─────────────────────────────────────────────────────────────────── */
|
||
|
||
:root {
|
||
/* ─── Surface (3 levels — schema slot) ─────────────────────────────
|
||
* The void is the canvas. DESIGN.md §7: "Don't lighten the
|
||
* background above #000000 — the pure black void is non-
|
||
* negotiable." `--surface` matches `--bg` because cards on Resend
|
||
* read by their frost border alone, not by a tinted fill.
|
||
* `--surface-warm` aliases to surface — the brand has no second
|
||
* background color anywhere. */
|
||
--bg: #000000;
|
||
--surface: #000000;
|
||
--surface-warm: var(--surface); /* alias — Resend has no warm tier */
|
||
|
||
/* ─── Foreground ramp (4 levels) ──────────────────────────────────
|
||
* Near White → Silver → Mid Gray → Dark Gray, the documented
|
||
* neutral scale from DESIGN.md §2. `#f0f0f0` instead of `#ffffff`
|
||
* matters — pure white is reserved for the white-pill CTA and link
|
||
* highlights; the softened near-white keeps body type calm against
|
||
* the void. All four tiers are independently bound (not aliased)
|
||
* because DESIGN.md names four distinct neutral roles: primary
|
||
* text, secondary / link-muted, hover / caption, tertiary /
|
||
* quaternary timestamp. */
|
||
--fg: #f0f0f0; /* Near White — primary text, button labels */
|
||
--fg-2: #a1a4a5; /* Silver — secondary text, muted links */
|
||
--muted: #5c5c5c; /* Mid Gray — captions, hover, subtle emphasis */
|
||
--meta: #464a4d; /* Dark Gray — tertiary text, timestamps */
|
||
|
||
/* ─── Border (2 levels) ──────────────────────────────────────────
|
||
* Frost-as-border is THE signature: `rgba(214, 235, 253, 0.19)`
|
||
* at 1px replaces every gray border in the system. Binding
|
||
* `--border` to the alpha (not a solid hex) lets `--elev-ring`
|
||
* reproduce the icy line by default, and lets
|
||
* `border: 1px solid var(--border)` paint the same value when a
|
||
* real CSS border is structurally required (e.g. the bottom edge
|
||
* of the sticky nav per DESIGN.md §4). `--border-soft` drops to
|
||
* `0.145` alpha for inner row separators that must not compete
|
||
* with the container's outer frost edge. */
|
||
--border: rgba(214, 235, 253, 0.19); /* signature frost border alpha */
|
||
--border-soft: rgba(217, 237, 254, 0.145); /* inner row separator — lighter frost */
|
||
|
||
/* ─── Accent ─────────────────────────────────────────────────────
|
||
* Resend Orange (Orange 10 from DESIGN.md §2). Hard cap of ≤2
|
||
* visible uses per screen — DESIGN.md §7 forbids cross-mixing
|
||
* accent colors within a single component. The multi-color
|
||
* scale (green/blue/yellow/red) lives at the semantic / inline
|
||
* layer; only the orange slot rides on `--accent`.
|
||
*
|
||
* `--accent-on` is BLACK, not white — saturated #ff801f against
|
||
* black reads cleanest with black labels (the white-pill CTA in
|
||
* DESIGN.md §4 uses #ffffff fill with #000000 text, not the
|
||
* orange accent). Hover brightens 10% toward white, active
|
||
* darkens 12% toward black — the inverse of the schema's all-
|
||
* darken default, matching the dark-theme convention where
|
||
* "pressed" reads as recession into the void. */
|
||
--accent: #ff801f; /* Resend Orange — primary chromatic accent */
|
||
--accent-on: #000000; /* black label on saturated orange fill */
|
||
--accent-hover: color-mix(in oklab, var(--accent), white 10%);
|
||
--accent-active: color-mix(in oklab, var(--accent), black 12%);
|
||
|
||
/* ─── Semantic ───────────────────────────────────────────────────
|
||
* Saturated source values from DESIGN.md §2's multi-color accent
|
||
* scale. Components reach the documented 12–42% opacity tints
|
||
* via `color-mix(in oklab, var(--success), transparent 80%)` in
|
||
* situ, keeping the alpha-blend decision at the component layer. */
|
||
--success: #11ff99; /* Green 4 — emerald success indicator */
|
||
--warn: #ffc53d; /* Yellow 9 — warm gold warning */
|
||
--danger: #ff2047; /* Red 5 — error / destructive */
|
||
|
||
/* ─── Typography ─────────────────────────────────────────────────
|
||
* Three-font editorial hierarchy from DESIGN.md §3. ABC Favorit
|
||
* carries display; Inter carries body and UI; Commit Mono
|
||
* carries code and technical labels. Domaine Display (the
|
||
* editorial serif hero face) is intentionally not in the
|
||
* `--font-display` stack — it is a paid Klim Type Foundry face
|
||
* whose absence would surface as a jarring serif drop. Heroes
|
||
* that want Domaine layer it in via `font-family: "Domaine
|
||
* Display", var(--font-display)` at the component level. */
|
||
--font-display: "ABC Favorit", "Inter", -apple-system, system-ui, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
|
||
--font-body: "Inter", -apple-system, system-ui, "Segoe UI", "Helvetica Neue", Arial, sans-serif;
|
||
--font-mono: "Commit Mono", "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Monaco, Consolas, monospace;
|
||
|
||
/* Type scale (px) — derived from DESIGN.md §3 hierarchy table.
|
||
* 12 / 14 / 16 / 18 / 20 / 24 / 56 / 96 are all documented; the
|
||
* 36px `--text-2xl` is the synthesized intermediate that bridges
|
||
* 24px feature-title to 56px section-heading. Without it, every
|
||
* H2 would have to undershoot at 24 or overshoot at 56 and the
|
||
* type rhythm would jump. */
|
||
--text-xs: 12px; /* Small — tags, meta, fine print */
|
||
--text-sm: 14px; /* Caption, button, nav link */
|
||
--text-base: 16px; /* Body — standard reading */
|
||
--text-lg: 20px; /* Sub-heading — ABC Favorit */
|
||
--text-xl: 24px; /* Feature Title — Inter weight 500 */
|
||
--text-2xl: 36px; /* Synthesized H2 — bridges 24 → 56 */
|
||
--text-3xl: 56px; /* Section Heading — ABC Favorit */
|
||
--text-4xl: 96px; /* Display Hero — Domaine / ABC Favorit */
|
||
|
||
/* Leading + tracking.
|
||
* --leading-body 1.5: DESIGN.md body / feature-title / body-large.
|
||
* --leading-tight 1.0: DESIGN.md Display Hero (96px).
|
||
* --tracking-display -0.05em: ABC Favorit Section Heading
|
||
* (-2.8px / 56px). Harder compression than Domaine's -0.01em;
|
||
* binding the slot to the ABC Favorit value gives display tiers
|
||
* the brand's "engineered masthead" feel. */
|
||
--leading-body: 1.5;
|
||
--leading-tight: 1.0;
|
||
--tracking-display: -0.05em;
|
||
|
||
/* ─── Spacing ────────────────────────────────────────────────────
|
||
* Standard 4px-grid base scale. DESIGN.md §5 also documents 5px,
|
||
* 6px, 7px, 10px, 30px, 40px micro-tiers — those are too fine to
|
||
* belong in the shared schema and are inlined per-component when
|
||
* needed (button padding `5px 12px`, etc.). The 4/8/12/16/20/
|
||
* 24/32/48 tier covers the structural rhythm. */
|
||
--space-1: 4px;
|
||
--space-2: 8px;
|
||
--space-3: 12px;
|
||
--space-4: 16px;
|
||
--space-5: 20px;
|
||
--space-6: 24px;
|
||
--space-8: 32px;
|
||
--space-12: 48px;
|
||
|
||
/* Section rhythm — DESIGN.md §5: "Cinematic black space" with
|
||
* 80–120px+ vertical padding between sections. 120px desktop sits
|
||
* at the top of the documented range, dropping to 80px tablet
|
||
* (still generous) and 48px phone (the documented mobile floor). */
|
||
--section-y-desktop: 120px;
|
||
--section-y-tablet: 80px;
|
||
--section-y-phone: 48px;
|
||
|
||
/* ─── Radius ─────────────────────────────────────────────────────
|
||
* DESIGN.md §5 radius scale: 4 / 6 / 8 / 10 / 12 / 16 / 24 / 9999.
|
||
* We bind the four schema tiers to: 4 (sharp — ghost button,
|
||
* inputs), 8 (standard — tabs, content), 16 (large — feature
|
||
* cards, images, main buttons), 9999 (pill — primary CTAs, tags,
|
||
* badges). The 24px "Section" radius is component-specific (large
|
||
* panels) and reached inline. */
|
||
--radius-sm: 4px; /* Sharp — ghost button, input */
|
||
--radius-md: 8px; /* Standard — tab, content block */
|
||
--radius-lg: 16px; /* Large — feature card, image, main button */
|
||
--radius-pill: 9999px; /* Pill — primary CTA, tag, badge */
|
||
|
||
/* ─── Elevation (3 levels) ───────────────────────────────────────
|
||
* Resend barely uses shadows — DESIGN.md §6: "On a pure black
|
||
* background, traditional shadows are invisible — you can't cast
|
||
* a shadow into the void. Instead, Resend creates depth through
|
||
* its signature frost borders."
|
||
*
|
||
* --elev-flat no shadow (page background, text blocks)
|
||
* --elev-ring the signature frost hairline (most surfaces)
|
||
* --elev-raised ring + subtle drop for true "lifted" feel
|
||
*
|
||
* `--elev-raised` layers the documented `rgba(176, 199, 217, 0.145)
|
||
* 0 0 0 1px` ring with the §6 Level 2 subtle drop. Never strip
|
||
* the ring when overriding — it is the edge mechanism that lets
|
||
* a card read against the void at all. */
|
||
--elev-flat: none;
|
||
--elev-ring: 0 0 0 1px var(--border);
|
||
--elev-raised:
|
||
0 0 0 1px rgba(176, 199, 217, 0.145),
|
||
0 1px 3px rgba(0, 0, 0, 0.4),
|
||
0 1px 2px -1px rgba(0, 0, 0, 0.4);
|
||
|
||
/* ─── Focus ring ─────────────────────────────────────────────────
|
||
* Sharp 2px ring at `var(--accent)`, NOT the schema's 3px alpha
|
||
* glow. DESIGN.md §6 documents an 8px black ring that works in
|
||
* product context (against non-black surroundings); on this
|
||
* brand fixture the black canvas would swallow that ring, so we
|
||
* substitute the orange accent at 2px — sharp, engineered,
|
||
* legible against both the void and any card surface. */
|
||
--focus-ring: 0 0 0 2px var(--accent);
|
||
|
||
/* ─── Motion ─────────────────────────────────────────────────────
|
||
* Two durations + one easing curve. Resend's micro-states are
|
||
* quick and unobtrusive — pill buttons crossfade to white glass,
|
||
* frost borders intensify on focus, no choreographed entrances. */
|
||
--motion-fast: 150ms;
|
||
--motion-base: 200ms;
|
||
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
|
||
|
||
/* ─── Layout ─────────────────────────────────────────────────────
|
||
* 1200px max content width — DESIGN.md §5 "Centered content with
|
||
* generous max-width". Gutters stay wide on desktop (32px) so
|
||
* the gallery margin around the void canvas reads as intentional
|
||
* framing; mobile narrows to 16px to preserve readable measure. */
|
||
--container-max: 1200px;
|
||
--container-gutter-desktop: 32px;
|
||
--container-gutter-tablet: 24px;
|
||
--container-gutter-phone: 16px;
|
||
}
|