Features — .mv-features
Editorial features section: a numbered index grid on hairlines, tinted panels whose whole tile is the link, or a ledger with a sticky intro and numbered steps.
| Category | Blocks |
|---|---|
| Type | Block (ready-made section) (.mv-features) |
| Status | stable |
| Also installs | button |
| Keywords | features, fonctionnalités, grid, panels, steps, how it works, landing, marketing, editorial |
When to use
- A marketing page must present product features as a numbered editorial grid on hairlines
- Each feature needs a tinted panel whose whole tile links to a detail page
- A how-it-works section should list numbered steps beside a sticky intro
Avoid when
- Steps must be tied to a pinned visual that changes as the user scrolls → use Sticky Scroll instead
Install
node scripts/add.mjs features --out ./src/marvelousAI agent with the Marvelous UI MCP server: install_components({ slugs: ["features"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).
Files copied (dependencies included): tokens/tokens.css, core/base.css, components/features/features.css, components/button/button.css.
Usage
Canonical markup — start from it and customize with attributes, data-* and CSS variables:
<mv-tabs id="features-demo" value="index" data-size="sm" style="gap:0;background:var(--mv-bg)">
<style>
#features-demo > [role="tablist"] { justify-self: center; margin: .75rem auto 0; }
/* ── Demo art inside the panels (replace with your own visuals) ── */
#features-demo .fx { isolation: isolate; display: grid; gap: .5rem; font-size: 12px; line-height: 1.4; font-variant-numeric: tabular-nums; }
#features-demo .fx-card { display: flex; align-items: center; gap: .65rem; padding: .6rem .75rem; border: 1px solid var(--mv-border); border-radius: var(--mv-radius-md); background: var(--mv-surface); box-shadow: var(--mv-shadow-sm); }
#features-demo .fx-card small { display: block; color: var(--mv-fg-subtle); font-size: 11px; }
#features-demo .fx-card > :last-child { margin-left: auto; }
#features-demo .fx-card[data-dim] { opacity: .55; scale: .96; margin-top: -.9rem; position: relative; z-index: -1; }
#features-demo .fx-ico { display: grid; place-items: center; flex: none; width: 1.75rem; height: 1.75rem; border-radius: 6px; background: var(--mv-bg-muted); font-weight: 600; font-size: 11px; }
#features-demo .fx-btn { padding: .2rem .55rem; border-radius: 5px; background: var(--mv-fg); color: var(--mv-bg); font-weight: 600; font-size: 11px; }
#features-demo .fx-tag { padding: .1rem .45rem; border-radius: 4px; font: 500 10.5px/1.5 var(--mv-font-mono); color: var(--mv-success); background: color-mix(in oklch, var(--mv-success) 13%, transparent); }
#features-demo .fx-bars { display: flex; align-items: end; gap: 5px; height: 5.5rem; padding: .75rem; border: 1px solid var(--mv-border); border-radius: var(--mv-radius-md); background: var(--mv-surface); box-shadow: var(--mv-shadow-sm); }
#features-demo .fx-bars i { flex: 1; height: var(--v); border-radius: 2px 2px 0 0; background: var(--mv-bg-emphasis); }
#features-demo .fx-bars i[data-f] { background: repeating-linear-gradient(135deg, var(--mv-fg) 0 2px, transparent 2px 5px); border: 1px solid var(--mv-fg); border-bottom: 0; }
#features-demo .fx-bars i[data-now] { background: var(--mv-fg); }
#features-demo .fx-log { display: grid; gap: .35rem; padding: .75rem; border: 1px solid var(--mv-border); border-radius: var(--mv-radius-md); background: var(--mv-surface); box-shadow: var(--mv-shadow-sm); font: 11px/1.45 var(--mv-font-mono); color: var(--mv-fg-muted); }
#features-demo .fx-log b { color: var(--mv-fg); font-weight: 500; }
#features-demo .fx-limit { height: 5px; margin-top: .45rem; border-radius: 99px; background: var(--mv-bg-muted); overflow: hidden; }
#features-demo .fx-limit i { display: block; width: 64%; height: 100%; background: var(--mv-fg); }
#features-demo .fx-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5rem; }
/* ── Demo media in a ledger row ── */
#features-demo .fx-media { display: grid; gap: .45rem; padding: .85rem; font: 11px/1.45 var(--mv-font-mono); color: var(--mv-fg-muted); }
#features-demo .fx-media div { display: flex; justify-content: space-between; gap: .5rem; padding-bottom: .45rem; border-bottom: 1px dashed var(--mv-border); }
#features-demo .fx-media div:last-child { border: 0; padding: 0; color: var(--mv-fg); font-weight: 600; }
</style>
<div role="tablist" aria-label="Block variant">
<button role="tab" data-value="index">Index grid</button>
<button role="tab" data-value="panels">Panels</button>
<button role="tab" data-value="ledger">Ledger</button>
</div>
<!-- ═════════ Index grid (default) ═════════ -->
<div role="tabpanel" data-value="index">
<section class="mv-features" aria-labelledby="ft-i-title">
<div class="mv-features-inner">
<header class="mv-features-header">
<p class="mv-features-eyebrow">Platform</p>
<h2 class="mv-features-title" id="ft-i-title">Everything month-end needs, <span class="mv-features-muted">in one ledger.</span></h2>
<p class="mv-features-lead">Six building blocks that replace the spreadsheet, the shared inbox and the checklist taped to your monitor.</p>
</header>
<ul class="mv-features-grid">
<li class="mv-features-item">
<span class="mv-features-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M3 21h18M5 21V10M19 21V10M9 21v-7M15 21v-7M12 3 3 8h18z"/></svg></span>
<h3 class="mv-features-item-title">Live bank feeds</h3>
<p class="mv-features-item-text">Transactions from 11,000 banks land every hour, already categorised and converted at the day’s ECB rate.</p>
</li>
<li class="mv-features-item">
<span class="mv-features-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3M16 3h3a2 2 0 0 1 2 2v3M8 21H5a2 2 0 0 1-2-2v-3M16 21h3a2 2 0 0 0 2-2v-3"/><path d="m8 12 3 3 5-6"/></svg></span>
<h3 class="mv-features-item-title">Auto-matching</h3>
<p class="mv-features-item-text">Rules and learned patterns pair 98% of lines with their invoice or receipt. You only look at the exceptions.</p>
</li>
<li class="mv-features-item">
<span class="mv-features-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M9 11 12 14 22 4"/><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"/></svg></span>
<h3 class="mv-features-item-title">Approval chains</h3>
<p class="mv-features-item-text">Route bills by amount, entity or cost centre. Approvers sign off from Slack or email in a single tap.</p>
</li>
<li class="mv-features-item">
<span class="mv-features-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M12 8v4l3 2"/><path d="M3.05 11a9 9 0 1 1 .5 4M3 4v7h7"/></svg></span>
<h3 class="mv-features-item-title">Immutable audit trail</h3>
<p class="mv-features-item-text">Every edit, match and approval is timestamped and signed. Hand your auditor a read-only link, not a zip file.</p>
</li>
<li class="mv-features-item">
<span class="mv-features-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><path d="M14 17.5h7M17.5 14v7"/></svg></span>
<h3 class="mv-features-item-title">Multi-entity</h3>
<p class="mv-features-item-text">Run 40 subsidiaries in 12 currencies. Intercompany balances eliminate themselves at consolidation.</p>
</li>
<li class="mv-features-item">
<span class="mv-features-icon" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"><path d="M9 6h11M9 12h11M9 18h11"/><path d="m3 6 1 1 2-2M3 12l1 1 2-2M3 18l1 1 2-2"/></svg></span>
<h3 class="mv-features-item-title">Close checklist</h3>
<p class="mv-features-item-text">A shared, recurring task list with owners and due dates, so day five of the close is never a surprise.</p>
<a class="mv-features-link" href="#features-demo">See the template</a>
</li>
</ul>
</div>
</section>
</div>
<!-- ═════════ Panels ═════════ -->
<div role="tabpanel" data-value="panels">
<section class="mv-features" data-variant="panels" aria-labelledby="ft-p-title">
<div class="mv-features-inner">
<header class="mv-features-header">
<p class="mv-features-eyebrow">Spend management</p>
<h2 class="mv-features-title" id="ft-p-title">Control spend <span class="mv-features-muted">before it becomes a variance.</span></h2>
<p class="mv-features-lead">Cards, bills and receipts flow into the same ledger your accountants already trust.</p>
</header>
<ul class="mv-features-panels">
<li class="mv-features-panel" data-span="2" style="--mv-features-hue:265">
<p class="mv-features-panel-eyebrow">Approvals</p>
<h3 class="mv-features-item-title">Sign off on bills from anywhere</h3>
<p class="mv-features-item-text">Requests arrive with the PO, the contract and last year’s spend with that vendor attached.</p>
<a class="mv-features-panel-link" href="#features-demo">Explore approvals</a>
<div class="mv-features-panel-art" aria-hidden="true">
<div class="fx">
<div class="fx-card"><span class="fx-ico">CH</span><span>Cloudmere Hosting<small>$1,196.40 · Engineering</small></span><span class="fx-btn">Approve</span></div>
<div class="fx-card" data-dim><span class="fx-ico">BL</span><span>Brightwater Legal<small>$3,150.00 · Legal</small></span><span class="fx-btn">Approve</span></div>
</div>
</div>
</li>
<li class="mv-features-panel" style="--mv-features-hue:150">
<p class="mv-features-panel-eyebrow">Receipts</p>
<h3 class="mv-features-item-title">Snap it, forget it</h3>
<p class="mv-features-item-text">Forward or photograph a receipt; it finds its transaction on its own.</p>
<a class="mv-features-panel-link" href="#features-demo">How matching works</a>
<div class="mv-features-panel-art" aria-hidden="true">
<div class="fx"><div class="fx-card"><span class="fx-ico">VC</span><span>Vela Coffee<small>−$86.50 · Sep 26</small></span><span class="fx-tag">MATCHED</span></div></div>
</div>
</li>
<li class="mv-features-panel" style="--mv-features-hue:55">
<p class="mv-features-panel-eyebrow">Cards</p>
<h3 class="mv-features-item-title">Limits that enforce policy</h3>
<p class="mv-features-item-text">Issue virtual cards per vendor, with budgets that reset monthly.</p>
<a class="mv-features-panel-link" href="#features-demo">Issue a card</a>
<div class="mv-features-panel-art" aria-hidden="true">
<div class="fx"><div class="fx-card" style="display:block">Design tools · •••• 4417<small>$640 of $1,000 this month</small><div class="fx-limit"><i></i></div></div></div>
</div>
</li>
<li class="mv-features-panel" style="--mv-features-hue:215">
<p class="mv-features-panel-eyebrow">Forecast</p>
<h3 class="mv-features-item-title">Cash, twelve weeks out</h3>
<p class="mv-features-item-text">Scheduled bills and expected receivables, projected week by week.</p>
<a class="mv-features-panel-link" href="#features-demo">Open the forecast</a>
<div class="mv-features-panel-art" aria-hidden="true">
<div class="fx-bars"><i style="--v:42%"></i><i style="--v:55%"></i><i style="--v:48%"></i><i style="--v:66%"></i><i data-now style="--v:72%"></i><i data-f style="--v:78%"></i><i data-f style="--v:70%"></i><i data-f style="--v:86%"></i></div>
</div>
</li>
<li class="mv-features-panel" style="--mv-features-hue:340">
<p class="mv-features-panel-eyebrow">Audit</p>
<h3 class="mv-features-item-title">A log nobody can edit</h3>
<p class="mv-features-item-text">Signed, append-only history for every figure in the books.</p>
<a class="mv-features-panel-link" href="#features-demo">Read the security page</a>
<div class="mv-features-panel-art" aria-hidden="true">
<div class="fx-log"><span>09:41 <b>A. Reyes</b> matched #8812</span><span>09:43 <b>J. Tan</b> approved BL-221</span><span>09:47 <b>system</b> locked Aug 2026</span></div>
</div>
</li>
</ul>
</div>
</section>
</div>
<!-- ═════════ Ledger ═════════ -->
<div role="tabpanel" data-value="ledger">
<section class="mv-features" data-variant="ledger" aria-labelledby="ft-l-title" style="--mv-features-bg:var(--mv-bg-subtle)">
<div class="mv-features-inner">
<header class="mv-features-header">
<p class="mv-features-eyebrow">How the close works</p>
<h2 class="mv-features-title" id="ft-l-title">Four steps, <span class="mv-features-muted">one shared screen.</span></h2>
<p class="mv-features-lead">The same sequence your controller runs today — minus the copy-paste between six tools.</p>
<div class="mv-features-actions">
<a class="mv-button" href="#features-demo">Book a walkthrough</a>
<a class="mv-button" data-variant="ghost" href="#features-demo">Download the playbook</a>
</div>
</header>
<ol class="mv-features-rows">
<li class="mv-features-row">
<div class="mv-features-row-body">
<h3 class="mv-features-row-title">Connect your accounts</h3>
<p class="mv-features-row-text">Link banks, cards and your ERP in about ten minutes. Historical data back to January imports automatically.</p>
</div>
</li>
<li class="mv-features-row">
<div class="mv-features-row-body">
<h3 class="mv-features-row-title">Clear the exceptions</h3>
<p class="mv-features-row-text">Ledgerline pre-matches everything it can and queues the rest, grouped by what’s missing.</p>
<ul class="mv-features-list">
<li>Missing receipts go straight to the cardholder</li>
<li>Amount mismatches show both documents side by side</li>
</ul>
</div>
<div class="mv-features-row-media" role="img" aria-label="Exception queue: 18 lines, of which 11 missing receipts, 5 amount mismatches and 2 duplicates">
<div class="fx-media" aria-hidden="true">
<div><span>Missing receipt</span><span>11</span></div>
<div><span>Amount differs</span><span>5</span></div>
<div><span>Possible duplicate</span><span>2</span></div>
<div><span>To review</span><span>18</span></div>
</div>
</div>
</li>
<li class="mv-features-row">
<div class="mv-features-row-body">
<h3 class="mv-features-row-title">Post accruals and adjustments</h3>
<p class="mv-features-row-text">Recurring journals draft themselves from last month; reviewers approve them in bulk.</p>
</div>
</li>
<li class="mv-features-row">
<div class="mv-features-row-body">
<h3 class="mv-features-row-title">Lock the period</h3>
<p class="mv-features-row-text">One click freezes the month and publishes the reporting pack to your board folder.</p>
<ul class="mv-features-list">
<li>P&L, balance sheet and cash flow in PDF and XLSX</li>
<li>Variance commentary carried over from each owner</li>
</ul>
</div>
</li>
</ol>
</div>
</section>
</div>
</mv-tabs>API
Attributes
| Name | Type | Default | Description |
|---|---|---|---|
data-variant | index | panels | ledger | index | index / panels: header with title on the left and lead on the right (from 48rem); ledger: the header becomes a sticky left column next to the rows (from 60rem). The body layout comes from the structure you use (.mv-features-grid, .mv-features-panels or .mv-features-rows). |
Content structure
| Name | Description |
|---|---|
.mv-features-header | -eyebrow (mono kicker with an accent square), -title (with -muted), -lead, and in ledger an optional -actions row. |
.mv-features-grid > .mv-features-item | Index grid, 1 → 2 → 3 columns: automatic 01, 02… number on a hairline, optional -icon (top right), -item-title, -item-text, optional -link. |
.mv-features-panels > .mv-features-panel | Tinted tile (--mv-features-hue): -panel-eyebrow, -item-title, -item-text, -panel-link (stretched over the tile), -panel-art (visual pinned to the bottom). data-span="2" spans two columns from 64rem. |
.mv-features-rows > .mv-features-row | Numbered row: -row-body (-row-title, -row-text, -list) and an optional -row-media shown on the right from 44rem. |
CSS classes
| Name | Description |
|---|---|
mv-features | Root section, mv-features query container. |
mv-features-icon | Bordered square icon badge. |
mv-features-link / -panel-link | Text link with an arrow that nudges on hover; -panel-link makes the whole panel clickable. |
mv-features-list | Checkmark list (CSS only, no icon markup). |
CSS variables
| Name | Default | Description |
|---|---|---|
--mv-features-max | 72rem | Max width. |
--mv-features-bg | transparent | Section background. |
--mv-features-rule | var(--mv-border-strong) | Color of the main hairlines. |
--mv-features-hue | var(--mv-accent-h) | Per-panel tint hue (OKLCH), adapted to light and dark. |
--mv-features-panel-bg | (tint from --mv-features-hue) | Explicit panel background. |
--mv-features-sticky-top | 2rem | Sticky offset of the ledger header. |
Accessibility
Hierarchical headings (section h2, one h3 per feature); items are list elements so screen readers announce the count. Numbers are CSS-generated (decorative). Panel art is aria-hidden; a panel's stretched link keeps its own accessible name and shows the focus ring on the whole tile. Informative media get role="img" + aria-label.