# Pricing

<div id="pricing-app"></div>

<script>
(function() {
const app = document.getElementById('pricing-app');
if (!app) return;

let computers = 100;
let runtimeGb = 2;
let activePercent = 30;
let plan = 'startup';

const plans = {
  free: { name: 'Free', sub: 0, maxComputers: 10, maxMemory: 4, cpuCores: 4, support: 'Community', credits: 200 },
  startup: { name: 'Startup', sub: 29, maxComputers: 1000, maxMemory: 16, cpuCores: 4, support: 'Email', credits: 0 },
  scale: { name: 'Scale', sub: 199, maxComputers: 10000, maxMemory: 64, cpuCores: 8, support: 'Priority', credits: 0 },
  enterprise: { name: 'Enterprise', sub: null, maxComputers: null, maxMemory: null, cpuCores: null, support: 'Dedicated + SLA', credits: 0 },
};

const runtimeRate = 0.005;
const diskRate = 0.05;

const e2bCpuHr = 0.0504;
const e2bRamGbHr = 0.0162;
const e2bPlanCost = 150;

const daytonaCpuHr = 0.0504;
const daytonaRamGbHr = 0.0162;

function calc() {
  const p = plans[plan];
  if (!p.sub && p.sub !== 0) return { orb: null, e2b: null, daytona: null };
  const activeHours = 720 * (activePercent / 100);
  const orbRuntime = computers * runtimeGb * activeHours * runtimeRate;
  const orbDisk = computers * 0.2 * (1 - activePercent / 100) * diskRate;
  const orb = p.sub + orbRuntime + orbDisk;
  const e2bUsage = computers * 720 * (e2bCpuHr + e2bRamGbHr * runtimeGb);
  const e2b = e2bPlanCost + e2bUsage;
  const daytonaUsage = computers * 720 * (daytonaCpuHr + daytonaRamGbHr * runtimeGb);
  const daytona = daytonaUsage;
  return {
    orb: Math.round(orb),
    orbSub: p.sub,
    orbUsage: Math.round(orbRuntime + orbDisk),
    e2b: Math.round(e2b),
    daytona: Math.round(daytona),
    savings: Math.round((1 - orb / Math.min(e2b, daytona)) * 100)
  };
}

function render() {
  const c = calc();
  const isEnterprise = plan === 'enterprise';
  const p = plans[plan];

  app.innerHTML = `
<style>
  #pricing-app { margin: -0.6rem 0 0 0; }
  .pricing-hero { text-align: center; margin-bottom: 3rem; }
  .pricing-hero h2 { font-family: 'Baumans', sans-serif; font-size: 1.8rem; font-weight: 400; color: #1a1a1a; border: none; margin-top: 0.5rem; padding: 0; letter-spacing: 0.02em; }
  .pricing-hero p { color: #888; font-size: 1rem; margin-top: 0.5rem; }

  .plan-switcher { display: flex; justify-content: center; gap: 0; margin-bottom: 3rem; background: #ede9e5; border-radius: 10px; padding: 4px; max-width: 520px; margin-left: auto; margin-right: auto; }
  .plan-btn { flex: 1; padding: 0.6rem 0.8rem; font-size: 0.82rem; font-weight: 700; color: #888; background: none; border: none; border-radius: 8px; cursor: pointer; transition: all 0.25s ease; font-family: 'Lato', sans-serif; letter-spacing: 0.02em; }
  .plan-btn:hover { color: #555; }
  .plan-btn.active { background: #fff; color: #1a1a1a; box-shadow: 0 1px 4px rgba(0,0,0,0.08); }

  .plan-detail-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: #e8e4e0; border-radius: 12px; overflow: hidden; margin-bottom: 3rem; }
  .plan-col { background: #fff; padding: 1.5rem; }
  .plan-col.active { background: #1a1a1a; color: #fff; }
  .plan-col h3 { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em; color: #999; margin: 0 0 0.75rem 0; }
  .plan-col.active h3 { color: #888; }
  .plan-col .price { font-family: 'JetBrains Mono', monospace; font-size: 1.6rem; font-weight: 700; margin-bottom: 0.25rem; }
  .plan-col .price-sub { font-size: 0.75rem; color: #999; margin-bottom: 1rem; }
  .plan-col.active .price-sub { color: #666; }
  .plan-col .feat { font-size: 0.8rem; color: #888; padding: 0.3rem 0; border-bottom: 1px solid #f0ece8; }
  .plan-col.active .feat { border-color: #333; color: #aaa; }
  .plan-col .feat:last-child { border: none; }
  .plan-col .feat strong { color: #1a1a1a; }
  .plan-col.active .feat strong { color: #fff; }

  .usage-rates { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-bottom: 3rem; }
  .rate-card { background: #fff; border-radius: 12px; padding: 1.5rem; border: 1px solid #e8e4e0; }
  .rate-card h3 { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em; color: #999; margin: 0 0 0.75rem 0; }
  .rate-amount { font-family: 'JetBrains Mono', monospace; font-size: 1.8rem; font-weight: 700; color: #1a1a1a; }
  .rate-unit { font-size: 0.8rem; color: #999; margin-left: 0.15rem; }
  .rate-note { font-size: 0.8rem; color: #888; margin-top: 0.5rem; }

  .calculator { background: #fff; border-radius: 12px; padding: 2rem; border: 1px solid #e8e4e0; margin-bottom: 3rem; }
  .calculator h3 { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em; color: #999; margin: 0 0 1.5rem 0; }
  .slider-group { margin-bottom: 1.5rem; }
  .slider-label { display: flex; justify-content: space-between; margin-bottom: 0.4rem; }
  .slider-label .name { font-size: 0.85rem; color: #555; }
  .slider-label .val { font-family: 'JetBrains Mono', monospace; font-size: 0.85rem; color: #1a1a1a; font-weight: 700; }
  input[type=range] { -webkit-appearance: none; width: 100%; height: 4px; background: #ede9e5; border-radius: 2px; outline: none; }
  input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 18px; height: 18px; background: #1a1a1a; border-radius: 50%; cursor: pointer; transition: transform 0.15s; }
  input[type=range]::-webkit-slider-thumb:hover { transform: scale(1.2); }
  input[type=range]::-moz-range-thumb { width: 18px; height: 18px; background: #1a1a1a; border-radius: 50%; cursor: pointer; border: none; }

  .compare-table { width: 100%; border-collapse: collapse; margin-top: 2rem; }
  .compare-table th { text-align: left; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; color: #999; padding: 0.6rem 1rem; border-bottom: 2px solid #e8e4e0; }
  .compare-table td { padding: 0.6rem 1rem; font-size: 0.85rem; border-bottom: 1px solid #f0ece8; }
  .compare-table tr:last-child td { border-bottom: none; font-weight: 700; font-size: 1rem; }
  .compare-table .orb-col { background: #fafaf8; }
  .compare-table .total-orb { color: #1a1a1a; font-family: 'JetBrains Mono', monospace; }
  .compare-table .total-comp { color: #999; font-family: 'JetBrains Mono', monospace; text-decoration: line-through; }
  .savings-badge { text-align: center; margin-top: 1.5rem; }
  .savings-badge span { background: #1a1a1a; color: #fff; padding: 0.4rem 1rem; border-radius: 20px; font-size: 0.85rem; font-weight: 700; font-family: 'JetBrains Mono', monospace; }

  .faq { margin-top: 3rem; padding-top: 2rem; border-top: 1px solid #e8e4e0; }
  .faq h3 { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.1em; color: #999; margin-bottom: 1rem; }
  .faq-item { margin-bottom: 1.25rem; }
  .faq-q { font-size: 0.9rem; font-weight: 700; color: #1a1a1a; margin-bottom: 0.25rem; }
  .faq-a { font-size: 0.85rem; color: #888; line-height: 1.6; }

  .enterprise-cta { text-align: center; padding: 2.5rem; background: #1a1a1a; border-radius: 12px; margin-bottom: 3rem; }
  .enterprise-cta h3 { font-family: 'Baumans', sans-serif; font-size: 1.4rem; color: #fff; font-weight: 400; margin-bottom: 0.5rem; }
  .enterprise-cta p { color: #888; font-size: 0.9rem; margin-bottom: 1.5rem; }
  .enterprise-cta a { display: inline-block; padding: 0.7rem 2rem; background: #fff; color: #1a1a1a; text-decoration: none; border-radius: 8px; font-weight: 700; font-size: 0.85rem; transition: opacity 0.2s; }
  .enterprise-cta a:hover { opacity: 0.85; }

  @media (max-width: 700px) {
    .plan-detail-grid { grid-template-columns: 1fr 1fr; }
    .usage-rates { grid-template-columns: 1fr; }
  }
</style>

<div class="pricing-hero">
  <h2>Pay for what runs</h2>
  <p>Sleeping computers cost nothing. You only pay when they're active.</p>
</div>

<div class="plan-switcher">
  <button class="plan-btn ${plan==='free'?'active':''}" onclick="window._setPlan('free')">Free</button>
  <button class="plan-btn ${plan==='startup'?'active':''}" onclick="window._setPlan('startup')">Startup</button>
  <button class="plan-btn ${plan==='scale'?'active':''}" onclick="window._setPlan('scale')">Scale</button>
  <button class="plan-btn ${plan==='enterprise'?'active':''}" onclick="window._setPlan('enterprise')">Enterprise</button>
</div>

${isEnterprise ? `
<div class="enterprise-cta">
  <h3>Enterprise</h3>
  <p>Dedicated bare metal. Volume pricing. Unlimited computers. SLA.</p>
  <a href="mailto:hey@orbcloud.dev">Talk to us</a>
</div>
` : `

<div class="plan-detail-grid">
  ${['free','startup','scale','enterprise'].map(k => {
    const pl = plans[k];
    const isActive = k === plan;
    return '<div class="plan-col ' + (isActive ? 'active' : '') + '">' +
      '<h3>' + pl.name + '</h3>' +
      '<div class="price">' + (pl.sub === null ? 'Custom' : pl.sub === 0 ? 'Free' : '$' + pl.sub) + '</div>' +
      '<div class="price-sub">' + (pl.sub === null ? 'volume pricing' : pl.sub === 0 ? '+ usage' : '/mo + usage') + '</div>' +
      '<div class="feat"><strong>' + (pl.maxComputers || 'Unlimited') + '</strong> computers</div>' +
      '<div class="feat">Up to <strong>' + (pl.maxMemory ? pl.maxMemory + ' GB' : 'custom') + '</strong> shared memory</div>' +
      '<div class="feat"><strong>' + (pl.cpuCores || 'Custom') + '</strong> CPU cores</div>' +
      '<div class="feat">' + pl.support + ' support</div>' +
      (pl.credits ? '<div class="feat"><strong>$' + pl.credits + '</strong> free credits</div>' : '') +
    '</div>';
  }).join('')}
</div>

<div class="usage-rates">
  <div class="rate-card">
    <h3>Runtime</h3>
    <div class="rate-amount">$${runtimeRate}<span class="rate-unit">/ GB-hour</span></div>
    <div class="rate-note">Active only. Sleeping = $0.</div>
  </div>
  <div class="rate-card">
    <h3>Disk</h3>
    <div class="rate-amount">$${diskRate.toFixed(2)}<span class="rate-unit">/ GB-month</span></div>
    <div class="rate-note">Files, packages, checkpoints.</div>
  </div>
</div>

<div class="calculator">
  <h3>Estimate your cost</h3>

  <div class="slider-group">
    <div class="slider-label"><span class="name">Computers</span><span class="val">${computers}</span></div>
    <input type="range" min="1" max="${p.maxComputers || 500}" value="${Math.min(computers, p.maxComputers || 500)}" oninput="window._setComputers(+this.value)">
  </div>

  <div class="slider-group">
    <div class="slider-label"><span class="name">Shared memory per computer</span><span class="val">${runtimeGb} GB</span></div>
    <input type="range" min="1" max="${p.maxMemory || 16}" value="${Math.min(runtimeGb, p.maxMemory || 16)}" oninput="window._setRuntime(+this.value)">
  </div>

  <div class="slider-group">
    <div class="slider-label"><span class="name">Active time</span><span class="val">${activePercent}%</span></div>
    <input type="range" min="5" max="100" value="${activePercent}" oninput="window._setActive(+this.value)">
  </div>

  <table class="compare-table">
    <thead>
      <tr><th></th><th class="orb-col">ORB Cloud</th><th>E2B</th><th>Daytona</th></tr>
    </thead>
    <tbody>
      <tr>
        <td>Subscription</td>
        <td class="orb-col">$${c.orbSub}/mo</td>
        <td>$150/mo</td>
        <td>$0</td>
      </tr>
      <tr>
        <td>Usage</td>
        <td class="orb-col">$${c.orbUsage?.toLocaleString()}</td>
        <td>$${(c.e2b - e2bPlanCost)?.toLocaleString()}</td>
        <td>$${c.daytona?.toLocaleString()}</td>
      </tr>
      <tr>
        <td>Sleeping cost</td>
        <td class="orb-col">$0</td>
        <td>N/A</td>
        <td>N/A</td>
      </tr>
      <tr>
        <td>Monthly total</td>
        <td class="total-orb orb-col">$${c.orb?.toLocaleString()}</td>
        <td class="total-comp">$${c.e2b?.toLocaleString()}</td>
        <td class="total-comp">$${c.daytona?.toLocaleString()}</td>
      </tr>
    </tbody>
  </table>

  ${c.savings > 0 ? '<div class="savings-badge"><span>' + c.savings + '% less</span></div>' : ''}
</div>
`}

<div class="faq">
  <h3>FAQ</h3>
  <div class="faq-item"><div class="faq-q">Do I pay when my computer is sleeping?</div><div class="faq-a">No. Sleeping computers use zero runtime. You only pay for disk storage.</div></div>
  <div class="faq-item"><div class="faq-q">What is shared memory?</div><div class="faq-a">The RAM pool your computer uses. More memory means higher throughput. You choose how much when creating a computer.</div></div>
  <div class="faq-item"><div class="faq-q">What is active time?</div><div class="faq-a">The percentage of time your computer is actively running. Most workloads are active 5-30% of the time.</div></div>
  <div class="faq-item"><div class="faq-q">Can I change plans?</div><div class="faq-a">Yes, at any time. Changes take effect immediately.</div></div>
  <div class="faq-item"><div class="faq-q">How does billing work?</div><div class="faq-a">Runtime is metered per-second while active, billed monthly. Disk is metered for the lifetime of your computer. Subscription is billed monthly.</div></div>
</div>
`;
}

window._setPlan = function(p) { plan = p; render(); };
window._setComputers = function(v) { computers = v; render(); };
window._setRuntime = function(v) { runtimeGb = v; render(); };
window._setActive = function(v) { activePercent = v; render(); };

render();
})();
</script>
