# 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'; {children} ``` CSS custom properties for the accent color are set on `` 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 Configurare Semnatura Completati datele pentru generarea semnaturii. {/* form fields, content */} {/* action buttons */} ``` 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

{label}

{value}

``` ### 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

{labels.fieldHint}

``` - 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 &&

{error}

} ``` 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'; ``` 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
{/* stat cards row */}
{/* widget cards */}
``` ### 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'; ``` **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 `` has an associated `