# Antz Mobile & Tablet UI Standards

Version 1.0 · 26 Oct 2026 · owner: Sourav Tambe

Source of truth: the Figma files listed in §1. Every value here was read from Figma variables, styles or measured layers, then settled by Sourav where files disagreed (§11). Code is never the source. Rule ids (`COL-01`) are stable; cite them in reviews and specs.

Companion files: `COMPONENTS.md` / `components.json` (every component and layout with HTML examples; generated with the website and the source of truth for component detail), `tokens.css` / `tokens.json` (values), `antz.css` (component classes), `site/` (the Antz Design website), `sources/*.md` (Figma measurements with node ids), `decisions.json` (the 36 settled conflicts).

§7 and §8 below summarise; where they differ from COMPONENTS.md, COMPONENTS.md wins.

---

## 1. Sources

| Source | Figma file key | Frames | Device |
| --- | --- | --- | --- |
| VVMS Mobile | `74YTD7MToJVweXNuVri6xY` | Mobile UI 8:5555; Requests & Approval 383:4510 | Phone 390 × 844 |
| Training | `76AVD9M2CKL758DpHVnTi4` | iPad 230:7594; phone Handoff 238:4007; dashboard 318:4379 | Phone 390, iPad 834 |
| Help Desk ("Requests - Task") | `VPKybj9jCMEQKKPynTu7Zo` | Simple Request Module 349:83318; Section 5 4707:32312; Masters 1249:15848 | Phone 390 |
| Hospital | `NcSjVLd98TjNftPuPalL4b` | Section 3 1099:33858 | iPad 810 × 1080 |

Open a node: `https://www.figma.com/design/<key>?node-id=<node with ":" → "-">`.

---

## 2. Devices

| | Phone | Tablet |
| --- | --- | --- |
| Frame | 390 × 844 | 834 × 1194 (iPad Pro 11, portrait) |
| Side padding | 16 (content 358) | 20 |
| Landscape | — | Not designed yet (§12) |

**DEV-01** Build phone first. A tablet screen is designed for the tablet (list + detail side by side where it helps), never a stretched phone.

---

## 3. Colour

Use token names (`tokens.css`), never raw hex. One set, `MD3_Antz`, identical across all four files.

| Token | Hex | Role |
| --- | --- | --- |
| Primary | #37BD69 | Main action, active underline tab, active Secondary tab, switch on, success |
| OnPrimary | #FFFFFF | Text on Primary |
| OnPrimaryContainer | #1F515B | Selected fill (chips, pills, tiles), navy action, values, links in menus |
| OnSecondaryContainer | #1F415B | Dark detail header; sheet scrim at 50% |
| OnSurfaceVariant | #44544A | Screen titles, card titles, labels, body, default icons |
| neutralSecondary | #7A8684 | Meta lines: dates, IDs, org, "2 d" |
| Outline | #839D8D | Placeholder text, disabled button text, approver avatar fill |
| OutlineVariant | #C3CEC7 | Field border, outline button border, dividers, switch off |
| Surface | #F2FFF8 | Field fill, selected option fill |
| SurfaceVariant | #DAE7DF | Disabled button fill, tags |
| Background | #EFF5F2 | Nested containers: animal card, pill-tab track, sheet body, filter rail |
| displaybgPrimary | #E8F4F2 | Page background option; bottom nav; soft blocks |
| displaybgSecondary | #DDEBE9 | Page background option; default chip; picked item |
| OnBackground | #E1F9ED | Positive status fill |
| OnSurface | #006D35 | Positive status text, dark green text and links |
| Secondary | #00D6C9 | Initials avatar, male sex tag |
| SecondaryContainer | #AFEFEB | Active bottom-nav pill |
| addPrimary | #00AFD6 | Add buttons, tablet FAB pill, picker add icon |
| Tertiary | #FA6140 | Cancel actions, required `*`, female sex tag, warning icons |
| TertiaryContainer | #FFBDA8 | Cancelled tint |
| OnTertiaryContainer | #250E01 | Awaiting-approval text |
| Error | #E93353 | Reject, delete, expired, not authorised |
| ErrorContainer / OnErrorContainer | #FFD3D3 / #4A0415 | Error tint / text on it |
| moderateSecondary | #E4B819 | Pending / upcoming, ratings |
| moderatePrimary | #FFE86E | Pending tint base |
| notes | #FCF4AE | Notes fields, scheduled cells |
| neutral05 | #000 at 5% | Search and filter fill, hairlines, neutral pill |
| neutralPrimary20 | #000 at 20% | Empty rating, round buttons on dark |
| greenturq (gradient) | #00D6C9 → #37BD69, 116.5° | Phone FAB, module icons |

**COL-01** Tokens only. A colour with no token is added to `tokens.css` once, then used by name.
**COL-02** Colour marks what is wrong or needs action; it is never decoration. No colour stripes, no tinted callouts inside cards.
**COL-03** Retired values: #00572A (use OnSurface), #3C6480, raw `rgba(76,78,100,.12)` MUI disabled.
**COL-04** Page background is one of displaybgSecondary, displaybgPrimary, Background, SurfaceVariant, chosen per screen to break a monotonous run (§11).

### Status colours

| Meaning | Statuses | Fill | Text |
| --- | --- | --- | --- |
| Positive | Active, Approved, Entry, Completed | OnBackground #E1F9ED | OnSurface #006D35 |
| Pending | Upcoming, Waiting, Draft | #FFE86E at 30% | moderateSecondary #E4B819 |
| Negative | Expired, Rejected, Denied, Not authorised | #FFD3D3 at 40% | Error #E93353 |
| Cancelled | Cancelled | #FFBDA8 at 30% | Tertiary #FA6140 |
| Neutral | Exit, Inactive, Auto | neutral05 | OnSurfaceVariant #44544A |
| Awaiting (strip only) | Awaiting approval | #E4B819 at 10% | OnTertiaryContainer #250E01 |

---

## 4. Type

Inter only. Line height 100% unless noted; paragraphs 20px, bullet lists 24px. Letter-spacing 0 except Body Medium 0.1px.

| Style (Figma) | Size / weight | Use |
| --- | --- | --- |
| Antz_Stat_Title | 28 / 600 | Big numbers on tablet; scan-result title |
| Antz_Major_Title | 24 / 600 | Big numbers on phone (stat tiles) |
| Antz_Major_Medium | 24 / 500 | Large sheet/edit title (rare) |
| Antz_Medium_Medium | 20 / 500 | Screen title, sheet title, dark-header title, empty-state text |
| Antz_Minor_Title | 16 / 600 | Section title, count in count tabs, main button label |
| Antz_Minor_Medium | 16 / 500 | Names on cards, section headings in forms, decision buttons |
| Antz_Minor_Regular | 16 / 400 | Field values and placeholders |
| Antz_Body_Title | 14 / 600 | Count line "Requests (6)", filter rail items |
| Antz_Body_Medium | 14 / 500, 0.1 | Field labels, tabs, menu items, detail values, tablet status pill |
| Antz_Body_Regular | 14 / 400 | Body, descriptions, secondary lines |
| Antz_Subtext_title | 12 / 600 | IDs, phone status pill, initials |
| Antz_Subtext_Regular | 12 / 400 | Meta, timestamps, count-tab labels |
| Antz_Small | 10 / 500 | Badges only (sex, CITES) |

**TYP-01** No size off this ladder; no 13, 15 or 700. Never MUI default button/chip sizes.
**TYP-02** Numbers lean light: on phone 24/600 or 20/500; tablet 28/600.
**TYP-03** Sentence case for tabs, buttons, titles. No uppercase eyebrows.

---

## 5. Space, radius, elevation

| Measure | Phone | Tablet |
| --- | --- | --- |
| Side padding | 16 | 20 |
| Gap between list cards | 12 | 12 |
| Gap between form section cards | 16 | 16 |
| Card padding | 12 list/detail, 16 form | 16 |
| Gap inside a card | 12 | 12 |
| Label → field | 8 | 12 |
| Top bar | 72 tall, pt 26 pb 22 px 16 | 72, p 20 |
| Sticky action bar | white, p 16 | white, p 20 |

| Radius | Use |
| --- | --- |
| 4 | Status pills, thumbnails, tags |
| 8 | Cards, fields, buttons, chips, search, filter button, menus |
| 12 | Request cards, animal card, tablet panels, segmented track |
| 16 | Bottom sheets, FAB, dialogs, decision bar top |
| 24 | White sheet over the dark header, scan-result sheet, tablet FAB pill |
| 100 | Avatars, Secondary tab, switch |

| Effect (Figma name) | Value | Use |
| --- | --- | --- |
| `cards` | 0 2 2 rgba(0,0,0,.1) | Cards that need lift (request card) |
| `1px Shadow` | 0 1 1 rgba(0,0,0,.1) | White header blocks, chip row, sheet title bar |
| `-1px Shadow` | 0 -1 0 rgba(0,0,0,.1) | Sticky footers |
| `FAB` | 0 4 4 rgba(0,0,0,.15) | Phone FAB |
| menu | 0 4 14 rgba(0,0,0,.15) | ⋮ menus |

**SPC-01** One container level: no card in a card. Border or shadow, never both.
**SPC-02** Touch targets ≥ 44.

---

## 6. Icons

Material Symbols Rounded (Figma component `Mobile / Icon / ALL`). In code: `<span class="az-i">arrow_back</span>`; the font is in `assets/`.

| Size | Use |
| --- | --- |
| 24 | App bar, bottom nav, field trailing, checkbox, close, menu |
| 20 | Section headings, detail rows, status strip, call/chat |
| 18 | Search, filter |
| 16 | Tab icons, ID badge, inline chevrons |
| 50 | Home/module tiles (gradient) |
| 64 / 96 | Confirm hero / scan-result hero |

Common glyphs (not a closed list; any Material Symbols Rounded glyph may be used when it fits the meaning): arrow_back, close, more_vert, search, tune (filter), add_circle, qr_code_2, qr_code_scanner, badge, call, chat, mail, location_on, date_range, event, schedule, pace, devices_other, check_circle, cancel, block, gpp_maybe, swap_horiz, download, ios_share, content_copy, delete, edit, drag_indicator, person, corporate_fare, keyboard_arrow_down, chevron_right, check_box, check_box_outline_blank, indeterminate_check_box, radio_button_checked, radio_button_unchecked, select_all, deselect.

**ICN-01** Icon colour follows its text. On the dark header: white.
**ICN-02** A control's states are different glyphs from the same set (check_box / indeterminate_check_box / check_box_outline_blank). Colour alone is never a state.

---

## 7. Components

Class names refer to `antz.css`. Source = the frame to copy from.

### Headers and navigation

| Component | Spec | Class | Source |
| --- | --- | --- | --- |
| Top app bar | White, 72, pt 26 pb 22 px 16, gap 4. ← 24 in 30 × 48. Title 20/500 OnSurfaceVariant. Trailing 36 icon buttons. 1px neutral05 bottom | `.az-topbar` | VVMS 190:17741 |
| Dark detail header | OnSecondaryContainer. Bar pt 32 pb 12 px 16: ←, title 20/500 white (centred or left + subtitle), ⋮. Who row: 36 avatar, name 16/500, org 14/400. White sheet overlaps, r24 | `.az-darkhead` + `.az-sheetbody` | VVMS 220:23313 |
| Requester strip | OnSecondaryContainer + black 10%, p 16. 36 photo, name 14/400 white, date 10/400 #E8F4F2. Call/chat 20 icons in black-20% circles | — | VVMS 370:10429 |
| Bottom nav (phone) | 80, displaybgPrimary, px 8 gap 8. Icon 24 in 64 × 32 layer; active = SecondaryContainer pill r16. Labels 12/500 | `.az-nav` | Training 78:4008 |
| Bottom nav (tablet) | 97, tinted, p 20, 3 items; active item in a white box r8; labels 14/400 OnPrimaryContainer | — | Hospital 1096:32028 |

### Tabs and filters (Sourav's names)

| Component | Spec | Class | Source |
| --- | --- | --- | --- |
| **Primary tab — count** | Count 16/600 over label 12/400. Active count Primary + 2px Primary bar. Scrolls sideways | `.az-counttabs` | VVMS 370:7146 |
| **Primary tab — underline** | Equal widths, 14/500. Active Primary text + 2px bar; inactive 1px OutlineVariant | `.az-tabs` | VVMS 190:17749 |
| **Secondary tab — pill** | Background track r100 p 4; segment px 16 py 12; active Primary fill white text | `.az-segment` | Training 177:4850 |
| **Chip tab** (smallest) | 32, r8, px 8. Selected OnPrimaryContainer + white 14/500; default displaybgSecondary + OnPrimaryContainer 14/400. Label carries the count: "All - 22" | `.az-chip` | VVMS 190:17765 |
| Search + filter | Search 40, neutral05, r8, 18 icon, 12/400. Filter 40 × 40 same fill. Gap 8, row px 16 py 12. Outlined (44–48) or white-with-shadow (56) when more prominence is needed | `.az-searchrow` | Training 230:7268 |
| Filter screen | Full screen. Header pt 44 pb 16 "Filter - 0" + ×. Left rail 162, Background, items 14/600 OnPrimaryContainer, active white. Footer 80: "12 results", Clear all (outline 40), Apply Filters (Primary 40) | — | Training 186:8074 |

### Cards and status

| Component | Spec | Class | Source |
| --- | --- | --- | --- |
| List card | White, r8, no shadow. Optional head strip px 12 py 8 (ID 12/600 + pill). Body p 12 gap 12: who row, facts | `.az-card` | VVMS 281:7032 |
| Request card | White, r12, `cards`; status strip at the bottom. Only for request/approval cards | `.az-card--request` + `.az-strip` | Help Desk 89:129699 |
| Status pill | px 8 py 4, r4. Phone 12/600, tablet 14/500 | `.az-pill--*` | VVMS 281:7044 |
| Status strip | 2px inset, px 14 py 12, bottom r10; 20 icon + 14/500 label + 12/400 time at 40% black | `.az-strip--*` | Help Desk 89:129883 |
| Avatar | 36 initials on Secondary; 48 on scan card; 24 on Outline for approvers | `.az-avatar` | VVMS 281:7032 |
| Detail row | 20 icon; label 14/400 neutralSecondary over value 14/500 | `.az-drow` | VVMS 220:23332 |
| Activity timeline | 36 dot, 20 glyph, tinted by event; 2px connector; title 14/500, meta 12/400 | `.az-timeline` | VVMS 220:25863 |
| Stat tile | White, corners 8, padding 12 (16 left). Number 24 Semibold black (28 tablet), label 12 Regular Ink, 44 icon box corners 8 tinted turquoise / green / coral / amber. Group of 2 per row on phone, up to 4 on tablet, gap 12, on Pale green. Not tappable | `.az-stats` · `.az-stat--*` | Egg module prototype |
| Approver row | 24 avatar, name 14/500, role 12/400, state icon 20 on the right | — | VVMS 379:11909 |

### Entity cards

Entity cards show a thing in the zoo: animal, site, section, enclosure. Only the measured ones are listed; section and enclosure cards are a gap (§12).

| Component | Spec | Class | Source |
| --- | --- | --- | --- |
| Animal card | Background, r12, p 8, gap 8. Photo 104 × 104 r8 with sex tag 24 at 4,4 (M Secondary, F Tertiary, UD Error; 10/500 white), CITES tag "C 1" at left 73 (black 40%, r6), expand icon bottom-right. Text column gap 4, single line with ellipsis: "Ear Tag / Name / Chip: …" 14/600 OnPrimaryContainer; AID, common name, Encl 14/500 OnSurfaceVariant; scientific name 14 italic neutralSecondary. Use for every animal on screen | `.az-animal` + `.az-photo` | Training 193:9208, 225:6202; photo 40:1646 |
| Site card (choosing) | White, r8, p 12, gap 12. Thumb 48 r4 (neutral05 behind). Name 16/500, area 14/400 OnSurfaceVariant. 24 checkbox right. Selected: 1px Primary border + check_circle Primary. Rows gap 8 | `.az-site` | VVMS 22:10637, 370:10985 |
| Site card (picked) | 56 tall, displaybgPrimary, 1px white border, r8, p 8, gap 12. Thumb 40 r4. Name 16/500, sub 14/400. Remove: 24 cancel in Tertiary | `.az-site--picked` | Training 225:5782 |

### Fields

| Component | Spec | Class | Source |
| --- | --- | --- | --- |
| Text field | 56, Surface, 1px OutlineVariant, r8, px 16. Placeholder 16/400 Outline; value 16/400 OnSurfaceVariant. Label 14/500 above, gap 8; required `*` Tertiary | `.az-input` | VVMS 22:7770 |
| Dropdown | As text field; value OnPrimaryContainer; 24 keyboard_arrow_down | `.az-input--select` | VVMS 22:7780 |
| Date | As text field with 24 calendar trailing; pairs two-up, gap 16 | `.az-two` | VVMS 22:7790 |
| Phone | Prefix "+91 ▾" 14/500 then the number | — | VVMS 22:7771 |
| Text area | 112 tall, pt 12 | `.az-textarea` | VVMS 22:7853 |
| Picker field | 56, add_circle 24 addPrimary | — | VVMS 8:6237 |
| Picked item | displaybgSecondary, r8, p 12, 36 photo, 16/500 + 14/400, 24 cancel | `.az-picked` | VVMS 22:7802 |
| Checkbox row | 1px OutlineVariant, r8, 24 box, 16/400; rows gap 8 | `.az-checkrow` | VVMS 8:6250 |
| Switch | 39 × 24, r100; on Primary, off OutlineVariant; 18 knob | `.az-switch` | VVMS 309:9693 |
| Form section | White, r8, p 12, gap 16; heading 20 icon + 16/500 | `.az-section` | VVMS 8:6186 |

### Buttons

| Button | Spec | Class | Source |
| --- | --- | --- | --- |
| Main action | 56, r8, Primary, 16/600 white. Navy OnPrimaryContainer 56 to vary a run of screens | `.az-btn`, `.az-btn--navy` | Help Desk 355:107528 |
| Approve / Reject | 48, r8, Primary / Error, 16/500. Phone stacked gap 12 in a white bar r16 top; tablet side by side | `.az-btn--approve/--reject` | VVMS 370:10676 |
| Outline | White, 1px OutlineVariant, OnPrimaryContainer 16/500 | `.az-btn--outline` | Training 186:8096 |
| Add | addPrimary, 16/500, 20 icon | `.az-btn--add` | Training 230:7527 |
| Compact | 40 (filter footer) | `.az-btn--compact` | Training 186:8098 |
| Disabled | SurfaceVariant fill, Outline text | `.az-btn[disabled]` | Decision, not yet in Figma |
| FAB (phone) | 56, r16, greenturq, add_circle 24 white, `FAB`. Right 24, above the nav | `.az-fab` | VVMS 190:17772 |
| FAB (tablet) | Pill 48, r24, addPrimary, icon + 16/500 label; when the page has one action | `.az-fab--pill` | Hospital 1096:32025 |

**BTN-01** One main action per screen, the rest in ⋮. Delete never sits in red beside Edit.
**BTN-02** Confirm-popup buttons are 56.

### Sheets, dialogs, menus, feedback

| Component | Spec | Class | Source |
| --- | --- | --- | --- |
| Bottom sheet | Scrim OnSecondaryContainer 50%. Top r16. Title bar px 16 py 20, 20/500 left + ×, `1px Shadow`. Body Background p 16 gap 12. Footer white p 16: Cancel + action 50/50 (one button when a single decision). Handle 48 × 4 #999 only when draggable | `.az-sheet` | VVMS 220:24043 |
| Option row | White, 1px OutlineVariant, r8, p 12; selected 1px Primary + Surface + check_circle | `.az-option` | VVMS 306:5068 |
| Confirm popup | White r16, 64 hero icon, 16/600 title, 14/400 body (line 20), two 56 buttons gap 12 | `.az-confirm` | VVMS 220:24315 |
| Menu | Background 1px gaps between white items, r8, menu shadow; item px 16 py 12, 24 icon, 14/500 OnPrimaryContainer; destructive Error | `.az-menu` | VVMS 304:4618 |
| Toast | r8, px 16 py 12, 16/600 title + 14/400 body, white on Error or Primary; 0 4 2 rgba(0,0,0,.15) | — | Help Desk 272:37375 |
| Empty state | Centred text 20/500 OnSurfaceVariant; the action lives in the bottom bar | `.az-empty` | Help Desk 1318:78949 |

---

## 8. Screen patterns

| Screen | Top → bottom | Source |
| --- | --- | --- |
| List | White block: top bar → Primary tabs or chips → search + filter. Page body: count line "Requests (6)" 14/600 → cards gap 12 → FAB | VVMS 190:17739 |
| Detail · owned record | Dark header → white sheet r24 (or flat sections) → History last → sticky decision bar when the viewer must decide | VVMS 220:23313, 370:10429 |
| Detail · request record | White header (record number; category tile + priority flag; date; requester with call/chat) → sections on Field fill split by hairlines → Activity (comments + status changes, comment box on top) → current status bar at the bottom, holding decisions | Help Desk 355:109064, 611:48888 |
| Form | Top bar (× or ←) → page body p 16 → white section cards gap 16 → sticky bar with one 56 main action | VVMS 8:6186 |
| Sheet | Scrim → sheet r16: title bar → search (lists) → options → footer | VVMS 220:24043 |
| Filter | Full screen: header with count → rail + options → footer | Training 186:8074 |
| Result (scan) | Full-bleed tint (positive OnBackground, negative Error 10%, pending #FFE86E 30%) → 96 icon + 28/600 title + ID → white sheet r24 → one sticky 56 action | VVMS 281:5763 |
| Tablet list + detail | 10-column grid: list 4, detail 6, gap 8, padding 12, white panels r12 | Training 177:6944 |

Modules open from the Antz Home grid. The old "Modules" list screen is retired.

---

## 9. Content and formats

| Thing | Format | Example |
| --- | --- | --- |
| Date | D Mon YYYY | 10 Aug 2026 |
| Date range on a card | D Mon 'YY → D Mon 'YY | 10 Aug '26 → 20 Aug '26 |
| Date + time | D Mon YYYY • h:mm AM | 22 Apr 2024 • 09:14 AM |
| Age of an item | n d, n h | 2 d |
| Wait on a strip | Since n days | Since 2 days |
| Record IDs | Prefix + number | VPS26-1029, REQ 567, TRN-0001 |
| Meta line | parts joined by " • " | REQ 567 • Robert Miller • 2 d |
| Count line | Noun (n) | Requests (6) |
| Count in a chip | Label - n | All - 22, Filter - 0 |
| Phone | +91 then number | +91 98765 43210 |
| Money | ₹ with currency_rupee_circle icon | ₹ 12,500 |
| Sample people | Plain English names | Robert Miller, Emma Stone |

**TXT-01** No sentence that explains the obvious: no page descriptions, helper captions or meta lines repeating a pill, count or label.
**TXT-02** One fact, one place. Status is said once.
**TXT-03** Sample data is real-world and domain-accurate.
**TXT-04** No colons after field labels. Identifier lines on the animal card keep their Figma form ("Ear tag: value").

---

## 10. Behaviour rules

**BHV-01** Reading and acting are separate: the read view is a clean list; changes go through one form or ⋮.
**BHV-02** No new concepts: before adding a state, status or field, name the existing mechanism (note, chat, filter, linked record) that could carry it.
**BHV-03** One form with a toggle inside, never two forms. A toggle never hides needed fields.
**BHV-04** Delete only unused records; a used record offers Deactivate; inactive stays listed, greyed.
**BHV-05** Every record keeps history (who, when, old → new). An owned record ends with a History section; a request record keeps it in Activity, together with comments.
**BHV-06** Pickers save on explicit Save; closing drops unsaved picks.
**BHV-07** Rejecting always requires a reason.
**BHV-08** Scrollbars only while scrolling.

---

## 11. Settled decisions (26 Oct 2026)

Fixed: field 56 / OutlineVariant / r8 / Surface · screen title OnSurfaceVariant · top bar hairline · dark header OnSecondaryContainer · card title OnSurfaceVariant · card r8 (12 only when asked) · selected fill OnPrimaryContainer · underline tab Primary · Secondary tab Primary pill (OnPrimaryContainer when needed) · filter 40 grey · dark green OnSurface · add addPrimary · outline OutlineVariant · disabled SurfaceVariant/Outline · confirm 56 · sheet r16, title 20 left with × · handle 48×4 only when draggable · tablet 834, gutter 20.

Context rules: page background per screen (variety on purpose) · main action green 56, navy 56 to vary · search 40 grey standard, outlined/shadow for prominence · pill always, strip for request/approval cards · Approve/Reject stacked on phone, side by side on tablet · FAB gradient on phone, blue pill on tablet with one action · pill 12 phone / 14 tablet · numbers 24–20 phone / 28 tablet · sheet footer 50/50 standard · dark-header title centred or left by screen · bottom nav as the module designer chose.

Full list with reasons: `decisions.json`.

---

## 12. Not yet designed (gaps)

An AI must not invent these silently; use the interim rule and flag it as a departure.

| Gap | Interim rule until designed |
| --- | --- |
| Field states: focus, error, disabled, read-only | Focus: 1px Outline border, Surface fill (Hospital 723:96981). Error: 1px Error border + 12/400 Error message 4 below. Disabled: SurfaceVariant fill, Outline text. Read-only: label + value as a detail row, no field |
| Loading | Keep layout; grey neutral05 blocks where text will be. No spinners over content |
| Empty state with illustration | Text only (§7) |
| Error / offline banner | Toast (Error) for failures; no persistent banner |
| Success toast | Primary fill toast, same anatomy |
| Dropdown open / date picker | Bottom sheet with option rows (§7) |
| Tablet landscape, 820-wide iPads | Not designed: ask |
| Section and enclosure cards | Not sourced. Antz library has "Egg - Enclosure details card" (2025) and older "Site Cards" (2024); get the current Figma frame before building |
| Antz Home grid (new) | Not in these files: get the Figma frame before building |
| Motion | Sheets slide up 260ms, chips/toggles 180ms, no decorative motion; respect reduced motion |
| Dark mode | Antz has none |
| Pressed and focus | Pressed: 10% black layer on buttons, 5% on tabs and chips; focus: 2px Teal ink ring, 2 outside |
| Date picker | Month grid in a bottom sheet with Cancel / Done |
| Active filter | Teal ink filter button with a Coral count badge |
| Pending-pill contrast | #E4B819 on its tint is below 3:1; pair with an icon or keep label short |

---

## 13. Before showing any screen

1. Every value traces to a token or a component here; nothing off the type ladder.
2. Put the render beside its Figma frame; build nothing the frame lacks.
3. Walk every tap, role and status; check the empty first state.
4. Strike every string that repeats what the UI already shows.
5. Critique the screenshot in plain words: what, where, fix.
