Setup Guide
One-time setup for using FOLIO // NEXT components. Add these to your project, then copy any component from the theme.
The cn() utility combines clsx and tailwind-merge for conditional class names. Install both packages.
npm install clsx tailwind-mergeCreate lib/utils.ts with the cn() helper. Every component imports this for class name merging.
import { type ClassValue, clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]): string {
return twMerge(clsx(inputs))
}Add the FOLIO // NEXT design tokens to your globals.css. These define colors, fonts, and animation tokens used by every component in the theme.
@theme {
/* ── Colors ──────────────────────────────────────────── */
--color-folio-bg: #F4F1EC;
--color-folio-bg-alt: #EDE9E2;
--color-folio-bg-deep: #E8E3DA;
--color-folio-accent: #1A3027;
--color-folio-accent-mid: #244035;
--color-folio-accent-muted: rgba(26, 48, 39, 0.45);
--color-folio-cta: #B5562E;
--color-folio-cta-dark: #9A4424;
--color-folio-ink: #1A1814;
--color-folio-ink-mid: #2E2A24;
--color-folio-rule: rgba(26, 24, 20, 0.14);
--color-folio-rule-strong: rgba(26, 24, 20, 0.28);
--color-folio-muted: rgba(26, 24, 20, 0.52);
--color-folio-faint: rgba(26, 24, 20, 0.28);
/* ── Fonts ───────────────────────────────────────────── */
--font-display: var(--font-cormorant);
--font-body: var(--font-inter);
/* ── Animations ──────────────────────────────────────── */
--animate-ticker: ticker-scroll 32s linear infinite;
}Each component may need its own CSS classes in your globals.css. Copy the styles for the components you use.
/* ─── Buttons ────────────────────────────────────────── */
.btn-base {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
font-family: var(--font-body);
font-weight: 500;
font-size: 0.8rem;
letter-spacing: 0.08em;
text-transform: uppercase;
cursor: pointer;
text-decoration: none;
line-height: 1;
transition: background 0.2s, color 0.2s, border-color 0.2s;
white-space: nowrap;
border: 1px solid transparent;
border-radius: 0;
}
.btn-sm { padding: 9px 20px; }
.btn-md { padding: 12px 28px; }
.btn-lg { padding: 15px 36px; }
.btn-primary {
background: var(--color-folio-cta);
color: #F4F1EC;
border-color: var(--color-folio-cta);
}
.btn-primary:hover {
background: var(--color-folio-cta-dark);
border-color: var(--color-folio-cta-dark);
color: #F4F1EC;
}
.btn-secondary {
background: transparent;
color: var(--color-folio-accent);
border-color: var(--color-folio-accent);
}
.btn-secondary:hover {
background: var(--color-folio-accent);
color: var(--color-folio-bg);
}
.btn-ghost {
background: transparent;
color: var(--color-folio-muted);
border-color: var(--color-folio-rule-strong);
}
.btn-ghost:hover {
color: var(--color-folio-ink);
border-color: var(--color-folio-ink);
}
/* ─── Hero Mobile ────────────────────────────────────── */
@media (max-width: 480px) {
.hero-title { font-size: clamp(3rem, 14vw, 4rem); }
.hero-actions { flex-direction: column; }
.hero-actions .btn-base { width: 100%; justify-content: center; }
.hero-stats { flex-wrap: wrap; gap: 0; }
.hero-stat {
flex: 0 0 50%;
border-right: none;
margin-right: 0;
padding: 20px 16px 20px 0;
border-bottom: 1px solid var(--color-folio-rule);
}
.hero-stat:nth-last-child(-n+2) { border-bottom: none; }
.hero-stat:nth-child(even) { padding-left: 20px; padding-right: 0; }
.hero-stat:nth-child(odd) { border-right: 1px solid var(--color-folio-rule); }
}/* ─── Badge ──────────────────────────────────────────── */
.folio-badge {
display: inline-flex;
align-items: center;
font-family: var(--font-body);
font-size: 0.6rem;
font-weight: 500;
letter-spacing: 0.12em;
text-transform: uppercase;
border: 1px solid transparent;
border-radius: 0;
padding: 3px 9px;
white-space: nowrap;
line-height: 1.6;
}
.folio-badge-ink {
color: var(--color-folio-ink);
background: transparent;
border-color: var(--color-folio-rule-strong);
}
.folio-badge-accent {
color: #F4F1EC;
background: var(--color-folio-accent);
border-color: var(--color-folio-accent);
}
.folio-badge-cta {
color: #F4F1EC;
background: var(--color-folio-cta);
border-color: var(--color-folio-cta);
}
.folio-badge-ghost {
color: var(--color-folio-muted);
background: transparent;
border-color: var(--color-folio-rule);
}
.folio-badge-parchment {
color: var(--color-folio-muted);
background: var(--color-folio-bg-deep);
border-color: var(--color-folio-rule-strong);
}/* ─── Card ───────────────────────────────────────────── */
.folio-card {
background: var(--color-folio-bg);
border: 1px solid var(--color-folio-rule-strong);
border-radius: 0;
overflow: hidden;
}
.folio-card-header {
padding: 20px 24px;
border-bottom: 1px solid var(--color-folio-rule);
background: var(--color-folio-bg-deep);
}
.folio-card-body {
padding: 24px;
}
.folio-card-footer {
padding: 14px 24px;
border-top: 1px solid var(--color-folio-rule);
background: var(--color-folio-bg-alt);
}/* ─── Calendar ───────────────────────────────────────── */
.folio-calendar {
border: 1px solid var(--color-folio-rule-strong);
background: var(--color-folio-bg);
max-width: 360px;
overflow: hidden;
}
.folio-calendar-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 14px 16px;
border-bottom: 2px solid var(--color-folio-rule-strong);
background: var(--color-folio-bg-deep);
}
.folio-calendar-month-label {
font-family: var(--font-display);
font-size: 1.1rem;
font-weight: 400;
font-style: italic;
color: var(--color-folio-ink);
letter-spacing: 0.01em;
}
.folio-calendar-nav-btn {
background: none;
border: 1px solid var(--color-folio-rule-strong);
border-radius: 0;
cursor: pointer;
padding: 4px 10px;
color: var(--color-folio-muted);
font-size: 0.8rem;
transition: all 0.15s;
line-height: 1.4;
}
.folio-calendar-nav-btn:hover {
background: var(--color-folio-accent);
color: #F4F1EC;
border-color: var(--color-folio-accent);
}
.folio-calendar-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
}
.folio-calendar-day-name {
font-family: var(--font-body);
font-size: 0.56rem;
font-weight: 500;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--color-folio-faint);
text-align: center;
padding: 9px 2px;
border-bottom: 1px solid var(--color-folio-rule);
border-right: 1px solid var(--color-folio-rule);
}
.folio-calendar-day-name:last-child { border-right: none; }
.folio-calendar-cell {
aspect-ratio: 1;
display: flex;
align-items: center;
justify-content: center;
font-family: var(--font-body);
font-size: 0.76rem;
font-weight: 400;
color: var(--color-folio-ink);
cursor: pointer;
transition: all 0.12s;
border-right: 1px solid var(--color-folio-rule);
border-bottom: 1px solid var(--color-folio-rule);
background: var(--color-folio-bg);
user-select: none;
}
.folio-calendar-cell:nth-child(7n) { border-right: none; }
.folio-calendar-cell:hover { background: var(--color-folio-bg-deep); }
.folio-calendar-cell.other-month {
color: var(--color-folio-faint);
cursor: default;
}
.folio-calendar-cell.other-month:hover { background: var(--color-folio-bg); }
.folio-calendar-cell.today {
background: var(--color-folio-accent);
color: #F4F1EC;
font-weight: 500;
}
.folio-calendar-cell.today:hover { background: var(--color-folio-accent-mid, #244035); }
.folio-calendar-cell.selected {
background: var(--color-folio-cta);
color: #F4F1EC;
font-weight: 500;
}
.folio-calendar-cell.selected:hover { background: var(--color-folio-cta-dark); }/* ─── Date Block ─────────────────────────────────────── */
.folio-date-block {
display: inline-flex;
flex-direction: column;
align-items: stretch;
border: 1px solid var(--color-folio-rule-strong);
min-width: 148px;
background: var(--color-folio-bg);
overflow: hidden;
}
.folio-date-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 16px;
border-bottom: 1px solid var(--color-folio-rule);
background: var(--color-folio-accent);
}
.folio-date-month-label {
font-family: var(--font-body);
font-size: 0.6rem;
font-weight: 500;
letter-spacing: 0.14em;
text-transform: uppercase;
color: rgba(244, 241, 236, 0.75);
}
.folio-date-year-label {
font-family: var(--font-body);
font-size: 0.6rem;
font-weight: 500;
letter-spacing: 0.1em;
color: rgba(244, 241, 236, 0.55);
}
.folio-date-day-num {
font-family: var(--font-display);
font-size: clamp(3.5rem, 6vw, 5rem);
font-weight: 300;
font-style: italic;
line-height: 1;
color: var(--color-folio-ink);
padding: 20px 20px 12px;
text-align: center;
}
.folio-date-weekday {
font-family: var(--font-body);
font-size: 0.58rem;
font-weight: 500;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--color-folio-muted);
padding: 10px 20px 18px;
border-top: 1px solid var(--color-folio-rule);
text-align: center;
}/* ─── Pullquote ──────────────────────────────────────── */
.folio-pullquote {
padding: clamp(28px, 4vw, 48px) clamp(16px, 3vw, 32px);
border-top: 2px solid var(--color-folio-rule-strong);
border-bottom: 2px solid var(--color-folio-rule-strong);
text-align: center;
margin: 0;
}
.folio-pullquote-text {
font-family: var(--font-display);
font-size: clamp(1.35rem, 2.8vw, 2.1rem);
font-weight: 300;
font-style: italic;
line-height: 1.45;
color: var(--color-folio-ink);
max-width: 680px;
margin: 0 auto 20px;
letter-spacing: -0.01em;
}
.folio-pullquote-attribution {
font-family: var(--font-body);
font-size: 0.68rem;
font-weight: 500;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--color-folio-muted);
font-style: normal;
}/* ─── Text Variants ──────────────────────────────────── */
.text-body { font-size: 0.95rem; line-height: 1.8; color: var(--color-folio-muted); }
.text-caption { font-size: 0.78rem; color: var(--color-folio-faint); letter-spacing: 0.04em; }
.text-label {
font-family: var(--font-body);
font-size: 0.7rem;
font-weight: 500;
letter-spacing: 0.1em;
text-transform: uppercase;
color: var(--color-folio-muted);
}
.text-code { font-family: monospace; font-size: 0.85rem; color: var(--color-folio-accent); }@keyframes ticker-scroll {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}
/* ─── Hero ───────────────────────────────────────────── */
.hero-outer {
padding-top: 64px;
min-height: 100vh;
display: flex;
flex-direction: column;
border-bottom: 2px solid var(--color-folio-rule-strong);
}
.hero-ticker-wrap {
background: var(--color-folio-accent);
overflow: hidden;
white-space: nowrap;
border-bottom: none;
flex-shrink: 0;
}
.hero-ticker-inner {
display: inline-flex;
animation: ticker-scroll 32s linear infinite;
}
.hero-ticker-text {
display: inline-block;
font-family: var(--font-body);
font-size: 0.65rem;
font-weight: 500;
letter-spacing: 0.14em;
text-transform: uppercase;
color: rgba(244, 241, 236, 0.7);
padding: 10px 48px;
}
.hero-ticker-sep {
color: rgba(244, 241, 236, 0.3);
margin: 0 8px;
}
.hero-grid {
flex: 1;
display: grid;
grid-template-columns: 44px 1fr 380px;
align-items: stretch;
}
.hero-spine {
border-right: 1px solid var(--color-folio-rule);
display: flex;
align-items: center;
justify-content: center;
padding: 40px 0;
}
.hero-spine-text {
writing-mode: vertical-rl;
text-orientation: mixed;
transform: rotate(180deg);
font-family: var(--font-body);
font-size: 0.62rem;
font-weight: 500;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--color-folio-faint);
}
.hero-main {
padding: clamp(56px, 8vw, 96px) clamp(32px, 5vw, 72px);
display: flex;
flex-direction: column;
justify-content: center;
}
.hero-badge {
display: inline-flex;
align-items: center;
gap: 10px;
font-family: var(--font-body);
font-size: 0.65rem;
font-weight: 500;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--color-folio-muted);
margin-bottom: 40px;
}
.hero-badge-rule {
width: 28px;
height: 1px;
background: var(--color-folio-rule-strong);
flex-shrink: 0;
}
.hero-title {
font-family: var(--font-display);
font-size: clamp(3.5rem, 12vw, 10rem);
font-weight: 300;
line-height: 0.88;
letter-spacing: -0.02em;
color: var(--color-folio-ink);
margin-bottom: 8px;
}
.hero-title-line2 {
display: block;
color: var(--color-folio-accent);
font-style: italic;
}
.hero-title-div {
display: block;
font-family: var(--font-body);
font-size: 0.72rem;
font-weight: 400;
letter-spacing: 0.12em;
color: var(--color-folio-muted);
margin: 12px 0 0;
}
.hero-sub {
font-family: var(--font-body);
font-size: 0.95rem;
color: var(--color-folio-muted);
line-height: 1.82;
max-width: 480px;
margin-bottom: 44px;
margin-top: 32px;
}
.hero-actions {
display: flex;
gap: 16px;
flex-wrap: wrap;
margin-bottom: 56px;
}
.hero-stats {
display: flex;
gap: 0;
border-top: 1px solid var(--color-folio-rule);
padding-top: 32px;
}
.hero-stat {
flex: 1;
padding-right: 24px;
border-right: 1px solid var(--color-folio-rule);
margin-right: 24px;
}
.hero-stat:last-child {
border-right: none;
margin-right: 0;
}
.hero-stat-val {
display: block;
font-family: var(--font-display);
font-size: 2rem;
font-weight: 400;
color: var(--color-folio-ink);
line-height: 1;
letter-spacing: -0.02em;
}
.hero-stat-lbl {
display: block;
font-family: var(--font-body);
font-size: 0.65rem;
font-weight: 400;
letter-spacing: 0.10em;
text-transform: uppercase;
color: var(--color-folio-faint);
margin-top: 4px;
}
.hero-toc {
border-left: 1px solid var(--color-folio-rule);
background: var(--color-folio-bg-alt);
display: flex;
flex-direction: column;
padding: clamp(40px, 5vw, 64px) 40px;
}
.hero-toc-label {
font-family: var(--font-body);
font-size: 0.62rem;
font-weight: 500;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--color-folio-faint);
margin-bottom: 32px;
padding-bottom: 16px;
border-bottom: 1px solid var(--color-folio-rule);
}
.hero-toc-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
flex: 1;
}
.hero-toc-item {
display: flex;
align-items: baseline;
gap: 16px;
padding: 18px 0;
border-bottom: 1px solid var(--color-folio-rule);
text-decoration: none;
transition: color 0.2s;
color: inherit;
}
.hero-toc-item:hover .hero-toc-item-label { color: var(--color-folio-cta); }
.hero-toc-item-num {
font-family: var(--font-display);
font-size: 0.75rem;
font-weight: 400;
font-style: italic;
color: var(--color-folio-faint);
min-width: 28px;
}
.hero-toc-item-label {
font-family: var(--font-body);
font-size: 0.82rem;
font-weight: 400;
letter-spacing: 0.04em;
color: var(--color-folio-muted);
transition: color 0.2s;
flex: 1;
}
.hero-toc-item-arrow {
font-size: 0.75rem;
color: var(--color-folio-faint);
flex-shrink: 0;
}
.hero-toc-footer {
margin-top: auto;
padding-top: 32px;
border-top: 1px solid var(--color-folio-rule);
}
.hero-toc-ver {
font-family: var(--font-body);
font-size: 0.62rem;
letter-spacing: 0.10em;
text-transform: uppercase;
color: var(--color-folio-faint);
margin-bottom: 12px;
display: block;
}
.hero-stack {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.hero-stack-item {
font-family: var(--font-body);
font-size: 0.62rem;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--color-folio-accent);
background: rgba(26, 48, 39, 0.08);
padding: 4px 10px;
border: 1px solid rgba(26, 48, 39, 0.18);
}
/* ─── Hero Mobile ────────────────────────────────────── */
@media (max-width: 960px) {
.hero-grid { grid-template-columns: 1fr; }
.hero-spine { display: none; }
.hero-toc { display: none; }
.hero-main { padding: 52px clamp(20px, 5vw, 48px); }
}
@media (max-width: 480px) {
.hero-title { font-size: clamp(3rem, 14vw, 4rem); }
.hero-actions { flex-direction: column; }
.hero-actions .btn-base { width: 100%; justify-content: center; }
.hero-stats { flex-wrap: wrap; gap: 0; }
.hero-stat {
flex: 0 0 50%;
border-right: none;
margin-right: 0;
padding: 20px 16px 20px 0;
border-bottom: 1px solid var(--color-folio-rule);
}
.hero-stat:nth-last-child(-n+2) { border-bottom: none; }
.hero-stat:nth-child(even) { padding-left: 20px; padding-right: 0; }
.hero-stat:nth-child(odd) { border-right: 1px solid var(--color-folio-rule); }
}/* ─── Layout Helpers ─────────────────────────────────── */
.section-inner {
max-width: 1200px;
margin: 0 auto;
padding: 0 clamp(24px, 5vw, 72px);
}
/* ─── Section Eyebrow ────────────────────────────────── */
.section-eyebrow {
font-family: var(--font-body);
font-size: 0.68rem;
font-weight: 500;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--color-folio-muted);
margin-bottom: 24px;
display: flex;
align-items: center;
gap: 12px;
}
.section-eyebrow::before {
content: '';
display: block;
width: 32px;
height: 1px;
background: var(--color-folio-rule-strong);
flex-shrink: 0;
}
.section-title {
font-family: var(--font-display);
font-size: clamp(2.4rem, 4.5vw, 3.8rem);
font-weight: 400;
font-style: italic;
line-height: 1.1;
letter-spacing: -0.01em;
margin-bottom: 16px;
color: var(--color-folio-ink);
}
.section-sub {
font-family: var(--font-body);
font-size: 0.95rem;
color: var(--color-folio-muted);
max-width: 520px;
line-height: 1.8;
}
/* ─── Features Section ───────────────────────────────── */
.features-header {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 48px;
align-items: end;
margin-bottom: 64px;
padding-bottom: 48px;
border-bottom: 1px solid var(--color-folio-rule);
}
@media (max-width: 768px) {
.features-header { grid-template-columns: 1fr; gap: 24px; }
}
.features-ledger { display: flex; flex-direction: column; gap: 0; }
.feature-row {
display: grid;
grid-template-columns: 56px 1fr auto;
gap: 24px;
align-items: start;
padding: 28px 0;
border-bottom: 1px solid var(--color-folio-rule);
transition: background 0.2s;
}
.feature-row:first-child { border-top: 1px solid var(--color-folio-rule); }
.feature-row:hover { background: var(--color-folio-bg-alt); margin: 0 -24px; padding: 28px 24px; }
@media (max-width: 640px) {
.feature-row { grid-template-columns: 40px 1fr; }
.feature-tag { display: none; }
}
.feature-index {
font-family: var(--font-display);
font-size: 0.9rem;
font-weight: 400;
font-style: italic;
color: var(--color-folio-faint);
padding-top: 3px;
}
.feature-title {
font-family: var(--font-display);
font-size: 1.25rem;
font-weight: 400;
color: var(--color-folio-ink);
margin-bottom: 6px;
line-height: 1.3;
}
.feature-description {
font-family: var(--font-body);
font-size: 0.875rem;
color: var(--color-folio-muted);
line-height: 1.78;
}
.feature-tag {
font-family: var(--font-body);
font-size: 0.6rem;
font-weight: 500;
letter-spacing: 0.12em;
text-transform: uppercase;
color: var(--color-folio-accent);
background: rgba(26, 48, 39, 0.07);
border: 1px solid rgba(26, 48, 39, 0.14);
padding: 4px 10px;
white-space: nowrap;
align-self: start;
margin-top: 4px;
}
/* ─── Footer ─────────────────────────────────────────── */
@media (max-width: 480px) {
footer .section-inner { padding-left: 32px; padding-right: 32px; }
}/* ─── Layout Helpers ─────────────────────────────────── */
.section-inner {
max-width: 1200px;
margin: 0 auto;
padding: 0 clamp(24px, 5vw, 72px);
}
/* ─── About Section ──────────────────────────────────── */
.about-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: clamp(48px, 8vw, 96px);
align-items: start;
}
@media (max-width: 768px) {
.about-grid { grid-template-columns: 1fr; }
}
.about-section-num {
font-family: var(--font-body);
font-size: 0.62rem;
font-weight: 500;
letter-spacing: 0.16em;
text-transform: uppercase;
color: rgba(244, 241, 236, 0.4);
margin-bottom: 32px;
display: flex;
align-items: center;
gap: 12px;
}
.about-section-num::before {
content: '';
display: block;
width: 24px;
height: 1px;
background: rgba(244, 241, 236, 0.3);
flex-shrink: 0;
}
.about-heading {
font-family: var(--font-display);
font-size: clamp(2.2rem, 4vw, 3.4rem);
font-weight: 300;
font-style: italic;
letter-spacing: -0.01em;
line-height: 1.1;
color: #F4F1EC;
margin-bottom: 40px;
}
.about-pullquote {
font-family: var(--font-display);
font-size: clamp(1.3rem, 2.2vw, 1.8rem);
font-weight: 300;
font-style: italic;
line-height: 1.4;
color: rgba(244, 241, 236, 0.82);
padding-left: 24px;
border-left: 2px solid rgba(244, 241, 236, 0.3);
margin-bottom: 40px;
}
.about-body {
display: flex;
flex-direction: column;
gap: 16px;
margin-bottom: 48px;
}
.about-body p {
font-size: 0.9rem;
color: rgba(244, 241, 236, 0.65);
line-height: 1.85;
}
.about-inline-code {
background: rgba(244, 241, 236, 0.12);
border: 1px solid rgba(244, 241, 236, 0.2);
padding: 2px 8px;
font-family: monospace;
font-size: 0.85em;
color: rgba(244, 241, 236, 0.9);
}
.about-stat-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 0;
border: 1px solid rgba(244, 241, 236, 0.15);
}
.about-stat {
padding: 28px 24px;
border-right: 1px solid rgba(244, 241, 236, 0.12);
border-bottom: 1px solid rgba(244, 241, 236, 0.12);
}
.about-stat:nth-child(even) { border-right: none; }
.about-stat:nth-last-child(-n+2) { border-bottom: none; }
.about-stat-val {
display: block;
font-family: var(--font-display);
font-size: 2.6rem;
font-weight: 300;
color: #F4F1EC;
line-height: 1;
letter-spacing: -0.02em;
margin-bottom: 6px;
}
.about-stat-lbl {
display: block;
font-family: var(--font-body);
font-size: 0.62rem;
font-weight: 400;
letter-spacing: 0.12em;
text-transform: uppercase;
color: rgba(244, 241, 236, 0.35);
}
/* ─── Footer ─────────────────────────────────────────── */
@media (max-width: 480px) {
footer .section-inner { padding-left: 32px; padding-right: 32px; }
}Button
Multi-variant button with primary, secondary, and ghost styles in three sizes. Renders as a Next.js Link when an href is provided.
Badge
Inline label badge with five variants: ink, accent, cta, ghost, and parchment. Suited for tags, status labels, and category markers.
Card
Composable card container with sharp zero-radius corners in the FOLIO aesthetic. Pairs with folio-card-header, folio-card-body, and folio-card-footer CSS classes.
Calendar
Interactive month-view calendar with previous/next navigation and day selection. Highlights today in forest green and the selected day in cognac.
DateBlock
Magazine-style date display that renders month, day number, and weekday name in an editorial dateline layout. Server component.
Pullquote
Editorial blockquote with ruled top and bottom borders and an optional attribution citation. Suited for testimonials and highlighted copy.
Text
Polymorphic text primitive with body, caption, label, and code variants. Renders as any inline or block HTML tag via the `as` prop.
Hero
Three-column editorial hero with a 44px spine, a full-width copy column, and a 380px table-of-contents sidebar. Includes a scrolling ticker strip and collapses to a single column on mobile.
Features
Ledger-row feature list using a 56px index gutter, feature title, description, and a right-aligned tag. Roman numeral indexes reinforce the editorial aesthetic.
About
Two-column about section with forest green background, a pullquote, and body copy. Pairs a narrative text column with a supporting details column.