> ## Documentation Index
> Fetch the complete documentation index at: https://velt-codex-ui-customization-guide-refresh.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Decision Tree: Which approach for your design?

> Choose the right UI customization layer for each Velt surface using a step-by-step decision tree.

**This is the spine of the guide. Run it for every design, feature by feature.**

There is no single "best" layer, but there **is** a default order to reach for them. Cheaper layers (CSS, wireframes) are faster and upgrade-safe; richer layers (primitives, headless) give more control but you do more work and maintain more.

> **Golden principles**
>
> 1. **Use the cheapest layer that can express the design.** Reach in this order: **CSS → Wireframes → Primitives → Headless.**
> 2. **Wireframes are the default for structural customization.** Prefer them. Drop to CSS if you only need theming; escalate to **primitives** only when you need full control / your own UI component library / your own interactivity (or to customize a *leaf* piece); use **headless** only as a last resort.
> 3. **CSS is always available** and layers on top of every other approach (override with `!important`).
> 4. **You can mix layers: even on the same surface** (e.g. a `VeltCommentDialog` primitive *and* a wireframe for parts of it).
> 5. **Mind positioning (a second axis).** Some surfaces are **anchored**: Velt's host computes their on-page position (the floating **pin dialog**, comment **pins**, **bubbles**, **cursors**, **minimap**). For these, dropping **below wireframes forfeits Velt's anchoring engine**; prefer wireframes + CSS and escalate only if a positioning path is *verified* feasible. **Statically-placed** surfaces (sidebar, inline section, notifications panel) carry no such penalty. See [`Behaviors`](/ui-customization/reference/behaviors).

***

## How to use this

1. Split the design into **features/surfaces** (comment dialog, comments sidebar, comment pin/bubble, notifications panel, reaction tool, …). Velt is customized **per feature**, so decide per feature. *Not sure which Velt component a design element is?* Recognize it first with [`Component definitions`](/ui-customization/reference/component-definitions) (design intent → component, with disambiguation for look-alikes and off-by-default flags); if nothing matches, it's host UI (ignore) or an SDK gap ([`SDK gaps and blockers`](/ui-customization/sdk-gaps-and-blockers)).
2. For each feature, walk the **questions** below in order. Stop at the first "yes".
3. Record the chosen layer **and the reason**. Different features can land on different layers, and one feature can use more than one layer. That is expected; see [`Combining approaches`](/ui-customization/combining-approaches).

> **Before customizing:** if the design needs a piece that isn't showing by default (reply avatars, priority, minimap, @here, device badge, …), check [`Feature flags`](/ui-customization/reference/feature-flags): many features are behind a prop. And if the design surfaces *your app's data* in the comment UI, that's [context](/ui-customization/context).
>
> **Three references make these decisions confident: use them:** [`Behaviors`](/ui-customization/reference/behaviors) for **how a prop behaves and how props combine** (defaults, interactions, the dialog state machine, variant→context scoping, positioning ownership); [`Data models`](/ui-customization/reference/data-models) for **what data exists** (fields, which hook/event exposes each, custom-data storage, and documented **absences**); [`Component definitions`](/ui-customization/reference/component-definitions) for **what a component is *for*** (right-tool / wrong-tool). Together they let you give a definitive supported / not-supported verdict instead of a guess.

***

## The questions (per feature)

**Q1: Is the only difference colors, spacing, fonts, radius, or shadows?**
(The layout and which elements appear are basically Velt's default.)
→ **CSS.** Theme with `--velt-*` variables; override classes with `!important`. See [`CSS`](/ui-customization/styling).

**Q2: Does the design change the *structure/layout* (custom header, reordered/added/removed parts, custom thread-card, custom empty state) while keeping the same features: AND you don't need your own interactive components or UI-library widgets *inside* the comment UI?**
→ **Wireframes** (+ CSS). **This is the default for structural customization: prefer it.** Velt fetches the data, loops the threads/comments, and wires each slot's behavior; you just supply layout markup. See [`Wireframes`](/ui-customization/layout).

**Q3: Do you need full control: your own **UI component library**, your own **interactivity/state**, to **compose Velt's building blocks yourself** (fetch data, loop, conditionals, pass props), to place Velt pieces **anywhere** in your tree, or to customize a piece **more deeply than its wireframe allows**?**
→ **Primitives** (+ CSS, + a leaf's wireframe where needed). You write the React (loop annotations, pass `annotation-id`, loop comments, pass each `comment`); you compose the building-block components and their sub-components into any layout; you wrap them in any UI library. More effort, most control. See [`Primitives`](/ui-customization/primitives).

**Q4: Does nothing Velt renders fit: you must own 100% of the UI, or render on a surface Velt can't draw into (PDF, canvas, video timeline)?**
→ **Headless** (last resort). Data + actions via hooks; you build everything. See [`Headless`](/ui-customization/headless).

**Still unsure between wireframes and primitives?** Default to **wireframes** and only switch to primitives when you hit one of the Q3 triggers (UI library, custom interactivity, leaf-deep changes, arbitrary placement).

***

## Flowchart

```text theme={null}
                    ┌─────────────────────────────────────────────┐
                    │  For ONE feature/surface of the design       │
                    └──────────────────────┬──────────────────────┘
                                           ▼
              Only colors / spacing / fonts / radius differ?
                          │ yes ──────────────► CSS
                          │ no
                          ▼
        Custom STRUCTURE/LAYOUT, same features, no need for your
        own interactive/UI-library components inside?
                          │ yes ──────────────► WIREFRAMES (+ CSS)   ◄── default
                          │ no
                          ▼
        Need full control: own UI library, own interactivity,
        compose building blocks yourself, place anywhere, or
        change a piece deeper than its wireframe allows?
                          │ yes ──────────────► PRIMITIVES (+ CSS, + leaf wireframes)
                          │ no
                          ▼
        Must own 100% of the UI, or render where Velt can't draw?
                          │ yes ──────────────► HEADLESS (last resort)
                          │ no  ──────────────► re-check Q1-Q4
```

***

## After you pick a layer: the sub-decisions (run every time)

Q1-Q4 pick the **primary layer**. These checks (S1-S8) then refine it. Run all of them for **every** surface, in order, and record each answer alongside the layer + reason: they're what turn "use wireframes" into an exact, buildable spec. None of them is a hack; each is a supported, documented branch.

**S1: Is a piece the design shows hidden by default?**
Many features are **off by default** (reply avatars, priority, minimap, `@here`, device indicator, comment index / pin number, sidebar-button-on-dialog, format toolbar, …). If the design shows one, **enable it with its prop** (e.g. `priority`, `replyAvatars`, `commentIndex`, `sidebarButtonOnCommentDialog`): look up the exact prop in [`Feature flags`](/ui-customization/reference/feature-flags). Enabling a documented feature is **not** a hack and is **not** a reason to escalate layers.

**S2: Does the design surface custom data?**
Custom **statuses / priorities / categories / reactions** → configure `customStatus` / `customPriority` / `customCategory` / `customReactions` ([`Component config`](/ui-customization/reference/component-config)). The design surfaces **your app's own data** in the comment UI → that's [context](/ui-customization/context). Neither changes the layer: they're data config layered on top.

**S3: UI-component-library placement (the table below).**
If the design is built from your own component library, *where* those components sit decides wireframe vs primitive. Static shell + classes only → wireframe is OK; must stay interactive → **primitive**. See the [next section](#the-uicomponentlibrary-question-dont-miss-this).

**S4: Mix per piece?**
A surface can combine layers: wireframe most of it + use a **leaf's** wireframe for one piece; or a **primitive** for the surface + a leaf wireframe for one part; + CSS on either. Record `layer = mixed` and the per-piece split. Keep **one** `<VeltWireframe>` and **one** stylesheet globally ([`Combining approaches`](/ui-customization/combining-approaches)).

**S5: Do *you* need to control show/hide?**
If the design requires **your** logic to decide when a piece appears (not Velt's internal condition), that's a **primitive** with `defaultCondition={false}`: wireframes have **no** equivalent ([`Primitives`](/ui-customization/primitives)). This can flip a Q2 "wireframe" answer to a primitive; resolve it here.

**S6: Shadow-DOM decision (whenever you wireframe or write class CSS).**

* Wireframing a surface's **ROOT** wireframe (e.g. `VeltCommentDialogWireframe`, `VeltCommentPinWireframe`) → Velt **auto-removes that surface's shadow DOM** → your class CSS reaches it, no flag needed.
* Wireframing **only a nested / leaf** slot (no root wireframe for that surface) → shadow is **not** removed → set `shadowDom={false}` (or the per-surface flag / `injectCustomCss`) for class CSS.
* **CSS variables** (`--velt-*`) and **inline `style=""`** always work, shadow or not.
  See [`CSS`](/ui-customization/styling#shadow-dom--wireframes-root-vs-nested). (Which wireframes are roots: the per-surface map in [`Component catalog`](/ui-customization/reference/component-catalog).)

**S7: Anchored surface? (positioning ownership.)**
If the surface is **anchored** (pin dialog, pins, bubbles, cursors, minimap), Velt's host owns its on-page position: the dialog component itself only *requests* re-anchoring and has no position input. **Wireframes keep that positioning for free; primitives/headless mean *you* own it**, which for a pin-anchored dialog may not even be feasible via the public API. Treat this as a strong reason to stay at wireframes; escalate only after a positioning path is *verified* feasible. Statically-placed surfaces have no penalty. See [`Behaviors`](/ui-customization/reference/behaviors).

**S8: Confirm against the data, then give a definitive verdict.**
Before concluding a goal needs **primitives/headless** or is **not possible**, confirm in [`Data models`](/ui-customization/reference/data-models) that the required fields/events exist. If they do → feasible via headless; say so. If they're a documented **absence** → genuinely not achievable client-side; say *that*. State the **first layer that achieves the goal** (default behavior → prop/config → wireframe → primitive → headless) as a **definitive verdict**. If the guide doesn't cover it, that's an **unknown to verify against ground truth** (the live SDK / running app), not a reason to hedge or to declare impossible.

> **Output of the decision tree (per surface):** primary layer (Q1-Q4) · feature flags to enable (S1) · custom-data config (S2) · UI-library placement (S3) · mix split if any (S4) · escape-hatch / `defaultCondition` (S5) · shadow handling (S6) · positioning ownership (S7) · data-confirmed definitive verdict (S8) · and the reason. That's a complete, buildable spec: resolve all of it here so the build step only executes.

***

## The UI-component-library question (don't miss this)

If your design is built from **your own component library** (MUI, shadcn/ui, Ant, Radix, Chakra, Tailwind UI…), where those components live changes everything:

| Where your library components sit                                                              | Allowed?       | Why                                                                                                                                |
| ---------------------------------------------------------------------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| **Around / next to** a Velt **primitive** (`<MuiCard><VeltCommentDialog/></MuiCard>`)          | ✅ Yes          | Primitives are real React components; your library renders normally beside them.                                                   |
| **As interactive components composed with primitives**                                         | ✅ Yes          | You own the React tree: full interactivity.                                                                                        |
| **As the visual shell** inside a **wireframe** slot (static components + classes, no behavior) | ⚠️ Static only | Velt clones the markup: your library's **static rendered output + CSS classes** survive, but `onClick`/state/hooks **do not run**. |
| **As interactive components** inside a **wireframe** slot (needing their own click/state)      | ❌ No           | Cloning strips React interactivity. Use **primitives** instead.                                                                    |
| **Anywhere**, in a **headless** build                                                          | ✅ Yes          | You render everything yourself; Velt only supplies data/actions.                                                                   |

**Rule of thumb:** *want to reuse your interactive design-system components inside the collaboration UI?* → **Primitives** (or Headless). Not wireframes.

***

## Comparison matrix

|                                   | **CSS**                                                                                                                 | **Wireframes**                                                                                                                             | **Primitives**                                                                                                                            | **Headless**                                 |
| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| **Reach order**                   | 1st (theming)                                                                                                           | 2nd (default structural)                                                                                                                   | 3rd (full control)                                                                                                                        | 4th (last resort)                            |
| **Design control**                | Theme only                                                                                                              | High (any layout/structure)                                                                                                                | Highest short of headless                                                                                                                 | Total                                        |
| **Effort**                        | Lowest                                                                                                                  | Low                                                                                                                                        | Medium-High                                                                                                                               | Highest                                      |
| **Who does data/looping/wiring**  | Velt                                                                                                                    | **Velt** (you just lay out slots)                                                                                                          | **You** (fetch, loop, pass props)                                                                                                         | You (from hooks)                             |
| **Velt-managed behavior**         | All                                                                                                                     | All (via slots)                                                                                                                            | All (you compose it)                                                                                                                      | None: you wire actions                       |
| **Custom layout/structure**       | ❌                                                                                                                       | ✅ (slots)                                                                                                                                  | ✅ (sub-components; leaf via wireframe)                                                                                                    | ✅                                            |
| **Use your UI library**           | n/a                                                                                                                     | ⚠️ static components & classes only (no behavior)                                                                                          | ✅ fully                                                                                                                                   | ✅ fully                                      |
| **Your own interactivity inside** | n/a                                                                                                                     | ❌ (cloned markup)                                                                                                                          | ✅                                                                                                                                         | ✅                                            |
| **Upgrade safety**                | Highest                                                                                                                 | High                                                                                                                                       | Medium                                                                                                                                    | Lowest                                       |
| **Maintenance burden**            | Lowest                                                                                                                  | Low                                                                                                                                        | Medium-High                                                                                                                               | Highest                                      |
| **Reference page**                | [`css-variables`](/ui-customization/reference/css-variables) · [`css-classes`](/ui-customization/reference/css-classes) | [`wireframe-components`](/ui-customization/reference/wireframe-components) · [`wireframe-variables`](/ui-customization/template-variables) | [`component-catalog`](/ui-customization/reference/component-catalog) · [`component-config`](/ui-customization/reference/component-config) | [`hooks`](/ui-customization/reference/hooks) |

***

## When a layer "breaks down" → escalate

Signs you've outgrown your current layer:

* **CSS → Wireframes:** you're writing `display:none` to hide parts, or you need to reorder/add/remove parts or restructure the header/composer/thread-card layout.
* **Wireframes → Primitives:** you need your **own interactive component** inside the UI, your **own UI component library** there, to **place Velt pieces arbitrarily** in your tree, custom data composition/conditionals beyond `velt-if`, or to customize a **leaf** piece more than its slot allows. (For a single leaf you can stay in wireframes and use that leaf's wireframe; switch to primitives when the *whole surface* needs that level of control.)
* **Primitives → Headless:** Velt can't render where you need it (PDF/canvas), or you want to own 100% of the data→view pipeline.

And the reverse: **don't over-escalate**:

* Went **primitives** just to restructure layout that wireframe slots already expose? Wireframes are less work.
* Went **headless** just to recolor or reflow? CSS or wireframes would do it.

***

## Worked examples

| Design intent                                                                                   | Chosen layer(s)      | Why                                                              |
| ----------------------------------------------------------------------------------------------- | -------------------- | ---------------------------------------------------------------- |
| Velt sidebar, brand colors + tighter spacing                                                    | **CSS**              | Only theme differs.                                              |
| Custom dialog with a custom header, thread card, and empty state                                | **Wireframes + CSS** | Structure changes, features stay the same.                       |
| App-native page-mode sidebar (custom cards, attachments, assign rows) anchored to page elements | **Wireframes**       | Deep slot customization; Velt keeps behavior, data, and looping. |
| Comment UI rendered inside an app built on a component library, composed with that library      | **Primitives + CSS** | Needs the UI library + custom composition.                       |
| A fully bespoke, interactive comment panel built from your own components                       | **Primitives**       | Full control + own interactivity.                                |
| Unread-count badge in your own app header, no Velt UI                                           | **Headless**         | Data only: `useUnreadCommentAnnotationCountOnCurrentDocument`.   |
| Comments rendered as overlays on a PDF / canvas / video timeline                                | **Headless**         | No Velt UI fits; render from `useCommentAnnotations`.            |

Picked your layer or layer mix? Go to [`Setup`](/ui-customization/setup), follow the [`Build methodology`](/ui-customization/build-methodology), then open the matching approach page from the UI Customization navigation.
