SIGN IN SIGN UP

docs(react): cover the cascade layer, read-only, returnTo, and observe requirements (#99)

## Summary

Document the four things `@domainkit/react` grew in #97. One of them is
breaking, so it says so
where a host will look.

## The stylesheet moved into a cascade layer

```css
@layer domainkit, app;
```

Every rule now sits in `@layer domainkit`, below any unlayered rule, so
a host's own CSS wins
without out-specifying a part selector. A host that relied on the
package winning orders a layer of
its own below it. That opt-in is on the React overview and the reference
page, from
`examples/react/styles.css`.

## Read-only, and what it is not

| Renders in read-only | Does not |
| -------------------- |
----------------------------------------------------------------- |
| Status, records, evidence | Connect, detach, disconnect |
| Checking DNS | Review, approve, decline, cleanup |
| | Every `retry`, because re-running a failed write is still a write |

A write surface is removed rather than disabled. The pages say plainly
that this is not capability
gating: a group the transport never declares still never renders, and
`readOnly` covers the
authorization a transport cannot express. `DomainKit.useReadOnly` and
`DomainKit.ReadOnly` are on
the reference page, and `notConnected` joins the catalog in the
presentation page.

## Two smaller ones

`returnTo` defaults to the page the customer is on and is read when they
connect, not when the flow
renders; `null` leaves the server's `defaultReturnTo` in charge.
`Verify.useController` takes
`requirements` and `Domain.Flow` passes its own, so a domain with
nothing attached verifies instead
of failing on a missing receipt. `Records.requirementsKey` is separated
from `Records.identity`:
`identity` answers "is this the same record" for a React key, while a
plan and an observation turn
on `policy`, `ttl`, and `purpose` too.

## The catalog shows it

The preview gains a read-only dial, and `?readOnly=1` makes it linkable.
It sits outside the
remount key on purpose: it changes which controls render, not what the
fake server holds, so
toggling it does not throw away the connection the reader just made.
`test:preview` pins that
exception beside the inputs that must remount.

| Writable | Read-only |
| --- | --- |
| ![Writable
flow](https://github.com/user-attachments/assets/2d003af1-85e2-4feb-95ab-be2909a8ed8d)
| ![Read-only
flow](https://github.com/user-attachments/assets/0e0ec226-321e-4c96-b030-efc03d91d2f6)
|

Both shots also show #97's observe change: the records carry a status
for a domain with no provider
attached.

## Validation

- `bun run release:check` (root, React leg included)
- `bun run typecheck:examples`
- `bun run --filter @domainkit/docs typecheck`, `test:preview`,
`reference:check`, `build`
- `blume validate --strict` (no broken links)
- `blume audit --strict` (3,724 audits, 0 errors, 0 warnings)
S
Saatvik Arya committed
73e3ed7f1296b8ba24d95443f447bc055030d028
Parent: 22b0c59
Committed by GitHub <noreply@github.com> on 9/3/2026, 8:57:38 PM