Design guide with principles, layout patterns, component usage, navigation rules, and checklist. References homekit.html as the design gold standard and design-system.html for components.
8.4 KiB
name, description, disable-model-invocation
| name | description | disable-model-invocation |
|---|---|---|
| frontend_design_strix | Create or redesign frontend pages for Strix. Use when building new HTML pages, redesigning existing ones, or working on any UI task in the www/ directory. Covers design principles, layout patterns, and component usage. | true |
Strix Frontend Design
You are creating or modifying a frontend page for Strix. Your goal is to produce a page that looks identical in quality to the existing pages, especially www/homekit.html which is the design reference.
Before you start
Read these files completely:
www/design-system.html-- All CSS variables, every component, JS patterns. This is your component library.www/homekit.html-- The design reference. This page is the gold standard. Study its structure, spacing, how little text it uses, how the back button is positioned.www/index.html-- The entry point. Understand the probe flow and how data is passed between pages via URL params.
If you need to understand backend APIs or the probe system, read:
www/standard.html-- how probe data flows into a configuration pagewww/test.html-- how polling and real-time updates workwww/config.html-- complex two-column layout with live preview
Design Philosophy
Radical minimalism
Every element on screen must earn its place. If something doesn't help the user complete their task, remove it.
- 10% text, 90% meaning. A label that says "Pairing Code" with an info-icon is better than a paragraph explaining what a pairing code is.
- Hide details behind info-icons. Long explanations go into tooltips (the
(i)icon pattern). The user who needs the explanation can hover. The user who doesn't is not bothered. - No decorative elements without function. No ornamental icons, no badges that don't convey information, no cards-as-decoration.
- One action per screen. Each page should have one primary thing the user does. Everything else is secondary.
How we think about design decisions
When building homekit.html, we went through this process:
- Started with all the data -- device info table, long descriptions, badges, decorative icons
- Asked "does the user need this?" for every element
- Removed everything that wasn't essential -- the device info table (IP, MAC, vendor) was removed because the user doesn't need it to enter a PIN code
- Moved explanations into tooltips -- "This camera supports Apple HomeKit. Enter the 8-digit pairing code printed on your camera or included in the manual" became just a label "Pairing Code" with a tooltip
- Removed format hints -- "Format: XXX-XX-XXX" was removed because the input fields themselves make the format obvious
- Made the primary action obvious -- big button, full width, impossible to miss
Apply this same thinking to every page you create.
Visual rules
- Dark theme with purple accent -- never deviate from the color palette in
:root - All icons are inline SVG -- never use emoji, never use icon fonts, never use external icon libraries
- Fonts: system font stack for UI, monospace for technical values (URLs, IPs, codes)
- Borders are subtle:
rgba(139, 92, 246, 0.15)-- barely visible purple tint - Glow effects on focus and hover, never on static elements (except logos)
- Animations are fast (150ms) and subtle -- translateY(-2px) on hover, fadeIn on page load
- No rounded corners larger than 8px (except special cases like toggle switches)
Layout Patterns
Pages after probe (like homekit.html) -- TRUE CENTER
This is the most common case for new pages. Content is vertically centered on screen.
.screen {
min-height: 100vh;
display: flex;
align-items: center; /* TRUE CENTER -- not flex-start */
justify-content: center;
}
.container { max-width: 480px; width: 100%; }
Back button is positioned OUTSIDE the container, wider than content, using .back-wrapper:
.back-wrapper {
position: absolute; top: 1.5rem;
left: 50%; transform: translateX(-50%);
width: 100%; max-width: 600px; /* wider than container */
padding: 0 1.5rem;
z-index: 10;
}
This is MANDATORY for all centered layout pages. The back button must NOT be inside the centered container.
Entry page (like index.html) -- TOP CENTER
Content is near the top with margin-top: 8vh. Used for the main entry point only.
Content pages (like standard.html, create.html) -- STANDARD
Back button at top, then title, then content flowing down. max-width: 600px, no vertical centering.
Data-heavy pages (like test.html) -- WIDE
max-width: 1200px with card grids.
Two-column (like config.html) -- SPLIT
Settings left, live preview right. Collapses to tabs on mobile.
Hero Section Pattern
For centered pages, the hero contains a logo/icon + short title:
<div class="hero">
<svg class="logo-icon">...</svg> <!-- 48-72px, with glow filter -->
<h1 class="title">Short Name</h1> <!-- 1.25rem, white, font-weight 600 -->
</div>
- The icon should be recognizable and relevant (Strix owl for main, HomeKit house for HomeKit)
- The title is SHORT -- one or two words max
- No subtitles unless absolutely necessary
- Glow effect on the icon via
filter: drop-shadow()
Component Usage
All components are documented with live examples in www/design-system.html. Key ones:
- Buttons:
.btn .btn-primary .btn-largefor primary action (full width),.btn-outlinefor secondary - Inputs:
.inputwith.labeland optional.info-iconwith.tooltip - Toast: Every page needs
<div id="toast" class="toast hidden"></div>and theshowToast()function - Error box:
.error-boxwith.visibleclass toggled - Info icon + tooltip: For hiding explanations -- always prefer this over visible text
Navigation -- CRITICAL
Always pass ALL known data forward
When navigating to another page, pass every piece of data you have. This is non-negotiable. Future pages may need any of these values.
function navigateNext() {
var p = new URLSearchParams();
p.set('primary_data', value);
// Pass through EVERYTHING known:
if (ip) p.set('ip', ip);
if (mac) p.set('mac', mac);
if (vendor) p.set('vendor', vendor);
if (model) p.set('model', model);
if (server) p.set('server', server);
if (hostname) p.set('hostname', hostname);
if (ports) p.set('ports', ports);
if (user) p.set('user', user);
if (channel) p.set('channel', channel);
// ... any other params from probe
window.location.href = 'next.html?' + p.toString();
}
Page init always reads all params
var params = new URLSearchParams(location.search);
var ip = params.get('ip') || '';
var mac = params.get('mac') || '';
var vendor = params.get('vendor') || '';
// ... read ALL possible params even if this page doesn't use them
// They need to be available for passing to the next page
JavaScript Rules
- Use
var, notlet/const-- ES5 compatible - Build DOM with
document.createElement, not innerHTML - Use
async function+fetch()for API calls - Always handle errors: check
!r.ok, catch exceptions, show toast - Debounce input handlers if they trigger API calls (300ms)
- Use
addEventListener, never inline event handlers in HTML
API Pattern
async function doSomething() {
try {
var r = await fetch('api/endpoint', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
if (!r.ok) {
var text = await r.text();
showToast(text || 'Error ' + r.status);
return;
}
var data = await r.json();
// success...
} catch (e) {
showToast('Connection error: ' + e.message);
}
}
Checklist before finishing
- Page uses correct layout pattern for its type
- Back button positioned correctly (
.back-wrapperfor centered, inline for standard) - All CSS variables from
:root-- no hardcoded colors - No unnecessary text -- everything possible hidden behind info-icons
- All known URL params are read at init and passed forward on navigation
- Toast element present, showToast function included
- Error states handled (API errors, validation)
- Mobile responsive (test at 375px width)
- No emoji anywhere
- All icons are inline SVG
- Primary action is obvious and full-width
- Page looks like it belongs with homekit.html and index.html