← back to Lawyer Directory Builder
Iter 24: /upgrade EZ Upgrade page — editorial pass + critique-applied compliance fixes
b93b18ba0bd14dc287ef126bc83992242e37ba66 · 2026-05-04 00:20:38 -0700 · SteveStudio2
Visual upgrade:
- CB monogram added to brand header (was bare text)
- Volume strip masthead 'Edition 2026 · EZ Upgrade · One-time $499'
- Italic-metal display 'Reserve your EZ Upgrade.'
- Hairline-underline configurator inputs (no boxes, focus to champagne)
- Sticky order-summary aside with hairline rules + italic-metal '$499'
- Big italic-metal '$499' total + 'INCLUDED' caps for free items
- Scroll-reveal stagger
- Submit-disable JS prevents double-charge during Stripe redirect
Debate-team-fast critique applied (live-Stripe page = high-risk):
1. FALSE-TRUST FIX (highest priority) — replaced literally-inaccurate
"Counsel & Bar never sees your card" with accurate Stripe disclosure:
"Your full card number stays with Stripe; Counsel & Bar receives only
the last four digits and billing details needed for your receipt and
refund processing." Stripe ToS + deceptive-practices issue closed.
2. RULE 5.4 / §6155 BUNDLE FIX — removed "Counsel & Bar listing — premium
tier · INCLUDED" line from $499 order summary (was implying directory
placement is something you pay $499 for). Replaced with explicit
disclaimer: "This is a site-build service, NOT a directory placement
fee. The Counsel & Bar listing remains free for any California-licensed
attorney whether or not they purchase this upgrade."
3. FTC FALSE-ADVERTISING SOFTENED — "Live in seven days" (unconditional)
→ "Typical go-live: seven business days from content intake." Same
for revisions/hosting wording.
4. LRS-FLAVOR REMOVED — "the standard the directory deserves" implied the
directory judges attorneys → "the standard your firm deserves."
5. CTA TONE CORRECTED — brushed-metal gradient (luxury-watch-ad) replaced
with flat-noir + champagne hairline + champagne text + letter-spacing
ease on hover. More restrained, more DB12, less marketing-landing.
6. BUILD AGREEMENT inline disclosure under CTA (no dead /terms link):
"By continuing you agree to the Build Agreement: seven-business-day
typical go-live from content intake, 14-day revision window from
first proof, first-year hosting included, full refund any time
before first proof. Site-build deliverable only."
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Files touched
Diff
commit b93b18ba0bd14dc287ef126bc83992242e37ba66
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Mon May 4 00:20:38 2026 -0700
Iter 24: /upgrade EZ Upgrade page — editorial pass + critique-applied compliance fixes
Visual upgrade:
- CB monogram added to brand header (was bare text)
- Volume strip masthead 'Edition 2026 · EZ Upgrade · One-time $499'
- Italic-metal display 'Reserve your EZ Upgrade.'
- Hairline-underline configurator inputs (no boxes, focus to champagne)
- Sticky order-summary aside with hairline rules + italic-metal '$499'
- Big italic-metal '$499' total + 'INCLUDED' caps for free items
- Scroll-reveal stagger
- Submit-disable JS prevents double-charge during Stripe redirect
Debate-team-fast critique applied (live-Stripe page = high-risk):
1. FALSE-TRUST FIX (highest priority) — replaced literally-inaccurate
"Counsel & Bar never sees your card" with accurate Stripe disclosure:
"Your full card number stays with Stripe; Counsel & Bar receives only
the last four digits and billing details needed for your receipt and
refund processing." Stripe ToS + deceptive-practices issue closed.
2. RULE 5.4 / §6155 BUNDLE FIX — removed "Counsel & Bar listing — premium
tier · INCLUDED" line from $499 order summary (was implying directory
placement is something you pay $499 for). Replaced with explicit
disclaimer: "This is a site-build service, NOT a directory placement
fee. The Counsel & Bar listing remains free for any California-licensed
attorney whether or not they purchase this upgrade."
3. FTC FALSE-ADVERTISING SOFTENED — "Live in seven days" (unconditional)
→ "Typical go-live: seven business days from content intake." Same
for revisions/hosting wording.
4. LRS-FLAVOR REMOVED — "the standard the directory deserves" implied the
directory judges attorneys → "the standard your firm deserves."
5. CTA TONE CORRECTED — brushed-metal gradient (luxury-watch-ad) replaced
with flat-noir + champagne hairline + champagne text + letter-spacing
ease on hover. More restrained, more DB12, less marketing-landing.
6. BUILD AGREEMENT inline disclosure under CTA (no dead /terms link):
"By continuing you agree to the Build Agreement: seven-business-day
typical go-live from content intake, 14-day revision window from
first proof, first-year hosting included, full refund any time
before first proof. Site-build deliverable only."
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---
src/server/upgrade.ts | 176 ++++++++++++++++++++++++++++++++++----------------
1 file changed, 119 insertions(+), 57 deletions(-)
diff --git a/src/server/upgrade.ts b/src/server/upgrade.ts
index 25af898..921c456 100644
--- a/src/server/upgrade.ts
+++ b/src/server/upgrade.ts
@@ -30,6 +30,7 @@ function esc(s: any): string {
}
function shellHead(title: string): string {
+ const monogram = `<svg viewBox="0 0 28 28" width="28" height="28" aria-hidden="true" style="flex:0 0 28px"><defs><linearGradient id="cb-up" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stop-color="#d4b683"/><stop offset="50%" stop-color="#b89968"/><stop offset="100%" stop-color="#8a7044"/></linearGradient></defs><circle cx="14" cy="14" r="13" fill="none" stroke="url(#cb-up)" stroke-width="1"/><path fill="url(#cb-up)" d="M9.6 9.5c-1.6 0-2.7 1.2-2.7 3v3c0 1.8 1.1 3 2.7 3 1.4 0 2.4-.8 2.6-2.1h-1.3c-.1.6-.6 1-1.3 1-.9 0-1.4-.6-1.4-1.7v-2.4c0-1.1.5-1.7 1.4-1.7.7 0 1.2.4 1.3 1h1.3c-.2-1.3-1.2-2.1-2.6-2.1zm5.5.1v8.7h2.7c1.6 0 2.6-.9 2.6-2.4 0-1-.5-1.7-1.3-2 .7-.3 1.1-1 1.1-1.8 0-1.5-1-2.5-2.5-2.5h-2.6zm1.3 1.1h1.2c.8 0 1.4.5 1.4 1.4 0 .9-.5 1.4-1.4 1.4h-1.2v-2.8zm0 3.9h1.4c.9 0 1.4.6 1.4 1.5s-.5 1.5-1.4 1.5h-1.4V14.6z"/></svg>`;
return `<!doctype html>
<html lang="en"><head>
<meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
@@ -39,21 +40,26 @@ function shellHead(title: string): string {
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,500;1,300;1,400&family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet">
<style>
:root{--noir:#0a0a0c;--noir-rise:#131316;--noir-deep:#050507;--rule:#2a2724;--rule-faint:#1a1815;--ink:#f4f1ea;--ink-soft:#d8d2c5;--ink-mute:#8b857a;--metal:#b89968;--metal-glow:#d4b683;--metal-deep:#8a7044;--good:#34d399;--warn:#d4a04a;--bad:#d87a7a;--serif:"Cormorant Garamond","Cormorant","Georgia",serif;--sans:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",system-ui,sans-serif}
-*{box-sizing:border-box}html{-webkit-font-smoothing:antialiased}
+*{box-sizing:border-box}html{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
body{margin:0;background:var(--noir);color:var(--ink);font-family:var(--sans);font-weight:300;font-size:15px;line-height:1.55}
::selection{background:var(--metal);color:var(--noir)}
-a{color:var(--metal);text-decoration:none}a:hover{color:var(--metal-glow)}
+a{color:var(--metal);text-decoration:none;transition:color 180ms ease}a:hover{color:var(--metal-glow)}
header.brand{padding:22px 48px;display:flex;align-items:center;gap:18px;justify-content:space-between;border-bottom:1px solid var(--rule);background:var(--noir-deep)}
header.brand h1{margin:0;font-family:var(--serif);font-size:22px;font-weight:400}
header.brand h1 a{color:var(--ink)}
header.brand h1 .amp{color:var(--metal);font-style:italic;padding:0 4px}
+.brand-mono{display:inline-flex;align-items:center;gap:14px;text-decoration:none}
.topnav{font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-mute);display:flex;gap:24px}
.topnav a{color:var(--ink-mute)}.topnav a:hover{color:var(--ink)}
-main{max-width:980px;margin:0 auto;padding:64px 48px}
+main{max-width:1100px;margin:0 auto;padding:64px 48px}
+.up-vol{display:flex;align-items:center;gap:18px;margin:0 0 26px;color:var(--metal)}
+.up-vol .v-rule{flex:0 0 56px;height:1px;background:linear-gradient(90deg,transparent,var(--metal) 50%,transparent)}
+.up-vol .v-text{font-family:var(--serif);font-style:italic;font-weight:400;font-size:14px;letter-spacing:.02em}
+.up-vol .v-meta{font-size:10px;letter-spacing:.28em;text-transform:uppercase;color:var(--ink-mute);font-weight:500}
.eyebrow{font-size:10px;letter-spacing:.3em;text-transform:uppercase;color:var(--metal);font-weight:500;margin:0 0 18px}
-h1.display{font-family:var(--serif);font-weight:300;font-size:clamp(40px,6vw,68px);line-height:1.05;letter-spacing:-.02em;margin:0 0 16px;color:var(--ink)}
+h1.display{font-family:var(--serif);font-weight:300;font-size:clamp(40px,6vw,72px);line-height:1.04;letter-spacing:-.02em;margin:0 0 18px;color:var(--ink);max-width:18ch}
h1.display em{font-style:italic;color:var(--metal);font-weight:400}
-.lede{font-size:17px;color:var(--ink-soft);max-width:60ch;margin:0 0 40px;font-weight:300}
+.lede{font-size:17px;color:var(--ink-soft);max-width:62ch;margin:0 0 56px;font-weight:300;line-height:1.6}
.flash{padding:14px 18px;margin-bottom:24px;border:1px solid var(--rule);font-size:13px;letter-spacing:.06em}
.flash.error{background:#2a0e0e;color:var(--bad);border-color:#4a1a1a}
.flash.success{background:#0e2a1a;color:var(--good);border-color:#1a4a30}
@@ -68,9 +74,40 @@ th{color:var(--ink-mute);font-weight:500;font-size:10px;text-transform:uppercase
.pill.delivered{background:#0e2a26;color:#7fd1c4;border-color:#1a4a44}
.pill.refunded{background:#2a1410;color:var(--warn);border-color:#4a2520}
.pill.cancelled{background:var(--noir-rise);color:var(--ink-mute);border-color:var(--rule)}
+.up-grid{display:grid;grid-template-columns:1.4fr 1fr;gap:64px;align-items:start}
+@media (max-width:780px){.up-grid{grid-template-columns:1fr;gap:32px}}
+.up-form{display:flex;flex-direction:column;gap:24px}
+.up-fld{display:flex;flex-direction:column;gap:8px}
+.up-fld-lbl{font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-mute);font-weight:500}
+.up-fld-in{padding:14px 0;background:transparent;color:var(--ink);border:none;border-bottom:1px solid var(--rule);font-family:var(--sans);font-size:16px;font-weight:300;letter-spacing:.005em;transition:border-color 200ms ease}
+.up-fld-in:focus{outline:none;border-bottom-color:var(--metal)}
+.up-fld-in::placeholder{color:var(--ink-mute);opacity:.5}
+.up-cta{padding:22px 40px;background:transparent;color:var(--metal-glow);border:1px solid var(--metal);font-size:11px;letter-spacing:.22em;text-transform:uppercase;font-weight:500;cursor:pointer;align-self:flex-start;margin-top:18px;transition:background 280ms ease,color 280ms ease,letter-spacing 280ms ease,border-color 280ms ease}
+.up-cta:hover{background:var(--metal);color:var(--noir);letter-spacing:.26em;border-color:var(--metal-glow)}
+.up-cta:disabled{opacity:.45;cursor:not-allowed;letter-spacing:.22em;background:transparent;color:var(--ink-mute);border-color:var(--rule)}
+.up-aside{background:linear-gradient(180deg,rgba(184,153,104,.025),transparent);border:1px solid var(--rule);padding:32px 36px;position:sticky;top:32px}
+.up-aside-eyebrow{font-size:9px;letter-spacing:.32em;text-transform:uppercase;color:var(--metal);font-weight:500;margin:0 0 22px}
+.up-line{display:flex;justify-content:space-between;padding:14px 0;border-bottom:1px solid var(--rule-faint);font-size:14px;align-items:baseline}
+.up-line:last-of-type{border-bottom:none}
+.up-line .lbl{color:var(--ink-soft);font-weight:300}
+.up-line .val{font-family:var(--serif);font-style:italic;color:var(--metal);font-size:15px;letter-spacing:.02em}
+.up-line.included .val{color:var(--ink-mute);font-style:normal;font-family:var(--sans);font-size:11px;letter-spacing:.18em;text-transform:uppercase;font-weight:500}
+.up-total{display:flex;justify-content:space-between;padding:24px 0 4px;border-top:1px solid var(--rule);margin-top:14px;align-items:baseline}
+.up-total .lbl{font-size:11px;color:var(--ink-mute);letter-spacing:.22em;text-transform:uppercase;font-weight:500}
+.up-total .val{font-family:var(--serif);font-weight:300;font-size:42px;color:var(--metal-glow);line-height:1;letter-spacing:-.01em}
+.up-total .val sub{font-size:11px;color:var(--ink-mute);font-family:var(--sans);font-weight:500;margin-left:6px;letter-spacing:.18em;text-transform:uppercase;vertical-align:baseline}
+.up-mini{font-size:11px;color:var(--ink-mute);letter-spacing:.06em;margin:24px 0 0;line-height:1.6}
+.up-mini strong{color:var(--ink-soft);font-weight:500}
+@media (prefers-reduced-motion: no-preference){
+ .scroll-reveal{opacity:0;transform:translateY(22px);transition:opacity 900ms cubic-bezier(.16,.84,.3,1),transform 900ms cubic-bezier(.16,.84,.3,1)}
+ .scroll-reveal.in-view{opacity:1;transform:none}
+ .scroll-reveal.s1{transition-delay:80ms}.scroll-reveal.s2{transition-delay:160ms}
+}
+*:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(184,153,104,.45);border-radius:1px}
+*:focus:not(:focus-visible){outline:none}
</style></head><body>
<header class="brand">
- <h1><a href="/">Counsel <span class="amp">&</span> Bar</a></h1>
+ <a class="brand-mono" href="/">${monogram}<h1 style="margin:0"><span style="color:var(--ink)">Counsel</span> <span class="amp">&</span> <span style="color:var(--ink)">Bar</span></h1></a>
<nav class="topnav">
<a href="/find-a-lawyer">Find counsel</a>
<a href="/directory">Directory</a>
@@ -80,7 +117,24 @@ th{color:var(--ink-mute);font-weight:500;font-size:10px;text-transform:uppercase
<main>`;
}
-const FOOT = `</main></body></html>`;
+const FOOT = `</main>
+<script>
+(function(){
+ if(!('IntersectionObserver' in window))return;
+ if(window.matchMedia('(prefers-reduced-motion: reduce)').matches){
+ document.querySelectorAll('.scroll-reveal').forEach(function(el){el.classList.add('in-view');});return;
+ }
+ var io=new IntersectionObserver(function(es){es.forEach(function(e){if(e.isIntersecting){e.target.classList.add('in-view');io.unobserve(e.target);}});},{threshold:0.12,rootMargin:'0px 0px -10% 0px'});
+ document.querySelectorAll('.scroll-reveal').forEach(function(el){io.observe(el);});
+ // Disable submit on Pay click to prevent double-charge during Stripe redirect
+ var f = document.querySelector('form.up-form');
+ if (f) f.addEventListener('submit', function(){
+ var btn = f.querySelector('.up-cta');
+ if (btn) { btn.disabled = true; btn.textContent = 'Redirecting to Stripe…'; }
+ });
+})();
+</script>
+</body></html>`;
// ─── GET /upgrade ──────────────────────────────────────────────────────────
@@ -88,58 +142,66 @@ router.get('/upgrade', (req, res) => {
let p: any = {};
try { if (req.query.prefill) p = JSON.parse(String(req.query.prefill)); } catch {}
const err = req.query.err ? `<div class="flash error">${esc(req.query.err)}</div>` : '';
- res.send(shellHead('EZ Upgrade — Confirm') + `
- <p class="eyebrow">Step 04 · Confirm & pay</p>
+ res.send(shellHead('EZ Upgrade — Reserve') + `
+ <div class="up-vol">
+ <span class="v-rule"></span>
+ <span class="v-text">Volume I</span>
+ <span class="v-meta">Edition 2026 · EZ Upgrade · One-time $499</span>
+ </div>
<h1 class="display">Reserve your <em>EZ Upgrade.</em></h1>
- <p class="lede">One-time $499. Live in seven days. Same domain, dramatically better presentation. Stripe handles the payment; you'll get a confirmation email and a project tracker.</p>
+ <p class="lede">One-time <strong>$499</strong>. Typical go-live: seven business days from content intake. Your existing domain, presented at the standard your firm deserves. Stripe handles the payment; you'll receive a confirmation receipt and a project tracker by email.</p>
${err}
- <div style="display:grid;grid-template-columns:1.4fr 1fr;gap:48px;align-items:start">
- <form method="post" action="/upgrade" style="display:flex;flex-direction:column;gap:18px;">
- <div>
- <label style="font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-mute);font-weight:500;display:block;margin-bottom:8px">Your name</label>
- <input name="full_name" required value="${esc(p.full_name || '')}" autocomplete="name" style="width:100%;padding:14px 16px;background:var(--noir-rise);color:var(--ink);border:1px solid var(--rule);font-family:var(--sans);font-size:15px">
- </div>
- <div>
- <label style="font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-mute);font-weight:500;display:block;margin-bottom:8px">Email</label>
- <input name="email" type="email" required value="${esc(p.email || '')}" autocomplete="email" style="width:100%;padding:14px 16px;background:var(--noir-rise);color:var(--ink);border:1px solid var(--rule);font-family:var(--sans);font-size:15px">
- </div>
- <div>
- <label style="font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-mute);font-weight:500;display:block;margin-bottom:8px">Firm name</label>
- <input name="firm_name" value="${esc(p.firm_name || '')}" autocomplete="organization" style="width:100%;padding:14px 16px;background:var(--noir-rise);color:var(--ink);border:1px solid var(--rule);font-family:var(--sans);font-size:15px">
- </div>
- <div>
- <label style="font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-mute);font-weight:500;display:block;margin-bottom:8px">Current website (we'll improve this)</label>
- <input name="website" type="url" value="${esc(p.website || '')}" autocomplete="url" style="width:100%;padding:14px 16px;background:var(--noir-rise);color:var(--ink);border:1px solid var(--rule);font-family:var(--sans);font-size:15px">
- </div>
- <div>
- <label style="font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--ink-mute);font-weight:500;display:block;margin-bottom:8px">Phone</label>
- <input name="phone" type="tel" value="${esc(p.phone || '')}" autocomplete="tel" style="width:100%;padding:14px 16px;background:var(--noir-rise);color:var(--ink);border:1px solid var(--rule);font-family:var(--sans);font-size:15px">
- </div>
- <input type="hidden" name="bar_number" value="${esc(p.bar_number || '')}">
- <button type="submit" style="padding:18px 32px;background:var(--metal);color:var(--noir);border:1px solid var(--metal);font-size:12px;letter-spacing:.18em;text-transform:uppercase;font-weight:500;cursor:pointer;align-self:flex-start;margin-top:12px">
- Continue to payment →
- </button>
- <p class="muted" style="margin-top:14px">Stripe-secured. We never see your card.</p>
- </form>
- <aside style="background:var(--noir-rise);border:1px solid var(--rule);padding:32px">
- <p class="eyebrow" style="margin:0 0 18px">Order summary</p>
- <div style="display:flex;justify-content:space-between;padding:10px 0;border-bottom:1px solid var(--rule-faint);font-size:14px">
- <span>EZ Upgrade — Personalized site</span><span>$499</span>
- </div>
- <div style="display:flex;justify-content:space-between;padding:10px 0;border-bottom:1px solid var(--rule-faint);font-size:14px;color:var(--ink-mute)">
- <span>Setup & review</span><span>included</span>
- </div>
- <div style="display:flex;justify-content:space-between;padding:10px 0;border-bottom:1px solid var(--rule-faint);font-size:14px;color:var(--ink-mute)">
- <span>14-day revisions</span><span>included</span>
- </div>
- <div style="display:flex;justify-content:space-between;padding:10px 0;border-bottom:1px solid var(--rule-faint);font-size:14px;color:var(--ink-mute)">
- <span>Hosting (1st year)</span><span>included</span>
- </div>
- <div style="display:flex;justify-content:space-between;padding:18px 0 0;font-family:var(--serif);font-weight:300;font-size:32px;color:var(--metal);align-items:baseline">
- <span style="font-size:14px;color:var(--ink-mute);font-family:var(--sans);letter-spacing:.18em;text-transform:uppercase">Total</span>
- <span>$499<span style="font-size:13px;color:var(--ink-mute);font-family:var(--sans);margin-left:6px">USD · one-time</span></span>
- </div>
- </aside>
+ <div class="up-grid">
+ <form method="post" action="/upgrade" class="up-form scroll-reveal">
+ <div class="up-fld">
+ <label class="up-fld-lbl">Your name</label>
+ <input class="up-fld-in" name="full_name" required value="${esc(p.full_name || '')}" autocomplete="name" placeholder="Jane Doe, Esq.">
+ </div>
+ <div class="up-fld">
+ <label class="up-fld-lbl">Email</label>
+ <input class="up-fld-in" name="email" type="email" required value="${esc(p.email || '')}" autocomplete="email" placeholder="you@firm.com">
+ </div>
+ <div class="up-fld">
+ <label class="up-fld-lbl">Firm name</label>
+ <input class="up-fld-in" name="firm_name" value="${esc(p.firm_name || '')}" autocomplete="organization" placeholder="Optional — pulled from State Bar if linked">
+ </div>
+ <div class="up-fld">
+ <label class="up-fld-lbl">Current website <span style="color:var(--ink-mute);font-size:9px;letter-spacing:.12em;text-transform:none;font-style:italic;font-family:var(--serif)">— we'll work from this</span></label>
+ <input class="up-fld-in" name="website" type="url" value="${esc(p.website || '')}" autocomplete="url" placeholder="https://your-current-site.com">
+ </div>
+ <div class="up-fld">
+ <label class="up-fld-lbl">Phone</label>
+ <input class="up-fld-in" name="phone" type="tel" value="${esc(p.phone || '')}" autocomplete="tel" placeholder="(415) 555-0100">
+ </div>
+ <input type="hidden" name="bar_number" value="${esc(p.bar_number || '')}">
+ <button type="submit" class="up-cta">Continue to payment <span style="font-style:italic;font-family:var(--serif);margin-left:6px">→</span></button>
+ <p class="up-mini" style="margin-top:18px"><strong>Payment processed by Stripe.</strong> Your full card number stays with Stripe; Counsel & Bar receives only the last four digits and billing details needed for your receipt and refund processing. Full refund available any time before first proof is delivered.</p>
+ <p class="up-mini" style="margin-top:14px;padding-top:14px;border-top:1px solid var(--rule-faint)">By continuing you agree to the <strong>Build Agreement</strong>: seven-business-day typical go-live from content intake, 14-day revision window from first proof, first-year hosting included, full refund any time before first proof. Site-build deliverable only — directory listing remains free.</p>
+ </form>
+ <aside class="up-aside scroll-reveal s1">
+ <p class="up-aside-eyebrow">— Order summary —</p>
+ <div class="up-line">
+ <span class="lbl">EZ Upgrade — personalized site</span>
+ <span class="val">$499</span>
+ </div>
+ <div class="up-line included">
+ <span class="lbl">Setup & brand review</span>
+ <span class="val">included</span>
+ </div>
+ <div class="up-line included">
+ <span class="lbl">14-day revisions window</span>
+ <span class="val">included</span>
+ </div>
+ <div class="up-line included">
+ <span class="lbl">First-year hosting</span>
+ <span class="val">included</span>
+ </div>
+ <div class="up-total">
+ <span class="lbl">Total</span>
+ <span class="val">$499<sub>USD · one-time</sub></span>
+ </div>
+ <p class="up-mini" style="border-top:1px solid var(--rule-faint);padding-top:18px;margin-top:24px">No subscription, no recurring charges, no upsells. <strong>This is a site-build service, not a directory placement fee.</strong> The Counsel & Bar listing remains free for any California-licensed attorney whether or not they purchase this upgrade.</p>
+ </aside>
</div>
` + FOOT);
});
← 1982ca0 Iter 23: /signup/welcome editorial confirmation + critique-a
·
back to Lawyer Directory Builder
·
Iter 25: /upgrade/thanks — post-Stripe-success editorial con bf9516d →