# Contract: Web Visual Baseline Version: 1.0 ## Scope Defines the default visual baseline for future web applications in this ecosystem. The canonical reference is the UI style from: - `/Users/mchusavitin/Documents/git/chart/web/static/view.css` - `/Users/mchusavitin/Documents/git/chart/web/templates/view.html` - `/Users/mchusavitin/Documents/git/chart/web/templates/upload.html` When a project does not already have an established design system, use this baseline by default. ## Core Direction - Prefer a clean, data-first interface over decorative marketing UI. - Default to server-rendered HTML with simple CSS. - Optimize for scanability, density, and operational clarity. - Use restrained visual hierarchy, not novelty effects. - Reuse the baseline directly when possible; copying the canonical CSS and adapting tokens is allowed. ## Canonical Visual Language - Dark application header on top. - White page background and white content surfaces. - Light secondary surfaces for headers and table heads. - Thin gray borders with a subtle shadow. - Small radii (`4px`). - Dense but readable typography (`14px/1.5` baseline). - Blue accent in the `#2185d0` family for primary actions and active accents. - Tables and key-value layouts as the primary presentation pattern. - Status communicated with both text and color. ## Typography - Use `Lato, "Helvetica Neue", Arial, Helvetica, sans-serif` unless a project has an approved alternative. - Page titles are compact and strong, not oversized hero typography. - Section titles should be clear and structural. - Avoid display fonts, novelty fonts, and oversized marketing headings in application UI. ## Layout Primitives - `page-header`: dark global header with page title and compact actions. - `page-main`: centered content area with generous outer margin and bounded max width. - `panel`: white surface with border, light shadow, and simple heading strip. - `section-card`: heading followed by table/content block. - `table-wrap`: horizontal overflow container for dense data tables. ## Preferred Components - Key-value tables for singleton object/detail views. - Dense data tables for repeated records. - Compact upload/open panels when local file input is needed. - Quiet header actions for secondary navigation. - Clear primary buttons for the main action on a screen. - Simple alert/error boxes with border + tinted background. ## Status Rules - `OK`: green - `Warning`: amber - `Critical`: red - `Unknown`: gray - `Empty`: light gray Status must not rely on color alone. Show text or another explicit indicator together with the color treatment. ## Responsive Rules - Keep desktop density high. - Collapse grids to one column on small screens. - Preserve table readability with horizontal scrolling instead of destructive cardification by default. - Header actions may wrap or stack on mobile, but should remain compact. ## Forbidden Drift - Do not default to glassmorphism, blurred shells, floating neon gradients, or soft-dribbble styling. - Do not replace dense tables with oversized card grids when the data is inherently tabular. - Do not introduce arbitrary color coding for non-status fields. - Do not use oversized border radii, heavy shadows, or large empty spacing as the default application style. - Do not import a SPA/dashboard aesthetic unless the product explicitly requires it. ## Relationship To Other UI Contracts - Use this contract as the visual baseline. - Use `table-management` for shared table geometry and interaction seams. - Use `controls-selection` for button hierarchy, filters, and bulk selection semantics. - Pattern-specific contracts may override details only when they document the reason. ## Copyable Starter CSS Use this as the default starting point for new web apps: ```css :root { --bg: #ffffff; --surface: #ffffff; --surface-2: #f9fafb; --border: rgba(34, 36, 38, 0.15); --border-lite: rgba(34, 36, 38, 0.1); --ink: rgba(0, 0, 0, 0.87); --muted: rgba(0, 0, 0, 0.6); --accent: #2185d0; --accent-dark: #1678c2; --accent-bg: #dff0ff; --ok: #16ab39; --warn: #f2711c; --crit: #db2828; --header-bg: #1b1c1d; --radius: 4px; --shadow: 0 1px 2px 0 rgba(34, 36, 38, 0.15); --content-width: 1500px; } * { box-sizing: border-box; } body { margin: 0; background: var(--bg); color: var(--ink); font: 14px/1.5 Lato, "Helvetica Neue", Arial, Helvetica, sans-serif; } .page-header { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 14px 24px; background: var(--header-bg); } .page-header h1 { margin: 0; font-size: 18px; font-weight: 700; color: rgba(255, 255, 255, 0.9); } .page-main { width: min(var(--content-width), calc(100vw - 48px)); margin: 28px auto 56px; } .panel { margin-bottom: 28px; overflow: hidden; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); } .panel > h2 { margin: 0; padding: 13px 16px; background: var(--surface-2); border-bottom: 1px solid var(--border); font-size: 13px; font-weight: 700; } .table-wrap { overflow-x: auto; } .kv-table, .data-table { width: 100%; border-collapse: collapse; background: var(--surface); } .kv-table th, .kv-table td, .data-table th, .data-table td { padding: 11px 14px; text-align: left; vertical-align: top; border-top: 1px solid var(--border-lite); } .kv-table th, .data-table th { background: var(--surface-2); border-top: 0; border-bottom: 1px solid var(--border-lite); font-weight: 700; white-space: nowrap; } .data-table tbody tr:hover { background: rgba(0, 0, 0, 0.04); } .button-primary { display: inline-block; padding: 8px 18px; border: none; border-radius: var(--radius); background: var(--accent); color: #fff; font: inherit; font-weight: 700; text-decoration: none; cursor: pointer; } .button-primary:hover { background: var(--accent-dark); } .header-action { display: inline-block; padding: 6px 14px; border-radius: var(--radius); background: rgba(255, 255, 255, 0.12); color: rgba(255, 255, 255, 0.85); text-decoration: none; font-size: 13px; font-weight: 700; } .header-action:hover { background: rgba(255, 255, 255, 0.2); } .status-ok { color: var(--ok); } .status-warning { color: var(--warn); } .status-critical { color: var(--crit); } .status-unknown { color: rgba(0, 0, 0, 0.45); } @media (max-width: 720px) { .page-header { flex-direction: column; padding: 12px 16px; } .page-main { width: calc(100vw - 24px); margin-top: 20px; } } ``` ## Copyable Starter HTML ```html

Overview

Host server-01
Status OK

Devices

Name Vendor Status
NIC 1 Intel Warning
```