UI / Implementation
Tailwind, with IVR character
A portable Tailwind v4 theme, a small component layer, and patterns grounded in the current Rails app.
What to use
The system is built with Tailwind CSS v4. theme.css defines semantic utilities; components.css provides repeated controls using @apply. fonts.css loads local Inter assets. The guide adds its own documentation layout in site/site.css.
| File | Purpose |
|---|---|
brand/theme.css |
Semantic color roles, radii, fonts, and dark variant |
brand/components.css |
Buttons, inputs, cards, badges, alerts, tables, nodes |
brand/fonts.css |
Self-hosted Inter font faces |
brand/tokens.json |
Maintained machine-readable palette and foundation values |
brand/ivr.css |
Compiled guide/demo CSS for immediate inspection |
site/site.css and site/site.js |
Documentation presentation and local demo behavior |
The compiled guide stylesheet includes utilities scanned from this toolkit. Compile against your own application sources when integrating so new utility classes are generated. Do not assume ivr.css contains every possible Tailwind class.
Tailwind entrypoint
Copy brand/ to your project’s design-system directory, preserving the font paths. Create an input stylesheet such as:
@import "tailwindcss" source(none);
@import "./design-system/theme.css";
@import "./design-system/fonts.css";
@import "./design-system/components.css";
@source "../views";
@source "../javascript";
tailwindcss -i app/assets/ivr-tailwind.css \
-o app/assets/stylesheets/ivr.css --minify
Paths depend on where you put the input stylesheet. Tailwind @source paths are relative to that file. Write complete class names in templates: bg-warning-soft text-warning, rather than constructing names such as bg-${state}-soft at runtime.
See the official Tailwind CLI, theme variables, and source detection documentation. The standalone CLI is sufficient; this toolkit needs no npm installation or browser CDN.
Rails integration
The current app uses Rails, Propshaft, Importmap, Turbo, and Stimulus. Tailwind compilation is a build step; Propshaft serves the generated CSS. Keep that separation explicit. You can use the standalone CLI shown above or the application’s chosen Rails Tailwind setup. This toolkit does not require adding a JavaScript package manager to the app.
<%= stylesheet_link_tag "ivr", "data-turbo-track": "reload" %>
<main class="bg-canvas font-sans text-ink">
<%= image_tag "ivr-cloud-primary.svg", alt: "IVR Cloud",
width: 146, height: 36 %>
<%= button_to "Publică versiunea", publication_path,
class: "ivr-btn" %>
</main>
The route above is illustrative: use the application’s account-scoped helper. Preserve real form methods, CSRF protection, authorization, Turbo behavior, and Stimulus controllers. The toolkit’s site.js belongs to the guide; it is not an application dependency.
Tailwind Preflight resets global element defaults. Integrate through deliberate template migration and stylesheet ordering; do not blindly layer it over .account-* styles and expect complete compatibility. Copy fonts into served asset paths and adjust font URLs for Propshaft’s asset handling as needed. Check the browser’s actual font requests after precompilation.
Component recipes
The component library covers all 24 TWR component categories plus forms/tables and IVR patterns. Its HTML snippets are included in the built page and are readable without JavaScript. Native disclosures, dialogs, progress, and popovers supply semantics; the consuming app owns behavior and data for tabs, pagination, loading, notifications, and navigation.
<button type="button" class="ivr-btn">Salvează ciorna</button>
<button type="button" class="ivr-btn ivr-btn-secondary">Anulează</button>
<span class="ivr-badge ivr-badge-warning">Ciornă</span>
<div class="ivr-card">Contained work</div>
<label class="ivr-label" for="flow-name">Numele fluxului</label>
<input class="ivr-input" id="flow-name" name="name"
aria-describedby="flow-help" required>
<p class="ivr-help" id="flow-help">Alege un nume ușor de recunoscut.</p>
Prefer utility classes for one-off layout and component classes for repeated behavior and appearance. Use text-muted for supporting copy, border-control for essential boundaries, and tabular-nums for comparable data.
Themes
Set data-theme="light" or data-theme="dark" on the root element. Use semantic utility names in both themes. Identity artwork does not recolor automatically: swap primary/reversed assets for the actual background.
<html lang="ro" data-theme="dark">
<!-- bg-canvas, text-ink, bg-brand, and text-on-brand adapt. -->
</html>
The guide stores theme preference locally and falls back to the operating system’s preference. A consuming app owns its own theme behavior; move it into the application’s normal JavaScript/Stimulus lifecycle. If your CSP blocks inline scripts, provide the initial theme through a nonce-approved script or server-rendered attribute.
Product contracts
| Pattern | What the UI must make clear |
|---|---|
| IVR editor | Root step, reachable paths, outcome labels, selected inspector, unconnected steps |
| Publication | Creates an immutable version; does not itself switch phone routes |
| Deployment | Names the endpoint, phone number, and published revision being activated |
| Rollback | Names the earlier ready deployment and affected route |
| Call history | Separate session/call status, timestamp, duration, and available recording |
| Voicemail | Recording availability and transcription state are separate |
| Campaign | State and actions correspond to the real run; do not imply completion from scheduling |
| Empty state | Explain what is absent and offer one relevant action |
Inspect component examples and the product specimen. Product examples use fictional data and do not invoke the Rails application.
Adoption checks
Compile with actual templates, inspect both themes, verify font loading, and check the affected flow with keyboard and screen-reader use. Keep publication and deployment copy accurate. Check tables and flow inspectors at narrow widths. Preserve tenant/account names in navigation and consequential actions.