---
import BaseLayout from '../layouts/BaseLayout.astro';

// Pricing structure locked 2026-04-25:
//   Free       $0/mo            1 printer  · 1 seat   · personal use
//   Pro        $49/mo           1 printer  · 1 seat   · hobbyists & personal projects
//   Business   $199/mo          3 printers · 3 seats · for prints you sell
//                                +$15/printer over 3 (cap 50)
//                                +$50/seat over 3 (cap 10)
//   Enterprise hidden            50 printers · flexible · custom
//                                Contact us — quoted per deal.
//
// Annual ~20% off for Pro and Business.  Enterprise is custom.
//
// Copy convention: tier descriptions in this file deliberately avoid
// the words "commercial use" and "non-commercial license" because
// Kiln itself ships under AGPL-3.0, and the FAQ at the bottom of
// this page references a *separate* "AGPL commercial license" for
// proprietary code use.  Two unrelated meanings of "commercial" on
// the same page would confuse OSS-aware buyers.  Use concrete
// behaviour ("selling what you print" / "personal projects") for
// the subscription-tier UI; reserve "commercial license" for the
// AGPL-alternative FAQ where it's the standard term of art.

const pricingSchema = {
  '@type': 'OfferCatalog',
  name: 'Kiln Pricing Plans',
  itemListElement: [
    {
      '@type': 'Offer',
      name: 'Free',
      price: '0',
      priceCurrency: 'USD',
      availability: 'https://schema.org/InStock',
      url: 'https://kiln3d.com/pricing',
    },
    {
      '@type': 'Offer',
      name: 'Pro',
      price: '49',
      priceCurrency: 'USD',
      availability: 'https://schema.org/InStock',
      url: 'https://kiln3d.com/pricing',
    },
    {
      '@type': 'Offer',
      name: 'Business',
      price: '199',
      priceCurrency: 'USD',
      availability: 'https://schema.org/InStock',
      url: 'https://kiln3d.com/pricing',
    },
    // Enterprise omitted from schema — pricing is custom-quoted per
    // deal, not a public number.  Keeping it in the schema would
    // anchor every Google rich-result viewer to a specific dollar
    // figure that varies wildly by customer profile (compliance-grade
    // verticals vs SMB-leaning Enterprise).
  ],
};

const pricingFaqSchema = {
  '@type': 'FAQPage',
  mainEntity: [
    {
      '@type': 'Question',
      name: 'Is local printing really free?',
      acceptedAnswer: {
        '@type': 'Answer',
        text: 'Yes. Kiln is open source under AGPL-3.0 and local printing, slicing, and printer control are free forever.',
      },
    },
    {
      '@type': 'Question',
      name: 'Can I self-host everything?',
      acceptedAnswer: {
        '@type': 'Answer',
        text: 'Yes. Kiln runs entirely locally. Pro/Business/Enterprise tiers add optional cloud features, but free tier local basic functionality never requires a subscription.',
      },
    },
    {
      '@type': 'Question',
      name: 'Do I need a paid plan for multiple printers?',
      acceptedAnswer: {
        '@type': 'Answer',
        text: 'Free and Pro tiers each support 1 printer. Business includes 3 printers ($15/mo per additional, up to 50). For larger fleets, Enterprise is custom-quoted.',
      },
    },
    {
      '@type': 'Question',
      name: "What's included in Enterprise?",
      acceptedAnswer: {
        '@type': 'Answer',
        text: 'Enterprise is for teams running production print operations. It includes a dedicated single-tenant MCP server, SSO, role-based access control, full audit trails, lockable safety profiles, and a 99.9% uptime SLA. Pricing is custom — contact us for a quote that fits your team and use case.',
      },
    },
  ],
};
---

<BaseLayout
  title="Kiln Pricing — Plans for AI 3D Printing Infrastructure"
  description="Kiln pricing for AI 3D printing infrastructure. Local printing is free forever. Paid tiers add fleet management, hosted MCP, and enterprise controls."
  current="pricing"
  keywords={[
    'kiln pricing',
    '3d print farm pricing',
    'ai 3d printer infrastructure pricing',
    'mcp server pricing',
  ]}
  schema={[pricingSchema, pricingFaqSchema]}
>
  <section class="pricing-hero">
    <div class="container">
      <h1>Pricing</h1>
    </div>
  </section>

  <section class="pricing-cards">
    <div class="container-wide">
      <div class="billing-toggle">
        <span class="toggle-label" data-period="monthly">Monthly</span>
        <label class="toggle-switch">
          <input type="checkbox" id="billing-toggle" />
          <span class="toggle-slider"></span>
        </label>
        <span class="toggle-label" data-period="annual">Annual <span class="save-badge">Save 20%</span></span>
      </div>

      <div class="cards-grid">
        <!-- Free Tier -->
        <div class="card pricing-card">
          <div class="card-header">
            <h3>Free</h3>
            <p class="tier-tagline">For trying Kiln on your own printer.</p>
            <div class="price">
              <span class="amount">$0</span>
              <span class="period">/ forever</span>
            </div>
          </div>
          <ul class="features">
            <li><span class="check">&#10003;</span> Unlimited local printing</li>
            <li><span class="check">&#10003;</span> 1 printer</li>
            <li><span class="check">&#10003;</span> For personal projects</li>
            <li><span class="check">&#10003;</span> 10-job queue</li>
            <li><span class="check">&#10003;</span> Design intelligence (25 FDM materials, 45 brand-specific filament profiles, 20 patterns)</li>
            <li><span class="check">&#10003;</span> Natural-language to physical fabrication &mdash; text/image to validated 3D print</li>
            <li><span class="check">&#10003;</span> Multi-modal decoration engine &mdash; 3/mo (QR, photos, text, SVG, brand assets)</li>
            <li><span class="check">&#10003;</span> Closed-loop AI generation feedback &mdash; failed prints auto-improve future generations</li>
            <li><span class="check">&#10003;</span> Printability engine (7-dimension analysis with conservative material defaults)</li>
            <li><span class="check">&#10003;</span> Multi-part assembly (up to 10 parts)</li>
            <li><span class="check">&#10003;</span> Cost estimation &amp; recommendations</li>
            <li><span class="check">&#10003;</span> 14-component parametric catalog</li>
            <li><span class="check">&#10003;</span> Local design history (linear) &mdash; branching, merge, and signed releases require Pro</li>
            <li><span class="check">&#10003;</span> 800 MCP capabilities &amp; 221 CLI commands</li>
            <li><span class="check">&#10003;</span> Community support</li>
            <li><span class="check">&#10003;</span> 3 fulfillment orders/month free</li>
            <li><span class="check">&#10003;</span> 5% orchestration fee on fulfillment</li>
          </ul>
          <a href="/install" class="btn card-cta">Let's build &#8594;</a>
          <p class="upgrade-note">Install with <code>pip install kiln3d</code></p>
        </div>

        <!-- Pro Tier -->
        <div class="card pricing-card">
          <div class="card-header">
            <h3>Pro</h3>
            <p class="tier-tagline">For hobbyists &amp; personal projects.</p>
            <div class="price">
              <span class="amount monthly-price">$49</span>
              <span class="amount annual-price" style="display:none">$39</span>
              <span class="period monthly-period">/ month</span>
              <span class="period annual-period" style="display:none">/ mo, billed annually</span>
            </div>
          </div>
          <ul class="features">
            <li><span class="check">&#10003;</span> Everything in Free</li>
            <li><span class="check">&#10003;</span> 1 printer (single-printer use)</li>
            <li><span class="check">&#10003;</span> Hobbyist &amp; personal projects only</li>
            <li><span class="check">&#10003;</span> Unlimited job queue</li>
            <li><span class="check">&#10003;</span> Unlimited assembly parts</li>
            <li><span class="check">&#10003;</span> Auto-generated assembly manuals &mdash; multi-part prints ship with a printable single-language PDF, "Made with Kiln" cover</li>
            <li><span class="check">&#10003;</span> Git for 3D &mdash; branch, merge, cherry-pick, and Ed25519-sign releases for designs, decorations, and mechanical features</li>
            <li><span class="check">&#10003;</span> Ed25519-signed releases with tamper-evident fingerprint recompute &mdash; FDA 21 CFR 820.70 / AS9100 / ISO 13485 grade</li>
            <li><span class="check">&#10003;</span> Three-way semantic mesh merge &mdash; Z-level / pocket / bounding-box diff at manufacturing tolerance</li>
            <li><span class="check">&#10003;</span> Versioned decoration presets &mdash; brand-asset library with signed releases</li>
            <li><span class="check">&#10003;</span> Versioned mechanical features &mdash; chamfers, fillets, pockets, holes, bosses, ribs, screw-hole patterns, custom OpenSCAD</li>
            <li><span class="check">&#10003;</span> Solo cloud sync to Kiln Cloud &mdash; tenant-isolated RLS + Merkle push receipts</li>
            <li><span class="check">&#10003;</span> Product templates (coasters, keychains, ornaments, and more)</li>
            <li><span class="check">&#10003;</span> Procedural textures (tiger stripe, camo, marble, lava, wood, honeycomb)</li>
            <li><span class="check">&#10003;</span> Unlimited decorations &mdash; photo, text, SVG, brand assets <span class="feature-note">(QR codes are Business)</span></li>
            <li><span class="check">&#10003;</span> Mid-print modification engine &mdash; decorate, add features, swap material mid-job</li>
            <li><span class="check">&#10003;</span> Autonomous failure recovery &amp; print resume</li>
            <li><span class="check">&#10003;</span> Design provenance, regression detection, cross-branch outcome A/B</li>
            <li><span class="check">&#10003;</span> Manual speed control &amp; print learning</li>
            <li><span class="check">&#10003;</span> Per-printer calibration grounding &amp; continuous learning &mdash; Kiln imports your OrcaSlicer / Bambu Studio / PrusaSlicer profiles AND keeps refining per-printer offsets from your actual prints. Freshness tracking knows when your printer drifts; ask &ldquo;why is this dimension what it is?&rdquo; and get a real answer with full provenance.</li>
            <li><span class="check">&#10003;</span> Material-aware printability &mdash; PLA, PETG, ABS and every other Kiln-supported material get per-material checks. Free uses one conservative default; Pro tunes to what&rsquo;s on your spool.</li>
            <li><span class="check">&#10003;</span> Kiln learns your printer&rsquo;s habits &mdash; knows whether yours prints walls thicker or thinner than designed, and tunes the warnings to fit.</li>
            <li><span class="check">&#10003;</span> Every warning has a fix &mdash; Pro shows both the design fix (&ldquo;thicken to 1.5mm&rdquo;) and the slicer fix (&ldquo;or set 4+ perimeters&rdquo;), and can apply the slicer fix for you.</li>
            <li><span class="check">&#10003;</span> Design matches what you asked for &mdash; tell Kiln what you&rsquo;re making, and it checks the result actually does the job. PLA in a cookie cutter? Approved. PLA in a water bottle? Steered to PETG.</li>
            <li><span class="check">&#10003;</span> REST API server</li>
          </ul>
          <button type="button" class="btn card-cta checkout-cta" data-tier="pro">Get Pro &#8594;</button>
          <p class="upgrade-note">Already installed? Run <code>kiln license activate &lt;key&gt;</code></p>
        </div>

        <!-- Business Tier -->
        <div class="card pricing-card featured">
          <div class="badge">Recommended</div>
          <div class="card-header">
            <h3>Business</h3>
            <p class="tier-tagline">For anyone selling what they print &mdash; Etsy, Shopify, custom orders, client work.</p>
            <div class="price">
              <span class="amount monthly-price">$199</span>
              <span class="amount annual-price" style="display:none">$159</span>
              <span class="period monthly-period">/ month</span>
              <span class="period annual-period" style="display:none">/ mo, billed annually</span>
            </div>
          </div>
          <ul class="features">
            <li><span class="check">&#10003;</span> Everything in Pro</li>
            <li><span class="check">&#10003;</span> Sell what you print &mdash; Etsy, Shopify, custom orders, client work</li>
            <li><span class="check">&#10003;</span> 3 printers included <span class="feature-note">($15/mo each above, up to 50)</span></li>
            <li><span class="check">&#10003;</span> 3 team seats included <span class="feature-note">($50/mo each above, up to 10)</span></li>
            <li><span class="check">&#10003;</span> Multi-printer fleet management &amp; cross-printer learning</li>
            <li><span class="check">&#10003;</span> Co-branded assembly manuals &mdash; your name on the cover, "Powered by Kiln" in the footer</li>
            <li><span class="check">&#10003;</span> Multilingual single PDF &mdash; English / German / French / Spanish / Italian sections in one document</li>
            <li><span class="check">&#10003;</span> "What changed" PDFs &mdash; buyers of v1.2 get a 5-page diff manual when you ship v1.3 instead of a 60-page rebuild</li>
            <li><span class="check">&#10003;</span> QR code generation</li>
            <li><span class="check">&#10003;</span> Layer-scheduled speed adjustments (auto-apply per-layer)</li>
            <li><span class="check">&#10003;</span> Team pull requests on design versions &mdash; code-review-style approval workflow with latest-decision-wins</li>
            <li><span class="check">&#10003;</span> Approval gates &mdash; required team reviewers, step-up authentication on production releases</li>
            <li><span class="check">&#10003;</span> Cross-organization artifact transfer &mdash; assign IP between orgs with audit trail</li>
            <li><span class="check">&#10003;</span> Federated design sharing &mdash; cross-operator cloud push/pull with SHA-256 branch anonymization</li>
            <li><span class="check">&#10003;</span> Unlimited fulfillment orders</li>
            <li><span class="check">&#10003;</span> Same 5% orchestration fee</li>
            <li><span class="check">&#10003;</span> Material compliance tracking</li>
            <li><span class="check">&#10003;</span> Priority support</li>
            <li><span class="check">&#10003;</span> Custom safety profiles</li>
            <li><span class="check">&#10003;</span> Webhook integrations</li>
          </ul>
          <button type="button" class="btn card-cta checkout-cta" data-tier="business">Get Business &#8594;</button>
          <p class="upgrade-note">Already installed? Run <code>kiln license activate &lt;key&gt;</code></p>
        </div>

        <!-- Enterprise Tier -->
        <div class="card pricing-card enterprise-card">
          <div class="card-header">
            <h3>Enterprise</h3>
            <p class="tier-tagline">Built for your team. Let's talk.</p>
            <div class="price">
              <span class="amount-text">Contact us</span>
            </div>
          </div>
          <ul class="features">
            <li><span class="check">&#10003;</span> Everything in Business</li>
            <li><span class="check">&#10003;</span> Unlimited team seats &amp; large fleets</li>
            <li><span class="check">&#10003;</span> SSO (SAML / OIDC) + SCIM provisioning</li>
            <li><span class="check">&#10003;</span> Role-based access control</li>
            <li><span class="check">&#10003;</span> Full audit trail with long-term retention</li>
            <li><span class="check">&#10003;</span> Lockable safety profiles</li>
            <li><span class="check">&#10003;</span> Encrypted G-code at rest</li>
            <li><span class="check">&#10003;</span> Full white-label manuals &amp; buyer-side authenticity verification</li>
            <li><span class="check">&#10003;</span> 99.9% uptime SLA</li>
            <li><span class="check">&#10003;</span> Dedicated CSM + sub-24h response SLA</li>
            <li><span class="check">&#10003;</span> On-prem / VPC deployment options</li>
            <li><span class="check">&#10003;</span> Custom integrations &amp; procurement terms</li>
          </ul>
          <a href="https://cal.com/kiln3d/intro-call" target="_blank" rel="noopener" class="btn card-cta">Book an intro call &#8594;</a>
          <p class="upgrade-note">Prefer email? <a href="mailto:adam@kiln3d.com?subject=Kiln%20Enterprise%20enquiry">adam@kiln3d.com</a>. Custom pricing tailored to your team, fleet, and compliance needs.</p>
        </div>
      </div>
      <p class="patent-footer">Kiln's core technology is protected by multiple US patents pending.</p>
    </div>
  </section>

  <section class="faq">
    <div class="container">
      <h2>Frequently Asked Questions</h2>
      <div class="faq-list">
        <details>
          <summary>Is local printing really free?</summary>
          <p>Yes. Kiln is open source (AGPL-3.0). Local printing, slicing, and printer control are free forever with no limits on print volume.</p>
        </details>
        <details>
          <summary>What is a fulfillment order?</summary>
          <p>When you outsource manufacturing through Craftcloud via Kiln. Local printing to your own printers does not count.</p>
        </details>
        <details>
          <summary>Can I self-host everything?</summary>
          <p>Yes. Kiln runs entirely locally. Pro/Business/Enterprise tiers add optional cloud features, but free tier local basic functionality never requires a subscription.</p>
        </details>
        <details>
          <summary>Do I need a paid plan for multiple printers?</summary>
          <p>Free and Pro tiers each support 1 printer. Business includes 3 printers ($15/mo per additional, up to 50). For larger fleets, Enterprise is custom-quoted.</p>
        </details>
        <details>
          <summary>What's the difference between Pro and Business?</summary>
          <p>Pro is for hobbyists and personal projects — single user, single printer, not for prints sold for revenue. Business is for anyone running a real operation: Etsy shops, Shopify stores, custom-order businesses, agencies, schools, manufacturers. Business adds multi-printer fleet management, team seats, QR codes, and the workflow features small shops actually need. (Both tiers are subscription plans for the hosted product — separate from the AGPL-alternative licensing covered below.)</p>
        </details>
        <details>
          <summary>What does annual billing save?</summary>
          <p>Annual plans save roughly 20% compared to monthly. Pro drops from $49/mo to $39/mo ($468/yr). Business drops from $199/mo to $159/mo ($1,908/yr). Enterprise pricing is custom — annual savings are part of the conversation. You can switch between monthly and annual at any time.</p>
        </details>
        <details>
          <summary>What's included in Enterprise?</summary>
          <p>Enterprise is for teams running production print operations — manufacturing, regulated industries, large fleets. It includes a dedicated single-tenant MCP server, SSO, role-based access control, full audit trails, lockable safety profiles, on-prem or VPC deployment options, dedicated CSM, and a 99.9% uptime SLA. Pricing is tailored per deal — contact us for a quote that fits your team and use case.</p>
        </details>
        <details>
          <summary>Can I try Enterprise before committing?</summary>
          <p>Yes. Email <a href="mailto:adam@kiln3d.com?subject=Kiln%20Enterprise%20evaluation">adam@kiln3d.com</a> and we'll set you up with full Enterprise access to evaluate.</p>
        </details>
        <details>
          <summary>Need a non-AGPL license to use Kiln in proprietary code?</summary>
          <p>Different from the subscription tiers above. Kiln is open source under AGPL-3.0, which requires that derivative works and networked services built on Kiln also be open-sourced. If your company needs to use Kiln in proprietary products without AGPL obligations, we offer an <strong>AGPL commercial license</strong> (a dual-licensing alternative — not a subscription tier). Contact <a href="mailto:adam@kiln3d.com?subject=AGPL%20Commercial%20License">adam@kiln3d.com</a> to discuss.</p>
        </details>
      </div>
    </div>
  </section>

  <!-- "Are you selling what you print?" modal — fired before Pro
       checkout to route sellers into Business.  Defense-in-depth:
       the /api/billing/create-checkout-session endpoint also
       rejects Pro signups that declare commercial_use=true.

       Copy avoids the words "commercial" and "license" because
       this page also has a "Need a non-AGPL license to use Kiln
       in proprietary code?" FAQ entry that's a separate
       (legitimate) AGPL-alternative offering — see the file-header
       comment.  Concrete behaviour ("selling what you print")
       side-steps the conflation. -->
  <dialog id="commercial-use-modal" class="commercial-use-modal">
    <form method="dialog" class="commercial-use-content">
      <h3>Are you selling what you print?</h3>
      <p>
        Pro is for personal projects. Business is for prints you
        sell &mdash; Etsy, Shopify, custom orders, client work
        &mdash; and includes the team and fleet features
        you&rsquo;ll want once revenue is on the line.
      </p>
      <div class="commercial-use-buttons">
        <button type="submit" value="yes" class="btn commercial-use-yes">
          Yes &mdash; I sell prints
        </button>
        <button type="submit" value="no" class="btn commercial-use-no">
          No &mdash; personal projects
        </button>
      </div>
      <p class="commercial-use-note">
        About your subscription plan &mdash; not Kiln&rsquo;s
        open-source (AGPL-3.0) license. You can change plans
        anytime in billing settings.
      </p>
    </form>
  </dialog>
</BaseLayout>

<script>
  const toggle = document.getElementById('billing-toggle') as HTMLInputElement | null;
  if (toggle) {
    toggle.addEventListener('change', () => {
      const isAnnual = toggle.checked;
      document.querySelectorAll('.monthly-price, .monthly-period, .monthly-price-period').forEach(el => {
        (el as HTMLElement).style.display = isAnnual ? 'none' : '';
      });
      document.querySelectorAll('.annual-price, .annual-period, .annual-price-period').forEach(el => {
        (el as HTMLElement).style.display = isAnnual ? '' : 'none';
      });
    });
  }

  // Stripe Checkout CTAs — POST to the kiln-pro REST API, redirect to
  // the returned Stripe-hosted checkout URL.  The API root is resolved
  // from PUBLIC_KILN_API_URL at build time; falls back to the production
  // deployment so the static site works locally-built too.
  const API_ROOT =
    (import.meta as any).env?.PUBLIC_KILN_API_URL ||
    'https://api.kiln3d.com';

  async function startCheckout(
    tier: string,
    billing: 'monthly' | 'annual',
    btn: HTMLButtonElement,
    extraBody: Record<string, unknown> = {},
  ) {
    const originalLabel = btn.textContent;
    btn.disabled = true;
    btn.textContent = 'Redirecting to Stripe…';
    try {
      const resp = await fetch(`${API_ROOT}/api/billing/create-checkout-session`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          tier,
          billing,
          cancel_url: `${window.location.origin}/pricing`,
          ...extraBody,
        }),
      });
      const data = await resp.json();
      if (!resp.ok || !data.success || !data.checkout_url) {
        // If the API redirects us to a different tier (Pro→Business
        // when commercial_use=true sneaks through), surface a clear
        // message rather than a generic error.
        if (data.upgrade_to) {
          alert(
            `Pro is for personal projects only.\n\n` +
            `Click "Get Business" instead — that's the right plan ` +
            `when you're selling what you print.`,
          );
          btn.disabled = false;
          btn.textContent = originalLabel;
          return;
        }
        throw new Error(data.error || `Checkout failed (${resp.status})`);
      }
      window.location.href = data.checkout_url;
    } catch (err: any) {
      btn.disabled = false;
      btn.textContent = originalLabel;
      console.error('Checkout error:', err);
      alert(
        `Couldn't start checkout: ${err?.message ?? 'unknown error'}\n\n` +
        `If this keeps happening, email adam@kiln3d.com and we'll set you up manually.`,
      );
    }
  }

  function pickBusinessButton(): HTMLButtonElement | null {
    return document.querySelector<HTMLButtonElement>(
      '.checkout-cta[data-tier="business"]',
    );
  }

  document.querySelectorAll<HTMLButtonElement>('.checkout-cta').forEach(btn => {
    btn.addEventListener('click', async () => {
      const tier = btn.dataset.tier;
      if (!tier) return;
      const billing: 'monthly' | 'annual' = toggle?.checked ? 'annual' : 'monthly';

      // Pro CTA → first ask the commercial-use question.  If the
      // buyer answers "yes", route to the Business CTA instead.  If
      // they answer "no", continue with Pro.  The modal closes
      // returning '' if dismissed without choosing — abort silently.
      if (tier === 'pro') {
        const modal = document.getElementById(
          'commercial-use-modal',
        ) as HTMLDialogElement | null;
        if (modal) {
          modal.showModal();
          const answer = await new Promise<string>(resolve => {
            modal.addEventListener(
              'close',
              () => resolve(modal.returnValue),
              { once: true },
            );
          });
          if (answer === 'yes') {
            const businessBtn = pickBusinessButton();
            if (businessBtn) {
              businessBtn.click();
            } else {
              await startCheckout('business', billing, btn);
            }
            return;
          }
          if (answer !== 'no') {
            // User dismissed without choosing — abort.
            return;
          }
          // answer === 'no' → fall through to Pro checkout, with the
          // commercial_use=false flag passed through to Stripe metadata
          // so the audit trail captures the explicit declaration.
          await startCheckout('pro', billing, btn, {
            commercial_use: false,
          });
          return;
        }
      }

      await startCheckout(tier, billing, btn);
    });
  });
</script>

<style>
  .pricing-hero {
    text-align: center;
    padding: 100px 0 40px;
  }
  .pricing-hero h1 {
    font-size: 40px;
    font-weight: 700;
    margin-bottom: 16px;
  }
  .pricing-hero .lead {
    color: var(--text-muted);
    font-size: 17px;
    max-width: 580px;
    margin: 0 auto;
    line-height: 1.6;
  }

  /* Billing toggle */
  .billing-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin-bottom: 32px;
  }
  .toggle-label {
    font-size: 14px;
    font-weight: 500;
    color: var(--text-muted);
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 6px;
  }
  .save-badge {
    background: var(--accent);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: 10px;
    white-space: nowrap;
  }
  .toggle-switch {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 24px;
  }
  .toggle-switch input {
    opacity: 0;
    width: 0;
    height: 0;
  }
  .toggle-slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--border);
    border-radius: 24px;
    transition: 0.2s;
  }
  .toggle-slider::before {
    content: '';
    position: absolute;
    height: 18px;
    width: 18px;
    left: 3px;
    bottom: 3px;
    background: #fff;
    border-radius: 50%;
    transition: 0.2s;
  }
  .toggle-switch input:checked + .toggle-slider {
    background: var(--accent);
  }
  .toggle-switch input:checked + .toggle-slider::before {
    transform: translateX(20px);
  }

  /* Cards grid */
  .pricing-cards {
    padding: 20px 0 80px;
  }
  .cards-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 20px;
    align-items: stretch;
  }

  /* Card */
  .pricing-card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 32px 28px;
  }
  .pricing-card .card-header {
    margin-bottom: 24px;
  }
  .pricing-card h3 {
    font-size: 20px;
    font-weight: 600;
    margin-bottom: 4px;
    color: var(--text);
  }
  .tier-tagline {
    font-size: 13px;
    color: var(--text-muted);
    margin: 0 0 12px;
    line-height: 1.5;
    min-height: 36px;
  }
  .price {
    display: flex;
    align-items: baseline;
    gap: 4px;
  }
  .price .amount {
    font-size: 40px;
    font-weight: 700;
    color: var(--text);
    line-height: 1;
  }
  .price .amount-text {
    font-size: 26px;
    font-weight: 600;
    color: var(--text);
    line-height: 1;
  }
  .price .period {
    font-size: 14px;
    color: var(--text-muted);
  }
  .price-note {
    font-size: 12px;
    color: var(--text-muted);
    margin-top: 6px;
    margin-bottom: 0;
  }

  /* Features list */
  .features {
    list-style: none;
    margin-bottom: 32px;
    flex: 1;
  }
  .features li {
    padding: 6px 0;
    font-size: 13px;
    color: var(--text-muted);
    display: flex;
    align-items: flex-start;
    gap: 10px;
    line-height: 1.5;
  }
  /* Inline detail next to a feature label — used for usage-pricing
     footnotes like "(50 included; $15/each above)" so the per-printer
     math reads as a parenthetical, not as a competing claim against
     the bullet's headline ("Unlimited printers"). */
  .features .feature-note {
    color: var(--text-muted);
    font-size: 12px;
    opacity: 0.85;
  }
  .features .check {
    color: var(--accent);
    font-weight: 600;
    font-size: 13px;
    flex-shrink: 0;
    margin-top: 1px;
  }

  /* CTA button — bottom-pinned by .features { flex: 1 } absorbing leftover
   * space.  We deliberately do NOT use margin-top: auto here: combined with
   * the same on .upgrade-note it splits leftover space between the two,
   * making short-feature cards (Free) "float" the button mid-card while
   * dense cards (Pro/Business) anchor it correctly.  Letting flex grow do
   * the work keeps all four CTAs y-aligned regardless of bullet count. */
  .card-cta {
    width: 100%;
    text-align: center;
  }

  /* Featured card (Business — recommended for sellers) */
  .pricing-card.featured {
    border-color: var(--accent);
    box-shadow: 0 0 40px var(--accent-glow), 0 0 80px rgba(255, 107, 43, 0.05);
  }
  .badge {
    position: absolute;
    top: -12px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--accent);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
    padding: 4px 16px;
    border-radius: 20px;
    white-space: nowrap;
  }

  /* Enterprise card */
  .enterprise-card {
    border-color: var(--text-muted);
  }
  .enterprise-cta {
    background: var(--text);
    color: var(--bg);
  }
  .enterprise-cta:hover {
    opacity: 0.9;
  }

  /* Upgrade note under CTA.  min-height pins notes to a 2-line block so
   * their varying lengths ("Install with…", "Already installed? Run…",
   * "Custom pricing tailored…") don't shift the CTA y-position between
   * cards.  The code chip can flex-wrap to a second line on narrow
   * columns without crowding the button above. */
  .upgrade-note {
    text-align: center;
    font-size: 12px;
    line-height: 1.5;
    color: var(--text-muted);
    margin: 12px 0 0;
    min-height: 36px;
  }
  .upgrade-note code {
    font-size: 12px;
    background: var(--bg);
    padding: 2px 6px;
    border-radius: 4px;
    border: 1px solid var(--border);
    white-space: nowrap;
  }

  /* Commercial-use modal */
  .commercial-use-modal {
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 0;
    background: var(--bg-card);
    color: var(--text);
    max-width: 460px;
    width: 90%;
  }
  .commercial-use-modal::backdrop {
    background: rgba(0, 0, 0, 0.6);
    backdrop-filter: blur(2px);
  }
  .commercial-use-content {
    padding: 28px 28px 24px;
  }
  .commercial-use-content h3 {
    margin: 0 0 8px;
    font-size: 18px;
    font-weight: 600;
  }
  .commercial-use-content p {
    margin: 0 0 18px;
    font-size: 14px;
    color: var(--text-muted);
    line-height: 1.5;
  }
  .commercial-use-buttons {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 14px;
  }
  .commercial-use-buttons .btn {
    width: 100%;
    text-align: center;
    cursor: pointer;
  }
  .commercial-use-yes {
    background: var(--accent);
    color: #fff;
  }
  .commercial-use-no {
    background: var(--bg);
    color: var(--text);
    border: 1px solid var(--border);
  }
  .commercial-use-note {
    font-size: 12px;
    color: var(--text-muted);
    margin: 0 !important;
    line-height: 1.5;
  }

  /* FAQ */
  .faq {
    padding: 60px 0 100px;
    border-top: 1px solid var(--border);
  }
  .faq h2 {
    text-align: center;
    margin-bottom: 40px;
  }
  .faq-list {
    max-width: 680px;
    margin: 0 auto;
  }
  details {
    border: 1px solid var(--border);
    border-radius: 10px;
    margin-bottom: 12px;
    background: var(--bg-card);
    overflow: hidden;
  }
  summary {
    padding: 18px 24px;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    color: var(--text);
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  summary::-webkit-details-marker { display: none; }
  summary::after {
    content: '+';
    font-size: 20px;
    color: var(--text-muted);
    font-weight: 400;
    flex-shrink: 0;
    margin-left: 16px;
    transition: transform 0.2s;
  }
  details[open] summary::after {
    content: '\2212';
  }
  details p {
    padding: 0 24px 18px;
    font-size: 14px;
    color: var(--text-muted);
    line-height: 1.7;
  }

  /* Responsive */
  @media (max-width: 1100px) {
    .cards-grid {
      grid-template-columns: repeat(2, 1fr);
      max-width: 700px;
      margin: 0 auto;
    }
  }
  @media (max-width: 640px) {
    .cards-grid {
      grid-template-columns: 1fr;
      max-width: 420px;
    }
    .pricing-card.featured {
      order: -1;
    }
    .pricing-hero {
      padding: 70px 0 24px;
    }
    .pricing-hero h1 {
      font-size: 32px;
    }
    .pricing-cards {
      padding: 20px 0 50px;
    }
    .tier-tagline {
      min-height: 0;
    }
  }

  /* Patent-pending footer — one confident, generic line below the
   * plan cards.  No per-surface breakdown: a list of named claim
   * areas is a design-around map for competitors, and the
   * deterrent value of "patent-pending" doesn't require naming
   * which patents.  The pricing page sells; this is the quiet
   * IP signal that confirms substance without exposing the
   * filing surface. */
  .patent-footer {
    text-align: center;
    margin: 32px auto 0;
    font-size: 12px;
    color: rgba(255, 255, 255, 0.45);
    letter-spacing: 0.01em;
    max-width: 720px;
  }
</style>
