Skip to content

usalu/semio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

semio
A free online playground to toy with semio without login. The documentation page to learn semio. The semio storybook for all javascript components and tests. Discord
The semio repository. Cite Affero General Public License v3.0 or later
The presentation of our latest research paper on LLMs with semio. The latest research paper on LLMs with semio. The presentation of our previous research paper on formalizing architecture.
Browser Grasshopper Windows macOS
Typescript Python C#

🧩 Design-Information-Modeling for Kit-of-Parts 🏘️


You want to 🧩 the next 🏘️🏛️🏢🏭🏫🏨⛪🕌 with 🤖? But 📐🔢🗣️👥🖱️⌨️ takes all your ⌚? Then try to 🧠 the 🧬 and let semio 💉🖥️✒️🖨️🪄🚀

👋 Hello contributor

Note

Are you a user or new to semio? Then you might want to first check out our docs 📖

Glad to see you!

Let me walk you through 🚶

📑 Overview

  1. 🛍️ Products
  2. 📄 Specs
  3. 🦑 Repo
  4. 🧑‍💻 Development
  5. ♻️ Ecosystems
  6. 📦 Components
  7. 🏘️ Examples
  8. 💯 Brand
  9. ⚖️ License
  10. 🔒Security
  11. ✨ Contributors
  12. 📊 Stats

🛍️ Products

Do you wonder how semio is interopable? The reason are shared specification, ecosystems and components 🪢

Work-in-progress artifacts stay bundled with the active ticket workspace so teams can trace temporary data without hunting global temp locations.

✏️ sketchpad

sketchpad is a simple-to-use, accessible and browser-based user interface for semio🖱️

It is the digital pencil for sketching plans and digital scalpel for building models in semio ✍️

Sketchpad uses semantic borders to communicate interactive element edges and window boundaries. Windows are separated from the canvas edge and from each other by a single spacing unit, and each window is outlined by a continuous border.

Each window has a consistent set of icon actions (open in new window, maximize/minimize, close) that stays in the same position across window kinds.

Sketchpad uses background levels to visually distinguish the base canvas from windows, panels, and transient UI surfaces.

Sketchpad is a multi-window workspace: each app defines which window kinds it supports and window layouts persist so users can restore their preferred arrangement.

In a multi-window workspace, exactly one window is active and its surface uses the active background color; table views follow the active window surface background.

Hover and selection cues stay consistent across Home, Kit, Design, Type, Quality, Docs, and Feedback so focus follows your pointer and selection across the workspace.

sketchpad demo

👥 studio

A studio is a synchronous collaboriation environment for teams to work together in semio 🤝

☁️ cloud

Use any file-hosting platform as an asynchronous Common-Data-Environment 📁

Cloud Demo

🤖 assistant

The assistant helps you on every step in the design process with semio ✍️

semio assistant Demo

VS Code Extension

The VS Code extension keeps tickets close to daily work with inline close or reopen actions that act on the selected ticket, commit visibility, and concise hover descriptions for quick scanning. Automation tooling rejects invalid arguments and non-file paths so MCP-driven workflows surface mistakes immediately. Ticket creation and iteration starts always request a description, while file lists can be added later when needed. Ticket iteration and finish actions attach git-derived file lists and line totals scoped to the ticket files so progress and impact are visible from the ticket view. Code hygiene diagnostics ignore comment markers inside string literals so snippets and URLs stay clean of false comment warnings. Code hygiene diagnostics flag orphan definitions outside named sections so the file structure stays consistent. The command browser mirrors the repo command and subcommand hierarchy so discovery follows the same structure as the CLI. Problem list entries open in dedicated editor tabs so edits are immediately saveable. Contributor views merge ticket activity and file header credits into a per-person breakdown with line totals, grouped tickets, commits, bundles, and file navigation for quick context. The built-in Explorer adds a Sections panel that lists the current file structure (including JSON object keys), lets you jump to a section on click, supports F2 rename, and provides inline create-child, rename, delete, and drag-move actions.

A batteries-included Grasshopper plugin for semio ⚡

semio Grasshopper Demo

🦏 semio.3dm

A Grasshopper-based integration of Rhino and semio 🔀

🐝 semio.wasp

A Grasshopper-based integration of Wasp and semio 🔀

Wasp Demo

🦌 semio.monoceros

A Grasshopper-based integration of Monoceros and semio 🔀

Monoceros Demo

🐞 semio.ladybug

A Grasshopper-based integration of Ladybug and semio 🔀

📄 Specs

📦 Kit

A kit is a collection of types, designs, authors, qualities, attributes, and concepts 📦

A kit is either static (a special .zip file) or dynamic (bound to a runtime) 📦

A static kit contains a reserved .semio folder that contains a kit.db sqlite file 💾

The SQL-schema of kit.db is found in ./sqlite/schema.sql 📄

For Inter-Process-Communication (IPC) the JSON-schema in ./jsonschema/kit.json is used 📄

🏘️ Design

A design is an undirected graph of pieces (nodes) and connections (edges) with organizational layers, groups, stats, attributes, and concepts 📐

A design is proto (a protodesign) when it has no parent.

Children of a parent are _subdesigns.

A flat design has no connections and all pieces are fixed

The pieces are placed hierarchically (breadth-first) for every component 🌿

Additional connections which where not used in the placement can be used to validate the computed planes 🛂

🏠 Type

A type is a reusable component with different models, connectors, attributes, concepts, and authors 🧱

A type is proto (a prototype) when it has no parent.

Children of a parent are _subtypes.

A type can be virtual (intermediate type requiring other virtual types to form a physical type), scalable, and mirrorable with stock quantity, unit, and optional location 📍

🔗 Connection

A connection is a 3D-Link between two pieces with the translation parameters gap (offset in y-direction), shift (offset in x-direction) and rise (offset in z-direction), and the rotation parameters rotation (rotation around y-axis), turn (rotation around z-axis) and tilt (rotation around x-axis) 🪢

The translation is applied first, then the rotation 🥈

The two pieces are called connected and connecting but there is no difference between them 🔄

The direction of a connection goes from the lower hierarchy to the higher hierarchy of the pieces ➡️

A connection can have attributes and diagram positioning with x and y offsets 📍

⭕ Piece

A piece is an instance of either a type or a design with id, optional description, optional plane, center position, scale, optional mirror plane, hidden and locked states, color, and attributes 📐

A piece is either fixed (with a plane) or linked (with a connection) 📐

A group of connected pieces is called a component 🌿

The hierarchy of a piece is the length of the shortest path to the next fixed piece 👣

⚓ Connector

A connector is a conceptual connection point with an outwards direction, id, optional description, and t value for diagram ring positioning 🤝

A connector can be marked as mandatory in which case it is required to be connected to a piece 💯

A connector can have a connector port and a list of compatible ports for explicit compatibility control 👨‍👩‍👧‍👦

No port means the default port and no compatible ports means the connector is compatible with all other connectors 🔑

It is enough for one connector to be compatible with another connector to be compatible with each other ↔️

A connector can have props that define measurable characteristics and attributes for additional metadata 📏

💾 Model

A model is a tagged url to a resource with an optional description 📄

No tags means the default model 🔑

The similarity of models is determined by the jaccard index of their tags 🔄

🏷️ Attribute

A attribute is metadata with a unique name, an optional value, an optional unit and an optional definition (url or text) 🔤

The name iskebab-cased and with .-separated string similar to toml keys 🔑

No value is equivalent to the boolean true where the name is the category of the attribute 🔑

The unit is a unit identifier 🔢

  • mm for millimeter, cm for centimeter, dm for decimeter, m for meter, km for kilometer
  • for square meter, for cubic meter, m⁴ for quartic meter
  • ° for degree, rad for radian
  • N for newton, kN for kilonewton, MN for meganewton
  • °C for degree Celsius, °F for degree Fahrenheit
  • W for watt, kW for kilowatt, MW for megawatt, GW for gigawatt
  • Wh for watt-hour, kWh for kilowatt-hour, MWh for megawatt-hour, GWh for gigawatt-hour
  • J for joule, kJ for kilojoule, kcal for kilocalorie
  • kWh/m²a for kilowatt-hour per square meter per year
  • m/s for meter per second, m²/s for square meter per second, m³/s for cubic meter per second
  • Pa for pascal, kPa for kilopascal, MPa for megapascal

A list of attributes is semantically equivalent to nested dictionaries where the key is the name and the value is the value ↔️

🏷️ Tag

A tag is a kebab-cased name 🔤

◳ Plane

A plane is a location (origin) and orientation (x-axis, y-axis and derived z-axis) in 3D space ✈️

The coordinate system is left-handed where the thumb points up into the direction of the z-axis, the index-finger forwards into the direction of the y-axis and the middle-finger points to the right into the direction of the x-axis 👈

🔗 Url

A url is either relative (to the root of the .zip file) or remote (http, https, ftp, …) string🌐

A relative url is a /-normalized path to a file in the .zip file and is not prefixed with with ., ./, /, …

🔢 Quality

A quality is a measurement definition with a key, name, description, kind (General, Design, Type, Piece, Connection, Connector), unit information (SI and Imperial), range constraints (min/max with exclusion flags), default value, and optional formula 📏

A quality can be scalable (adjusts with piece scaling) and have multiple benchmarks for performance evaluation 🎯

The kind determines which entities the quality can be applied to using a bitwise enum system 🔢

📊 Benchmark

A benchmark is a performance standard within a quality with a name, optional icon, and range (min/max with exclusion flags) 🏆

Benchmarks provide reference points for evaluating quality measurements against industry or design standards 📈

🏷️ Concept

A concept is a name and order pair that provides semantic grouping for kits, types, or designs 🧠

Concepts enable hierarchical organization and categorization of design elements beyond simple naming 📂

👤 Author

An author has a name and email and can be associated with kits, types, or designs with a rank indicating contribution level 👨‍💻

Authors provide attribution and contact information for design ownership and collaboration 🤝

📋 Layer

A layer is an organizational grouping within a design with a name, optional description, and color for visual organization 🎨

Layers provide a way to group and manage pieces logically within complex designs 📑

👥 Group

A group is a collection of pieces within a design with optional name, description, color, and attributes 👥

Groups enable semantic clustering of pieces that belong together functionally or conceptually 🔗

⚙️ Prop

A prop is a key-value pair on a connector that references a quality with a specific value and optional unit 🔧

Props define measurable characteristics of connectors using the quality system for standardized measurement 📐

📈 Stat

A stat is a statistical measurement on a design that references a quality with range (min/max) and optional unit 📊

Stats provide computed or measured performance data for entire designs using the quality framework 📈

🦑 Repo

This git repo has everything that exists in the open semio ecosystem 🤯

⚖️ Principles

Let's start with the rules of thumbs that this codebase was built with 🫰

💾 If something can be written in a single file, then it probably should ✅

I know, the urge to tidy up or separate things is big 🗃️

But try to withstand it 🫥

Out of my experience, it makes development slower, not faster 🐌

A single file is easier for humans and computers to understand 💡

You will be surprised

  • by the awesome fill-in-the-middle suggestions of your copilot 🤖
  • by the hassle-free context selection for your ai agent 🖱️
  • by the smooth refactor experience by just going top-to-bottom ⬇️
  • by the beautiful diff for your next code review 🔍
  • by the clean git-history when you try to find a certain change 🔁
🙃 Write and read code upside down ✅

Whenever something is referenced it should be above in the source code ⬆️

This means that all the building blocks (functions, classes, components, …) are first defined and then used below ⬇️

If you have a cyclic depedency (really?!) then put the object with lower complexity first 🥇

This means that when you start with unknown code, it is probably best to start on the bottom and go upwards 🖱️

Why? LLMs, reflection, … , work best left-to-write 🤖

But Fill-in-the-Middle training is for free!?

Yeah, if you consider only FiM for code, then yes 🆗

But we want it all!

And is really so hard to start reading a from the bottom?

📑 If a class, function, component, … is only used once, then don't create it ❌

Probably, you learned to group code by classes, functions, components, … even if those definitions are only used once 🥇

It hides the actual complexity and makes it harder to navigate the code 🔍

📺 Inline everything that bearly fits onto the screen ✅

Smaller code, less tokens and easier diffs 🔍

Your ai bill will be lower and the completions will resolve faster 🚀

If you are not sure what the code does, you can ask ai 💬

🗣️ Don't use comments or if you must, only tag code at the end of the line ❌

Smaller code, less tokens and easier diffs 🔍

Your ai bill will be lower and the completions will resolve faster 🚀

If you are not sure what the code does, you can ask ai 💬

📑 Use regions to structure your code ✅

Because you are not using classes, functions, components, … and you are inlining everything, your code will become long 📃

To organize your code, you can use nested regions 📂

In general, our files follow this structure:

  1. Header
  2. TODOs
  3. Imports
  4. Constants
  5. CODE
📁 If a folder doesn't make your life dramatically easier, don't create it ❌

We all know this ./src/** folder that has made it into a lot of starters 🚀

Other than feeling cool about using hacky abbreviations, does it really help you to understand the bundle faster and work more efficient on it?

If your bundle contains hundreds of config file and other bundle folders at the root, maybe 🤔

But most likely not ❌

📦 Parts that belong together should be close in the source code ✅

The default code organization is to group kind of structurally similar parts together 📂

All models next to each other, all controllers next to each other, all errors next to each other, …

While this pattern supports structural refactoring, it makes plain extensions harder because you have to search through all the files 🔍

Most changes are plain extensions and not structural refactors 🔄

Further it has the advantage that every LLM-agent only has to predict one big block of code instead of plenty of small ones 🤖

That's why frameworks like React exist or vendoring such as with shadcn is more flexible than dependcenies such as with bootstrap

Cutting components vertically (a bit of logic with a bit of UI) instead of horizontally (all logic, all ui) requires more effort but enhances reusability 🔮

📄 If multiple people work longterm on the same part, then one file for each part should be created ✅

Trust me, it will make collaboration much easier 🔀

🔮 If you don't need an port because something is not likely to be extended soon, don't create it ❌

The main question is the port productive or not?

The pay-off of abstraction happens in the future 🛣️

Every extension profits from a clean port 🚀

Most things are not extended 🪨

If you change your architecture, just design proper ports for something concrete not something potential and reactor it ✍️

🤏 Repeating code is ok if it the repeated code is close in the source code ✅

We are past the time where we copy code for no reason 📃

Actually repeated code can improve the attribute of your copilots suggestion 🤯

The main question is how can your application grow?

If a change requires exponentially more duplication then you'll probably have to fix it 🛠️

If not, then you are probably good 👌

🏷️ Never use `type` for naming enums, ports, or types. Always use `kind` instead ✅

To avoid confusion with the native type concept in Semio, always use kind for naming enums, ports, or types that represent categories or classifications 🏷️

Examples: ArtifactTypeArtifactKind, WindowTypeWindowKind, etc. 🔄

🤨 Wait, no high-level advice and only plain numbers, files, folders or close line of codes?

In our understanding, policy-of-thumbs are most useful when they are concrete 🔨

Besides that we are sure you know about KISS (Keep-It-Simple-Stupid), DRY (Dont-Repeat-Yourself) vs WET (Write-Every-Thing-Twice)/RUG (Repeat-Until-Good), YAGNI (You-Aren't-Gonna-Need-It), SoC (Separation-of-Concerns), Avoid Premature Optimization, Law of Demeter, LCHC (Low-Coupling-High-Cohesion), SOLID (SR (Single Responsibility), OC (Open/Closed), LS (Liskov's Substitution), IS (Interface Segregation), DI (Dependency Inversion)), …

But as always, the devil is in the details 😈

Even if 95% of the codebase follows those principles, there are good reasons for the other 5% ⚖️

🚩 Don't worry, you'll figure out the possibilities and make the right choice for the specific problems ✅

🔀 Git

🦑 GitKraken

Note

It is free for open-source bundles like this one ❤️

We use GitKraken Desktop as our git client 🖱️

It is the only nice chronological graphical overview for all branches at the same time that we found 🔍

💬 Discord

Most git events are synchronized with our repo channel 💬

It is perfect to find the latest activities and the history 🔍

📢 Release

Every release contains a set of matching specs, components, examples and docs 📦

The release notes follow this format:

SYMBOL TITLE

COMPONENT
- SYMBOL SUMMARY [CONTRIBUTOR]
…

Title symbols:

  • 🏗️ Foundational work
  • 🛠️ Heavy work
  • 🪛 Minor work
  • 🐛 Major Bug fix

Description symbols:

  • 🌱 Started [not yet ready]
  • ➕ Added [ready]
  • ⬆️ Updated
  • 🔄️ Renamed
  • 🔁 Refactored
  • 🐛 Bug fix

Before every release the repo is archived 📦

🏷️ Tag

We have two different types of tags:

🌿 Branch

The main branch is compressed (squashed history) and acts as the canonical integration branch 🗜️

If a release receives updates after main already progressed, create a parallel release/rYY.MM-V branch for that release and keep it compressed as well 🧵

Every contributor has their own FIRSTNAME general-purpose development branch 🛠️

In GitKraken you will quickly find the latest development branch 👀

Other branches are created for components, specific features or bug fixes 🐛

Usually one person works on one feature at a time and hence the -NAME suffix 📛

🗃️ Commit

Commit messages follow this format:

MAIN-TASK-SYMBOL SUMMARY WORK-SYMBOL

The first symbol encodes the main task of the commit and the last symbol encodes the amount of work (🪛 < 🔨 < 🛠️ < 🏗️) 🧰

📦 Commit as much as you like ✅

Are you worried about committing all those binary application files (.zip, .gh, .blend, .glb, .3dm, …) or the intermediate versions between your ai edits?

Well, normally you should be 💾

But as we archive and squash all commits on every release nothing is lost or polluted 💯

⌛ Push around once an hour ✅

Pushing regularly keeps you extra safe from losing your work 🛟

There are a few services (like Discord) that are automatically updating to what happens in the repo 🔄️

To keep our inbox notifications low, we try to push not more than once an hour ⬆️

🧑‍💻 Development

Different ecosystems need different tools 🧰

For a complete setup you need:

If you do not have Python installed, I recommend to install it over the Microsoft Store 🏪

Afterwards you can install poetry with this command:

(Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python -

In the console you will see a warning that the poetry.exe is not installed in the requested location 📁 Actual Location Then copy the actual path ...\AppData\Local\Packages\PythonSoftwareFoundation...\Roaming\pypoetry\venv\Scripts and add it to your environmental path variable ➕

Then you can run npm run build from the root to build all packages, or run tsx ./build.ts in the Grasshopper directory and add your full path LOCAL_PATH\net\Semio.Grasshopper\Debug\net48 to your GrasshopperDeveloperSettings ⚙️

🎫 Tickets

Contributor workflows use tickets to track each task across iterations, recording prompts, file touch lists, and per-file line diffs so work is auditable and easy to continue.

🧰 Violations

Contributor workflows include an automated code-quality report that highlights inline and multi-line comments (including JSDoc blocks), missing license headers, malformed region blocks, and empty regions before changes are shared. It also enforces module boundaries and domain-neutral terminology for shared UI building blocks, while automated fixes remove empty regions to keep region structure meaningful. Each reported problem includes a short reason and solution so contributors can resolve violations quickly.

🔌 Port Numbers

Overview of all connectors used during development and in final packages:

Service Port Command / Package Notes
Sketchpad 3000 dev js js sketchpad Vite dev server for Sketchpad
Play 4000 dev play Vite dev server for Play
Docs 4321 dev docs Astro dev server (default)
Storybook 6006 dev js js storybook Storybook dev server (default)
Playwright 5173 npm test (js) Test server for Playwright E2E tests
Engine YYMM @semio/engine package Connector derived from release: rYY.MM-VYYMM (e.g., r25.07-12507)

📒 Tickets and reports

  • Automation scripts now live in TypeScript; run them with npx tsx <script>.ts and keep shared helpers in scripts/utils.ts.
  • Development tickets live under log/YEAR/MONTH/DAY/SLUG.md with YAML frontmatter tracking iterations (agent work sessions).
  • Create a ticket: npx tsx scripts/log.ts ticket create SLUG --prompt="User prompt...".
  • Start an iteration (requires files): npx tsx scripts/log.ts ticket iteration start SLUG --model=MODEL --prompt="User prompt..." --file=path.ts.
  • Finish an iteration (requires files, computes git line stats): npx tsx scripts/log.ts ticket iteration finish SLUG --file=path1.ts --file=path2.ts.
  • Finish the ticket (aggregates files and recomputes total line stats): npx tsx scripts/log.ts ticket finish SLUG --summary="...".
  • Reopen a finished ticket (removes total files/lines, sets status to open): npx tsx scripts/log.ts ticket reopen SLUG.
  • Backfill missing ticket prompts: npx tsx scripts/log.ts ticket migrate prompts.
  • Validation reports live in reports/ and are generated by husky pre-commit hooks in JSON format; all reports are gitignored.
  • The codebase report reports/code.json runs the code policy with tree-structured violation kinds: code:header:* (validates header region with filename, contributors, AGPL-3.0 license), code:section:* (validates region naming, content, and definition-scoped orphans outside sections, including comment and import/package blocks in Go), code:comment:* (flags inline, block, and JSDoc comments); license headers, region markers, TODOs, and [DEBUG] logs are exempt from comment enforcement.
  • Each code report problem includes a reason and a solution to document policy intent and remediation steps.
  • Documentation is centralized in the root README.md and AGENTS.md; non-root AGENTS.md files and non-package README.md files are flagged by reports/code.json and deleted by npm run fix.
  • Runtime Sketchpad components stay console-clean: keep only warnings/errors for real problems and gate temporary diagnostics behind [DEBUG] strings that get removed after use.

Preflight Checks

The repository uses a split fix/analyze pipeline where preflight runs both.

Running Preflight

Run all preflight checks across the entire monorepo:

npm run preflight

Run only auto-fixes/formatters:

npm run fix

Run only non-mutating checks (reports in reports/):

npm run analyze

What Preflight Does

preflight runs:

  • fix: hooks/code.ts --fix, hooks/prettier.ts, hooks/ruff.ts
  • analyze: hooks/i18n.ts, hooks/code.ts (emits reports/code.json), hooks/typescript.ts, hooks/eslint.ts

Prettier uses .prettierignore (via hooks/prettier.ts --ignore-path, includes **/prompts.md).

test runs preflight and then nx run-many -t test. build runs test and then nx run-many -t build. publish:test and publish run build first.

Skip Mechanism

All pipeline commands support skipping earlier steps:

  • Skip preflight when running tests: npm run test -- --skip=preflight
  • Skip test when running a build: npm run build -- --skip=test
  • Skip build when running publish:test/publish: npm run publish -- --skip=build

To scope Nx-powered steps (e.g. test, build, ESLint) to specific bundles, pass Nx args after --nx:

npm run test -- --nx --projects=@semio/js

Pre-commit Hooks (Husky)

The repository uses husky to automatically run preflight checks before each commit:

npm install  # Husky auto-installs via prepare script

The pre-commit hook automatically runs npm run preflight to ensure all code meets quality standards before committing.

VS Code Integration

All monorepo commands are available in VS Code through Tasks and Launch configurations.

Formatting uses .prettierrc.json and .prettierignore via .vscode/settings.json (prettier.configPath, prettier.ignorePath).

Running Tasks

Press Ctrl+Shift+P (or Cmd+Shift+P on macOS) → "Tasks: Run Task" and select from:

Root-level commands:

  • build - Build all packages
  • test - Run all tests
  • fix - Run auto-fixes/formatters
  • analyze - Run non-mutating checks
  • preflight - Run all preflight checks (default build task)
  • update - Update dependencies
  • publish:test - Publish to test servers
  • publish - Publish packages
  • dev - Start all dev servers
  • dev js js storybook - Start @semio/js Storybook
  • dev js js sketchpad - Start @semio/js Vite Sketchpad (connector 3000)

Workspace-specific commands:

  • build [workspace] - e.g., build js, build engine, build vscode
  • test [workspace] - e.g., test js, test engine, test vscode
  • preflight [workspace] - e.g., preflight js, preflight engine
  • dev [workspace] - e.g., dev js, dev engine, dev play, dev docs

Launch Configurations

Press F5 or use the Run and Debug panel to launch:

Development:

  • dev - Start all services with Python debugger attached
  • dev engine / dev js / dev play / dev docs / dev vscode - Individual services
  • dev js js storybook / dev js js sketchpad - @semio/js specialized dev entrypoints

Testing:

  • test - Run all tests
  • test js / test engine / test vscode - Individual test suites

Fix / Analyze:

  • fix - Run auto-fixes/formatters
  • analyze - Run non-mutating checks

Preflight:

  • preflight - Run all preflight checks
  • preflight js / preflight engine / preflight vscode - Individual checks

Building:

  • build assets / build icons / build engine / build js / build docs - Individual builds

Publishing:

  • update / publish:test / publish - Root-level publishing commands

Manual Hook Execution (Advanced)

If you need to run individual hooks for debugging:

# Formatters
npx tsx hooks/prettier.ts
npx tsx hooks/ruff.ts

# Linters
npx tsx hooks/i18n.ts
npx tsx hooks/code.ts
npx tsx hooks/typescript.ts  # Uses root tsconfig.json
npx tsx hooks/eslint.ts

Required post-change checks are npx tsx hooks/code.ts, npx tsx hooks/typescript.ts, and npx tsx hooks/eslint.ts (plus npx tsx hooks/i18n.ts when changing UI IDs/translations).

The TypeScript hook runs tsc --noEmit --project tsconfig.json. The root tsconfig.json is strict and uses moduleResolution: "bundler", explicitly includes .storybook/**/*.ts(x), and excludes temp/, js/temp/, reports/, and log/.

🪄 AI

Most of our codebase is heavily optimized for AI agents 🤖

We pick tools based on billing model (request-based vs token-based), required context size, and whether a workflow needs MCP (e.g. Playwright) 🧰

🛠️ Uses-Cases

Here some strategic advice for different uses-cases 🗺️

⚖️ Decision Making

Model will always tell you that your ideas, guesses, analysis, … are great 💯

This makes it really hard to use them for decision making because they tend to just reinforce your own bias 📢

Try to formulate everything as neutral, general and unbiased as possible 🕊️

🔁 Refactoring

Most refactors are too big to be done in one go and models are usually steered that if they think the problem is too big then they try to automate it with scripting 🤖

This is usually not possible and then they fail ❌

After all from a provider perspective those tasks are dangerous and hard to scale and we understand why they want the model to avoid doing it 🔥

The next problem is that when they take the wrong approach then, due to large context, they hardely remember how the original state was 🤔

For this reason, we usually create a new file which we name with the suffix*.old and this way in the prompt we can refer to the original state 📄

🐛 Bug Fixes

Try to describe only how to the bug appears and not what you think caused it 😶

Experience what can be causes for bugs is increadibly valuable skill as a developer but the problem is that models are really biased the way you ask questions 🏋️

Especially when your guess is wrong then the model might have found the mistake but because of your bias it tries to take a different approach to fix it 🔀

Secondly, if the model can't find the bug then it will often try to remove functionality, add try catch blocks, add logging and other things that fastly turn your codebase into a mess 💣

Therefore, it is often a good idea that after you found the bug, reset your branch and create a new ticket where you define exactly how to fix the bug 🪛

⌨️ Tools

🌐 Web-Chat

For research, prompt preparation or single file-related operations (sorting, formatting, explaining, …) we use the free , Gemini or Groq, … in the browser to not waste precious tokens 🆓

The free quota is very quickly reached but resets regularly and hence we just use it for questioning or prompt preparation 💬

Good for larger experiments due to more generous free quota 🧪

💻 Editor

✈️ Copilot

📚 Resources:

Copilot is our default for most tickets because request-based billing makes fast iteration cheap 💳

🖱️ Cursor

📚 Resources:

We have the Pro plan 💳

We use Cursor as our main editor for typing code mostly with Tab ➡️

For tasks that require updated large docs that are too large to paste into the prompt, we use the agent 📚

But in general, we don't use the chat because it is way too expensive 💰

🌊 Windsurf

Used for token-heavy test-driven-development workflows with MCP (especially Playwright) 🧪

⌨️ CLI

We have the Pro plan 💳

Used for small bugs and focused fixes with strong repo context 🧠

🧾 Codex

Used for simple tasks (small edits, small refactors, small doc updates) 🧩

☁️ Cloud

🦑 Jules

[!NOTE] Free plan includes 15 tasks per day, 3 concurrent tasks and powered by Gemini 2.5 Pro 🚀

Used on the phone when no IDE is available 📱

🔍 Agents

↕️ Reorderer

Used to ensure consistent order of source code, docs, …

🔁 Formatter

Used to ensure consistent formatting of source code, docs, …

🤖 Models

The default model for agent work is Claude Opus 4.5, with GPT-5.2 Codex as an alternative 🧠

Claude Opus 4.5

GPT-5.2 Codex

🔄 CI/CD

📺 Channels:

All automation, CI runs, and agent workflows are controlled through the canonical root commands dev, fix, analyze, preflight, test, build, update, publish:test, and publish. Only dev is allowed to stay live for watch mode, while the remaining commands must exit so CI and agents can finish reliably. publish:test and publish always run a full build first. The root package.json uses preflight.ts to orchestrate the command pipeline, and delegates bundle builds/tests/publishing to Nx (npx nx run-many -t <target>).

♻️ Ecosystems

📺 Channels:

You might have noticed that the individual components can be closely related such as sketchpad, Grasshopper and engine but they are in totally different folders 📂

The reason for this is that the repo is not disected according content but according technology stack ✂️

This is less intuitive but more tool-friendly and everything that is easier for our tools is less pain to develop 🧑‍💻

📚 Resources:

Workspaces

  • js/semio - Shared TypeScript/React codebase (Sketchpad UI, components, libs).
  • js/desktop - Electron desktop shell.
  • js/sketchpad - Standalone Sketchpad web app shell.
  • js/docs - Documentation site.
  • js/play - Playground.
  • js/vscode - VS Code extension.

Preflight

cd js/semio && npm run preflight
📺 Channels:

🟪 .NET

📚 Resources:
📺 Channels:

A .NET core for semio 🥜

Workspace

  • net/Semio.sln - .NET solution.
  • net/Semio.Grasshopper - Grasshopper plugin.

Warning

Rhino still runs on .NET 7.0 7️⃣ Be careful to not update packages to a higher version, that might break the compatibility 🚨

🐍 Python

📚 Resources:
📺 Channels:

Currently only engine but in the future it might grow and then the .venv will be centralized, …

Workspace

  • py/engine - Python engine (domain, serialization, APIs).

Preflight

cd py/engine && npm run preflight

📦 Components

A component is a piece of software which is packaged independently 🏝️

🧼 Code Hygiene Hooks

The code hygiene hook enforces comment, license, and region policies before changes are shared. It treats empty regions as invalid structure and removes them automatically in fix mode so region blocks stay meaningful and concise. All code must sit inside named regions; orphan definitions outside any section are reported as code:section:orphan-definition so you can relocate them as full definition blocks.

✅ Validation System

semio includes a domain-pure validation system built entirely in semio.ts with zero JSON dependencies. All validation logic works with Kit objects and produces KitDiff-based fixes.

11 Validation Constraints:

  1. GUID Uniqueness - All GUIDs must be unique globally
  2. Type Name Uniqueness - Sibling types must have unique names
  3. Design Name Uniqueness - Sibling designs must have unique names
  4. Piece Name Uniqueness - Pieces in a design must have unique names
  5. Quality Name Uniqueness - All qualities must have unique names
  6. Interface Name Uniqueness - All ports must have unique names
  7. File Name Uniqueness - All files must have unique names
  8. Folder Name Uniqueness - Sibling folders must have unique names
  9. Connector Name Uniqueness - Connectors in a type must have unique names
  10. Model Name Uniqueness - Models in a type must have unique names
  11. Layer Path Uniqueness - Layers in a design must have unique paths

Platform Integrations:

  • VS Code Extension - Kit validation with Quick Fixes, violation diagnostics with auto-refresh on save
  • Sketchpad UI - In-app validation panel (planned)
  • CLI - Command-line validation tool (planned)
  • Backend - API validation endpoint (planned)

Usage:

import { validateSemioKit, applyKitDiff } from "@semio/js";

const result = validateSemioKit(kit);
if (result.problems.length > 0) {
  const fix = result.problems[0].fixes[0];
  const fixedKit = applyKitDiff(kit, fix.diff);
}

See AGENTS.md for complete technical documentation.

🧾 Code Report

The repository emits a machine-readable report (reports/code.json) that enforces a comment-free codebase (including multi-line and JSDoc blocks, with explicit exemptions), flags temporary [DEBUG] logs, auto-adds missing SPDX license headers in npm run fix, validates properly nested named regions, checks that js/semio files do not import outside the workspace unless they are the shared elements.tsx, flags domain-specific terminology inside those shared elements, and includes reason/solution text for each problem to make remediation explicit. Comment detection skips comment markers inside string literals and template literal text so valid content does not raise false violations.

🎫 Ticket System

Development work is tracked as tickets composed of iterations. Ticket creation does not create an iteration; iterations are explicitly started and finished, require file lists (updated, created, removed), and iteration finish derives the per-file lists and line stats from git diffs between the last iteration commit (or ticket base) and the current commit. Ticket finish aggregates all iteration files and recomputes total line stats from git against the ticket base commit. Ticket entry points require prompt text for ticket creation and iteration start, while file arrays can be omitted at entry and still enforced by iteration rules. Line totals only include the files declared in the ticket iterations so unrelated diffs stay out of ticket reports. Temporary scripts, fixtures, and data stay inside the active ticket folder so work-in-progress artifacts remain scoped to the task.

?? MCP Tool Gateway

The MCP server validates tool argument types and required fields before invoking the CLI so errors are surfaced at the tool boundary instead of silently proceeding. File and folder arguments are checked for path correctness so directory paths cannot be passed where files are required.

👥 Contributors

Contributor activity is derived from ticket frontmatter and source file headers, so authorship and ownership stay aligned with the artifacts people actually touch. Each contributor aggregates tickets, commits, bundles, files, and line totals, and the list is ordered by ticket volume so the most active contributors surface first.

🧭 Command Tree

The command browser groups actions by command families and subcommands, using the same command breakdown as the CLI so users learn one structure across tools. Search matches either command labels or group names, and matching a group keeps its full subtree visible for quick discovery.

🧩 Sections Explorer

The VS Code extension adds a Sections view to the built-in Explorer that lists nested regions for the active file via the repo section list. Selecting a section navigates to its start, F2 triggers rename, drag-and-drop moves sections, and inline actions use repo commands to create child sections, rename sections, or delete them. The view refreshes on editor focus and text changes so the tree stays aligned with the current file structure. JSON files surface object keys as section entries so structured config files are navigable in the same tree.

Borders

UI borders are semantic kinds so the same component can be restyled without rewriting class lists:

  • border-element is the default UI element border kind and matches the hover color.
  • border-window is the window border kind and matches the normal border color.

GoldenLayout stack windows render the window frame as an inset 1px stroke (overlay frame) so all four edges stay visible even when containers clip their contents.

Background levels

  • The base canvas, windows, panels, and temporary surfaces use different background levels.
  • In a multi-window layout, exactly one window is active; its surface uses an active background tint and embedded table views inherit that surface background.

Use them with normal Tailwind border utilities like border, border-t, border-l, and divide-*.

📚 Resources:
📼 Videos:

The core which is shared in the semio JavaScript ecosystem 🥜

Sketchpad

Sketchpad transactions

  • js/semio/sketchpad/elements.tsx provides TransactionProvider and useTransaction() for UI-scoped transactions.
  • Sketchpad elements (Input, Textarea, Select, Slider, Stepper, Combobox, ...) use useTransaction() internally and do not accept a transaction prop.
  • Apps wrap their UI subtree with TransactionProvider using the appropriate transaction hook so all descendant elements participate in undo/redo consistently.

Sketchpad selection + hover visuals

  • js/semio/sketchpad/elements.tsx Geometry renders selection/hover colors even when a base color is provided (it is treated as the non-interactive default).
  • Hover and selection state for Home/Kit/Design/Type/Quality/Docs/Feedback is stored in the Sketchpad state machine; UI rows and diagram nodes dispatch hover events and visuals read from machine state.
  • js/semio/sketchpad/elements.tsx Table exposes row hover callbacks so apps can forward row enter/leave events into their state machine commands.
  • js/semio/sketchpad/Design.tsx diagram nodes use ring-* (not ring-inset) so hover/selection rings remain visible with AvatarFallback backgrounds.

Sketchpad windows

  • Window spacing uses the shared unit sizing system: a single unit gap between windows and a single unit margin between windows and the canvas edge.
  • js/semio/sketchpad/Sketchpad.tsx Canvas applies p-single (1 unit) and window containers (HorizontalWindows / VerticalWindows) apply gap-single (1 unit).
  • GoldenLayout window gaps use splitters sized to 1 unit and window borders are applied to the stack container via an inset 1px stroke; Window uses kind="layout" inside GoldenLayout to avoid nested borders.
  • Window chrome controls are rendered as Action UI elements and forwarded to the underlying layout system when needed.
  • Window surfaces paint the only filled background surface; surrounding UI and overlays remain transparent and rely on borders/blur.
  • Each app registers its supported window kinds and provides a default layout; per-app windowLayout is persisted as a JSON string.

Kit app artifact creation

  • js/semio/sketchpad/Kit.tsx create actions for ports, tags, concepts, and folders set the kind filter and selection to the newly created entity so the details panel opens immediately.
  • Default names are resolved via i18n labels: semio.sketchpad.app.port.defaultName, semio.sketchpad.app.tag.defaultName, semio.sketchpad.app.concept.defaultName.
  • js/semio/sketchpad/Kit.tsx details panel sections are registered dynamically; remove all possible section ids (including conditional variants) before adding the active one and mirror removals in the effect cleanup.
  • js/semio/sketchpad/Kit.tsx details panel section content that uses useKit() is wrapped in KitScopeProvider so read-only detail sections can resolve kit data consistently.
  • js/semio/sketchpad/Kit.tsx read-only artifact detail fields reuse the same id values as the corresponding app details (Type/Design) so i18n/tooltips stay centralized.

Sketchpad state

  • js/semio/sketchpad/Sketchpad.tsx exposes a single sketchpadMachine actor that owns all Sketchpad UI state (SketchpadState + app slices like Home/Kit/Design/Type/Quality/Tutorial).
  • Y.js is reserved for Kit data synchronization (per-kit KitStore documents).
  • Sketchpad UI state is persisted locally via localStorage key semio.sketchpad.state.<id> (no Y.js dependency for settings/navigation/panel sizes).
  • Global interaction mode is stored as SketchpadState.device and controlled via useDevice() / SET_DEVICE with i18n IDs semio.sketchpad.settings.device.*.
  • layout naming is reserved for window layout configs (GoldenLayout) and the Layout component in js/semio/sketchpad/elements.tsx.

KitStore keeps kit concepts in the yConcepts array as ConceptStore entries so snapshots expose full concept data (name, description, icon, attributes) and persistence rehydrates from that array instead of guid placeholders.

UI System

The UI uses a standardized unit-based sizing system for consistent spacing and sizing across all components. The system is derived from the --spacing CSS variable and uses Tailwind utility classes.

UI Levels

The UI consists of five hierarchical levels, each with its own z-index and background styling:

  1. Base - The foundation layer for the main canvas and background
  2. Window - Container level for windows within the canvas
  3. Panel - Floating panels and sidebars
  4. Overlay - Transparent layer (only affects z-index, not background)
  5. Temporary - Tooltips, dropdowns, modals, and transient UI

Each level (except overlay) has a background surface. Components use the LevelProvider context and useLevel() hook to access the current level, with helper functions for consistent styling:

The global Sketchpad shell is wrapped in LevelProvider level="base" so top-level chrome (Navbar/Footer) always resolves bg-base.

Panels are rendered under LevelProvider level="panel" so panel chrome and content consistently resolves bg-panel.

  • getLevelBgClass(level) - Returns background class (e.g., bg-base, bg-window, bg-panel, bg-temporary)
  • getLevelHoverClass(level) - Returns hover background class (e.g., hover:bg-hover-base)
  • getLevelZClass(level) - Returns z-index class (e.g., z-base, z-window, z-panel, z-overlay, z-temporary)
  • getLevelActiveHoverClass(level) - Returns active state hover class (e.g., data-[state=active]:bg-hover-base)

Size Constants

All size constants are defined in js/semio/globals.css and derived from --spacing:

  • Single: 1 unit (e.g. gap-1) - spacing between elements and between icon and element
  • Tiny: 3 units (e.g. h-tiny, w-tiny, text-tiny) - icon size in actions, action text size
  • Small: 5 units (e.g. h-small, w-small) - actions, avatars, Strip items
  • Medium: 7 units (e.g. h-medium, w-medium) - buttons, toggles, inputs, sliders, steppers, Footer, table rows, Strip
  • Large: 9 units (e.g. h-large, w-large) - Band, Navbar
  • Huge: 11 units (e.g. h-11) - height of navigation buttons at bottom of docs pages
  • Mega: 13 units (e.g. w-mega) - width of toggles with actions (toggles with dropdown or action buttons)
  • Giga: 15 units (e.g. w-giga) - reserved for future use

Guidelines

  • All spacing between elements uses Tailwind unit classes (e.g. gap-1, p-1, m-1)
  • Icons within actions use h-tiny w-tiny and action labels use text-tiny
  • Interactive elements (buttons, toggles, inputs) use h-medium
  • Toggles with actions (dropdown or action button) use h-medium w-mega
  • Bands and navbars use h-large
  • Strips, footers, and table rows use h-medium
  • Table body cells use px-single py-0 and center their content so h-medium row height stays fixed even when cells contain h-medium controls (toggles/inputs)
  • Table headers use h-large
  • Large navigation elements use h-11 (huge)
  • Navbar panel toggles list panels in the fixed order Details, Chat, Settings across all apps

The unit system automatically adapts based on the --spacing mode (compact vs touch).

Platform Compatibility

The code runs in different environments (different browsers, electron, mobile/desktop/tablet). Platform-specific functionality MUST be generalized and provided as props to Sketchpad. NEVER hardcode platform-specific behavior or APIs directly in components.

📚 Resources:
An electron-based desktop app primarly working for with local kits 💾

🤖 @semio/assistant

📚 Resources:

Currently not implemented in this repo (planned component) 🧩

📚 Resources:
📺 Channels:

A playground for sketchpad 🎮

VS Code extension providing real-time violation diagnostics for semio development.

Violation Diagnostics

Shows policy violations as diagnostics for all supported file types (TypeScript, JavaScript, JSON, Python, C#, Go):

  • Loads cached violations on file open for immediate feedback
  • Re-runs repo analyze on file save and updates diagnostics
  • Quick Fix actions to apply automated fixes via repo fix
  • Promotes preview editors opened from the Problems list into regular tabs for save-ready edits

Kit Validation

Real-time validation for kit JSON files with Quick Fix code actions that apply KitDiff-based fixes.

Sidebar

Tree views for tickets, policies, contributors, and commands with search and filter support.

Tickets

Ticket tree items expose inline close or reopen actions that apply to the clicked ticket, list commit entries derived from ticket and iteration commits, and keep hover tooltips limited to the ticket description.

📚 Resources:

The core which is shared in the semio .NET ecosystem 🥜

📚 Resources:
📺 Channels: - [Nono Martínez Alonso](https://www.youtube.com/c/NonoMart%C3%ADnezAlonso)

A full-blown Grasshopper Plugin that has (almost) everything 💯

🪢 Scripting

Analogous to our principles for text-based code, we follow a similar logic for script-based code 🔄

💻 Optimize your definitions for rectangular space ✅

Every inch of wasted screen space, means a loss of productivity because you need longer for navigation 🖱️

It is harder to understand something far away compared to something close 🔍

I know, the triangular layout where you place the next component always vertically in the middle of the inputs looks cleaner due to the better wire display 🧹

But you waste a lot of space for nothing 💸

📛 Don't name things unless it is the output of a group or cluster ❌

We know that there are only two hard things in Computer Science: Cache invalidation and naming things 🥈

Visual programming languages solve the naming problem by using wires to overcome the neeed of names ⬆️

That is a big gain in productivity because you can focus on the logic instead of the names 🚀

Wait, but how I am supposed to understand what is happening in the code if I don't use names?

Most things in Grasshopper are visual and the green Only draw preview of selected components button on the top left is your best friend 🔍

📦 If you don't absolutely need a cluster, don't create it ❌

Clusters are a good way to make code reusable and hide complexity 🥸

But hiding complexity means a slower development speed because you have to navigate through more files 🐌

Did you know that Grasshopper behaves different inside a cluster when outside?

E.g. when you feed an empty branch into a cluster the input inside it its magically pruned and when you leave it is there again which makes debugging much harder 🐛

I don't have to tell you about open definition tabs, updating nested clusters, recompute, performance, … right?

🤏 Minimize the amount of external parameters and take as much decisions as possible ✅

Designing means making decisions 🪨

Fewer parameters makes your design more parameteric and not less 🤯

The price for a synergizing system is the loss of flexibility 🤷‍♂️

If you don't know the parameters in the first place, you shouldn't create the Grasshopper script in the first place 🥈

Grasshopper is an amazing tool if you know the system that you want to create but is terrible for prototyping because of its lack of abstraction ⬇️

📚 Resources:

A hidden fat-client which exposes shared functionality to other desktop uis 🤝

It takes care of:

  • CRUDs (Create-Read-Update-Delete) for local kits 💾
  • Client-Server communication ↔️

It offers two APIs to other clients:

  • A simple REST OpenAPI 🥇
  • A complex GraphQL Relay API 🥈

If you go to http://127.0.0.1:2412/api/docs/ you find the Swagger UI:

GraphQL Query

Still a prototype ✏️

If you go to http://127.0.0.1:2412/graphql/ you find the GraphiQL UI:

GraphQL Query

🏷️ Badges

Each badge is created with shields.io with style flat-square and semio colors.

  1. Copy the *.shields file of an existing badge 📄
  2. Open and download the *.svg file ⬇️

📄 Fonts

  1. Search font on fontsource.org 🔍
  2. Hit Download and extract zip file 📂
  3. Use kebaberized font name as folder name and remove everything else (such as version numbers) ➖
  4. Merge all types in one folder (ttf, webfonts, …) - they won't collide due to different extensions 🗃️
  5. Remove all parts that repeat everywher (such as common name prefix, single weighted fonts, …) 💯

👁️ Icons

  1. Open favicongenerator.net 🔍
  2. Select Circle as Background Shape ⏺️
  3. Select Anta as Font Family 📃
  4. Enter the Code that you find in the dictionary
  5. Adjust the Font Size to the largest so that the space to the side is the same as the thickness of the stroke 🖊️
  6. Toggle Enable SVG on 🔳
  7. Hit Generate Favicon and download the zip file to assets/icons/temp/NAME.zip where NAME is the lowercase name and verb of the icon 📂
  8. Repeat the process for all icons 🔁
  9. Run build icons in the debugger of vscode 🔨

🧱 Kits

assets/index.ts is the shared entry point for @semio/assets. It re-exports the icon layer plus the Metabolism kit fixtures and helper constants. The kit fixtures are available as MetabolismKit, MetabolismKitDiff, MetabolismKitDiffed, MetabolismKitDiffInverted, InvalidKit, and InvalidKitValidation, while each kit entity list is exposed through MetabolismKitTypes, MetabolismKitDesigns, MetabolismKitInterfaces, MetabolismKitQualities, MetabolismKitFiles, MetabolismKitFolders, MetabolismKitAuthors, MetabolismKitTags, MetabolismKitConcepts, MetabolismKitAttributes, and the dedicated MetabolismKitNakaginCapsuleTowerDesigns.

Lookup tables MetabolismKitTypesByGuid, MetabolismKitTypesByName, MetabolismKitDesignsByGuid, MetabolismKitDesignsByName, MetabolismKitInterfacesByGuid, and MetabolismKitInterfacesByName provide direct access to every type, design, and port without filtering.

🏘️ Examples

💯 Brand

✍️ Concept

✅ Do

  • Visual is better than text 👀
  • Compact ➡️ More information ➡️ Faster to understand 🚀

❌ Dont

  • Rounded corners ⬜
  • Shadows 🌤️
  • Multiple unicode directly after each other 🥇🥈🥉

🌈 Colors

Palette

Name Hex RGB HSL HSV (or HSB) CMYK Color
Primary #FF344F 255, 52, 79 352, 100, 60.2 352, 79.6, 100 0, 80, 69, 0 Folly
Secondary #00A69D 0, 166, 157 176.7, 100, 32.5 176.7, 100, 65.1 100, 0, 5, 35 Persian green
Tertiary #FA9500 250, 149, 0 34.8, 100, 49 35.76, 1, 0.49 0, 40, 100, 2 Princeton orange
Dark (= 0) #001117
Grey 100 (= 0.1 = 1/10) #06171C
Dark 8-9 (= 0.1̅ = 1/9) #07181D
Dark-Dark-Dark-Grey (= 0.125 = 1/8) #091A1F
Dark 6-7 (= 0.142857 = 1/7) #0C1C21
Dark-Dark-Grey (= 0.166667 = 1/6) #112025
Grey 200 (= 0.2 = 1/5) #18272A
Dark 7-9 (= 0.2̅ = 2/9) #1D2B2F
Dark Grey (= 0.25 = 1/4) #243235
Dark 5-7 (= 0.285714 = 2/7) #2E3C3D
Grey 300 (= 0.3 = 3/10) #334041
Dark-Dark-Grey (= 0.3̅ = 1/3) #3E494A
Dark-Grey-Grey-Grey (= 0.375 = 3/8) #4C5756
Grey 400 (= 0.4 = 2/5) #555F5D
Dark 4-7 (= 0.428571 = 3/7) #606966
Dark 5-9 (= 0.4̅ = 4/9) #666E6B
Grey (= 0.5 = 1/2) #7B827D
Light 5-9 (= 0.5̅ = 5/9) #91968F
Light 4-7 (= 0.571429 = 4/7) #979B94
Grey 600 (= 0.6 = 3/5) #A2A59D
Light-Grey-Grey-Grey (= 0.625 = 5/8) #ABADA4
Light-Grey-Grey (= 0.6̅ = 2/3) #B9BBB0
Grey 700 (= 0.7 = 7/10) #C4C4B9
Light 5-7 (= 0.714286 = 5/7) #C9C8BD
Light Grey (= 0.75 = 3/4) #D3D2C5
Light 7-9 (= 0.7̅ = 7/9) #DAD9CB
Grey 800 (= 0.8 = 4/5) #DFDDD0
Light-Light-Grey (= 0.8̅ = 5/6) #E6E4D5
Light 6-7 (= 0.857143 = 6/7) #EBE8D9
Light-Light-Light-Grey (= 0.875 = 7/8) #EEEADB
Light 8-9 (= 0.8̅ = 8/9) #F0ECDD
Grey 900 (= 0.9 = 9/10) #F1EDDE
Light (= 1) #F7F3E3

🥇 Primary

Use the primary color for the most important elements of your design 🏆

We use it e.g. for:

  • Highlighting interactive elements 🖱️
  • Background for important elements 🟥

🥈 Secondary

🥉 Tertiary

⚫ Dark

⚪ Light

🩶 Gray

Are you curious how a 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 and 11 colored gradient can come together for an invertible theme in a semantically meaningfull way? Well, here is how you achieve it with 33 colors 🤯

Grayscale

📄 Typography

Note

Try to place notes either in the beginning or the end of a section ↕️ A starting note should contain something important but not crucial to give the brain the right context 🧠 The starting sentence of a note needs no symbol because every note type starts with a symbol 🥇

  • Be consistent with your language ♻️
  • When things are analogical use the same sentence structure for it 🔄
  • One symbol after every sentance 💯
  • One symbol at a time 🥇
  • A symbol is preferably an emoji or otherwise unicode ⚖️
  • 📝 One symbol to summarize a title
  • 💡 One symbol to summarize a title description and one to think about in the end 🤔
  • . are forbidden ⛔
  • All components in semio (sketchpad,studio, …) start with a small letter 🔡
  • Did you know that is just one character?

Tip

In the end of a section you can give the curious reader a summarizing question to think about the consequences and a link to more resources 🤔

👀 Visual elements

  • Sharp corners 📐
  • Borders □
  • Basic geometric shapes ⚪

⚖️ License

The files in this repository are licensed under the GNU Affero General Public License unless otherwise described. Most libraries, modules, extensions, objects or code herein are explicitly licensed. This is indicated in the root of the containing folder under a different license file, or in the configuration files of a bundle or in the respective file's header.

As a reference, different type of components have usually different licenses:

If you have any questions, please don't hesitate to get in touch with us over email 📧

🔒 Security

If you have any security vulnerabilities or concerns, please contact us over email and don't open an issue, discussion or write into our public discord server 🥷

Ueli Saluz
Ueli Saluz
🟨 🟪 🐍 🦗
✏️ ⚙️ 🤖 🎛️
📚 🛍️ 💯
🦏 🐝 🦌 🐞
🫀 👋 🚀
KinanSarak
KinanSarak

📚 👋 🦗
EinMysterium
Christian Hödtke

🦗
AdrianoCelentano
AdrianoCelentano

🟨
drymuzzle
drymuzzle

🦗 🐞
kaatzjo
kaatzjo

⚙️
pizzadizza
pizzadizza

🤖

📊 Stats

We use Goatcounter for gaining insights about our docs 📈

views

Pixel