Desk Companion — Kiosk Dashboard Design¶
Date: 2026-06-16 Status: Approved (brainstorm) — ready for implementation plan Target device: iPad (11th gen, A16, 2025) — model A3354 / MD4Q4LL/A. 10.9″ Liquid Retina, 2360×1640 px (≈1180×820 pt @2x), landscape, on a fixed desk arm, charging, kiosk mode during the workday.
1. Purpose¶
A brand-new, standalone Home Assistant dashboard — not a tab on the existing Home Command Dashboard — purpose-built for one always-on screen at Louis's desk. It is a glance-first "Desk Companion": you mostly look at it, with media playback as the one routinely-interactive element. It must look premium ("Midnight Glass") and be readable at a glance from a seated desk distance.
Decisions locked during brainstorm (visual companion)¶
| Decision | Choice |
|---|---|
| Primary job | Desk Companion (personal + house blend, glance-first) |
| Modules | Time+Weather · Office Air · Energy Now · Now Playing · House at a Glance |
| Aesthetic | Midnight Glass (frosted glass on deep navy, gradient accents, thin type) |
| Layout | Layout B — full-width hero band / three equal columns / thin house-status strip |
| Kiosk method | HA Companion iOS app + Guided Access |
| Screen hours | Always-on while charging (LCD, no burn-in); iOS Night Shift at night |
Modules deliberately excluded (YAGNI): focus/pomodoro timer, a full internet panel (internet appears only as one chip), quick controls, calendar agenda.
2. Architecture¶
2.1 Dashboard delivery — YAML mode¶
A new YAML-mode dashboard, not a storage-mode one.
- File:
desk_companion.yaml(repo root, alongside other deployable config). - Registration: in
configuration.yaml: - Why YAML, not storage: this dashboard is code-built and heavily templated; Louis will never edit it in the UI. A version-controlled YAML file is the right home and avoids the fragile storage
stop→swap→startdeploy dance used for the main dashboard. The existinglovelace/home_command_dashboard.jsonstays storage-mode (the user does edit that one in the UI). - URL:
/desk-companion(or/desk-companion/0for the single view).
2.2 Deploy via CI¶
- Add
desk_companion.yamlto the deployable-config list in.github/workflows/ci.yml(deploy-hajob scps it to/config/). - Registering a new dashboard in
configuration.yamlrequires a full HA restart (not just a Lovelace reload), so the change set (configuration.yaml + desk_companion.yaml) deploys as a config change → CIha core restartwith health-check wait. - After registration, subsequent edits to
desk_companion.yamlalone hot-reload via the dashboard's ⋮ → "Reload" (no restart) — but CI will still restart on push since it can't distinguish; acceptable for an infrequently-changed file. (Plan may add a YAML-only fast path later.)
2.3 Test-suite integration¶
- Add
desk_companion.yamlto the entity-reference scan (the test that asserts every referencedentity_idexists intests/fixtures/entities.txtor the allowlist). - All entities this dashboard references already exist (see Appendix A) except
sensor.time(added via the Time & Date integration — see §3) and the three new card resources (frontend, not entities). Refreshmake snapshotafter the Time & Date integration is added sosensor.time/sensor.dateland in the fixture. make testmust stay green before any push.
3. Dependencies¶
3.1 HACS frontend cards to install (3 new)¶
Already installed: button-card, Mushroom, mini-graph-card, apexcharts-card.
| Card | Purpose | Why needed |
|---|---|---|
| card-mod | Frosted-glass effect (backdrop-filter: blur), gradient backgrounds, per-card CSS, full-viewport grid sizing | Near-essential for the Midnight Glass aesthetic; nothing native does glassmorphism |
| mini-media-player | "Now Playing" with album art, transport, volume, room source-select | Themeable to Midnight Glass; native media-control can't be styled to match |
| kiosk-mode | Hide HA header + sidebar for a full-screen kiosk view | Standard way to strip HA chrome on a tablet |
All three are standard, free HACS frontend plugins. Each must be added as a Lovelace resource (HACS does this on install). The plan documents install + resource registration.
3.2 Native integration to add¶
- Time & Date (
time_date/ Settings → Devices → Add Integration → "Time & Date") to createsensor.time(minute resolution) andsensor.date. The hero clock binds tosensor.timeso it ticks every minute without custom JS timers.
4. Visual system — "Midnight Glass"¶
Implemented as reusable card-mod snippets / button-card style blocks (the plan will factor these into shared templates so each module isn't copy-pasting CSS).
4.1 Color tokens¶
| Token | Value | Use |
|---|---|---|
--bg | radial-gradient(130% 120% at 8% -10%, #1b2542 0%, #0a0e1a 58%) | Dashboard background |
| Glass fill | rgba(255,255,255,0.055) | Card body |
| Glass border | 1px solid rgba(255,255,255,0.12) | Card edge |
| Glass blur | backdrop-filter: blur(9px) | Frosted effect |
| Text primary | #e7ecf6 | Values |
| Text muted | #9fb0d0 | Labels/secondary |
| Accent cool | linear-gradient(120deg, #34d399, #22d3ee) | Energy / good states |
| Accent brand | linear-gradient(120deg, #fff, #9db4ff) | Clock / hero |
| Accent purple | linear-gradient(135deg, #8b5cf6, #3b82f6, #22d3ee) | Media art, progress |
| Warn | #fbbf24 (amber) / #ef4444 (red) | Threshold states |
| Glow blobs | blurred radial #3b82f6 (top-left) + #8b5cf6 (bottom-right) behind cards | Depth |
4.2 Typography¶
System font stack (-apple-system). Clock: thin (300), large, gradient-clipped. Values: 600–800 weight. Labels: 9px uppercase, 1.5px letter-spacing, muted.
4.3 Glass card recipe¶
Semi-transparent white fill + 1px translucent border + backdrop-filter: blur + 14px radius, over the navy gradient background with two blurred accent blobs for depth. Reference mockup: .superpowers/brainstorm/<session>/content/layout-options.html (Layout B, gitignored).
5. Layout (Layout B)¶
Single full-screen view (panel-style root card stretched to 100vh via card-mod) holding a CSS-grid of three bands:
┌───────────────────────────────────────────────┐
│ HERO BAND (clock + date ···· weather) │ ~22% height, full width
├───────────────┬───────────────┬─────────────────┤
│ OFFICE AIR │ ENERGY NOW │ NOW PLAYING │ ~56% height, 3 equal cols
│ (CO₂ ring) │ ($ + TOU) │ (media player) │
├───────────────┴───────────────┴─────────────────┤
│ HOUSE AT A GLANCE (chip row) │ ~22% height, full width
└───────────────────────────────────────────────┘
- Implemented with
vertical-stack→ [hero,horizontal-stack(air, energy, now), house], with card-mod forcing the stacks/cards to flex to fill the viewport height (nolayout-carddependency). - 12–14px gaps; 14px outer padding. Tuned so nothing scrolls — the whole thing fits one screen at 1180×820 pt.
6. Module specifications¶
6.1 Time + Weather hero (full-width band)¶
- Cards:
custom:button-card(clock/date, bindssensor.time) + weather glyph/temps fromweather.officeandweather.forecast_home. - Shows: big live clock (HH:MM), long date, office temp + outdoor temp + condition, today's hi/lo.
- Interaction: none (display only).
6.2 Office Air (column 1)¶
- Card:
custom:button-cardrendering a conic-gradient ring gauge for CO₂, plus a 3-stat row (VOC, temp, RH). - Entities:
sensor.office_carbon_dioxide(ring),sensor.office_volatile_organic_compounds,sensor.office_temperature,sensor.office_humidity. - Color thresholds (tunable):
- CO₂: green < 800, amber 800–1200, red > 1200 ppm.
- VOC: green < 500, amber 500–1000, red > 1000 (sensor units; verify ppb vs µg/m³ at build).
- Interaction: tap → more-info popup (optional). Display-first.
6.3 Energy Now (column 2)¶
- Cards:
custom:button-cardfor the figures +custom:mini-graph-cardsparkline. - Entities:
sensor.energy_cost_today(big$),sensor.tou_period+sensor.tou_rate(pill),sensor.whole_home_power(live kW + sparkline),input_boolean.peak_mode(peak state). - States: TOU pill green for off/super-off-peak; red "PEAK · $0.30/kWh" with a "hold big appliances" hint when
peak_modeis on. Sparkline = last few hours of whole-home power. - Interaction: none.
6.4 Now Playing (column 3)¶
- Card:
custom:mini-media-player, card-mod themed to glass. - Entities: default
media_player.office_apple_tv; fall back / source-select amongmedia_player.office_soundbarand other rooms (Sonos, echoes). Album art, title/artist, ⏮ ⏯ ⏭, volume. - Interaction: full transport control (the one routinely-interactive module). Source/room picker so Louis can drive office audio or grab another room.
6.5 House at a Glance (full-width strip)¶
- Card: chip row (Mushroom chips or button-card chips), card-mod themed.
- Chips (real entities only — no locks; none installed yet):
- Garage:
cover.right_garage_door_opener_garage_door+cover.left_garage_door_opener_garage_door→ "Garage closed/OPEN" (red if either open). - Leaks: any of the ~12 leak
binary_sensor.*wet → "Leak!" red, else "No leaks" green. - Presence:
person.louis/person.lindsay(orzone.homecount) → who's home. - Internet (single chip):
sensor.speedtest_download→ "858↓ Mbps", red if degraded. - Interaction: tap a chip → more-info (optional). When smart locks are installed later, add a lock chip.
7. Kiosk setup (device-side, documented not automated)¶
- Install the Home Assistant Companion app on the iPad; log in to the instance.
- Open the
/desk-companiondashboard. - Enable Guided Access (Settings → Accessibility → Guided Access) and triple-click to lock the iPad to the dashboard.
- kiosk-mode plugin config hides the HA header + sidebar — target this dashboard by path (and/or this device/user) so the rest of HA is unaffected.
- Always-on: Settings → Display → Auto-Lock → Never; keep it on the charging arm. Enable Night Shift (and optionally Reduce White Point) for nighttime comfort. Midnight Glass is already dark.
The plan will produce a step-by-step setup doc (and likely a short page in the MkDocs manual under a "Desk Kiosk" entry).
8. Testing & deploy plan¶
- Install 3 HACS cards + Time & Date integration; register resources.
make snapshot(with the newsensor.time/sensor.date) → commit refreshedtests/fixtures/entities.txt.- Build
desk_companion.yaml; register inconfiguration.yaml. - Extend
ci.ymldeploy list + the entity-ref test to includedesk_companion.yaml. make testgreen locally.- Push → CI tests →
ha core restart(new dashboard registration) → verify dashboard renders on the iPad. - Document kiosk setup steps.
9. Out of scope (YAGNI)¶
Focus/pomodoro timer; a dedicated internet panel; quick-controls module; calendar agenda (no calendar integration connected); any HVAC control (Ecobee-owned); editing the existing Home Command Dashboard.
10. Risks / open questions¶
- Full-viewport fit without
layout-card: card-mod height forcing on stacks should fill 1180×820 cleanly, but exact%/vhvalues need tuning on the real device. If stacks prove fiddly, fall back to addingcustom:layout-card(a 4th HACS card). - mini-media-player + Apple TV / Echo quirks: Apple TV media entities expose limited transport; Alexa media players read
unavailablewhen idle. Confirm which office player gives the best control surface at build; the source-picker mitigates. - VOC units: office VOC sensor may report ppb vs µg/m³ — confirm before setting thresholds.
- YAML edits still trigger CI restart: acceptable now; optional future optimization to hot-reload YAML-only changes.
Appendix A — Entity reference¶
# Time / weather
sensor.time (NEW — Time & Date integration)
weather.office
weather.forecast_home
# Office air
sensor.office_carbon_dioxide
sensor.office_volatile_organic_compounds
sensor.office_temperature
sensor.office_humidity
# Energy
sensor.energy_cost_today
sensor.tou_period
sensor.tou_rate
sensor.whole_home_power
input_boolean.peak_mode
# Media
media_player.office_apple_tv
media_player.office_soundbar
# House at a glance
cover.right_garage_door_opener_garage_door
cover.left_garage_door_opener_garage_door
binary_sensor.*_leak_detector / *_leak_sensor (group)
person.louis
person.lindsay
sensor.speedtest_download