--- name: apple-modern-ui description: "Apple-style anti-slop web UI ruleset: Onest typography, one-accent color tokens with verified contrast, functional glass, Lucide icons, Motion + anime.js recipes, components, accessibility, Delivery Gate. Use for any web UI work: landing pages, components, styling, animation, UI review." --- # Apple-Modern UI Ruleset · anti-slop edition **Version 1.0 (EN).** Rules for AI agents (Claude Code, Cursor, Codex, Windsurf, v0, etc.) and humans. Goal: the web UI looks like a modern Apple site, not a generated template. **Default stack:** **Onest** typeface, **Lucide** icons, **Motion (motion.dev)** + **anime.js v4** for animation, CSS-first. **Compiled from 17 skills and guidelines** (full list in §20): anthropics/frontend-design, taste-skill, anti-slop (antislop), impeccable, hallmark, ui-ux-pro-max, Emil Kowalski (design-eng + apple-design), GSAP skills, Motion AI Kit, anime.js skills, Vercel Web Interface Guidelines, make-interfaces-feel-better, ui-skills, Apple HIG / Liquid Glass (apple-design-skill), Apple DESIGN.md (awesome-design-md), LottieFiles motion-design, motion-dev-animations. --- ## Contents 0. How to use 1. Direction: Apple-modern 2. Resolving conflicts between skills 3. Hard bans (AI-slop registry) 4. Typography (Onest) 5. Color 6. Grid, spacing, rhythm, responsive 7. Surfaces, radii, shadows, glass 8. Icons (Lucide) 9. Motion (Motion + anime.js) 10. Components and states 11. Images and media 12. Copy (Russian UI) 13. Accessibility 14. Performance 15. Mobile layer 16. Tokens (CSS + Tailwind v4) 17. Hero skeleton (as in the reference) 18. Delivery Gate (pre-handoff check) 19. Installing the skills 20. Sources --- ## 0. How to use ### 0.1 Connecting to an agent (load on demand) The file is large (~36k tokens). Load it only for UI work; never put it into always-on context. - **As a skill (best):** copy the file to `.claude/skills/apple-modern-ui/SKILL.md` (Claude Code), `.agents/skills/apple-modern-ui/SKILL.md` (Codex) or `.cursor/skills/apple-modern-ui/SKILL.md` (Cursor). The frontmatter at the top is the skill header: until a UI task triggers the skill, only its `description` sits in context. - **As a project file:** put it in the project root as `DESIGN-RULES.md` and add one line to `CLAUDE.md` / `AGENTS.md`: `Before any UI work, read DESIGN-RULES.md and follow it.` Write it without `@`: in Claude Code an `@DESIGN-RULES.md` import loads the whole file into every session. - **Cursor rule:** `.cursor/rules/design.mdc`, attached by globs, not always: ```md --- description: Apple-modern UI ruleset (anti-slop). Use for any web UI work. globs: ["**/*.{tsx,jsx,vue,svelte,astro,html,css}"] alwaysApply: false --- Follow @DESIGN-RULES.md for every UI change. ``` - Installed skills (frontend-design, taste-skill, impeccable, etc.) may run alongside. §2 resolves their conflicts. ### 0.2 Modality - **MUST / NEVER**: hard rule. Deviate only on the user's explicit request. - **SHOULD**: default. Deviation is fine if the reason is recorded in one line (PR or `DESIGN.md`). - **AVOID**: AI-slop tell. Use only with a recorded reason. ### 0.3 Source priority 1. The user's explicit words and the brief. Pinned fonts, palettes and eras are honored even against anti-slop warnings ("the brief wins", impeccable). 2. The project's `DESIGN.md` / brand guide. 3. This Ruleset. 4. Defaults of installed skills. **Exception:** accessibility (§13) and honesty (§3.7) are never overridden by any brief. ### 0.4 Agent workflow 1. **Read the project:** stack, tokens, components, real content. Don't ask what the code can tell you. 2. **Write the Design Read and Dials** (§1.4) as the first line of the reply. 3. **Plan before code:** tokens (colors, font, scale), copy deck (real text), per-screen composition (ASCII sketch), one signature animation. 4. **Build the static version** without animation: content, grid, typography, all states. 5. **Add motion** within the budget (§9.4). 6. **Check the render** at 390, 768, 1280×800, 1440×900 and 1920 px, light and dark theme, keyboard, reduced motion. Pass the Delivery Gate (§18) and attach evidence. --- ## 1. Direction: Apple-modern ### 1.1 Seven pillars 1. **The hero is the product and the content; the UI steps back.** Color and emotion come from photos, renders and real screenshots. Chrome stays neutral and quiet. 2. **One accent.** One interactive color for everything "press me": links, primary CTA, focus, selected state. No second brand color. 3. **Big, dense grotesque.** Huge short headline with negative tracking, calm 17 px body. Hierarchy comes from size and weight, not color or decoration. 4. **Whitespace as structure.** One screen, one idea. Sections are separated by a surface change (white ↔ "parchment" #f5f5f7 ↔ black), not by lines and shadows. 5. **Materials by meaning.** Translucent glass only on floating chrome: navigation, panels, controls over media. Shadow only on what truly floats (menu, popover, dialog) and on a product standing on a surface. 6. **Physical, interruptible motion.** Instant press feedback, springs without bounce, animation explains cause and effect. One authored scene per page. 7. **Craft in the details.** Concentric radii, optical alignment, tabular numerals, styled `::selection` / `caret` / scrollbar, precise copy, all states. ### 1.2 Apple principles as questions for every screen | Principle | Question | |---|---| | Purpose | Why does this screen exist, and does the design serve it? | | Agency | Can the user skip, cancel, go back? Undo beats confirm. | | Responsibility | Is it transparent about data and permissions? | | Familiarity | Are the patterns familiar and consistent? | | Flexibility | Does it work at any size, with any input, with enlarged text? | | Simplicity ≠ minimalism | Has every element earned its place? | | Craft | Are spacing, alignment, wording and motion finished? | | Delight | Is there feeling, and is it the right one? "Don't confuse delight with decoration." | ### 1.3 Reference composition: cinematic hero Breakdown of the provided example (antislop.ai): - full-bleed cinematic illustration or photo filling the first screen (`min-height: 100svh`), dark vignette scrim at the bottom and edges for legibility; - transparent header over the hero: wordmark left, 4–5 centered items with `ChevronDown` on dropdowns, on the right one text link and one glass pill CTA; - centered huge dense grotesque (max 2 lines, tracking -0.03…-0.04em), below it 1–2 subtitle lines in ~80 % white (verify contrast!); - glass pill field with a monospace `npx …` command and a round copy button (Lucide `Copy` → `Check`); - small footnote at the bottom center. This is the page's **only centered moment**. Everything after it uses left-aligned compositions with varied rhythm. ### 1.4 Design Read and Dials Mandatory first line of the agent's reply, before any code: ```text Design Read: for , Apple-modern language (), signature: . Dials: E2 R2 M2. ``` | Dial | 1 | 2 (default) | 3 | |---|---|---|---| | **ENERGY** (contrast, scale, color) | quiet: docs, app | confident: landing | poster: launch, promo | | **RHYTHM** (density, composition changes) | even | breathing | dramatic shifts | | **MOTION** | feedback + 1 reveal | + hero sequence and 2–3 reveals | + one scroll scene and a "living image" | ### 1.5 Surface mode (impeccable) - **Persuade** (landing, marketing, pricing): bold, one strong idea, real imagery. - **Operate** (app, dashboard, settings): scannability and stability over expression. Motion only for feedback. - **Read** (docs, articles): reading comes first. - **Experience** (portfolio, gallery): the artifact leads, the UI steps back. Choose the mode by surface, not by product: a tool's landing page is still Persuade; a fashion house's docs are still Read. --- ## 2. Resolving conflicts between skills | # | Topic | What the skills say | Ruleset decision | |---|---|---|---| | 1 | Glass / backdrop-blur | taste: banned. antislop: max 1–2 elements. impeccable: not as decoration. Apple HIG and Emil: material of the functional layer. | Only for floating chrome and controls over media: header, sticky bar, menus and popovers, sheet, pill CTA and command field over the hero. Max 2 glass roles per viewport. Never on content cards, never glass on glass. Fallbacks are mandatory (§7.5). | | 2 | Floating pill nav | taste: warned. hallmark: reflexive "AI nav". | The header is a full-width bar like on apple.com, not a floating pill island. Pill shape only for buttons, fields and segments. | | 3 | "Don't clone Apple" | antislop: don't copy Apple/Linear/Vercel unless asked. | Apple style was requested, so it is the direction. Transfer principles and proportions, not Apple's logos, copy or photos. The project's brand stays its own. | | 4 | Lucide | antislop: "Lucide look" as a template tell. | Lucide is a deliberate choice. The anti-slop requirement shifts to usage: icons by meaning, stroke matched to text weight, no "icon in a coin" above every card, no Sparkles / Rocket / Zap. | | 5 | Centered hero | taste: center in at most one place. hallmark 6b: center axis as a default. | One centered moment is allowed: the hero, as in the reference. Other sections are left-aligned or asymmetric. | | 6 | Tracking | ui-skills: don't change letter-spacing. | Apple typography needs negative tracking at display sizes (table §4.4). Never loosen labels. | | 7 | Custom curves and animation | ui-skills: animate only on request, no custom easing. | Animation was requested; use the §9.3 tokens. Don't animate actions repeated 100+ times a day. | | 8 | Monospace | taste / hallmark / impeccable: mono as a costume is banned. | Mono only for real code, commands and measurements (the `npx …` field). No mono labels or captions. | | 9 | Shadows | taste: no shadows at rest. Apple: one shadow under the product. | Shadow signals elevation only (menu, popover, dialog, glass sticky bar) plus one "product" shadow under a render. Cards separate by tone, not shadow. | | 10 | Parallax and smooth scroll | hallmark: never parallax. taste: parallax under 8 %, Lenis optional. | Default: native scroll, no parallax. At MOTION 3, one scroll scene is allowed (travel up to 8 % or a sticky stage). Lenis only on marketing pages, disabled for touch and reduced motion. No scroll-jacking. | | 11 | `text-wrap: balance` on display text | hallmark F3: against. impeccable / ui-skills: for. | `balance` for h2–h4 and short centered blocks. For h1, an authored break by meaning (`
` verified at all widths), or `balance` if the break is not authored. Always check visually. | | 12 | Radii | taste: square or full round, pick once. impeccable: cards 12–16. Apple: cards 18, pill buttons. | Buttons, search and command fields, chips: pill (decided once and for all). Cards 22, panels 28, full-bleed media 0. Radii are concentric. | | 13 | ease-in on exit | Emil: never ease-in in UI. taste / hallmark: ease-in for things "leaving for good". | Exit defaults to ease-out and is 25–40 % shorter than the enter. `--ease-exit` (ease-in) only for things leaving the screen for good, at most 200 ms. | | 14 | Dark theme | antislop: not "because tech". impeccable: by usage scenario. | A cinematic hero may be dark, but the page theme follows the usage scenario. Without a reason, ship a working light / dark toggle, system default. | | 15 | Pure #000 / #fff | hallmark: tint them. Apple: white canvas and black "void" under media. | Allowed only as tokens (`--bg`), never as literals in code. Neutrals come from Apple's palette (#1d1d1f, #f5f5f7, #6e6e73). | | 16 | Hover effects | motion-dev-skill: `whileHover scale 1.05`, "magnetic" buttons. | Not in Apple style: no card scaling, no magnetic buttons. Hover is one signal (tone or contrast) and only under `(hover: hover) and (pointer: fine)`. | | 17 | Dashes | antislop / hallmark: no em/en dashes in UI. | In UI copy (headings, buttons, labels, short captions) no dashes; rephrase. In long Russian text where the dash is grammatically required, use " — " with a non-breaking space before it, sparingly. | | 18 | JS hero animation | Motion / anime: everything in JS. taste / hallmark: content visible without JS. | Animate the first screen with CSS keyframes (they start on first paint and don't wait for hydration). Use Motion and anime.js for interaction, scroll, layout and everything below the fold (§9.5). | --- ## 3. Hard bans (AI-slop registry) Everything below is **NEVER**. Deviate only on the user's explicit request (§0.3). The fix follows the arrow. ### 3.1 Color and surfaces - **Purple-indigo gradients** (purple→blue, purple→pink, cyan on dark), gradient text, aurora, mesh blobs, orbs, halos, glow around buttons and cards. → Atmosphere comes from photos and the product. A gradient is allowed only as a neutral scrim under text on a photo. - **"Assistant" palettes:** cream #F4F1EA + terracotta #D97757 + a serif; near-black + acid green or vermilion + neon. → Apple neutrals and one accent (§5). - **Stock Tailwind swatches** (`indigo-500`, `violet-600`, `slate-900`) as the brand. → Own tokens. - **A shadow on every card** (soft gray `rgba(0,0,0,.1)`), colored halo without offset, hard offset shadows. → Cards are separated by surface tone (§7). - **Card in a card**; 1px border plus a wide soft shadow on one surface ("ghost card"). → One means only: tone, border or shadow. - **Decorative backgrounds:** grids, dots, `feTurbulence` noise, grain, diagonal stripes. - **Colored left stripe** on a card or alert without a real status. - **Pulsing status dots** and any infinite pulse. - **Glass on content cards**, glass on glass, glass everywhere at once (header + cards + modals + sidebar). → §7.4. - **`#000` / `#fff` / hex literals in components.** → Tokens only. - **Accent on more than ~5 % of the screen area.** The accent is a signal, not a fill. ### 3.2 Typography - **Inter, Roboto, Arial, system-ui as the headline voice**; Space Grotesk or Geist "by default" without a reason. → Onest (§4). - **One "accent" word** in a headline set in italic, color or gradient. - **Eyebrow / kicker above the headline:** letter-spaced caps, pill badge "New", "Beta", "✨ Introducing". - **Small letter-spaced caps labels**, monospace labels, small caps. → A label is the same font one step smaller, sentence case, no letter-spacing. - **Section numbering 01 / 02 / 03**, meta lines "A · B · C", "WORD — fragment" constructions. - **text-shadow, outline or gradient** on display text. - **Text under 12 px**; body under 16 px; inputs under 16 px on mobile (iOS zooms the page). - **More than 3 weights** in use, more than one family (plus mono for code only). - **h1 longer than 2 lines** at any width; 8–9 near-identical font sizes. → At most 5–6 steps, clearly distinct. - **Justified text**, centered blocks longer than 3 lines. - **Weight change on hover** (text "jumps"). - **Synthesized bold or italic.** → `font-synthesis: none`. - `...` instead of `…`; straight quotes `"…"` instead of «guillemets» in Russian. ### 3.3 Composition - **The landing template:** hero → "Trusted by" → 3 feature cards → "How it works" in 3 steps → testimonials → 3 pricing tiers → CTA → 4-column footer. - **"Trusted by" logo bar** with made-up logos. - **Three identical cards** "icon in a rounded square + title + two lines". - **Bento by default.** Bento only if the content truly has different sizes and weights. - **Same rhythm for every section**, same spacing, differing only by background color. - **Everything centered.** Center is allowed once, in the hero (§2 #5). - **A dashboard, terminal or browser window drawn in HTML** instead of a real screenshot; phone or laptop frames more than once. - **A CSS box with a gradient** in place of an image; empty placeholder blocks. - **"Hand-drawn" illustrations**, Undraw, Storyset, 3D blobs, abstract "neural networks". - **Near-empty screens** (more than one intentional pause per page), "dead" bands over 160 px inside the hero. - **A lone orphan item** in the last grid row. - **Decorative text:** rotated captions, "Scroll ↓", "© 2026 · Scroll", local time, coordinates, crop marks. - **The same fact** repeated 3–4 times on a page. - **Floating pill-island navigation.** → Full-width header (§10.2). ### 3.4 Components and chrome - **AI-cliché icons:** `Sparkles`, `WandSparkles`, `Zap`, `Rocket`, `Bot`, `BrainCircuit`, `Gem`, `Lightbulb`, decorative `Star`. Icon in a colored "coin". Emoji in the UI. - **An "→" arrow on every button and link.** Arrows only where they say something (external link: `ArrowUpRight`; "next" in a step flow). - **Two filled buttons side by side**, more than one primary per viewport. - **Faceless CTAs:** «Начать», «Узнать больше», «Попробовать», «Подробнее», "Get Started", "Learn More", "Explore". → Verb + object: «Скачать для macOS» (Download for macOS), «Скопировать команду» (Copy command), «Посмотреть тарифы» (See pricing). - **Glow as the main clickability cue.** - **Hover ensemble:** lift + shadow + scale on every card, image zoom on hover, several effects on one element, hover on non-interactive elements. - **Custom cursor**, cursor trail, magnetic buttons. - **Capsule badges** with border, glow, dot and caps. - **A modal by reflex** when the task can be done inline. - **Celebratory toast** for a result the user already sees. - **Links to nowhere** (`href="#"`), buttons without behavior, fake form submission. - **Generic FAQ** of questions nobody asks. ### 3.5 Motion - **The same fade-up on every section**; "everything moves" (fade + float + scale + bounce). - **Infinite loops** (except a loading indicator), floating elements, autoplaying carousels and marquees without pause. - **Bounce and overshoot on UI states**; `ease-in` on enter and on ordinary exits. - **`transition: all`**; animating `width`, `height`, `top`, `left`, `margin`. - **Starting from `scale(0)`**; a popover expanding from its center instead of from the trigger. - **Preloaders, loading counters, "gates"**, scroll-jacking, wheel hijacking, mouse parallax, starfields. - **Animating keyboard-initiated actions** and frequent actions (100+ times a day). - **Content hidden until JS or until scroll.** The first screen doesn't wait for scroll; nothing in view stays hidden longer than 900 ms. - **scrambleText and typewriter effects** on headlines; per-character splits of long headlines (characters only for 1–3 words). - **Blur-in on body text**; animated large `blur` or `backdrop-filter` on full-screen surfaces. - **Motion longer than 5 s without a pause control.** - **`will-change` in a class "just in case".** ### 3.6 Copy - **Filler words (RU):** революционный, инновационный, передовой, нового поколения, на базе ИИ, бесшовный, мощный, интеллектуальный, идеальный, уникальный, непревзойдённый, «откройте для себя», «погрузитесь», «раскройте потенциал», «на новом уровне», «всё, что нужно», «меняет правила игры», «будущее уже здесь», «путешествие», «экосистема» and «решение» as empty words. - **(EN):** AI-powered, next-generation, revolutionary, seamless, cutting-edge, intelligent, ultimate, powerful, effortless, unlock, elevate, supercharge, reimagine, game-changer, journey, delve. - **Patterns:** «Не просто X, а Y» (not just X, but Y), «Будь вы X или Y…» (whether you're X or Y…), «Забудьте о…» (forget about…), «Скажите „прощай“…» (say goodbye to…), adjective triads («быстрый, простой и надёжный»), colon headlines, «Нажмите здесь» (click here), «Упс!» (oops), apologies in errors, exclamation marks, emoji, dashes in UI. ### 3.7 Honesty - **No invented** numbers, percentages, "10,000+ customers", ratings, testimonials, faces, client logos, awards, certificates. - **Honest placeholders, visible on the page** (in the page language): `[LOGO]`, `[REAL DATA: number of active teams]`, `[TESTIMONIAL: name, role, company]`, `[PHOTO: product on a desk, daylight, 3:2]`, `[SCREENSHOT: report screen]`. Every placeholder goes into the TODO list in the agent's reply. - **Demo data** is labeled as demo: `example.com`, `name@example.com`. - **A form without a backend** honestly says "Form not connected yet" and doesn't fake success. - **Don't claim what wasn't measured:** "Lighthouse 100", "loads in 0.5 s". Only with a measurement. ### 3.8 Accessibility (the floor) - `outline: none` without a replacement; a focus ring that animates in; focus hidden under a sticky header. - `user-scalable=no`, `maximum-scale=1`. - Icon button without `aria-label`; `
` instead of ` Документация Планы

Интерфейсы без шаблонов

Один файл правил, после которого ИИ-агент собирает сайт в стиле Apple, а не из готовых клише.

npx ruleset init

Открытый код, лицензия MIT.

``` ```css /* hero.css (+ .btn from §10.2, load animation from R2, glass from §7.5, scrim from §5.5) */ .skip-link { position: absolute; inset-inline-start: var(--space-4); inset-block-start: var(--space-4); z-index: var(--z-toast); padding: var(--space-2) var(--space-4); border-radius: var(--radius-pill); background: var(--surface); color: var(--ink); transform: translateY(-200%); } .skip-link:focus-visible { transform: none; } #top-sentinel { position: absolute; top: 0; width: 1px; height: 1px; } /* Header */ .site-header { position: fixed; inset: 0 0 auto; z-index: var(--z-header); block-size: var(--header-h); color: var(--on-media); background-color: transparent; -webkit-backdrop-filter: blur(0) saturate(1); backdrop-filter: blur(0) saturate(1); transition: background-color var(--dur-ui) var(--ease-out), color var(--dur-ui) ease, -webkit-backdrop-filter var(--dur-ui) var(--ease-out), backdrop-filter var(--dur-ui) var(--ease-out); } .site-header[data-scrolled="true"] { color: var(--ink); background-color: color-mix(in srgb, var(--bg) 72%, transparent); -webkit-backdrop-filter: blur(24px) saturate(1.5); backdrop-filter: blur(24px) saturate(1.5); } .site-header__inner { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; block-size: 100%; max-inline-size: var(--container-wide); margin-inline: auto; padding-inline: var(--gutter); } .wordmark { justify-self: start; color: inherit; text-decoration: none; font: 600 1.0625rem / 1 var(--font-sans); letter-spacing: -0.01em; } .nav { display: flex; gap: var(--space-1); } .nav__item { display: inline-flex; align-items: center; gap: var(--space-1); min-block-size: 44px; padding-inline: var(--space-3); border: 0; border-radius: var(--radius-pill); background: none; color: inherit; text-decoration: none; font: 500 var(--text-callout) / 1 var(--font-sans); white-space: nowrap; } .nav__item svg { transition: transform var(--dur-ui) var(--ease-out); } .nav__item[aria-expanded="true"] svg { transform: rotate(180deg); } .site-header__actions { justify-self: end; display: flex; align-items: center; gap: var(--space-2); } .btn--header { position: relative; min-block-size: 36px; padding-inline: var(--space-4); font-size: var(--text-callout); } .btn--header::before { content: ""; position: absolute; inset: -4px 0; } /* 44 px hit area */ .site-header[data-scrolled="true"] .btn--header { /* on light glass: primary */ background: var(--accent); color: var(--on-accent); border-color: transparent; -webkit-backdrop-filter: none; backdrop-filter: none; } .menu-btn { display: none; } @media (max-width: 1023px) { .nav, .nav__item--plain { display: none; } .site-header__inner { grid-template-columns: 1fr auto; } .menu-btn { display: inline-grid; place-items: center; inline-size: 44px; block-size: 44px; border: 0; border-radius: 50%; background: none; color: inherit; } } /* Hero */ .hero { position: relative; isolation: isolate; display: grid; place-items: center; min-block-size: 100svh; overflow: clip; text-align: center; color: var(--on-media); background-color: var(--media-solid); } .hero__media, .hero__media img { position: absolute; inset: 0; inline-size: 100%; block-size: 100%; object-fit: cover; } .hero__media { z-index: -2; } .media-scrim { z-index: -1; } .hero__content { display: grid; justify-items: center; gap: var(--space-5); max-inline-size: 60rem; padding: calc(var(--header-h) + var(--space-8)) var(--gutter) var(--space-10); } .hero__title { font-size: var(--text-hero); font-weight: 600; line-height: 1; letter-spacing: -0.035em; } .hero__lead { max-inline-size: 36ch; color: var(--on-media-2); text-wrap: balance; font-size: var(--text-lead); line-height: 1.35; letter-spacing: -0.01em; } .hero__cta { margin-block-start: var(--space-3); max-inline-size: 100%; } .hero__note { color: var(--on-media-2); font-size: var(--text-caption); line-height: 1.38; } /* Command field */ .command { display: inline-flex; align-items: center; gap: var(--space-3); max-inline-size: 100%; min-block-size: 56px; padding-inline: var(--space-5) var(--space-2); border-radius: var(--radius-pill); } .command code { overflow-x: auto; white-space: nowrap; scrollbar-width: none; font: 400 var(--text-callout) / 1 var(--font-mono); } .command__prompt { margin-inline-end: 1ch; color: var(--on-media-2); user-select: none; } .command__copy { position: relative; display: grid; place-items: center; flex: none; inline-size: 40px; block-size: 40px; border: 0; border-radius: 50%; color: inherit; background: var(--glass-media-fill); transition: transform var(--dur-press) var(--ease-out), background-color var(--dur-hover) ease; } .command__copy::before { content: ""; position: absolute; inset: -2px; border-radius: 50%; } .command__copy:active { transform: scale(.95); } .command__copy svg { grid-area: 1 / 1; transition: opacity 200ms var(--ease-out), transform 200ms var(--ease-out), filter 200ms var(--ease-out); } .command__copy .i-check, .command__copy[data-state="copied"] .i-copy { opacity: 0; transform: scale(.25); filter: blur(4px); } .command__copy[data-state="copied"] .i-check { opacity: 1; transform: none; filter: none; } @media (hover: hover) and (pointer: fine) { .command__copy:hover { background: color-mix(in srgb, var(--on-media) 22%, transparent); } } @media (prefers-reduced-motion: reduce) { .command__copy svg { transform: none !important; filter: none !important; transition: opacity 150ms ease; } } ``` ```js // hero.js // Header: glass after scrolling starts (R8) const header = document.querySelector(".site-header"); new IntersectionObserver(([entry]) => { header.dataset.scrolled = String(!entry.isIntersecting); }).observe(document.getElementById("top-sentinel")); // Copy command (R5 without React) for (const button of document.querySelectorAll("[data-copy]")) { const status = button.parentElement.querySelector('[role="status"]'); let timer; button.addEventListener("click", async () => { try { await navigator.clipboard.writeText(button.dataset.copy); button.dataset.state = "copied"; status.textContent = "Команда скопирована"; clearTimeout(timer); timer = setTimeout(() => { button.dataset.state = ""; status.textContent = ""; }, 1800); } catch { status.textContent = "Не удалось скопировать. Выделите команду вручную"; } }); } window.__motionReady = true; ``` **Skeleton check:** the headline stays at 2 lines from 320 to 1920 px (measured with Onest 600 metrics: «без шаблонов» = 6.44 em, i.e. 257 px of the 280 available at 320 px with 40 px type); lead and footnote contrast measured at the lightest spot of the photo; with the glass header and the command field there are 2 glass roles per viewport; with JS disabled everything is visible and works except copying. --- ## 18. Delivery Gate (pre-handoff check) ### 18.1 Format The agent hands off with a table. **A FAIL blocks handoff. "Not checked" counts as FAIL.** Evidence: a screenshot path, a measured value, `file:line` or command output. | # | Check | Status | Evidence | |---|---|---|---| | B2 | h1 at most 2 lines at 320–1920 px | PASS | `shots/hero-320.png` … `hero-1920.png` | | C1 | `--ink-2` contrast on `--bg-2` | PASS | 4.66:1 | ### 18.2 Checklist **A. Direction and anti-slop** - A1 Design Read, Dials and surface mode are recorded (§1.4–1.5). - A2 One signature, one centered moment, the logo-swap test passes. - A3 Not a single item from §3 (autochecks §18.3 + screenshot review). - A4 Glass only in the functional layer, at most 2 roles per viewport, fallbacks in place. - A5 One accent, at most ~5 % of the area. **B. Typography** - B1 Onest loads with Cyrillic (Network tab), font swap without a jump. - B2 h1 at most 2 lines at 320, 390, 768, 1024, 1280, 1440, 1920 px. - B3 Tracking and leading per §4.4; at most 3 weights and 6 sizes per page. - B4 Guillemets, `…`, non-breaking spaces, no dangling prepositions or one-word lines, no dashes in UI. - B5 Figures in prices, tables and counters are tabular. **C. Color and contrast** - C1 Measurement table: text from 4.5:1, large text from 3:1, icons, input borders and focus from 3:1. - C2 Text over media measured at the lightest point beneath it. - C3 Dark theme: every surface checked, the toggle works without a flash. - C4 Tokens only; no hex literals outside `tokens.css`. - C5 `::selection`, `caret-color`, `scrollbar-color`, `theme-color` are styled. **D. Grid and responsive** - D1 No horizontal scroll at 320 px. - D2 Hero headline, phrase and action visible without scrolling at 1280×800 and 390×844. - D3 Section rhythm varies, all spacing comes from the scale, no orphans in grids. - D4 At 1920 px content is bounded by the container; no extra columns. **E. Components** - E1 Every control has hover, focus, active, disabled, loading, error (state screenshots). - E2 One primary per viewport; button labels don't wrap. - E3 Forms: visible labels, error at the field, focus moves to the first error, paste allowed. - E4 Empty, loading and error states exist and are written per §10.10–10.11. - E5 No links to nowhere and no buttons without behavior. **F. Motion** - F1 The chosen MOTION budget is respected: one entry pattern, one scroll choreography. - F2 Motion tokens only; no `transition: all`; transform and opacity animated (filter and clip-path deliberately). - F3 Reduced motion (DevTools emulation): no movement, all content visible. - F4 With JS disabled content is visible; if scripts fail, the safety net fires after 2.5 s. - F5 Animations are interruptible, input isn't blocked, motion longer than 5 s can be paused. - F6 At 10 % speed: no jank, origin at the trigger, exit faster than enter. **G. Accessibility** - G1 Full keyboard pass: order, visible focus, Esc, focus traps only in modals. - G2 Screen reader: landmarks, one h1, no skipped levels, icon-button labels, live regions. - G3 Touch targets from 44×44 (min 24×24). - G4 200 % zoom, 320 px width, forced colors, reduced transparency, increased contrast. **H. Performance** - H1 LCP, INP, CLS measured and reported as numbers (lab; field data if available). - H2 The LCP image is not lazy and has `fetchpriority="high"`; all media have dimensions; AVIF / WebP. - H3 One variable font file, only the critical one preloaded. - H4 Tested on iPhone Safari in Low Power Mode or with 4× CPU slowdown. **I. Honesty** - I1 No invented numbers, testimonials, logos or faces. - I2 All placeholders listed as a TODO list in the reply. - I3 A form without a backend says so. **J. Code** - J1 Imports: `motion/react` (no `framer-motion`), named Lucide icons, modular anime.js. - J2 No `outline: none` without a replacement, no `100vh`, no `overflow-x: hidden` on html and body, no `user-scalable=no`. - J3 Production build checked: `backdrop-filter` and the `-webkit-` prefix are in place. ### 18.3 Autochecks ```bash # Banned patterns rg -n "transition:\s*all|outline:\s*none|\b100vh\b|overflow-x:\s*hidden|user-scalable=no|maximum-scale=1|from ['\"]framer-motion['\"]" src # Hex literals outside tokens rg -n "#[0-9a-fA-F]{3,8}\b" src -g '!**/tokens.css' -g '!**/*.svg' # AI-cliché icons and whole-library imports rg -n "\b(Sparkles|WandSparkles|Rocket|BrainCircuit|Bot|Gem|Zap)\b|import \* as \w+ from ['\"]lucide" src # Filler words (RU + EN) rg -n -i "революц|инновац|бесшовн|нового поколения|на базе ии|раскройте|погрузитесь|seamless|cutting-edge|next-gen|revolutionary|supercharge|unlock" src # Dashes in UI copy rg -n " — | – " src -g '*.{tsx,jsx,vue,svelte,astro,html,mdx}' # Animating layout properties rg -n "transition:[^;]*\b(width|height|top|left|margin|padding)\b" src ``` ### 18.4 Self-score and "remove one accessory" Before handoff, score each axis 1 to 5. **Anything below 4 gets fixed before handoff.** | Axis | Question | |---|---| | **P** Purpose | Does every element serve the screen's goal? | | **H** Hierarchy | Is it clear within 3 seconds what matters and what to press? | | **E** Execution | Are spacing, alignment, states and copy finished? | | **S** Specificity | Does the page belong only to this product (logo-swap test)? | | **R** Restraint | One accent, one signature, nothing extra? | | **V** Vitality | Is there life (media, rhythm, motion) rather than a sterile template? | Then **remove one decorative element** and compare screenshots. If it's no worse without it, it doesn't come back. ### 18.5 Review format for an existing UI | Severity | Where | Before | After | Why | |---|---|---|---|---| | Blocker | `Hero.tsx:42` | `outline: none` on a button | `:focus-visible` ring 2 px `--focus` | WCAG 2.4.7, §13 | | Major | «Возможности» section | 3 identical cards with icons in circles | one large scene + a list | template, §3.3 | | Minor | Footer | `...` | `…` | §4.8 | Severity: **Blocker** (accessibility, honesty, broken behavior), **Major** (slop, hierarchy, motion), **Minor** (polish). Verdict: "Block", "Changes needed" or "Accepted". --- ## 19. Installing the skills Skills install into the project (or globally with `-g`) for the chosen agents via the Skills CLI. The skill names below were checked against each repository's `--list` output. **Flags:** `-s, --skill` space-separated names · `-a, --agent` space-separated agents (`claude-code`, `cursor`, `codex`, `windsurf`, `github-copilot`, `gemini-cli`, `opencode`, etc.; `'*'` for all) · `-g` global · `-y` no prompts · `-l` list a repository's skills · `npx skills use @` use once without installing. ```bash # Core: design and anti-slop npx skills@latest add anthropics/skills --skill frontend-design npx skills@latest add Leonxlnx/taste-skill --skill design-taste-frontend npx skills@latest add miqdadbadjuber/anti-slop --skill antislop antislop-ui antislop-copywriting antislop-layoutmobile npx skills@latest add nextlevelbuilder/ui-ux-pro-max-skill --skill ui-ux-pro-max npx skills@latest add pbakaus/impeccable --skill impeccable npx skills@latest add Nutlope/hallmark --skill hallmark # Emil Kowalski: design engineering and animation npx skills@latest add emilkowalski/skills --skill emil-design-eng animate animation-performance review-animations improve-animations # Apple: both skills are named apple-design, install one npx skills@latest add dickwu/apple-design-skill # HIG + Liquid Glass # npx skills@latest add emilkowalski/skills --skill apple-design # Designing Fluid Interfaces → web # use the other one ad hoc: npx skills use emilkowalski/skills@apple-design | claude # Motion npx skills@latest add motiondivision/ai-kit --skill motion npx skills@latest add BowTiedSwan/animejs-skills --skill animejs # GSAP only if the project already uses GSAP: # npx skills@latest add greensock/gsap-skills --skill gsap-core gsap-timeline gsap-scrolltrigger gsap-react gsap-performance # Guidelines and polish npx skills@latest add vercel-labs/agent-skills --skill web-design-guidelines npx skills@latest add ibelick/ui-skills --skill baseline-ui fixing-accessibility fixing-motion-performance npx skills@latest add jakubkrehel/make-interfaces-feel-better # Example: Claude Code and Cursor only, no prompts npx skills@latest add pbakaus/impeccable --skill impeccable -a claude-code cursor -y ``` **Optional:** - `199-biotechnologies/motion-dev-animations-skill` (`motion-dev-animations`): many Motion recipes, but its defaults (`whileHover` scale 1.05, magnetic buttons) contradict Apple style. Reference only. - `LottieFiles/motion-design-skill` (`motion-design`): timings and principles for Lottie. - `VoltAgent/awesome-design-md`: not a skill. Its `design-md/apple/DESIGN.md` can go into the project as an apple.com breakdown. - anti-slop has its own installer: `npx antislop-ai`. **Connecting this Ruleset:** §0.1. Skills with similar triggers (frontend-design, taste, impeccable, hallmark, antislop) may load at the same time; §2 resolves their conflicts and §0.3 sets the priority. --- ## 20. Sources **Skills:** the repositories in §19, plus `vercel-labs/web-interface-guidelines`. **Docs:** [Motion](https://motion.dev/docs) · [anime.js v4](https://animejs.com/documentation) · [Lucide](https://lucide.dev) · [Onest](https://fonts.google.com/specimen/Onest) · [Apple HIG](https://developer.apple.com/design/human-interface-guidelines) · [WCAG 2.2](https://www.w3.org/TR/WCAG22/) · [Core Web Vitals](https://web.dev/articles/vitals) **Versions checked against npm at compile time:** lucide-react, lucide, lucide-static, @lucide/vue, @lucide/svelte, @lucide/angular, @lucide/astro 1.67.0 · motion 14.9.0 · animejs 4.5.0 · gsap 3.15.0 · @gsap/react 2.1.2 · @fontsource-variable/onest 5.3.1.