3.4 KiB
Mako design language
Mako follows the Lightwell design language, the same one Hammerhead and Megalodon use. The reference is docs/design.md in the Lightwell repository. When this page and Lightwell disagree, Lightwell wins.
Shared with Lightwell
- Tokens. Colors, spacing (4px scale), radius, type sizes, the single shadow and the dark theme are the Lightwell values. The accent is teal,
#1f5c5c. Raw colors live only betweentokens:beginandtokens:endinstyle.css. - Voice. No emoji, no em or en dashes, no exclamation marks, sentence case, buttons that name the result, and errors that say what happened and what to do next. Server errors are capitalized in one place (
failininternal/web/server.go). - Status carries text. "Pinned", "Saving", "Saved" and "Not saved" are words, never a colored dot.
- Structure. Sidebar and drawer shell, cards, dialogs with a focus trap,
confirmDialogfor anything that cannot be undone, skeletons for loading, empty states that say why a list is empty.
Where Mako differs
- The page is the interface. Lightwell puts the one primary button in the page header. A page has none: the title and the text are the thing, and everything else (Pin, Move, Subpage, Delete) is a small ghost button above them. On Home the primary button, Save note, sits in the quick-note box. Elsewhere the rule holds: Write today on the Journal, Continue with Authentik on the sign-in page.
- Saving is automatic and says so. There is no Save button on a page. The status reads Saving, Saved, Unsaved or Not saved, and a problem (offline, session ended, changed elsewhere) is a notice above the text that keeps the text on screen.
- Deleting a page is not confirmed, it is undoable. Delete moves a page to the trash and offers Undo. Only Delete for good and Empty trash ask first, naming what is lost.
- Navigation is a tree. The sidebar nests pages the way they were made. A page that holds the one you are on stays open. Quick notes with no title stay out of it.
- Script and styles are separate files, because the Content-Security-Policy forbids inline script and
styleattributes. Widths and indents come from classes.element.styleis used only to size a text box to its text and to place the suggestion list at the caret, which the policy allows. - Rendered pages use a small safe markdown renderer in
markdown.js. It builds elements, never HTML, and onlyhttp(s)links are links.[[Page]]links are internal; a dashed one is a page that does not exist yet. - Edits go through the browser (
execCommand), not by assigning the text box's value, so Undo keeps working after a list continues or a suggestion is picked.
Icons
Lucide style, outline only, stroke 1.75, round caps, currentColor, sizes 16, 18 and 22. An icon goes with a text label, and icon-only buttons carry an aria-label.
Approved names: fin, notes, home, today, journal, pin, tag, trash, edit, restore, clock, view, download, copy, prev, next, chev, search, link, move, lock, settings, out, menu, close, add, check, light, dark, alert. Add a name here and in ICONS together.
Checking a change
node scripts/lint-design.mjs
It fails on em and en dashes, emoji, and raw colors outside the token block. Then check the page in light and dark, at phone and desktop width, using only the keyboard.