Head
Use content_for :l_ui_head to inject arbitrary content into the layout <head>, after the stylesheet. This is the place for third-party scripts (analytics, chat widgets), a page-specific inline <script>, meta and verification tags, preload hints, or a per-request stylesheet link - anything you would normally add to the head of a page. For styling, the overrides file is usually a better fit (see below).
<% content_for :l_ui_head do %>
<%= javascript_include_tag "https://cdn.example.com/widget.js", defer: true %>
<meta name="google-site-verification" content="...">
<% end %>
Where styles fit best. layered-ui token and component overrides (e.g. --accent, restyling a .l-ui-* class) fit in app/assets/tailwind/layered_ui_overrides.css - see the colors page. Other custom styling fits in your app's own application stylesheet, like any normal Rails app. Both keep styles with the rest of your CSS, where they are easier to maintain than inline in the head.
Per-tenant theming
When brand colors vary per request and cannot be known at build time, a good option is to serve them as a dedicated stylesheet from a Rails controller and link it here. The stylesheet overrides the design tokens, and this approach is Turbo- and CSP-friendly while keeping styling out of the markup.
<% content_for :l_ui_head do %>
<%= stylesheet_link_tag tenant_theme_path(current_tenant) %>
<% end %>
The controller behind tenant_theme_path renders CSS that overrides the design tokens, for example :root { --accent: <%= @tenant.accent_color %>; --accent-foreground: oklch(1 0 0); }.
Security: never interpolate user-supplied strings directly into the served CSS - this allows CSS injection. Validate or sanitise any user-derived values before interpolation.
CSP and Turbo compatibility
The linked-stylesheet pattern above sidesteps two issues that an inline <style> block runs into. A stylesheet served from your own origin satisfies a strict Content-Security-Policy: style-src 'self' with no nonce, and Turbo caches and reuses it by URL - both reasons to prefer it.
If you do inject an inline <style> block instead, two caveats apply. Under a strict CSP, add a nonce with Rails' content_security_policy_nonce helper - Rails includes the matching nonce in the CSP header automatically:
<% content_for :l_ui_head do %>
<style nonce="<%= content_security_policy_nonce %>">
:root { --accent: <%= @tenant.accent_color %>; --accent-foreground: oklch(1 0 0); }
</style>
<% end %>
And on Turbo's preview pass - when it restores a cached snapshot before the network response arrives - an inline block may briefly show stale tokens. If tokens are stable for a session, add data-turbo-track="reload" so Turbo reloads only when the block changes between visits; if they vary per navigation this disables Turbo, so the linked stylesheet is the better fit.