# Amaca — full context (self-contained) > Amaca is a dark-first, token-only design system, and amaca.ai is the compiler that turns any > design system into rules your AI tools follow. Reference every value by name (var(--token)); > never hardcode a hex, px, or easing. This file inlines the agent rules and the full token > table so a tool can load Amaca in a single fetch. For the complete prose spec (components, > motion, accessibility, examples) see https://amaca.design/DESIGN.md. Version: 3.3.0 · Released: 2026-07-17 · Matches the DESIGN.md frontmatter version Source: https://amaca.design/llms.txt · Spec: https://amaca.design/DESIGN.md · Compiler: https://amaca.ai ================================================================================ # Agent rules (AGENTS.md) ================================================================================ # Amaca — AGENTS.md > Agent rules for the **Amaca Design System**. Place at repo root; read natively by Codex, Cursor, Copilot, Windsurf, Amp, Devin, Aider, Zed, Jules, VS Code, JetBrains Junie, and any tool on the [AGENTS.md](https://agents.md) standard. > **Full spec:** `DESIGN.md` · **tokens:** `tokens.css` / `tokens.dtcg.json` · **home:** [amaca.design](https://amaca.design). On conflict, `DESIGN.md` wins. Dark-first, single typeface (Satoshi), one brand accent (magenta) spent sparingly. **Reference every value as a token by name (`var(--token)`) — never hardcode a hex, px, or `cubic-bezier`.** The full token tables live in `tokens.css`; read them, don't restate them. If a value isn't on a scale, **stop and ask** — never extend the system silently. ## Token roles (anchors; full scales in `tokens.css`) - **Brand:** `--magenta-500` (#F051D5) = **primary** · CTAs · focus rings. Magenta scale `--magenta-100…800`. - **Neutral:** `--obsidian-950` (page) → `--obsidian-050` (bone); text on dark = `--obsidian-100`. - **Supporting (rare):** `--secondary-400` cyan (data-viz), `--tertiary-500` petrol; semantic `--success / --warning / --danger / --info` — feedback only. - **Type:** Satoshi; scale `--t-micro 10 … --t-body 15 (default) … --t-h1 76 / --t-display 112`. One H1 per page. - **Spacing:** 4px grid `--s-1 4 … --s-32 128`. **Radius:** `--r-md 8` (default) / `--r-lg 12` (cards). **Motion:** 6 durations `--d-instant…--d-draw`, 4 easings `--ease-standard / -accel / -decel (signature) / -spring` — no others; `--ease-spring` = spatial properties only. ## The laws 1. **85 / 10 / 5.** ~85% obsidian, ~10% supporting, **≤5% magenta** (one CTA per viewport). Magenta on >1 element per viewport = decorating. 2. **Clarity before cleverness · evidence over opinion · precision is a feeling · quiet then loud · motion is a material.** Values off a scale break precision (`padding:14px` ✗ → `var(--s-3) var(--s-4)` ✓). 3. **Motion is feedback, not decoration** — if it doesn't communicate a state change, cut it. **Always provide a `prefers-reduced-motion: reduce` fallback** (gate JS-driven animation too). `--ease-spring` rides **spatial** properties only — transform, size, position; never color, background, opacity, or shadow. 4. **Stat count-up (site-canonical, RIGID).** Numeric stats/KPIs count up from zero to their target on entrance (`--d-draw` · `--ease-decel`) and land exactly on the final value — a static stat number where a count-up belongs is off-system. Under reduced motion the counter jumps straight to the target. ## Components — reuse, don't reinvent Each maps to a class in `components.css` (`.btn-primary`, `.card`, `.field`, `.select`, …); full specs in `DESIGN.md → Components`. One `.btn-primary` per screen. Dropdown/Select placement is viewport-aware (opens below, flips above, never covers adjacent content). **A new `.classname` not in the canonical set is a gap** — surface it (workaround / extend / refactor), never ship a silent variant. ## Accessibility floor (non-negotiable) Color never carries meaning alone (pair with shape + label) · no text < 12px, no body < 14px · every field has a persistent label (placeholder ≠ label) · every image has `alt` · focus follows reading order · no auto-advancing content · touch target 44×44 (32×32 dense desktop). Focus: pressables get a dual-ring (white outline + magenta halo); inputs get the magenta border + glow. On `--magenta-500` use a dark label (`--obsidian-950`, AA) by default; the one ratified exception is `.btn-primary` (light `--obsidian-050` label, scoped to that CTA). ## Snippets — reuse these verbatim (token-only) ```html ``` ```css .btn-primary{ background:var(--magenta-500); color:var(--obsidian-050); padding:var(--s-3) var(--s-5); border-radius:var(--r-md); font-family:var(--font-sans); font-size:var(--t-body); font-weight:500; transition:background var(--d-quick) var(--ease-standard); } .btn-primary:hover{ background:var(--magenta-600); } .btn-primary:focus-visible{ outline:2px solid var(--obsidian-100); outline-offset:3px; box-shadow:0 0 0 4px rgba(240,81,213,0.35); } ``` ```html ``` ```css .field-label{ font-family:var(--font-mono); font-size:var(--t-micro); text-transform:uppercase; letter-spacing:var(--tr-mono); color:var(--obsidian-400); } .input{ background:var(--obsidian-900); border:1px solid var(--obsidian-700); border-radius:var(--r-md); padding:var(--s-3) var(--s-4); color:var(--obsidian-100); } .input:focus{ border-color:var(--magenta-500); box-shadow:0 0 0 3px rgba(240,81,213,0.15); } ``` ## Voice Imperative and terse in specs/code; editorial (paragraphed, sentence-case) in marketing. **Never use AI tells** ("delve", "leverage", "robust", "seamless", "effortlessly"). Say "surface" not "background", "token" not "variable", "ship" not "launch". ## Conventions **Semantic HTML first** — `