Farvist docs
A lightweight (~20 KB), Sass-powered glassmorphism CSS framework. Frosted surfaces, neon glow, gradients and a free backgrounds library β generated from design tokens with @for / @each loops.
Installation
Drop in one stylesheet β no build step. Add the optional 2.5 KB script for modals, tabs, toasts and the theme toggle.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/farvist/dist/farvist.min.css">
<script src="https://cdn.jsdelivr.net/npm/farvist/assets/farvist.js" defer></script>
Or build from the Sass source to customize the tokens:
npm install
npm run dev # β dist/farvist.css + dist/farvist.min.css
Theming
Everything is driven by --fv-* custom properties. The default is the dark glass theme; add data-theme="light" to <html> to flip every surface at runtime β no recompile.
document.documentElement.setAttribute('data-theme', 'light'); // or remove for dark
Re-theme at build time by configuring the module:
@use 'farvist/scss/farvist' with (
$primary: #00e0ff,
$accent: #ff4dd2,
$glass-blur: 22px
);
Add a key to the $theme-colors map and you instantly get .btn-*, .badge-*, .text-*, .bg-* and more for it β that's the payoff of generating from maps.
Cascade layers β easy overrides
Farvist's CSS is wrapped in cascade layers β @layer reset, base, layout, components, utilities β so utilities beat components by layer order, not !important. The practical win: any CSS you write outside a layer beats all of Farvist, no specificity battles or !important needed.
/* your stylesheet, loaded after farvist.css */
.btn { border-radius: 0; } /* unlayered β wins over Farvist's .btn */
Prefer to keep your overrides organized? Put them in your own layer after utilities.
Browser support: the shipped CSS is autoprefixed (PostCSS + Autoprefixer). Everything works in Chrome/Edge 111+, Safari 16.4+, Firefox 113+ (~early 2023); older browsers degrade gracefully β glass falls back to an opaque surface via @supports, and the color-mix status pulse simply doesn't animate. Full matrix in the readme.
Grid
A 12-column flexbox grid with responsive breakpoints (sm md lg xl xxl).
<div class="row gy-2">
<div class="col-12 col-md-8">β¦</div>
<div class="col-12 col-md-4">β¦</div>
</div>
Utilities
Spacing, display, flex, text, color and sizing β all generated. Spacing follows {m|p}{t e b s x y}-{0β8} with optional -{breakpoint}-.
.mt-3 .px-4 .p-0 .m-md-5 .mx-auto <!-- spacing -->
.d-flex .justify-content-between .align-items-center .gap-3
.fs-2xl .fw-bold .text-center .text-muted <!-- type -->
.bg-primary .text-accent .rounded-lg .shadow-lg <!-- color/shape -->
Backgrounds free Β· exclusive
Mesh gradients, patterns, spotlights and fade-masks β one class each. The headline feature Tailwind and Bootstrap make you hand-roll.
<section class="bg-mesh-aurora">β¦</section> <!-- mesh gradient -->
<div class="bg-grid bg-fade">β¦</div> <!-- pattern, faded at edges -->
<header class="bg-spotlight-primary">β¦</header> <!-- radial glow -->
Meshes: aurora Β· sunset Β· ocean Β· nebula. Patterns: grid Β· graph Β· dots Β· lines Β· noise. Modifiers: .bg-fade (put on a decorative layer β it masks children too), .bg-drift (animate a mesh).
Cards & badges
Glass card
Frosted surface with an inner highlight.
badge solid<article class="card card-glow">
<div class="card-body">
<h3 class="card-title">Glass card</h3>
<p class="card-text">β¦</p>
</div>
</article>
Forms
<label class="form-label">Email</label>
<input class="form-control" type="email">
Modal Β· Tabs Β· Toast
These three use the optional JS companion. Modal is a native <dialog>; accordion and dropdown are pure CSS (<details>).
<button data-fv-open="#m">Open</button>
<dialog class="modal" id="m"> β¦ </dialog>
Farvist.toast({ title: 'Saved', variant: 'success' });
Feedback
Alerts, callouts and empty states.
Nothing here yet.
<div class="alert alert-success"><div class="alert-heading">Saved</div>β¦</div>
<div class="callout callout-accent">A tip or aside.</div>
<div class="empty-state"><div class="empty-state-icon">π</div><p>Nothing yet.</p></div>
Data display
| Name | Status |
|---|---|
| Ada | Active |
| Mira | Away |
- Inbox
- Drafts
- Shipped v0.11today
- Docs polishearlier
- 1Account
- 2Plan
- 3Done
<div class="table-responsive"><table class="table table-hover">β¦</table></div>
<ul class="list-group"><li class="list-group-item">Inbox</li></ul>
<div class="stat-value text-gradient">8.4k</div><div class="stat-label">Users</div>
<ul class="timeline"><li class="timeline-item timeline-primary">
<div class="timeline-marker"></div><div class="timeline-content">β¦</div></li></ul>
<ol class="stepper"><li class="step is-active"><span class="step-dot">2</span>β¦</li></ol>
Indicators
<div class="progress"><div class="progress-bar" style="width:60%"></div></div>
<div class="spinner spinner-primary"></div>
<div class="spinner-dots"><span></span><span></span><span></span></div>
<span class="status status-online">Online</span>
<div class="skeleton skeleton-text"></div>
More inputs
A styled range slider and a JS-free segmented control. (The switch is in Forms.)
<input type="range" class="form-range">
<div class="segmented">
<input type="radio" id="d" name="seg" checked><label for="d">Day</label>
<input type="radio" id="w" name="seg"><label for="w">Week</label></div>
Icons & accordion
55 line icons (24Γ24, sized via font-size or width/height, coloured by currentColor). The AI/chat set is highlighted.
Is it accessible?
Does it need a build step?
<svg class="icon"><use href="assets/icons/farvist-icons.svg#i-home"/></svg>
<details class="accordion-item">
<summary>Question</summary>
<div class="accordion-body">Answer.</div></details>
Chat & AI kit β¦
Components for AI products β a conversation thread, a prompt composer and agent-status indicators β all built on the glass system. See the full AI console template.
Chat thread
<div class="chat">
<div class="message"> <!-- assistant (left) -->
<span class="avatar avatar-sm avatar-accent">AI</span>
<div class="message-body">
<div class="message-bubble">How can I help?</div>
<div class="message-meta">Assistant</div>
</div>
</div>
<div class="message message-out"> β¦ </div> <!-- user (right) -->
</div>
<!-- typing dots -->
<span class="typing"><span></span><span></span><span></span></span>
Prompt composer
Agent status
Streaming messages
After injecting new messages into the DOM, call Farvist.enhance() so any new tooltips, tabs and ARIA get wired up.
chat.insertAdjacentHTML('beforeend', bubbleHTML);
Farvist.enhance(); // re-run progressive enhancement
Use Farvist with your AI β¦
Farvist is built to be generated correctly by AI assistants. Point your tool at the machine-readable context, or paste the primer below.
- llms-full.txt β every convention, component, icon and copy-paste recipe. Paste this into Cursor / Claude / ChatGPT.
- ai-context.json β machine-readable catalog (components, utilities, icons, recipes).
- llms.txt β the concise index (llms.txt convention).
- farvist.cursorrules β drop into your project as
.cursorrules.
Paste-in primer
You are an expert in Farvist, a glassmorphism CSS framework.
Prefer Farvist classes (components + utilities) over hand-written CSS.
Dark by default; add data-theme="light" to switch; give the page a
bg-mesh-* background so the glass reads. Colors: primary, accent, successβ¦
(suffixes: btn-primary, text-accent). Spacing 0β7 (p-4 = 1rem).
Icons: <svg class="icon"><use href="β¦#i-bot"/></svg>.
Full context: https://farvist.com/llms-full.txt
JS companion
~2.5 KB, no dependencies. It auto-applies ARIA to tabs & progress bars and wires these data-attributes:
data-fv-open="#id" // open a <dialog class="modal">
data-fv-dismiss // close the nearest dialog
data-fv-tab="#panel" // switch tabs (arrow-key nav included)
data-fv-theme-toggle // flip dark / light
data-fv-nav-toggle // toggle the mobile navbar
<pre class="snippet"> // gets a copy button (or use any [data-fv-copy])
Farvist.toast({ title, message, variant, timeout });
Farvist.copy(text); // copy text to the clipboard
Farvist.enhance(); // re-wire after injecting DOM dynamically
Accessibility
Farvist aims to be accessible by default. The optional farvist.js companion progressively enhances your markup on load, adding the ARIA that's tedious to hand-write β drop it in and most of the list below is automatic.
Automatic (via farvist.js)
- Tabs β full
tablist/tab/tabpanelroles, roving tabindex, arrow-key nav. - Progress bars β
role="progressbar"+aria-valuenow/min/max. - Breadcrumb Β· stepper Β· pagination β
aria-currenton the active item. - Forms β
.is-invalidgetsaria-invalidand is linked to its.invalid-feedbackviaaria-describedby. - Tooltips β the
data-tooltiptext is exposed to screen readers and shows on keyboard focus. - Toasts β announced via a live region;
variant:'danger'is assertive (role="alert"), others polite (role="status"). - Modal β native
<dialog>(focus trap + Esc); the navbar hamburger exposesaria-expanded.
Skip link
Make it the first element in <body>; it stays hidden until focused, then pins to the top-left.
<a class="skip-link" href="#main">Skip to content</a>
<main id="main" tabindex="-1"> β¦ </main>
Form validation β try tabbing to the field
Mark the control .is-invalid and put the message in a sibling .invalid-feedback; the JS wires the rest.
<label class="form-label" for="email">Email</label>
<input class="form-control is-invalid" id="email">
<div class="invalid-feedback">Enter a valid email.</div>
<!-- JS adds aria-invalid + aria-describedby -->
Good to know
- Tooltips describe, they don't name β give icon-only controls their own
aria-label. - Pagination β wrap it in
<nav aria-label="Pagination">and label the prev/next arrows. - Focus is always visible for keyboard users; restyle it via the
--fv-focus-ringtoken. - Reduced motion β animation and transition are suppressed under
prefers-reduced-motion: reduce.
Contribute
Farvist is open source (MIT). Issues and PRs welcome. The framework lives under scss/, generated from token maps in scss/abstracts/_variables.scss.