# CannaManage — Wireframes & UI Mockups

**Phase 4a | Document 6 of 7**  
**Date:** 2026-04-06  
**Stack:** Spring Boot 3.x · PrimeFaces JSF · PostgreSQL

---

## Table of Contents

1. [Design System Overview](#1-design-system-overview)
2. [Admin Portal Screens](#2-admin-portal-screens)
3. [Member Portal Screens](#3-member-portal-screens)
4. [Navigation & Information Architecture](#4-navigation--information-architecture)
5. [Responsive Design Notes](#5-responsive-design-notes)
6. [Accessibility](#6-accessibility)

---

## 1. Design System Overview

### 1.1 Color Palette

| Token | Hex | Usage |
|---|---|---|
| `--color-primary` | `#2D5016` | Sidebar background, primary buttons, active nav items |
| `--color-primary-medium` | `#4A7C28` | Hover states, section headers, badge outlines |
| `--color-accent` | `#8BC34A` | Highlights, progress bars filled, success indicators |
| `--color-bg` | `#F5F5F5` | Page background, card backgrounds |
| `--color-text` | `#1A1A1A` | Body text, table cell content |
| `--color-warning` | `#FF6B35` | Quota >80%, low stock, warnings |
| `--color-error` | `#D32F2F` | Quota exceeded, recalled batches, destructive actions |
| `--color-white` | `#FFFFFF` | Sidebar text, button labels on dark bg, card surfaces |

### 1.2 Typography

| Element | Font | Size | Weight |
|---|---|---|---|
| H1 — Page title | Inter | 24px | 600 |
| H2 — Section heading | Inter | 18px | 600 |
| H3 — Card title | Inter | 14px | 600 |
| Body / table rows | Inter | 14px | 400 |
| Caption / label | Inter | 12px | 400 |
| Mono (codes, IDs) | JetBrains Mono | 13px | 400 |

### 1.3 Component Library

All UI components come from **PrimeFaces 13.x** (JSF-based). No external React/Angular dependencies in MVP.

| Component | Usage |
|---|---|
| `p:panel` | Section containers, card wrappers |
| `p:dataTable` with `p:column` | Tabular data: distributions, members, batches |
| `p:paginator` | Pagination on all tables |
| `p:inputText` | Single-line text fields |
| `p:inputNumber` | Weight inputs (gram precision) |
| `p:selectOneMenu` | Dropdown selects (member, strain, batch) |
| `p:calendar` | Date range pickers for reports |
| `p:progressBar` | Quota consumption display |
| `p:commandButton` | Primary and secondary actions |
| `p:confirmDialog` | Dangerous actions (recall, delete) |
| `p:messages` / `p:message` | Inline validation errors |
| `p:badge` | Status indicators (AVAILABLE, LOW, RECALLED) |
| `p:sidebar` | Mobile nav drawer (member portal) |
| `p:dialog` | Modal overlays |

### 1.4 Layout Grid

```
┌────────────────────────────────────────────────────┐
│  TOP NAVBAR (56px)  club name · avatar · logout    │
├──────────────┬─────────────────────────────────────┤
│              │                                     │
│   SIDEBAR    │         MAIN CONTENT                │
│   (240px)    │         (fluid, min 784px)          │
│   fixed      │                                     │
│              │                                     │
└──────────────┴─────────────────────────────────────┘
```

- **Sidebar:** fixed left, `#2D5016` background, white nav labels with `#8BC34A` icons
- **Top Navbar:** `#FFFFFF` with bottom border `#E0E0E0`, breadcrumb left, user controls right
- **Main Content:** `#F5F5F5` background, 24px padding, max content width 1200px centered

---

## 2. Admin Portal Screens

### Screen 1 — Admin Dashboard

![Admin Dashboard](images/mockup-admin-dashboard.png)

#### ASCII Wireframe

```
┌─────────────────────────────────────────────────────────────────────┐
│  🌿 CannaManage          Grüne Oase Berlin e.V.   👤 Max M.  [⏻]   │
├────────────┬────────────────────────────────────────────────────────┤
│            │  Dashboard                           🗓 April 2026     │
│  📊 Dashboard◄│                                                      │
│            │  ┌──────────────┐ ┌──────────────┐ ┌───────────────┐  │
│  👥 Members│  │ Total Members│ │  Distributions│ │ Stock Available│ │
│            │  │              │ │  This Month   │ │               │  │
│  📋 Distrib│  │     142      │ │      87       │ │   3,240 g     │  │
│            │  │  ▲ +3 MoM   │ │  ▲ +12 MoM   │ │  ▼ -800g MoM │  │
│  📦 Stock  │  └──────────────┘ └──────────────┘ └───────────────┘  │
│            │                                                         │
│  📄 Reports│  Recent Distributions                    [+ New Entry] │
│            │  ┌─────────────────────────────────────────────────┐   │
│  ✅ Complian│  │ Member      │ Strain      │  Qty  │ Date  │ ✓  │   │
│            │  ├─────────────┼─────────────┼───────┼───────┼────┤   │
│  ⚙ Settings│  │ Müller, A.  │ OG Kush B12 │  5.0g │ 06.04 │ ✓  │   │
│            │  │ Schmidt, K. │ Amnesia H09 │  3.5g │ 06.04 │ ✓  │   │
│            │  │ Weber, T.   │ OG Kush B12 │  7.0g │ 05.04 │ ✓  │   │
│            │  │ …           │             │       │       │    │   │
└────────────┴──┴─────────────────────────────────────────────────────┘
```

#### Components & Behavior

| Component | PrimeFaces | Behavior |
|---|---|---|
| KPI Cards | `p:panel` with custom CSS | Auto-refreshed via `@poll` every 60s |
| Recent Distributions table | `p:dataTable` (5 rows, no paginator) | Row click → navigate to distribution detail |
| Member column link | `p:commandLink` | Navigate to `/admin/members/{id}` |
| `+ New Entry` button | `p:commandButton` style="primary" | Navigate to `/admin/distributions/new` |
| Trend indicators | Custom CSS `<span>` | Green ▲ / Red ▼ with delta value |

---

### Screen 2 — Distribution Recording Form

![Distribution Form](images/mockup-distribution-form.png)

#### ASCII Wireframe

```
┌─────────────────────────────────────────────────────────────────────┐
│  🌿 CannaManage          Grüne Oase Berlin e.V.   👤 Max M.  [⏻]   │
├────────────┬────────────────────────────────────────────────────────┤
│            │  Distributions › New Distribution                      │
│  📊 Dashbrd│                                                         │
│            │  ┌──────────────────────────────────────────────────┐  │
│  👥 Members│  │  Member *                                         │  │
│            │  │  ┌──────────────────────────────────────────┐    │  │
│  📋 Distrib◄│  │  │  🔍 Search by name or member no.         │    │  │
│            │  │  └──────────────────────────────────────────┘    │  │
│  📦 Stock  │  │                                                    │  │
│            │  │  Strain / Batch *                                 │  │
│  📄 Reports│  │  ┌──────────────────────────────────────────┐    │  │
│            │  │  │  Select available batch           ▼      │    │  │
│  ✅ Complian│  │  └──────────────────────────────────────────┘    │  │
│            │  │                                                    │  │
│  ⚙ Settings│  │  Weight (grams) *                                 │  │
│            │  │  ┌──────────┐                                     │  │
│            │  │  │   0.0 g  │  ← p:inputNumber min=0.1 max=25    │  │
│            │  │  └──────────┘                                     │  │
│            │  │                                                    │  │
│            │  │  Monthly Quota — Müller, Anna                     │  │
│            │  │  ████████████░░░░░░░░  32.5g / 50g  65%          │  │
│            │  │  [████████████████░░░] <- p:progressBar           │  │
│            │  │                                                    │  │
│            │  │  [    Record Distribution    ]  [Cancel]          │  │
│            │  └──────────────────────────────────────────────────┘  │
└────────────┴────────────────────────────────────────────────────────┘
```

#### Compliance UX — Real-Time Quota Indicator

The quota progress bar updates live as the weight field changes (via `f:ajax event="keyup"`):

| Quota Used After Distribution | Bar Color | Submit Button | Message |
|---|---|---|---|
| 0–79% | `#8BC34A` (green) | Enabled | — |
| 80–99% | `#FF6B35` (orange) | Enabled | "⚠ Approaching monthly limit" |
| 100% | `#D32F2F` (red) | **Disabled** | "🚫 Monthly limit reached (50g)" |
| Over-21 member, >30g monthly | `#D32F2F` (red) | **Disabled** | "🚫 Under-21 limit reached (30g)" |

#### Components & Behavior

| Component | PrimeFaces | Behavior |
|---|---|---|
| Member search | `p:selectOneMenu` with `p:ajax` filter | Filters on type, shows name + member no. |
| Strain/Batch dropdown | `p:selectOneMenu` | Populated after member selection; shows only `AVAILABLE` batches |
| Weight input | `p:inputNumber` min=`0.1` max=`25.0` step=`0.1` | Triggers quota recalculation on blur |
| Quota bar | `p:progressBar` with dynamic `value` | Color class applied via `styleClass` computed in backing bean |
| Submit | `p:commandButton` | Disabled via `disabled="#{bean.quotaExceeded}"` |
| Cancel | `p:link` | Returns to distribution log without saving |

---

### Screen 3 — Stock Management

![Stock Management](images/mockup-stock-management.png)

#### ASCII Wireframe

```
┌─────────────────────────────────────────────────────────────────────┐
│  🌿 CannaManage          Grüne Oase Berlin e.V.   👤 Max M.  [⏻]   │
├────────────┬────────────────────────────────────────────────────────┤
│            │  Stock Management                    [+ Add Batch]     │
│  📊 Dashbrd│                                                         │
│            │  ┌──────────────────────┐  ┌────────────────────┐     │
│  👥 Members│  │ 🔍 Filter by strain   │  │ Status: All     ▼  │     │
│            │  └──────────────────────┘  └────────────────────┘     │
│  📋 Distrib│                                                         │
│            │  ┌───────────────────────────────────────────────────┐ │
│  📦 Stock ◄│  │ Strain       │Batch│THC% │CBD%│  Qty  │Status│Act │ │
│            │  ├──────────────┼─────┼─────┼────┼───────┼──────┼────┤ │
│  📄 Reports│  │ OG Kush      │B-12 │ 19% │ 1% │ 850g  │  ●   │[R] │ │
│            │  │ Amnesia Haze │H-09 │ 22% │<1% │  72g  │  ⚠   │[R] │ │
│  ✅ Complian│  │ Blue Dream   │D-05 │ 17% │ 2% │    0g │  —   │[R] │ │
│            │  │ Hindu Kush   │K-21 │  8% │15% │ 340g  │  ✓   │[R] │ │
│  ⚙ Settings│  │ AK-47 #4    │A-03 │ 20% │ 1% │  RECALLED  │ ⛔ │[R] │ │
│            │  └───────────────────────────────────────────────────┘ │
│            │  [◄ 1 2 3 … ►]                        Showing 1-10/42 │
└────────────┴────────────────────────────────────────────────────────┘
```

#### Status Badges

| Badge | Color | Icon | Condition |
|---|---|---|---|
| `AVAILABLE` | `#4A7C28` bg | ✓ checkmark | `qty > 100g` and not recalled |
| `LOW` | `#FF6B35` bg | ⚠ warning | `0 < qty ≤ 100g` |
| `EXHAUSTED` | `#9E9E9E` bg | — dash | `qty = 0` |
| `RECALLED` | `#D32F2F` bg | ⛔ stop | `recall_date IS NOT NULL` |

#### Components & Behavior

| Component | PrimeFaces | Behavior |
|---|---|---|
| Strain filter | `p:inputText` with `filterBy` | Filters table client-side on keyup |
| Status filter | `p:selectOneMenu` | Filters table rows by status value |
| Batch table | `p:dataTable` lazy=`true` | Server-side pagination, 10 rows/page |
| Status badge | Custom CSS `<span class="badge badge-{status}">` | Icon + text label (not color alone) |
| Recall button | `p:commandButton` styleClass=`p-button-danger` | Opens `p:confirmDialog` before executing |
| Confirm dialog | `p:confirmDialog` | "Recall batch B-12 (OG Kush, 850g)? This cannot be undone." |
| Add Batch | `p:commandButton` | Opens `p:dialog` with batch entry form |

---

### Screen 4 — Compliance Report Generation

![Compliance Report](images/mockup-compliance-report.png)

#### ASCII Wireframe

```
┌─────────────────────────────────────────────────────────────────────┐
│  🌿 CannaManage          Grüne Oase Berlin e.V.   👤 Max M.  [⏻]   │
├────────────┬────────────────────────────────────────────────────────┤
│            │  Reports › Monthly Compliance Report                   │
│  📊 Dashbrd│                                                         │
│            │  ┌─────────────────────────────────────────────────┐  │
│  👥 Members│  │  Reporting Period                                │  │
│            │  │  Month: [ March ▼ ]   Year: [ 2026 ▼ ]          │  │
│  📋 Distrib│  │                         [ Generate Report ]      │  │
│            │  └─────────────────────────────────────────────────┘  │
│  📦 Stock  │                                                         │
│            │  ┌─────────────────────────────────────────────────┐  │
│  📄 Reports◄│  │  PDF PREVIEW                                    │  │
│            │  │  ┌─────────────────────────────────────────┐    │  │
│  ✅ Complian│  │  │ 🌿 CannaManage — Monthly Report Mar 2026 │    │  │
│            │  │  │ Club: Grüne Oase Berlin e.V.            │    │  │
│  ⚙ Settings│  │  │ ─────────────────────────────────────── │    │  │
│            │  │  │ Total Members:              142          │    │  │
│            │  │  │ Active Members (distributed): 87        │    │  │
│            │  │  │ Total Distributed:         435.5g       │    │  │
│            │  │  └─────────────────────────────────────────┘    │  │
│            │  │                                                    │  │
│            │  │  [⬇ Download PDF]   [⬇ Download CSV]             │  │
│            │  └─────────────────────────────────────────────────┘  │
│            │                                                         │
│            │  Summary Table                                         │
│            │  ┌────────────────────────────────────────────────┐   │
│            │  │ Metric               │ Value     │ Limit        │   │
│            │  ├──────────────────────┼───────────┼─────────────┤   │
│            │  │ Members >50g/month   │     0     │ Must be 0   │   │
│            │  │ Members >30g (U21)   │     0     │ Must be 0   │   │
│            │  │ Recalled Batches     │     1     │ — (info)    │   │
│            │  │ Avg grams / member   │   5.0g    │ —           │   │
│            │  └────────────────────────────────────────────────┘   │
└────────────┴────────────────────────────────────────────────────────┘
```

#### Components & Behavior

| Component | PrimeFaces | Behavior |
|---|---|---|
| Month selector | `p:selectOneMenu` | Months Jan–Dec |
| Year selector | `p:selectOneMenu` | Current year ± 2 |
| Generate button | `p:commandButton` | Calls report service; shows spinner; renders PDF thumbnail |
| PDF preview | `<iframe>` embedding `/report/preview?month=3&year=2026` | Generated by iText 7 in `cannamanage-report` module |
| Download PDF | `p:commandButton` | Streams PDF response from REST endpoint |
| Download CSV | `p:commandButton` | Streams CSV response (member-level data) |
| Summary table | `p:dataTable` | Computed compliance metrics; zero violations = green row |

---

## 3. Member Portal Screens

### Screen 5 — Member Dashboard / Quota View

![Member Quota](images/mockup-member-quota.png)

#### ASCII Wireframe

```
┌────────────────────────────────────────────────────┐
│  🌿 CannaManage           Anna Müller  #M-0042     │
│  ──────────────────────────────────────────────    │
│                                                    │
│           Monthly Quota Remaining                  │
│                                                    │
│               ╭───────────────╮                    │
│               │               │                    │
│               │   17.5 g      │                    │
│               │  remaining    │                    │
│               │               │                    │
│               │  of 50g/month │                    │
│               ╰───────────────╯                    │
│          ▓▓▓▓▓▓▓▓▓▓▓░░░░░░░ 65% used              │
│                                                    │
│  Distribution History                              │
│  ┌────────────────────────────────────────────┐   │
│  │ Date       │ Strain       │ Quantity       │   │
│  ├────────────┼──────────────┼────────────────┤   │
│  │ 06.04.2026 │ OG Kush      │ 5.0g           │   │
│  │ 02.04.2026 │ Amnesia Haze │ 12.5g          │   │
│  │ 28.03.2026 │ OG Kush      │ 15.0g          │   │
│  └────────────┴──────────────┴────────────────┘   │
│                                                    │
│  Available Strains                                 │
│  ┌────────────────────────────────────────────┐   │
│  │ Strain       │ Availability               │   │
│  ├──────────────┼─────────────────────────────┤   │
│  │ OG Kush      │ ● Available                │   │
│  │ Amnesia Haze │ ⚠ Limited                  │   │
│  │ Hindu Kush   │ ● Available                │   │
│  └────────────────────────────────────────────┘   │
│                                                    │
└────────────────────────────────────────────────────┘
```

#### Compliance Note — Available Strains Display

Per CanG §§6–7, members may NOT see specific batch quantities or total stock levels. The **Available Strains** table shows only:
- Strain name
- Availability status (Available / Limited / Unavailable)

Quantities, batch codes, and THC/CBD percentages are **not exposed** in the member portal.

#### Components & Behavior

| Component | PrimeFaces | Behavior |
|---|---|---|
| Quota circle | Custom CSS radial progress (`conic-gradient`) | Computed from monthly total; color matches threshold rules |
| Quota bar | `p:progressBar` | Same color logic as admin distribution form |
| History table | `p:dataTable` | Last 10 distributions; sorted newest first; no pagination in MVP |
| Strains table | `p:dataTable` | `status` column: text + icon only, no quantities |

---

### Screen 6 — Member Login

> *No mockup image — ASCII wireframe only.*

#### ASCII Wireframe

```
┌──────────────────────────────────────────┐
│                                          │
│            🌿 CannaManage                │
│                                          │
│   ┌──────────────────────────────────┐   │
│   │  E-Mail Address                  │   │
│   │  ┌────────────────────────────┐  │   │
│   │  │ you@example.com            │  │   │
│   │  └────────────────────────────┘  │   │
│   │                                  │   │
│   │  Password                        │   │
│   │  ┌────────────────────────────┐  │   │
│   │  │ ••••••••••••               │  │   │
│   │  └────────────────────────────┘  │   │
│   │                                  │   │
│   │  [ ████ Log In ████████████ ]   │   │
│   └──────────────────────────────────┘   │
│                                          │
│   Problems logging in?                   │
│   Contact your club administrator.       │
│                                          │
└──────────────────────────────────────────┘
```

#### Design Decisions

- **No self-registration link** — member accounts are created exclusively by admins via the admin portal. The login page has no "Create account" or "Sign up" flow.
- **No forgot-password link** — password resets are initiated by the club admin only. The login page directs users to contact their admin, avoiding email-based reset flows that would require verified email infrastructure in MVP.
- **No social login** — DSGVO compliance and club accountability require traceable credential management.
- **Form submission:** POST to `/login` (Spring Security form login), redirect to `/member/dashboard` on success.

#### Components & Behavior

| Component | PrimeFaces | Behavior |
|---|---|---|
| Email field | `p:inputText` with `required="true"` | Bean Validation `@Email` |
| Password field | `p:password` feedback=`false` | No strength meter on login |
| Login button | `p:commandButton` | Submit form; shows `p:messages` on failure |
| Error message | `p:messages` | "Invalid email or password." (never specific about which field failed) |

---

## 4. Navigation & Information Architecture

```mermaid
graph TD
    Root["CannaManage Root"]
    Root --> AdminPortal["Admin Portal /admin/"]
    Root --> MemberPortal["Member Portal /member/"]

    AdminPortal --> AdminDash["Dashboard (default)"]
    AdminPortal --> Members["Members"]
    Members --> MemberList["Member List"]
    Members --> MemberDetail["Member Detail"]
    AdminPortal --> Distributions["Distributions"]
    Distributions --> DistLog["Distribution Log"]
    Distributions --> NewDist["New Distribution"]
    AdminPortal --> Stock["Stock"]
    Stock --> Strains["Strains"]
    Stock --> Batches["Batches"]
    AdminPortal --> Reports["Reports"]
    Reports --> MonthlyReport["Monthly Compliance"]
    Reports --> MemberExport["Member Export"]
    Reports --> RecallReport["Batch Recall Report"]
    AdminPortal --> Compliance["Compliance"]
    Compliance --> PreventionOfficer["Prevention Officer Info"]
    AdminPortal --> Settings["Settings"]
    Settings --> ClubProfile["Club Profile"]

    MemberPortal --> MemberDash["Dashboard / Quota"]
    MemberPortal --> DistHistory["Distribution History"]
    MemberPortal --> StockAvail["Stock Availability"]
```

### URL Structure

| Path | Description | Role |
|---|---|---|
| `/login` | Login page | Public |
| `/admin/dashboard` | Admin home | `ROLE_ADMIN` |
| `/admin/members` | Member list | `ROLE_ADMIN` |
| `/admin/members/{id}` | Member detail | `ROLE_ADMIN` |
| `/admin/distributions` | Distribution log | `ROLE_ADMIN` |
| `/admin/distributions/new` | New distribution form | `ROLE_ADMIN` |
| `/admin/stock/strains` | Strain catalog | `ROLE_ADMIN` |
| `/admin/stock/batches` | Batch management | `ROLE_ADMIN` |
| `/admin/reports/monthly` | Compliance reports | `ROLE_ADMIN` |
| `/admin/reports/members` | Member data export | `ROLE_ADMIN` |
| `/admin/reports/recall` | Recall report | `ROLE_ADMIN` |
| `/admin/compliance` | Prevention officer | `ROLE_ADMIN` |
| `/admin/settings` | Club settings | `ROLE_ADMIN` |
| `/member/dashboard` | Member quota view | `ROLE_MEMBER` |
| `/member/distributions` | Personal history | `ROLE_MEMBER` |
| `/member/stock` | Strain availability | `ROLE_MEMBER` |

---

## 5. Responsive Design Notes

### MVP (v1) — Desktop-First

Target viewport: **1024px+**. PrimeFaces responsive grid (`p:panelGrid` with responsive columns, `ui-g-12 ui-md-6 ui-lg-4`) handles most layout adaptation down to tablet without custom media queries.

| Breakpoint | Behavior |
|---|---|
| `≥ 1280px` | Full layout — sidebar + content side-by-side |
| `1024–1279px` | Sidebar collapses to icon-only (60px); tooltips on hover |
| `768–1023px` | Sidebar hidden; hamburger menu in top navbar |
| `< 768px` | Admin portal degraded (tables scroll horizontally) |

### Member Portal — Mobile-First from Day One

Members will typically check quota status on their phone. The member portal is designed mobile-first regardless of MVP/v2 timeline.

| Breakpoint | Behavior |
|---|---|
| `≥ 1024px` | Two-column layout: quota circle left, history right |
| `768–1023px` | Single-column, full-width cards |
| `375–767px` | Single-column, compact quota ring, condensed table |
| `< 375px` | Minimum supported; no horizontal scroll |

### v2 Roadmap

- PWA manifest + service worker (offline quota display)
- 768px and 375px explicit breakpoints with design tokens
- Touch-friendly `p:sidebar` for mobile member nav
- Push notifications for low quota warnings

---

## 6. Accessibility

CannaManage targets **WCAG 2.1 AA** compliance across both portals.

### Keyboard Navigation

| Element | Keyboard Behavior |
|---|---|
| Navigation sidebar | Tab navigates items; Enter activates |
| Data tables | Tab to table; arrow keys for row navigation |
| Dropdown menus | Enter/Space to open; arrow keys to navigate; Escape to close |
| Modal dialogs | Focus trapped inside; Escape to close; first focusable element receives focus on open |
| Confirmation dialogs | Tab between Confirm and Cancel; Enter on focused button |

### Screen Reader Support

- All `p:inputText` / `p:inputNumber` fields have `<label>` with `for` attribute
- `aria-label` set on icon-only buttons (e.g., recall action column)
- `aria-live="polite"` region on quota bar — announces percentage changes
- `aria-describedby` links compliance warning messages to the weight input
- PrimeFaces generates `role="grid"` and `aria-rowcount` on all data tables

### Color Independence

Status badges must never rely on color alone:

| Status | Color | Icon | Text label |
|---|---|---|---|
| AVAILABLE | Green | ✓ | "Available" |
| LOW | Orange | ⚠ | "Low Stock" |
| RECALLED | Red | ⛔ | "Recalled" |
| EXHAUSTED | Gray | — | "Exhausted" |

Quota progress bar additionally shows numeric percentage text alongside color change.

### Contrast Ratios

| Foreground | Background | Ratio | AA pass |
|---|---|---|---|
| `#FFFFFF` | `#2D5016` | 9.1:1 | ✅ |
| `#1A1A1A` | `#F5F5F5` | 16.0:1 | ✅ |
| `#1A1A1A` | `#FFFFFF` | 19.0:1 | ✅ |
| `#FFFFFF` | `#D32F2F` | 5.1:1 | ✅ |
| `#FFFFFF` | `#FF6B35` | 3.1:1 | ⚠ verify at large text only |

---

*Next: [07-CODING-STANDARDS.md](07-CODING-STANDARDS.md)*
