| 1 | # Product and design conventions |
| 2 | |
| 3 | These are the project's strong defaults for product and design decisions. |
| 4 | Contributions are expected to follow them; where one doesn't fit, say why in |
| 5 | the pull request. |
| 6 | |
| 7 | ## Sign-in: passkeys first |
| 8 | |
| 9 | - People sign in with passkeys (WebAuthn). Don't add passwords. |
| 10 | - New people create their passkey from their invite link. |
| 11 | - Recovery goes through a one-time sign-in link from an admin, or email |
| 12 | verification through Cloudflare Access at `/auth/access`. Access guards only |
| 13 | that path. |
| 14 | - Machines (git, the CLI, MCP clients, runners) use Diffinery tokens, never |
| 15 | browser sessions. |
| 16 | |
| 17 | ## UI: Kumo |
| 18 | |
| 19 | - The look follows [Kumo](https://kumo-ui.com), Cloudflare's design system: |
| 20 | its color tokens (light and dark), radii, type and focus styles. The tokens |
| 21 | live as CSS variables in `apps/diffinery/src/web/assets.ts`. |
| 22 | - Never use a native `<select>`, checkbox or radio. Use the Kumo components |
| 23 | through `KSelect`, `KCheckbox` and `KRadio` from |
| 24 | `apps/diffinery/src/web/kumo.tsx`. The server renders a placeholder and the |
| 25 | hidden inputs the form posts; a small client bundle (`apps/diffinery/islands/`) |
| 26 | mounts the real Kumo component over it. Kumo's stylesheet is confined to those |
| 27 | islands so it can't restyle the rest of the page. |
| 28 | - For anything else interactive (menus, dialogs, pickers), reach for the Kumo |
| 29 | component the same way rather than hand-rolling one. |