# Zemail (iMail) — Design System & UI/UX Guidelines
> **Version:** 1.1.0 — Last updated: 2026-03-06
>
> This document is the single source of truth for every visual, interactive, and architectural decision in the Zemail project. Any developer or AI agent working on this codebase **must** read this document before making any frontend changes, and **must** update it after completing any UI/UX-related work.
---
## Table of Contents
1. [Activated Skills & References](#1-activated-skills--references)
2. [Design Philosophy](#2-design-philosophy)
3. [Tech Stack](#3-tech-stack)
4. [Aesthetic Preset: "DevTool Dark"](#4-aesthetic-preset-devtool-dark)
5. [Design Tokens (CSS Custom Properties)](#5-design-tokens-css-custom-properties)
6. [Typography](#6-typography)
7. [Color System](#7-color-system)
8. [Spacing & Layout](#8-spacing--layout)
9. [Component Library](#9-component-library)
10. [Animation & Micro-Interactions](#10-animation--micro-interactions)
11. [Real-Time UI Patterns](#11-real-time-ui-patterns)
12. [Responsive Design Rules](#12-responsive-design-rules)
13. [Accessibility](#13-accessibility)
14. [Iteration History & Design Decisions](#14-iteration-history--design-decisions)
15. [Maintenance Protocol (MANDATORY)](#15-maintenance-protocol-mandatory)
---
## 1. Activated Skills & References
The following `.agents/skills` were activated during the initial design and development of this project. **Any future developer or AI agent must activate the relevant skill before working in that domain.**
| Skill | Path | When to Activate |
|-------|------|------------------|
| **`bento-landing-page-generator`** | `.agents/skills/bento-landing-page-generator/SKILL.md` | Building or modifying Bento-style landing pages, hero sections, feature grids. This was the **primary skill** used to establish the entire visual language of this project. |
| **`tailwindcss-development`** | `.agents/skills/tailwindcss-development/SKILL.md` | Any styling work. Uses Tailwind CSS **v4** with CSS-first `@theme` configuration. Never use deprecated v3 utilities. |
| **`fluxui-development`** | `.agents/skills/fluxui-development/SKILL.md` | Building forms, modals, inputs, or interactive UI components. Uses the **Flux UI Free** edition. |
| **`volt-development`** | `.agents/skills/volt-development/SKILL.md` | Creating single-file Livewire components. Check existing Volt components for functional vs. class-based style before creating new ones. |
| **`cinematic-landing-page-builder`** | `.agents/skills/cinematic-landing-page-builder/SKILL.md` | Building cinematic, pixel-perfect landing pages with strict design system enforcement, micro-interactions, and GSAP animations. |
| **`pest-testing`** | `.agents/skills/pest-testing/SKILL.md` | Writing or modifying tests. Uses Pest 3. |
### External References Used
- **Appwrite Dashboard** — Dark UI inspiration for surface colors, card borders, and glow effects.
- **Vercel** — Minimal dark theme, clean typography hierarchy, terminal-style code blocks.
- **Stripe / BentoNow** — Asymmetric Bento Grid layout patterns, card span ratios.
- **Heroicons** — Default icon set. Search at [heroicons.com](https://heroicons.com/). Never guess icon names.
---
## 2. Design Philosophy
### Core Principles
1. **Premium-First**: Every element must feel premium and state-of-the-art. No basic MVPs, no generic layouts. The user should be "wowed" at first glance.
2. **Dark Mode Native**: The application is dark-mode-only (`class="dark"` on ``). All design tokens, colors, and contrasts are optimized for dark backgrounds.
3. **Cinematic Motion**: Interfaces should feel alive. Use GSAP for scroll-driven reveals, Alpine.js for instant state transitions, and CSS `transition-all` for micro-interactions.
4. **Information Density**: Mailbox UIs are information-dense by nature. Use compact typography (`text-[10px]`, `text-[11px]`), uppercase tracking (`tracking-widest`, `tracking-[0.2em]`), and monospace fonts for data.
5. **No Placeholders**: Never use placeholder images or `lorem ipsum`. Build all visuals with HTML/CSS/SVG. Use `generate_image` tool if real images are needed.
6. **Glassmorphism & Glow**: Frosted glass effects (`backdrop-blur-xl`, `bg-white/5`) and colored glows (`shadow-[0_0_30px_rgba(236,72,153,0.3)]`) are signature visual elements.
### The "Bento Box" Layout Rules
- Use **asymmetric CSS Grids** (e.g., `grid-cols-1 md:grid-cols-3` or `md:grid-cols-4`).
- Cards must have **distinct spans** (`col-span-2`, `row-span-2`) to create a mosaic effect.
- All cards use `rounded-2xl` or `rounded-3xl` border radii.
- Cards use `bg-zinc-900` surface color with `border border-white/5` borders.
- Background glows inside cards use `blur-2xl` with accent color at very low opacity (`bg-pink-500/5`).
---
## 3. Tech Stack
| Layer | Technology | Version |
|-------|-----------|---------|
| Backend | Laravel | v12 |
| Real-Time | Livewire | v3 |
| Client-Side Reactivity | Alpine.js | (bundled with Livewire) |
| Styling | Tailwind CSS | v4 |
| Animations | GSAP | 3.12.5 |
| Component Library | Flux UI Free | v2 |
| WebSocket | Laravel Reverb | v1 |
| Fonts | Google Fonts (via Bunny) | Inter, JetBrains Mono |
| Icons | Heroicons (via Flux) | — |
| QR Generator | QRious | 4.0.2 |
| Build Tool | Vite | v7 |
### Asset Pipeline
```
resources/css/app.css → Tailwind v4 with @theme design tokens
resources/js/app.js → Laravel Echo + Pusher + WebSocket status dispatching
resources/views/ → Blade templates, Livewire components, anonymous components
```
All frontend changes require `npm run build` (or `npm run dev` during development) to take effect.
---
## 4. Aesthetic Preset: "DevTool Dark"
This project uses **Preset A — "DevTool Dark"**, inspired by Appwrite and Vercel.
| Property | Value |
|----------|-------|
| Background | `#09090B` (`bg-app-bg`) |
| Surface | `#18181B` (`bg-app-surface` / `bg-zinc-900`) |
| Borders | `#27272A` (`border-app-border` / `border-white/5`) |
| Primary Accent | `#EC4899` (Pink) |
| Secondary Accent | `#10B981` (Emerald) |
| Text Primary | `#FAFAFA` |
| Text Secondary | `#737373` (`text-zinc-500`) |
| Text Muted | `#525252` (`text-zinc-600`) |
| Selection Highlight | `rgba(236, 72, 153, 0.3)` (`selection:bg-[#EC4899]/30`) |
---
## 5. Design Tokens (CSS Custom Properties)
All design tokens are defined in `resources/css/app.css` using Tailwind v4's CSS-first `@theme` directive.
```css
@theme {
/* Core Application Colors */
--color-app-bg: #09090B;
--color-app-surface: #18181B;
--color-app-border: #27272A;
--color-app-red: #EC6A5F; /* macOS-style traffic light red */
--color-app-yellow: #F4BF4F; /* macOS-style traffic light yellow */
--color-app-green: #61C554; /* macOS-style traffic light green */
/* Zinc Scale (Dark Mode Neutrals) */
--color-zinc-50: #fafafa;
--color-zinc-500: #737373;
--color-zinc-600: #525252;
--color-zinc-800: #262626;
--color-zinc-900: #171717;
--color-zinc-950: #0a0a0a;
/* Primary (Purple/Indigo Scale — used for accents) */
--color-primary-500: #787ddc;
--color-primary-600: #615dce;
/* App Primary (oklch scale — for gradients and advanced color) */
--color-app-primary-500: oklch(0.589 0.137 290.02);
--color-app-primary-600: oklch(0.506 0.16 288.92);
/* Typography */
--font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif;
}
```
### Important Token Rules
- **Never hardcode colors** that already exist as tokens. Use `bg-app-bg`, `text-zinc-500`, etc.
- **Opacity modifiers** use the Tailwind v4 slash syntax: `bg-pink-500/10`, not the deprecated `bg-opacity-*`.
- **New tokens** must be added to `@theme {}` in `app.css`, not in a `tailwind.config.js` file (Tailwind v4 is CSS-first).
---
## 6. Typography
### Font Stack
| Usage | Font | Weight | Loaded Via |
|-------|------|--------|------------|
| Body & UI | **Inter** | 400, 500, 600, 700 | Bunny Fonts CDN |
| Code, Data, Addresses | **JetBrains Mono** | 400, 500 | Bunny Fonts CDN |
### Font Loading
```html
```
### Typography Scale
| Element | Classes | Example Usage |
|---------|---------|---------------|
| Page Heading | `text-2xl font-black tracking-tight uppercase italic` | Confirm modal title |
| Section Label | `text-[10px] font-bold text-zinc-500 uppercase tracking-widest` | "Active Mailbox", "Your Sessions" |
| Category Label | `text-[10px] font-bold text-zinc-600 uppercase tracking-[0.2em]` | Sidebar section headers |
| Data Display (email) | `text-[11px] font-mono text-white break-all` | Email address display |
| Toast Type Label | `text-[10px] font-black uppercase tracking-[0.2em] opacity-40` | Toast "SUCCESS", "INFO" label |
| Toast Message | `text-[11px] font-bold tracking-wide whitespace-pre-wrap` | Toast notification body |
| Button Text | `text-xs font-bold` | Primary action buttons |
| Compact Button Text | `text-[10px] font-black uppercase tracking-[0.2em]` | Modal confirm/cancel buttons |
| Timer Display | `text-[10px] font-mono text-pink-500` | Expiration countdown |
| Badge/Count | `text-[10px] font-bold px-1.5 py-0.5` | Unread count badge |
### Typography Rules
- **No comments in code** unless logic is exceptionally complex. Use PHPDoc blocks instead.
- **Uppercase + Wide Tracking** is the signature style for labels and metadata text.
- **Monospace (`font-mono`)** is used for any machine-readable data: email addresses, timers, code blocks.
- **`break-all`** must be applied to email addresses to prevent overflow on small screens.
---
## 7. Color System
### Semantic Color Mapping
These semantic colors are used consistently across all components (toasts, modals, buttons, indicators):
| Semantic | Background | Border | Text | Icon BG | Glow |
|----------|-----------|--------|------|---------|------|
| **Success** | `bg-emerald-500/10` | `border-emerald-500/20` | `text-emerald-100` | `bg-emerald-500/20 text-emerald-400` | `bg-emerald-500/10` |
| **Info** | `bg-blue-500/10` | `border-blue-500/20` | `text-blue-100` | `bg-blue-500/20 text-blue-400` | `bg-blue-400/10` |
| **Warning** | `bg-amber-500/10` | `border-amber-500/20` | `text-amber-100` | `bg-amber-500/20 text-amber-400` | `bg-amber-400/10` |
| **Danger** | `bg-rose-500/10` | `border-rose-500/20` | `text-rose-100` | `bg-rose-500/20 text-rose-400` | `bg-rose-400/10` |
### Important Color Rules
- **Never use generic red/blue/green**. Always use the curated semantic mapping above.
- **Pink (`#EC4899` / `pink-500`)** is the project's primary accent. Used for highlights, CTAs, gradients, and the expiration progress bar.
- **Emerald (`emerald-500`)** is the secondary accent. Used for success states and the WebSocket connection indicator.
- **Rose (`rose-500`)** is used for destructive actions, errors, and the disconnected WebSocket indicator.
- The **expiration progress bar** uses a gradient from pink to emerald: `bg-gradient-to-r from-pink-500 to-emerald-500`.
- **Toast notification types**: `success`, `info`, `warning`, `danger`. **Never** use `error` — use `danger` instead.
---
## 8. Spacing & Layout
### Global Spacing Constants
| Context | Value | Tailwind Class |
|---------|-------|----------------|
| Card Padding | 16px | `p-4` |
| Card Border Radius | 16px | `rounded-2xl` |
| Modal Border Radius | 32px | `rounded-[32px]` |
| Button Border Radius | 16px | `rounded-2xl` |
| Icon Container Radius | 12px | `rounded-xl` |
| Section Gap | 24px | `space-y-6` |
| Inner Element Gap | 8px | `space-y-2` / `gap-2` |
| Toast Container Spacing | 12px | `gap-3` |
| Screen Edge Margin | 24px | `bottom-6 left-6 right-6` (responsive) |
### Layout Architecture
The main mailbox view (`mailbox.blade.php`) uses a **three-panel layout**:
```
┌──────────┬──────────────┬──────────────────────┐
│ Sidebar │ Email List │ Email Detail │
│ (280px) │ (flex-1) │ (flex-1, lg only) │
│ │ │ │
│ - Active │ - Search │ - Header │
│ Mailbox│ - Email rows │ - Body (iframe) │
│ - Create │ - Pagination │ - Attachments │
│ - Sessions │ │
└──────────┴──────────────┴──────────────────────┘
```
- Sidebar uses `w-[280px]` when open, collapses on smaller screens.
- `overflow-hidden` on `
` prevents page-level scrolling. Each panel scrolls independently.
- Use `scrollbar-hide` utility class (custom CSS) to hide scrollbars in compact panels.
### Body-Level Styling
```html
```
---
## 9. Component Library
### 9.1 Global Toast Notification System
**Location:** `resources/views/components/layouts/app.blade.php`
**Trigger:** `$this->dispatch('notify', message: '...', type: 'success')` from Livewire, or `addToast('...', 'success')` from Alpine.js.
**Event:** `@notify.window` on ``.
#### Architecture
```
└── @notify.window="addToast($event.detail.message, $event.detail.type)"
└── @ws-status.window="wsConnected = $event.detail.connected"
└──
└──
└── Toast card with icon, type label, message, close button
```
#### Allowed Types
| Type | Visual | Use Case |
|------|--------|----------|
| `success` | Emerald green | Copy to clipboard, successful actions |
| `info` | Blue | New email received, informational alerts |
| `warning` | Amber/Orange | Cooldown period active, soft warnings |
| `danger` | Rose red | Address already in use, destructive errors |
#### Design Specifications
- **Container:** `fixed bottom-6 left-6 right-6 sm:left-auto sm:right-6 z-[100]`
- Mobile: Full-width with 24px margins on both sides.
- Desktop: Anchored to bottom-right.
- **Toast Card:** `w-full sm:min-w-[320px] p-4 rounded-2xl border backdrop-blur-xl shadow-2xl`
- **Auto-dismiss:** 4000ms timeout.
- **Enter Animation:** `transition ease-out duration-500` — slides in from right with scale.
- **Leave Animation:** `transition ease-in duration-300` — fades out with scale.
- **Multiline Support:** `whitespace-pre-wrap` on message div. Use `\n` in PHP strings for line breaks.
- **Icon:** 40×40px container (`w-10 h-10 rounded-xl`) with SVG stroke icon.
- **Close Button:** `p-1.5 rounded-lg hover:bg-white/5` with X icon.
#### Toast Message Formatting Examples
```php
// Single-line (copy confirmation)
$this->dispatch('notify', message: 'Address copied to clipboard', type: 'success');
// Multi-line (new email notification)
$this->dispatch('notify',
message: "Sender: {$sender}\nSubject: {$subject}",
type: 'info'
);
// Cooldown warning with precise timer
$this->dispatch('notify',
message: "Address is in cooldown. Try again in {$remaining}.",
type: 'warning'
);
// Error (address conflict)
$this->dispatch('notify', message: 'Address already in use.', type: 'danger');
```
### 9.2 Confirm Modal
**Location:** `resources/views/components/bento/confirm-modal.blade.php`
**Trigger:** `$dispatch('open-confirm-modal', { title, message, confirmLabel, type, action })`
#### Design Specifications
- **Backdrop:** `bg-zinc-950/80 backdrop-blur-xl` — heavy frosted glass overlay.
- **Card:** `max-w-[400px] bg-zinc-900 border border-white/10 rounded-[32px] p-8` — super-rounded.
- **Glow:** `w-64 h-64 rounded-full blur-[80px] opacity-20` — type-colored radial glow behind the card.
- **Icon:** `w-16 h-16 rounded-2xl` — large, prominent, type-colored icon container.
- **Title:** `text-2xl font-black text-white tracking-tight uppercase italic` — bold, dramatic.
- **Message:** `text-xs font-bold text-zinc-500 uppercase tracking-widest leading-relaxed` — subdued.
- **Buttons:** `grid grid-cols-2 gap-4` — two equal-width buttons with `py-4 rounded-2xl`.
- **Cancel:** `bg-white/5 border border-white/10 text-zinc-400` — ghost style.
- **Confirm:** Solid type-colored background (e.g., `bg-rose-600 text-white` for danger).
#### Supported Types
Same four types as the toast system: `danger`, `info`, `warning`, `success`.
### 9.3 WebSocket Connection Indicator
**Location:** `resources/views/livewire/mailbox.blade.php` (Active Mailbox card)
**State Source:** Global `wsConnected` from ``.
```html
```
- **Connected:** Emerald green pulsing dot.
- **Disconnected:** Rose red pulsing dot.
- **Transition:** `duration-500` smooth color transition between states.
- The dot sits next to the "ACTIVE MAILBOX" label in the sidebar card.
### 9.4 Expiration Progress Bar
**Location:** `resources/views/livewire/mailbox.blade.php`
#### Design Specifications
- **Track:** `h-1 bg-white/5 rounded-full overflow-hidden`
- **Fill:** `bg-gradient-to-r from-pink-500 to-emerald-500 transition-all duration-1000 ease-linear`
- **Timer Text:** `text-[10px] font-mono text-pink-500`
- **Label:** `text-[10px] text-zinc-500 uppercase font-black tracking-tighter` — "EXPIRES IN"
#### Time Display Rules (User Iteration)
The expiration timer processes remaining time **in seconds** and displays with adaptive precision:
```javascript
// Display hierarchy (most precise possible):
if (days > 0) → "14d 23h 59m 59s"
if (hours > 0) → "23h 59m 59s"
if (mins > 0) → "59m 59s"
else → "59s"
```
> **User Iteration Note:** Originally showed "0 minutes" when only seconds remained. Fixed to always show seconds-level precision and cascade upward to days.
#### Auto-Expiration Behavior
When the timer reaches zero:
1. Alpine.js sets `isExpired = true` and fires `$wire.deleteMailbox(id)`.
2. This triggers a soft delete on the Mailbox model.
3. The `deleted` Eloquent event fires cleanup (MongoDB email bodies, MariaDB email metadata).
4. UI refreshes to show a new auto-generated mailbox.
### 9.5 Cinematic Creation Overlay
**Location:** `resources/views/livewire/mailbox.blade.php`
Shown when a first-time visitor arrives or all mailboxes are deleted:
- **Backdrop:** `fixed inset-0 z-[200] bg-zinc-950/90` — full-screen dark overlay.
- **Logo:** `animate-pulse` with scale transition (`scale-110 opacity-100` → `scale-90 opacity-0`).
- **Spinner:** Custom CSS spinner using `border-4 border-pink-500 border-t-transparent animate-[spin_1.5s_cubic-bezier(0.4,0,0.2,1)_infinite]` with pink glow shadow.
- **Auto-dismiss:** `setTimeout(() => $wire.finishAutoCreation(), 1000)` — 1 second cinematic delay.
### 9.6 Action Button Patterns
#### Icon Buttons (Toolbar Style)
```html
```
#### Full-Width CTA Button
```html
```
#### Key Button Rules
- All buttons must have `cursor-pointer`.
- Icon containers inside buttons use `group-hover:scale-110 transition-transform` for a micro-interaction.
- Destructive buttons use the rose color scale at reduced opacity (`rose-500/10`, `rose-500/60`).
- Ghost buttons use `bg-white/5 border border-white/10`.
---
## 10. Animation & Micro-Interactions
### GSAP (Heavy Scroll Animations)
Loaded via CDN in the layout:
```html
```
- Used primarily on the **landing page** for cinematic scroll reveals.
- Initialize inside Alpine's `x-init` hook: `x-init="gsap.from($el, { opacity: 0, y: 50, scrollTrigger: $el })"`.
- GSAP is **not used** in the mailbox application UI — Alpine.js handles all reactive transitions there.
### Alpine.js (Instant UI State)
All immediate user interactions must be handled client-side with Alpine.js:
| Pattern | Usage |
|---------|-------|
| `x-show` + `x-transition` | Modals, overlays, conditional panels |
| `x-data` + `$watch` | Reactive state management (timers, mobile view switching) |
| `@click` + `$wire` | Livewire method calls from the client |
| `@click` + `$dispatch` | Triggering global events (toasts, modals) |
| `@resize.window` | Responsive sidebar behavior |
| `:class` bindings | Dynamic styling (WebSocket indicator, toast types) |
### CSS Transitions
| Property | Duration | Easing | Usage |
|----------|----------|--------|-------|
| `transition-all` | default (150ms) | default | Button hover states |
| `transition-colors duration-500` | 500ms | default | WebSocket indicator color change |
| `transition-all duration-1000 ease-linear` | 1000ms | linear | Progress bar width |
| `transition ease-out duration-500` | 500ms | ease-out | Toast enter |
| `transition ease-in duration-300` | 300ms | ease-in | Toast leave |
| `transition ease-out duration-700` | 700ms | ease-out | Full-screen overlay enter |
| `transition ease-in duration-500` | 500ms | ease-in | Full-screen overlay leave |
| `transition ease-out duration-500` | 500ms | ease-out | Modal card enter (with scale + translateY) |
### Custom Keyframes
```css
@keyframes slide-right {
from { opacity: 0; transform: translateX(-10px); }
to { opacity: 1; transform: translateX(0); }
}
@keyframes slide-up {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-slide-up {
animation: slide-up 0.8s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
```
---
## 11. Real-Time UI Patterns
### WebSocket Architecture
```
app.js → Laravel Echo (Reverb broadcaster)
→ Pusher connection state listeners
→ Dispatches window events: 'ws-status'
app.blade.php → Listens for @ws-status.window
→ Updates global Alpine 'wsConnected' state
mailbox.blade.php → Reads 'wsConnected' for indicator color
```
### Connection Status Lifecycle
```javascript
// resources/js/app.js
window.Echo.connector.pusher.connection.bind('connected', () => dispatchStatus(true));
window.Echo.connector.pusher.connection.bind('unavailable', () => dispatchStatus(false));
window.Echo.connector.pusher.connection.bind('disconnected', () => dispatchStatus(false));
window.Echo.connector.pusher.connection.bind('failed', () => dispatchStatus(false));
```
### Conditional Echo Initialization
Echo is only initialized on pages that need it, controlled by a data attribute:
```html
...
```
```javascript
if (document.querySelector('[data-requires-reverb]')) {
window.Echo = new Echo({ ... });
}
```
### New Email Real-Time Flow
1. `ProcessIncomingEmail` job saves email to MariaDB + MongoDB.
2. `NewEmailReceived` event broadcasts on `mailbox.{domain}` channel.
3. Livewire listener `echo:mailbox.{domain},.new.email` fires `onNewEmail()`.
4. `onNewEmail()` dispatches a toast notification with sender + subject.
5. `onNewEmail()` dispatches `$refresh` to reload the email list.
---
## 12. Responsive Design Rules
### Breakpoint Strategy
| Breakpoint | Prefix | Behavior |
|-----------|--------|----------|
| < 640px | (none) | Mobile: full-width toast, collapsed sidebar, single-panel view |
| ≥ 640px | `sm:` | Toast anchors to bottom-right, min-width restored |
| ≥ 1024px | `lg:` | Email detail panel becomes visible. Mobile view switcher deactivated |
| ≥ 1280px | `xl:` | Sidebar always open |
### Mobile View Switching
On mobile (`< 1024px`), the mailbox uses an Alpine-driven view switcher:
```javascript
$watch('selectedId', value => { if (value && window.innerWidth < 1024) mobileView = 'detail' });
$watch('mobileView', value => { if (value === 'list' && window.innerWidth < 1024) selectedId = null });
```
### Toast Responsiveness (User Iteration)
> **User Iteration Note:** The toast container originally used `fixed bottom-6 right-6` with a hard `min-w-[320px]`, causing it to overflow and touch the left screen edge on small devices. This was fixed by:
> - Container: `left-6 right-6 sm:left-auto sm:right-6` — full-width with margins on mobile, bottom-right anchor on desktop.
> - Toast card: `w-full sm:min-w-[320px]` — fluid on mobile, minimum width on desktop.
---
## 13. Accessibility
### Required Patterns
- All interactive elements must have `cursor-pointer`.
- Icon-only buttons must have a `title` attribute for tooltip/screen-reader context.
- `antialiased` is applied globally on `` for smoother font rendering.
- `selection:bg-[#EC4899]/30` provides a branded text selection color.
- Use semantic HTML elements wherever possible (`