# UI components and states

North brand guidelines for AI agents · https://identity.north.ae/AGENTS/components · Updated 2026-10-14
Use when: Building any product UI component: buttons, inputs, selects, secrets, tabs, menus, badges, chips, cards, lists, code blocks, accordions, tooltips, dialogs, drawers, calendars.
Rules that always apply: https://identity.north.ae/AGENTS

## Library
- Reference implementation: `/assets/tokens/north-components.css` (classes `.n-btn`, `.n-input`, `.n-select`, `.n-check`, `.n-radio`, `.n-switch`, `.n-badge`, `.n-chip`, `.n-pill`, `.n-tag`, `.n-tabs/.n-tab`, `.n-segmented`, `.n-ribbon`, `.n-breadcrumb`, `.n-pagination/.n-page`, `.n-stepper`, `.n-tree`, `.n-menu`, `.n-burger`, `.n-card`, `.n-avatar`, `.n-list`, `.n-dl`, `.n-accordion`, `.n-tooltip`, `.n-code/.n-copy`, `.n-media`, `.n-cal`, `.n-table`, `.n-alert`, `.n-toast`, `.n-progress`, `.n-spinner`, `.n-dots`, `.n-pulse`, `.n-skel`, `.n-ghost`, `.n-dialog`, `.n-drawer`, `.n-popover`, `.n-scrim`). Requires north-tokens.css. Tailwind recipes: /AGENTS/tailwind.
- Machine-readable component tokens (states as separate entries): `/DESIGN.md`.

## State model (every interactive component)
| State | Treatment | Set by |
|---|---|---|
| Hover | one step stronger background/border; pointer only | :hover |
| Focus | 3px --n-focus outline, 2px offset | :focus-visible |
| Pressed | 1px down shift, slightly darker | :active |
| Selected/current | filled/underlined/checked + aria state | aria-selected, aria-current, aria-pressed, :checked |
| Disabled | 40% opacity, no pointer events, explain why nearby | disabled / aria-disabled |
| Loading | spinner replaces label, width kept, clicks ignored | aria-busy="true" |
| Error | danger border + message below with icon | aria-invalid="true" + aria-describedby |
| Read-only | subtle background, selectable | readonly |

## Sizes
- Controls 32px / 40px (default) / 48px; touch target ≥ 44px; icons 16/20/24. Comfortable density default; compact (32px rows, 8px gaps) for operator tools, never text < 13px.

## Buttons
- Variants: primary (bg --n-action, text --n-text-on-action, hover --n-action-hover), secondary (1px --n-border-ui, raised surface), tertiary (text --n-text-link), danger (bg --n-status-danger, text --n-text-on-danger), danger-secondary (outlined red, opens confirmation), inverse (marketing on dark).
- Radius 8, padding 12/16/22px, Text Medium 15px, icon 18px leading with 8px gap. One primary per view; primary last in a row (first in RTL).
- Labels: specific verbs in sentence case ("Send 3 emails"), consistent through the flow (Publish → Publishing… → Published). Never "OK", "Submit", "Click here".
- Press feedback: pressed state immediately; loading after ~300ms; success = past-tense label + check for 1.5s; failure = restore + error next to the button.
- Icon buttons 40px (32 small), aria-label + tooltip. Floating over images: Midnight 95 at 64% + 8px backdrop blur, Snow icon.
- Burger: 3 × 20px lines (1.75px) morphing to a cross in 220ms; leading edge of the header; only below 960px; aria-expanded/aria-controls; opens a drawer from the same edge with scrim.
- Copy buttons: top-right of the code block header (top-left RTL), 10px inset; label → "Copied" + check for 1.5s; inline icon button after single values.

## Forms
- One column, labels above (Text Medium 14px), hints/errors below (13px with 15px icon), placeholders only for example formats, "Optional" marker instead of asterisks, validate on blur and submit, keep input on error, error summary on submit.
- Input: 40px, 1px Steel 20, radius 8, focus border --n-focus + 3px 22% halo, error border --n-status-danger, disabled panel background.
- Secrets/passwords: masked, JetBrains Mono, reveal button with changing aria-label ("Show key"/"Hide key"), strength meter (4 bars), copy without revealing, re-mask on blur, never prefill or show in toasts/logs, proper autocomplete.
- Select: native for ≤ ~15 options; combobox for long lists; listbox menu (radius 12, shadow 3, 6px padding, 36px items, check at trailing edge) for rich options.
- Checkbox (20px, radius 5) for independent choices; radio for one of 2–6; switch for instant settings; segmented control for views.
- Date picker: typed entry plus calendar; weeks start Monday; today ring; selected filled action; ranges tinted; disabled struck through; event dot Oasis 70; time zone (GST) beside time.
- Upload: dashed 1.5px drop zone, accepted types, size limit, "files stay on this machine".
- Specialised inputs: search field (icon, clear, ⌘K hint, debounced results), combobox (matches SemiBold, arrows/Enter/Esc, "Create …" when allowed), input group (non-editable prefix/suffix add-ons on panel bg), number field (steppers for small counts, tabular, unit suffix), verification code (one Mono 22px box per digit, 3+3, auto-advance, paste fills, autocomplete="one-time-code"), time field (24-hour segments + time zone), date range (two fields, one calendar, presets), slider (value beside label, end marks, typed alternative).

## Navigation
- Underline tabs (2px Midnight underline on active, caption colour inactive, 2–7 tabs, scroll on overflow), segmented control (raised white segment), ribbon tabs (joined to panel, 2px action-colour top edge). Disabled = 40%, skipped by arrows.
- Breadcrumbs for depth > 2 (current page plain text, aria-current); mobile shows parent back link.
- Pagination with range text ("1–25 of 291"); current page filled Midnight.
- Stepper only for real sequences.
- Hierarchies: reading content → section navigation (.n-secnav: section labels in small caps with trailing chevron, pages 15px with current page bold, on-page headings 13.5px on a 1px guide line indented 24px, heading in view = heading colour + 3px bar centred on the guide line, aria-current="location"). Working with objects → tree (.n-tree, role="tree": rows 14px + 16px icon, leading chevron, 24px indent with guide line, current item = heading colour + SemiBold + 3px bar on the guide line (aria-current), selected = action tint (aria-selected), row actions on hover/focus/selection, ≤ 3 visible levels). Both mirror in Arabic.
- Menus: separators and labels, destructive last in red, shortcuts trailing in kbd, 36px items (44 touch). Command palette on ⌘K / Ctrl+K and /.
- App navigation: sidebar 240–280px ≥1280px; icon rail 64px at tablet; burger drawer or bottom tabs (3–5) on phones.

## Content
- Badges: 22px, radius 4, 11.5px bold, one or two words; neutral/info/success/warning/danger/AI/solid. The AI badge marks only AI output/activity.
- Pills (read-only, full radius, panel fill), filter chips (outline; selected = filled Midnight), input chips (with remove), tags (mono, outline, radius 4) for versions/IDs/models.
- Avatars: people = initials on Dawn/Oasis/Gulf tints; agents = Midnight with Oasis agent icon. Cards: radius 16, 1px border, 24px padding, shadow 2 on hover only, selected = 2px action border.
- Lists: bullets (Midnight 50 markers), numbered steps in 24px panel circles, nested numbering 1 → a, check lists, description lists.
- Code blocks: Midnight 95 in both modes, radius 16, JetBrains Mono 13.5/1.65, header with filename + copy; syntax: keys Oasis 30, strings Dawn 40, numbers Gulf 20, comments Midnight 40 italic; line numbers Midnight 50; highlighted line = faint Oasis band + 2px edge; no wrap; omit shell prompts.
- Accordion: native details/summary, trailing chevron rotating 180° in 220ms. Tooltips: 400ms delay, Midnight bubble (Snow in dark), 12.5px; never essential info.
- Scroll areas: 10px Steel 30 thumbs, transparent track, never on page body; fade last 32px.
- Meters (levels in a known range: seats, storage, context): 8px track, action colour < 80%, warning ≥ 80%, danger ≥ 95%, always with the number in words. Progress rings 48px (with %) / 24px (tooltip) for completion in tight spaces.
- Toggle buttons (aria-pressed, pressed = panel fill + UI border) grouped in toolbars: 36px buttons, 2px gaps, separators between groups, one row, overflow into "More", role="toolbar" with arrow keys.

## Overlays
- Dialog: 480px (640 forms), radius 24, shadow 4, scrim --n-scrim + 4px blur, title asks the question, action-named buttons (danger last), native <dialog>, focus trapped and returned, never stacked.
- Drawer: trailing edge, 380–480px; bottom sheet on mobile (≤ 90% height, handle). Mai docked panel = non-modal drawer.
- Image overlays: actions top-right (top-left RTL) 12px inset, 8px gaps (zoom, download, more), visible on hover/focus (always on touch); badges top-left; caption bottom on Midnight gradient. Zoom viewer on 92% Midnight 95.
- Placement: menus below trigger 6px; popovers 8px with arrow; tooltips above 8px; toasts bottom-right (bottom-left RTL, bottom-centre mobile) 24px, max 3.
