# Domain Entities — react-frontend-app ## Overview This unit has no persisted backend entities. The "domain" here is the static content model and the theme model that drive rendering. ## Entity Relationships ```mermaid graph TD theme_pref["ThemePreference"] theme_tokens["ThemeTokens"] site_content["SiteContent"] nav_link["NavLink"] hero_content["HeroContent"] package_card["PackageCard"] process_step["ProcessStep"] about_content["AboutContent"] contact_info["ContactInfo"] theme_pref -->|"selects"| theme_tokens site_content -->|"has many"| nav_link site_content -->|"has one"| hero_content site_content -->|"has many"| package_card site_content -->|"has many"| process_step site_content -->|"has one"| about_content site_content -->|"has one"| contact_info classDef entity fill:#2196F3,stroke:#0d47a1,stroke-width:1px,color:#000; classDef value fill:#FF9800,stroke:#e65100,stroke-width:1px,color:#000; class theme_pref,site_content entity; class theme_tokens,nav_link,hero_content,package_card,process_step,about_content,contact_info value; ``` Text alternative: A ThemePreference selects a set of ThemeTokens; SiteContent aggregates NavLinks, one HeroContent, many PackageCards, many ProcessSteps, one AboutContent, and one ContactInfo (blue = stateful entity, orange = static value objects). ## Entity Definitions ### ThemePreference | Field | Type | Required | Description | |---|---|---|---| | `value` | `'red' \| 'purple'` | Yes | Currently active theme; defaults to `'red'` per BR-1 | | `source` | `'stored' \| 'default'` | Yes | Whether the value came from `localStorage` or the default fallback | ### ThemeTokens | Field | Type | Required | Description | |---|---|---|---| | `bg`, `surface`, `surfaceAlt`, `line`, `text`, `muted` | `string` (hex) | Yes | Neutral palette tokens, taken 1-to-1 from the reference CSS variables | | `accent`, `accentSoft`, `accentLine` | `string` (hex/rgba) | Yes | Accent palette tokens (red or purple variant), taken 1-to-1 from the reference CSS variables | ### NavLink | Field | Type | Required | Description | |---|---|---|---| | `label` | `string` | Yes | Link text (e.g. "Pakketten") | | `href` | `string` | Yes | Anchor target (e.g. "#pakketten") | | `isCta` | `boolean` | No | Marks the "Start project" call-to-action link | ### HeroContent | Field | Type | Required | Description | |---|---|---|---| | `eyebrow` | `string` | Yes | Small label above the heading | | `heading` | `string` | Yes | Main H1 text | | `lead` | `string` | Yes | Lead paragraph text | | `codeLine` | `string` | Yes | The animated code-line snippet text | ### PackageCard | Field | Type | Required | Description | |---|---|---|---| | `id` | `string` | Yes | e.g. `pakket_01` | | `title` | `string` | Yes | e.g. "Landingspagina" | | `description` | `string` | Yes | Short description | | `price` | `string` | Yes | e.g. "€ 300" or "Op maat" | | `priceNote` | `string` | Yes | e.g. "eenmalig, excl. btw" | | `features` | `string[]` | Yes | Bullet list of included features | | `ctaLabel` | `string` | Yes | Button text | | `featured` | `boolean` | No | Marks the "Meest gekozen" (most chosen) card | ### ProcessStep | Field | Type | Required | Description | |---|---|---|---| | `label` | `string` | Yes | e.g. "stap 01 — intake" | | `title` | `string` | Yes | e.g. "Kennismaken" | | `description` | `string` | Yes | Step description | ### AboutContent | Field | Type | Required | Description | |---|---|---|---| | `paragraphs` | `string[]` | Yes | About-section body paragraphs | | `techStack` | `{ label: string; value: string }[]` | Yes | Tech-stack list items (Front-end, Back-end, API's, Focus) | ### ContactInfo | Field | Type | Required | Description | |---|---|---|---| | `heading` | `string` | Yes | Contact section heading | | `description` | `string` | Yes | Contact section body text | | `email` | `string` | Yes | `info@slpsoftware.nl` | | `mailSubject` | `string` | Yes | Prefilled mailto subject |