Layout
SwiftUI-inspired layout primitives for the web. Stack, HStack, VStack and Spacer compose exactly like their Swift namesakes; containers, grids, split views and scroll areas cover the rest. Everything spaces itself from the 4px token scale — no margin fiddling.
Container
.b-container centers content and clamps its width — the
default cap is --b-container-lg (64rem). Size variants
swap the cap; --fluid removes it. Wider variants clamp
to this page's width here, which is exactly what they'd do on a
narrow viewport.
Stack (VStack)
.b-stack (alias .b-vstack) is a vertical
flex column with a token gap — the default building block for any
view. Tune spacing with the gap scale — .b-gap-0,
.b-gap-1, .b-gap-2, .b-gap-3,
.b-gap-4, .b-gap-6, .b-gap-8 —
instead of margins on children.
Alignment
Cross-axis alignment mirrors SwiftUI's
VStack(alignment:) — --start,
--center and --end (children stretch by
default).
HStack
.b-hstack lays children out in a row, vertically
centered. The alignment modifiers are shared with Stack — add
.b-stack--between to spread children across the row.
Title + Spacer + action
The classic SwiftUI bar: a title, a .b-spacer to eat
the middle, and a trailing action.
.b-gap-*) and
push them apart with .b-spacer or
--between — one knob, consistent rhythm.
Grid
.b-grid is a 12-column grid by default: set
--b-cols (or a .b-grid--2/3/4/6 preset)
and place children with .b-col-span-* classes.
The presets are responsive, and the base 12 is not. A row of N equal
cards is a desktop shape: three pricing cards on a 390px phone came
out 110px wide with one word per line, so
.b-grid--2/3/4/6 start at one column and earn more at
36rem and 62rem. The 12-column base is an explicit layout you placed
by hand, so it is left alone; anything that genuinely wants a fixed
count at every width sets --b-cols itself, which is what
the presets are written in terms of.
Auto-fit
.b-grid--auto packs as many tracks of at least
--b-col-min (default 16rem) as fit — responsive with
zero media queries.
Flex
A thin display: flex shorthand for when a stack is too
opinionated. --center and --between handle
both axes; .b-grow and .b-shrink-0 tune
individual children.
Split View
Master–detail in one line of markup: .b-split stretches
.b-panel children to equal height with a
.b-resize-handle between them. Make the sidebar
.b-resizable and dragging is native CSS
resize — no JavaScript.
role="separator" with
aria-orientation and an aria-label, and
offer a keyboard path — arrow-key handling on the handle or a width
control elsewhere in the view.Resizable Panel
.b-resizable adds the browser's native resize grip to
any panel — horizontal by default, --vertical for
height. Look for the grip in the bottom-trailing corner; min and max
bounds are built in.
Panel
.b-panel is the plain workhorse surface: surface
background, hairline border, large radius. --plain
strips the chrome for panels that only exist to scroll or resize.
Section
.b-section adds generous block padding between page
regions — the vertical rhythm of a landing or settings page.
--tight is the compact cut. Dividers shown here only to
make the padding visible.
Card Grid
A responsive shelf of cards: auto-fill columns at least 17rem wide, token gap, no breakpoints. The default answer for dashboards and galleries.
Masonry
CSS-columns masonry for content of uneven height — pins, notes,
image cards. Items flow down each column in source order; cap the
column count with --b-masonry-cols.
Scroll Area
Give it a height and .b-scroll-area contains the
scrolling: overscroll never leaks to the page and the scrollbar
gutter stays stable. --fade masks both edges so clipped
content looks intentional.
<div> isn't keyboard-reachable on every browser.
Add tabindex="0" plus role="region" and an
aria-label (as above) so keyboard users can focus and
scroll it.Spacer
Straight from SwiftUI: .b-spacer is an empty flex-1
element that absorbs leftover space. Push row siblings apart, or pin
a footer to the bottom of a fixed-height stack.
Divider
Hairline separators drawn with --b-separator.
Horizontal by default; use them sparingly — a stack gap is often
separation enough.
Above the fold
Below the fold
Vertical
--vertical separates inline actions inside an hstack or
toolbar.
Inset
--inset starts the hairline past the leading edge so it
aligns with list text — the iOS settings look.
Label
--label centers a caption between two hairlines —
the classic "or" between sign-in choices.
<hr> maps
to role="separator" and is announced. That's right for
meaningful breaks like the labelled "or"; mark purely decorative
hairlines aria-hidden="true" so screen readers skip
them.Responsive
Barua is mobile-first and the components own their own shrinking —
pages should not need bespoke media queries. .b-dashboard
spans collapse to full width below md (768px) and the
column grid engages above it. Floating surfaces clamp themselves to
the viewport: toasts, notifications, menus and the command palette
cap their width, and the dock tray scrolls when crowded. The
breakpoint scale lives in
Foundations; when a component should
respond to its box rather than the viewport, use container queries
below.
Wrapping toolbars
Add .b-stack--wrap to any .b-hstack so a
crowded row reflows onto new lines instead of squeezing its items —
the pattern behind the ambient example’s header.
Visibility utilities
.b-hide-mobile and .b-hide-desktop flip at
md — use them to drop rails, inspectors and secondary
chrome on phones. Resize the window to see them trade places.
Stage
.b-stage turns a page into a fixed screen: full
viewport height, no scrolling — the layout for ambient walls,
kiosks and TV-style surfaces where everything must be visible at
once. Its .b-container child stretches, a
.b-dashboard inside shares the remaining height
between rows, and cards clip internally instead of growing the
page. Below md it steps aside and the page scrolls
like any phone screen. The ambient example is built on it.
This is the Barua stance, not a special case: on desktop
there is no page scroll. A surface ends at the screen —
chrome stays put, and only designated panes move:
.b-scroll-area, a workspace main, a list. Every
example ships this way; build products the same way.
Container Queries
SwiftUI's ViewThatFits, the CSS way: mark a wrapper
.b-cq and children respond to the container's
width — .b-cq-show-sm/md/lg appear at ≥24/40/56rem,
.b-cq-hide-* retire. The same component adapts in a
sidebar and in a full-width main without media queries.
Text that fits
SwiftUI has minimumScaleFactor; CSS has no direct
equivalent, but a container query unit does the same job honestly.
.b-fit-text sizes its child as a fraction of the
container's width, clamped so it can never become unreadable at one
end or absurd at the other.
Same figure, three widths, one class. Tune it with
--b-fit-min, --b-fit-max and
--b-fit-scale. It is for a single line that must not wrap
— a total, a headline figure, a name in a narrow column — not for
paragraphs, which should wrap rather than shrink.