Doop
Doop is an open-source multiplayer design canvas and design MCP for Claude Code, Codex, and any AI agent. Design side by side with agents — free in beta.
A design system for dense, data-heavy interfaces. Light and dark, with every contrast ratio measured rather than assumed.
DesignTypeScript · CSSGitHub @fernandorvianaOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Loading the full README. The saved excerpt is shown below.
A design system for dense, data-heavy interfaces. Light and dark, with every
contrast ratio measured rather than assumed.
Named after the light that stays on the mountains after the sun has gone —
and after my daughter Leonor, a name to which the sense of "light" is
usually attributed.
Theme: Eleonora.
With Tailwind v4, import the stylesheet into a layer so utilities can override
components:
More on the site: Install ·
Tailwind ·
Dark mode.Read the full README ↗A design system for dense, data-heavy interfaces. Light and dark, with every contrast ratio measured rather than assumed.
Named after the light that stays on the mountains after the sun has gone — and after my daughter Leonor, a name to which the sense of "light" is usually attributed.
Theme: Eleonora.
npm install alpenglow
import 'alpenglow/styles.css';
import { Button } from 'alpenglow';
With Tailwind v4, import the stylesheet into a layer so utilities can override components:
@import "tailwindcss";
@import "alpenglow/styles.css" layer(components);
@import "alpenglow/tailwind-theme.css";
More on the site: Install · Tailwind · Dark mode.
Three layers, mirrored in Figma as three variable collections, and density, a fourth collection whose modes are comfortable and compact rather than light and dark.
| Layer | Varies by mode | What it holds |
|---|---|---|
| Primitives | no | The raw ramps. 113 opaque colours — white and ten families of eleven stops, generated in OKLCH with one lightness per stop, plus a twelfth, 925, the surface step, in stone and night only — plus 21 alpha values: twelve on the black and white ramps, four inks (the light divider, two shadows, the dark scrim), the light scrim's mist, and the four hazes of the hover and pressed wash. Nothing references these directly. |
| Theme | Light / Dark | 94 semantic tokens — surface, text, interactive, border, category, six hues for colour by category rather than by meaning, and chart, a sequential and a diverging ramp, each step measured on the canvas and on a card. Every value is an alias. |
| Elevation | Light / Dark | Shadows. Only the ink varies by mode; the geometry does not. |
| Scale | no | Spacing, radius and border width. Dimension must not be reachable by a theme switch. |
| Motion | no | Two durations and two curves. fade for a change in place, travel, a little longer, for something that moves. |
| Density | Comfortable / Compact | Five heights — a control, a table row and its header, the scheduler's hour, a navigation item. Compact is chosen with data-density="compact" on any element, and gives the comfortable values back under a touch pointer. A control given a size keeps it. |
TypeScript is the source of truth. Both stylesheets are generated from it, and the type system prevents a token from aliasing a primitive that does not exist.
| Artefact | Consumed by |
|---|---|
src/styles/tokens.css | Anyone. Plain CSS custom properties. |
src/styles/tailwind-theme.css | Tailwind v4 projects, via @theme. Points at the variables above rather than restating the palette, so utilities follow light and dark. |
src/components/* | React, styled with CSS Modules. Nothing to configure. |
The token layer is not tied to a styling choice — that is the point of shipping both, and tests assert the two stay in step.
253 test cases covering what the design actually depends on: text clearing AA on every surface it can appear on, the chart ramps' steps kept a measured lightness apart and the text a value takes on each, status text clearing AA on its own subtle background, every button label clearing AA on all of its fill states, control borders clearing WCAG 1.4.11, the dark elevation ladder staying ordered and separable, no token collapsing into the surface behind it, and a dialog staying distinguishable from its backdrop.
It is not decoration. It caught five real defects on its first run, including a divider that resolved to exactly the same colour as the surface beneath it.
The set is IBM Carbon — around 2,700 icons, Apache 2.0. Carbon is not a dependency: a design system that bundles an icon library makes everyone carry all of it to use six, so you install it yourself.
npm install @carbon/icons-react
import { Search } from '@carbon/icons-react';
<Input iconStart={<Search size={20} />} placeholder="Search clients" />
Sizes are 16, 20, 24 and 32. Components size their own icon slot, so pass the size that matches: 16 in a badge, 20 in a field.
Fifteen icons are not Carbon's. They were drawn for this system because Carbon
does not have them, and they ship with it, exported alongside the components —
ChevronSmallDown, AiSparkle, WaitingRoom and twelve more.
Eight more exist in Carbon under a different name — notifications is
Notification, list--task is TaskComplete — which is the kind of mismatch
that costs an afternoon. The full mapping is on the Icons page.
Light and dark are asymmetric. In light, surface/raised and
surface/overlay are both white and the shadow separates them. In dark, shadows
stop reading as elevation, so overlay has to be a lighter colour step.
Button labels are themed, not constant. In dark the accent fill lightens across hover and pressed while its label darkens to compensate. Keeping a white label there fails AA at the hover step — which is precisely the trap that makes the palette look incapable of a lighter dark-mode hover.
npm install
npm run dev # the documentation site at localhost:3000
npm run build:css # regenerate both stylesheets
npm run check # types, then every documented contrast ratio
npm run build:docs # the site as a static export, in out/
npm run audit:responsive # the build, every route, five widths
npm run audit:css-order -- --a <dev url> --b <built url> # the same pages, dev against the build
The site is a static export, so it hosts anywhere. Set DOCS_BASE if it is
served from a subpath.
The two audits are how a change is seen in the production build and not only
in next dev, which loads CSS in a different order. audit:responsive serves
out/ itself and opens every route at 320, 375, 768, 1024 and 1440 (dark at
375 and 1440 too), and reports a page that scrolls sideways, content that
overflows with nothing clipping it, and content a box clips instead of
wrapping; --only /drawer,/table narrows the routes, --widths 320,375 the
widths, and --shots keeps screenshots. audit:css-order measures every
element's box under <main> on two servers of the same site, at 1440 and 375,
and reports any that differ by more than 2px — a rule that wins on one side
and loses on the other; it skips /screen, which frames /screen/full, and
says so. Both exit 1 on a failure or a run that errored, and 2 when --only
names a route the build does not have; both write to .audit/.
They drive Google Chrome, headless, over the DevTools protocol — from its
macOS path, or from CHROME=/path/to/chrome — and need Node 22 or later, for
its global WebSocket.
MIT