Detail Page Bar — Back, title and action — the title appears once the heading scrolls away
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Detail Page Bar — Back, title and action — the title appears once the heading scrolls away
**Why this component matters:** The back control must sit at the inline start and mirror with direction: a hard-coded left arrow points the wrong way in Arabic and silently breaks the mental model.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Greeting Bar with Account — The greeting follows the clock, and the balance can be hidden
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Greeting Bar with Account — The greeting follows the clock, and the balance can be hidden
**Why this component matters:** A balance-hiding toggle protects the user in public. Persist the choice — re-revealing the number on every launch defeats the purpose entirely.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Immersive Transparent Bar — Transparent over the cover, gaining a surface once it scrolls past
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Immersive Transparent Bar — Transparent over the cover, gaining a surface once it scrolls past
**Why this component matters:** Over imagery, give bar text a scrim or shadow — contrast against an unknown photo cannot be guaranteed, and WCAG applies to the worst pixel, not the average one.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Large Title Bar — The large title collapses into a compact one on scroll
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Large Title Bar — The large title collapses into a compact one on scroll
**Why this component matters:** Cross-fade the two titles rather than swapping them: an abrupt switch at the threshold reads as a glitch, and the collapsed title must stay legible at every point in between.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Reading Progress Bar — Progress computed from the scrollable height, not from scroll position alone
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Reading Progress Bar — Progress computed from the scrollable height, not from scroll position alone
**Why this component matters:** Divide by scrollHeight minus clientHeight, not by scrollHeight: using the raw height means the bar never reaches 100% and the reader never sees the article end.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Bar with Inline Search — Search lives in the bar, with a cancel button that appears on focus
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Bar with Inline Search — Search lives in the bar, with a cancel button that appears on focus
**Why this component matters:** The cancel button should appear only while the field is active — reserving its space permanently steals width from the query on a screen that has none to spare.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Bar with Segmented Filter — A segment that swaps content and recomputes the visible total
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Bar with Segmented Filter — A segment that swaps content and recomputes the visible total
**Why this component matters:** When a filter changes, every derived number under it must change too. A total that ignores the active segment contradicts the rows beneath it.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Savings Goal Card — Remaining amount and expected date derived from the monthly rate
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Savings Goal Card — Remaining amount and expected date derived from the monthly rate
**Why this component matters:** Project the finish date from the actual monthly rate: a progress ring alone answers “how far” but never “when”, which is the question the saver actually has.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Habit Card with Computed Streak — Streak and rate computed from the day log, never stored
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Habit Card with Computed Streak — Streak and rate computed from the day log, never stored
**Why this component matters:** Compute the streak by walking backwards from today and stopping at the first gap — a stored counter drifts the moment a day is edited retroactively.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Mini Player Card — A draggable scrubber, with time-left adjusted for playback speed
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Mini Player Card — A draggable scrubber, with time-left adjusted for playback speed
**Why this component matters:** Divide remaining time by playback rate: at 1.5× a 30-minute episode has 20 minutes left, and showing the raw figure makes every estimate wrong.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Story Cards with Progress Ring — A dashed ring built from the segment count; seen stories dim
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Story Cards with Progress Ring — A dashed ring built from the segment count; seen stories dim
**Why this component matters:** Build the ring segments from stroke-dasharray computed from the item count — a fixed dash pattern desynchronises the moment someone posts one more story.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Swipe-to-Reveal Card — A swipe reveals two actions and springs back below the threshold
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Swipe-to-Reveal Card — A swipe reveals two actions and springs back below the threshold
**Why this component matters:** Mirror the swipe direction with the document direction and expose the same actions in a menu: gesture-only affordances are invisible and unreachable by keyboard.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Ticket Card with Code — Side notches, a generated barcode, and a countdown from the event date
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Ticket Card with Code — Side notches, a generated barcode, and a countdown from the event date
**Why this component matters:** Generate the barcode bars from the ticket code so the two cannot diverge, and count down from a target date instead of decrementing a number that drifts.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Live Tracking Card — A vertical timeline with an ETA derived from the current stage
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Live Tracking Card — A vertical timeline with an ETA derived from the current stage
**Why this component matters:** A vertical timeline suits narrow screens far better than a horizontal one: labels get full width instead of being truncated into ambiguity.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Flipping Bank Card — Two faces, with a masked number revealed briefly then re-hidden
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Flipping Bank Card — Two faces, with a masked number revealed briefly then re-hidden
**Why this component matters:** Re-mask the card number on a timer rather than leaving it exposed: the user asked to read it once, not to leave it visible for whoever picks up the phone next.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Weather Card with Hourly Curve — The curve is generated from the values, scaled to their own min and max
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Weather Card with Hourly Curve — The curve is generated from the values, scaled to their own min and max
**Why this component matters:** Scale the sparkline to the actual min and max of the series, not to zero: a range of 33–38°C flattens into a straight line the moment you anchor the axis at zero.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Paired Floating Actions — A primary and a secondary action at different sizes and weights
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Paired Floating Actions — A primary and a secondary action at different sizes and weights
**Why this component matters:** When two floating actions coexist, they must differ in size and weight — equal-looking buttons force the user to read both every time instead of recognising one.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Draggable FAB — Drags freely, snaps to the nearest edge, and never leaves the screen
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Draggable FAB — Drags freely, snaps to the nearest edge, and never leaves the screen
**Why this component matters:** Snap to an edge on release and clamp inside the safe area: a free-floating button can end up under a system bar where the user can no longer reach it.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Extended FAB that Collapses — Starts with a label and collapses to an icon on scroll
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Extended FAB that Collapses — Starts with a label and collapses to an icon on scroll
**Why this component matters:** Collapse the label but keep the icon and the accessible name: shrinking the touch target below 44px to save space is the one trade you must never make.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
FAB that Morphs into a Panel — Expands from a circle into a form and returns on close
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** FAB that Morphs into a Panel — Expands from a circle into a form and returns on close
**Why this component matters:** The morph must keep focus continuity: move focus into the panel when it opens and back to the trigger when it closes, or keyboard users lose their place entirely.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
FAB with Progress Ring — An SVG ring computed from its own circumference, not a fixed width
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** FAB with Progress Ring — An SVG ring computed from its own circumference, not a fixed width
**Why this component matters:** Derive stroke-dasharray from 2πr in code: hard-coding the dash length breaks the moment anyone changes the radius, and the ring silently stops reaching 100%.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Scroll-to-Top FAB — Appears after enough distance and returns smoothly — or instantly when motion is reduced
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Scroll-to-Top FAB — Appears after enough distance and returns smoothly — or instantly when motion is reduced
**Why this component matters:** Pass behavior:"auto" when prefers-reduced-motion is set: a smooth scroll of thousands of pixels can trigger nausea in users who asked for less motion.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Speed Dial FAB — Opens named actions in sequence, closing on Escape and on the scrim
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Speed Dial FAB — Opens named actions in sequence, closing on Escape and on the scrim
**Why this component matters:** Every speed-dial action needs a visible label, not an icon alone: the icons appear only once opened, so the user has no chance to learn them beforehand.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Checklist with Computed Progress — Completed items sink to the bottom; percentage and remaining are computed
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Checklist with Computed Progress — Completed items sink to the bottom; percentage and remaining are computed
**Why this component matters:** Move completed items to the end instead of hiding them: the user needs to see what they finished, and a disappearing row makes an accidental tap impossible to undo.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Infinite Scroll List — An intersection observer loads the next batch and states clearly when it ends
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Infinite Scroll List — An intersection observer loads the next batch and states clearly when it ends
**Why this component matters:** Say “that’s everything” at the end instead of leaving a spinner forever: an endless loader is indistinguishable from a stuck request, and users keep scrolling into nothing.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Pull-to-Refresh List — Increasing resistance, a release threshold, and a spinner that announces state
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Pull-to-Refresh List — Increasing resistance, a release threshold, and a spinner that announces state
**Why this component matters:** Add resistance past the threshold so the pull feels bounded, and only trigger at scrollTop zero — starting a refresh from mid-list steals the user’s reading position.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Reorderable List — Drag by the handle, with an arrow-key path as the alternative
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Reorderable List — Drag by the handle, with an arrow-key path as the alternative
**Why this component matters:** Every drag-to-reorder needs a keyboard equivalent: bind arrow keys on the handle and announce the new position, or the feature simply does not exist for many users.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Sectioned List with Side Index — Sticky headers and a letter index that jumps to its section
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Sectioned List with Side Index — Sticky headers and a letter index that jumps to its section
**Why this component matters:** The side index must be reachable by the thumb and expose each letter as a real button: a canvas-drawn index looks right but is invisible to assistive technology.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Grouped Settings List — Titled groups with several working row types
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Grouped Settings List — Titled groups with several working row types
**Why this component matters:** Give each row type the right control: a switch for instant effect, a chevron for a sub-screen, and a value for a picker — mixing them teaches the user nothing about what a tap will do.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
List with Loading Skeleton — The skeleton matches the real content’s size so nothing shifts on arrival
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** List with Loading Skeleton — The skeleton matches the real content’s size so nothing shifts on arrival
**Why this component matters:** Match the skeleton to the final layout’s dimensions exactly: a placeholder of the wrong height guarantees a layout shift the moment real content lands.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Action Sheet — Grouped actions with the destructive one separated and marked
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Action Sheet — Grouped actions with the destructive one separated and marked
**Why this component matters:** Separate the destructive action into its own group with a gap: adjacency to a routine action is how “Delete” gets tapped instead of “Duplicate”.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Irreversible Confirm Sheet — Requires typing a confirmation word before the button activates
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Irreversible Confirm Sheet — Requires typing a confirmation word before the button activates
**Why this component matters:** For a truly irreversible action, a typed confirmation beats a second tap: it forces a deliberate pause, and muscle memory cannot produce it accidentally.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Bottom Sheet with Detents — Third, half and full — it settles at the nearest detent on release
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Bottom Sheet with Detents — Third, half and full — it settles at the nearest detent on release
**Why this component matters:** Snap to the nearest detent on release rather than freezing wherever the finger stopped: a sheet resting at an arbitrary height looks broken and hides content unpredictably.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Filter Sheet — Changes stay pending until Apply — Reset restores the last applied state
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Filter Sheet — Changes stay pending until Apply — Reset restores the last applied state
**Why this component matters:** Keep filter edits in a draft and commit only on Apply. Filtering live behind an open sheet re-renders a list the user cannot see, and Cancel then has nothing to undo.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Payment Method Sheet — Each method carries its fee, and the total recomputes on switch
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Payment Method Sheet — Each method carries its fee, and the total recomputes on switch
**Why this component matters:** Show the fee difference at the moment of choice, not on the receipt: a method that costs more must say so before it is picked, or the charge feels like a trick.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Wheel Picker Sheet — Wheels snap on scroll and the value is read from the position
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Wheel Picker Sheet — Wheels snap on scroll and the value is read from the position
**Why this component matters:** Read the wheel value from scroll position with CSS snap points instead of tracking it separately: the two can never disagree, and an interrupted flick still lands on a real value.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Share Sheet Grid — A row of people, a row of actions, and a copy-link that actually copies
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Share Sheet Grid — A row of people, a row of actions, and a copy-link that actually copies
**Why this component matters:** Put frequent recipients above app targets: sharing is usually to a person, not to a platform, and the extra hop through an app picker is pure friction.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Icon that Expands into Search — A small icon opens a full bar and closes it on Escape
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Icon that Expands into Search — A small icon opens a full bar and closes it on Escape
**Why this component matters:** Move focus into the field the moment it expands — an animation that finishes with the caret nowhere forces a second tap and feels broken.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Search with Filter Chips — Horizontally scrolling chips narrow the result, with a counter that follows
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Search with Filter Chips — Horizontally scrolling chips narrow the result, with a counter that follows
**Why this component matters:** Show the active filter count on the row itself: chips scroll out of view, and a user who cannot see their filters will blame the search for the empty result.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Sticky In-list Search — Sticks to the top of the list on scroll and reports the match count
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Sticky In-list Search — Sticks to the top of the list on scroll and reports the match count
**Why this component matters:** A sticky search must announce its result count in a live region: filtering silently leaves screen-reader users with no idea the list changed under them.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Floating Search over a Map — Floats above the map with results sliding out beneath it
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Floating Search over a Map — Floats above the map with results sliding out beneath it
**Why this component matters:** A bar floating over a map needs a solid surface and a shadow: transparency over unpredictable terrain colours destroys contrast in exactly the places you cannot test.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Search with Multiple Inputs — Type, scan a code, or use location — three ways into one result
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Search with Multiple Inputs — Type, scan a code, or use location — three ways into one result
**Why this component matters:** Give every alternate input its own accessible name and a text equivalent: a camera or GPS entry point that only exists as an icon is unreachable for many users.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Full-screen Search Sheet — Tapping the bar opens a search screen with history and trending
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Full-screen Search Sheet — Tapping the bar opens a search screen with history and trending
**Why this component matters:** The full-screen sheet is the mobile pattern for search because the keyboard eats half the viewport — an inline dropdown would have nowhere left to render.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Search with Keyboard Suggestions — Live suggestions navigable with arrows and accepted with Enter
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Search with Keyboard Suggestions — Live suggestions navigable with arrows and accepted with Enter
**Why this component matters:** A combobox needs aria-activedescendant, not focus movement: the caret must stay in the input while the highlighted option changes, or typing after arrowing breaks.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Tab Bar with Count Badges — The badge caps at 99+ and the total is summed from the conversations
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Tab Bar with Count Badges — The badge caps at 99+ and the total is summed from the conversations
**Why this component matters:** Cap the badge and keep the real number in aria-label: “99+” fits the pill while the assistive announcement stays exact.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Tab Bar with Centre Action — Four tabs with one raised primary action in the middle
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Tab Bar with Centre Action — Four tabs with one raised primary action in the middle
**Why this component matters:** The raised centre button is an action, not a tab: keep it out of the tablist and give it its own role, or arrow-key navigation lands on something that never has a panel.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Dot Page Indicator — Follows the horizontal swipe and jumps when a dot is pressed
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Dot Page Indicator — Follows the horizontal swipe and jumps when a dot is pressed
**Why this component matters:** Derive the active dot from scroll position with snap points instead of tracking it in state: the two can never disagree, and a mid-swipe interruption still lands correctly.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Icon and Label Tab Bar — Five items maximum, each with an accessible name and a sliding indicator
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Icon and Label Tab Bar — Five items maximum, each with an accessible name and a sliding indicator
**Why this component matters:** Cap the bar at five items: past that, touch targets fall below 44px and the thumb cannot hit them reliably on a one-handed grip.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Label-only Tab Bar — No icons — plain labels with a moving underline
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Label-only Tab Bar — No icons — plain labels with a moving underline
**Why this component matters:** Text-only bars beat ambiguous icons for content sections: no one agrees what a “Discover” glyph looks like, but everyone reads the word.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Morphing Tab Bar — The active item expands to reveal its label; the rest stay icons
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Morphing Tab Bar — The active item expands to reveal its label; the rest stay icons
**Why this component matters:** Animate flex-grow, not width: with grow the remaining items redistribute the leftover space themselves and the row never overflows at any label length.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Floating Pill Tab Bar — Floats above content and hides when scrolling down
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Floating Pill Tab Bar — Floats above content and hides when scrolling down
**Why this component matters:** Hide on scroll down, reveal on scroll up, and always reveal near the bottom — a bar that stays hidden at the end of a list strands the user with no way back.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Arabic Data Table — Numbers align left inside a table that reads right
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Arabic Data Table — Numbers align left inside a table that reads right
**Why this component matters:** Arabic text aligns to the start while numbers always align left, so their decimal places line up and can be compared by eye. A table that aligns numbers with the text makes comparison impossible.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Quadruple Name Field — Official Gulf names have four parts, not two
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Quadruple Name Field — Official Gulf names have four parts, not two
**Why this component matters:** Official names in Saudi Arabia, Jordan and the Gulf have four parts. A two-field form forces users to cram three names into one box, breaking the match against their ID document.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Auth Form — Forms
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Auth Form — Forms
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
**Typography:** Cairo for Arabic, IBM Plex Sans for Latin. Arabic line-height must be
Contact Section — A multi-field form validating on blur, with an error summary
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Contact Section — A multi-field form validating on blur, with an error summary
**Why this component matters:** On failed submit, move focus to an error summary listing every invalid field — a screen-reader user otherwise has no way to discover what went wrong.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Call-to-Action Section — One field, one button, and validation only after the field is left
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Call-to-Action Section — One field, one button, and validation only after the field is left
**Why this component matters:** One field only. Every extra input in a CTA measurably reduces completion — ask for the email now and the rest after they are already committed.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
FAQ Section — An accordion built on native details — works with JavaScript off
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** FAQ Section — An accordion built on native details — works with JavaScript off
**Why this component matters:** Use native details/summary: it is keyboard-accessible, searchable by the browser’s find-in-page, and survives with JavaScript disabled. A div-based accordion gives up all three.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Three-up Features — Three cards of equal height regardless of copy length
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Three-up Features — Three cards of equal height regardless of copy length
**Why this component matters:** Feature cards must stretch to equal height — align-items:stretch on the grid — or a shorter card leaves a ragged baseline that reads as a rendering bug.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Full Footer — Link columns, a newsletter, and a copyright year computed rather than typed
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Full Footer — Link columns, a newsletter, and a copyright year computed rather than typed
**Why this component matters:** Compute the copyright year at render time. A hard-coded year is the most common stale detail on the web and quietly signals an abandoned site.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Hero Section — Headline, promise, two actions and one trust signal in a single visual order
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Hero Section — Headline, promise, two actions and one trust signal in a single visual order
**Why this component matters:** A hero needs exactly one primary action. A second equally weighted button splits attention and measurably lowers click-through on both.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Client Logo Marquee — An endless strip that stops completely when motion is reduced
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Client Logo Marquee — An endless strip that stops completely when motion is reduced
**Why this component matters:** Duplicate the track and translate by exactly −50% so the loop is seamless; and under prefers-reduced-motion stop it outright rather than slowing it — vestibular triggers do not care about speed.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Pricing with Billing Toggle — The annual saving is computed from both prices, never hand-written
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Pricing with Billing Toggle — The annual saving is computed from both prices, never hand-written
**Why this component matters:** Compute the annual discount from the two prices. A hard-coded “save 20%” badge silently becomes a lie the first time either price changes.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Animated Stats Band — Numbers count up on entry — and appear complete when motion is reduced
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Animated Stats Band — Numbers count up on entry — and appear complete when motion is reduced
**Why this component matters:** Start the count only when the band enters the viewport, and skip straight to the final value under prefers-reduced-motion — an animation nobody sees is wasted work, and one that cannot be stopped is an accessibility failure.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Numbered Steps — A horizontal path whose connector stops at the last step instead of overshooting
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Numbered Steps — A horizontal path whose connector stops at the last step instead of overshooting
**Why this component matters:** Draw the connector between steps, not through them: a line that runs past the final step reads as an unfinished process.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Team Section — People cards with roles and links, on an equal-height grid
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Team Section — People cards with roles and links, on an equal-height grid
**Why this component matters:** Team photos are decorative when the name is already text — mark them aria-hidden and let the name carry the meaning, or a screen reader reads each person twice.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Testimonials Carousel — Auto-advances, and pauses on hover and on focus
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Testimonials Carousel — Auto-advances, and pauses on hover and on focus
**Why this component matters:** An auto-rotating carousel must pause on hover AND on keyboard focus, and expose arrow-key navigation — otherwise it steals content away from anyone reading slowly.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Copy Button with Confirmation — Actually copies, with a fallback when clipboard permission is unavailable
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Copy Button with Confirmation — Actually copies, with a fallback when clipboard permission is unavailable
**Why this component matters:** The Clipboard API rejects outside a secure context or without permission. Always keep a selection-based fallback and report failure honestly instead of showing a false “Copied”.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Hold-to-Delete — The delete completes after a sustained press and aborts on release
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Hold-to-Delete — The delete completes after a sustained press and aborts on release
**Why this component matters:** Hold-to-confirm replaces a modal for irreversible actions, but it must be reachable by keyboard: bind Space and Enter to the same press-and-release cycle as the pointer.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Icon Buttons with Tooltips — Each has an accessible name, and the tooltip shows on focus, not hover alone
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Icon Buttons with Tooltips — Each has an accessible name, and the tooltip shows on focus, not hover alone
**Why this component matters:** An icon-only button is invisible to a screen reader without aria-label, and its tooltip must appear on keyboard focus too — hover-only tooltips exclude every keyboard user.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Async Loading Button — Blocks the double click and holds its width while pending
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Async Loading Button — Blocks the double click and holds its width while pending
**Why this component matters:** A payment button that stays clickable while the request is in flight will charge twice. Lock it on the first click and keep the width fixed so the layout does not jump.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Magnetic Button — Leans toward the pointer within range, and stops when motion is reduced
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Magnetic Button — Leans toward the pointer within range, and stops when motion is reduced
**Why this component matters:** Read prefers-reduced-motion in JavaScript, not only in CSS: a transform driven by pointer events keeps running regardless of what the stylesheet says.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Progress-in-Button — Progress lives inside the button, and the upload can be cancelled mid-flight
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Progress-in-Button — Progress lives inside the button, and the upload can be cancelled mid-flight
**Why this component matters:** If an operation can be cancelled, the same control must offer the cancel — sending the user hunting for a separate button while bytes are moving is how uploads get abandoned.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Segmented Control — Single choice with a sliding indicator measured from the active segment
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Segmented Control — Single choice with a sliding indicator measured from the active segment
**Why this component matters:** Arrow keys in a radio group must follow document direction, not the key name: in RTL, ArrowLeft moves to the next item, not the previous one.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Expanding Share Buttons — One button expands into options, with a counter that actually increments
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Expanding Share Buttons — One button expands into options, with a counter that actually increments
**Why this component matters:** Prefer the native share sheet when navigator.share exists — it is one tap on mobile — and fall back to your own list everywhere else instead of shipping both blindly.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Base Buttons with States — Four levels of emphasis, five states each
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Base Buttons with States — Four levels of emphasis, five states each
**Why this component matters:** Emphasis is a hierarchy, not a palette: exactly one primary per view. Two primaries side by side leave the user with no signal about which action is the expected one.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Split Button — The default action is one click; its alternatives sit behind an arrow
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Split Button — The default action is one click; its alternatives sit behind an arrow
**Why this component matters:** The split button is two controls in one shell: give each its own accessible name, or a screen reader announces the same label twice with no way to tell them apart.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Quantity Stepper — Respects stock and minimum, recomputing the line total instantly
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Quantity Stepper — Respects stock and minimum, recomputing the line total instantly
**Why this component matters:** Clamp on every path — buttons, typing, and paste. A stepper that guards only its buttons lets a typed 999 through and the order fails at checkout instead of here.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Toggle Switches — State announced to screen readers, with computed dependency between switches
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Toggle Switches — State announced to screen readers, with computed dependency between switches
**Why this component matters:** A switch needs role="switch" and aria-checked, not colour alone. And when one option depends on another, disable the dependant and say why — do not let it sit enabled but inert.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Doctor Card with Slots — Booked ratio and open slots computed from the schedule
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Doctor Card with Slots — Booked ratio and open slots computed from the schedule
**Why this component matters:** Disable taken slots rather than hiding them: a visibly full morning tells the patient to look at the afternoon, while an empty list looks like a loading failure.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Course Card with Progress — Percentage and time left derived from the lesson list
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Course Card with Progress — Percentage and time left derived from the lesson list
**Why this component matters:** Progress must come from the lesson data, not a stored percentage — and the remaining time should be the sum of unfinished lessons, not an estimate.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Flight Card — Duration computed from both times including the timezone offset
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Flight Card — Duration computed from both times including the timezone offset
**Why this component matters:** Subtracting local departure from local arrival gives the wrong duration across timezones. Convert both to UTC first, then format — this is the bug in most flight cards.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Invoice Card — Subtotal, VAT and total all computed from the line items
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Invoice Card — Subtotal, VAT and total all computed from the line items
**Why this component matters:** Round once at the total, not per line: summing pre-rounded lines drifts by a halala and the printed invoice stops reconciling with the ledger.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Media Card — Aspect ratio preserved, duration formatted from raw seconds
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Media Card — Aspect ratio preserved, duration formatted from raw seconds
**Why this component matters:** Use aspect-ratio so the thumbnail reserves its box before paint — a media card without it shifts the whole grid when the image finally loads.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Order Card with Timeline — Progress derived from the current stage within the stage list
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Order Card with Timeline — Progress derived from the current stage within the stage list
**Why this component matters:** A four-stage tracker is not 25/50/75/100: the first stage is already reached, so the fill is index ÷ (count − 1). Getting this wrong makes a fresh order look a quarter done.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Product Card — The discount is computed from both prices, never hand-written
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Product Card — The discount is computed from both prices, never hand-written
**Why this component matters:** Hard-coding “-30%” next to two prices guarantees they will disagree after the first price edit. Derive the badge from list and sale price so it can never be wrong.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Employee Card — Tenure computed from the hire date
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Employee Card — Tenure computed from the hire date
**Why this component matters:** Store the hire date and derive tenure at render time; a stored “3 years” silently becomes wrong the moment the page is cached.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Property Card — Price per square metre derived from price and area
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Property Card — Price per square metre derived from price and area
**Why this component matters:** Price per m² is the number buyers actually compare on. Compute it from price ÷ area instead of storing it, so the two can never drift apart.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Ratings Card — The average is computed from the star distribution, not stored
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Ratings Card — The average is computed from the star distribution, not stored
**Why this component matters:** Show the distribution, not just the mean: 4.0 from all-fours and 4.0 from half ones and half fives are different products, and only the histogram tells them apart.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Shipment Card — Days left and delay computed from the dates themselves
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Shipment Card — Days left and delay computed from the dates themselves
**Why this component matters:** Compare dates at day granularity, not by millisecond subtraction: two timestamps hours apart can land on different days and flip “arrives today” to “arrives tomorrow”.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Team Card with Capacity — Overflow count and capacity load both computed
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Team Card with Capacity — Overflow count and capacity load both computed
**Why this component matters:** Cap the avatar stack and compute the “+N” from the remainder; a hard-coded +3 becomes a lie the first time someone joins or leaves the team.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Staff Table — Tables
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Staff Table — Tables
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
**Typography:** Cairo for Arabic, IBM Plex Sans for Latin. Arabic line-height must be
Semicircular Gauge — An arc whose angle comes from the ratio and whose length comes from the radius
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Semicircular Gauge — An arc whose angle comes from the ratio and whose length comes from the radius
**Why this component matters:** Semicircular gauges are usually faked with a hardcoded dasharray tuned to one size. Deriving the arc length from the radius (π·r for a half turn) keeps the fill exact at any dimension.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Micro Candlestick — High, low, open and close on one computed scale
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Micro Candlestick — High, low, open and close on one computed scale
**Why this component matters:** Candles must share a single scale derived from the global min and max; scaling each candle to itself produces a chart that looks plausible and is meaningless.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Countdown from a Real Interval — Computes the gap from a real date, so it never drifts
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Countdown from a Real Interval — Computes the gap from a real date, so it never drifts
**Why this component matters:** Counting down by subtracting one each second drifts: setInterval is not exact and a backgrounded tab throttles it. Recomputing the difference from the target date every tick is always right.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Deviation from Target — Bars that grow out of zero in both directions by the sign of the gap
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Deviation from Target — Bars that grow out of zero in both directions by the sign of the gap
**Why this component matters:** A deviation chart must anchor at zero and grow both ways; drawing negatives as short positive bars is the most common way a dashboard tells the opposite of the truth.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Conversion Funnel — Each stage carries two ratios: from the previous stage and from the first
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Conversion Funnel — Each stage carries two ratios: from the previous stage and from the first
**Why this component matters:** A funnel showing only the overall rate hides where the drop happens. Showing step-over-step beside total conversion is what turns the chart into a decision.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Weekly Heatmap — Colour derived from the actual range — not from hardcoded thresholds
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Weekly Heatmap — Colour derived from the actual range — not from hardcoded thresholds
**Why this component matters:** Fixed colour thresholds break when the data shifts scale: a “hot” day last month becomes cold this month. Normalising against the observed min and max keeps the map readable whatever the numbers do.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Hijri Date Picker — Exists in no global library
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Hijri Date Picker — Exists in no global library
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
**Typography:** Cairo for Arabic, IBM Plex Sans for Latin. Arabic line-height must be
HR Dashboard — Dashboard
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** HR Dashboard — Dashboard
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
**Typography:** Cairo for Arabic, IBM Plex Sans for Latin. Arabic line-height must be
National ID / Iqama Field — Tells citizen from resident by the first digit, and validates the checksum
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** National ID / Iqama Field — Tells citizen from resident by the first digit, and validates the checksum
**Why this component matters:** The first digit identifies the document type; the last is a checksum computed from the preceding nine. Validating in the browser prevents typos that would otherwise surface days later inside government systems.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Navbar with Account and Alerts — Two separate menus — opening one closes the other
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Navbar with Account and Alerts — Two separate menus — opening one closes the other
**Why this component matters:** Two independent dropdowns in one bar must be mutually exclusive; leaving both open stacks panels over each other and traps keyboard focus between them.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Navbar with Announcement Bar — A promo strip above with a real timer that stays dismissed
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Navbar with Announcement Bar — A promo strip above with a real timer that stays dismissed
**Why this component matters:** A promo bar that returns on every page load is an annoyance; persist the dismissal, and compute the countdown from a target date so it never drifts.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Compact App Bar — The slimmest size, with a project switcher and a command key
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Compact App Bar — The slimmest size, with a project switcher and a command key
**Why this component matters:** At 34px every pixel counts: use a single row, icon-sized controls, and expose the keyboard shortcut visually so the bar stays usable without growing.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Navbar with Breadcrumb — A hierarchical trail whose separators mirror with direction
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Navbar with Breadcrumb — A hierarchical trail whose separators mirror with direction
**Why this component matters:** Breadcrumb separators are directional glyphs: “›” must become “‹” in RTL, and the trail needs aria-current="page" on its last item.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Centred-Logo Navbar — Logo in the centre with links balanced on both sides
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Centred-Logo Navbar — Logo in the centre with links balanced on both sides
**Why this component matters:** Centring by margin alone drifts when the two link groups differ in width. Give both sides flex:1 so the logo stays optically centred regardless of label lengths.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Classic Navbar — Logo, links and one action — the baseline that always works
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Classic Navbar — Logo, links and one action — the baseline that always works
**Why this component matters:** The default bar. Its only hard requirement is aria-current on the active link: without it a screen reader cannot tell which page the user is on.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Navbar with Mega Menu — A multi-column panel that closes on Escape and outside click
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Navbar with Mega Menu — A multi-column panel that closes on Escape and outside click
**Why this component matters:** A mega menu is a disclosure, not a hover trick: bind it to aria-expanded and aria-controls so keyboard users can open and close it deliberately.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Mobile Navbar with Sheet — A hamburger that opens a full sheet and traps focus
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Mobile Navbar with Sheet — A hamburger that opens a full sheet and traps focus
**Why this component matters:** A mobile sheet must trap focus and restore it to the trigger on close, or keyboard users tab straight into the page hidden behind it.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Navbar with Centre Search — The search expands on focus without shifting the layout
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Navbar with Centre Search — The search expands on focus without shifting the layout
**Why this component matters:** Expanding a search on focus must not reflow its neighbours; reserve the space with flex-basis so the bar does not jump under the pointer.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Shrinking Navbar — Starts tall, shrinks on scroll, and restores at the top
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Shrinking Navbar — Starts tall, shrinks on scroll, and restores at the top
**Why this component matters:** Shrink on scroll must use a threshold with hysteresis, or the bar oscillates between states at the boundary and flickers under the reader.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Navbar with Secondary Tabs — Two rows: identity above, tabs below with a sliding indicator
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Navbar with Secondary Tabs — Two rows: identity above, tabs below with a sliding indicator
**Why this component matters:** The moving indicator must be positioned from the active tab’s measured box, not from a fixed index — tab widths differ with label length and language.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Transparent Navbar that Fills — Transparent over the hero, gains a background on scroll
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Transparent Navbar that Fills — Transparent over the hero, gains a background on scroll
**Why this component matters:** Transparent bars fail on light imagery. Give the text a shadow while transparent, and swap to a solid surface as soon as the hero scrolls away.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Pricing Card — Pricing
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Pricing Card — Pricing
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
**Typography:** Cairo for Arabic, IBM Plex Sans for Latin. Arabic line-height must be
Autocomplete Search — Suggests, navigates by arrows, and remembers your last searches
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Autocomplete Search — Suggests, navigates by arrows, and remembers your last searches
**Why this component matters:** A combobox needs role="combobox" with aria-expanded and aria-activedescendant, or a screen reader announces a plain text field while sighted users see a list of options.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Search with Compound Filters — A term plus conditions — each filter shown as a chip you can remove
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Search with Compound Filters — A term plus conditions — each filter shown as a chip you can remove
**Why this component matters:** Compound filters must be visible and individually removable. Hiding active filters in a collapsed panel is the classic cause of “why are there no results?”
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Typo-Tolerant Search — Finds the match despite a typo, and suggests “did you mean?”
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Typo-Tolerant Search — Finds the match despite a typo, and suggests “did you mean?”
**Why this component matters:** Exact matching fails on one wrong keystroke. A bounded edit-distance (max 2, and only for terms of 4+ characters) recovers typos without turning the search into noise.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Radius Search — Distance computed with haversine, not raw coordinate differences
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Radius Search — Distance computed with haversine, not raw coordinate differences
**Why this component matters:** Subtracting latitudes and longitudes is not distance: a degree of longitude shrinks with latitude. Use the haversine formula or the radius filter is simply wrong.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Grouped Global Search — Results from several sources, each under its own heading
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Grouped Global Search — Results from several sources, each under its own heading
**Why this component matters:** A global search that returns one flat list forces the user to guess what each row is. Grouping by source, with a count per group, answers “where does this live?” before they click.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Instant Search with Highlight — Filters as you type and highlights the match in the original text
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Instant Search with Highlight — Filters as you type and highlights the match in the original text
**Why this component matters:** Highlighting must run on the raw string, not the normalised one: normalisation changes character counts, so an index taken from the normalised text underlines the wrong letters.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Paginated Search — Pages computed from the result count, resetting on every new query
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Paginated Search — Pages computed from the result count, resetting on every new query
**Why this component matters:** Reset to page one whenever the query changes: staying on page four of a result set that now has two pages shows an empty list and reads as a broken search.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Search with Price Range — Two handles that cannot cross, with results recomputed instantly
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Search with Price Range — Two handles that cannot cross, with results recomputed instantly
**Why this component matters:** A dual range must clamp: if the lower handle passes the upper one the query becomes impossible and silently returns nothing. Clamp on input, not on submit.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Search with Recent History — Stores recent searches locally and offers them before you type
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Search with Recent History — Stores recent searches locally and offers them before you type
**Why this component matters:** Show history only while the field is empty. Once the user types, suggestions must come from the data — mixing history into live results makes stale entries look like matches.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Field-scoped Search — Restricts the query to one field instead of every field
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Field-scoped Search — Restricts the query to one field instead of every field
**Why this component matters:** Scoping cuts false positives: searching “123” across all fields matches phone numbers and room numbers alike. Let the user say which column they mean.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
In-table Search — Highlights inside cells, counts rows and sums only what is visible
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** In-table Search — Highlights inside cells, counts rows and sums only what is visible
**Why this component matters:** The footer total must recompute over visible rows only. A total that ignores the filter contradicts the rows above it, and finance users will trust neither.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Tag-based Search — Each tag is a condition — results are their intersection, not their union
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Tag-based Search — Each tag is a condition — results are their intersection, not their union
**Why this component matters:** Tag filters must AND, not OR: a user adding a second tag is narrowing the search, and returning more rows than before feels broken.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Setup Wizard — Progress follows reading order
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Setup Wizard — Progress follows reading order
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
**Typography:** Cairo for Arabic, IBM Plex Sans for Latin. Arabic line-height must be
Sidebar with Live Badges — Counters that change and announce themselves to screen readers
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Sidebar with Live Badges — Counters that change and announce themselves to screen readers
**Why this component matters:** A badge that changes silently is invisible to screen-reader users. aria-live="polite" announces the new count without interrupting — exactly what a notification counter needs.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Collapsible Sidebar — Folds into an icon rail and remembers your choice
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Collapsible Sidebar — Folds into an icon rail and remembers your choice
**Why this component matters:** On narrow screens a 200px sidebar eats a third of the viewport. Folding it to a rail keeps navigation reachable — and the state must persist, or the user re-folds it on every page.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Sidebar with Command Palette — Ctrl+K opens a search that jumps anywhere by keyboard alone
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Sidebar with Command Palette — Ctrl+K opens a search that jumps anywhere by keyboard alone
**Why this component matters:** Power users navigate by typing, not clicking. A palette needs a visible keyboard hint, arrow-key selection, Enter to confirm and Escape to dismiss — a search box without those is just a filter.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Mobile Drawer — Slides from the start edge and traps focus inside
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Mobile Drawer — Slides from the start edge and traps focus inside
**Why this component matters:** A drawer that leaves focus behind lets keyboard users tab into hidden content. Trapping focus and restoring it on close is what separates a drawer from a div that slides.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Grouped Sidebar — Group headings separate sections without collapsing
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Grouped Sidebar — Group headings separate sections without collapsing
**Why this component matters:** When every item must stay visible, headings give structure without hiding anything. Use aria-labelledby so a screen reader announces which group each item belongs to.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Icon Rail with Tooltips — As narrow as it gets — the label appears on hover and focus
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Icon Rail with Tooltips — As narrow as it gets — the label appears on hover and focus
**Why this component matters:** An icon-only rail is unusable without labels. The tooltip must appear on keyboard focus too, not hover alone — otherwise the component excludes anyone not using a mouse.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Nested Sidebar — Groups that expand and collapse — one open at a time
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Nested Sidebar — Groups that expand and collapse — one open at a time
**Why this component matters:** Accounting systems have more sections than fit on a screen. Accordion groups keep the list scannable; opening one closes the others so the user never faces a wall of links.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Sidebar with Pinned Items — Pin what you use daily to the top — and it stays pinned
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Sidebar with Pinned Items — Pin what you use daily to the top — and it stays pinned
**Why this component matters:** In a long menu the same three items get used every day. Letting the user pin them removes a daily scan; persisting the choice is what makes it worth doing at all.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Sidebar with User Menu — A menu that closes on outside click and on Escape
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Sidebar with User Menu — A menu that closes on outside click and on Escape
**Why this component matters:** A dropdown that only closes by clicking its trigger again traps the user. Escape and outside-click are not extras — they are what makes a menu a menu.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Sidebar with Progress Meters — Each section carries a computed meter, announced to screen readers
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Sidebar with Progress Meters — Each section carries a computed meter, announced to screen readers
**Why this component matters:** A meter drawn with a fixed width lies the moment the data moves. Compute it, and expose the value through role="meter" with aria-valuenow so it is readable, not merely visible.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Searchable Sidebar — Arabic-normalized search filters items instantly
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Searchable Sidebar — Arabic-normalized search filters items instantly
**Why this component matters:** Past twenty items, scanning fails. The filter must normalise Arabic — hamza forms, taa marbuta, tashkeel, the definite article — or typing “العقود” will not find “عقود”.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Split Rail with Context Panel — An icon column that swaps the contents of the panel beside it
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Split Rail with Context Panel — An icon column that swaps the contents of the panel beside it
**Why this component matters:** Two navigation levels in one strip: the rail picks the area, the panel lists what is inside it. Each rail button must own its panel through aria-controls, or the relationship exists only visually.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Sidebar with Workspace Switcher — Switching the client swaps the whole navigation
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Sidebar with Workspace Switcher — Switching the client swaps the whole navigation
**Why this component matters:** Agencies work across clients. Switching workspace must rebuild the nav, reset the active item and announce the change — otherwise the user acts on the previous client’s data.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
National Address Sign-up — Postal code, building number and additional number — each with its correct length
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** National Address Sign-up — Postal code, building number and additional number — each with its correct length
**Why this component matters:** The Saudi national address has four fixed-width parts. Validate each on its own length and auto-advance focus, so the user never has to count digits.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Sign-up with Age Check — Age computed from the full date difference, not by subtracting years
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Sign-up with Age Check — Age computed from the full date difference, not by subtracting years
**Why this component matters:** Subtracting birth year from current year is wrong for anyone whose birthday has not passed yet this year — and that is roughly half your users on any given day.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Business Sign-up with CR Number — Validates the commercial registration and the VAT number together
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Business Sign-up with CR Number — Validates the commercial registration and the VAT number together
**Why this component matters:** Saudi CR numbers are ten digits starting with 1, 2, 4, 5 or 7; VAT numbers are fifteen digits starting and ending with 3. Checking length alone lets obviously invalid records into the database.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Sign-up with Layered Consent — Required and optional consents, with a genuinely tri-state “select all”
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Sign-up with Layered Consent — Required and optional consents, with a genuinely tri-state “select all”
**Why this component matters:** “Select all” has three states, not two: checked, unchecked, and indeterminate. Skipping the third makes the box lie whenever only some children are ticked.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Bank Account Sign-up — IBAN verified with the full mod-97 checksum, not just its length
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Bank Account Sign-up — IBAN verified with the full mod-97 checksum, not just its length
**Why this component matters:** A length check accepts a mistyped IBAN and the transfer bounces days later. Implement mod-97: move the first four characters to the end, map letters to numbers, and require a remainder of 1.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Join by Team Invite — The invite code resolves both the team and the role
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Join by Team Invite — The invite code resolves both the team and the role
**Why this component matters:** Never let the joiner pick their own role. Resolve it from the invite code server-side and render it read-only, or the form is a privilege-escalation hole.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
OTP Code Entry — Accepts a pasted code, moves back on delete, and re-sends on a timer
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** OTP Code Entry — Accepts a pasted code, moves back on delete, and re-sends on a timer
**Why this component matters:** Most OTP inputs break on paste — the user copies six digits and only the first lands. Handle the paste event, distribute the digits, and move focus to the last filled box.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Sign-up with Password Strength — Strength computed from variety and length together — not length alone
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Sign-up with Password Strength — Strength computed from variety and length together — not length alone
**Why this component matters:** Length-only meters call “aaaaaaaaaaaa” strong. Score character-class variety, penalise repetition, and cap the score so a long weak password never reads as safe.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Phone Sign-up — Accepts Saudi and Jordanian numbers and normalises the international form
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Phone Sign-up — Accepts Saudi and Jordanian numbers and normalises the international form
**Why this component matters:** Users type 0501234567, +966501234567 or 966501234567 interchangeably. Normalise to a single canonical form on blur, and validate the operator prefix — not just the digit count.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Sign-up with Providers — Provider buttons, a divider and an email fallback — in correct focus order
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Sign-up with Providers — Provider buttons, a divider and an email fallback — in correct focus order
**Why this component matters:** The divider between providers and the email form must be decorative for assistive tech (aria-hidden), or a screen reader reads the word “or” as if it were a control in the tab order.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Multi-step Sign-up — No step advances before the previous one is valid — progress is computed
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Multi-step Sign-up — No step advances before the previous one is valid — progress is computed
**Why this component matters:** Splitting a long form reduces abandonment only if each step blocks on its own validity. Letting the user reach step three with an invalid step one just moves the failure later.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Username with Live Availability — Checks after typing stops and suggests alternatives on collision
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Username with Live Availability — Checks after typing stops and suggests alternatives on collision
**Why this component matters:** Debounce the availability check, and always render the response for the current value — a slow earlier request arriving late will otherwise overwrite a newer, correct answer.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Ranked Bars — Sorts itself and scales each bar against the largest
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Ranked Bars — Sorts itself and scales each bar against the largest
**Why this component matters:** Ranked lists must sort in code, not in the markup. Hardcoding the order means a data change silently produces a wrong ranking that still looks plausible.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Period Comparison — Current against previous — the delta computed both ways
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Period Comparison — Current against previous — the delta computed both ways
**Why this component matters:** A single number answers “how many”, never “is that good”. Showing the previous period beside it, with the gap computed, is what turns a number into information.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Stats Grid — Four numbers at a glance — every delta computed, not typed
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Stats Grid — Four numbers at a glance — every delta computed, not typed
**Why this component matters:** The most common stat block. Its trap is hardcoded deltas: the moment the data changes the percentage lies. Compute it from the current and previous values so it can never drift.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Live Counter — Animates between values smoothly and honours reduced motion
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Live Counter — Animates between values smoothly and honours reduced motion
**Why this component matters:** A counter that jumps is hard to read; one that animates for two seconds is annoying. Ease it over ~600ms, and skip the animation entirely when prefers-reduced-motion is set.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Progress Ring — A share of a target — the ring’s circumference computed from its radius
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Progress Ring — A share of a target — the ring’s circumference computed from its radius
**Why this component matters:** Rings are usually faked with a hardcoded stroke-dasharray, which breaks the moment the size changes. Computing the circumference from the radius keeps the fill exact at any dimension.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Stat with Sparkline — The curve is drawn from the data itself — not a static image
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Stat with Sparkline — The curve is drawn from the data itself — not a static image
**Why this component matters:** A sparkline pasted as an SVG shape is decoration. Generating the path from the series means the line always tells the truth, and the min/max labels stay correct.
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
Support Chat — Bubbles swap sides
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Support Chat — Bubbles swap sides
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
**Typography:** Cairo for Arabic, IBM Plex Sans for Latin. Arabic line-height must be
Toasts — Slide from the correct side
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Toasts — Slide from the correct side
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
**Typography:** Cairo for Arabic, IBM Plex Sans for Latin. Arabic line-height must be
Tax Invoice — ZATCA-compliant layout
**Role:** You are an Arabic-first UI designer and front-end engineer. Read the whole
**Goal:** Tax Invoice — ZATCA-compliant layout
**Direction:** Genuine RTL — not a mirrored Latin layout. Use logical properties
**Typography:** Cairo for Arabic, IBM Plex Sans for Latin. Arabic line-height must be
لا نتائج. جرّب كلمة أقصر.