Pricing <mv-pricing>

Sección de precios con estilo de ficha técnica: paneles de planes dentro de un mismo marco atenuado, un selector segmentado mensual / anual sobre radios nativos, un plan recomendado marcado con un anillo, medidores de uso y un ahorro explícito tachado en los precios anuales; en columnas, en filas horizontales o con un único plan.

CategoríaBloques
TipoBloque (sección lista para usar) (<mv-pricing>)
Estadoestable
También instalabadge, button
Keywordspricing, tarifs, plans, tiers, popular, abonnement, subscription, monthly, yearly, billing, landing

When to use

  • Plans must be compared like a spec sheet with a monthly / yearly switch and explicit yearly savings
  • Plans should read as horizontal rows or a single plan instead of columns
  • Usage limits per plan should appear as meters next to the feature list

Avoid when

  • The page sells physical products with variants rather than subscription plans → use Buy Box instead

Instalación

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

Agente de IA con el servidor MCP de Marvelous UI: install_components({ slugs: ["pricing"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Archivos copiados (dependencias incluidas): tokens/tokens.css, core/base.css, components/badge/badge.css, components/button/button.css, core/element.js, core/i18n.js, components/pricing/pricing.css, components/pricing/pricing.js.

Uso

Marcado de referencia: parte de él y personalízalo con atributos, data-* y variables CSS:

<mv-tabs id="pricing-demo" value="tiers" data-size="sm" style="gap:0;background:var(--mv-bg)">
  <style>
    #pricing-demo > [role="tablist"] { justify-self: center; margin: .75rem auto 0; }
    /* The panels run edge to edge, so an outer ring would be clipped by the frame: draw it inside */
    #pricing-demo > [role="tabpanel"]:focus-visible { box-shadow: none; outline: 2px solid var(--mv-ring); outline-offset: -2px; }
  </style>
  <div role="tablist" aria-label="Block variant">
    <button role="tab" data-value="tiers">Plans</button>
    <button role="tab" data-value="rows">Rows</button>
    <button role="tab" data-value="single">Single plan</button>
  </div>

  <!-- ═════════ Plans grid ═════════ -->
  <div role="tabpanel" data-value="tiers">
    <mv-pricing>
      <section class="mv-pricing" aria-labelledby="pr-title">
        <div class="mv-pricing-inner">
          <header class="mv-pricing-header">
            <p class="mv-pricing-eyebrow">Pricing</p>
            <h2 class="mv-pricing-title" id="pr-title">Pay for the team you have today</h2>
            <p class="mv-pricing-lead">Start free, add members as you grow. Switch plans or cancel whenever you like.</p>
            <div class="mv-pricing-toggle" data-billing-toggle role="radiogroup" aria-label="Billing period">
              <label><input type="radio" name="pr-billing" value="monthly" checked>Monthly</label>
              <label><input type="radio" name="pr-billing" value="yearly">Yearly <span class="mv-badge" data-variant="success" data-size="sm">−20%</span></label>
            </div>
          </header>
          <div class="mv-pricing-plans">
            <article class="mv-pricing-plan" aria-labelledby="pr-solo">
              <div class="mv-pricing-plan-head">
                <h3 class="mv-pricing-name" id="pr-solo">Solo</h3>
                <p class="mv-pricing-desc">For freelancers juggling a handful of clients.</p>
              </div>
              <p class="mv-pricing-price">
                <span class="mv-pricing-amount" data-monthly="$0" data-yearly="$0">$0</span>
                <span class="mv-pricing-period">/ month</span>
                <span class="mv-pricing-billing" aria-live="polite" data-monthly="Free forever" data-yearly="Free forever">Free forever</span>
              </p>
              <a class="mv-button" data-variant="outline" href="#pricing-demo">Get started for free</a>
              <div class="mv-pricing-meters">
                <div class="mv-pricing-meter" role="meter" aria-label="Active projects" aria-valuemin="0" aria-valuemax="25" aria-valuenow="3" aria-valuetext="3" style="--value:12%"><span aria-hidden="true">Active projects</span><span aria-hidden="true">3</span></div>
                <div class="mv-pricing-meter" role="meter" aria-label="Storage" aria-valuemin="0" aria-valuemax="25" aria-valuenow="2" aria-valuetext="2 GB" style="--value:8%"><span aria-hidden="true">Storage</span><span aria-hidden="true">2 GB</span></div>
              </div>
              <ul class="mv-pricing-features">
                <li>Unlimited boards and sprints</li>
                <li>Time tracking</li>
                <li>Basic client portal</li>
                <li data-off>Planning assistant</li>
                <li data-off>Automations</li>
              </ul>
            </article>
            <article class="mv-pricing-plan" data-highlight aria-labelledby="pr-team">
              <div class="mv-pricing-plan-head">
                <h3 class="mv-pricing-name" id="pr-team">Team</h3>
                <span class="mv-badge mv-pricing-ribbon" data-variant="accent" data-size="sm">Recommended</span>
                <p class="mv-pricing-desc">For studios and product teams of up to 50 people.</p>
              </div>
              <p class="mv-pricing-price">
                <span class="mv-pricing-amount" data-monthly="$24" data-yearly="$19">$24</span>
                <span class="mv-pricing-was" data-monthly="" data-yearly="$24" aria-hidden="true"></span>
                <span class="mv-pricing-period">/ member / month</span>
                <span class="mv-pricing-billing" aria-live="polite" data-monthly="Billed monthly, no commitment" data-yearly="Billed $228 per member per year">Billed monthly, no commitment</span>
              </p>
              <a class="mv-button" href="#pricing-demo">Start 14-day free trial</a>
              <div class="mv-pricing-meters">
                <div class="mv-pricing-meter" role="meter" aria-label="Active projects" aria-valuemin="0" aria-valuemax="1" aria-valuenow="1" aria-valuetext="Unlimited" style="--value:100%"><span aria-hidden="true">Active projects</span><span aria-hidden="true">Unlimited</span></div>
                <div class="mv-pricing-meter" role="meter" aria-label="Storage" aria-valuemin="0" aria-valuemax="100" aria-valuenow="60" aria-valuetext="100 GB / member" style="--value:60%"><span aria-hidden="true">Storage</span><span aria-hidden="true">100 GB / member</span></div>
              </div>
              <ul class="mv-pricing-features">
                <li class="mv-pricing-features-title">Everything in Solo, plus:</li>
                <li>Unlimited projects and guests</li>
                <li>Planning assistant</li>
                <li>60 ready-made automations</li>
                <li>White-label client portal</li>
                <li>Weekly reports by email</li>
              </ul>
            </article>
            <article class="mv-pricing-plan" aria-labelledby="pr-ent">
              <div class="mv-pricing-plan-head">
                <h3 class="mv-pricing-name" id="pr-ent">Enterprise</h3>
                <p class="mv-pricing-desc">For organizations with strict security requirements.</p>
              </div>
              <p class="mv-pricing-price">
                <span class="mv-pricing-amount" data-monthly="$39" data-yearly="$31">$39</span>
                <span class="mv-pricing-was" data-monthly="" data-yearly="$39" aria-hidden="true"></span>
                <span class="mv-pricing-period">/ member / month</span>
                <span class="mv-pricing-billing" aria-live="polite" data-monthly="From 50 members" data-yearly="Billed $372 per member per year">From 50 members</span>
              </p>
              <a class="mv-button" data-variant="secondary" href="#pricing-demo">Talk to sales</a>
              <div class="mv-pricing-meters">
                <div class="mv-pricing-meter" role="meter" aria-label="Active projects" aria-valuemin="0" aria-valuemax="1" aria-valuenow="1" aria-valuetext="Unlimited" style="--value:100%"><span aria-hidden="true">Active projects</span><span aria-hidden="true">Unlimited</span></div>
                <div class="mv-pricing-meter" role="meter" aria-label="Storage" aria-valuemin="0" aria-valuemax="1" aria-valuenow="1" aria-valuetext="Unlimited" style="--value:100%"><span aria-hidden="true">Storage</span><span aria-hidden="true">Unlimited</span></div>
              </div>
              <ul class="mv-pricing-features">
                <li class="mv-pricing-features-title">Everything in Team, plus:</li>
                <li>SAML SSO and SCIM provisioning</li>
                <li>Audit log, custom retention</li>
                <li>Regional data hosting</li>
                <li>99.99% uptime SLA</li>
                <li>Named account manager</li>
              </ul>
            </article>
          </div>
          <p class="mv-pricing-note">Prices exclude tax. Nonprofits and schools get 50% off. <a href="#pricing-demo">Compare every feature</a></p>
        </div>
      </section>
    </mv-pricing>
  </div>

  <!-- ═════════ Rows ═════════ -->
  <div role="tabpanel" data-value="rows">
    <mv-pricing>
      <section class="mv-pricing" data-variant="rows" aria-labelledby="prr-title">
        <div class="mv-pricing-inner">
          <header class="mv-pricing-header">
            <p class="mv-pricing-eyebrow">Pricing</p>
            <h2 class="mv-pricing-title" id="prr-title">Three plans, no surprises</h2>
            <p class="mv-pricing-lead">Every plan includes unlimited boards, sprints and time tracking.</p>
            <div class="mv-pricing-toggle" data-billing-toggle role="radiogroup" aria-label="Billing period">
              <label><input type="radio" name="prr-billing" value="monthly" checked>Monthly</label>
              <label><input type="radio" name="prr-billing" value="yearly">Yearly <span class="mv-badge" data-variant="success" data-size="sm">−20%</span></label>
            </div>
          </header>
          <div class="mv-pricing-plans">
            <article class="mv-pricing-plan" aria-labelledby="prr-solo">
              <div class="mv-pricing-plan-head">
                <h3 class="mv-pricing-name" id="prr-solo">Solo</h3>
                <p class="mv-pricing-desc">For freelancers juggling a handful of clients.</p>
              </div>
              <p class="mv-pricing-price">
                <span class="mv-pricing-amount" data-monthly="$0" data-yearly="$0">$0</span>
                <span class="mv-pricing-period">/ month</span>
                <span class="mv-pricing-billing" aria-live="polite" data-monthly="Free forever" data-yearly="Free forever">Free forever</span>
              </p>
              <a class="mv-button" data-variant="outline" href="#pricing-demo">Get started for free</a>
              <ul class="mv-pricing-features">
                <li>Unlimited boards and sprints</li>
                <li>Time tracking</li>
                <li>Basic client portal</li>
                <li data-off>Planning assistant</li>
                <li data-off>Automations</li>
              </ul>
            </article>
            <article class="mv-pricing-plan" data-highlight aria-labelledby="prr-team">
              <div class="mv-pricing-plan-head">
                <h3 class="mv-pricing-name" id="prr-team">Team</h3>
                <span class="mv-badge mv-pricing-ribbon" data-variant="accent" data-size="sm">Recommended</span>
                <p class="mv-pricing-desc">For studios and product teams of up to 50 people.</p>
              </div>
              <p class="mv-pricing-price">
                <span class="mv-pricing-amount" data-monthly="$24" data-yearly="$19">$24</span>
                <span class="mv-pricing-was" data-monthly="" data-yearly="$24" aria-hidden="true"></span>
                <span class="mv-pricing-period">/ member / month</span>
                <span class="mv-pricing-billing" aria-live="polite" data-monthly="Billed monthly, no commitment" data-yearly="Billed $228 per member per year">Billed monthly, no commitment</span>
              </p>
              <a class="mv-button" href="#pricing-demo">Start 14-day free trial</a>
              <ul class="mv-pricing-features">
                <li class="mv-pricing-features-title">Everything in Solo, plus:</li>
                <li>Unlimited projects and guests</li>
                <li>Planning assistant</li>
                <li>60 ready-made automations</li>
                <li>White-label client portal</li>
                <li>Weekly reports by email</li>
              </ul>
            </article>
            <article class="mv-pricing-plan" aria-labelledby="prr-ent">
              <div class="mv-pricing-plan-head">
                <h3 class="mv-pricing-name" id="prr-ent">Enterprise</h3>
                <p class="mv-pricing-desc">For organizations with strict security requirements.</p>
              </div>
              <p class="mv-pricing-price">
                <span class="mv-pricing-amount" data-monthly="$39" data-yearly="$31">$39</span>
                <span class="mv-pricing-was" data-monthly="" data-yearly="$39" aria-hidden="true"></span>
                <span class="mv-pricing-period">/ member / month</span>
                <span class="mv-pricing-billing" aria-live="polite" data-monthly="From 50 members" data-yearly="Billed $372 per member per year">From 50 members</span>
              </p>
              <a class="mv-button" data-variant="secondary" href="#pricing-demo">Talk to sales</a>
              <ul class="mv-pricing-features">
                <li class="mv-pricing-features-title">Everything in Team, plus:</li>
                <li>SAML SSO and SCIM provisioning</li>
                <li>Audit log, custom retention</li>
                <li>Regional data hosting</li>
                <li>99.99% uptime SLA</li>
                <li>Named account manager</li>
              </ul>
            </article>
          </div>
          <p class="mv-pricing-note">Prices exclude tax. Nonprofits and schools get 50% off. <a href="#pricing-demo">Compare every feature</a></p>
        </div>
      </section>
    </mv-pricing>
  </div>

  <!-- ═════════ Single plan ═════════ -->
  <div role="tabpanel" data-value="single">
    <mv-pricing billing="yearly">
      <section class="mv-pricing" data-variant="single" aria-labelledby="pr1-title" style="--mv-pricing-bg:var(--mv-bg-subtle)">
        <div class="mv-pricing-inner">
          <header class="mv-pricing-header">
            <p class="mv-pricing-eyebrow">One plan</p>
            <h2 class="mv-pricing-title" id="pr1-title">Everything included, for everyone</h2>
            <p class="mv-pricing-lead">No hidden tiers or paid add-ons: every member gets all of Canopy.</p>
            <div class="mv-pricing-toggle" data-billing-toggle role="radiogroup" aria-label="Billing period">
              <label><input type="radio" name="pr1-billing" value="monthly">Monthly</label>
              <label><input type="radio" name="pr1-billing" value="yearly" checked>Yearly <span class="mv-badge" data-variant="success" data-size="sm">2 months free</span></label>
            </div>
          </header>
          <article class="mv-pricing-single" aria-labelledby="pr1-name">
            <div class="mv-pricing-single-body">
              <div class="mv-pricing-plan-head">
                <h3 class="mv-pricing-name" id="pr1-name">Canopy Pro</h3>
                <span class="mv-badge" data-variant="secondary" data-size="sm">New</span>
                <p class="mv-pricing-desc">Plan, track and bill your projects, for teams of 1 to 500 people.</p>
              </div>
              <ul class="mv-pricing-features">
                <li class="mv-pricing-features-title">What's included</li>
                <li>Unlimited projects and guests</li>
                <li>Planning assistant</li>
                <li>Time tracking and payroll export</li>
                <li>White-label client portal</li>
                <li>120 integrations</li>
                <li>SSO and audit log</li>
                <li>24/7 human support</li>
                <li>US or EU data hosting</li>
              </ul>
            </div>
            <div class="mv-pricing-single-aside">
              <p class="mv-pricing-price">
                <span class="mv-pricing-amount" data-monthly="$24" data-yearly="$20">$20</span>
                <span class="mv-pricing-was" data-monthly="" data-yearly="$24" aria-hidden="true">$24</span>
                <span class="mv-pricing-period">/ member / month</span>
                <span class="mv-pricing-billing" aria-live="polite" data-monthly="Billed monthly, no commitment" data-yearly="Billed $240 per member per year">Billed $240 per member per year</span>
              </p>
              <a class="mv-button" data-size="lg" href="#pricing-demo">Start free trial</a>
              <p class="mv-pricing-billing">14-day trial, no credit card required</p>
            </div>
          </article>
        </div>
      </section>
    </mv-pricing>
  </div>
</mv-tabs>

API

Attributes

NameTipoPredeterminadoDescripción
billingmonthly | yearlymonthlyOn <mv-pricing>: active period (reflected as an attribute, controllable from outside). Without the attribute, it is read from the checked radio.
data-variantrows | singleOn .mv-pricing: rows = one horizontal band per plan from 50rem (head · features · price + CTA; meters hidden); single = one plan (.mv-pricing-single). Default: plan columns (1 → 2 → 3).
data-highlightbooleanOn a plan: recommended (accent ring, raised); put a .mv-badge.mv-pricing-ribbon in its -plan-head.
data-monthly / data-yearlystringOn any descendant: value per period; its text is replaced (an empty value empties it). An <mv-number-ticker>, if you use one, gets its value attribute set instead.
data-billing-togglebooleanOn the radio group (or a <mv-toggle-group>) that drives the period.
data-offbooleanOn a .mv-pricing-features <li>: feature not included (dash mark, struck through).

Events

NameDescripción
mv-changePeriod changed (detail.billing).

Content structure

NameDescripción
.mv-pricing-header-eyebrow, -title, -lead on the left; the .mv-pricing-toggle moves to the right from 48rem.
.mv-pricing-toggleSegmented control: two <label><input type=radio></label> (inputs visually hidden, still focusable), optional discount badge.
.mv-pricing-plans > .mv-pricing-plan-plan-head (-name, optional badge, -desc), -price (-amount, optional -was, -period, -billing), button, optional -meters, -features (-features-title).
.mv-pricing-wasStruck-through reference price, shown only while billing is yearly (give it data-monthly="" data-yearly="$24").
.mv-pricing-meters > .mv-pricing-meterRead-only usage bar: two <span> (label, value) and --value (0-100%); give it role="meter" with aria-value* / aria-valuetext.
.mv-pricing-single-single-body (head + features in 2 columns) and -single-aside (price + CTA), split by a dashed rule from 44rem.
.mv-pricing-noteNote below the plans.

CSS classes

NameDescripción
mv-pricingRoot section, mv-pricing query container.

CSS variables

NamePredeterminadoDescripción
--mv-pricing-columns3Columns from 60rem.
--mv-pricing-max72remMax width.
--mv-pricing-bgtransparentSection background.
--mv-pricing-framevar(--mv-bg-muted)Color of the frame around the plans and of the switch track.

Accessibility

The switch uses native radios (role=radiogroup, arrow keys, focus ring on the label). Each plan is an <article> labeled by its name. Billing text is aria-live="polite"; the struck-through price is aria-hidden (the billing line states the yearly total). Usage bars are role=meter with a text value. Works without JS (prices stay on the initial period). Forced colors: panels outlined, the selected billing option and the recommended plan in Highlight, checks and meters redrawn with system colors.

Esta página se tradujo con IA. Informar de un problema de traducción