Files
lodge/DESIGN.md

20 KiB
Raw Permalink Blame History

name, description, colors, typography, rounded, spacing, components
name description colors typography rounded spacing components
lodge The admin of a notes server for coding agents, drawn as a borehole strip log.
survey-green curve-red ochre log-paper log-paper-2 ink ink-2 rule grid grid-strong green-wash red-wash night-survey-green night-curve-red night-ochre night-ground night-ground-2 night-ink night-ink-2 night-rule night-grid night-grid-strong night-green-wash night-red-wash
#24694f #b3341f #c9a24a #eef0e6 #e3e7d8 #15211d #46544d rgb(21 33 29 / 0.2) rgb(36 105 79 / 0.13) rgb(36 105 79 / 0.3) rgb(36 105 79 / 0.12) rgb(179 52 31 / 0.11) #74caa6 #f08a74 #d9b45e #162026 #1d2a31 #e6eadc #a5b2a8 rgb(230 234 220 / 0.2) rgb(111 199 163 / 0.09) rgb(111 199 163 / 0.24) rgb(116 202 166 / 0.14) rgb(240 138 116 / 0.14)
display headline title body prose label mono
fontFamily fontSize fontWeight lineHeight fontVariation
Archivo Variable, system-ui, sans-serif clamp(2.25rem, 6vw, 4rem) 700 1 'wdth' 66
fontFamily fontSize fontWeight lineHeight fontVariation
Archivo Variable, system-ui, sans-serif 2.5rem 700 1.05 'wdth' 75
fontFamily fontSize fontWeight lineHeight letterSpacing fontVariation fontFeature
Archivo Variable, system-ui, sans-serif 1.75rem 600 1.1 0.02em 'wdth' 68 'tnum'
fontFamily fontSize fontWeight lineHeight
Archivo Variable, system-ui, sans-serif 1rem 400 1.5
fontFamily fontSize fontWeight lineHeight
Archivo Variable, system-ui, sans-serif 1.0625rem 400 1.65
fontFamily fontSize fontWeight letterSpacing fontVariation
Archivo Variable, system-ui, sans-serif 0.75rem 500 0.06em 'wdth' 80
fontFamily fontSize fontWeight
JetBrains Mono Variable, ui-monospace, monospace 0.8125em 400
none
0
xs sm md lg xl 2xl
0.5rem 0.75rem 1rem 1.5rem 2rem 3rem
action-text action-text-hover action-text-danger action-text-danger-hover action-solid action-solid-hover action-solid-danger field file-row file-row-hover file-row-current top-bar code-block
textColor padding rounded
{colors.survey-green} 0.125rem 0 {rounded.none}
backgroundColor
{colors.green-wash}
textColor
{colors.curve-red}
backgroundColor
{colors.red-wash}
backgroundColor textColor padding rounded
{colors.ink} {colors.log-paper} 0.625rem 1rem {rounded.none}
backgroundColor
{colors.survey-green}
backgroundColor textColor
{colors.curve-red} {colors.log-paper}
textColor padding rounded width
{colors.ink} 0.5rem 0 {rounded.none} 100%
textColor padding
{colors.ink} 0.5rem 0.375rem
backgroundColor
{colors.green-wash}
backgroundColor textColor
{colors.ink} {colors.log-paper}
height padding
3rem 0 1rem
backgroundColor typography padding
{colors.log-paper-2} {typography.mono} 0.875rem 1rem

Design System: lodge

Overview

Creative North Star: "The Borehole Strip Log"

History is a drilled column. Every revision is a bed at its depth, newest at the surface, and the note on screen is the core pulled from the selected depth. The interface is a sheet of survey log paper: a fine green depth grid under the column, ink rules, condensed stamped numerals, and one hatch per machine, the way a geologist's log gives every rock type its own fill. The machines page is the legend of that log.

The sheet carries no chrome. There are no cards, no boxed buttons, no shadows and no rounded corners. Hierarchy comes from scale contrast (a 4rem condensed repository name against 0.75rem labels), from full-strength ink rules against faint ones, and from fills: ink for the current row, washes for hover, hatches for who wrote what. It refuses the forge layout of a file table with a commits tab, and the metric-card dashboard.

The dark theme is the same sheet as a night print: the same grid, rules and hatches in pale ink on a near-black blue ground. Nothing is restyled between themes; only the token values change, which is why hatches are masks over the ink colour instead of drawn images.

Key Characteristics:

  • One column of beds is the navigation: drag it, step it with arrow keys or j/k, and every depth, file and view is a deep link.
  • Type, fills and rules only. Zero radius, zero shadow, zero boxed controls.
  • Three working colours with fixed meanings: green selects and links, red is the depth cursor and destruction, ochre is the web's own hand.
  • Archivo's width axis does the stamping: the narrower the setting, the more the text is data.
  • Reading first: the note sits at a 70ch measure and management lives in the margins.

Colors

A cool greenish log paper and near-black green ink, worked with a survey green, a curve red and a small amount of ochre. Every colour is a CSS custom property that the .dark class redefines; components never name a hex.

Primary

  • Survey Green (survey-green, night: night-survey-green): links on hover, text actions, the selection background of ::selection, list markers in notes, added lines and the ADDED kind in a bed, the mark beside beds that touched the open file, and the hatch colour of a hovered bed. At 12 to 14% alpha it is the hover wash (green-wash) and at 13% and 30% it is the depth grid (grid, grid-strong).

Secondary

  • Curve Red (curve-red, night: night-curve-red): the depth cursor (a 3px line across the column with a 0.625rem by 2.75rem handle on its right edge) and the selected depth numeral; the 2px underline of the current nav item and current view; the focus ring and the text caret; deletions, problems and destructive actions. red-wash is its hover and removed-line fill.

Tertiary

  • Ochre (ochre, night: night-ochre): a solid fill, never text. It is the lithology of revisions made from the web admin (restores), and the 1px rule beside a blockquote in a note.

Neutral

  • Log Paper (log-paper, night: night-ground): the page ground, and the text colour on ink and red fills.
  • Log Paper 2 (log-paper-2, night: night-ground-2): the ground of the strip log column, code and pre blocks, the pairing command, and loading skeletons.
  • Ink (ink, night: night-ink): text, structural 1px rules (column edge, title block base, group headings, list separators on index pages), hatches, the solid action and the current file row.
  • Ink 2 (ink-2, night: night-ink-2): labels, meta lines, depth numerals, unchanged diff lines, quiet beds, placeholders, the scrollbar thumb.
  • Rule (rule, night: night-rule): ink at 20% for the faint separators between rows, title block cells and beds, and the resting underline of links.

Named Rules

The Three Pens Rule. Green, red and ochre each have one job. Green means select or go, red means you are here or this destroys, ochre means the web did it. A new state borrows one of those meanings or uses ink; it does not get a fourth colour.

The Text Contrast Rule. Green and red are used as text on paper, so they are held at 4.5:1 or better against log-paper. This is why the shipped light values are darker than the direction contract's #2f7d62 and #c5402f: those failed as text on #eef0e6. Ochre does not pass as text on paper and is used only as a fill or a rule.

The Night Print Rule. The dark ground is night-ground (#162026), not the contract's slate #33444c. The owner saw the slate ground during the build and asked for the darker one back; treat this as a decided value. A --slate custom property is still declared in the stylesheet but nothing uses it.

Typography

Display Font: Archivo Variable with its width axis (with system-ui, sans-serif) Body Font: Archivo Variable at normal width Label/Mono Font: JetBrains Mono Variable (with ui-monospace, monospace)

Character: One family doing two jobs through its width axis. At normal width it is a plain reading face; squeezed to 62 to 80% it becomes the stamped lettering of a drawing title block. JetBrains Mono, with ligatures off, carries everything a machine produced: SHAs, keys, paths, commands, code, diffs.

Hierarchy

  • Display (700, clamp(2.25rem, 6vw, 4rem), line-height 1, width 66%): repository names on the index and the Machines page heading. The login wordmark is the one larger setting (800, clamp(3.5rem, 10vw, 6rem), width 62%, line-height 0.9).
  • Headline (700, 2.5rem, line-height 1.05, width 75%): the file name above a note; 1.75rem below 56rem.
  • Title (600, width 68%, tabular numerals, 0.02em tracking): the stamp. 1.75rem for the repository name in the title block and machine names, 1.375rem for the "Depth N" heading, 1.125rem for counts in fact lines, 0.8125rem for depth numerals on the column. The top bar wordmark is the same idea at 800 weight, 1.25rem.
  • Body (400, 1rem, line-height 1.5): interface text. Meta and fact lines drop to 0.875rem or 0.9375rem in ink-2.
  • Prose (400, 1.0625rem, line-height 1.65, 70ch measure): rendered notes. Headings inside a note are 700 at width 85%: 1.625rem, 1.3125rem, 1.125rem, line-height 1.2, balanced wrap.
  • Label (500, 0.75rem, width 80%, uppercase, 0.06em tracking, ink-2): field names in the title block (Repository, Depth, Root), space group headings over file lists, form labels, and at 600 weight with 0.04em tracking the change kind (ADDED, MODIFIED, DELETED).
  • Mono (JetBrains Mono, 0.8125em of its context, ligatures off): SHAs, repository keys, paths, commands, inline code, source and diff views at line-height 1.6, tab size 2.

Named Rules

The Width Is Meaning Rule. Condensed width marks data the system stamped: names, depths, counts, kinds. Sentences a person reads stay at normal width. Do not condense body copy to save space, and do not set a stamp at normal width.

The Label Names A Field Rule. An uppercase label always names the value or list directly under it, as in a drawing's title block. It is never a decorative line above a headline.

Layout

The signed-in shell is a 3rem top bar with a 1px rule base, then the page.

The reader is a three-track sheet filling the rest of the viewport (100dvh - 3rem), each track scrolling on its own: the strip log at 17.5rem, the file list at 20rem, and the note taking the remainder. Below 72rem the first two narrow to 15rem and 17rem. Below 56rem the log collapses to a 4.5rem rail on the left edge (depth numerals and hatch only; formation labels and the Depth and Root cells are dropped) and the files and the reader take turns in the second track, with a "Files" link leading back. The column edge and the title block base are full ink; the edge between files and note is rule.

Index pages (repositories, machines) are a single 72rem column with 3rem top, 1.5rem side and 6rem bottom padding (2rem, 1rem, 4rem below 40rem or 48rem). Their lists are rows separated by a 1px ink top rule with no enclosing box. The login page is a two-track grid: a full-height hatch core clamp(3rem, 12vw, 9rem) wide, then a form capped at 26rem and centred vertically.

Spacing is a rem rhythm of 0.5, 0.75, 1, 1.5, 2 and 3. Panels pad 1.5rem; the note pads 2rem on top, clamp(1.5rem, 4vw, 4rem) at the sides and 6rem below. Empty and hint text is capped at 34rem, the note at 70ch.

Inside the column, a bed's height is its size: 20px plus 6px per changed file, capped at six changes. Its grid is 2.75rem depth numerals, 4.5rem hatch, 0.5rem touch mark, then the formation label. Numerals print on every fifth depth, the first, the last and the selected one. A formation label (branch and short SHA) prints only where the main commit changes. The depth grid is 8px squares with a stronger line every 40px.

Motion: state changes ease over 150ms with cubic-bezier(0.16, 1, 0.3, 1). The only animation is settle, a 600ms top-down clip reveal on a bed that has just arrived over SSE. Under reduced motion both collapse to 1ms.

Elevation & Depth

Flat. There is no box-shadow anywhere in the build, and no overlays, modals or popovers. Depth in this system is literal: the vertical position of a bed in the column. Layering is tonal and ruled: log-paper-2 sits under the column and code, ink rules mark structure, rule marks rows. Confirmations open in place in the flow of the page rather than floating above it.

Named Rules

The One Sheet Rule. Everything is printed on the same sheet. If something needs to stand out, give it an ink rule, a fill or a bigger size, not a shadow or a raised surface.

Shapes

Square. No radius is used anywhere and inputs reset it to 0. Borders are 1px hairlines, in ink for structure and rule for separation; the only heavier strokes are the 2px field underline, the 2px focus ring, the 2px current-item underline and the 3px depth cursor. Dashed 1px lines mean absence: the outline of a bed whose machine is gone, and the "N unchanged lines" gap in a diff.

The recurring figure is the lithology hatch. Seven authored SVG tiles (dots 6x6, diagonals 8x8, dashes 12x10, bricks 12x8, crosses 8x8, waves 12x6, chevrons 8x6, all 1px strokes) are applied as repeating CSS masks on a pseudo-element filled with a --l colour that defaults to ink. Because the tile is a mask and the colour is a token, hatches follow the theme and can be recoloured per state (green on hover, ink-2 at 60% for beds that did not touch the open file). A machine takes the tile at its index modulo seven. Web revisions are solid ochre. Revoked or unknown machines get no fill and a dashed outline. Beds above the selected depth lose their hatch, so the column reads as drilled down to the cursor.

The contract listed six hatches drawn as SVG patterns; the build ships seven, as masks.

Components

Buttons

Actions are text with a rule under them, not boxes.

  • Shape: square (0 radius), no border box.
  • Text action: weight 600 in survey green, 0.125rem vertical padding, a 1px underline in its own colour. Hover fills green-wash behind it. The danger variant is curve red with red-wash. Links use the same class to act as actions.
  • Solid action: the one filled control, for the single primary act of a page (sign in, create or copy a pairing command, delete with all history). log-paper text on ink, 0.625rem by 1rem padding, no underline; hover turns the fill survey green. The danger variant is filled curve red.
  • Plain tool: top bar utilities (theme switch labelled "Night print" or "Day print", sign out) are bare ink-2 text that goes to ink on hover.
  • Disabled: 50% opacity, default cursor. Focus: the global 2px curve red outline at 2px offset.
  • Destructive flow: confirmations replace the action in place with a question and two text actions; deleting a repository sits in a closed disclosure at the foot of the file list and needs the repository name typed.

Cards / Containers

There are none. Groups are made by an uppercase label over a 1px ink rule and rows beneath it. Code, pre blocks and the pairing command are log-paper-2 fills with no border, the command with a 1px ink rule on its left edge.

Inputs / Fields

  • Style: transparent ground, full width, 0.5rem vertical padding, a 2px ink rule underneath and nothing else. Placeholder in ink-2. Tokens and keys are typed in mono.
  • Focus: the underline turns curve red; the outline is suppressed because the underline is the indicator. The caret is curve red everywhere.
  • Error: a weight 500 curve red sentence with role="alert" above or below the control.

Navigation

A 3rem bar: the wordmark "lodge" (800, width 68%, 1.25rem, no underline), then section links at body size with a transparent underline. The current section gets a 2px curve red underline. Below 40rem the Repositories link is dropped because the wordmark already goes there. The view switch over a note (Read, Changes, Source) uses the same treatment plus weight 700 for the current view, sitting on a rule line with the restore action pushed to the right.

Links everywhere are ink with a 1px rule underline at 0.22em offset; hover turns the text and the underline survey green.

Strip Log

The signature component: a vertical listbox of beds on log-paper-2 with the depth grid. Above it a title block, a ruled dl whose cells are a label over a stamp (Repository across the full width, then Depth as "selected / total" and Root as a mono key). Click or tap selects a depth; pressing with a mouse, or on the already selected bed by touch, starts a scrub that re-renders files and note live and replaces history state until release. Arrow keys and j/k step. The selected bed carries the red cursor and a red numeral, scrolls itself into view, and takes over touch so a thumb drag scrubs instead of scrolling. When a file is open, beds that touched it show a survey green mark in the 0.5rem track and the rest go quiet.

File Row

A row in the file list: directory in regular weight at 65% opacity, file name at 600, a change track on the second line, and a relative time at 0.8125rem. The track is a 0.4375rem high baseline with a 2px tick wherever the file changed across the whole history; ticks above the selected depth drop to 30%. Hover is green-wash; the open file inverts to log-paper on ink. The repository index uses the same idea at a larger size: a 1.75rem high ink-bordered core strip with one hatch cell per recent revision, which turns green on hover along with the name.

Note

Three views of one file. Read is sanitised markdown at the prose size and measure, with square survey green list markers, log-paper-2 code, a 1px ochre rule beside blockquotes and rule lines under table rows. Source is mono, preformatted. Changes is a mono line diff with three lines of context: added lines on green-wash with a green "+", removed on red-wash with a red "−" and a red strikethrough, unchanged lines in ink-2, and collapsed runs as a dashed-ruled "N unchanged lines" line in the sans face.

Skeleton

Loading is a flat log-paper-2 block the size of what is coming. It does not shimmer.

Do's and Don'ts

Do:

  • Do take every colour from the custom properties so the night print follows for free; add a value to both :root and .dark or not at all.
  • Do draw any new pattern as an SVG tile used as a CSS mask over --l, so it inherits ink and can be recoloured by state.
  • Do keep green and red at 4.5:1 or better on log-paper when they carry text, and keep ochre to fills and rules.
  • Do use Archivo's width axis for stamped data (66 to 80%) and normal width for sentences; set numerals tabular.
  • Do make every new view state a URL parameter, the way depth, file and view already are.
  • Do keep motion to 150ms state changes on the shared ease, with the clip-reveal settle reserved for a revision arriving live.
  • Do name component classes so they cannot collide with Tailwind utilities. Tailwind is imported globally, so a scoped class called fixed picked up position: fixed during this build. Avoid bare utility words (fixed, static, hidden, block, flex, grid, container, truncate, underline, transition) as class names.

Don't:

  • Don't add cards, boxed or pill buttons, radii or shadows. Separation is an ink rule, a rule line or a fill.
  • Don't build a file table with a commits tab or a metric-card dashboard; history stays a column you drag.
  • Don't give a state a fourth accent colour, and don't set ochre as text.
  • Don't lighten the night ground toward slate; #162026 is the owner's decision.
  • Don't float confirmations in modals or popovers; they open in place.
  • Don't put an uppercase label above a headline as decoration. A label names the field or the list under it.
  • Don't embed hatches as coloured images or fixed-colour backgrounds; they would not follow the theme.