---
/**
* PricingCommission: one lead offer shown large, the other packages as a
* quiet list beneath. Suits studios and services that quote by appointment.
* The featured tier leads (or the first, if none is featured).
*
* @example
* <PricingCommission title="Commissions" accent="by appointment." tiers={[...]} />
*/
import Button from "../button/Button.astro";
import Icon from "../icon/Icon.astro";
interface Cta {
label: string;
href: string;
}
interface Tier {
name: string;
price: string;
period?: string;
description?: string;
features?: string[];
cta: Cta;
featured?: boolean;
}
interface Props {
title: string;
accent?: string;
intro?: string;
tiers: Tier[];
as?: "h2" | "h3";
class?: string;
}
const { title, accent, intro, tiers, as: Heading = "h2", class: className } = Astro.props;
const leadIndex = Math.max(0, tiers.findIndex((t) => t.featured));
const lead = tiers[leadIndex];
const rest = tiers.filter((_, i) => i !== leadIndex);
---
<section class:list={["vs-pricing-commission", className]}>
<div class="vs-pricing-commission__inner">
<Heading class="vs-display vs-pricing-commission__title">{title}{accent && <> <em>{accent}</em></>}</Heading>
{intro && <p class="vs-pricing-commission__intro">{intro}</p>}
{
lead && (
<article class="vs-pricing-commission__lead">
<div>
<h3 class="vs-pricing-commission__name">{lead.name}</h3>
<p class="vs-display vs-pricing-commission__price">{lead.price}</p>
{lead.period && <p class="vs-pricing-commission__period">{lead.period}</p>}
{lead.description && <p class="vs-pricing-commission__desc">{lead.description}</p>}
<div class="vs-pricing-commission__action">
<Button href={lead.cta.href} variant="primary">{lead.cta.label}</Button>
</div>
</div>
{lead.features && lead.features.length > 0 && (
<ul class="vs-pricing-commission__features">
{lead.features.map((f) => (
<li>
<Icon name="check" size={16} strokeWidth={2.25} />
<span>{f}</span>
</li>
))}
</ul>
)}
</article>
)
}
{
rest.length > 0 && (
<ul class="vs-pricing-commission__also" aria-label="Other packages">
{rest.map((t) => (
<li>
<span class="vs-pricing-commission__also-name">{t.name}</span>
<span class="vs-pricing-commission__also-desc">{t.description}</span>
<span class="vs-pricing-commission__also-price">{t.price}</span>
<a class="vs-pricing-commission__also-link" href={t.cta.href}>
{t.cta.label}
<span class="vs-sr-only">: {t.name}</span>
<Icon name="arrow-right" size={14} />
</a>
</li>
))}
</ul>
)
}
</div>
</section>
<style>
.vs-pricing-commission {
container-type: inline-size;
background: var(--vs-page);
color: var(--vs-ink);
font-family: var(--vs-font-sans);
font-stretch: var(--vs-font-stretch);
}
.vs-pricing-commission__inner {
max-width: var(--vs-container);
margin-inline: auto;
padding: var(--vs-section-y) var(--vs-gutter);
}
.vs-pricing-commission__title {
font-size: clamp(2rem, 6.5cqi, 4.25rem);
}
.vs-pricing-commission__intro {
max-width: 34rem;
margin: 1.25rem 0 0;
font-size: 1.0625rem;
line-height: 1.55;
color: var(--vs-ink-2);
}
.vs-pricing-commission__lead {
display: grid;
gap: 32px;
margin-top: clamp(28px, 5cqi, 56px);
padding: clamp(24px, 5cqi, 48px);
border: var(--vs-border-w) solid var(--vs-line);
border-radius: var(--vs-radius-window);
background: var(--vs-surface);
box-shadow: var(--vs-pop-shadow, var(--vs-shadow-md));
}
.vs-pricing-commission__name {
margin: 0;
font-size: 1.125rem;
font-weight: 600;
}
.vs-pricing-commission__price {
margin-top: 20px;
font-size: clamp(3rem, 10cqi, 6rem);
line-height: 1;
}
.vs-pricing-commission__period {
margin: 8px 0 0;
font-size: 0.8125rem;
color: var(--vs-ink-3);
}
.vs-pricing-commission__desc {
max-width: 26rem;
margin: 16px 0 0;
font-size: 0.9375rem;
line-height: 1.55;
color: var(--vs-ink-2);
}
.vs-pricing-commission__action {
margin-top: 24px;
}
.vs-pricing-commission__features {
display: grid;
gap: 12px;
align-content: start;
margin: 0;
padding: 0;
list-style: none;
font-size: 0.9375rem;
}
.vs-pricing-commission__features li {
display: flex;
gap: 10px;
line-height: 1.4;
}
.vs-pricing-commission__features :global(.vs-icon) {
margin-top: 2px;
color: var(--vs-accent-ink);
}
@container (min-width: 760px) {
.vs-pricing-commission__lead {
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
gap: clamp(32px, 6cqi, 72px);
}
.vs-pricing-commission__features {
padding-left: clamp(24px, 4cqi, 48px);
border-left: var(--vs-border-w) solid var(--vs-line);
}
}
.vs-pricing-commission__also {
margin: 0;
padding: 0;
list-style: none;
}
.vs-pricing-commission__also li {
display: grid;
gap: 4px 20px;
padding: 18px 4px;
border-bottom: var(--vs-border-w) solid var(--vs-line-strong);
}
.vs-pricing-commission__also-name,
.vs-pricing-commission__also-price {
font-weight: 600;
}
.vs-pricing-commission__also-desc {
font-size: 0.9375rem;
color: var(--vs-ink-2);
}
.vs-pricing-commission__also-link {
display: inline-flex;
align-items: center;
gap: 6px;
width: fit-content;
font-size: 0.875rem;
font-weight: 500;
color: var(--vs-ink);
text-underline-offset: 4px;
}
.vs-pricing-commission__also-link:focus-visible {
outline: none;
box-shadow: var(--vs-focus-ring);
}
@container (min-width: 760px) {
.vs-pricing-commission__also li {
grid-template-columns: minmax(0, 3fr) minmax(0, 6fr) minmax(0, 2fr) auto;
align-items: baseline;
}
}
</style>