← Design · c140

plan.md

c140 plan: the QGUIkit surface, scored against our principles

Written: 2026-11-12, before the evidence came back, so the rubric is set before the scores. Reader: Mark first, then whoever ports the next page or component to the native app, then the engineers who will run both surfaces. Rests on: brand/component_philosophy.md (the eight principles, the pantry, documentation architecture, the design guidelines), brand/design_methodology.md (modularity = purpose + protocol, assemblage, the five questions), brand/design_tokens.md, qnative's CLAUDE.md (R1–R8 from qdash's data-interface bible), c131 D18 (our layer drawn on GPUI, the kit for the shell), c132's two-media loop (process.md).

What is being evaluated

The QGUIkit surface (called the GPUI surface when this plan was written; named by D1 the same day): our component system as drawn in Rust on GPUI, in ../qnative. That means the layer crate (our vocabulary: Data Machine family, Surface family, DataTable, nav, editor, tour, pills, the token bridge's outputs) and the app crate's pages as consumers of it. The Vue surface (q-nuxt-layer, consumed by qdash and this site) is the reference. Its known weak spots are named where they explain a QGUIkit score; it is not re-audited here.

Read at qnative main e609f42 (2026-11-12) and design main 4453a8c085. Another session is merging branches in both repos as this runs (qnative c2/rulings, c3/phases, the c6 and c7 branches; design's c139 cloud branch). A finding that the merge changes gets re-read, not re-argued.

The rubric

Each principle gets one score for the QGUIkit surface, 1 to 5, and the evidence behind it (file:line, counts, commits).

ScoreMeaning
5Holds by construction: the shape of the code makes the wrong thing hard, and a machine checks it
4Holds in practice: every instance we read honours it, checked by a person's eye
3Mostly holds, with named exceptions that have a known fix
2Holds only where someone was careful; the structure does not help
1Does not hold

Each score also carries:

  • Trend: better than, the same as, or worse than the Vue surface on the same principle, in a word.
  • Course correction: the smallest change that would raise the score by one. If none is worth making, say so.
  • Divergence: whether the gap is a flaw to fix, or a difference to welcome and write down for the operators (Mark's Surface entry: "acknowledge and welcome the instances where they diverge").

The principles

The eight Mark named

  1. Modularity. One purpose per component, a clean interface, free internals.
  2. Clean data boundaries. The layer takes view data and knows no source; pages go page → repository → nozzle (R2).
  3. Composition over configuration. Children and slots before flags and enums.
  4. View complexity contained. Probes, scroll, sticky, measured heights and animation live inside the component; the caller holds nothing it should not.
  5. Low knowledge of context. A component does not assume its parent, the rail, the window size or the page.
  6. Slots. Is there a GPUI equivalent of default, named and scoped slots, and is it used?
  7. Brand tokens. How hard to change a colour, a type step, a theme (light, dark, a third).
  8. Two surfaces. What it costs to keep pages that are nearly identical on both: where one change lands, what is checked by a machine, what has drifted already.

What our docs add (the ones the prompt asked us to find)

  1. Functional, not decorative; colour is semantic. Variant names, not colour arguments.
  2. Native to the medium. The web rule is Tailwind-native; its native reading is "kit-native where the kit has it, GPUI-idiomatic where it does not" (R8: a kit component before a drawn one).
  3. Progressive enhancement, base + curated presets. Simple bases; advanced behaviour composed by the consumer; presets copied, not configured.
  4. Accessibility by default. Keyboard, focus, the accessibility tree (AccessKit on GPUI).
  5. States are explicit. The interactive states table (default, hover, focus, active, disabled, loading) and the honest data states (R5: empty, minimal, typical, overflow, error).
  6. Replicate first, optimize later. The port matches the web before it improves on it, and each improvement is decided, not drifted into.
  7. Consume during implementation; the demo is the test. Doc pages with every scenario; stories as tests (R6).
  8. Constrained size and consistent motion. Named size steps, the 200 ms and 500 ms transitions.
  9. The unified pantry. Everything that renders without side effects belongs in the layer; nothing app-wired does.
  10. Documentation architecture. The library ships components; the docs live in a separate consumer (the design site).
  11. Naming. One vocabulary across surfaces, so UxPill means the same thing in both.
  12. The budget (new, native only). The medium adds a principle the web never needed: a component's cost in memory, binary and wakes is part of its interface (R7).

The five questions (useful, clear, precise, necessary, beautiful) are the closing read over the whole, not a row.

Method

  1. Evidence, in parallel, read-only. Four readers, each with a narrow brief and no scores: the layer's component APIs (1–6, 12, 13, 19); the token path (7, 9, 16); parity and drift across repos (8, 14, 18); the app's pages and the repeated manual work (2, 15, 17, and the tooling question).
  2. Scoring, by one hand. The scores are written here from the evidence, against the rubric above, so they are comparable across rows.
  3. Course corrections. Each row's smallest raise-by-one, then a ranked short list across rows: what to do this week, what to rule, what to leave.
  4. Skills and tools. Every step the records show done by hand more than twice becomes a candidate, with how often it recurred and where it went wrong.
  5. The pages. The findings on the design site as cycle reports linked from CYCLE.md's header (/cycles/design/c140/…), and the markdown behind them as cycle documents (/cycles/design/c140/doc/…).
  6. Review stop. Mark reads the scores and rules the course corrections and the open calls. Nothing is changed in qnative or the layer in this cycle without that ruling.

Out of scope

  • Changing any code in ../qnative or ../q-nuxt-layer. This cycle evaluates and proposes.
  • Re-auditing the Vue surface. c135 (Component Cleanup) does that, and its five checks are used here where they apply.
  • Building the dual-surface component docs. The Surface glossary entry asks for them; this cycle proposes their shape and leaves the build to a ruling.

Qpoint Brand Style Guide