┌─────────────────────┐
│ │
│ C O D A │
│ │
│ 22 keys. │
│ The distilled │
│ form. │
└─────────────────────┘
CODA
22 keys. The distilled form of Cadenza.
v0.1 · Concept
Colemak-DH
9 layers
39 Tap Dances
QMK keymap.c
SFB ~0.90%
No pinky · No inner column
Coda (n.): the concluding passage — a concentrated, essential statement that brings everything together.
Coda is a 22-key split keyboard layout and the minimal sibling of Cadenza. Designed for German + English prose, shell/code work, and tiling window manager use — without pinkies, without an inner column, and with an estimated SFB rate lower than Colemak-DH.
Physical Layout
Left Right
┌───┬───┬───┐ ┌───┬───┬───┐
│ L │ G │ D │ │ H │ F │ C │ ← top row
├───┼───┼───┤ ├───┼───┼───┤
│ R │ S │ T │ │ N │ E │ I │ ← home row
├───┼───┼───┤ ├───┼───┼───┤
│ B │ W │ M │ │ Z │ K │ U │ ← bottom row
└───┴───┴───┘ └───┴───┴───┘
┌───┬───┐ ┌───┬───┐
│ A │Spc│ │ O │Ent│ ← thumbs
└───┴───┘ └───┴───┘
Fingers per half (outer→inner): Ring · Middle · Index (no Pinky, no Inner column)
A, Spc, O, Ent = letters (tap) + layer access (hold)
Design Principles
- No pinky column — by design, not constraint. The pinky is the weakest finger and primary RSI source. Removing it forces better decisions everywhere else.
- No inner column. Lateral index finger movement destabilises hand position. Enforced physically on Coda.
- Strongest finger earns highest priority. Index > Middle > Ring within every row and every layer.
- A and O on thumbs. These two (7.4% and 5.0%) were on pinkies in Colemak-DH. Thumbs give the highest-frequency non-home letters to the strongest fingers.
- Colemak-DH inner home row preserved. T·S·R / N·E·I — identical to Cadenza. Zero muscle-memory penalty.
- Frequency × Ergonomic quality = access key rank.
A thumb earns Navigation (most-used non-alpha function) because it is the best thumb position.
- Bilateral access for layer triggers and Meta. Code (G/F), WM (M/U), Fn (D/C), and Meta (L/H) are each reachable from either hand. Holding the right-hand key frees the left for numpad-style input.
- NEIO = ← ↓ ↑ → everywhere. Arrows, WM focus switching, window movement — same spatial convention throughout.
- Combos replace dedicated keys. Space+Enter=Backspace. N+E=↑. Z+K=PgUp. Physical positions freed for valuable use.
- QMK keymap.c — not Vial. Layer-specific combos, unlimited macros, full C programmability.
Letter Placement
Letters placed by combined German + English frequency, assigned to fingers in strength order, avoiding same-column bigrams.
| Rank | Letter | Freq | Position | Rationale |
| 1 | E | 15.0% | R home middle | Highest frequency → best position. ER cross-hand ✓ |
| 2 | N | 8.0% | R home index | Strongest right finger. EN inward roll ✓ |
| 3 | T | 7.5% | L home index | Strongest left finger. TH cross-hand ✓ |
| 4 | A | 7.4% | L thumb | Thumb solves pinky-removal gap. AN cross ✓ |
| 5 | I | 7.3% | R home ring | Colemak home ✓. IN inward roll ✓. IE inward roll ✓ |
| 6 | S | 6.8% | L home middle | ST inward roll ✓. Colemak home ✓ |
| 7 | R | 6.5% | L home ring | ER cross-hand ✓. Colemak home ✓ |
| 8 | H | 5.5% | R top index | TH cross-hand ✓. CH = C→H right inward roll ✓✓ |
| 9 | O | 5.0% | R thumb | Thumb solves pinky-removal gap |
| 10 | D | 4.7% | L top index | DE cross-hand ✓ (German der/die/das) |
| 11 | L | 3.7% | L top ring | EL cross-hand ✓. Hold=Meta |
| 12 | U | 3.6% | R bot ring | Avoids EU same-finger (E=R-mid) and UN same-finger (N=R-idx) |
| 13 | C | 2.8% | R top ring | CH inward roll ✓✓ (German most common digraph 2.4%) |
| 14 | G | 2.5% | L top middle | IG cross-hand ✓ (German -ig: richtig, wenig, möglich) |
| 15–20 | M W F B Z K | 1.0–2.5% | Bottom rows | Less frequent — acceptable positions. Z on base for German "zu" |
| Overflow: P(0.8%) · V(0.7%) · Y(0.4%) · J(0.2%) · X(0.1%) · Q(0.05%) — combined ~3% — via Hold A+Ent |
Ergonomic Metrics
| Metric | Value | Notes |
| SFB rate | ~0.90% | Estimated from column-pair bigram analysis |
| Home row usage (fingers) | 51.1% | T+S+R+N+E+I frequencies |
| Home row usage (+ thumbs A/O) | 63.5% | Effective home-accessible character percentage |
| Pinky load | 0% | No pinky column — physically zero |
| Lateral index stretch | Zero | No inner column — physically impossible |
| Hand balance | ~46% L / 54% R | Right-heavy due to E (15%) on right middle |
| Heaviest single finger | R-Middle 17.9% | E(15%)+F(1.9%)+K(1.0%) — all on home row (best position) |
Comparison
| Metric | QWERTZ | Dvorak | Colemak-DH | Coda |
| SFB rate | 6.31% | 2.62% | 1.28% | ~0.90% |
| Home row usage | 34% | 71% | 68% | 64% |
| Pinky load | ~14% | ~7% | ~6% | 0% |
| Lateral stretch | Very high | Moderate | Low | Zero |
| German CH bigram | Same-finger | Cross-hand | Cross-hand | Inward roll |
| German IG bigram | Same-hand | Varies | Varies | Cross-hand |
| German EI bigram | Same-hand | Same-hand | Same-hand | Adjacent outward roll |
| Hardware availability | Any | Any | Any/remap | Custom 22-key PCB |
| Learning curve | None | Very high | High | Extreme |
QWERTZ, Dvorak, Colemak-DH SFB values: documented (carpalx / Patrick Steele corpus). Coda: estimated from column-pair analysis.
vs. Cadenza
| Dimension | Cadenza v1.0.0 | Coda v0.1 |
| Keys | 36 | 22 |
| Pinky load | ~5% | 0% |
| Base-layer letters | 26 | 20 (+6 overflow) |
| Layers | 13 | 9 |
| Tap dances | 43 | 34 |
| Combos | 0 | 9 (incl. layer-specific) |
| Firmware | Vial / QMK | QMK keymap.c only |
| Hardware | Corne Choc — available | Custom PCB — concept |
| Status | Daily driver · v1.0.0 stable | Concept · v0.1 |
Layer Architecture
| Layer | Name | Access | Purpose |
| L0 | Base | Always active | 20 letters + HRM |
| L1-Over | Overflow / International | Hold Spc | P V Y J X Q · ä ö ü · ß € |
| L2-Sym | Symbols | Hold Ent | Symbols · Punctuation · Brackets |
| L3-Num | Numbers | Hold O | Numpad 1–9 · Operators |
| L4-Nav | Navigation | Hold A | Arrows · Word nav · Modifiers |
| L5-Mouse | Mouse | Tap-then-Hold A | Pointer · Scroll · Buttons |
| L6-Fn | Function + Media | Hold D or C | F1–F12 · Media |
| L7-Code | Code / CLI | Hold G or F | Shell operators · Path nav · Code macros |
| L8-WM | Tiling WM | Hold M or U | Workspaces 1–10 · Focus · Window movement |
Layer Reference
Colemak-DH inner home row preserved unchanged (R·S·T / N·E·I). A and Ent on thumbs solve the pinky-removal gap. Layer access distributed bilaterally: D/C (top corners — left index, right ring) carry Fn, G/F (top middle column) carry Code, M/U (bottom corners — left index, right ring) carry WM. L (left ring top) and H (right index top) carry Meta as a tap/hold modifier — same HRM pattern as the home row.
P/V/Y on left home (strongest fingers, most frequent overflow letters). J/X/Q on left top. Umlauts placed at their base-letter positions for muscle-memory consistency: ä on A, ö on O, ü on U. ß on Z (AltGr+S) · € on K (AltGr+5).
Frequency+Strength: = (rank 1) on T (strongest left finger). . , : on right home — most common prose punctuation. Bracket pairs as Tap Dance: tap=open, hold=close. ( ) on H · [ ] on F · < > on C · { } on U. *|@ on Spc (TD_STAR_AT). L falls through to base (Meta hold).
Numpad layout on left hand — ring=1/4/7 · middle=2/5/8 · index=3/6/9. Same spatial positions as L8-WM workspace keys. 0 on A-thumb. € via AltGr+5 (direct keycode, same as Cadenza).
All 4 arrows on right side: ← ↓ → on home row (N·E·I), ↑ on F (above ↓ for inverted-T cluster). Home/PgDn/End on right bottom. PgUp via Z+K combo. Word-skip on C (Ctrl+←) and H. Del on Enter thumb. Modifiers on left for Shift+arrows (selection).
Ctrl+←H·word
↑F
Ctrl+←C·word
HomeZ·idx
PgDnK·mid
EndU·rng
Tap A, then hold — different tap-dance state from plain Hold-A (Nav). Mouse movement on right (N=← E=↓ I=→ H=↑). Scroll on right middle column. Modifiers on left for Shift-click, Ctrl-click. Buttons on right thumbs.
F1–F9 on left in numpad positions (same spatial shape as L3-Num — muscle memory transfers). F10–F12 on right home. Media controls on right. Hold C (right) frees the left for the F-key numpad. ⚠ When holding D (left, index top), F9 is occupied by the trigger — use the right-hand C-hold for full F-key numpad access.
Bilateral middle-finger top access — hold the right G/F to free the left for code typing, or vice versa. Left home row: T= | · S=&& · R=||. Right home: N=TD(/ ~/hold ../dbl) · E=TD($()/${}) · I=TD(!= ==) · H=TD(=> ->). $? and 2>&1 on right bottom. Mirrors Cadenza L9.
/|~/N·TD
$()|${}E·TD
!=|==I·TD
Numpad positions: ring=WS1/4/7 · mid=WS2/5/8 · idx=WS3/6/9 · A-thumb=WS10. Tap=⊞+N (go) · Hold=⊞⇧+N (move window). Hold U (right) frees the left hand for the workspace numpad. ⚠ When holding M (left, index bot), WS3 is occupied by the trigger — use the right-hand U-hold for full numpad access.
⊞+→H·focus
FullF·⊞F
FloatC·⊞Spc
⊞+←N·focus
⊞+↓E·focus
⊞+↑I·focus
⊞⇧+←Z·win
⊞⇧+↓K·win
★ heldU
Tap Dance Reference
39 tap dances. QMK keymap.c — no slot limit. Tipping terms: index/middle = 200 ms · ring = 250 ms.
| TD | Key | Tap | Hold | Tap-then-Hold | ms |
TD_A | A (L thumb · below B) | a | MO(Nav) | MO(Mouse) | 200 |
TD_SPC | Space (L thumb · in gap) | Space | MO(Overflow) | — | 200 |
TD_O | O (R thumb · in gap) | o | MO(Num) | — | 200 |
TD_ENT | Enter (R thumb · below Z) | Enter | MO(Sym) | — | 200 |
| TD | Key | Tap | Hold | ms |
TD_D | D (L idx top) | d | MO(Fn) | 200 |
TD_C | C (R rng top) | c | MO(Fn) | 250 |
TD_G | G (L mid top) | g | MO(Code) | 200 |
TD_F | F (R mid top) | f | MO(Code) | 200 |
TD_M | M (L idx bot) | m | MO(WM) | 200 |
TD_U | U (R rng bot) | u | MO(WM) | 250 |
| TD | Key | Tap | Hold | ms |
TD_L | L (L rng top) | l | KC_LGUI · Meta | 250 |
TD_H | H (R idx top) | h | KC_LGUI · Meta | 200 |
| TD | Key | Tap | Hold | ms |
TD_T | T | t | Shift | 200 |
TD_S | S | s | Ctrl | 200 |
TD_R | R | r | Alt | 250 |
TD_N | N | n | Shift | 200 |
TD_E | E | e | Ctrl | 200 |
TD_I | I | i | AltGr | 250 |
| TD | Tap | Hold | Double | Usage |
TD_PAREN | ( | ) | — | Sym layer H |
TD_SQBR | [ | ] | — | Sym layer F |
TD_CURL | { | } | — | Sym layer U |
TD_ANGLE | < | > | — | Sym layer C |
TD_STAR_AT | * | @ | — | Sym layer Spc |
TD_QUOTE | " dead key | " literal (M9) | — | German umlauts via dead key + vowel |
TD_BTICK | ` dead key | ` literal (M10) | ``` (M11) | Sym layer K |
| TD | Tap | Hold | Double | Key / Layer |
TD_SLASH | / | ~/ (M1) | ../ (M2) | Code N — path navigation |
TD_EXP | $() + ← (M3) | ${} + ← (M4) | — | Code E — shell expansion, cursor inside |
TD_CMP | != (M5) | == (M6) | — | Code I — comparison operators |
TD_ARR | => (M7) | -> (M8) | — | Code H — arrow operators |
| TD | Tap | Hold | Key position |
TD_WS1 | ⊞+1 (go to WS1) | ⊞⇧+1 (move window to WS1) | B · L-bot-ring |
TD_WS2 | ⊞+2 | ⊞⇧+2 | W · L-bot-mid |
TD_WS3 | ⊞+3 | ⊞⇧+3 | M · L-bot-idx |
TD_WS4 | ⊞+4 | ⊞⇧+4 | R · L-hom-ring |
TD_WS5 | ⊞+5 | ⊞⇧+5 | S · L-hom-mid |
TD_WS6 | ⊞+6 | ⊞⇧+6 | T · L-hom-idx |
TD_WS7 | ⊞+7 | ⊞⇧+7 | L · L-top-ring |
TD_WS8 | ⊞+8 | ⊞⇧+8 | G · L-top-mid |
TD_WS9 | ⊞+9 | ⊞⇧+9 | D · L-top-idx |
TD_WS10 | ⊞+0 | ⊞⇧+0 | A · L-thumb |
Numpad positions: ring=WS1/4/7 · middle=WS2/5/8 · index=WS3/6/9 (same spatial memory as L3-Num)
Macro Reference
16 macros. In QMK keymap.c these are C functions with no slot limit.
| ID | Output | Function | Triggered by |
| M1 | ~/ | Home directory | TD_SLASH hold |
| M2 | ../ | Parent directory | TD_SLASH double |
| M3 | $() + ← | Shell expansion, cursor inside | TD_EXP tap |
| M4 | ${} + ← | Variable expansion, cursor inside | TD_EXP hold |
| M5 | != | Not equal | TD_CMP tap |
| M6 | == | Equal | TD_CMP hold |
| M7 | => | Fat arrow (Python, JS, Rust) | TD_ARR tap |
| M8 | -> | Thin arrow / pointer | TD_ARR hold |
| M9 | " + Space | Literal quote (US Intl dead-key bypass) | TD_QUOTE hold |
| M10 | ` + Space | Literal backtick (US Intl dead-key bypass) | TD_BTICK hold |
| M11 | ``` | Markdown code fence | TD_BTICK double |
| M12 | 2>&1 | Stderr redirect with spaces | Code K |
| M13 | | | Pipe with surrounding spaces | Code T |
| M14 | $? | Last exit code | Code Z |
| M15 | && | And-chain | Code S |
| M16 | || | Or-chain | Code R |
Combo Reference
9 combos — 7 global (any layer), 2 Nav-layer-specific.
Global combos
| Keys | Type | Output | Notes |
Space + Enter | tap | Backspace ★ | Cross-hand, unambiguous, most critical |
A + O | tap | Escape | Cross-hand |
A + Enter | tap | Tab | Cross-hand diagonal |
Space + O | tap | Delete | Cross-hand diagonal |
Nav-layer combos COMBO_ONLY_FROM_LAYER
| Keys | Output | Physical motion |
N + E | ↑ up arrow | Right index + middle simultaneously — adjacent, comfortable |
Z + K | Page Up | Right index + middle, bottom row |
Nav combos use COMBO_ONLY_FROM_LAYER in QMK — active only when Nav layer is on. This feature requires QMK keymap.c and is unavailable in Vial.
Hardware & Firmware
Hardware
| Board | Keys | Gap from Coda target |
| Ferris Sweep / Bling | 34 | Has pinkies + inner column |
| Absolem | 46 | Too many keys |
| Custom PCB | 22 | Target — to be designed |
Firmware
#define TAP_DANCE_ENTRIES 34
#define COMBO_COUNT 9
#define TAPPING_TERM 200 // overridden per-key for ring (250ms)
#define PERMISSIVE_HOLD // helps HRM in fast typing
#define HOLD_ON_OTHER_KEY_PRESS // for layer-access thumbs
// OS layout: US International
// ß = RALT(KC_S) · € = RALT(KC_5) · dead " for ä/ö/ü
Known Limitations
| Limitation | Severity | Workaround |
| Custom hardware doesn't exist | Critical | Use Ferris Sweep (34 keys) as approximation |
| Backspace is a combo | High | Muscle memory adapts in 1–2 weeks |
| P, V on overflow layer | Medium | ~1.5% of characters — acceptable |
| Extreme learning curve | Expected | New hardware + new paradigm |
Roadmap
| Version | Focus | Status |
| v0.1 | Complete design — all layers, TDs, macros, combos, comparison | ✓ Done |
| v0.2 | Custom 22-key PCB design + QMK firmware | Planned |
| v0.3 | 30-day daily use · real SFB measurement · tipping term tuning | Planned |
| v1.0 | Hardware open-sourced · firmware published · stable release | Planned |
Coda v0.1 · Concept · April 2026 · one7two99 · MIT · github.com/one7two99/coda
Sibling of Cadenza · Based on Colemak-DH