|
|
||
|---|---|---|
| .github | ||
| assets | ||
| fonts | ||
| preview | ||
| references | ||
| ui_kits | ||
| uploads | ||
| vue | ||
| .gitignore | ||
| AGENT_RULES.md | ||
| CLAUDE.md | ||
| colors_and_type.css | ||
| README.md | ||
| SKILL.md | ||
| tokens.json | ||
| tokens.ts | ||
LoSnoCo Design System
LoSnoCo — López and Snowhill Company. Kevin López and Chris Snowhill, working as a two-person studio. The design language is the visual expression of that: confident, restrained, built by two people who know what they're doing — not a Series B pitch deck.
This system covers everything we produce, for ourselves and for others. Internal tooling (dashboards, docs, service portals like Mastodon, Forgejo, auth), our own public-facing sites, and client-facing work we ship under the LoSnoCo name — decks, proposals, emails, marketing pages, apps. Any LoSnoCo-branded surface should feel like part of the same system.
Sources used to build this system
uploads/SKILL.md— the canonical LoSnoCo design brief, written in platform-neutral terms (tokens, component semantics, voice, logo rules). This is the source of truth. Copied here as the starting point; the rest of the files below are derivatives or implementations of it.uploads/tailwind.css— full Tailwind v4 theme mapping of LoSnoCo tokens. Copied verbatim toreferences/tailwind.css.uploads/quasar.md— SCSS configuration for applying the LoSnoCo language to a Quasar v2 (Vue 3) project. Copied verbatim toreferences/quasar.md.uploads/losnoco25-sq.svg— Badge logo (black-ground, self-contained). Copied toassets/losnoco25-sq.svg.uploads/WordmarkForLight.svg— Wordmark (context-aware, class-targeted fills). Copied toassets/WordmarkForLight.svg.
No codebase, Figma link, or slide template was attached. This system is built entirely from the brief + logo assets. If there is a live LoSnoCo web application, reattach it via the Import menu and we can pull real components.
Index — what's in this folder
| Path | Purpose |
|---|---|
README.md |
You are here |
SKILL.md |
Portable Agent Skill entry point — brand summary + how to use this folder |
colors_and_type.css |
Canonical CSS custom properties — brand colors, UI surfaces, type scale, spacing, radii, semantic selectors (h1, h2, code, p…). Drop-in for any HTML prototype |
fonts/losnoco-fonts.css |
Imports the self-hosted Inter LoSnoCo + Iosevka LoSnoCo webfonts from assets.losno.co |
assets/ |
Logo SVGs — losnoco25-sq.svg (badge) and WordmarkForLight.svg (wordmark) |
references/ |
Reference implementations for specific stacks: tailwind.css (Tailwind v4 theme), quasar.md (Quasar/Vue 3 SCSS), LoSnoCo-color-theme.json (VS Code-compatible syntax highlighting theme) |
preview/ |
Per-token / per-component preview cards rendered in the Design System tab |
ui_kits/ |
High-fidelity recreations of LoSnoCo surfaces — one folder per product |
UI kits:
ui_kits/services_directory/— aservices.losno.co-style directory page listing internal services (Mastodon, Forgejo, auth, wiki, etc.), the canonical long-form LoSnoCo content surface.ui_kits/admin_panel/— a Quasar-style operational dashboard showing host status, sessions, and recent events. Represents the internal side of the same system.
Content Fundamentals
Who's writing: a two-person studio. The voice is the same whether we're writing for ourselves, for peers who already speak the language, or for a client we're producing work for under the LoSnoCo name — adjust explanation depth to the audience, not the voice itself.
Voice
- Technically fluent. On internal or peer-facing surfaces, the copy doesn't explain federation, mesh VPN, or SSO — it assumes the reader knows, or will figure it out. On client-facing surfaces, explain as much as the audience needs, but don't pad. Link the doc before you inline the 101.
- Dry, not nihilistic. Humor is allowed and occasionally earned. Sarcasm is a seasoning, not the dish.
- Values embedded, not announced. Positions (craft, restraint, self-hosting, owning our stack) are expressed through what's on the page, not through manifesto paragraphs. You don't need to say "we believe in owning our stack" when the work demonstrates it.
- Personal but edited. Warm and polished are not mutually exclusive.
Specific examples (from the brief)
"social.losno.co — a Mastodon instance on the Fediverse. Small by design."
"Forgejo over GitHub because that question answered itself."
"auth.losno.co · realm: LoSnoCo · the layer that makes this feel like one system."
Note the register: confident, concise, occasionally funny, never explains itself more than necessary. A sentence ends as soon as it has earned its meaning.
Casing and punctuation
- Labels are always uppercase. No exceptions. If it isn't uppercase, it isn't a label — it's a heading, a caption, or running text.
- Titles use sentence case, not Title Case. "Small by design" — not "Small By Design".
- Hostnames, paths, and technical strings are rendered in the mono family
and preserve their original casing (
social.losno.co, notSOCIAL.LOSNO.CO). - Em dashes (—) and middle dots (·) are used as connectives in single-line taglines. Prefer them to commas where they read more like UI.
- Pronouns: first-person plural ("we run…") is fine for two-people statements; second-person ("you can…") for user-facing instructional copy. No royal "we" stand-ins for "I".
Emoji
No. Not in UI labels, not in body copy, not as bullets or status markers.
Emoji are conspicuously absent — they read as a different voice and would
undermine the restraint. Use colored dots, Iosevka punctuation glyphs
(→, ·, •), or small SVG icons instead.
Visual Foundations
Colors
Two brand colors, one accent, one background family. That's it.
- Orange
#F25E0D— Kevin / "Lo". Used sparingly. Section labels, key callouts, the single most important button on a screen. Earns its authority through scarcity. Three orange buttons on one view = zero orange buttons. - Teal
#0DF2C9— Chris / "Sno". High-energy. Dark surfaces only — too low-contrast on light. Used inside the badge logo and on dark UI. - Teal-light
#00967F— the contrast-safe Chris/Sno. Use for teal text, links, focus rings, and interactive elements on light surfaces. This is the default "interactive" color in the light theme. - Purple
#7B41B9— the third accent. Tags, annotations, status. Never mixed with orange or teal inside the same element. Not for primary nav or links — that register belongs to teal. - Orange and teal only appear together in the logo. Not alternated freely as UI accents.
Surfaces (light): warm off-white #F4F3F0 page → #ECEAE5 surface →
#D8D5CE border → #888880 muted → #1A1917 text. Deliberately not stark
white; the warmth reads as personal, edited, not corporate-default.
Surfaces (dark): cool teal-tinted near-black #111C1A → #182926 →
#243D38 → #7A9E98 → #E5EFED. Cool contrasts the warm light theme.
Code is the deliberate exception: inline code and code blocks keep a dark terminal treatment in both color schemes. They do not flip to warm light surfaces when the page is in light mode.
Syntax highlighting follows the editor theme: when rendered code is actually
token-highlighted, use references/LoSnoCo-color-theme.json as the source of
truth so highlighted output matches the LoSnoCo editor palette instead of a
library default.
Typography
- Inter LoSnoCo — custom variable-font build of Inter. OpenType features
(case alternates, disambiguation, tabular numbers, etc.) frozen into the
build via featfreeze — no
font-feature-settingsneeded anywhere. - Iosevka LoSnoCo — three builds:
Iosevka LoSnoCo Web→ code blocks, terminals (operator ligatures on)Iosevka LoSnoCo NoLig Web→ inline code, identifiersIosevka LoSnoCo NoLig QP Web→ hostnames, paths, metadata in prose (quasi-proportional — reads more naturally than strict monospace)
- Base size 15px. Type scale is semantic (display / heading / subheading / body / technical / label / caption), not numeric steps.
- Labels always uppercase with +0.2em tracking. The rule.
All fonts self-hosted at assets.losno.co. Not Google Fonts — that would be a
rather ironic surrender for an org whose identity is owning its stack.
When emitting HTML, preload the exact LoSnoCo CSS URLs the page uses via the
framework's head/preload mechanism, or with explicit
<link rel="preload" as="style"> tags in <head> before the stylesheet
links. That includes the local entrypoints (fonts/losnoco-fonts.css and
colors_and_type.css) and any direct assets.losno.co stylesheet URLs. If
the page links hosted font files directly, add a preconnect to
https://assets.losno.co and preload those files with as="font" and
crossorigin.
Spacing
Six-step scale: xs/sm/md/lg/xl/2xl = 4/8/15/24/38/60px. Multiplicative, not
arithmetic — the jumps read as distinct without ornamental in-between values.
Borders, cards, shadows
- Cards are
surfacebackground with aborderoutline. Radius8px. - Multi-cell grids use a trick: give the container a
1pxgap and set the gap's background toborder. Cells get no individual borders. Result: clean hairline separators with no double-border artifacts. - Shadows only where structurally necessary (modals, toggle thumbs, popped
menus). No ornamental shadows on resting cards or buttons. Light theme
shadow:
0 4px 24px rgb(0 0 0 / 0.1). Dark:… / 0.4. - Radii scale: 10px major containers → 8px cards → 6px buttons/inputs/notes → 4px checkboxes → 3px inline code → pill for dots and tags.
Backgrounds
Flat. Warm off-white (light) or cool near-black (dark). No gradients. No patterns. No imagery. Full-bleed photography is not part of the language; the one exception is the Badge logo's self-contained black ground. If a page needs visual texture, that texture comes from typography and the hairline-grid card structure — not decorative overlays.
Animation
-
All transitions are short (100–150ms) and ease-ed, not bouncy.
-
Button state change:
120ms ease. -
Toggle thumb slide:
150ms ease(slightly longer so the motion reads). -
Focus rings appear without animation.
-
No spring physics, no bounces, no parallax. Motion is functional, not decorative.
-
The motion layer is part of the brand, not optional polish. Apply it on every runtime that supports animation by translating the duration and easing tokens into the host framework's primitives:
- Web (HTML/CSS, Vue, Quasar):
transition+ the.enter-*utilities,prefers-reduced-motionfor opt-out. - SwiftUI:
withAnimation/.animation(...)withAnimation.timingCurve(...)matching--ease-out/--ease-in-out, gated onaccessibilityReduceMotion. - WinUI XAML: storyboards or
ImplicitAnimationswith the duration tokens, gated onUISettings.AnimationsEnabled. - Flutter:
AnimationControllerand implicitAnimated*widgets withCurves.easeOut/easeInOut, gated onMediaQuery.disableAnimations.
Skip motion only on platforms that genuinely can't run it (static email, exported PDF, rasterized slide images).
- Web (HTML/CSS, Vue, Quasar):
Interaction states
- Hover: darken surface by one step (
surface→surface-2). Borders may darken toborder-strong. Links switch fromteal-lighttotext. - Active/Press: darken one more step (
surface-2→surface-3). No scale transform — the system reads as digital and stable, not tactile. - Focus: 2px
teal-lightring. 2px offset for buttons, 0 offset (flush) for inputs. Never optional — keyboard nav is not an afterthought. - Disabled: 40% opacity for buttons; receded bg/border for inputs.
- Selected state:
purpleaccent (from the annotation register).
Transparency and blur
- Navigation bar is sticky,
rgba(244,243,240,0.92)+backdrop-filter: blur(8px). The content underneath remains faintly visible — the nav sits above content without fully obscuring it. - Modal backdrops: solid-ish scrim at
rgb(0 0 0 / 0.4). No blur under modals (would compete with the blurred nav). - Elsewhere, transparency is avoided — UI surfaces are opaque so text stays crisp.
Layout rules
- Max content width: 820px, centered.
- Page padding: horizontal
space-md(1rem), bottomspace-2xl+. - Section padding:
space-2xltop,space-xlbottom, hairlineborderat bottom. - Grid gap:
space-mdbetween free-standing cards;1pxfor hairline- separator grids. - No defined breakpoints. Components should work from ~320px up; horizontal scroll is a last resort, not a strategy.
Imagery
There essentially isn't any — and that's the point. No stock photos, no illustrations, no hero images. The only graphics are:
- The two logo SVGs.
- Colored status dots.
- Iosevka glyphs (arrows, middle dots, bullets).
- Form control SVGs (select arrow, checkbox checkmark) embedded as data URIs.
If a real product page ever needs a photo, treat that as an exceptional event and brief separately. The default is "text and tokens do the visual work".
Iconography
LoSnoCo's brief does not ship a bespoke icon set. The pragmatic implementation uses a hairline-stroke outline style at ~1.5px that reads well next to Inter's optical sizing and stays quiet against surfaces.
- No emoji. Ever. See the Content Fundamentals section.
- No unicode char icons as primary glyphs (✓ / ✗ are allowed inside Do/Don't list markers only; the brief names them explicitly).
- Colored dots serve as category/status indicators — an orange dot for
Kevin-owned services, a teal or green dot for Chris-owned, a muted dot for
shared. These come from
<span class="dot dot-orange">with a simple CSS circle, not SVG. - Logo SVGs (
assets/losnoco25-sq.svg,assets/WordmarkForLight.svg) are the only vector brand assets that ship. Don't recolor or decompose the badge; the wordmark has three class-targeted fills (.lopez,.snowhill,.co) that adapt to context —.coiscurrentColor. - UI icons — because no repo-specific icon font was provided, this system links Lucide from CDN as the default. Lucide's 1.5px stroke, rounded-join geometry and open-aperture forms match Inter LoSnoCo's "disambiguation" alternates better than Heroicons or Feather. This is a substitution — flag it to the user. If LoSnoCo has a house icon set, provide it and we'll swap.
Logo usage — which asset when
When applying the skill to a real project or scaffold, ask the user whether the LoSnoCo logo should be included before adding either logo asset.
| Context | Asset |
|---|---|
| Avatar, favicon, app icon, profile picture | losnoco25-sq.svg (badge) |
| Page header, footer, inline brand mention | WordmarkForLight.svg (wordmark) |
| Unknown / variable background | Badge |
| Known light or dark surface | Wordmark |
The badge carries its own black ground and its own contrast — drop it on any
surface. The wordmark is context-aware: .lopez is always orange; .snowhill
is teal-light on light / teal on dark; .co inherits currentColor.
⚠ Substitutions flagged to the user
- Fonts —
assets.losno.cois imported via CSS@import. If the preview environment is offline or the host is unreachable, the cards will render in system-ui fallbacks. If that happens and you want pixel-perfect LoSnoCo type, either drop the Inter LoSnoCo / Iosevka LoSnoCo webfont files intofonts/and switch to@font-facerules, or confirm network access. - Icons — no repo icon set provided; Lucide linked from CDN as a close stylistic match. Swap if LoSnoCo has a house icon set.
- UI kits — no codebase or Figma was attached. The UI kits in
ui_kits/are high-fidelity reconstructions from the brief + voice examples. They represent what a LoSnoCo services directory and admin dashboard would look like per the spec — not screenshots of something that already exists.