# Rahhal's Marsam — agent index

Cross-platform design system used by Rahhal mini-apps (web, iOS, Android, slides, marketing). Tokens are surfaced in platform-agnostic forms (#RRGGBB hex, rem/px sizes, font-family names with iOS/Android equivalents). Match by **token name**, not by hex (which differs per theme).

## Where to start

- [Concise agent index](https://marsam.rahhal.app/llms.txt): Start here for the most useful documentation and direct Rahhal icon downloads.
- [Complete reference](https://marsam.rahhal.app/llms-full.txt): All catalog documentation in one text file.
- [Rahhal icons and brand assets](https://marsam.rahhal.app/components/icons.md): Downloadable PNG and SVG assets with React usage.

- `/skill.md` — this file.
- `/why.md` — why this design system exists; problem and use cases.
- `/guidelines.md` — operating rules (compose-first, tokens, RTL, auth, "what to do when a component is missing").
- `/faq.md` — quick answers to onboarding questions.
- Browse the catalog at `/components` (UI) — every entry below has a Markdown twin.
- `/components/colors.md` — every color token (light + dark, hex + HSL, CSS var).
- `/components/typography.md` — font families (web stacks + iOS + Android), type scale, weights.

## All component pages

- [Colors & radius](https://marsam.rahhal.app/components/colors.md): Every design token from @rahhal/themes. Tokens are stored as HSL channels (so Tailwind opacity modifiers compose) AND surfaced as #RRGGBB hex for cross-platform consumers (iOS, Android, slides, Figma). Light + dark are the two themes; system preference is auto-detected on web.
- [Typography](https://marsam.rahhal.app/components/typography.md): Font families (sans · arabic · mono) with web stacks plus iOS/Android equivalents, type scale (rem + px), and weight ramp. Bilingual EN/AR samples live alongside each other.
- [Icons & brand marks](https://marsam.rahhal.app/components/icons.md): Download official Rahhal icons in PNG and SVG, with light and dark variants, React usage, and guidance for Lucide UI icons and social brand marks.
- [RahhalIcon](https://marsam.rahhal.app/components/rahhal-icon.md): Cross-platform icon renderer. Parses the same prefixed catalog strings the iOS shell understands (`url:…`, `emoji:…`, `system:…`, `resource:…`, plus bare URLs/emojis) so a CMS-authored value paints identically on every client. Falls back to a muted square when the value is empty; `system:` and `resource:` render as debug tokens on the web because there's no SF Symbols / iOS bundle equivalent.
- [Button](https://marsam.rahhal.app/components/button.md): Primary actionable element. Six variants and four sizes. Use `asChild` to keep button styling on a router-aware link.
- [Toggle · ToggleGroup](https://marsam.rahhal.app/components/toggle.md): On/off button (`<Toggle>`) and grouped toggle sets (`<ToggleGroup>`). Use for formatting toolbars, view-mode switches, and any compact two-state control. `ToggleGroup` accepts `type="single"` for radio-style behavior or `type="multiple"` for checkbox-style.
- [BackButton](https://marsam.rahhal.app/components/back-button.md): Small ghost capsule with a leading chevron — the standard 'go back' affordance for nested pages. Defaults to `window.history.back()`; pass `onClick` to plug in router-aware navigation. The chevron rotates automatically under RTL.
- [PasteButton](https://marsam.rahhal.app/components/paste-button.md): Icon button that reads the system clipboard and forwards the text to a callback. Defaults to a clipboard glyph; pair with a string-transform helper at the call site (URL extractor, code parser, normaliser).
- [Input & Textarea](https://marsam.rahhal.app/components/input.md): Native `<input>` and `<textarea>` wrappers themed via design tokens. Pair with `<Label htmlFor>` for accessible click-the-text targets.
- [SearchBar](https://marsam.rahhal.app/components/search-bar.md): Capsule-shaped search input with leading magnifier, optional clear button, optional trailing slot (e.g. ⌘K hint), and Enter-to-submit. Wrapped in `<form role="search">` so iOS shows the on-screen "Search" key. Inputs are normally rectangular in this design system — search is the one intentional capsule exception, matching Apple's HIG.
- [FilterChip](https://marsam.rahhal.app/components/filter-chip.md): Toggleable filter pill. Two interaction modes that compose: `active`+`onToggle` for multi-select category chips, `onRemove` for "applied filter" chips that show what's currently filtering the list. Optional `leading` icon and `count` badge.
- [FileDropzone](https://marsam.rahhal.app/components/file-dropzone.md): Drop-or-browse file picker with native HTML5 drag-and-drop, click-to-select fallback, and built-in `accept` / `maxSize` / `maxFiles` validation. Always controlled — the parent owns the file list. RTL-safe via logical Tailwind utilities.
- [Switch · Checkbox · Radio](https://marsam.rahhal.app/components/switch-and-toggles.md): Boolean and small-set selectors. `<Switch>` for on/off settings, `<Checkbox>` for individual toggles, `<RadioGroup>` for mutually-exclusive choices.
- [Slider](https://marsam.rahhal.app/components/slider.md): Value picker with a draggable thumb. Built on Radix Slider. Pass a single-element array for a normal slider or a two-element array for a range slider.
- [Combobox](https://marsam.rahhal.app/components/combobox.md): Searchable single-select picker. Composes `<Popover>` + `<Command>` + `<Button>` into the canonical shadcn pattern. Use for country / city / airport / category pickers where `<Select>` becomes unwieldy past ~10 options.
- [Calendar & DatePicker](https://marsam.rahhal.app/components/date-picker.md): Themed `<Calendar>` (react-day-picker) plus the canonical `<DatePicker>` recipe (Calendar inside a Popover). Single date and range modes share the same trigger.
- [Form (react-hook-form)](https://marsam.rahhal.app/components/form.md): Validated form composition built on react-hook-form. `<FormField>` wires a controller into descendant `<FormLabel>` / `<FormControl>` / `<FormDescription>` / `<FormMessage>` parts via shared aria attributes — labels point to inputs, errors are announced, and focus rings show on the right element automatically.
- [Section](https://marsam.rahhal.app/components/section.md): Page-section building block: header (title + description + optional action), spacing rhythm, and footer slot. Pairs with `Card`, `List`, or `Table` for the surface; `Section` only handles labeling and rhythm so layouts stay uniform.
- [Card](https://marsam.rahhal.app/components/card.md): Surface container for grouped content. Compose with `CardHeader`, `CardTitle`, `CardDescription`, `CardContent`, `CardFooter`.
- [List](https://marsam.rahhal.app/components/list.md): Apple-style inset grouped list with section headers/footers. Each `ListGroup` is a rounded card; rows separate with hairline dividers. `variant="plain"` flattens the chrome for embedding inside another card. Mirrors the iOS Settings UX.
- [PlaceCard](https://marsam.rahhal.app/components/place-card.md): Compact, mobile-first card for a single geographic place. Name, optional address, and the coordinate readout stack vertically and truncate — never scroll horizontally. The title is adaptive (name → address → coordinates) so a nameless waypoint still renders. Pass an `<Input/>` as `name` for inline editing; use `leading`/`trailing` slots for an icon and a checkbox/switch.
- [Map](https://marsam.rahhal.app/components/map.md): Declarative wrapper around MapLibre GL JS. Compose `MapMarker`, `MapPolyline`, `MapPolygon`, `MapCircle`, and `MapCluster` as children — geometry inherits the platform's blue primary by default. Free OpenFreeMap tiles light/dark; switch via the `style` prop. RTL Arabic labels render correctly out of the box.
- [Kanban board](https://marsam.rahhal.app/components/kanban.md): Column-based task board layout primitive. Provides board frame, columns (title / count / accent / action), and cards (title / description / leading / trailing / meta). Layout only — apps wire drag-and-drop with their own DnD library (e.g. `@dnd-kit/core`). On small screens columns snap-scroll horizontally so swipes feel native.
- [Carousel](https://marsam.rahhal.app/components/carousel.md): Horizontal (or vertical) scroller built on Embla Carousel. Used for photo galleries, onboarding card stacks, and any "swipe through a row" UX. Detects `[dir="rtl"]` automatically and forwards the right axis direction to Embla.
- [Collapsible](https://marsam.rahhal.app/components/collapsible.md): Minimal disclosure primitive (one toggle, one panel). Re-exports of Radix Collapsible. For multiple sections, use `<Accordion>` instead.
- [Layout primitives](https://marsam.rahhal.app/components/primitives.md): `<AspectRatio>` (lock a media ratio), `<ScrollArea>` (themed custom scrollbar), and `<Separator>` (semantic divider). Three small but essential primitives shipped in one catalog page.
- [Table](https://marsam.rahhal.app/components/table.md): Themed `<table>` family wrapped in a rounded card surface. Use for tabular data with multiple columns. For settings-style single-column lists, use `List` instead.
- [Badge](https://marsam.rahhal.app/components/badge.md): Inline label for status, counts, tags. Variants: default / secondary / destructive / outline.
- [Avatar · Skeleton · Progress](https://marsam.rahhal.app/components/avatar-and-skeleton.md): Compact identity + loading-state primitives.
- [Alert](https://marsam.rahhal.app/components/alert.md): Inline status callout. Pair with a leading icon for instant recognition.
- [Callout](https://marsam.rahhal.app/components/callout.md): Inline note / hint / warning / important block. Lighter than an Alert — used inside page bodies for disclaimers, agent-targeted hints, deprecation notes, and similar asides.
- [Rating](https://marsam.rahhal.app/components/rating.md): Star rating control with read-only display + interactive input modes. Half-star increments by default, keyboard support (Arrow / Home / End), and an `aria-label` describing the current value. Always renders LTR so 1-star sits at the start edge in both reading directions.
- [EmptyState](https://marsam.rahhal.app/components/empty-state.md): Recurring "nothing here yet" surface. Drop into any list, table, or section that can be empty — icon, title, description, and an optional action keep the spacing rhythm consistent across mini-apps.
- [Toaster (sonner)](https://marsam.rahhal.app/components/toaster.md): One `<Toaster />` mount + the imperative `toast(...)` helper. Theme follows `useTheme()` automatically.
- [JsonViewer](https://marsam.rahhal.app/components/json-viewer.md): Read-only, syntax-highlighted JSON block. Use for admin payload inspectors, debug panels, webhook viewers — any surface where an operator skims, copies, or downloads a structured payload. Theme tokens are wired through CSS variables so it follows light / dark automatically.
- [Spinner](https://marsam.rahhal.app/components/spinner.md): Small indeterminate loading indicator. Stroke is `currentColor` so it inherits the surrounding text color (slot inside a destructive button → destructive-on-foreground spinner). Declares `role="status"` and an `aria-label` so assistive tech announces the pending state.
- [NavBar](https://marsam.rahhal.app/components/nav-bar.md): Opinionated top navigation built on `<AppHeader>`. Brand on the start, typed links centered on `md+`, actions on the end. Router-agnostic via a `renderLink` render prop so apps can supply their own `<NavLink>` / `<Link>`.
- [Stepper](https://marsam.rahhal.app/components/stepper.md): Multi-step progress indicator. Horizontal (default) or vertical orientation; status (`complete`, `current`, `upcoming`) is derived per-step from `activeStep`.
- [WizardHeader](https://marsam.rahhal.app/components/wizard-header.md): Sticky per-step header for multi-step flows inside a native host (`?host=…`), where the web hides its own AppHeader/AppFooter. Back control at the start, centered title, optional action at the end, plus a slim segmented progress bar. Back navigation is delegated via `onBack`; top safe-area padding clears the iOS notch. RTL-aware.
- [Breadcrumb](https://marsam.rahhal.app/components/breadcrumb.md): Hierarchical navigation trail. Compose `<Breadcrumb>` → `<BreadcrumbList>` → `<BreadcrumbItem>` (containing `<BreadcrumbLink>` or `<BreadcrumbPage>`) with `<BreadcrumbSeparator>` between siblings. The default chevron flips under RTL.
- [Pagination](https://marsam.rahhal.app/components/pagination.md): Accessible page navigator. Compose `<Pagination>` → `<PaginationContent>` → `<PaginationItem>` (with `<PaginationLink>`, `<PaginationPrevious>`, `<PaginationNext>`, or `<PaginationEllipsis>` inside). Previous/Next chevrons rotate under RTL.
- [Tabs · Accordion](https://marsam.rahhal.app/components/tabs-and-accordion.md): Disclose grouped content. Use tabs for parallel views, accordion for sequential reveal.
- [Sidebar](https://marsam.rahhal.app/components/sidebar.md): Layout primitives for the catalog-style left rail every Rahhal mini-app uses: a glassy floating column with a sticky filter / brand area, a scrolling body, and collapsible sections. Layout-only — apps supply data, routing, and filtering.
- [Embedded mode](https://marsam.rahhal.app/components/embedded-mode.md): Detection helper for when a mini-app is loaded inside an iOS / Android / desktop host container. The host signals via `?host=<value>`; the web persists it in sessionStorage and exposes it to layouts via `useIsEmbedded()` so chrome (`<AppHeader>`, `<AppFooter>`) can be hidden in favor of the host's native nav.
- [Footer](https://marsam.rahhal.app/components/footer.md): Bottom chrome for a Rahhal mini-app. A floating glassy capsule that mirrors `<AppHeader>`: links + social inside a pill, brand line below. Helpers `<FooterLinks>`, `<FooterLink>`, and `<FooterSocial>` keep spacing and ARIA consistent.
- [AlertDialog](https://marsam.rahhal.app/components/alert-dialog.md): Interrupting confirmation dialog for destructive or unrecoverable actions. The user must explicitly confirm or cancel — clicking outside does not dismiss. Built on Radix Alert Dialog.
- [Drawer](https://marsam.rahhal.app/components/drawer.md): Bottom-sheet style modal that slides up from the edge of the viewport. Built on `vaul` for touch-friendly drag-to-dismiss. Use for mobile-first flows where a centered `<Dialog>` would feel heavy. For desktop side panels, prefer `<Sheet>`.
- [Popover](https://marsam.rahhal.app/components/popover.md): Floating panel anchored to a trigger. Non-modal — clicking outside dismisses. Built on Radix Popover. Use for date pickers, filter panels, color pickers, settings popouts.
- [HoverCard](https://marsam.rahhal.app/components/hover-card.md): Small floating preview shown on hover or focus. Use for profile cards, link previews, or anywhere a tooltip would be too small. Built on Radix Hover Card.
- [Command palette](https://marsam.rahhal.app/components/command.md): Searchable list / command palette built on `cmdk`. Use inline (`<Command>`) for typeahead pickers, or wrapped in `<CommandDialog>` for a global cmd-K launcher. Items are scored client-side as the user types.
- [Dialog · Sheet](https://marsam.rahhal.app/components/dialog-and-sheet.md): Centered modal vs. side sheet. Use a dialog for short focused interactions; use a sheet for navigation drawers, filters, or contextual editors.
- [Dropdown · Select · Tooltip](https://marsam.rahhal.app/components/menus-and-tooltip.md): Floating triggers and selectors. All three flip correctly under RTL.
- [PhoneInput](https://marsam.rahhal.app/components/phone-input.md): International phone field with searchable country picker. Default country is auto-detected from the user's IANA timezone (e.g. KSA for Asia/Riyadh). Numbers always render LTR even inside RTL regions.
- [InputOTP](https://marsam.rahhal.app/components/input-otp.md): Segmented one-time-code input. Used for the SMS code step of the Rahhal phone-OTP sign-in flow, but generic enough for any 4–8 digit verification code. Built on the `input-otp` library; logical Tailwind utilities mean the rounded ends and divider borders flip correctly under RTL.
- [LoginScreen (demo)](https://marsam.rahhal.app/components/login-screen.md): A UI-only walk-through of the canonical Rahhal phone-OTP login: phone step → OTP step → success. Two layouts share the same form body — `centered` (default) is a focused single-card screen; `split` adds a brand-led marketing pane on the start edge at `lg+`. Production mini-apps consume the same UX via `<LoginScreen>` from `@rahhal/auth/react`.
- [RequireRole](https://marsam.rahhal.app/components/require-role.md): Render-gate that requires both an active session and a named role string in the user's `app_metadata.roles` claim. Compose at the top of a protected subtree so the gate runs once. Roles are issued backend-side by writing `auth.users.app_metadata.roles`; this component is read-only.
- [AccessDeniedScreen](https://marsam.rahhal.app/components/access-denied-screen.md): Full-screen "you don't have permission" surface. Pairs with `<RequireRole>` from `@rahhal/auth/react` as the default `deniedFallback`. Same anatomy as `<EmptyState>` — icon · title · description · action — with a destructive-tinted icon tile and a viewport-filling default layout.
- [Country facts](https://marsam.rahhal.app/components/countries.md): Drop-in country UI from `@rahhal/countries/react`: `CountryFlag`, `CountryCard`, `CountryFacts`, `CountryDetail`. Data-in or self-fetching (by `name`/`code`), label-injected for i18n, and composed from `@rahhal/ui`. Backed by a REST Countries v4 client with an automatic v3.1 fallback.

## Conventions

- **Hex is the canonical cross-platform format.** CSS vars + Tailwind utilities are listed for web; iOS / Android equivalents use the same hex (or a named system font).
- **Two themes — `light` and `dark`.** Web auto-detects via `prefers-color-scheme`; native apps should mirror that.
- **Tokens are stable; values are not.** Match by name (e.g. `primary`) so a theme refresh doesn't break consumers.
- **Locales — `en` (LTR) + `ar` (RTL).** Use logical CSS / layout (Tailwind `ms-*` / `me-*`) on the web. On native, mirror layouts under RTL.

## How to fetch

Every `.md` page is plain text served at the same origin as the dev preview. Fetch with a normal HTTP GET; no auth required. Response `Content-Type: text/markdown; charset=utf-8`.
