# Kutby Design System

**Status:** Binding engineering design contract  
**Applies to:** Every page, component, admin screen, frontend template, and feature  
**Theme:** Kutby  
**Audience:** Engineers, reviewers, and future maintainers  

This document is not a mood board. It is the **visual and interaction law** of Kutby.

Every future UI must follow this contract. Creativity that breaks consistency is rejected.

### Design priorities

1. Simplicity  
2. Readability  
3. Accessibility  
4. Consistency  
5. Performance  
6. Scalability  

### Visual direction

Modern · Clean · Professional · Minimal · Educational · Fast  

Avoid trendy UI that ages quickly. Prefer calm surfaces, clear hierarchy, and durable patterns.

**Related contracts:** `PERFORMANCE.md` (speed), Foundation architecture reports (structure). Design must never violate performance rules.

---

## 1. Design Philosophy

### Content first

Kutby serves educational platforms. Lessons, courses, articles, and Admin settings are the product. The interface exists to support them.

### Interface second

Controls, chrome, and navigation must be clear and quiet. They guide; they do not perform.

### Decoration last

Ornament is optional. If removing a shadow, gradient, badge, or animation does not hurt understanding, remove it.

### Non-negotiables

- The UI must **never compete** with educational content.
- Every component must have a **purpose**.
- **Consistency beats creativity.** Prefer the existing pattern over a clever new one.
- Prefer **fewer variants** that work everywhere over many one-off skins.
- Design decisions must be expressible as **tokens + components**, not as one-off CSS.

---

## 2. Typography

### Primary font

**Tajawal** only (local files). Fallback: `Tahoma, sans-serif`.

- No Google Fonts CDN  
- No alternative display fonts for “brand flair”  
- `font-display: swap`  

Code identifiers remain English; **UI copy for this theme remains Arabic** in Admin and frontend product surfaces unless a feature explicitly documents otherwise. Layout is **RTL**.

### Type scale (token-aligned)

| Role | Token / size | Typical use |
|------|----------------|-------------|
| Caption / meta | `--kutby-font-size-sm` (0.875rem) | Hints, timestamps, helper text |
| Body | `--kutby-font-size-body` (1rem / 16px baseline) | Paragraphs, form values |
| Lead / emphasis | `--kutby-font-size-lg` (1.125rem) | Intro lines, panel leads |
| Title small | `--kutby-font-size-xl` (1.25rem) | Card titles, subheads |
| Title | `--kutby-font-size-2xl` (1.5rem) | Section titles |
| Display | `--kutby-font-size-3xl` (1.875rem) | Page heroes / H1 (frontend) |

Do not invent intermediate sizes (e.g. `15px`, `17px`) in feature CSS.

### Weights

| Token | Weight | Use |
|-------|--------|-----|
| `--kutby-font-weight-normal` | 400 | Body copy |
| `--kutby-font-weight-medium` / semibold | 500 | Labels, nav, UI chrome |
| `--kutby-font-weight-bold` | 700 | Headings, strong emphasis |

Avoid 300/800/900 unless Theme Options explicitly expose them and tokens are updated.

### Line height & spacing

| Token | Value | Use |
|-------|-------|-----|
| `--kutby-line-height` | 1.7 | Body, Arabic long-form |
| `--kutby-line-height-tight` | 1.35 | Headings, compact UI |
| `--kutby-letter-spacing` | 0 | Default; do not track Arabic aggressively |

Paragraph spacing: prefer **one spacing step** between blocks (`space-4`–`space-5`), not arbitrary margins.

### Heading hierarchy (H1–H6)

| Level | Intent |
|-------|--------|
| H1 | One per page/view — primary title |
| H2 | Major sections |
| H3 | Subsections / card groups |
| H4–H6 | Rare; prefer H3 + weight/size tokens before inventing deeper styles |

Do not skip levels for visual size alone. Style with tokens; keep semantics correct.

### Text colors

| Role | Token |
|------|-------|
| Primary text | `--kutby-color-text` |
| Secondary / muted | `--kutby-color-muted` |
| Links | `--kutby-color-link` |
| Link hover | `--kutby-color-hover` |
| On inverse (tooltips, dark chips) | `--kutby-color-on-inverse` |
| Danger text | `--kutby-color-danger` |

### Reading width

- Long-form educational content: aim for **~60–75 characters** per line (comfortable Arabic measure), typically inside a content column ≤ ~720–780px when sidebar is present, or within `--kutby-container-width` for full-width articles with generous line-height.
- Admin labels and controls: short lines; prefer card-row layouts over wide paragraphs.

### Arabic readability rules

- Always `dir="rtl"` for product UI surfaces.
- Prefer Tajawal 400/500/700 only as needed to limit font payload (`PERFORMANCE.md`).
- Avoid ultra-condensed layouts that crush Arabic letterforms.
- Do not justify Arabic body text unless carefully tested; default to start-aligned (right in RTL).
- Do not mix Latin display fonts with Arabic UI chrome.

---

## 3. Color System

**Do not hardcode page colors.** All color usage must go through **Design Tokens** (`Kutby\Design\Tokens` / `src/css/tokens`).

Semantic roles (purpose-driven):

| Role | Token (canonical) | Purpose |
|------|-------------------|---------|
| Primary | `--kutby-color-primary` | Brand actions, key accents, active nav |
| Primary hover | `--kutby-color-hover` | Interactive hover/focus fill for primary actions |
| Secondary | `--kutby-color-secondary` | Deeper brand support, secondary emphasis |
| Accent | `--kutby-color-accent` | Sparse highlights (badges, rare callouts) — not default chrome |
| Success | `--kutby-color-success` | Positive confirmation |
| Warning | `--kutby-color-warning` | Caution without failure |
| Danger | `--kutby-color-danger` | Errors, destructive actions |
| Info | Notice info tokens / muted primary | Neutral informational state |
| Background | `--kutby-color-bg` | Page canvas |
| Surface | `--kutby-color-surface` | Subtle regions, secondary buttons, table stripes |
| Card / elevated surface | `--kutby-color-card` | Panels, cards, dialogs |
| Border | `--kutby-color-border` | Dividers, input edges, hairlines |
| Muted | `--kutby-color-muted` | Secondary text, placeholders |
| Text primary | `--kutby-color-text` | Main copy |
| Text secondary | `--kutby-color-muted` | Supporting copy |
| Disabled | `--kutby-opacity-disabled` on controls + muted text | Unavailable UI |
| Focus | `--kutby-focus-ring` | Keyboard focus visibility |
| Selection | Derive from primary at low opacity (tokenize when implemented) | Text selection |
| Overlay | `--kutby-overlay` | Modal scrims |
| Scrollbar | Prefer neutral border/surface tones | Non-branded chrome |
| Code | Surface + border + monospace fallback (when needed) | Code blocks — rare in theme |
| Link | `--kutby-color-link` | Inline links |
| Visited | Keep close to link/secondary; do not invent purple trends | Visited links |
| On-inverse | `--kutby-color-on-inverse` | Text/icons on dark fills |

Notice surfaces use dedicated tokens (`--kutby-notice-*-bg|fg|bd`) so status UI stays consistent and Dark Mode–ready.

**Rule:** If a hex value appears in feature CSS, it is a defect unless it is defining a token in the token source files.

---

## 4. Spacing System

Use the scale. Do not invent `13px`, `22px`, or “visually tweaked” gaps.

| Token | Value | Typical use |
|-------|-------|-------------|
| `--kutby-space-1` | 0.25rem | Icon gaps, tight inline padding |
| `--kutby-space-2` | 0.5rem | Compact control padding, chip gaps |
| `--kutby-space-3` | 0.75rem | Form field internal comfort, list item padding |
| `--kutby-space-4` | 1rem | Default component padding, form row gaps |
| `--kutby-space-5` | 1.5rem | Card padding, panel header spacing |
| `--kutby-space-6` | 2rem | Section padding (compact), card group gaps |
| `--kutby-space-8` | 3rem | Major section spacing |
| `--kutby-space-10` | 4rem | Large frontend section rhythm (sparingly) |

### Application map

| Context | Guidance |
|---------|----------|
| Component spacing | `space-2`–`space-4` inside controls |
| Card spacing | Padding `space-4`–`space-5`; gap between cards `space-3`–`space-4` |
| Section spacing | Frontend vertical rhythm `space-6`–`space-8` |
| Grid spacing | Gaps `space-4`–`space-6` |
| Form spacing | Vertical stack `space-4`; label-to-control `space-2` |
| Content spacing | Paragraphs ~`space-4`; heading-to-body `space-3`–`space-4` |

**Avoid arbitrary spacing.** If a layout needs a new step, extend the token scale — do not special-case one page.

Whitespace is intentional. Prefer consistent vertical rhythm and grouping over extra borders; full Visual Rhythm rules live in Section 27.

---

## 5. Border Radius

| Token | Value | Use |
|-------|-------|-----|
| `--kutby-radius-sm` | 6px | Inputs, small chips, tooltips |
| `--kutby-radius-md` | 10px | Cards, notices, dropdowns, default controls |
| `--kutby-radius-lg` | 16px | Panels, modals, large media frames |
| `--kutby-radius-full` | 999px | Pills, badges, loaders, avatars (circle via equal width/height) |

### Rules

- Prefer **md** for most Admin UI.
- Do not mix sharp 0px corners with heavy radii on the same surface without reason.
- Circles are geometric (equal box + `radius-full`), not a separate ad-hoc radius.

Default border width: `--kutby-border-width` (1px).

---

## 6. Elevation

### Philosophy

Kutby prefers **borders and surface contrast** over heavy shadows.

Shadows exist to show **temporary layering** (dropdowns, modals, sticky elevation) — not to decorate every card.

### Levels

| Level | Token | When |
|-------|-------|------|
| 0 Flat | Border + surface/card | Default cards, forms, tables |
| 1 Soft | `--kutby-shadow-sm` | Subtle lift (rare) |
| 2 Raised | `--kutby-shadow-md` | Dropdown menus, floating panels |
| 3 Overlay | `--kutby-shadow-lg` | Modals / dialogs |

### Rules

- Prefer **border** for persistent structure.
- Prefer **shadow** for ephemeral overlays.
- Do not stack multiple shadows or neon glows.
- Dark Mode readiness: shadows should remain low-contrast; surfaces carry hierarchy.

---

## 7. Grid System

### Widths

| Token | Role |
|-------|------|
| `--kutby-container-width` | Primary content container (default ~1200px) |
| `--kutby-site-width` | Outer site shell / max site frame (~1400px) |

Theme Options may override container/site width; components must consume tokens, not hardcode.

### Breakpoints (reference tokens)

| Token | Approx | Behavior |
|-------|--------|----------|
| `--kutby-bp-sm` | 480px | Compact phones → comfortable phones |
| `--kutby-bp-md` | 768px | Tablet / small laptop split |
| `--kutby-bp-lg` | 1024px | Desktop layouts, sidebars |
| `--kutby-bp-xl` | 1280px | Wide desktop enhancements |

Use mobile-first media queries. Prefer behavior (“stack nav”, “show sidebar”) over pixel perfection.

### Columns, gaps, alignment

- Frontend grids: simple 1 → 2 → 3/4 columns as viewport grows.
- Gaps from spacing scale (`space-4`+).
- Content alignment in RTL: logical properties (`inset-inline`, `margin-inline`, `text-align: start`) over physical left/right.
- Admin shell: sidebar + main; collapse to single column below ~960px.

---

## 8. Icons

### Rules

- **SVG only** via Icon Registry / Icon helper.
- **No icon fonts** (Dashicons allowed only where WordPress Admin menu APIs technically require a menu icon).
- Consistent stroke (~1.75 in source icons) and `currentColor`.
- Sizes:

| Size | Class / intent |
|------|----------------|
| sm | `--` / `kutby-icon--sm` (~1rem) — dense nav |
| md | default (~1.25rem) — standard UI |
| lg | (~1.5rem) — emphasis |

Do not scale icons with random width/height in page CSS. Use the size system.

---

## 9. Motion

### Philosophy

Fast. Subtle. Useful. Never distracting.

Motion clarifies state change (open/close, hover, loading). It is not entertainment.

### Durations & easing

| Token | Value | Use |
|-------|-------|-----|
| `--kutby-transition` | 150ms ease | Hover, focus, color, border |
| `--kutby-transition-slow` | 250ms ease | Panels, dropdown appearance |
| Loader spin | ~0.7s linear | Indeterminate progress only |

### Rules

- Prefer CSS transitions over JS animation libraries.
- Animate `opacity` and `transform` only (see `PERFORMANCE.md`).
- Hover: slight color/border change — no bouncing.
- Focus: visible ring via `--kutby-focus-ring`, not motion-heavy outlines.
- Loading: loader/skeleton — avoid full-page animated wallpaper. Prefer skeletons for content regions (**Section 20**).
- Honor `prefers-reduced-motion: reduce` (disable non-essential motion).

---

## 10. Accessibility

### Requirements

- Full **keyboard navigation** for interactive Admin and frontend controls.
- **Visible focus** at all times for keyboard users (`--kutby-focus-ring`).
- **Contrast:** text and interactive elements aim for WCAG AA against their surfaces.
- **Touch targets:** aim ≥ 44×44px for primary mobile controls; do not shrink icon-only hit areas without padding.
- **ARIA:** use when semantics are insufficient; prefer native elements (`button`, `a`, `label`, `details`) first.
- **Screen readers:** meaningful labels; do not rely on color alone for status (pair with text/icons).
- **Reduced motion:** respect user preference.
- RTL: ensure focus order and overflow behave correctly; test with Arabic copy length.

Accessibility is not optional polish. A beautiful inaccessible component fails this contract.

---

## 11. Component Principles

Every component (Admin UI library and future frontend components) must be:

1. **Single responsibility** — one job, one clear API.
2. **Reusable** — no page-only forks of the same control.
3. **Configurable** — via props/args/attrs, not copy-paste variants.
4. **Accessible** — keyboard, focus, labels.
5. **Minimal DOM** — no decorative wrapper stacks.
6. **Non-duplicated** — one button system, one notice system, one card pattern.
7. **No inline styles** for design values — tokens/classes only.
8. **Token-driven** — colors, space, radius, motion from the design system.
9. **Performance-aware** — compatible with `PERFORMANCE.md` budgets.
10. **Documented by Showcase** — Admin components appear in UI Showcase when debug-enabled.

New UI must use existing Components when available. Duplicating markup is a design-system violation.

---

## 12. Admin UI Principles

The Control Center (**كتبي**) should feel:

**Fast · Professional · Native · Comfortable**

### Forms

- Label + control card rows (existing Admin card pattern).
- Clear Arabic labels; hints as secondary muted text.
- Primary save actions use primary button; destructive actions use danger/ghost carefully.
- Validate before save; surface errors via Notices.
- Full field/layout rules: **Section 22 Forms Standard**.

### Tables / lists

- Prefer Kutby surfaces over default WP table chrome when building theme screens.
- Paginate large datasets; avoid dense undecorated walls of data.
- Align numeric columns consistently; keep RTL headers readable.
- Full data-table rules: **Section 23 Tables**.

### Dashboard

- Overview first: version/status and next steps — not a marketing billboard.
- Widgets must stay light and cached (`PERFORMANCE.md`).
- Empty and loading states for widgets: **Sections 19–20**.

### Navigation

- Persistent sidebar with SVG icons + Arabic labels.
- Active state via primary color, not heavy shadows.
- Developer-only pages (UI Showcase) must not disturb primary IA for normal users.
- Broader navigation contract: **Section 25 Navigation Principles**.

### Settings pages

- One concern per panel.
- Reuse AbstractPage + Components + Field Registry.
- No native WP settings tables for Kutby options screens except where technically required.
- Feedback after save/error: Notices / **Section 21 Feedback States**.

---

## 13. Frontend Principles

- **Educational content first** — typography and measure beat chrome.
- **Large readable headings** with clear hierarchy.
- **Comfortable reading width** and generous line-height for Arabic.
- **Clear hierarchy** — H1 → sections → cards/lists.
- **Fast interaction** — deferred JS, minimal global scripts.
- **Minimal distractions** — no sticker UI, no animated noise, no card overload in the first viewport of marketing surfaces when those are designed later.

Future homepage/template design must still obey this contract and `PERFORMANCE.md`.

---

## 14. Responsive Strategy

**Mobile first.**

| Stage | Behavior |
|-------|----------|
| Mobile | Single column; stacked nav; full-width controls; large tap targets |
| Tablet | Optional two-column cards; condensed sidebar patterns |
| Desktop | Sidebar + main Admin; content + widget frontend layouts |
| Large screens | Constrain with container/site width; do not stretch prose endlessly |

Define **behavior** (stack, collapse, hide secondary) before fine pixel tweaks.

Use logical CSS properties for RTL-safe responsiveness.

---

## 15. Dark Mode Readiness

Initial release **does not ship Dark Mode**.

### Mandatory preparation

- Components must remain **compatible** with a future dark palette.
- **No hardcoded colors** in components/templates — tokens only.
- Semantic tokens (background, surface, text, border, notices) must be the only color API.
- Avoid baking “white card / dark text” assumptions into component structure; assume token values can invert later.
- Images/illustrations that assume a light canvas need future alternatives or neutral treatments.

When Dark Mode arrives, it should be a **token switch**, not a component rewrite.

---

## 16. Naming Conventions

### Tokens

- CSS: `--kutby-{category}-{name}`  
  Examples: `--kutby-color-primary`, `--kutby-space-4`, `--kutby-radius-md`
- PHP map keys match CSS custom property names.

### Components (PHP / UI)

- Classes under `Kutby\Admin\UI\Components` (and future frontend component namespaces).
- Method names: short nouns/verbs (`button`, `card`, `notice`, `media_upload`).

### CSS classes

- Namespace: `.kutby-…`
- Block: `.kutby-card`
- Element: `.kutby-card__label`
- Modifier: `.kutby-btn--primary`, `.kutby-notice--success`
- State: `.is-active`, `.is-open`, `.is-loading`, `.is-dismissible`

### Variants & modifiers

- Prefer **one block + modifiers** over parallel class families (`kutbyBtnPrimary` ❌).
- Size modifiers: `--sm`, `--md`, `--lg` or icon size classes already defined.
- Do not invent synonym modifiers (`--main` vs `--primary`).

### Inconsistency is debt

If two names mean the same thing, keep one and migrate. Do not dual-support forever without a deprecation note.

---

## 17. Future Checklist

Before approving any UI:

- [ ] **Uses Tokens** — no raw hex/spacing/radius in feature CSS
- [ ] **Uses Components** — no duplicated Admin/frontend markup
- [ ] **Responsive** — mobile-first, RTL-safe
- [ ] **Accessible** — focus, contrast, keyboard, labels
- [ ] **Consistent** — matches existing patterns
- [ ] **No duplicated design** — no one-off twin components
- [ ] **No unnecessary complexity** — simplest structure that works
- [ ] **Performance preserved** — complies with `PERFORMANCE.md`
- [ ] **Arabic/RTL preserved** — labels and direction unchanged unless explicitly scoped
- [ ] **Dark Mode ready** — token-driven surfaces only
- [ ] **UX clarity** — screen answers where / what / happened / next (Section 18)
- [ ] **Empty / loading / feedback states** handled deliberately (Sections 19–21)
- [ ] **Forms / tables / search / dialogs** follow interaction standards (Sections 22–26)
- [ ] **Visual rhythm** — calm spacing, no clutter (Section 27)

---

## 18. User Experience Principles

The interface should **explain itself**. Users should never wonder what to do next.

- Common actions should require **minimal effort**.
- Errors should **help recovery**, not merely announce failure.
- Prefer the **shortest path** to the user’s goal.
- Emphasize **clarity over cleverness**.

Every screen should answer:

1. **Where am I?**
2. **What can I do?**
3. **What happened?**
4. **What should I do next?**

These principles apply to Admin and frontend alike. They extend Design Philosophy; they do not replace it. Speed expectations remain governed by `PERFORMANCE.md`.

---

## 19. Empty States

Never leave users facing a blank page or empty table.

- Every empty view must **explain why** it is empty (no courses yet, no search hits, no widgets configured).
- Provide a **primary action** whenever possible (create, import, clear filters, open settings).
- Provide **secondary guidance** when appropriate (short tip, link to docs/panel).
- Optional illustration is acceptable when it stays calm, token-colored, and non-blocking — never required decoration.
- Empty states should **encourage progress**, not apologize endlessly.

Use Admin Components (panels, buttons, notices) — do not invent one-off empty-page layouts.

---

## 20. Loading States

Aligned with progressive Admin rendering and motion rules:

- Prefer **skeleton screens** over spinners for content regions (lists, cards, dashboard widgets).
- Use compact **loaders** for button-level or inline async actions (`Components::loader` / `is-loading`).
- **Never block the entire interface** unnecessarily; keep chrome and navigation usable.
- Show **progress** whenever duration is meaningful (imports, bulk jobs) — never a frozen page.
- Loading indicators should appear **quickly** when work is expected to exceed a brief moment.
- Avoid **flashing loaders** for very fast operations (sub-~150–200ms); prefer no indicator or an already-stable skeleton.
- **Maintain layout stability** while loading (reserved height / skeletons) to prevent CLS (`PERFORMANCE.md`).

---

## 21. Feedback States

Use the Notices system and semantic notice tokens. Do not invent parallel toast stacks.

| State | Intent |
|-------|--------|
| Success | Confirm completion |
| Information | Neutral status / guidance |
| Warning | Caution without hard failure |
| Error | Blocking or failed action |

### Rules

- Feedback should be **immediate** after the triggering action.
- Messages should be **concise** (Arabic product copy; no jargon).
- Errors should explain, in order:
  1. **What happened**
  2. **Why** (when it helps)
  3. **What to do next**
- Never expose technical details, PHP notices, SQL, or stack traces in UI feedback.
- Success messages should **confirm completion without interrupting workflow** (non-modal Notices; auto-hide when appropriate). Destructive confirmations belong in dialogs (Section 26), not success toasts.

Validation failures from Field Registry must surface through this feedback model.

---

## 22. Forms Standard

Applies to Theme Options panels, future Admin forms, and frontend forms built with Kutby Components / Field Registry.

- Prefer **single-column** layout whenever practical (Admin card rows already support this).
- **Logical field grouping** — related fields share a panel/section; do not scatter unrelated controls.
- **Required fields** clearly identified (schema `required` + visible affordance when introduced).
- **Helpful labels** (Arabic) and **helpful placeholders** that do not replace labels.
- **Inline validation** where it improves recovery; always **validate before submission** (save pipeline).
- **Keyboard friendly** with **logical tab order** (RTL-aware).
- **Preserve user input** after validation errors — never wipe a form on failed save.
- **Consistent spacing** between controls (`space-4` stacks; label-to-control `space-2`).
- Primary submit remains the clear path; secondary/destructive actions stay visually subordinate.

---

## 23. Tables

When presenting tabular Admin or frontend data:

- Prefer Kutby table/list surfaces over default WordPress table chrome on theme screens.
- **Sticky headers** where useful for long lists.
- **Responsive behavior** — stack or prioritize columns on small screens; avoid trapping users in unreadable grids.
- **Sorting** when appropriate; **searching** when lists grow (debounce — Section 24 / `PERFORMANCE.md`).
- Support **bulk actions** only when the task is real; keep **row actions** consistent across rows.
- Avoid unnecessary **horizontal scrolling**; prefer fewer columns or progressive disclosure.
- Maintain **readable density** — not spreadsheet-cramped, not sparse for its own sake.
- Empty tables must use Empty States (Section 19), not a lonely header row.

---

## 24. Search Experience

- **Debounced** querying/filtering — never fire on every keystroke without delay (`PERFORMANCE.md`).
- Provide a **clear** control to reset the query.
- **Highlight matches** where useful and affordable; do not sacrifice readability.
- Provide an **empty state** when no results exist (explain + suggest clearing filters or broader terms).
- **Remember active filters** where appropriate within the session/view.
- Optimize for **fast perceived response** — keep result payloads light; show skeletons if latency is visible.

---

## 25. Navigation Principles

- Users should **always know where they are**.
- **Current page / panel clearly highlighted** (Admin sidebar `is-active`; frontend current-menu classes).
- **Breadcrumbs** for hierarchical frontend (and Admin sub-flows when depth appears).
- Provide **clear back navigation** when a flow leaves the primary IA.
- Keep **menu structure consistent** across releases; do not reshuffle labels for novelty.
- Avoid **navigation dead ends** — every screen offers a way forward or back to a known hub (Control Center / site home).

Admin sidebar specifics remain in Section 12; this section is the cross-surface contract.

---

## 26. Dialog Principles

Use `Components::modal` (and future dialog primitives) — do not invent parallel overlays.

- Use confirmation dialogs **only for destructive or irreversible actions**.
- **Avoid unnecessary confirmations** for routine saves and toggles.
- **Escape** closes dialogs.
- Click outside closes dialogs **only when safe** (never while a destructive confirm is the sole barrier, or while an irreversible process is mid-flight without cancel).
- The **primary action should be visually obvious** (primary button); destructive primary actions use danger styling deliberately.
- Dialogs must **trap keyboard focus** correctly and restore focus on close (Accessibility §10).

---

## 27. Visual Rhythm

- Consistent spacing creates hierarchy — use the Spacing System, not one-off gaps.
- **Whitespace is a design tool**, not empty waste.
- Prefer **spacing before borders** whenever separation can be achieved without extra lines.
- Avoid visual clutter: competing accents, stacked cards-inside-cards, and decorative rules.
- Maintain **consistent vertical rhythm** across pages (same section gaps, same card padding language).
- **Group related elements** visually; separate unrelated groups with space, not noise.
- Every page should feel **balanced and calm** — educational and Admin UIs alike.

---

## Enforcement

- `DESIGN_SYSTEM.md` is the permanent design reference for Kutby.
- UI Showcase (dev-only) is living documentation for Admin Components — it must not diverge from this contract.
- PRs may be rejected solely for design-system violations, even when the feature works.
- Changes to this document require intentional revision; do not weaken standards silently.

**Revision:** 1.1  
**Effective:** Foundation 2.5 stable / frontend-ready era  

Content first. Interface second. Decoration last.
