# Portable Intranet Style System Spec ## Purpose and Scope This file is the canonical style contract for reproducing the current dark-theme design system across an intranet collection of services. - Scope included: shared service UI, operations/admin UI, print styles, and HTML email styles. - Output target: AI-agent implementation playbook with exact values and selector contracts. - Goal: faithful visual parity, not redesign. - Runtime/API impact: no runtime API changes. This style contract defines the portable interface another implementation must expose: - CSS custom properties (`--brand-*`) - required class names and state classes (`.alert-*`, `.status-*`, etc.) - context class (`body.admin-page`) - responsive table data-label interface (`td[data-label]`) The current class names originated in a shop system, but they are intentionally treated here as generic style primitives that can be reused for non-shop domains. ## Quick Start for AI Agents 1. Create the canonical token block (`:root`) with all `--brand-*` variables exactly as listed in this document. 2. Apply base primitives first: reset, `body`, `a`, `.container`, `main`. 3. Implement shared components in dependency order: header/nav -> buttons/forms -> cards/grids -> tables -> alerts/status -> panel/modal -> utilities. 4. Keep legacy class compatibility (for portability) and optionally add local alias classes in the target system. 5. Add responsive behavior for `max-width: 768px` and `max-width: 480px`. 6. Add operations context rules (`body.admin-page`) and responsive table card mode (`td[data-label]` required). 7. Add print contract for printable transaction/detail pages. 8. Add email theme contract using the email palette and block styles. 9. Validate with the parity checklist at the end. ## Style Tokens (Canonical) ### CSS Variable Tokens (`:root`) | Token | Value | Intended usage | | --- | --- | --- | | `--brand-primary` | `#2f3541` | Top bars, section headers, dense surfaces | | `--brand-primary-dark` | `#242a33` | Darker primary accent | | `--brand-danger` | `#cf2e2e` | Error/danger/action emphasis | | `--brand-danger-dark` | `#b12727` | Danger hover state | | `--brand-accent` | `#cac300` | Highlight/open/attention accent | | `--brand-dark` | `#1b1b1b` | Deep dark token | | `--brand-text` | `#f5f7fb` | Primary foreground text | | `--brand-muted` | `#c7ccd6` | Secondary/supporting text | | `--brand-surface` | `#2f3541` | Cards/panels/module containers | | `--brand-surface-alt` | `#3a4150` | Alternate surfaces, input fills, hover backgrounds | | `--brand-bg` | `#28292a` | Page/application background | | `--brand-border` | `#3b4252` | Default border color | ### Additional Non-Tokenized Colors (Must Preserve) | Value | Where used | | --- | --- | | `#e0d700` | Generic link hover | | `#ffffff` | White text/borders (`.status-notified`, `.status-picked`, footer links, info alert border) | | `#9ca3af` | Hidden/archived status text | | `#6b7280` | Hidden/archived status border | | `#303745` | Email item-panel background | | `#4a5263` | Email panel/list item borders | | `#e9ecef` | Generic placeholder SVG background | | `#6c757d` | Generic placeholder SVG text | ### RGBA Effects (Exact) | Value | Usage | | --- | --- | | `rgba(0,0,0,0.18)` | Header shadow | | `rgba(0,0,0,0.25)` | Logo drop shadow | | `rgba(0,0,0,0.4)` | Card default shadow | | `rgba(0,0,0,0.15)` | Card hover shadow | | `rgba(0,0,0,0.35)` | Table/stat/panel/card shadows | | `rgba(0,0,0,0.6)` | Modal backdrop | | `rgba(0,0,0,0.1)` | Media block image shadow | | `rgba(202, 195, 0, 0.2)` | Form focus ring overlay | ## Typography - Primary UI font stack: `-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif` - Primary line-height: `1.6` on body text. - Brand area: - `.brand-title`: `1.3rem`, `700`, `letter-spacing: 0.02em` - `.brand-subtitle`: `0.9rem`, `500`, `opacity: 0.9` - Navigation links: - `font-weight: 600` - `letter-spacing: 0.02em` - Emphasized record IDs: - web: `'Courier New', monospace`, `letter-spacing: 0.2rem` - email: `monospace` (inline) - Status pills: - `font-size: 0.85rem`, `font-weight: 600`, `letter-spacing: 0.02em` - Email typography: - `Arial, sans-serif`, `line-height: 1.6` ## Spacing, Radius, Shadows, Motion ### Spacing primitives in use - Common vertical rhythm: `0.5rem`, `1rem`, `1.5rem`, `2rem`. - Utility classes: - `.mt-1/.mt-2/.mt-3` = `0.5rem/1rem/1.5rem` - `.mb-1/.mb-2/.mb-3` = `0.5rem/1rem/1.5rem` - Container horizontal padding: - default: `20px` - mobile (`<=480px`): `12px` ### Radius values - `4px`: buttons, inputs, alerts - `6px`: callout/disclaimer boxes - `8px`: cards, tables, panels, modal content, code/ID boxes - `10px`: email outer card - `999px`: status pills ### Shadow system - Header: `0 2px 6px rgba(0,0,0,0.18)` - Cards: `0 2px 8px rgba(0,0,0,0.4)` -> hover `0 4px 12px rgba(0,0,0,0.15)` - Panels/tables/stats: `0 2px 4px rgba(0,0,0,0.35)` - Media/image detail view: `0 2px 8px rgba(0,0,0,0.1)` ### Motion - `.btn`: `transition: background-color 0.3s` - `.product-card`: `transition: transform 0.3s, box-shadow 0.3s` - `.product-card:hover`: `transform: translateY(-5px)` Note: - The `product-*` class family can be used as generic entity/service cards if not renamed. ## Layout and Grids - `.container`: centered layout, `max-width: 1200px`, side padding. - `main`: `min-height: calc(100vh - 200px)`, vertical section padding. - Header layout: - `.header-inner`: horizontal flex, center aligned, `justify-content: space-between`, gap-based spacing. - Generic module grids (legacy class names retained): - `.products-grid`: auto-fill card grid, `minmax(250px, 1fr)` desktop. - `.product-detail-grid`: two columns desktop, one column mobile. - `.checkout-grid`: two columns desktop, one column mobile. - Operations/admin width behavior: - `body.admin-page .container`: full width (`max-width: none`), compact side padding. ## Component Contracts (Class-by-Class) This is the portable public style interface. Implement these selectors and semantics exactly. ### Base - `body`: dark background (`--brand-bg`), light text (`--brand-text`), system font stack. - `a`: accent color; hover uses `#e0d700`. - `.container`: width cap and horizontal padding. - `main`: page body spacing and minimum viewport height behavior. ### Header, Navigation, Branding - `.site-header`: primary background, white text, shadow, vertical padding. - `.header-inner`: flex alignment and spacing. - `.brand`: inline flex logo + text, white, no underline. - `.brand-logo`: fixed height (52px desktop / 46px mobile), drop shadow. - `.brand-title` and `.brand-subtitle`: hierarchy and typography values. - `.site-nav`: horizontal link group; links are white, accent on hover. ### Buttons and Form Controls - `.btn`: primary action button in `--brand-danger`. - `.btn:hover`: `--brand-danger-dark`. - `.btn-secondary`: transparent with border (`--brand-border`) and text color (`--brand-text`). - `.btn-small`: compact button spacing and smaller text. - `.form-group`: vertical field spacing. - `.form-group input, textarea, select`: dark-alt surface fields, border, inherited font. - focus state: accent border + ring `0 0 0 3px rgba(202, 195, 0, 0.2)`. - `.quantity-input`: compact numeric field width and centered text. ### Entity / Workflow Components (Legacy Class Names) - `.products-grid`: generic service/entity card grid. - `.product-card`: dark surface card with hover lift. - `.product-card-content`: internal spacing. - `.price`: prominent numeric/value field (can represent any key metric). - `.stock.in-stock`: positive/available/open state accent. - `.stock.out-of-stock`: unavailable/error/depleted state danger color. - `.cart-item`: split content/action card row. - `.cart-actions`: summary and action group container, desktop right-aligned and mobile stacked. ### Data Display - `table`: full width, surface background, shadow, rounded corners. - `th`: primary background + white text. - `td`: bordered row separation. - `tr:hover`: alternate surface. - `.table-responsive`: horizontal overflow wrapper. - `.responsive-table`: required class for mobile card conversion in operations context. - `.table-compact`: denser table variant with reduced paddings/font size. ### Feedback and State - `.alert`: neutral surface alert container. - `.alert-success`: accent border. - `.alert-error`: danger border. - `.alert-info`: white border. - `.alert-warning`: accent border. - `.status`: pill base shape. - `.status-open`: open/pending/active text+border. - `.status-notified`: notified/informed text+border. - `.status-picked`: completed/processed text+border. - `.status-expired`: expired/invalid text+border. - `.status-hidden`: hidden/archived text+border. ### Structural / Operations / Modal - `.panel`: reusable surface box with border, radius, and shadow. - `.admin-header`: top section with title/actions. - `.admin-stats`: responsive metrics grid. - `.stat-card`, `.stat-value`: metric visuals. - `.modal`: full-screen backdrop overlay (`display: none` by default, fixed, centered). - `.modal-content`: constrained scrollable panel (`max-width: 1000px`, `max-height: 95vh`). - `.modal-close`: top-right positioned close action. ### Utilities - `.text-center`: text alignment helper. - `.mt-1/.mt-2/.mt-3`, `.mb-1/.mb-2/.mb-3`: simple spacing utilities. ### Context and Responsive Table Data Contract - `body.admin-page`: enables operations-wide layout/table behavior. - `td[data-label]` on responsive tables is required: - mobile uses `td::before { content: attr(data-label); }` - without `data-label`, mobile card mode loses column labels. ### Inline Overrides and Legacy Equivalents Current templates include inline styles. For portability, normalize them into reusable classes or exact one-off rules. | Legacy inline pattern | Portable equivalent | | --- | --- | | `width: 100%` | `.u-w-full { width: 100%; }` | | `text-align: center` | `.text-center` | | `margin-top: 1rem` / `1.5rem` / `2rem` | `.mt-2` / `.mt-3` / `section gap rule` | | `margin-left: 1rem` / `1.5rem` | `.ml-2` / `.list-indent` helper rule | | `padding: 1rem; margin-bottom: 1rem` (compact summary cards) | `.panel.panel-compact` | | `padding: 2rem; margin: 2rem 0` (detail blocks) | `.panel.panel-spacious` | | `display: inline` on action forms | `.inline-form { display: inline; }` | | `display: flex; gap: 1rem; align-items: end; flex-wrap: wrap` | `.filter-form` | | `flex: 1; min-width: 200px` | `.filter-field-grow` | | `max-width: 400px; margin-top: 4rem` (auth/login container) | `.auth-container` | | Inline media image (`width: 100%; border-radius: 8px; box-shadow: ...`) | `.media-hero-image` | | Inline full-width primary CTA (`width:100%; text-align:center; margin-top:1rem`) | `.btn-block + .mt-2` | Fidelity note: - The current login page uses a plain `
` element instead of `.site-header`. Preserve this behavior if strict parity is required. ## Responsive Behavior ### Breakpoint: `max-width: 768px` - Header stack: - `.header-inner` becomes column layout, left aligned. - `.site-nav` wraps. - Footer links become vertical. - `.brand-logo` height drops to `46px`. - Card grid shifts to `minmax(200px, 1fr)` with tighter gaps. - `.product-detail-grid`, `.checkout-grid` switch to 1 column. - `.cart-item` stacks vertically; actions expand. - `.cart-actions` left aligns; button groups stack vertically. - `.modal-content` adds margins and reduced max-height. - `.admin-header` stacks with wrapped action buttons. - Table cell typography/padding reduced. - `.admin-stats` becomes single column. - `body.admin-page .table-responsive` gets edge-to-edge compensation paddings. - `.table-responsive .btn` allows wrapping. - `body.admin-page table.responsive-table` transforms rows into card blocks with `td[data-label]` pseudo labels. ### Breakpoint: `max-width: 480px` - `.container` horizontal padding -> `12px`. - `main` vertical padding reduced. - Brand text sizes reduce (`.brand-title` `1.1rem`, `.brand-subtitle` `0.8rem`). - `.products-grid` becomes single column. - For non-card tables in narrow view: `.table-responsive table:not(.responsive-table) { min-width: 520px; }`. ## Admin Variant Contract - Set `` for operations/control pages to activate admin-specific layout behavior. - Operations pages rely on: - wide container (`max-width: none`) - `responsive-table` + `table-responsive` pairing - action-heavy row behavior with wrapped controls on mobile - status pill classes (`.status-*`) for workflow state display - Modal details contract: - overlay container `.modal` - content container `.modal-content` - close control `.modal-close` ## Print Contract Printable detail/receipt/ticket pages should preserve the existing minimal print mode. Required print rules: ```css @media print { header, footer, .btn, nav { display: none !important; } body { padding: 20px; } .order-number { page-break-inside: avoid; } table { page-break-inside: avoid; } } ``` Behavioral intent: - hide navigation/chrome/actions when printing - keep key identifier blocks and tables intact across page breaks ## Email Theme Contract Email styles are inline HTML/CSS and must keep the same dark-theme palette. ### Email token mapping | Email role | Value | | --- | --- | | Body background | `#28292a` | | Main card background | `#2f3541` | | Main card border | `#3b4252` | | Primary text | `#f5f7fb` | | Accent text/border | `#cac300` | | Item panel background | `#303745` | | Item panel border | `#4a5263` | | Warning panel border | `#cf2e2e` | ### Email typography - `font-family: Arial, sans-serif` - `line-height: 1.6` - key IDs use `font-family: monospace` ### Required structural blocks - Outer body wrapper (dark background, padded) - Centered email card (`max-width: 640px`, dark surface, border, rounded corners) - Identifier box (accent border, emphasized code) - Item-list panel (alt background + optional left accent stripe) - Warning panel (danger border) for exception or delay notices ## Asset and Branding Contract - Required organization logo: - `assets/images/feuerwehr-logo-invers.webp` - If rebranding for another intranet, replace asset file while preserving placement/sizing behavior. - Media/image behavior: - source path pattern in current system: `assets/images/` - detail/media view uses full-width image with `8px` radius and soft shadow. - Placeholder fallback behavior: - inline SVG fallback uses: - background `#e9ecef` - text `#6c757d` - Brand tone requirements: - dark neutral background/surfaces - yellow accent for highlights and open/positive states - red for warning/danger/error - white/near-white foreground text for contrast ## Implementation Checklist - [ ] Add canonical `:root` tokens exactly. - [ ] Add all non-tokenized colors and RGBA effects where required. - [ ] Implement base primitives (`body`, `a`, `.container`, `main`). - [ ] Implement header/nav/branding components. - [ ] Implement buttons/form controls/focus states. - [ ] Implement entity/workflow cards and split content/action rows. - [ ] Implement tables, `.table-responsive`, `.responsive-table`, `.table-compact`. - [ ] Implement alerts and status pill states. - [ ] Implement panels, stats/layout, and modal system. - [ ] Implement utility classes (`.text-center`, `.mt-*`, `.mb-*`). - [ ] Implement operations context via `body.admin-page`. - [ ] Ensure `td[data-label]` exists where responsive table cards are needed. - [ ] Migrate/replace inline styles with reusable equivalents where possible. - [ ] Add print rules for transaction/detail page parity. - [ ] Apply email theme block styles with exact palette and typography. - [ ] Verify logo/media/placeholder behavior. ## Parity Validation Checklist ### 1) Token fidelity - [ ] Every documented token and hardcoded color appears with exact value. - [ ] RGBA shadow/focus values match exactly. ### 2) Service UI parity - [ ] Header, cards, detail views, action rows, forms, and confirmation/detail pages match hierarchy and style. ### 3) Operations parity - [ ] Dashboard stats, data tables, status pills, panels, modal overlays, and action buttons match behavior and appearance. ### 4) Responsive parity - [ ] At `<=768px`, layout stacks and table card mode works. - [ ] At `<=480px`, compact spacing and single-column card layout are applied. ### 5) Print parity - [ ] Printing detail pages hides header/footer/nav/buttons and preserves key blocks from page breaks. ### 6) Email parity - [ ] Notification/confirmation emails render with dark card theme, accent highlights, and warning block usage where applicable. ### 7) Accessibility sanity - [ ] Text contrast remains readable on dark surfaces. - [ ] Form focus ring is visible and consistent.