# UI Layout Specification This document defines the layout structure, responsive behavior, and component constraints for Tatlock UI. It implements the "Rooms of the Estate" metaphor from [PHILOSOPHY.md](../PHILOSOPHY.md). ## Navigation Structure The UI uses a **tabbed room navigation** in the header rather than a traditional sidebar. Each "room" represents a distinct usage context, reducing cognitive clutter. | Room | Purpose | Chat Dock Default | |------|---------|-------------------| | **Front Hall** | Dashboard - estate overview, quick access, activity | Expanded | | **Control Room** | Infrastructure - containers, stacks, monitoring | Collapsed | | **Parlor** | Housekeeping - home automation, devices, scenes | Collapsed | | **Library** | Knowledge - docs, notes, bookmarks (future) | Collapsed | **Hidden for now:** - **Study** - Secretarial tasks (email, calendaring) - future implementation --- ## Layout Structure ``` ┌─────────────────────────────────────────────────────────────────────────────┐ │ HEADER (intrinsic height) │ │ [Logo] [═══════ Room Tabs (scrollable) ═══════] [Notifications] [Profile] │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ │ ┌─────────────────────────────────────────────────┐ ┌───────────────────┐ │ │ │ │ │ │ │ │ │ MAIN CONTENT │ │ CHAT DOCK │ │ │ │ flex: 1 │ │ flex: 0 │ │ │ │ │ │ │ │ │ │ ┌─────────────┐ ┌────────────────────────────┐ │ │ Tatlock chat │ │ │ │ │ CONTEXT │ │ PRIMARY │ │ │ assistant, │ │ │ │ │ SIDEBAR │ │ CONTENT │ │ │ persistent │ │ │ │ │ │ │ │ │ │ across rooms │ │ │ │ │ flex: 0 │ │ flex: 1 │ │ │ │ │ │ │ │ intrinsic │ │ │ │ │ │ │ │ │ └─────────────┘ └────────────────────────────┘ │ │ │ │ │ │ │ │ │ │ │ └─────────────────────────────────────────────────┘ └───────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────────────────┘ ``` ### Component Roles | Component | Flex | Description | |-----------|------|-------------| | **Header** | intrinsic | Logo, room tabs, action icons | | **Main Content** | `flex: 1` | Fills remaining horizontal space | | **Context Sidebar** | `flex: 0`, intrinsic | Room-specific navigation (Control Room, Parlor) | | **Primary Content** | `flex: 1` | Room's main working area | | **Chat Dock** | `flex: 0`, intrinsic | Tatlock assistant, collapsible | --- ## Responsive Breakpoints ### Wide (>= 1200px) ``` ┌────────────────────────────────────────────────────────┬────────────────────┐ │ [Sidebar] [══════════ Content ══════════] │ Chat (expanded) │ └────────────────────────────────────────────────────────┴────────────────────┘ ``` - Chat dock expanded by default on Front Hall - Context sidebar visible with labels - Full data grid columns ### Medium (>= 800px, < 1200px) ``` ┌────────────────────────────────────────────────────────────────────────┬────┐ │ [Sidebar] [══════════════════ Content ══════════════════] │ 💬 │ └────────────────────────────────────────────────────────────────────────┴────┘ ``` - Chat dock collapsed to icon rail - Click to expand as overlay - Context sidebar still visible ### Compact (>= 600px, < 800px) ``` ┌────────────────────────────────────────────────────────────────────────┬────┐ │ [≡] [════════════════════ Content ════════════════════] │ 💬 │ └────────────────────────────────────────────────────────────────────────┴────┘ ``` - Context sidebar becomes drawer (hamburger menu) - Chat dock collapsed - Reduced data grid columns ### Mobile (< 600px) ``` ┌────────────────────────────────────────────────────────────────────────┐ │ [≡] [Tabs scroll horizontally] [💬] │ ├────────────────────────────────────────────────────────────────────────┤ │ │ │ [══════════════════════ Content ══════════════════════] │ │ │ └────────────────────────────────────────────────────────────────────────┘ ``` - Single column layout - Room tabs scroll horizontally - Chat opens as bottom sheet - Context sidebar as full-screen drawer --- ## Component Constraints | Component | Min Width | Max Width | Collapse Behavior | |-----------|-----------|-----------|-------------------| | Chat Dock (expanded) | 280px | 33vw | Collapses to icon rail | | Chat Dock (collapsed) | 48px | 48px | - | | Context Sidebar | 200px | - | Collapses to 56px icon rail, then drawer | | Stat Card | 180px | 1fr | Grid reflows | | Service Card | 120px | 1fr | Grid reflows | | Data Grid | 400px | - | Horizontal scroll if needed | --- ## Room Wireframes ### Front Hall (Dashboard) Primary landing page. Chat dock expanded by default. ``` ┌─────────────────────────────────────────────────────────────┬─────────────────┐ │ │ │ │ STAT CARDS (auto-fit grid, min 180px) │ TATLOCK CHAT │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌────────┐ │ │ │ │ CPU │ │ Memory │ │ Disk │ │Containe│ │ [conversation] │ │ │ 45% │ │ 62% │ │ 78% │ │ 34/40 │ │ │ │ │ ████████░░░ │ │ ██████████░ │ │ ███████████ │ │ ██████ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ └────────┘ │ │ │ │ │ │ QUICK ACCESS (auto-fill grid, min 120px) │ │ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │ │ │ 🎬 │ │ 🔍 │ │ 📚 │ │ 🎮 │ │ 🌐 │ │ │ │ │Jellyfin│ │SearXNG │ │ Wiki │ │ AMP │ │Requests│ │ │ │ │● Online│ │● Online│ │● Online│ │● Online│ │● Online│ │ │ │ └────────┘ └────────┘ └────────┘ └────────┘ └────────┘ │ │ │ │ │ │ RECENT ACTIVITY │ [input field] │ │ ┌────────────────────────────────────────────────────────┐ │ │ │ │ 📦 Container 'ollama' restarted 15 min ago │ │ │ │ │ 🏠 Living room set to evening mode 1 hr ago │ │ │ │ │ 🔄 System backup completed 2 hrs ago │ │ │ │ └────────────────────────────────────────────────────────┘ │ │ │ │ │ └─────────────────────────────────────────────────────────────┴─────────────────┘ ``` **Components:** - Stat Cards: CPU, Memory, Disk, Containers - Quick Access: Service cards grid (external links) - Recent Activity: Timeline of system events --- ### Control Room (Infrastructure) Context sidebar with section navigation. Chat collapsed. ``` ┌───────────────┬───────────────────────────────────────────────────────┬──────┐ │ │ │ │ │ SECTIONS │ CONTAINERS [Search] [+ New] │ 💬 │ │ │ ─────────────────────────────────────────────────── │ │ │ ▸ Containers │ ☑ NAME STATUS CPU MEM IMAGE ⋮ │ │ │ Stacks │ ☐ jellyfin ● Run 2.3% 1.2GB latest ⋮ │ │ │ Networks │ ☐ ollama ● Run 45% 8.0GB 0.1.32 ⋮ │ │ │ Volumes │ ☐ postgres ● Run 1.1% 512MB 16-alp ⋮ │ │ │ Images │ ☐ redis ● Run 0.2% 128MB 7-alp ⋮ │ │ │ │ ☐ authentik ○ Stop - - 2024.2 ⋮ │ │ │ ──────────── │ ─────────────────────────────────────────────────── │ │ │ Netdata ↗ │ Showing 5 of 40 < 1 2 3 4 5 > │ │ │ Portainer↗ │ │ │ │ NPM ↗ │ │ │ │ │ │ │ └───────────────┴───────────────────────────────────────────────────────┴──────┘ ``` **Components:** - Context Sidebar: Section nav + external links - DataGrid: Container list with bulk actions - Detail Panel: Opens on row selection (replaces grid or slides in) --- ### Parlor (Housekeeping) Context sidebar with areas and scenes. Chat collapsed. ``` ┌───────────────┬───────────────────────────────────────────────────────┬──────┐ │ │ │ │ │ AREAS │ LIVING ROOM │ 💬 │ │ │ ─────────────────────────────────────────────────── │ │ │ ▸ Living Rm │ │ │ │ Bedroom │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Kitchen │ │ 💡 │ │ 📺 │ │ 🌡️ │ │ 🔌 │ │ │ │ Office │ │ Ceiling │ │ Samsung │ │ Thermo │ │ Outlet 1 │ │ │ │ Garage │ │ 75% │ │ OFF │ │ 72°F │ │ ON │ │ │ │ │ │ ○─────● │ │ [ ] │ │ [-] [+] │ │ [ ] │ │ │ │ ──────────── │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ SCENES │ │ │ │ 🌅 Morning │ SCENES │ │ │ ☀️ Day │ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │ │ │ 🌆 Evening │ │ 🌅 │ │ ☀️ │ │ 🌆 │ │ 🌙 │ │ 🎬 │ │ │ │ 🌙 Night │ │ Morn │ │ Day │ │ Eve │ │Night │ │Movie │ │ │ │ │ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ │ │ └───────────────┴───────────────────────────────────────────────────────┴──────┘ ``` **Components:** - Context Sidebar: Area list + scene shortcuts - Device Grid: Control tiles for current area - Scene Bar: Quick activation buttons --- ## Grid Specifications ### Stat Cards ```css grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1rem; ``` | Viewport Width | Cards per Row | |----------------|---------------| | >= 900px | 4 | | >= 720px | 3 | | >= 540px | 2 | | < 540px | 1 | ### Service Cards ```css grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: 0.75rem; ``` Reflows naturally based on available width. --- ## Chat Dock Behavior The Tatlock chat assistant is **omnipresent** - accessible from any room. | State | Width | Trigger | |-------|-------|---------| | Expanded | intrinsic (min 280px, max 33vw) | Default on Front Hall, click icon elsewhere | | Collapsed | 48px (icon rail) | Default on other rooms, viewport < 1200px | | Overlay | 90vw or 400px max | Expanded on medium viewports | | Bottom Sheet | 100vw, 60vh max | Mobile viewports | | **Fullscreen** | 100vw, 100vh | User-triggered overlay (future) | **Persistence:** Conversation state persists across room navigation. **Future:** Fullscreen mode provides an immersive chat experience as a modal overlay, independent of the current room. --- ## Flutter Implementation Notes ### Recommended Widgets | Concept | Flutter Widget | |---------|----------------| | Breakpoint detection | `LayoutBuilder`, `MediaQuery` | | Main layout | `Row` with `Expanded` and `SizedBox` | | Collapsible dock | `AnimatedContainer` or `AnimatedSize` | | Grid layouts | `GridView.builder` with `SliverGridDelegateWithMaxCrossAxisExtent` | | Drawer fallback | `Scaffold.drawer` or custom `Drawer` | | Bottom sheet chat | `showModalBottomSheet` or `DraggableScrollableSheet` | ### Breakpoint Constants ```dart abstract class Breakpoints { static const double mobile = 600; static const double compact = 800; static const double medium = 1200; } ``` ### Layout Builder Pattern ```dart LayoutBuilder( builder: (context, constraints) { if (constraints.maxWidth >= Breakpoints.medium) { return WideLayout(...); } else if (constraints.maxWidth >= Breakpoints.compact) { return MediumLayout(...); } else { return CompactLayout(...); } }, ) ``` --- ## Related Documents - [PHILOSOPHY.md](../PHILOSOPHY.md) - "Rooms of the Estate" metaphor - [ARCHITECTURE.md](./ARCHITECTURE.md) - Clean Architecture patterns - [THEMING.md](./THEMING.md) - Material3 color scheme - [DATAGRID.md](./DATAGRID.md) - DataGrid component API