---
type: design-system
title: "CAMDOM — Design System"
description: "Visual identity of the CAMDOM digital consent protection app. Muted teal palette, Skia-rendered ball metaphor, generator-based animations, haptic-first interaction."
tags: [design-system, camdom, react-native, skia, dark-mode, mobile, ble]
timestamp: "2026-07-20"
---

# CAMDOM — Design System

## Overview

The visual language of the world's first digital condom. A dark, minimal, haptic-first interface built for BILLY BOY / Innocean Berlin. Muted teal palette, Skia-rendered ball metaphor, generator-based worklet animations.

Full technical documentation: [[camdom-design-system]]

---

## Palette

| Token | Hex | Role |
|---|---|---|
| Primary | `#132037` | Navy — text, borders, separators |
| Warning | `#b2140c` | Red — alarm, error, danger |
| Background | `#9DB0B9` | Teal — default canvas, safe state |
| Alarm Background | `#06101A` | Near-black — consent violation |

### Derived Colors

| Value | Usage |
|---|---|
| `#BCD4DF` | Ball border (connected) |
| `#889AA2` | Ball border (disconnected) |
| `#D9D9D9` | Alarm mode text/icons |

---

## Typography

- **Primary**: BasicSans (14 OTF variants, Thin through Black, with italics)
- **Secondary**: Space Mono Regular (monospace, version display)
- **All text is UPPERCASE**
- **Size range**: 10px (buttons) to 16px (menu titles)
- **Ball text**: Skia Paragraph, SemiBold, 11px default / 14px alarm

---

## Layer System

| Layer | Z-Index | Component |
|---|---|---|
| Background | 0 | Canvas, orbs |
| Menu Bg | 1000 | Menu backdrop |
| Menu | 10001 | Full-screen overlay |
| Lateral Menu | 10002 | Right-edge strip (12px) |

---

## Core Visual Element: The Ball

Skia-rendered circle with ImageShader textures (`red-dot.png` / `black-dot.png`), 22px blur, dual-layer pulse animation. Represents the protection state through color, size, and animation behavior.

- Disconnected: static black, small
- Scanning: black with scanning rings
- Synced: breathing 300-360px
- Alarm: red, aggressive 310-360px pulse on dark background

---

## Animation Engine

Custom generator-based worklet system on Reanimated. Not declarative — imperative sequencing via JS generators running as worklets. Primitives: `timing`, `wait`, `waitUntil`, `parallel`, `stagger`.

Typical durations: 30-240ms for UI transitions, 1160-2500ms for ambient pulsing.

---

## Sound Design

5 sound types via `expo-av`, pre-loaded, server-broadcast synchronized:
1. `open` — scanning started
2. `pair` — protection active
3. `unpair` — protection ended
4. `alarm` — consent violated (loops, full volume, cannot be silenced by one party)
5. `ping` — proximity sensor (reserved)

Plays in silent mode. Volume forced to maximum. Alarm loops until all parties consent to stop.

---

## Interaction Model

- **Gesture-first**: swipe to connect, hold to disconnect
- **Haptic language**: Soft (gesture), Heavy (buttons), Success/Error (resolution/danger)
- **Consensus mechanism**: alarm stops only when ALL parties hold stop simultaneously
- **No navigation bars**: 12px lateral strip replaces traditional nav

---

## What to absorb

- The muted teal (#9DB0B9) as identity — not the typical dark mode
- The ball metaphor as the entire interaction model
- Consensus as a design principle (not just a feature)
- Sound as a first-class UI element, not decoration
- The generator animation pattern as an alternative to declarative animation chains

## What NOT to absorb

- Generic mobile UI patterns (tab bars, navigation stacks)
- Decorative animations that don't communicate state
- Sound as optional/secondary — in CAMDOM, sound IS the alarm
