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.

CategoryBlocks
TypeBlock (ready-made section) (.mv-features)
Statusstable
Also installsbutton
Keywordsfeatures, fonctionnalités, grid, panels, steps, how it works, landing, marketing, editorial

When to use

Avoid when

Install

node scripts/add.mjs features --out ./src/marvelous

AI 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&amp;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

NameTypeDefaultDescription
data-variantindex | panels | ledgerindexindex / 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

NameDescription
.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-itemIndex 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-panelTinted 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-rowNumbered row: -row-body (-row-title, -row-text, -list) and an optional -row-media shown on the right from 44rem.

CSS classes

NameDescription
mv-featuresRoot section, mv-features query container.
mv-features-iconBordered square icon badge.
mv-features-link / -panel-linkText link with an arrow that nudges on hover; -panel-link makes the whole panel clickable.
mv-features-listCheckmark list (CSS only, no icon markup).

CSS variables

NameDefaultDescription
--mv-features-max72remMax width.
--mv-features-bgtransparentSection background.
--mv-features-rulevar(--mv-border-strong)Color of the main hairlines.
--mv-features-huevar(--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-top2remSticky 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.