STYLE_SYSTEM.md 16 KB

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 <header> 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 <body class="admin-page"> 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:

@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/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/<filename>
    • 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.