# 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:
```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/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: `data/uploads/<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.
