mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-19 09:36:59 +03:00
skill: anti-cream + codex-specific defect bans + universal slop bans
Second pass after measuring more biases against the eval corpus. - SKILL.md Color: explicit "cream/sand/beige body bg is the saturated AI default of 2026" rule. Tone down the "tint every neutral" line so it doesn't read as "default to warm-tinted near-white" (which OpenAI hits at 74% and Anthropic at 31%-47%). - SKILL.md Absolute bans: add universal bans for two slop patterns detected at 55-95% across providers — tiny uppercase tracked eyebrow above every section (the 2023-era kicker that's now AI grammar) and numbered section markers (01/02/03). Also explicit "text that overflows its container is the universal defect on tablet/mobile." - SKILL.md Absolute bans → <codex> block: ban the GPT-specific defects Paul annotated repeatedly — `border:1px solid` + soft-wide-shadow (≥16px blur) "ghost cards", `border-radius:32px+` over-rounding, hand-drawn/sketchy SVG illustrations (loose-sketch / *-sketch classes, feTurbulence paper-grain filters), repeating-linear-gradient stripes, "X theater" AI-slop copy phrases. - SKILL.md Motion → <gemini> block: the image :hover transform tell (38% Google skill-on rate). Hover effects on images add no info; the image isn't an action target. Animate card chrome, not the image. - SKILL.md Typography: hard display letter-spacing floor ≥-0.04em (OpenAI defaults to -0.075em → cramped). Existing hero ceiling <codex> block extended with the letter-spacing rule. - codex.md Step A example: stop seeding "warm-grounded (deep oxblood + cream)" as the warm-palette template, which primes the cream default. - colorize.md Tinted backgrounds: stop printing the literal cream recipe `oklch(97% 0.01 60)`; replace with brand-anchored guidance. - document.md examples: warm-ash-cream → cool-paper so the example doesn't seed cream as the canonical neutral example. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
14791a0e35
commit
38b89de182
+23
-2
@@ -60,7 +60,8 @@ Apply to every design, both registers. Match implementation complexity to the ae
|
||||
### Color
|
||||
|
||||
- Use OKLCH. Reduce chroma as lightness approaches 0 or 100; high chroma at extremes looks garish.
|
||||
- Never use `#000` or `#fff`. Tint every neutral toward the brand hue (chroma 0.005–0.01 is enough).
|
||||
- Never use `#000` or `#fff`. When you use a neutral, tint it slightly toward the brand hue (chroma 0.005–0.01 is enough).
|
||||
- **The cream / sand / beige body bg is the saturated AI default of 2026.** Warm-tinted neutrals at ~95–97% lightness with hue 60–95 are the "safe warm" reflex; they aren't safe, they're the tell. The bg comes from the brand, not from a default palette — and the default-warm-tint is now the AI giveaway across providers.
|
||||
- Pick a **color strategy** before picking colors. Four steps on the commitment axis:
|
||||
- **Restrained**: tinted neutrals + one accent ≤10%. Product default; brand minimalism.
|
||||
- **Committed**: one saturated color carries 30–60% of the surface. Brand default for identity-driven pages.
|
||||
@@ -81,9 +82,12 @@ Before choosing, write one sentence of physical scene: who uses this, where, und
|
||||
- Cap body line length at 65–75ch.
|
||||
- Hierarchy through scale + weight contrast (≥1.25 ratio between steps). Avoid flat scales.
|
||||
- Hero / display heading ceiling: clamp() max ≤ 6rem (~96px). Above that the page is shouting, not designing.
|
||||
- Display heading letter-spacing floor: ≥ -0.04em. Anything tighter and letters touch — cramped, not "designed".
|
||||
|
||||
<codex>
|
||||
The hero ceiling is hard. Stop at 6rem max. 8–11rem (128–176px) clamp maxes read as comically loud, not bold.
|
||||
Two hard typographic ceilings you currently miss:
|
||||
- Hero clamp() max ≤ 6rem. 8–11rem (128–176px) reads as comically loud, not bold.
|
||||
- Display letter-spacing ≥ -0.04em. Your default of -0.05 to -0.085em on display H1s makes the letters touch and reads as cramped. -0.02 to -0.03em is plenty for tight grotesque display; -0.04em is the floor.
|
||||
</codex>
|
||||
|
||||
### Layout
|
||||
@@ -97,6 +101,10 @@ The hero ceiling is hard. Stop at 6rem max. 8–11rem (128–176px) clamp maxes
|
||||
- Don't animate CSS layout properties.
|
||||
- Ease out with exponential curves (ease-out-quart / quint / expo). No bounce, no elastic.
|
||||
|
||||
<gemini>
|
||||
**Gemini-specific defect.** Adding superfluous `:hover` transforms to images (`transform: scale(1.02-1.05)` or `rotate(N deg)` on `<img>` elements) is your most common motion tell. Hover effects on images add no real information; the image isn't an action target. Don't add image-hover transforms by reflex. If a card containing an image needs hover feedback, animate the card chrome (subtle elevation, border treatment), not the image inside it.
|
||||
</gemini>
|
||||
|
||||
### Absolute bans
|
||||
|
||||
Match-and-refuse. If you're about to write any of these, rewrite the element with different structure.
|
||||
@@ -107,6 +115,19 @@ Match-and-refuse. If you're about to write any of these, rewrite the element wit
|
||||
- **The hero-metric template.** Big number, small label, supporting stats, gradient accent. SaaS cliché.
|
||||
- **Identical card grids.** Same-sized cards with icon + heading + text, repeated endlessly.
|
||||
- **Modal as first thought.** Modals are usually laziness. Exhaust inline / progressive alternatives first.
|
||||
- **Tiny uppercase tracked eyebrow above every section.** The 2023-era kicker (small all-caps text with wide tracking, "ABOUT" "PROCESS" "PRICING" above each heading) is now the saturated AI scaffold — it appears on 55-95% of generations regardless of brief, which is the definition of a tell. One named kicker as a deliberate brand system is voice; an eyebrow on every section is AI grammar. Choose a different cadence.
|
||||
- **Numbered section markers (01 / 02 / 03).** Section labels as numbered display digits is the same trope, one tier deeper. If you find yourself reaching for them, you're scaffolding by reflex.
|
||||
- **Text that overflows its container.** Long heading words plus large clamp scales plus narrow grids cause headline overflow on tablet/mobile. Test the heading copy at every breakpoint; if it overflows, reduce the clamp max or rewrite the copy. The viewport is part of the design.
|
||||
|
||||
<codex>
|
||||
**Codex-specific defects** (your most-frequent giveaways — refuse-and-rewrite):
|
||||
|
||||
- **`border: 1px solid X` + `box-shadow: 0 Npx Mpx ...` with M ≥ 16px** on the same element. The "ghost-card" pattern — 1px border plus soft wide drop shadow on buttons and cards. Don't pair them. Pick one (a single solid border at the brand color, OR a defined shadow at no more than 8px blur), never both as decoration.
|
||||
- **`border-radius: 32px+` on cards / sections / inputs.** You over-round. Cards top out at 12–16px; full-pill is fine for tags/buttons. Picking 24/28/32/40px on a card is the codex tell — no brand wants "insanely rounded".
|
||||
- **Hand-drawn / sketchy SVG illustrations.** Class names like `loose-sketch`, `*-sketch`, `doodle`, `wavy`; `feTurbulence` / `feDisplacementMap` "paper grain" filters; 5-to-30 path crude scenes meant to depict a tangible subject (an otter, a table-and-fork, an album cover). All of these read as amateurish, not whimsical. If you can't render the scene with real assets, ship no illustration. Don't attempt sketchy SVG as a fallback.
|
||||
- **`repeating-linear-gradient(...)` stripe backgrounds.** Diagonal stripes in `body:before` or section backgrounds are pure codex decoration. Don't.
|
||||
- **"X theater" / "actually X" / "not just X, it's Y" copy.** "Productivity theater", "engagement theater", "growth theater": instant AI slop. Choose a specific noun, not a meta-criticism phrase.
|
||||
</codex>
|
||||
|
||||
### Copy
|
||||
|
||||
|
||||
@@ -23,8 +23,8 @@ Before generating anything, run a brief direction conversation grounded in the s
|
||||
|
||||
Ask **2-3 targeted questions** about visual lane, color strategy, atmosphere, and named anchor references. Don't enumerate generic menus; tie each question to the shape brief's answers. Example shape-grounded questions:
|
||||
|
||||
- "Brief says 'editorial restraint, Klim-adjacent.' Are we closer to a quiet specimen page or a magazine-spread feel with hero imagery?"
|
||||
- "Palette strategy from shape was 'Committed.' Want it warm-grounded (deep oxblood + cream) or cool-grounded (slate + paper white)?"
|
||||
- "Brief says 'specimen-page restraint.' Are we closer to a quiet typographic page or a wider editorial spread with hero imagery?"
|
||||
- "Palette strategy from shape was 'Committed.' Which one color carries the surface — a brand-driven pick rather than a default warm-or-cool framing? (And no, the answer isn't a cream/sand body bg — that's the saturated AI default.)"
|
||||
|
||||
**STOP and wait for answers.** These pin the palette before any pixel gets generated. Do not proceed to Step B until the user has responded.
|
||||
|
||||
|
||||
@@ -68,10 +68,10 @@ Add color systematically across these dimensions:
|
||||
- **Hover states**: Introduce color on interaction
|
||||
|
||||
### Background & Surfaces
|
||||
- **Tinted backgrounds**: Replace pure gray (`#f5f5f5`) with warm neutrals (`oklch(97% 0.01 60)`) or cool tints (`oklch(97% 0.01 250)`)
|
||||
- **Tinted backgrounds**: If you replace pure gray, tint toward the brand hue, not toward a generic-warm-or-cool pair. The default-warm-tint (`oklch(97% 0.01 60)` and its neighbors) is now the AI cream/sand giveaway. Be specific to the brand or stay neutral.
|
||||
- **Colored sections**: Use subtle background colors to separate areas
|
||||
- **Gradient backgrounds**: Add depth with subtle, intentional gradients (not generic purple-blue)
|
||||
- **Cards & surfaces**: Tint cards or surfaces slightly for warmth
|
||||
- **Cards & surfaces**: Tint cards or surfaces toward the brand, not "for warmth" by reflex
|
||||
|
||||
**Use OKLCH for color**: It's perceptually uniform, meaning equal steps in lightness *look* equal. Great for generating harmonious scales.
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ Rules that matter:
|
||||
- **Token refs** use `{path.to.token}` (e.g. `{colors.primary}`, `{rounded.md}`). Components may reference primitives; primitives may not reference each other.
|
||||
- **Stitch validates colors as hex sRGB only** (`#RGB` / `#RGBA` / `#RRGGBB` / `#RRGGBBAA`); OKLCH/HSL/P3 trigger a linter warning, not a hard error. YAML accepts the string either way and our own parser is format-agnostic. Choose based on project posture: (a) if the project has an "OKLCH-only" doctrine or uses Display-P3 values that don't round-trip through sRGB, put OKLCH directly in the frontmatter and accept the Stitch linter warning; (b) if the project wants strict Stitch compliance or plans to use their Tailwind/DTCG export pipeline, put hex in the frontmatter and keep OKLCH in prose as the canonical reference. Never split the source of truth without explicit reason.
|
||||
- **Component sub-tokens** are limited to 8 props: `backgroundColor`, `textColor`, `typography`, `rounded`, `padding`, `size`, `height`, `width`. Shadows, motion, focus rings, backdrop-filter: none of those fit. Carry them in the sidecar (Step 4b).
|
||||
- **Scale keys are open-ended.** Use whatever names the project already uses (`warm-ash-cream`, `surface-container-low`). Don't rename to Material defaults.
|
||||
- **Scale keys are open-ended.** Use whatever names the project already uses (`oxblood-deep`, `surface-container-low`). Don't rename to Material defaults.
|
||||
- **Variants are naming convention, not schema.** `button-primary` / `button-primary-hover` / `button-primary-active` as sibling keys.
|
||||
|
||||
## The markdown body: six sections (exact order)
|
||||
@@ -103,7 +103,7 @@ Build a structured draft from the discovered tokens. For each token class:
|
||||
|
||||
From the auto-extracted tokens, draft the YAML frontmatter now (you'll write it at the top of DESIGN.md in Step 4). This is the machine-readable layer: what the live panel and Stitch's linter consume.
|
||||
|
||||
- **Colors**: one entry per extracted color. Key = descriptive slug (`warm-ash-cream`, `editorial-magenta`, not `blue-800`). Value = whichever format the project treats as canonical (OKLCH or hex; see the frontmatter rules above). Don't split the source of truth: one format in the frontmatter, don't redefine the same token in prose with a different value.
|
||||
- **Colors**: one entry per extracted color. Key = descriptive slug (`oxblood-deep`, `editorial-magenta`, not `blue-800`). Value = whichever format the project treats as canonical (OKLCH or hex; see the frontmatter rules above). Don't split the source of truth: one format in the frontmatter, don't redefine the same token in prose with a different value.
|
||||
- **Typography**: one entry per role (`display`, `headline`, `title`, `body`, `label`). Typography is an object; include only the props that are real for the project (`fontFamily`, `fontSize`, `fontWeight`, `lineHeight`, `letterSpacing`, `fontFeature`, `fontVariation`).
|
||||
- **Rounded / Spacing**: whatever scale steps the project actually uses, keyed by whatever scale name the project uses (`sm` / `md` / `lg`, or `surface-sm`, or numeric steps).
|
||||
- **Components**: one entry per variant (`button-primary`, `button-primary-hover`, `button-ghost`). Reference primitives via `{colors.X}`, `{rounded.Y}`. If a variant needs a property Stitch's 8-prop set doesn't cover (shadow, focus ring, backdrop-filter), carry the full snippet in the sidecar instead.
|
||||
@@ -253,7 +253,7 @@ Regenerate the sidecar whenever you regenerate root `DESIGN.md`. If the user onl
|
||||
"extensions": {
|
||||
"colorMeta": {
|
||||
"primary": { "role": "primary", "displayName": "Editorial Magenta", "canonical": "oklch(60% 0.25 350)", "tonalRamp": ["...", "...", "..."] },
|
||||
"warm-ash-cream": { "role": "neutral", "displayName": "Warm Ash Cream", "canonical": "oklch(96% 0.005 350)", "tonalRamp": ["...", "...", "..."] }
|
||||
"cool-paper": { "role": "neutral", "displayName": "Cool Paper", "canonical": "oklch(96% 0.005 230)", "tonalRamp": ["...", "...", "..."] }
|
||||
},
|
||||
"typographyMeta": {
|
||||
"display": { "displayName": "Display", "purpose": "Hero headlines only." }
|
||||
|
||||
Reference in New Issue
Block a user