Files
ss-tools/specs/013-unify-frontend-css/research.md
2026-01-23 14:56:05 +03:00

2.8 KiB

Research: Unify Frontend CSS & Localization

1. Design System & Theming

Decision: Use Tailwind CSS as the engine for the design system, but encapsulate usage within reusable Svelte components (src/lib/ui/*).

Rationale:

  • Consistency: Centralizing styles in components ensures that a "Button" always looks like a "Button" without copy-pasting utility classes.
  • Maintainability: Tailwind configuration (tailwind.config.js) will hold the "Design Tokens" (colors, spacing), while components hold the "Structure".
  • Speed: Tailwind is already integrated and allows for rapid development.

Alternatives Considered:

  • Pure CSS/SCSS Modules: Rejected because it requires more boilerplate and context switching between files.
  • Component Library (e.g., Skeleton, Flowbite): Rejected to maintain full control over the visual identity and avoid bloat, but we will use the "Headless UI" concept where we build our own accessible components.

2. Internationalization (i18n)

Decision: Implement a lightweight, store-based i18n solution using Svelte stores and JSON dictionaries.

Rationale:

  • Simplicity: For just two languages (RU, EN) and a moderate number of strings, a full-blown library like svelte-i18n or i18next adds unnecessary complexity and bundle size.
  • Control: A custom store allows us to easily handle localStorage persistence and reactive updates across the app without fighting library-specific lifecycle issues.
  • Performance: Direct object lookups are extremely fast.

Implementation Detail:

  • src/lib/i18n/index.ts: Exports a derived store t that reacts to the current locale store.
  • src/lib/i18n/locales/ru.json: Default dictionary.
  • src/lib/i18n/locales/en.json: English dictionary.

Alternatives Considered:

  • svelte-i18n: Good library, but overkill for current requirements.
  • Server-side i18n: Rejected because the requirement specifies client-side persistence (LocalStorage) and immediate switching without page reloads.

3. Component Architecture

Decision: Create "Atomic" components in src/lib/ui that expose props for variants (e.g., variant="primary" | "secondary").

Proposed Components:

  • Button.svelte: Handles variants, sizes, loading states.
  • Card.svelte: Standard container with padding/shadow.
  • Input.svelte: Standardized text input with label and error state.
  • Select.svelte: Standardized dropdown.
  • PageHeader.svelte: Unified title and actions area for pages.

Rationale: These cover 80% of the UI inconsistency issues identified in the spec.

4. Migration Strategy

Decision: "Strangler Fig" pattern - create new components first, then incrementally replace usage in src/routes and existing src/components.

Rationale: Allows the application to remain functional at all times. We can migrate one page or one section at a time.