diff --git a/content/docs/protocol/objectui/concept.mdx b/content/docs/protocol/objectui/concept.mdx
index 54f97e9e6c..23ab6f53d2 100644
--- a/content/docs/protocol/objectui/concept.mdx
+++ b/content/docs/protocol/objectui/concept.mdx
@@ -601,7 +601,9 @@ actions:
### 3. Conditional Field Visibility
-Fields appear based on other field values:
+Fields appear based on other field values. The key is **`visibleWhen`**, and its value
+is a **CEL predicate string** evaluated per record — the field is shown only when the
+predicate is TRUE:
```yaml
fields:
@@ -611,9 +613,26 @@ fields:
- name: shipping_address
type: textarea
label: Shipping Address
- visible: { shipping_required: true } # ← Show only if checkbox checked
+ # Shown only while the checkbox is checked. `has()` guards the unset case:
+ # an unbound reference faults, and visibility's fallback is "shown".
+ visibleWhen: "has(record.shipping_required) && record.shipping_required"
```
+
+ There is **no `visible` key on a field**. `FieldSchema` is a strict object, so
+ `visible` is refused *by name* — before any value shape is examined — and no
+ filter object, boolean map or breakpoint map makes it parse. Which key you want
+ depends on the form the answer takes, and the two have **opposite polarity**:
+
+ - a **static** answer is `hidden`, which is **inverted** — `visible: false`
+ becomes `hidden: true`;
+ - a **per-record** answer is `visibleWhen`, the CEL predicate above, shown when
+ the predicate is **true**.
+
+ Its siblings are `readonlyWhen` and `requiredWhen`. See the
+ [Field Reference](/docs/references/data/field).
+
+
### 4. Field Dependencies and Cascading
```yaml
diff --git a/content/docs/protocol/objectui/layout-dsl.mdx b/content/docs/protocol/objectui/layout-dsl.mdx
index 9b3901843b..20f618e1e5 100644
--- a/content/docs/protocol/objectui/layout-dsl.mdx
+++ b/content/docs/protocol/objectui/layout-dsl.mdx
@@ -521,35 +521,48 @@ tab points at a named list view. See
## Responsive Layout Modifiers
-### Device-Specific Visibility
+**Responsive behaviour is not a form-field or form-section key.** A form field's
+only conditional-visibility key is `visibleWhen` — a CEL predicate over the
+record, so it varies per *record*, never per *viewport* — and a section's
+`columns` is a single scalar (`1`–`4`). Both shapes are strict, so a breakpoint
+or orientation map written on either is a **loud parse error** naming the key,
+not a layout that quietly does nothing.
-```yaml
-fields:
- - name: detailed_description
- span: 12
- visible:
- desktop: true # Show on desktop
- tablet: true # Show on tablet
- mobile: false # Hide on mobile
-
- - name: short_summary
- span: 12
- visible:
- desktop: false # Hide on desktop
- tablet: false # Hide on tablet
- mobile: true # Show on mobile
-```
+### Per-Breakpoint Styling
-### Orientation-Specific Layout
+Breakpoint-driven show/hide and per-breakpoint layout live one tier up, on a
+**page component**, and are expressed as scoped CSS through `responsiveStyles`
+([ADR-0065](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0065-sdui-styling-model.md)) — desktop-first buckets compiled to id-scoped CSS at
+render:
```yaml
-section:
- columns:
- portrait: 1 # 1 column in portrait mode
- landscape: 2 # 2 columns in landscape mode
- fields: [field_a, field_b, field_c]
+# On a page component (*.page.ts) — NOT on a form field or a form section
+responsiveStyles:
+ large: { gridColumn: 'span 6' } # unconditional base (desktop-first)
+ medium: { gridColumn: 'span 12' } # applied at ≤ medium
+ xsmall: { display: 'none' } # hidden at the smallest breakpoint
```
+The four buckets are `large` / `medium` / `small` / `xsmall`; values are a
+CSS-property map with camelCase keys. Prefer design tokens
+(`var(--space-6)`) over literals.
+
+
+ Earlier revisions of this page documented a field-level `visible:` breakpoint
+ map (`desktop` / `tablet` / `mobile`) and a section-level `columns:`
+ orientation map (`portrait` / `landscape`). **Neither existed on any schema.**
+ `visible` is not a form-field key at all — `FormFieldSchema` declares `hidden`
+ (static, and **inverted**: `visible: false` is `hidden: true`) and
+ `visibleWhen` (CEL predicate) — and `FormSection.columns` has always been a
+ scalar. Both are **removed rather than implemented**, because field-level
+ breakpoint visibility exists nowhere in the spec: there is no key to rename
+ them onto.
+
+ Nor is `responsive.hiddenOn` the answer. That layout block was retired in
+ v17.x under [ADR-0049](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0049-no-unenforced-security-properties.md) D2 precisely because no renderer ever applied it;
+ `responsiveStyles` above is the only per-breakpoint channel that is.
+
+
## Related Lists: Embedding Child Records
Display child records within a parent record's page.