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>
21 KiB
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.
// 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:
: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. Components are installed into src/shared/components/ui/ via the shadcn CLI and customized in place.
Customization approach:
- Install the shadcn/ui component (
npx shadcn@latest add button). - The component lands in
src/shared/components/ui/button.tsx. - Modify theme tokens in
globals.cssto match our color system. - Extend component variants if needed (e.g., adding a
brandvariant toButton). - 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 navigationInput,Textarea,Select-- form controlsCard,CardHeader,CardContent,CardFooter-- content containersDialog,AlertDialog-- modal interactions (replacesalert()/confirm())DropdownMenu-- context menus, overflow actionsTabs-- in-page mode switching (e.g., simple/advanced toggle)Table-- data displayBadge-- status indicators, category labelsTooltip-- icon-only button labelsSeparator-- visual dividersSwitch,Checkbox-- boolean togglesBreadcrumb-- navigation breadcrumbs in headerSidebar-- 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:
- Breadcrumbs (left): Module group > Module name > Sub-page. Uses shadcn
Breadcrumb. - Company selector (center-right): Dropdown to switch active company context. Drives branding colors and available configurations.
- Theme toggle (right): Sun/Moon icon button. Toggles between dark/light via
next-themes. - 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-7xlor 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.
<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.
<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:
<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-foregroundparagraphs 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:
{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:
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
// 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
<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
- Stat counters: Number of saved signature configs, XML templates, etc. Uses Stat Card pattern.
- Recent items: Last 5 saved/exported items across tools. List format inside a widget card.
- Quick actions: Buttons to jump to common tasks ("New signature", "New XML template"). Grid of icon+label buttons.
- 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 (lucide-react package).
Usage:
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) orh-4 w-4 ml-2(right of label) - Icon-only buttons must have a
Tooltiporaria-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 (shadcnSheet). - Below
md: single-column content layout. - At
lgand above: sidebar visible, two-column form layouts. - At
xland 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-150on 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-pulseon 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-105and 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:
alttext on informational images,aria-hidden="true"on decorative icons,aria-labelon icon-only buttons. - Form fields: every
<Input>has an associated<Label>viahtmlFor/id. - Dialogs: use shadcn/ui
Dialogwhich handles focus trapping andaria-*attributes. - No information conveyed by color alone (always pair with text or icon).
- Reduced motion: respect
prefers-reduced-motionby wrapping non-essential animations inmotion-safe:.
Summary: Design Tokens Quick Reference
/* 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%;
}