pricing-page-saas
the brief, redacted

Build a complete three-tier pricing page as one self-contained HTML document. Tests layout, typographic hierarchy, and restraint under a familiar brief.

504 chars · 76 words · fingerprint a8a380793653

raw output — byte exact

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Graft — Pricing</title>
<meta name="description" content="Graft pricing: preview environments for every pull request. Free for hobby projects, $20/mo for pros, $60/seat/mo for teams.">
<style>
  :root{
    --bg:#0a0c10;
    --surface:#10131a;
    --surface-2:#131824;
    --border:#1f2531;
    --border-strong:#2c3547;
    --text:#e9edf4;
    --muted:#9aa4b5;
    --faint:#6d7688;
    --accent:#7ee787;
    --accent-ink:#06120a;
    --accent-border:rgba(126,231,135,.4);
    --sans:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
    --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
  }
  *{box-sizing:border-box;margin:0;padding:0}
  html{color-scheme:dark;-webkit-text-size-adjust:100%}
  body{
    font-family:var(--sans);
    background:
      radial-gradient(1000px 520px at 50% -180px, rgba(126,231,135,.09), transparent 70%),
      var(--bg);
    color:var(--text);
    line-height:1.5;
    -webkit-font-smoothing:antialiased;
    text-rendering:optimizeLegibility;
  }
  body::before{
    content:"";position:fixed;inset:0;pointer-events:none;
    background-image:radial-gradient(rgba(255,255,255,.045) 1px, transparent 1.3px);
    background-size:26px 26px;
    -webkit-mask-image:linear-gradient(180deg,#000 0%,transparent 72%);
            mask-image:linear-gradient(180deg,#000 0%,transparent 72%);
  }
  ::selection{background:rgba(126,231,135,.28)}
  :focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:6px}

  .container{width:100%;max-width:1120px;margin:0 auto;padding:0 24px;position:relative}

  /* ---------- Header ---------- */
  .topbar{display:flex;align-items:center;justify-content:space-between;padding:22px 0}
  .brand{display:flex;align-items:center;gap:10px;text-decoration:none;color:var(--text)}
  .brand svg{color:var(--accent);display:block}
  .brand-name{font-family:var(--mono);font-weight:700;font-size:17px;letter-spacing:-.02em}
  .nav{display:flex;align-items:center;gap:26px}
  .nav a{color:var(--muted);text-decoration:none;font-size:14px;transition:color .15s ease}
  .nav a:hover{color:var(--text)}
  .nav a.active{color:var(--text)}
  .nav .signin{border:1px solid var(--border-strong);padding:7px 14px;border-radius:8px;color:var(--text);transition:border-color .15s ease,background .15s ease}
  .nav .signin:hover{border-color:var(--faint);background:rgba(255,255,255,.04)}

  /* ---------- Hero ---------- */
  .hero{text-align:center;padding:64px 0 8px}
  .eyebrow{font-family:var(--mono);font-size:12px;letter-spacing:.16em;color:var(--accent);text-transform:uppercase}
  .hero h1{font-size:clamp(34px,5vw,52px);letter-spacing:-.03em;line-height:1.08;margin:14px 0 16px;font-weight:700}
  .hero .sub{color:var(--muted);font-size:17px;max-width:560px;margin:0 auto}
  .cli{display:inline-flex;align-items:center;gap:9px;margin-top:28px;font-family:var(--mono);font-size:13px;background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:9px 15px}
  .cli .prompt{color:var(--accent)}
  .cli .cmd{color:var(--text)}
  .cursor{width:7px;height:15px;background:var(--accent);opacity:.9;animation:blink 1.1s steps(1) infinite}
  @keyframes blink{50%{opacity:0}}

  /* ---------- Billing toggle ---------- */
  .toggle-row{display:flex;justify-content:center;margin-top:34px}
  .billing-toggle{display:inline-flex;gap:4px;padding:4px;background:var(--surface);border:1px solid var(--border);border-radius:999px}
  .billing-toggle button{
    appearance:none;border:0;background:transparent;color:var(--muted);
    font-family:inherit;font-size:13.5px;padding:8px 18px;border-radius:999px;
    cursor:pointer;display:inline-flex;align-items:center;gap:8px;
    transition:color .15s ease,background .15s ease,box-shadow .15s ease;
  }
  .billing-toggle button:hover{color:var(--text)}
  .billing-toggle button[aria-pressed="true"]{background:var(--surface-2);color:var(--text);box-shadow:inset 0 0 0 1px var(--border-strong)}
  .billing-toggle .save{font-family:var(--mono);font-size:11px;color:var(--accent)}

  /* ---------- Plans ---------- */
  .plans{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;margin-top:48px}
  .plan{
    position:relative;overflow:hidden;
    display:flex;flex-direction:column;
    background:linear-gradient(180deg,rgba(255,255,255,.02),rgba(255,255,255,0)),var(--surface);
    border:1px solid var(--border);
    border-radius:16px;
    padding:26px;
    transition:transform .22s ease,border-color .22s ease,box-shadow .22s ease;
  }
  .plan:hover{transform:translateY(-3px);border-color:var(--border-strong)}
  .plan-tag{font-family:var(--mono);font-size:12px;letter-spacing:.02em;color:var(--accent);min-height:18px;margin-bottom:10px}
  .plan-name{font-size:19px;font-weight:650;letter-spacing:-.01em}
  .plan-pos{color:var(--muted);font-size:13.5px;margin-top:4px;min-height:42px}
  .price{display:flex;align-items:baseline;gap:6px;margin-top:16px;font-family:var(--mono)}
  .amount{font-size:42px;font-weight:600;letter-spacing:-.04em}
  .per{color:var(--muted);font-size:14px}
  .bill-note{font-family:var(--mono);font-size:11.5px;color:var(--faint);margin-top:7px;min-height:17px}

  .features{
    list-style:none;margin:22px 0 24px;padding:20px 0 0;
    border-top:1px dashed var(--border);
    display:grid;gap:10px;
    font-size:14px;color:#c4cbd8;
  }
  .features li{display:flex;gap:10px;align-items:flex-start}
  .features li::before{content:"✓";font-family:var(--mono);font-size:13px;line-height:1.55;color:var(--accent)}
  .features li.carry{color:var(--muted)}
  .features li.carry::before{content:"+";color:var(--faint)}

  .plan-cta{margin-top:auto}
  .btn{
    display:block;width:100%;text-align:center;text-decoration:none;cursor:pointer;
    font-family:inherit;font-weight:600;font-size:14.5px;
    padding:12px 18px;border-radius:10px;border:1px solid transparent;
    transition:background .15s ease,border-color .15s ease,filter .15s ease;
  }
  .btn-primary{background:var(--accent);color:var(--accent-ink)}
  .btn-primary:hover{filter:brightness(1.08)}
  .btn-ghost{border-color:var(--border-strong);color:var(--text);background:rgba(255,255,255,.02)}
  .btn-ghost:hover{border-color:var(--faint);background:rgba(255,255,255,.05)}
  .cta-note{text-align:center;font-size:12px;color:var(--faint);margin-top:10px;min-height:15px}

  /* Featured (Pro) — emphasis through elevation, accent border and glow */
  @media (min-width:981px){
    .plan--featured{transform:translateY(-10px)}
    .plan--featured:hover{transform:translateY(-13px)}
  }
  .plan--featured{
    background:linear-gradient(180deg,rgba(126,231,135,.07),rgba(126,231,135,.015) 55%),var(--surface-2);
    border-color:var(--accent-border);
    box-shadow:0 24px 70px -28px rgba(126,231,135,.28),0 0 0 1px rgba(126,231,135,.05);
  }
  .plan--featured:hover{border-color:rgba(126,231,135,.6)}
  .plan--featured::before{
    content:"";position:absolute;top:0;left:0;right:0;height:2px;
    background:linear-gradient(90deg,transparent,rgba(126,231,135,.9),transparent);
  }

  /* ---------- Assurance row ---------- */
  .assurance{display:flex;flex-wrap:wrap;justify-content:center;gap:8px 28px;margin-top:46px;color:var(--faint);font-size:13px}
  .assurance span::before{content:"✓ ";font-family:var(--mono);color:var(--accent)}

  /* ---------- FAQ ---------- */
  .faq{max-width:680px;margin:90px auto 0}
  .faq .eyebrow{display:block;text-align:center}
  .faq h2{text-align:center;font-size:24px;letter-spacing:-.02em;margin:10px 0 24px}
  details{background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:16px 18px}
  details+details{margin-top:12px}
  summary{cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:16px;font-weight:600;font-size:15px}
  summary::-webkit-details-marker{display:none}
  summary::after{content:"+";font-family:var(--mono);font-size:16px;color:var(--faint);transition:transform .18s ease}
  details[open] summary::after{transform:rotate(45deg);color:var(--accent)}
  details p{color:var(--muted);font-size:14px;margin-top:10px;max-width:56ch}

  /* ---------- Footer ---------- */
  footer{border-top:1px solid var(--border);margin-top:96px}
  .foot{display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap;padding:26px 0;color:var(--faint);font-size:13px}
  .foot-links{display:flex;align-items:center;gap:20px}
  .foot-links a{color:var(--faint);text-decoration:none;transition:color .15s ease}
  .foot-links a:hover{color:var(--text)}
  .status{display:inline-flex;align-items:center;gap:8px;font-family:var(--mono);font-size:12px}
  .dot{width:8px;height:8px;border-radius:50%;background:var(--accent);box-shadow:0 0 8px rgba(126,231,135,.8)}

  /* ---------- Responsive ---------- */
  @media (max-width:980px){
    .plans{grid-template-columns:1fr;max-width:460px;margin-left:auto;margin-right:auto}
    .plan-pos{min-height:0}
    .hero{padding:48px 0 4px}
    .faq{margin-top:70px}
  }
  @media (max-width:720px){
    .nav a:not(.signin){display:none}
  }
  @media (prefers-reduced-motion:reduce){
    *{animation:none!important;transition:none!important}
  }
</style>
</head>
<body>

<div class="container">

  <header class="topbar">
    <a class="brand" href="#">
      <svg width="20" height="20" viewBox="0 0 20 20" fill="none" aria-hidden="true">
        <rect x="1" y="1" width="18" height="18" rx="4.5" stroke="currentColor" stroke-width="1.6"/>
        <path d="M5.5 6.5l3.5 3.5-3.5 3.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/>
        <line x1="10.5" y1="13.5" x2="14.5" y2="13.5" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"/>
      </svg>
      <span class="brand-name">graft</span>
    </a>
    <nav class="nav" aria-label="Primary">
      <a href="#" class="active">Pricing</a>
      <a href="#">Docs</a>
      <a href="#">Changelog</a>
      <a href="#">GitHub</a>
      <a href="#" class="signin">Sign in</a>
    </nav>
  </header>

  <main>
    <section class="hero">
      <span class="eyebrow">Pricing</span>
      <h1>Pricing that scales with your pipeline.</h1>
      <p class="sub">Graft builds a throwaway preview environment for every pull request. Start free, upgrade when your team does.</p>
      <div class="cli" aria-hidden="true">
        <span class="prompt">$</span>
        <span class="cmd">graft preview --open</span>
        <span class="cursor"></span>
      </div>

      <div class="toggle-row">
        <div class="billing-toggle" role="group" aria-label="Billing period">
          <button type="button" data-mode="monthly" aria-pressed="true">Monthly</button>
          <button type="button" data-mode="annual" aria-pressed="false">Annual <span class="save">-20%</span></button>
        </div>
      </div>
    </section>

    <section class="plans" aria-label="Plans">

      <!-- Hobby -->
      <article class="plan">
        <p class="plan-tag" aria-hidden="true"></p>
        <h2 class="plan-name">Hobby</h2>
        <p class="plan-pos">For side projects and late-night experiments.</p>
        <div class="price">
          <span class="amount" data-monthly="$0" data-annual="$0">$0</span>
          <span class="per">/mo</span>
        </div>
        <p class="bill-note" data-monthly="free forever · no card required" data-annual="free forever · no card required">free forever · no card required</p>
        <ul class="features">
          <li>1 project</li>
          <li>100 build minutes / month</li>
          <li>Preview deploys on every PR</li>
          <li>7-day log &amp; artifact retention</li>
          <li>CLI + GitHub app</li>
          <li>Community support</li>
        </ul>
        <div class="plan-cta">
          <a href="#" class="btn btn-ghost">Start for free</a>
          <p class="cta-note"></p>
        </div>
      </article>

      <!-- Pro (featured) -->
      <article class="plan plan--featured">
        <p class="plan-tag">// most popular</p>
        <h2 class="plan-name">Pro</h2>
        <p class="plan-pos">For solo developers shipping production software.</p>
        <div class="price">
          <span class="amount" data-monthly="$20" data-annual="$16">$20</span>
          <span class="per">/mo</span>
        </div>
        <p class="bill-note" data-monthly="billed monthly · cancel anytime" data-annual="billed annually · $192/yr">billed monthly · cancel anytime</p>
        <ul class="features">
          <li>Unlimited projects</li>
          <li>2,000 build minutes / month</li>
          <li>Custom domains &amp; persistent previews</li>
          <li>2× build concurrency</li>
          <li>Secrets &amp; environment management</li>
          <li>30-day retention</li>
          <li>Priority email support</li>
        </ul>
        <div class="plan-cta">
          <a href="#" class="btn btn-primary">Start 14-day trial</a>
          <p class="cta-note">Free for 14 days · cancel anytime</p>
        </div>
      </article>

      <!-- Team -->
      <article class="plan">
        <p class="plan-tag" aria-hidden="true"></p>
        <h2 class="plan-name">Team</h2>
        <p class="plan-pos">For teams that review, stage, and ship together.</p>
        <div class="price">
          <span class="amount" data-monthly="$60" data-annual="$48">$60</span>
          <span class="per">/seat/mo</span>
        </div>
        <p class="bill-note" data-monthly="per seat · billed monthly" data-annual="per seat · billed annually · $576/yr">per seat · billed monthly</p>
        <ul class="features">
          <li class="carry">Everything in Pro, plus</li>
          <li>Pooled build minutes for the whole org</li>
          <li>SSO / SAML &amp; role-based access</li>
          <li>Shared staging environments</li>
          <li>Audit logs</li>
          <li>Slack, Linear &amp; Jira integrations</li>
          <li>99.9% uptime SLA · dedicated support</li>
        </ul>
        <div class="plan-cta">
          <a href="#" class="btn btn-ghost">Start with Team</a>
          <p class="cta-note">Pilot free for 30 days</p>
        </div>
      </article>

    </section>

    <div class="assurance">
      <span>No credit card to start</span>
      <span>Cancel anytime</span>
      <span>SOC 2 Type II</span>
      <span>Prices in USD</span>
    </div>

    <section class="faq">
      <span class="eyebrow">// faq</span>
      <h2>Questions, answered.</h2>

      <details>
        <summary>What counts as a build minute?</summary>
        <p>One minute of one build container running. A typical preview build takes 2–4 minutes, and cache hits don't count against your quota. You can watch usage live from the dashboard or via <code>graft usage</code>.</p>
      </details>
      <details>
        <summary>Can I change plans later?</summary>
        <p>Yes. Upgrades apply instantly and downgrades take effect at the end of your billing period. We prorate everything to the day — no emails to support required.</p>
      </details>
      <details>
        <summary>Do you offer discounts for open source?</summary>
        <p>Public repositories run free on the Pro plan, forever. Student and nonprofit discounts are also available — just ask.</p>
      </details>
    </section>
  </main>

  <footer>
    <div class="foot">
      <span>© 2025 Graft Systems, Inc.</span>
      <div class="foot-links">
        <a href="#">Security</a>
        <a href="#">Terms</a>
        <a href="#">Privacy</a>
        <span class="status"><span class="dot"></span>all systems normal</span>
      </div>
    </div>
  </footer>

</div>

<script>
(function () {
  var toggle = document.querySelector('.billing-toggle');
  if (!toggle) return;

  var buttons = toggle.querySelectorAll('button[data-mode]');
  var dynamic = document.querySelectorAll('[data-monthly]');

  function setMode(mode) {
    for (var i = 0; i < buttons.length; i++) {
      buttons[i].setAttribute('aria-pressed', String(buttons[i].getAttribute('data-mode') === mode));
    }
    for (var j = 0; j < dynamic.length; j++) {
      var value = dynamic[j].getAttribute('data-' + mode);
      if (value !== null) dynamic[j].textContent = value;
    }
  }

  for (var i = 0; i < buttons.length; i++) {
    buttons[i].addEventListener('click', function () {
      setMode(this.getAttribute('data-mode'));
    });
  }
})();
</script>

</body>
</html>

request envelope — prompt redacted

{
  "model": "moonshotai/kimi-k3",
  "system": "Respond with a single complete, self-contained HTML document and nothing else. No markdown fences, no explanation. Inline all CSS and JavaScript. Do not reference any external resource — no CDN scripts, no external stylesheets, no remote fonts or images. The document must render correctly offline.",
  "messages": [
    {
      "role": "user",
      "content": "«REDACTED — 81 words, 504 chars»"
    }
  ],
  "maxOutputTokens": 32000,
  "gatewayStringId": "1bfbb92f-8faa-4d8c-820a-3bc9a9aa46b6"
}