Rekta Design

Rekta Design · a design language · 0.2 · desktop and web

Straight lines, live tiles, sideways motion.

no cards · two independent themes · four status fills · every value a token · no framework

Rekta Design is a platform-neutral design language; the name comes from Latin recta, the straight line. This site is built in it, and every part of it is a live example: you are inside a panorama, the pivot above names its sections in a fixed order, and the app bar below holds the global controls.

active –tokens, for every platform Open the tokens: every value in a table you can sort, filter and select, each one's detail beside it. done 0.2what is new
done AAtext on every fill
active –frames a second, measured here
done 0external requests
waiting nextdate ranges

Move sideways with the mouse wheel, a trackpad swipe, or ← → once the panorama has focus. On a phone, just scroll down. Ctrl K goes anywhere; ? lists every key.

Inspired by Metro.

Rekta Design is inspired by Microsoft's Metro design language, to us one of the best UX designs ever shipped, from Zune and Windows Phone 7 (2010) to Windows 8 (2012). We find it a pity that no major product uses it today, so Rekta takes up its ideas in its own form: its own tokens, typography and components.

  • 2000sMedia Center, Zune
  • 2010Windows Phone 7
  • 2012Windows 8
  • todayRekta Design
  • content over chromeThe information is the interface. Nothing gets a box just to look tidy.
  • authentically digitalNo imitation leather or paper: type, colour and motion that belong to a screen.
  • type as structureRooted in the Swiss International Typographic Style and the wayfinding signage of public transport: large, plain, readable at a glance.

Its token values are derived from the source code of the Porsche Design System (Apache-2.0): numbers and colours only, no code, fonts or marks.

sources: Metro (design language) · International Typographic Style · Porsche Design System. Rekta Design is independent and not affiliated with or endorsed by Microsoft or Porsche.

Nothing is decoration.

  1. content over chromeNo cards, no boxed panels. Information sits on the ground, grouped by hairlines and whitespace.
  2. motion as guidanceEvery transition answers a question: where am I, which facet, what just happened.
  3. information-dense live tilesA tile's size follows importance; its fill is its status. It opens something or only informs.
  4. panorama and pivotOne place, wider than the screen, moved through sideways; its facets in a fixed order.
  5. refined precisionHairlines, tabular figures, calm large areas, vivid small accents.

Status is a fill, not an accent.

Neutral ground, no brand hue. Four status colours carry meaning and only meaning: large fills use the dampened tile form, small marks the saturated full form. Primary text sits on every fill and must clear AA; the ratios below are measured live, in the theme you are looking at.

active–primary text on info#7da1f4 · #244592
done–primary text on success#61caa6 · #337a62
waiting–primary text on warning#f8d866 · #6e5900
failed–primary text on error#c86065 · #76171f

activewaitingfaileddoneidle

In running text a status takes a soft tint: the import failed, the review is waiting.

neutral surfaces · light · dark

  • bg#ffffff · #0e0e12
  • surface#eeeff2 · #212225
  • surface-2#e4e5e9 · #2a2b2f
  • text-primary#010205 · #fbfcff
  • text-contrast-high#535457 · #afb0b3
  • text-contrast-medium#6b6d70 · #88898c
  • text-contrast-low#d8d8db · #404044
  • accenttext-primary · text-primary
  • focus#1a44ea · #178bff
  • disabled#949598 · #7e7f82

contrast on neutral ground

pairneedsnow
text-primary on bg4.5 : 1–
text-primary on surface4.5 : 1–
text-contrast-high on bg4.5 : 1–
text-contrast-high on surface4.5 : 1–
text-contrast-medium on bg3 : 1–
focus on bg3 : 1–
on-accent on accent4.5 : 1–

One slot is a product's own: the accent, ink until a product sets it. It fills the primary button, checked controls and a selected row; never a tile or a status. Try another in look, or make your own in forms.

Three levels, one bold title.

Level 1, a quiet kicker. Level 2, the one semibold title per screen. Level 3, a fact line. Navigation titles, like the pivot above, are large and light: they name a place, not a thing. UI words are lowercase; content keeps its own case. Sizes are in rem, so they follow your text size; large ones grow with the place, not the screen.

scale

  • Rektaxxs 0.75rem
  • Rektaxs 0.8125rem
  • Rektas 0.9375rem
  • Rektam 1.125rem
  • Rektal clamp(1.375rem, 1.5cqi, 1.75rem)
  • Rektaxl clamp(1.625rem, 2cqi, 2.125rem)
  • Rektaxxl clamp(1.875rem, 2.6cqi, 2.75rem)
  • Rektanav-active clamp(2.5rem, 4.2cqi, 4.5rem)
  • Rektanav-inactive clamp(1.375rem, 1.9cqi, 2rem)
  • Rektapivot-active clamp(1.75rem, 2.6cqi, 2.625rem)
  • Rektapivot-inactive clamp(1.25rem, 1.6cqi, 1.625rem)
  • Rektagroup clamp(1.375rem, 1.7cqi, 1.875rem)
  • Rektatitle clamp(1.875rem, 2.8cqi, 3rem)

Body text is Barlow at 15px, self-hosted under the SIL Open Font License; numbers that read as data use weight 500 and tabular figures.

Tiles, not cards.

A tile's whole area is one fill, and the fill is its status. Size follows importance; content follows a few patterns: a stat, a sparkline, progress, the status word. A tile opens something, or it only informs: it never changes data. Press one and it nudges back where you press it. These tiles measure this page, live.

active 1 / 16sections seen Every section you move to counts. When you have seen them all, this tile is done, and holds still.
active 0pointer moves a second
idle 0.2release notes
idle 0 stime on this page

The waiting tile is a button: it opens a sheet. The release notes tile is a link: it turns this place. Finished tiles drop their sparkline: stillness means done. Every chart has a text equivalent.

One place, wider than the screen.

A panorama is one place laid out sideways. One wheel gesture moves one thing: started over a section that can still scroll, it scrolls the section; otherwise it moves the panorama sideways. Horizontal input is left alone; at either end the wheel falls through.

Where the place is narrower than 760px or the window shorter than 480px, everything stacks and the page scrolls. Right now:

  • window-size class–
  • density–
  • theme–
  • motion–

A pivot is one place's facets in a fixed order. The active title is large; the strip never reorders. It glides by the title's place in the order, less than the content moves, so the titles before it stay in reach. Facets add nothing to history.

4 open · 2 waiting · 1 failed

  • Nightly importfailed
  • Release noteswaiting

The strip above this site is the same component: move the panorama and watch it follow, a step behind. Use ← → once a facet has focus.

Every transition means one thing.

transitiontimingmeans
place change400ms, turnstile 40degyou are somewhere else
press100ms in, tilt 8degthis heard you
facet change0.75 × 400ms, 24px slidesame place, other facet
tiles build in400ms, 30ms apartassembling from live data
reorder400msthis moved because of you
resize, re-flow400msthis grew; the rest made room
arrive, leave250ms, leaving fasterthis one is new; that one is gone
live tile news400ms: peek, or flipa new number; a new status
data morph600msthe same thing, measured again
sheet, toast250msa short question; something happened
floating list150msoptions for this control
loadingafter 300ms, a line every 1200msworking on it
live drawing600msupdating right now

reorder

  • write the release notes
  • check contrast in dark
  • tag 0.2

try

change place

Reduced motion zeroes every duration: transitions become instant, never skipped, and live values keep updating. Wall-clock timings, like a toast's undo window, stay.

Rows on hairlines, chosen the Metro way.

show columns



A click selects a row and shows it. Ctrl+click adds another and starts the selection mode: then every click adds or removes, and the app bar carries the selection. Shift+click takes a range, Esc ends it. A selected row nudges, takes the accent and a checkmark. Drag a column's edge to size it; double-click a group to edit it; right-click a row for its menu.

–

status

Nothing selected.

the same on rows

  • Nightly importfailed
  • Release noteswaiting
  • Contrast checkdone
  • Font subsetactive

Nothing selected. A selected failed job still says failed.

Every value of the system in a table, the current one beside it: the tokens. Narrower than 760px, rows stack as “label value”: no sideways scrolling on a phone.

A desktop app, by mouse and by keys.

Rest the pointer on a control: a tooltip. Right-click, long-press or Shift F10 on a file: a context menu. A tree that opens and closes, a list you order by its grip, and ten thousand lines that scroll like ten.

  • tokens
    • rekta.tokens.json
  • src

files

Choose a file.

Click a file, or move with the arrow keys: → opens a folder, ← closes it.


order the release, by its grip

  1. write the release notesdocs
  2. check contrast in darktokens
  3. run the smoke testtest
  4. tag the releasegit
  5. publish the tokensdist

ten thousand lines

–

Click a line, or focus the list and move with ↑ ↓ PageUp PageDown. Only the lines in view exist.

An event leaves, a state stays.

Something that just happened is a toast: ink, one at a time, with an undo window you can hold by pointing at it. A lasting state of the whole system takes the banner on top: one at a time, the most severe first, its end reported as a toast.

  • banner nownone
  • live dataupdating

a region loading, empty, failed

Nothing open. Well done.

Could not load: the server is offline.

Nothing shimmers: placeholders stand still, and the line comes only after 300ms, so a fast answer never flickers.

Live, and honest about it.

Live values say how fresh they are, and say so when they stop. Rest the pointer on them and they hold still while you read; updates wait behind a button. Turn the feed off and watch it go stale.

active–requests a second
waiting–jobs in the queue
done–finished today

    undo history

    1. Nothing yet. Archive a component, edit a group, or order the release.

    Everything you archive, edit or move on this page lands here. Ctrl Z takes the last step back, Ctrl Shift Z does it again; the toast offers the same.

    Checked late, corrected early.

    Make a product accent. A field is checked when you leave it and corrected as you type; sent with errors, a summary comes first. Name it “plum” and the server says no at the field; send it during maintenance and it says no to the form. Change something and leave: it asks first.

    How the product calls it, lowercase.
    A hex colour that holds 3:1 on the light ground.
    Left empty, dark keeps ink.

    Native where it can be, Rekta where it shows.

    Every input here changes something you can see. A select, a number, a date and a time are the platform's own controls in Rekta's frame, so their pickers, keys and screen readers come for free; the rest are Rekta's own.

    size
    active12builds today
    idle3a neighbour
    idle8another one
    A combobox: it filters as you type and keeps only a choice from its list.
    100%
    Sizes are in rem: the whole page follows, as it follows your browser's text size.
    The browser's own date and time pickers, in Rekta's frame.
    files

    Toggle switches act at once, so they live outside forms that are sent; a checkbox waits for “save”. Segments are for two to five options you see at a glance; more go in a select.

    Data, quiet until it matters.

    Charts in ink and grey: one axis, round ticks on hairlines, the accent only where you point. Every chart reads out its values under the pointer or with ← → once it has focus, and shows its numbers as a table. A status colour appears only where a value means that status.

    a day

    build minutes

    meters

    processor42%
    memory63%
    disk on runner 3 · waiting81%
    artifact storage · failed100%

    progress

    importing 1,284 runs0%
    reindexing, length unknown

    Yours to set.

    theme
    density
    By pointer: 44px controls with touch, smaller with a mouse or trackpad. The app bar stays 48px.
    motion
    accent

    Checked, not assumed.

    • keyboard firstEvery pointer action has a key; focus moves to what opens and comes back to what opened it.
    • focus on fillsOn a tile the ring is drawn inset in the tile's text colour, so it survives every fill. Tab into the tiles below.
    • colour is never aloneEvery status has its word, every chart a text equivalent, the app bar's square its word beside it.
    • contrast is measuredThe build fails when a pair drops below its minimum, or when two statuses come too close under colour blindness.
    • touch44px targets, no hover-only actions, 16px fields, and dragging never activates.
    • forced coloursFills drop; tiles keep an edge, marks and meters keep their shape.

    Fifty-one icons on one grid.

    20 × 20, a 1.6 stroke, square ends, in the text colour, so they follow every theme. An icon goes beside a word; alone, it has a name and a tooltip. The web takes rekta.icons.svg (a sprite: <use href="#rk-i-search">); other platforms take rekta.icons.json, the same shapes as data.

    Rest the pointer on one of the toolbar buttons in “desktop”: an icon alone gets its name as a tooltip, and its accessible name stays.

    An app, not a tab.

    Install this site and it opens in a window of its own, with Rekta's title bar where the browser's was. It works offline, and a new version waits until you say “reload”. A native shell (Electron, Tauri, a WebView) gets the same title bar by setting data-rk-titlebar.

    • works offline–
    • installed–
    • connection–

    Offline, the banner says so and the page keeps working from what it saved. A new version is announced by a toast with “reload”; it never replaces the page while you are in it.

    Same numbers, different plumbing.

    The tokens are platform-neutral; a native app reads rekta.tokens.json: the same values resolved, in logical px, ms, hex and four numbers per curve. Names are the same everywhere: space-m is --rk-space-m on the web and SpaceM in your toolkit.

    conceptwebnative desktop
    unitsrem for sizes that follow the text size; fluid type as clamp() against the placelogical pixels scaled with the OS text size; the same min, max and share of the pane's width
    window-size classcontainer queries on the place, and the viewport heightthe pane's width and the window's height, same thresholds
    densitythe pointer: fine without touch is compactthe input devices present; the same two densities
    wheelone gesture, one scrollerthe native wheel event, same rule; trackpad pans left alone
    backhistory: links, Esc, the browserthe shell's back command, the mouse back button, Alt+←
    reduced motionprefers-reduced-motion or data-motionthe OS setting or the same in-app switch
    themeprefers-color-scheme or data-themethe OS appearance or an in-app switch; two independent token sets

    Tokens first, then CSS and script.

    1. take the tokensrekta.tokens.json for any platform; rekta.tokens.css on the web.
    2. add the componentsrekta.css, with rekta.fonts.css and the Barlow files.
    3. add the behaviourrekta.js as a module, or rekta.global.js as a classic script. No framework needed, and any framework can use it.
    <link rel="stylesheet" href="rekta.tokens.css">
    <link rel="stylesheet" href="rekta.fonts.css">
    <link rel="stylesheet" href="rekta.css">
    <script type="module">
      import * as Rekta from './rekta.js';
      Rekta.start();
      Rekta.places({ home: 'home' });
      Rekta.panorama(document.querySelector('.rk-panorama'),
        { pivot: document.querySelector('.rk-pivot') });
    </script>

    Code, tokens, CSS and script: MIT. Docs and images: CC BY 4.0. Barlow: SIL Open Font License 1.1. Not affiliated with or endorsed by Microsoft or Porsche.

    Rekta Design

    tokens

    Every value, a token.

    –

    value
    tokens
    Rekta Design

    release notes

    Rekta 0.2

    tokens for every platform · components · behaviour, no framework

    done1token source for every platform
    done0frameworks needed
    waitingnextdate ranges

    new

    • tokensOne DTCG source; CSS with theme, density and reduced motion; resolved JSON for other platforms.
    • behaviourrekta.js: press, the turnstile, places and back, panorama, pivot, toasts, the banner, menus, tables, splits, the palette, forms.
    • window-size classesSideways or compact, decided by the place and the window's height.
    • densityCompact with a mouse, comfortable with touch, yours to choose.
    • listsTables that sort and stack, selection the Metro way, splits, search and filters in the address.
    • formsLate checks, early corrections, a summary, server answers at the field, a guard against lost input.

    unreleased, on its way

    • inputsSelect, combobox, the Metro toggle switch, stepper, slider, date and time, segments, a drop zone for files.
    • desktopTooltips, context menus, a tree, ordering by a grip, ten thousand lines, columns that size and hide, editing in place.
    • live and undoLive regions that say how fresh they are and hold still while you look; an undo history behind Ctrl+Z.
    • dataLine and bar charts in ink and grey, meters, progress, Metro's flying dots.
    • app shellFifty-one icons, the title bar of an installed app, installable and offline.

    open the tokens

    live
    0 selected

    help

    Keyboard shortcuts

    • go to a place or run a commandCtrl K
    • this list?
    • back, or close what is openEsc
    • previous or next section (panorama focused)← →
    • first or last sectionHome End
    • select another row, start the selection modeCtrl + click
    • select a rangeShift + click
    • select all rows (table focused)Ctrl A
    • undo the last actionCtrl Z
    • do it againCtrl Shift Z
    • the menu of a row or a fileShift F10
    • edit a cell (table row focused)F2
    • move an item by its gripSpace ↑ ↓

    sheet

    A button tile opens a sheet.

    It never changes data itself.

    sheet

    Reset the demo?

    Selections, filters, the accent, the banner and the counters go back to the start. Theme, density and motion stay as you set them.