Responsive
Phone first: what changes at 640, 768 and 1024px, 44px touch targets, and pickers that open from the bottom on phones.
Bridge is built phone first: the plain classes are the phone, and sm:, md: and lg: add the bigger screens. Three lines do the work, each with a known job, so every screen folds the same way.
Breakpoints
| Prefix | From | What changes |
|---|---|---|
| (none) | 0 | Phones. Write this first; everything else adds to it. One column, 16px edges, bottom tabs, 16px fields, 44px targets. |
sm: | 640px | Page edges 24px, card grids go two-up, the top bar's links appear and the bottom tabs go. |
md: | 768px | Tablets. Fields drop to 14px and 40px, menus replace bottom sheets, a list and its detail sit side by side. |
lg: | 1024px | Page edges 32px, card grids three-up, side rails and the admin sidebar appear. |
xl:, 2xl: | 1280px + | Not used. A bigger screen shows the same page, centred at its width. |
What changes at each width
Read across a row to see one part of a screen at every width.
| Phones | 640 to 1023px | From 1024px | |
|---|---|---|---|
| Navigation | Bottom tabs (up to 4) | Top bar | Top bar; sidebar for more than 4 places and admin |
| Page edges | 16px | 24px | 32px |
| Card grid | One column | Two columns | Three columns |
| Side rail | Above the main column | Above the main column | 340px beside it |
| List and detail | One pane, back arrow | Side by side from 768px | Side by side |
| Tables | Scroll sideways inside their card | Same | Every column shows |
| Filters, pickers | Bottom sheet, 44px rows | Menu from 768px | Menu |
| Fields | 16px text, 44px tall | 16px, 44px; 14px and 40px from 768px | 14px, 40px |
| Main buttons | 44px tall | 44px; 40px from 768px | 40px |
| Page header actions | Wrap under the title | Beside the title | Beside the title |
Touch
- On phones, anything tapped often is at least 44px tall: list rows, tabs, menu rows, fields and main buttons. The package's components already are.
- Everywhere, nothing is smaller to hit than 28px. A control can draw smaller (a 16px checkbox) and reach 28px with an invisible tap area around it, as Checkbox does.
- Never hide an action until the pointer hovers. Phones can't hover, so the action would never appear. Show it, or show it on hover only where hovering exists (
[@media(hover:hover)]:opacity-0 group-hover:opacity-100). - Tips and hover cards don't open on touch. Anything people need is in the visible label or on the page; a hover card's name is a link to the full page.
Pickers open from the bottom
Below 768px, a filter, a picker or any list people scroll or search slides up from the bottom, near the thumb, instead of opening a small menu by its button. The sheet names the choice, its rows are 44px, and a choice closes it.
A filter on a phone
Tap it: the choices slide up from the bottom. FilterPill and ColumnFilterMenu do this by themselves below 768px.
Opens as it would on a phone.
- FilterPill and ColumnFilterMenu switch by themselves. A new picker uses BottomSheet below 768px the same way.
- Short action menus (Edit, Share, Remove) stay menus, with 44px rows on phones.
- Drawers and dialogs stay as they are: a drawer fills the phone's width, and a dialog stacks its buttons.
When the structure changes
Style with classes (md:), which work before the page finishes loading. Use useIsMobile() only when the tree itself is different on a phone: one pane instead of two, a sheet instead of a menu.
import { useIsMobile } from "@brdgapp/ui/hooks/use-is-mobile";
// true below 768px; false until the page has loaded
function Inbox() {
const phone = useIsMobile();
const [open, setOpen] = useState<string | null>(null);
if (phone) return open ? <Thread id={open} onBack={() => setOpen(null)} /> : <List onOpen={setOpen} />;
return <SplitView … />;
}Rules
- No sideways page scroll at any width. A wide table scrolls inside its own card.
- On phones the page leaves room above the bottom tabs, and anything floating sits above them.
- Components follow the window, not the box they sit in. Bridge doesn't use container queries.
- Hide with
hidden md:blockonly what has another home on that screen: links that moved to the bottom tabs, a rail that moved above the column.
Check every screen at
| Width | Stands for | Check |
|---|---|---|
| 390px | A phone | 16px edges, no sideways scroll, one pane, bottom tabs, 16px fields, sheets instead of menus. |
| 768px | A tablet, upright | Menus return, list and detail side by side, 14px fields. |
| 1024px | A small laptop | Side rails and the admin sidebar appear without crowding the main column. |
| 1440px | A desktop | Pages stop at their width and centre; tools fill the screen. |