Implementation / Tailwind + DaisyUI

A shared language for the app.

Keep the existing Rails component conventions and give them the Small Council identity.

Install the library

The current app uses Tailwind CSS 4.2.1 through tailwindcss-rails, vendored DaisyUI v5, ERB, Turbo, and Stimulus. The guide uses the same plugin bundles. No React, Bootstrap, or npm application is required.

Copy the toolkit’s brand/ folder into the application’s Tailwind source tree. Replace the old DaisyUI themes: all plugin declaration with these imports; do not load the plugin twice:

@import "tailwindcss";
@import "./brand/theme.css";
@import "./brand/daisyui.css";
@import "./brand/fonts.css";
@import "./brand/components.css";
@source "../../views";
@source "../../javascript";
@source not "./brand/vendor";

These example paths assume app/assets/tailwind/application.css. Adjust @source if you put the files elsewhere. In that layout, views/javascript are two levels up. Preserve full class strings in ERB and Stimulus; computed fragments cannot be reliably scanned.

Set <html data-theme="light"> or dark, replacing the current wireframe theme when the application is migrated. Theme preferences and persistence belong to the application. This phase does not edit it.

Asset pipeline

The compiled CSS refers to assets/fonts/DejaVuSans.ttf and assets/fonts/DejaVuSans-Bold.ttf relative to the CSS output. Preserve those served paths for a static site. In Rails/Propshaft, register the fonts as application assets and adjust URLs to their logical asset paths so the pipeline can fingerprint them. Verify actual network requests after bin/rails assets:precompile; copying source folders alone does not establish working asset URLs.

Use the provided lockup and marks for app navigation and icons. Preserve the font license. Guide JavaScript and Hugo layouts are website-only; existing Turbo/Stimulus controllers continue to own app interactions.

Tokens and components

tokens.json preserves the supplied kit values. theme.css exposes semantic Tailwind utilities such as bg-canvas, text-ink, and text-brand-link. daisyui.css maps those values to DaisyUI’s base, primary, secondary, accent, and status roles. components.css supplies accessible sizing, borders, focus, rich text, dialogs, and Small Council compositions.

<button type="button" class="btn btn-primary">Start council</button>
<label for="advisor-name" class="sc-label">Advisor name</label>
<input id="advisor-name" class="input w-full" autocomplete="off">

Use DaisyUI controls for standard UI. Use sc-message, sc-prose, sc-workspace, sc-dialog, and sc-diff for product compositions. sc-btn, sc-card, and related aliases support the shared guide shell inherited from IVR. They share the same tokens, rather than replacing DaisyUI in the application.

The component guide includes the reference projects’ 24 general categories plus forms and tables. Each specimen includes HTML even without JavaScript. Theme-specific UI uses the same markup.

Application coverage

Existing app views Library specimens and behavior contracts
layouts/*, dashboard/*, spaces/* Navbar, drawer, space switcher, cards, empty states; responsive workspace
sessions/*, registrations/*, identity/*, passwords/* Authentication forms, persistent labels, errors, session lists
advisors/*, councils/* Advisor identity, participant selection, editable fields, rules of engagement
form_fillers/* AI-assisted form draft, pending, result, and error states
conversations/* Conversation list, archived state, participant configuration, messages, mentions/commands, composer and scroll affordance
messages/* Model interaction details, loading, partial/error, retry and copy actions
memories/* Search, editor, attachments, details, history/diff, export affordance
providers/*, settings/* Provider form, model filtering/toggles, default model, validation

See components and the workspace specimens. Specimen interactions affect only this guide. They are not new application features.

State and accessibility contracts

Use native disabled controls while a request is pending, keep the accessible name, preserve input after errors, and prevent repeated submissions in the app controller. An aria-busy attribute does not do that automatically. Every field needs a label and associated help/errors. Destructive actions name the object and consequence.

Keep AI identity, speaker name, and status visible. Use polite completion announcements rather than announcing every streamed token. Do not force-scroll readers who moved back in a conversation. Preserve completed responses on partial failure. Long messages, URLs, tables and code must not cause page-wide horizontal scrolling.

Use keyboard-operable navigation and native dialogs where possible. Restore focus after closing; never hide all message actions until hover. Support 200% text resizing, 400% reflow, and reduced motion. On mobile use a labelled drawer and a single conversation pane.

Product meaning

The app exposes open, consensus, and brainstorming modes. In open mode, mentions invite advisors; @all invites all participants. A mode named consensus does not by itself prove every participant agreed. The supplied synthesis layout is a design proposal: show agreement, dissent, and missing responses explicitly before adopting a recommendation.

Memory behavior and retention claims must follow the actual app implementation. Do not promise perfect recall, confidentiality, or automatic source verification. Provider settings must never display saved API keys in examples.

Checking integration later

After the separate app migration, compile assets, inspect both themes in the real views, test Turbo navigation/modal focus and Stimulus behaviors, and run the affected application tests. The static toolkit checks cannot establish that future Rails integration works.