Ostorya dev docs

Design system

Foundations

Color, status tones, type, sizes, glass, icons and motion: the values every Ostorya app uses.

Color#

Ostorya has one brand color, and it isn't fixed: the accent follows the merchant's wallpaper or their pick in Desktop & appearance. Use var(--o-accent) for primary buttons, switches and selected states, andvar(--o-accent-ink) for accent text, icons, borders and rings (on a dark wallpaper the accent can be near black; in dark mode --o-accent-ink lifts it so it stays readable). Never write the default sage #627a66 in your code.

--o-accentPrimary actions. Default sage, set from theme.accent.
--o-accent-softSelected rows, icon chips, highlights.
--o-inkText. #f5f5f7 in dark mode.
--o-mutedSecondary text, labels, placeholders.

No bright palette colors (a pure green, red or blue) and no third-party brand colors: they break the calm of the desktop and clash with the merchant's accent.

Status tones

Statuses use five soft tones, each with a light and a dark value. They are fixed: never the accent, so an order reads the same on every desktop. Grey means "not yet" or "over", never success; red only means failed or destructive.

To confirm Delivered Shipped No answer Returned
HTML
<div class="o-card o-row-gap">
  <span class="o-badge"><i data-lucide="clock"></i>To confirm</span>
  <span class="o-badge o-good"><i data-lucide="circle-check"></i>Delivered</span>
  <span class="o-badge o-info"><i data-lucide="truck"></i>Shipped</span>
  <span class="o-badge o-warn"><i data-lucide="phone-missed"></i>No answer</span>
  <span class="o-badge o-bad"><i data-lucide="undo"></i>Returned</span>
</div>
ToneClassUse for
Neutral (grey)o-badgePending, nothing yet, over: To confirm, Draft, Archived, Expired, Paused.
Good (sage)o-goodDone or live: Confirmed, Delivered, Paid, Active.
Info (slate)o-infoOn its way or later: Shipped, Out for delivery, Call back, Scheduled.
Warn (sand)o-warnNeeds attention: No answer, Attempted, Needs cost.
Bad (clay)o-badFailed: Refused, Returned, Lost, Cancelled. Solid clay for a delete button.

Typography#

Inter, with Western digits in every language. Ostorya's sizes are small and precise: most of the desktop is 13 and 14px.

SizeWeightUse for
22px600Page title inside a card, large numbers
18px600Section title, empty state title
20px600KPI value (tabular figures)
14px400Body text, inputs, card titles (600)
13.5px500–600Buttons, segmented controls, menu items
13px500Labels, compact buttons, secondary text
12–12.5px500Badges, help text, captions
12px uppercase600, +0.04emKPI labels only

Sizes and spacing#

Spacing follows a 4px grid: 4, 6, 8, 12, 16, 20, 24. Cards are 16px apart; content is 20px from a card's edge.

ElementSize
Button, field, select40px high (36px compact, 32px icon button in a row)
Segmented control36px buttons in a 4px padded track
Switch40 × 24px
Checkbox, radio18px
List row48px, one line, 36px thumbnail
Cardradius 22px, padding 20px
Field, inset panelradius 12px / 16px
Menu, popoverradius 14px, items 36px
Buttons, badges, tabsfully rounded (pill)
Icons16px in buttons and rows, 12px in badges, 26px in empty states

Glass#

Glass is Ostorya's signature: a light top-to-bottom gradient, a 24px blur with saturation, a hairline border and a soft long shadow. The kit's o-card is exactly the Store's card.

Glass card

The merchant's wallpaper shows through, blurred.

With an inset

Grouped content uses a soft inset, not another card.
HTML
<div class="o-grid o-grid-2">
  <div class="o-card">
    <h3 class="o-h3">Glass card</h3>
    <p class="o-muted" style="margin:0">The merchant's wallpaper shows through, blurred.</p>
  </div>
  <div class="o-card">
    <h3 class="o-h3">With an inset</h3>
    <div class="o-inset">Grouped content uses a soft inset, not another card.</div>
  </div>
</div>
  • Keep html and body transparent (o-app does it). Never paint a full-page background.
  • Don't put a card inside a card: group with o-inset instead.
  • Never put filter or opacity below 1 on an element with backdrop-filter: the blur disappears.
  • Reduce glass (a desktop setting, or the OS's reduced transparency): the kit makes cards solid whenreduce-glass is on html. Test your app with it on.
  • Menus, popovers and modals are nearly opaque (95%), so text stays readable over anything.

Icons#

Ostorya uses Lucide, stroke 2, 16px next to text. Every button, tab, filter, menu item and nav link gets one. In React use lucide-react; in plain HTML write <i data-lucide="plus"></i> and calllucide.createIcons(). The examples in this guide use that form.

Motion#

  • Short and physical: springs for things that move (a switch knob, the selected segment), 150ms fades for color.
  • Cards fade up 10px when a page opens; nothing loops except loading skeletons.
  • Respect prefers-reduced-motion: the kit stops its own animations.

Window and dock#

  • Your app fills a desktop window. Don't add a title bar or close button: use bridge.setTitle().
  • The dock floats over the bottom of every window: leave var(--o-dock-room) (92px) free at the bottom of scrolling pages, and never place fixed buttons there.
  • Under 768px your app is full screen above the dock bar. Design for 360px wide.