Initial commit: ArchiTools modular dashboard platform

Complete Next.js 16 application with 13 fully implemented modules:
Email Signature, Word XML Generator, Registratura, Dashboard,
Tag Manager, IT Inventory, Address Book, Password Vault,
Mini Utilities, Prompt Generator, Digital Signatures,
Word Templates, and AI Chat.

Includes core platform systems (module registry, feature flags,
storage abstraction, i18n, theming, auth stub, tagging),
16 technical documentation files, Docker deployment config,
and legacy HTML tool reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Marius Tarau
2026-02-17 12:50:25 +02:00
commit 4c46e8bcdd
189 changed files with 33780 additions and 0 deletions

View File

@@ -0,0 +1,586 @@
# UI Design System
ArchiTools internal design system reference. All UI decisions flow from this document.
---
## Design Philosophy
ArchiTools serves architecture and engineering professionals at Beletage SRL, Urban Switch SRL, and Studii de Teren SRL. The interface must reflect the discipline of the work itself: precise, structured, technically grounded.
**Guiding principles:**
- **Professional over playful.** No rounded bubbly elements, no bright consumer gradients, no emoji-heavy interfaces. The aesthetic is closer to a CAD toolbar than a social media dashboard.
- **Information-dense but not cluttered.** Architecture professionals need data visible at a glance. Favor card-based layouts with clear hierarchy over sparse minimalist voids.
- **Technical confidence.** Use monospaced fonts for data fields, structured grids for layout, and precise spacing. The UI should feel like a well-organized technical drawing.
- **Consistent across tools.** Every module (email signatures, XML generators, future tools) must feel like part of the same platform, not a collection of standalone pages.
- **Dark and light with equal quality.** Both themes are first-class. The dark theme is the default (matching existing tool aesthetics). The light theme must be equally polished.
---
## Color System
### Brand Colors
| Token | Hex | Usage |
|---|---|---|
| `brand-teal` | `#22B5AB` | Primary accent. Beletage brand teal. Used for active states, primary buttons, links, focus rings. |
| `brand-teal-light` | `#2DD4BF` | Hover state for teal elements. |
| `brand-teal-dark` | `#14978F` | Pressed/active state. |
Each company in the group may define an override accent color. The teal serves as the platform default and Beletage-specific accent.
| Company | Accent | Usage Context |
|---|---|---|
| Beletage SRL | `#22B5AB` (teal) | Architecture projects |
| Urban Switch SRL | TBD | Urban planning projects |
| Studii de Teren SRL | TBD | Land survey projects |
The company selector in the header drives the active accent color via a CSS custom property (`--accent`).
### Slate Backgrounds
Derived from Tailwind's `slate` scale. These form the structural palette for both themes.
**Dark theme (default):**
| Token | Tailwind Class | Hex | Usage |
|---|---|---|---|
| `bg-app` | `bg-slate-950` | `#020617` | Application background |
| `bg-card` | `bg-slate-900` | `#0f172a` | Card surfaces |
| `bg-card-elevated` | `bg-slate-800` | `#1e293b` | Elevated cards, dropdowns, popovers |
| `bg-input` | `bg-slate-950` | `#020617` | Input field backgrounds |
| `border-default` | `border-slate-700` | `#334155` | Card borders, dividers |
| `border-subtle` | `border-slate-800` | `#1e293b` | Subtle separators |
| `text-primary` | `text-slate-100` | `#f1f5f9` | Primary text |
| `text-secondary` | `text-slate-400` | `#94a3b8` | Secondary text, labels |
| `text-muted` | `text-slate-500` | `#64748b` | Disabled text, placeholders |
**Light theme:**
| Token | Tailwind Class | Hex | Usage |
|---|---|---|---|
| `bg-app` | `bg-slate-50` | `#f8fafc` | Application background |
| `bg-card` | `bg-white` | `#ffffff` | Card surfaces |
| `bg-card-elevated` | `bg-slate-50` | `#f8fafc` | Elevated cards |
| `bg-input` | `bg-white` | `#ffffff` | Input field backgrounds |
| `border-default` | `border-slate-200` | `#e2e8f0` | Card borders, dividers |
| `border-subtle` | `border-slate-100` | `#f1f5f9` | Subtle separators |
| `text-primary` | `text-slate-900` | `#0f172a` | Primary text |
| `text-secondary` | `text-slate-600` | `#475569` | Secondary text, labels |
| `text-muted` | `text-slate-400` | `#94a3b8` | Disabled text, placeholders |
### Semantic Colors
| Semantic | Light | Dark | Usage |
|---|---|---|---|
| `success` | `#16a34a` (green-600) | `#22c55e` (green-500) | Confirmations, valid states |
| `warning` | `#d97706` (amber-600) | `#f59e0b` (amber-500) | Caution states, non-blocking issues |
| `error` | `#dc2626` (red-600) | `#ef4444` (red-500) | Errors, destructive actions |
| `info` | `#2563eb` (blue-600) | `#3b82f6` (blue-500) | Informational highlights |
Each semantic color has a background variant at 10% opacity for alert/badge backgrounds:
- `bg-success`: `success / 10%` over card background
- Same pattern for `warning`, `error`, `info`
### Theme Implementation
Theme is managed by `next-themes` with the `attribute="class"` strategy. Tailwind's `darkMode: "class"` is enabled. All theme-dependent styles use the `dark:` prefix.
```tsx
// layout.tsx
import { ThemeProvider } from 'next-themes';
<ThemeProvider attribute="class" defaultTheme="dark" enableSystem>
{children}
</ThemeProvider>
```
CSS custom properties for the accent color are set on `<html>` based on the active company selection:
```css
:root {
--accent: 34 181 171; /* #22B5AB in RGB */
--accent-foreground: 255 255 255;
}
```
Components reference accent via `bg-[rgb(var(--accent))]` or through shadcn/ui's HSL-based theming variables in `globals.css`.
---
## Typography
### Font Stack
Primary: `Inter` (loaded via `next/font/google`), falling back to `system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`.
Monospace (for code, XML output, data fields): `"JetBrains Mono", "Fira Code", ui-monospace, monospace`.
### Size Scale
All sizes reference Tailwind's default scale. Do not use arbitrary pixel values.
| Token | Tailwind | Size | Usage |
|---|---|---|---|
| `text-xs` | `text-xs` | 0.75rem / 12px | Badges, fine print, metadata |
| `text-sm` | `text-sm` | 0.875rem / 14px | Labels, secondary text, table cells |
| `text-base` | `text-base` | 1rem / 16px | Body text, input values |
| `text-lg` | `text-lg` | 1.125rem / 18px | Card titles, section headers |
| `text-xl` | `text-xl` | 1.25rem / 20px | Page section titles |
| `text-2xl` | `text-2xl` | 1.5rem / 24px | Page titles |
| `text-3xl` | `text-3xl` | 1.875rem / 30px | Dashboard hero stats only |
### Font Weight
| Weight | Tailwind | Usage |
|---|---|---|
| 400 | `font-normal` | Body text |
| 500 | `font-medium` | Labels, table headers, navigation items |
| 600 | `font-semibold` | Card titles, section headers |
| 700 | `font-bold` | Page titles, stat values |
### Line Height
Use Tailwind defaults. Override only for tight stat displays (`leading-tight` / `leading-none` on large numeric values).
---
## Component Library
### Base: shadcn/ui
All interactive components are built on [shadcn/ui](https://ui.shadcn.com/). Components are installed into `src/shared/components/ui/` via the shadcn CLI and customized in place.
**Customization approach:**
1. Install the shadcn/ui component (`npx shadcn@latest add button`).
2. The component lands in `src/shared/components/ui/button.tsx`.
3. Modify theme tokens in `globals.css` to match our color system.
4. Extend component variants if needed (e.g., adding a `brand` variant to `Button`).
5. Never wrap shadcn components in another abstraction layer unless adding substantial logic. Use them directly.
**Key shadcn/ui components in use:**
- `Button` -- primary actions, secondary actions, destructive actions, ghost navigation
- `Input`, `Textarea`, `Select` -- form controls
- `Card`, `CardHeader`, `CardContent`, `CardFooter` -- content containers
- `Dialog`, `AlertDialog` -- modal interactions (replaces `alert()`/`confirm()`)
- `DropdownMenu` -- context menus, overflow actions
- `Tabs` -- in-page mode switching (e.g., simple/advanced toggle)
- `Table` -- data display
- `Badge` -- status indicators, category labels
- `Tooltip` -- icon-only button labels
- `Separator` -- visual dividers
- `Switch`, `Checkbox` -- boolean toggles
- `Breadcrumb` -- navigation breadcrumbs in header
- `Sidebar` -- app shell navigation (shadcn sidebar component)
- `Sheet` -- mobile navigation drawer
---
## Layout System
### App Shell
The application uses a fixed sidebar + header + scrollable content area layout.
```
+--------------------------------------------------+
| [Sidebar] | [Header: breadcrumbs | theme | co] |
| |--------------------------------------|
| Nav | |
| items | [Content area] |
| | |
| grouped | max-w-6xl mx-auto px-6 py-6 |
| by | |
| category | |
| | |
+--------------------------------------------------+
```
### Sidebar
- Width: `16rem` (256px) expanded, `3rem` (48px) collapsed (icon-only mode).
- Collapsible via a toggle button at the bottom of the sidebar.
- Collapse state persisted to localStorage via a cookie (for SSR compatibility with `next-themes`).
- Background: `bg-slate-900` (dark) / `bg-white` (light) with a right border.
- Navigation items are grouped by category. Groups are driven by the module registry (`src/config/modules.ts`).
**Navigation structure:**
```
INSTRUMENTE (Tools)
- Semnatura Email
- Generator XML Word
ADMINISTRARE (Admin)
- Etichete Proiecte (Project Tags)
- Configurare (Settings)
(future groups added via module registry)
```
Each nav item displays:
- A Lucide icon (24x24)
- The module label (from `labels.ts`)
- An optional badge (e.g., count of saved configs)
Active state: teal left border + teal-tinted background (`bg-teal-500/10`).
### Header
Fixed at the top of the content area. Contains:
1. **Breadcrumbs** (left): Module group > Module name > Sub-page. Uses shadcn `Breadcrumb`.
2. **Company selector** (center-right): Dropdown to switch active company context. Drives branding colors and available configurations.
3. **Theme toggle** (right): Sun/Moon icon button. Toggles between dark/light via `next-themes`.
4. **User area** (far right, future): Avatar + dropdown for auth when implemented.
Height: `h-14` (56px). Bottom border separator.
### Content Area
- Container: `max-w-6xl mx-auto px-4 sm:px-6 py-6`
- For full-width tools (e.g., XML generator with preview): use `max-w-7xl` or remove max-width constraint.
- Content scrolls independently of sidebar and header.
---
## Card Patterns
### Primary Content Card
The standard content container. Used for forms, configuration panels, output displays.
```tsx
<Card>
<CardHeader>
<CardTitle>Configurare Semnatura</CardTitle>
<CardDescription>Completati datele pentru generarea semnaturii.</CardDescription>
</CardHeader>
<CardContent>
{/* form fields, content */}
</CardContent>
<CardFooter>
{/* action buttons */}
</CardFooter>
</Card>
```
Styling: `rounded-xl border` with theme-appropriate background. No drop shadows in light mode (border is sufficient). Subtle shadow in dark mode (`shadow-lg shadow-black/20`).
### Stat Card
For dashboard counters and KPIs.
```tsx
<Card className="p-6">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-muted-foreground">{label}</p>
<p className="text-3xl font-bold leading-none mt-1">{value}</p>
</div>
<div className="rounded-lg bg-teal-500/10 p-3">
<Icon className="h-6 w-6 text-teal-500" />
</div>
</div>
</Card>
```
### Widget Card
For dashboard widgets (quick actions, recent items, external links).
Same structure as primary content card but with a fixed height and internal scroll if content overflows. Header includes an optional "View all" link.
---
## Form Patterns
### Input Groups
Each form field follows this structure:
```tsx
<div className="space-y-2">
<Label htmlFor="field-id">{labels.fieldName}</Label>
<Input id="field-id" {...props} />
<p className="text-xs text-muted-foreground">{labels.fieldHint}</p>
</div>
```
- Labels come from the label constants file (never hardcoded Romanian strings in JSX).
- Hints are optional `text-xs text-muted-foreground` paragraphs below the input.
- Required fields: no asterisk; instead, validation messages appear on submit.
### Form Layout
- Single column for simple forms.
- Two-column grid (`grid grid-cols-1 md:grid-cols-2 gap-4`) for forms with many short fields.
- Full-width fields (textareas, complex inputs) span both columns via `md:col-span-2`.
### Validation Display
Validation errors appear below the field as `text-xs text-destructive`:
```tsx
{error && <p className="text-xs text-destructive">{error}</p>}
```
Input border turns red on error: `border-destructive`.
### Romanian Labels
All user-facing text is sourced from `src/core/i18n/labels.ts`. Components reference label keys:
```tsx
import { labels } from '@/core/i18n/labels';
<Label>{labels.signature.fieldName}</Label>
```
Never write Romanian text directly in JSX. This ensures consistency, makes future i18n possible, and centralizes all copy for review.
### Label File Structure
```ts
// src/core/i18n/labels.ts
export const labels = {
common: {
save: 'Salveaza',
cancel: 'Anuleaza',
delete: 'Sterge',
download: 'Descarca',
copy: 'Copiaza',
generate: 'Genereaza',
reset: 'Reseteaza',
loading: 'Se incarca...',
noData: 'Nu exista date.',
confirm: 'Confirmare',
search: 'Cauta',
},
nav: {
tools: 'Instrumente',
admin: 'Administrare',
emailSignature: 'Semnatura Email',
xmlGenerator: 'Generator XML Word',
tagManager: 'Etichete Proiecte',
settings: 'Configurare',
},
signature: {
title: 'Configurator Semnatura Email',
fieldPrefix: 'Titulatura (prefix)',
fieldName: 'Nume si Prenume',
fieldRole: 'Functia',
fieldPhone: 'Telefon (format 07xxxxxxxx)',
sectionColors: 'Culori Text',
sectionLayout: 'Stil & Aranjare',
sectionOptions: 'Optiuni',
optionReply: 'Varianta simpla (fara logo/adresa)',
optionSuperReply: 'Super-simpla (doar nume/telefon)',
optionSvg: 'Foloseste imagini SVG (calitate maxima)',
exportHtml: 'Descarca HTML',
preview: 'Previzualizare Live',
},
xml: {
title: 'Generator XML pentru Word',
fieldNamespace: 'Namespace URI',
fieldRootElement: 'Element radacina',
fieldList: 'Lista de campuri (unul pe linie)',
modeSimple: 'Simplu',
modeAdvanced: 'Avansat',
categoryLabel: 'Categorii de date',
addCategory: 'Adauga categorie',
resetPreset: 'Reset categorie la preset',
clearFields: 'Curata campurile',
generateAll: 'Genereaza XML pentru toate categoriile',
downloadCurrent: 'Descarca XML categorie curenta',
downloadZip: 'Descarca ZIP cu toate XML-urile',
previewXml: 'XML categorie curenta',
previewXpath: 'XPaths categorie curenta',
},
// Additional module labels added here as modules are built.
} as const;
export type LabelKey = typeof labels;
```
---
## Table Patterns
Data tables use shadcn/ui `Table` components with the following conventions:
- **Header**: `font-medium text-sm text-muted-foreground`, no background color differentiation.
- **Rows**: alternating subtle background on hover (`hover:bg-muted/50`).
- **Sortable columns**: click header to toggle. Arrow indicator next to sorted column.
- **Filtering**: text input above the table, filters by visible columns.
- **Pagination**: below the table. "X of Y results" + page controls.
- **Empty state**: centered message inside the table area using `labels.common.noData`.
For complex data tables, use `@tanstack/react-table` as the headless engine with shadcn/ui table components for rendering.
---
## Dashboard Widgets
The dashboard home page (`/`) uses a responsive grid of widget cards.
### Layout
```tsx
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4 gap-4">
{/* stat cards row */}
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4 mt-4">
{/* widget cards */}
</div>
```
### Widget Types
1. **Stat counters**: Number of saved signature configs, XML templates, etc. Uses Stat Card pattern.
2. **Recent items**: Last 5 saved/exported items across tools. List format inside a widget card.
3. **Quick actions**: Buttons to jump to common tasks ("New signature", "New XML template"). Grid of icon+label buttons.
4. **External tool links**: If legacy HTML tools are still accessible, link out to them with an "external" icon.
Widgets are defined in a registry and rendered dynamically. Each widget is a self-contained component that fetches its own data.
---
## Icon System
All icons use [Lucide React](https://lucide.dev/) (`lucide-react` package).
**Usage:**
```tsx
import { Mail, FileCode, Settings, ChevronRight } from 'lucide-react';
<Mail className="h-5 w-5" />
```
**Conventions:**
- Navigation icons: `h-5 w-5`
- Inline icons (next to text): `h-4 w-4`
- Stat card icons: `h-6 w-6`
- Button icons: `h-4 w-4 mr-2` (left of label) or `h-4 w-4 ml-2` (right of label)
- Icon-only buttons must have a `Tooltip` or `aria-label`.
**Do not** use SVG icons inline. Do not use icon fonts. Do not mix icon libraries.
---
## Spacing and Grid Conventions
All spacing uses Tailwind's default 4px-based scale.
| Context | Spacing | Tailwind |
|---|---|---|
| Between form fields | 8px | `space-y-2` |
| Between card sections | 16px | `space-y-4` |
| Card internal padding | 24px | `p-6` |
| Grid gap (cards) | 16px | `gap-4` |
| Page padding (desktop) | 24px | `px-6 py-6` |
| Page padding (mobile) | 16px | `px-4 py-4` |
Grid uses Tailwind's `grid` utility with responsive column counts:
- `grid-cols-1` (mobile)
- `md:grid-cols-2` (tablet)
- `lg:grid-cols-3` (desktop)
- `xl:grid-cols-4` (wide desktop, stat cards only)
---
## Responsive Breakpoints
Using Tailwind's default breakpoints:
| Breakpoint | Min-width | Typical device |
|---|---|---|
| `sm` | 640px | Large phone, small tablet |
| `md` | 768px | Tablet portrait |
| `lg` | 1024px | Tablet landscape, small desktop |
| `xl` | 1280px | Desktop |
| `2xl` | 1536px | Wide desktop |
**Behavior:**
- Below `lg`: sidebar collapses to a mobile drawer (shadcn `Sheet`).
- Below `md`: single-column content layout.
- At `lg` and above: sidebar visible, two-column form layouts.
- At `xl` and above: four-column stat card grid.
---
## Animation Guidelines
Animations are minimal and purposeful. This is a professional tool, not a marketing site.
**Allowed animations:**
- **Transitions on interactive elements**: `transition-colors duration-150` on buttons, links, nav items.
- **Sidebar collapse/expand**: `transition-[width] duration-200 ease-in-out`.
- **Card hover elevation** (optional): `transition-shadow duration-150`.
- **Dialog/sheet enter/exit**: Use shadcn/ui defaults (Radix UI built-in animations).
- **Skeleton loading**: `animate-pulse` on placeholder blocks during data loading.
**Not allowed:**
- Page transition animations.
- Bouncing, jiggling, or attention-seeking element animations.
- Parallax or scroll-linked effects.
- Auto-playing animations that loop indefinitely (except loading spinners).
- Transform-based hover effects on buttons (`hover:scale-105` and similar -- this was used in the legacy HTML tools but is too playful for the dashboard).
---
## Accessibility Baseline
- All interactive elements must be keyboard navigable.
- Focus rings: `focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2`.
- Color contrast: minimum 4.5:1 for text, 3:1 for large text and UI elements (WCAG AA).
- Images and icons: `alt` text on informational images, `aria-hidden="true"` on decorative icons, `aria-label` on icon-only buttons.
- Form fields: every `<Input>` has an associated `<Label>` via `htmlFor`/`id`.
- Dialogs: use shadcn/ui `Dialog` which handles focus trapping and `aria-*` attributes.
- No information conveyed by color alone (always pair with text or icon).
- Reduced motion: respect `prefers-reduced-motion` by wrapping non-essential animations in `motion-safe:`.
---
## Summary: Design Tokens Quick Reference
```css
/* globals.css -- theme tokens (simplified) */
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--primary: 174 68% 41%; /* #22B5AB */
--primary-foreground: 0 0% 100%;
--muted: 210 40% 96%;
--muted-foreground: 215.4 16.3% 46.9%;
--border: 214.3 31.8% 91.4%;
--ring: 174 68% 41%;
--radius: 0.75rem;
}
.dark {
--background: 222.2 84% 2%; /* #020617 */
--foreground: 210 40% 93%;
--card: 222.2 84% 5%; /* #0f172a */
--card-foreground: 210 40% 93%;
--primary: 174 68% 41%;
--primary-foreground: 0 0% 100%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--border: 217.2 32.6% 17.5%;
--ring: 174 68% 41%;
}
```