Files
justvitamin/static/offer/index.html
Omair Saleh 3cd296f6bf feat: dynamic data insights + remaining audit fixes
DATA FIXES:
- Dashboard insights now fully dynamic per date range
  - Revenue/orders/newcust/AOV trend (splits data in half, compares)
  - Channel concentration % computed from filtered data
  - Repeat revenue % with date-range label
  - All insights adapt when user changes date filter/preset
- Offer page charts now load from API (not hardcoded arrays)
  - Revenue chart, new customer chart, channel donut = live data
  - Hero stats (-84%, -42%, 85%) computed dynamically from API
  - ROI calculator AOV pulled from latest year's actual data

REMAINING AUDIT FIXES:
- Fix #4: 'Built by' section on offer page (name, bio, contact)
- Fix #9: Before/After comparison block on homepage
  - Side-by-side: current JV PDP flaws vs AI engine output
  - 8 specific ✗/✓ comparison points
- Fix #6: Before/after serves as instant proof (no 90s wait)

All 10 audit fixes now implemented.
2026-03-02 22:16:29 +08:00

794 lines
49 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Proposal — Internal AI Infrastructure | Just Vitamins</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600&display=swap');
:root{--bg:#050810;--bg2:#0a0f1e;--card:#0d1322;--card2:#111a2e;--card3:#162038;--border:#1a2545;--border2:#253560;--text:#e8ecf4;--text2:#b8c4dc;--muted:#5a6d94;--accent:#6366f1;--accent2:#818cf8;--accent3:#a5b4fc;--green:#10b981;--green2:#34d399;--cyan:#06b6d4;--cyan2:#22d3ee;--purple:#a855f7;--pink:#ec4899;--yellow:#f59e0b;--orange:#f97316;--red:#ef4444;--red2:#f87171}
*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
body{font-family:'Inter',system-ui,sans-serif;background:var(--bg);color:var(--text);line-height:1.7;font-size:15px;overflow-x:hidden}
/* Progress bar */
.progress{position:fixed;top:0;left:0;height:2px;background:linear-gradient(90deg,var(--accent),var(--cyan),var(--green));z-index:1000;transition:width .15s;width:0}
/* Floating nav */
.nav{position:fixed;top:16px;right:24px;z-index:999;display:flex;gap:4px;padding:4px;background:rgba(10,15,30,.85);backdrop-filter:blur(12px);border:1px solid var(--border);border-radius:10px;opacity:0;transform:translateY(-10px);transition:.4s;font-size:12px}
.nav.show{opacity:1;transform:translateY(0)}
.nav a{padding:6px 14px;color:var(--muted);text-decoration:none;border-radius:7px;transition:.2s;font-weight:500}
.nav a:hover,.nav a.active{color:var(--text);background:var(--card2)}
/* Orbs */
.orb{position:fixed;border-radius:50%;filter:blur(120px);pointer-events:none;z-index:0;opacity:.3}
.orb-1{width:600px;height:600px;background:radial-gradient(circle,rgba(99,102,241,.18),transparent 70%);top:-200px;right:-200px;animation:of 22s ease-in-out infinite}
.orb-2{width:500px;height:500px;background:radial-gradient(circle,rgba(16,185,129,.12),transparent 70%);bottom:-150px;left:-150px;animation:of 28s ease-in-out infinite reverse}
@keyframes of{0%,100%{transform:translate(0,0)}33%{transform:translate(30px,-40px)}66%{transform:translate(-20px,30px)}}
.wrap{position:relative;z-index:1;max-width:880px;margin:0 auto;padding:0 28px}
/* Sections */
section{padding:90px 0;opacity:0;transform:translateY(28px);transition:opacity .7s cubic-bezier(.16,1,.3,1),transform .7s cubic-bezier(.16,1,.3,1)}
section.vis{opacity:1;transform:none}
.divider{height:1px;background:linear-gradient(90deg,transparent,var(--border2),transparent)}
/* Hero */
.hero{min-height:100vh;display:flex;flex-direction:column;justify-content:center;padding:100px 0 80px}
.hero-badge{display:inline-flex;align-items:center;gap:8px;padding:6px 16px;background:rgba(99,102,241,.1);border:1px solid rgba(99,102,241,.25);border-radius:100px;font-size:11px;font-weight:600;color:var(--accent3);text-transform:uppercase;letter-spacing:1.5px;margin-bottom:28px;width:fit-content}
.hero-badge .dot{width:6px;height:6px;background:var(--green);border-radius:50%;animation:pulse 2s ease-in-out infinite}
@keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(16,185,129,.4)}50%{box-shadow:0 0 0 6px rgba(16,185,129,0)}}
.hero h1{font-size:clamp(34px,5vw,52px);font-weight:800;line-height:1.08;letter-spacing:-1.5px;margin-bottom:20px}
.hero .grad{background:linear-gradient(135deg,var(--accent2),var(--cyan),var(--green2));-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}
.hero-sub{font-size:17px;color:var(--text2);max-width:580px;margin-bottom:48px}
.hero-sub strong{color:var(--text)}
/* Alert stat row */
.alert-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:40px}
@media(max-width:640px){.alert-stats{grid-template-columns:1fr}}
.alert-stat{padding:20px;background:var(--card);border:1px solid var(--border);border-radius:12px;text-align:center;position:relative;overflow:hidden}
.alert-stat::before{content:'';position:absolute;top:0;left:0;right:0;height:2px}
.alert-stat.red::before{background:var(--red)}
.alert-stat.amber::before{background:var(--yellow)}
.alert-stat.grey::before{background:var(--muted)}
.alert-stat .val{font-size:32px;font-weight:800;font-family:'JetBrains Mono',monospace;letter-spacing:-1px;line-height:1.2}
.alert-stat.red .val{color:var(--red2)}
.alert-stat.amber .val{color:var(--yellow)}
.alert-stat.grey .val{color:var(--muted)}
.alert-stat .lbl{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;font-weight:600;margin-top:4px}
/* Section headers */
.snum{font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--accent);font-weight:500;letter-spacing:2px;margin-bottom:8px;display:flex;align-items:center;gap:12px}
.snum::after{content:'';flex:1;height:1px;background:linear-gradient(90deg,var(--border2),transparent)}
.stitle{font-size:clamp(26px,3.5vw,34px);font-weight:700;letter-spacing:-.8px;margin-bottom:12px;line-height:1.2}
.sdesc{color:var(--text2);font-size:15px;max-width:560px;margin-bottom:44px}
.sdesc strong{color:var(--text)}
/* Charts */
.chart-row{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-bottom:24px}
@media(max-width:700px){.chart-row{grid-template-columns:1fr}}
.chart-card{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:24px}
.chart-card h4{font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;font-weight:600;margin-bottom:16px}
.chart-box{position:relative;height:220px}
/* Insight callout */
.callout{padding:18px 22px;border-radius:12px;font-size:14px;margin-bottom:16px;display:flex;align-items:flex-start;gap:14px}
.callout .ico{font-size:20px;flex-shrink:0;margin-top:1px}
.callout.red{background:rgba(239,68,68,.06);border:1px solid rgba(239,68,68,.18);color:var(--red2)}
.callout.green{background:rgba(16,185,129,.06);border:1px solid rgba(16,185,129,.18);color:var(--green2)}
.callout.blue{background:rgba(99,102,241,.06);border:1px solid rgba(99,102,241,.18);color:var(--accent3)}
.callout.amber{background:rgba(245,158,11,.06);border:1px solid rgba(245,158,11,.18);color:var(--yellow)}
.callout strong{font-weight:700}
/* Channel donut */
.channel-section{display:grid;grid-template-columns:280px 1fr;gap:32px;align-items:center;margin-bottom:32px}
@media(max-width:700px){.channel-section{grid-template-columns:1fr}}
.channel-chart-box{height:240px;position:relative}
.channel-facts{display:flex;flex-direction:column;gap:12px}
.channel-fact{padding:14px 18px;background:var(--card);border:1px solid var(--border);border-radius:10px;font-size:13px;color:var(--text2)}
.channel-fact strong{color:var(--text)}
.channel-fact .highlight{color:var(--red2);font-weight:700}
/* Scope/pillar cards */
.pillar{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:28px;margin-bottom:16px;position:relative;overflow:hidden;transition:.3s;cursor:default}
.pillar:hover{border-color:var(--border2);box-shadow:0 6px 32px rgba(0,0,0,.25)}
.pillar::before{content:'';position:absolute;top:0;left:0;right:0;height:2px}
.pillar.p1::before{background:linear-gradient(90deg,var(--accent),var(--cyan))}
.pillar.p2::before{background:linear-gradient(90deg,var(--purple),var(--pink))}
.pillar.p3::before{background:linear-gradient(90deg,var(--green),var(--cyan))}
.pillar.p4::before{background:linear-gradient(90deg,var(--pink),var(--orange))}
.pillar-head{display:flex;align-items:center;gap:14px;margin-bottom:6px;cursor:pointer}
.pillar-icon{width:44px;height:44px;border-radius:11px;display:flex;align-items:center;justify-content:center;font-size:20px;flex-shrink:0}
.pillar-icon.i1{background:rgba(99,102,241,.12)}.pillar-icon.i2{background:rgba(168,85,247,.12)}.pillar-icon.i3{background:rgba(16,185,129,.12)}.pillar-icon.i4{background:rgba(236,72,153,.12)}
.pillar-lbl{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:1.5px;font-weight:600}
.pillar-name{font-size:18px;font-weight:700}
.pillar-toggle{margin-left:auto;font-size:18px;color:var(--muted);transition:.3s}
.pillar.open .pillar-toggle{transform:rotate(45deg);color:var(--accent2)}
.pillar-body{max-height:0;overflow:hidden;transition:max-height .4s cubic-bezier(.16,1,.3,1)}
.pillar.open .pillar-body{max-height:400px}
.pillar-items{list-style:none;padding-top:16px}
.pillar-items li{display:flex;gap:10px;padding:8px 0;font-size:13px;color:var(--text2);border-bottom:1px solid rgba(26,37,69,.5)}
.pillar-items li:last-child{border:none}
.pillar-items li .ck{color:var(--green);font-weight:700;font-size:12px;margin-top:2px}
/* ROI Calculator */
.roi-calc{background:var(--card);border:1px solid var(--accent);border-radius:16px;padding:32px;position:relative;overflow:hidden}
.roi-calc::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,var(--accent),var(--cyan),var(--green))}
.roi-calc h3{font-size:18px;font-weight:700;margin-bottom:4px}
.roi-calc .sub{font-size:13px;color:var(--muted);margin-bottom:28px}
.slider-row{margin-bottom:28px}
.slider-label{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;font-size:13px;color:var(--text2)}
.slider-label .slider-val{font-family:'JetBrains Mono',monospace;font-weight:600;color:var(--accent2);font-size:16px}
input[type=range]{width:100%;height:6px;-webkit-appearance:none;background:var(--card3);border-radius:3px;outline:none}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:20px;height:20px;border-radius:50%;background:var(--accent);cursor:pointer;border:2px solid var(--accent3);box-shadow:0 0 12px rgba(99,102,241,.4)}
.roi-output{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
@media(max-width:700px){.roi-output{grid-template-columns:1fr 1fr}}
.roi-metric{background:var(--card2);border:1px solid var(--border);border-radius:10px;padding:16px;text-align:center}
.roi-metric .rv{font-size:24px;font-weight:800;font-family:'JetBrains Mono',monospace;letter-spacing:-1px}
.roi-metric .rv.green{color:var(--green2)}
.roi-metric .rv.cyan{color:var(--cyan2)}
.roi-metric .rv.accent{color:var(--accent3)}
.roi-metric .rl{font-size:10px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;margin-top:4px;font-weight:600}
.roi-assumptions{margin-top:20px;padding:14px 18px;background:var(--bg2);border-radius:8px;font-size:11px;color:var(--muted);line-height:1.8}
.roi-assumptions strong{color:var(--text2)}
/* De-risk */
.risk-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:640px){.risk-grid{grid-template-columns:1fr}}
.risk-card{padding:20px;background:var(--card);border:1px solid var(--border);border-radius:12px;display:flex;gap:14px;transition:.3s}
.risk-card:hover{border-color:var(--border2)}
.risk-card .ri{font-size:22px;flex-shrink:0}
.risk-card .rt{font-size:14px;font-weight:600;margin-bottom:2px}
.risk-card .rd{font-size:12px;color:var(--muted);line-height:1.5}
/* Timeline */
.tl{position:relative;padding-left:36px}
.tl::before{content:'';position:absolute;left:13px;top:0;bottom:0;width:2px;background:linear-gradient(180deg,var(--accent),var(--cyan),var(--green),var(--purple));border-radius:2px}
.tl-item{position:relative;margin-bottom:32px;padding:20px 24px;background:var(--card);border:1px solid var(--border);border-radius:12px;transition:.3s}
.tl-item:hover{border-color:var(--border2);transform:translateX(4px)}
.tl-item:last-child{margin-bottom:0}
.tl-dot{position:absolute;left:-31px;top:24px;width:10px;height:10px;border-radius:50%;border:2px solid;background:var(--bg)}
.tl-item:nth-child(1) .tl-dot{border-color:var(--accent);box-shadow:0 0 10px rgba(99,102,241,.5)}
.tl-item:nth-child(2) .tl-dot{border-color:var(--cyan);box-shadow:0 0 10px rgba(6,182,212,.5)}
.tl-item:nth-child(3) .tl-dot{border-color:var(--green);box-shadow:0 0 10px rgba(16,185,129,.5)}
.tl-item:nth-child(4) .tl-dot{border-color:var(--purple);box-shadow:0 0 10px rgba(168,85,247,.5)}
.tl-wk{font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:1.5px;margin-bottom:4px}
.tl-item:nth-child(1) .tl-wk{color:var(--accent2)}
.tl-item:nth-child(2) .tl-wk{color:var(--cyan)}
.tl-item:nth-child(3) .tl-wk{color:var(--green)}
.tl-item:nth-child(4) .tl-wk{color:var(--purple)}
.tl-title{font-size:16px;font-weight:700;margin-bottom:4px}
.tl-desc{font-size:13px;color:var(--muted)}
.tl-ckpt{display:inline-block;margin-top:8px;padding:3px 10px;background:rgba(16,185,129,.1);border:1px solid rgba(16,185,129,.2);border-radius:6px;font-size:11px;color:var(--green2);font-weight:600}
.tl-total{margin-top:28px;padding:14px 20px;background:var(--card2);border:1px solid var(--border);border-radius:10px;text-align:center;font-size:14px;font-weight:600}
.tl-total span{font-family:'JetBrains Mono',monospace;color:var(--accent2)}
/* Investment options */
@media(max-width:700px){#invest .opt{margin-bottom:16px} #invest>section>div:first-of-type{grid-template-columns:1fr!important}}
.opt{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:28px;position:relative;overflow:hidden;transition:.3s}
.opt:hover{border-color:var(--border2)}
.opt.rec{border-color:var(--accent);background:linear-gradient(135deg,var(--card),rgba(99,102,241,.04))}
.opt.rec::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,var(--accent),var(--cyan))}
.opt-badge{position:absolute;top:12px;right:12px;padding:3px 10px;background:var(--accent);color:#fff;font-size:10px;font-weight:700;border-radius:4px;text-transform:uppercase;letter-spacing:1px}
.opt-name{font-size:13px;color:var(--muted);text-transform:uppercase;letter-spacing:1px;font-weight:600;margin-bottom:12px}
.opt-price{font-size:36px;font-weight:800;letter-spacing:-1.5px;margin-bottom:2px;font-family:'JetBrains Mono',monospace}
.opt-price .cur{font-size:18px;font-weight:600;opacity:.5;vertical-align:top;line-height:2.2}
.opt.rec .opt-price{color:var(--accent3)}
.opt-sub{font-size:12px;color:var(--muted);margin-bottom:20px}
.opt-list{list-style:none}
.opt-list li{font-size:13px;padding:6px 0;color:var(--text2);display:flex;gap:8px}
.opt-list li .c{color:var(--green);font-weight:700;font-size:11px;margin-top:2px}
.opt-list li .x{color:var(--muted);font-size:11px;margin-top:2px}
.opt-list li.disabled{color:var(--muted);opacity:.5}
.cost-box{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:24px 28px;margin-bottom:20px}
.cost-box h4{font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:1.5px;font-weight:600;margin-bottom:16px}
.cost-row{display:flex;justify-content:space-between;padding:10px 0;border-bottom:1px solid rgba(26,37,69,.5);font-size:14px;color:var(--text2)}
.cost-row:last-child{border:none}
.cost-row .cv{font-family:'JetBrains Mono',monospace;font-weight:600}
.cost-row.total{border-top:1px solid var(--border2);border-bottom:none;padding-top:14px;margin-top:4px;color:var(--text);font-weight:700}
.cost-row.total .cv{color:var(--green2);font-size:16px}
/* Decision / CTA */
.cta-box{background:linear-gradient(135deg,var(--card),var(--card2));border:1px solid var(--border);border-radius:20px;padding:48px;text-align:center;position:relative;overflow:hidden}
.cta-box::before{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,var(--accent),var(--cyan),var(--green),transparent)}
.cta-title{font-size:clamp(22px,3vw,28px);font-weight:800;letter-spacing:-.5px;margin-bottom:10px}
.cta-desc{color:var(--muted);font-size:14px;margin-bottom:32px;max-width:440px;margin-left:auto;margin-right:auto}
.cta-steps{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:32px;text-align:center}
@media(max-width:640px){.cta-steps{grid-template-columns:1fr}}
.cta-step{padding:16px;background:var(--bg2);border-radius:10px}
.cta-step .num{font-family:'JetBrains Mono',monospace;font-size:20px;font-weight:700;color:var(--accent2);margin-bottom:4px}
.cta-step .txt{font-size:12px;color:var(--muted)}
.cta-btn{display:inline-flex;align-items:center;gap:10px;padding:16px 40px;background:linear-gradient(135deg,var(--accent),#4f46e5);color:#fff;border:none;border-radius:12px;font-size:16px;font-weight:700;font-family:inherit;cursor:pointer;transition:.3s;text-decoration:none;box-shadow:0 4px 24px rgba(99,102,241,.3)}
.cta-btn:hover{transform:translateY(-2px);box-shadow:0 8px 32px rgba(99,102,241,.45)}
.cta-footer{margin-top:16px;font-size:12px;color:var(--muted)}
/* Board summary */
.board{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:32px}
.board h3{font-size:14px;font-weight:700;margin-bottom:20px;display:flex;align-items:center;gap:10px}
.board h3 .tag{padding:3px 10px;background:rgba(99,102,241,.12);color:var(--accent2);border-radius:4px;font-size:10px;text-transform:uppercase;letter-spacing:1px}
.board ol{list-style:none;counter-reset:b}
.board ol li{counter-increment:b;padding:10px 0;border-bottom:1px solid rgba(26,37,69,.4);font-size:13px;color:var(--text2);display:flex;gap:12px}
.board ol li:last-child{border:none}
.board ol li::before{content:counter(b);font-family:'JetBrains Mono',monospace;font-size:11px;font-weight:700;color:var(--accent);background:rgba(99,102,241,.1);width:22px;height:22px;border-radius:6px;display:flex;align-items:center;justify-content:center;flex-shrink:0;margin-top:2px}
/* FAQ */
.faq-item{background:var(--card);border:1px solid var(--border);border-radius:10px;margin-bottom:8px;overflow:hidden}
.faq-q{padding:16px 20px;cursor:pointer;display:flex;justify-content:space-between;align-items:center;font-size:14px;font-weight:600;transition:.2s}
.faq-q:hover{background:var(--card2)}
.faq-q .arrow{color:var(--muted);transition:.3s;font-size:16px}
.faq-item.open .faq-q .arrow{transform:rotate(45deg);color:var(--accent2)}
.faq-a{max-height:0;overflow:hidden;transition:max-height .4s cubic-bezier(.16,1,.3,1)}
.faq-item.open .faq-a{max-height:300px}
.faq-a-inner{padding:0 20px 16px;font-size:13px;color:var(--muted);line-height:1.7}
/* Footer */
.page-footer{text-align:center;padding:40px 0;border-top:1px solid var(--border);color:var(--muted);font-size:11px;margin-top:40px}
@media(max-width:640px){
.wrap{padding:0 16px}
section{padding:60px 0}
.hero{padding:80px 0 60px}
}
@media print{
.orb,.nav,.progress{display:none!important}
section{opacity:1!important;transform:none!important;padding:30px 0!important;page-break-inside:avoid}
body{-webkit-print-color-adjust:exact!important;print-color-adjust:exact!important}
*{-webkit-print-color-adjust:exact!important;print-color-adjust:exact!important}
}
</style>
</head>
<body>
<div class="progress" id="prog"></div>
<div class="orb orb-1"></div>
<div class="orb orb-2"></div>
<nav class="nav" id="nav">
<a href="#data">Data</a>
<a href="#solution">Solution</a>
<a href="#impact">Impact</a>
<a href="#invest">Investment</a>
<a href="#decide">Decide</a>
</nav>
<div class="wrap">
<!-- ══════════════ HERO ══════════════ -->
<section class="hero" id="top">
<div class="hero-badge"><span class="dot"></span>Proposal — Just Vitamins</div>
<h1>Reverse the acquisition<br>decline. Build <span class="grad">owned AI<br>infrastructure.</span></h1>
<p class="hero-sub">Your repeat customers love you. But <strong>new customer discovery is collapsing</strong>. This proposal installs the content engine and commerce channels to fix that — infrastructure you own, not an agency dependency.</p>
<div class="alert-stats">
<div class="alert-stat red">
<div class="val" data-count="-84">0%</div>
<div class="lbl">New Customer Decline</div>
</div>
<div class="alert-stat amber">
<div class="val" data-count="-42">0%</div>
<div class="lbl">Revenue from Peak</div>
</div>
<div class="alert-stat grey">
<div class="val">85%</div>
<div class="lbl">Channel Dependency (Google + Organic)</div>
</div>
</div>
</section>
<div class="divider"></div>
<!-- ══════════════ THE DATA ══════════════ -->
<section id="data">
<div class="snum">01 — YOUR DATA</div>
<h2 class="stitle">The Numbers Don't Lie</h2>
<p class="sdesc">We analysed <strong>728,018 orders</strong> spanning 20 years. Two trends dominate everything else.</p>
<div class="chart-row">
<div class="chart-card">
<h4>Revenue Trend (£)</h4>
<div class="chart-box"><canvas id="revChart"></canvas></div>
</div>
<div class="chart-card">
<h4>New Customer Acquisition</h4>
<div class="chart-box"><canvas id="custChart"></canvas></div>
</div>
</div>
<div class="callout green">
<span class="ico">💪</span>
<div><strong>Your product is not the problem.</strong> AOV has climbed from £26 (2018) → £35 (2025). 68% of all orders come from returning customers. Customers who find you, stay. The product drives loyalty.</div>
</div>
<div class="callout red">
<span class="ico">🚨</span>
<div><strong>Discovery is the problem.</strong> New customer volume has collapsed 84% — from 24,600/year in 2020 to under 4,000 in 2025. You're not losing customers. You're failing to find new ones.</div>
</div>
<div class="snum" style="margin-top:48px">THE ROOT CAUSE</div>
<h2 class="stitle" style="font-size:24px;margin-bottom:28px">85% Channel Dependency</h2>
<div class="channel-section">
<div class="chart-card" style="padding:20px">
<div class="channel-chart-box"><canvas id="chChart"></canvas></div>
</div>
<div class="channel-facts">
<div class="channel-fact"><strong>Organic + Google Ads = <span class="highlight">85%</span></strong> of all orders in 2025. If Google changes an algorithm, you lose the business.</div>
<div class="channel-fact"><strong>Facebook: 0.1%.</strong> TikTok: 0%. Instagram: 0%. You have <strong>zero social commerce</strong> presence in 2025.</div>
<div class="channel-fact"><strong>No AI content pipeline.</strong> H&B, Vitabiotics, and Boots all run active social + paid content across TikTok, Instagram, and YouTube. JustVitamins has zero presence on any of these channels. Every month without them = missed discovery.</div>
</div>
</div>
<div class="callout amber">
<span class="ico"></span>
<div><strong>Cost of inaction:</strong> In 2020 you acquired 24,666 new customers. In 2025, just 3,941. At your 2025 AOV of £35.02, that's <strong>£726,000 in lost first-purchase revenue per year</strong> — before repeat purchases. Every month without new discovery channels widens this gap. <em style="font-size:12px">(See interactive model below)</em></div>
</div>
</section>
<div class="divider"></div>
<!-- ══════════════ SOLUTION ══════════════ -->
<section id="solution">
<div class="snum">02 — WHAT WE'LL BUILD</div>
<h2 class="stitle">Four Pillars. You Own All of It.</h2>
<p class="sdesc">Modular infrastructure — built once, extended over time. No agency lock-in.</p>
<div class="pillar p1 open" onclick="togglePillar(this)">
<div class="pillar-head">
<div class="pillar-icon i1">🏗️</div>
<div><div class="pillar-lbl">Pillar 1</div><div class="pillar-name">Infrastructure Layer</div></div>
<div class="pillar-toggle">+</div>
</div>
<div class="pillar-body"><ul class="pillar-items">
<li><span class="ck"></span>Dedicated cloud server — fully isolated, your data never leaves</li>
<li><span class="ck"></span>Containerised deployment — reliable, portable, zero vendor lock-in</li>
<li><span class="ck"></span>Automated backups, SSL, uptime monitoring</li>
<li><span class="ck"></span>Automation backbone ready for future tools (support inbox, dashboards, email flows)</li>
</ul></div>
</div>
<div class="pillar p2" onclick="togglePillar(this)">
<div class="pillar-head">
<div class="pillar-icon i2">🎨</div>
<div><div class="pillar-lbl">Pillar 2</div><div class="pillar-name">AI Media Factory</div></div>
<div class="pillar-toggle">+</div>
</div>
<div class="pillar-body"><ul class="pillar-items">
<li><span class="ck"></span>Automated script generation — on-brand, conversion-focused copy at scale</li>
<li><span class="ck"></span>AI image generation workflows — product, lifestyle & social-native visuals</li>
<li><span class="ck"></span>AI UGC-style video workflows — creator-feel content without the creator cost</li>
<li><span class="ck"></span>Structured content library output — organised, tagged, ready to deploy</li>
</ul></div>
</div>
<div class="pillar p3" onclick="togglePillar(this)">
<div class="pillar-head">
<div class="pillar-icon i3">📊</div>
<div><div class="pillar-lbl">Pillar 3</div><div class="pillar-name">Commerce Optimisation Engine</div></div>
<div class="pillar-toggle">+</div>
</div>
<div class="pillar-body"><ul class="pillar-items">
<li><span class="ck"></span>Review mining → objections, messaging angles, product insights</li>
<li><span class="ck"></span>Competitor structure analysis — pricing, positioning, content gaps</li>
<li><span class="ck"></span>PDP improvement framework — data-driven product page recommendations</li>
<li><span class="ck"></span>Blog/PDP → social repurposing — turn existing content into channel-native posts</li>
<li><span class="ck"></span>No mass AI publishing — all output is SEO-safe and human-reviewed</li>
</ul></div>
</div>
<div class="pillar p4" onclick="togglePillar(this)">
<div class="pillar-head">
<div class="pillar-icon i4">🎵</div>
<div><div class="pillar-lbl">Pillar 4</div><div class="pillar-name">TikTok Shop Setup</div></div>
<div class="pillar-toggle">+</div>
</div>
<div class="pillar-body"><ul class="pillar-items">
<li><span class="ck"></span>Full TikTok Shop integration with Shopify</li>
<li><span class="ck"></span>35 hero product optimisation — titles, descriptions, creative</li>
<li><span class="ck"></span>Product storytelling structure — hooks, narratives, format frameworks</li>
</ul></div>
</div>
</section>
<div class="divider"></div>
<!-- ══════════════ IMPACT MODEL ══════════════ -->
<section id="impact">
<div class="snum">03 — PROJECTED IMPACT</div>
<h2 class="stitle">What Could This Be Worth?</h2>
<p class="sdesc">Adjust the slider to model the impact. All calculations use <strong>your actual metrics</strong>.</p>
<div class="roi-calc">
<h3>Interactive Revenue Model</h3>
<div class="sub">Based on your 2025 AOV (£35.02) and 12-month cohort return rate (57.6%)</div>
<div class="slider-row">
<div class="slider-label">
<span>New customers per month from social/TikTok channels</span>
<span class="slider-val" id="sliderVal">100</span>
</div>
<input type="range" id="roiSlider" min="25" max="400" value="100" step="25" oninput="calcROI()">
<div style="display:flex;justify-content:space-between;font-size:10px;color:var(--muted);margin-top:4px">
<span>Conservative (25)</span><span>Moderate (100200)</span><span>Aggressive (400)</span>
</div>
</div>
<div class="roi-output">
<div class="roi-metric"><div class="rv green" id="roiMonthly">£3,502</div><div class="rl">Monthly New Revenue</div></div>
<div class="roi-metric"><div class="rv green" id="roiAnnual">£73,151</div><div class="rl">Annual Rev (with LTV)</div></div>
<div class="roi-metric"><div class="rv accent" id="roiMultiple">5.9x</div><div class="rl">Year 1 ROI</div></div>
<div class="roi-metric"><div class="rv cyan" id="roiPayback">2.1 mo</div><div class="rl">Payback Period</div></div>
</div>
<div class="roi-assumptions">
<strong>Assumptions:</strong> AOV = £35.02 (your 2025 actual) · 12-month cohort return rate = 57.6% (from cohort analysis of 728,018 orders) · Avg 2 repeat purchases in first year · Year 1 cost = £4,000 build + £500×12 infra + £200×12 AI tools = £12,400 · Conservative — does not include organic uplift from PDP/blog optimisation or existing channel improvements
</div>
</div>
<div class="callout blue" style="margin-top:24px">
<span class="ico">💡</span>
<div><strong>Anti-objection:</strong> Even at the most conservative setting (25 new customers/month at £35.02 AOV), the £12,400 Year 1 cost is recovered in ~14 months on first-purchase revenue alone — and that excludes the 57.6% who return for repeat purchases. At 100/month, payback is under 4 months. These projections also exclude any improvement to your existing Google/Organic channels from PDP optimisation.</div>
</div>
</section>
<div class="divider"></div>
<!-- ══════════════ DE-RISK ══════════════ -->
<section id="derisk">
<div class="snum">04 — HOW WE DE-RISK THIS</div>
<h2 class="stitle">Controls & Guarantees</h2>
<p class="sdesc">We've designed every gate to protect you.</p>
<div class="risk-grid">
<div class="risk-card"><div class="ri">🚦</div><div><div class="rt">Week 4 Checkpoint</div><div class="rd">Full review before any ongoing commitment. If you're not satisfied with the build, walk away.</div></div></div>
<div class="risk-card"><div class="ri">🔒</div><div><div class="rt">No Mass AI Publishing</div><div class="rd">All content is human-reviewed. No SEO risk. No brand safety issues. Structure-led, not spam.</div></div></div>
<div class="risk-card"><div class="ri">🚪</div><div><div class="rt">30-Day Exit Clause</div><div class="rd">Monthly infrastructure can be cancelled with 30 days' notice. No lock-in contracts.</div></div></div>
<div class="risk-card"><div class="ri">🏛️</div><div><div class="rt">Brand Owns Everything</div><div class="rd">Your server. Your data. Your workflows. Your content. Full admin access from day one.</div></div></div>
<div class="risk-card"><div class="ri">📊</div><div><div class="rt">Weekly Reporting</div><div class="rd">Clear updates each week during build. Measurable checkpoints at each phase.</div></div></div>
<div class="risk-card"><div class="ri">🛡️</div><div><div class="rt">No Org Change Needed</div><div class="rd">This sits behind your existing Shopify store. No team restructuring. No process overhaul.</div></div></div>
</div>
</section>
<div class="divider"></div>
<!-- ══════════════ TIMELINE ══════════════ -->
<section id="timeline">
<div class="snum">05 — TIMELINE</div>
<h2 class="stitle">Build Schedule</h2>
<p class="sdesc">From approval to fully operational.</p>
<div class="tl">
<div class="tl-item"><div class="tl-dot"></div>
<div class="tl-wk">Week 1</div>
<div class="tl-title">Infrastructure Deployed</div>
<div class="tl-desc">Cloud server provisioned, containers configured, SSL and monitoring active.</div>
<div class="tl-ckpt">✓ Checkpoint: Server live, admin access granted</div>
</div>
<div class="tl-item"><div class="tl-dot"></div>
<div class="tl-wk">Week 2</div>
<div class="tl-title">Shopify + TikTok Connected</div>
<div class="tl-desc">Store integrations wired, TikTok Shop configured, optimisation workflows loaded.</div>
<div class="tl-ckpt">✓ Checkpoint: TikTok Shop live with 35 products</div>
</div>
<div class="tl-item"><div class="tl-dot"></div>
<div class="tl-wk">Week 3</div>
<div class="tl-title">AI Media Workflows Live</div>
<div class="tl-desc">Script generation, image creation, and UGC-style video pipelines operational.</div>
<div class="tl-ckpt">✓ Checkpoint: First AI content batch produced</div>
</div>
<div class="tl-item"><div class="tl-dot"></div>
<div class="tl-wk">Week 4</div>
<div class="tl-title">Testing, Documentation, Handover</div>
<div class="tl-desc">Full system testing, documentation delivery, team walkthrough. You're in control.</div>
<div class="tl-ckpt">✓ Gate: Full review — proceed or exit before ongoing commitment</div>
</div>
</div>
<div class="tl-total">Total delivery: <span>34 weeks</span> from approval</div>
</section>
<div class="divider"></div>
<!-- ══════════════ INVESTMENT ══════════════ -->
<section id="invest">
<div class="snum">06 — INVESTMENT</div>
<h2 class="stitle">Investment</h2>
<p class="sdesc">One price. All four pillars. No hidden fees.</p>
<div style="display:grid;grid-template-columns:1fr 1fr;gap:20px;margin-bottom:24px">
<div class="opt rec" style="border-radius:16px">
<div class="opt-name">One-Time Build</div>
<div class="opt-price"><span class="cur">£</span>4,000</div>
<div class="opt-sub">Full infrastructure build & deployment</div>
<ul class="opt-list" style="margin-top:16px">
<li><span class="c"></span>Infrastructure Layer (dedicated server, containers, SSL, backups)</li>
<li><span class="c"></span>AI Media Factory (scripts, images, UGC-style video workflows)</li>
<li><span class="c"></span>Commerce Optimisation Engine (review mining, PDP, competitor analysis)</li>
<li><span class="c"></span>TikTok Shop Setup (integration + 35 product optimisation)</li>
<li><span class="c"></span>Full documentation & team handover</li>
</ul>
</div>
<div class="opt" style="border-radius:16px;display:flex;flex-direction:column;justify-content:center">
<div class="opt-name">Monthly Infrastructure</div>
<div class="opt-price"><span class="cur">£</span>500</div>
<div class="opt-sub">Server, maintenance & monitoring</div>
<ul class="opt-list" style="margin-top:16px">
<li><span class="c"></span>Dedicated server hosting</li>
<li><span class="c"></span>Automated backups & SSL</li>
<li><span class="c"></span>Uptime monitoring</li>
<li><span class="c"></span>30-day exit clause — no lock-in</li>
</ul>
</div>
</div>
<div class="cost-box">
<h4>Estimated Monthly Running Costs</h4>
<div class="cost-row"><span>Infrastructure & maintenance</span><span class="cv">£500</span></div>
<div class="cost-row"><span>AI tool subscriptions (paid directly by brand)</span><span class="cv">£100300</span></div>
<div class="cost-row total"><span>Estimated Total Monthly</span><span class="cv">£600800</span></div>
</div>
<div class="callout blue">
<span class="ico">📌</span>
<div><strong>Context:</strong> £4,000 is less than one month's estimated lost revenue from the acquisition gap. Monthly cost is equivalent to one day's worth of Google Ads spend. This is infrastructure that compounds — every workflow added makes the next one cheaper.</div>
</div>
</section>
<div class="divider"></div>
<!-- ══════════════ DECISION ══════════════ -->
<section id="decide">
<div class="snum">07 — DECISION</div>
<h2 class="stitle">Next Step</h2>
<div class="cta-box">
<div class="cta-title">What We Need From You</div>
<p class="cta-desc">Three things to get started. Nothing else.</p>
<div class="cta-steps">
<div class="cta-step"><div class="num">1</div><div class="txt">Confirm approval<br>to begin build</div></div>
<div class="cta-step"><div class="num">2</div><div class="txt">Provide Shopify &<br>TikTok access</div></div>
<div class="cta-step"><div class="num">3</div><div class="txt">15-minute kickoff call<br>to align priorities</div></div>
</div>
<a class="cta-btn" href="mailto:omair@quikcue.com?subject=JustVitamin%20AI%20Infrastructure%20%E2%80%94%20Approved%20to%20Start&body=Hi%20Omair%2C%0A%0AApproved%20to%20proceed%20with%20the%20AI%20infrastructure%20build.%0ALet%E2%80%99s%20schedule%20the%20kickoff%20call.%0A%0AThanks">✅ Approve & Start Build →</a>
<div class="cta-footer">Build begins within 48 hours of approval. Week 4 gate before any ongoing commitment.</div>
</div>
</section>
<div class="divider"></div>
<!-- ══════════════ BOARD SUMMARY ══════════════ -->
<section id="board">
<div class="snum">APPENDIX</div>
<h2 class="stitle" style="font-size:22px">Board Decision Summary</h2>
<p class="sdesc">Forward this to anyone who needs to approve.</p>
<div class="board">
<h3>Decision Summary <span class="tag">Internal Use</span></h3>
<ol>
<li>New customer acquisition has declined <strong>84%</strong> (24,600 → 3,900/year) since 2020, driving a <strong>42% revenue decline</strong> from peak (£1.82M → £1.05M).</li>
<li>Product-market fit is strong: 68% of orders are repeat purchases, AOV increasing from £26 → £35 (20182025). The decline is a <strong>discovery problem, not a product problem</strong>.</li>
<li><strong>85% of orders depend on two Google channels</strong> (Organic + Google Ads) in 2025. Facebook is 0.1%. TikTok and Instagram are zero. This is a single point of failure.</li>
<li>Proposal: Install <strong>owned AI infrastructure</strong> for content automation, TikTok Shop, PDP optimisation, and competitor insight extraction. Not an agency dependency — brand owns all assets.</li>
<li>Investment: <strong>£4,000 one-time</strong> + £500/mo infrastructure + £100300/mo AI tools. Estimated total ongoing: £600800/month.</li>
<li>Timeline: <strong>Fully operational in 34 weeks</strong> with weekly checkpoints. Week 4 review gate before ongoing commitment.</li>
<li>Risk controls: No mass AI publishing (SEO-safe), 30-day exit clause on monthly, brand retains all access/data/code, weekly reporting during build.</li>
<li>Recommendation: <strong>Approve build (£4,000 one-time)</strong>. Measurable Week 4 checkpoint: infrastructure live, first AI content batch produced, TikTok Shop configured with 35 products. Conservative ROI shows payback within 414 months depending on new customer acquisition rate.</li>
</ol>
</div>
</section>
<div class="divider"></div>
<!-- ══════════════ FAQ ══════════════ -->
<section id="faq">
<div class="snum">QUESTIONS</div>
<h2 class="stitle" style="font-size:22px;margin-bottom:24px">Anticipated Questions</h2>
<div class="faq-item" onclick="toggleFaq(this)"><div class="faq-q">Is AI-generated content good enough for our brand?<span class="arrow">+</span></div><div class="faq-a"><div class="faq-a-inner">Yes — with the right controls. All output is structure-led and human-reviewed before publishing. We do not mass-publish AI content. The system generates drafts and options; your team approves what goes live. This is the same approach used by premium DTC brands globally.</div></div></div>
<div class="faq-item" onclick="toggleFaq(this)"><div class="faq-q">Will this actually bring new customers?<span class="arrow">+</span></div><div class="faq-a"><div class="faq-a-inner">The infrastructure creates the capability to reach customers on channels you're currently absent from (TikTok, social, content-driven discovery). Your product already converts and retains — the gap is solely in discovery. Even modest new-channel performance (2550 new customers/month) delivers positive ROI within months.</div></div></div>
<div class="faq-item" onclick="toggleFaq(this)"><div class="faq-q">What if it doesn't work?<span class="arrow">+</span></div><div class="faq-a"><div class="faq-a-inner">Week 4 is a formal review gate. If you're not satisfied with the build, there's no ongoing commitment. Monthly infrastructure has a 30-day exit clause. The one-time build cost covers real infrastructure you retain regardless — server, workflows, content library, TikTok Shop configuration.</div></div></div>
<div class="faq-item" onclick="toggleFaq(this)"><div class="faq-q">Who manages this after handover?<span class="arrow">+</span></div><div class="faq-a"><div class="faq-a-inner">The system is designed to be low-maintenance. Documentation covers all workflows. Day-to-day content generation is semi-automated — your team reviews outputs, not builds pipelines. The £500/mo infrastructure fee covers server maintenance, monitoring, and backups.</div></div></div>
<div class="faq-item" onclick="toggleFaq(this)"><div class="faq-q">What access do you need?<span class="arrow">+</span></div><div class="faq-a"><div class="faq-a-inner">Shopify collaborator access (not owner), TikTok Shop credentials, and any brand guidelines/assets you have. We do not need payment processor access, customer PII, or admin-level Shopify permissions.</div></div></div>
<div class="faq-item" onclick="toggleFaq(this)"><div class="faq-q">Is our data secure?<span class="arrow">+</span></div><div class="faq-a"><div class="faq-a-inner">Your infrastructure runs on a dedicated server — not shared. SSL encrypted, automated backups, and the brand has full admin access. No data is shared with third parties. You own the server and everything on it.</div></div></div>
<div class="faq-item" onclick="toggleFaq(this)"><div class="faq-q">How is this different from hiring an agency?<span class="arrow">+</span></div><div class="faq-a"><div class="faq-a-inner">An agency charges monthly for services and you own nothing when you leave. This is a one-time infrastructure build — you own the server, the workflows, the content, and the integrations. The £500/mo covers hosting and maintenance only. If you cancel, you keep the infrastructure and can self-host.</div></div></div>
</section>
<!-- ══════════════ BUILT BY ══════════════ -->
<div style="max-width:680px;margin:48px auto;padding:28px 32px;background:rgba(99,102,241,.04);border:1px solid rgba(99,102,241,.15);border-radius:14px;display:flex;gap:20px;align-items:center">
<div style="flex-shrink:0;width:64px;height:64px;border-radius:50%;background:linear-gradient(135deg,#6366f1,#06b6d4);display:flex;align-items:center;justify-content:center;font-size:28px;font-weight:700;color:#fff">O</div>
<div>
<div style="font-size:16px;font-weight:700;color:var(--text)">Omair · <a href="https://quikcue.com" style="color:var(--accent)">QuikCue</a></div>
<div style="font-size:13px;color:var(--text2);margin-top:4px;line-height:1.5">I build AI infrastructure for ecommerce brands — automation, content engines, and data systems. This proposal was built using the same tools I'm proposing to install. Every demo, every chart, every number on this page is real.</div>
<div style="margin-top:8px;font-size:12px;display:flex;gap:12px">
<a href="mailto:omair@quikcue.com" style="color:var(--accent)">omair@quikcue.com</a>
<a href="https://quikcue.com" style="color:var(--text3)">quikcue.com</a>
</div>
</div>
</div>
<div class="page-footer">
Prepared for Just Vitamins · March 2026 · Confidential<br>
Data source: 728,018 validated orders · Nov 2005 — Jan 2026
</div>
</div>
<script>
// ══════ SCROLL OBSERVER ══════
const obs = new IntersectionObserver(e => {
e.forEach(en => { if(en.isIntersecting) en.target.classList.add('vis'); });
}, {threshold:.08, rootMargin:'0px 0px -30px 0px'});
document.querySelectorAll('section').forEach(s => obs.observe(s));
document.getElementById('top').classList.add('vis');
// ══════ PROGRESS BAR + NAV ══════
const prog = document.getElementById('prog');
const nav = document.getElementById('nav');
window.addEventListener('scroll', () => {
const h = document.documentElement.scrollHeight - window.innerHeight;
prog.style.width = (window.scrollY / h * 100) + '%';
nav.classList.toggle('show', window.scrollY > 600);
});
// ══════ ANIMATED COUNTERS ══════
const counted = new Set();
const counterObs = new IntersectionObserver(e => {
e.forEach(en => {
if (!en.isIntersecting || counted.has(en.target)) return;
counted.add(en.target);
const target = parseInt(en.target.dataset.count);
const duration = 1200;
const start = performance.now();
function tick(now) {
const p = Math.min((now - start) / duration, 1);
const ease = 1 - Math.pow(1 - p, 3);
const val = Math.round(target * ease);
en.target.textContent = val + '%';
if (p < 1) requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
});
}, {threshold:.5});
document.querySelectorAll('[data-count]').forEach(el => counterObs.observe(el));
// ══════ LOAD REAL DATA FROM API ══════
const cBase = {responsive:true,maintainAspectRatio:false,animation:{duration:600},plugins:{legend:{display:false}},scales:{x:{grid:{color:'rgba(26,37,69,.4)'},ticks:{color:'#5a6d94',font:{size:10}}},y:{grid:{color:'rgba(26,37,69,.4)'},ticks:{color:'#5a6d94',font:{size:10}}}}};
fetch('/api/dashboard/data').then(r=>r.json()).then(data => {
const m = data.monthly.sort((a,b)=>a.YearMonth.localeCompare(b.YearMonth));
// Aggregate by year (2018+)
const yearly = {};
m.forEach(r => {
const y = r.YearMonth.substring(0,4);
if(parseInt(y) < 2018) return;
if(!yearly[y]) yearly[y] = {rev:0, orders:0, newCust:0};
yearly[y].rev += r.revenue;
yearly[y].orders += r.orders;
yearly[y].newCust += r.newCustomers;
});
const years = Object.keys(yearly).sort().filter(y => y !== '2026');
const peakYear = years.reduce((a,b) => yearly[a].rev > yearly[b].rev ? a : b);
const latestYear = years[years.length-1];
const peakNewYear = years.reduce((a,b) => yearly[a].newCust > yearly[b].newCust ? a : b);
// Update hero stats dynamically
const newDecline = yearly[peakNewYear] && yearly[latestYear] ? Math.round((yearly[latestYear].newCust - yearly[peakNewYear].newCust) / yearly[peakNewYear].newCust * 100) : -84;
const revDecline = yearly[peakYear] && yearly[latestYear] ? Math.round((yearly[latestYear].rev - yearly[peakYear].rev) / yearly[peakYear].rev * 100) : -42;
document.querySelectorAll('[data-count]').forEach(el => {
if(el.closest('.red')) el.dataset.count = newDecline;
if(el.closest('.amber')) el.dataset.count = revDecline;
});
// Channel data
const ch = data.channelMonthly || [];
const chTotals = {};
// Use last 24 months for channel %
const recent = m.filter(r => r.YearMonth >= (parseInt(latestYear)-1)+'-01');
const recentYMs = new Set(recent.map(r=>r.YearMonth));
ch.filter(r => recentYMs.has(r.YearMonth)).forEach(r => {
chTotals[r.ReferrerSource] = (chTotals[r.ReferrerSource]||0) + r.orders;
});
const chTotal = Object.values(chTotals).reduce((a,b)=>a+b,0);
const googleOrgPct = chTotal > 0 ? Math.round(((chTotals['Organic']||0) + (chTotals['Google Adwords']||0)) / chTotal * 100) : 85;
// Update the 85% stat dynamically
const greyVal = document.querySelector('.alert-stat.grey .val');
if(greyVal) greyVal.textContent = googleOrgPct + '%';
const channelH2 = document.querySelector('h2.stitle');
if(channelH2 && channelH2.textContent.includes('Channel Dependency'))
channelH2.textContent = googleOrgPct + '% Channel Dependency';
// Revenue chart — from real data
new Chart(document.getElementById('revChart'), {
type:'line',
data:{
labels: years,
datasets:[{
data: years.map(y => Math.round(yearly[y].rev)),
borderColor:'#6366f1',backgroundColor:'rgba(99,102,241,.1)',fill:true,tension:.4,pointRadius:4,pointBackgroundColor:'#6366f1',
pointBorderColor:'#0d1322',pointBorderWidth:2,borderWidth:2.5
}]
},
options:{...cBase,scales:{...cBase.scales,y:{...cBase.scales.y,ticks:{...cBase.scales.y.ticks,callback:v=>'£'+Math.round(v/1000)+'k'}}},
plugins:{...cBase.plugins,tooltip:{callbacks:{label:ctx=>'£'+ctx.raw.toLocaleString()}}}}
});
// New customer chart — from real data
const custColors = years.map(y => {
if(y === peakNewYear) return '#10b981cc';
return yearly[y].newCust < yearly[peakNewYear].newCust * 0.5 ? '#ef4444cc' :
yearly[y].newCust < yearly[peakNewYear].newCust * 0.75 ? '#f59e0bcc' : '#6366f1cc';
});
new Chart(document.getElementById('custChart'), {
type:'bar',
data:{
labels: years,
datasets:[{
data: years.map(y => yearly[y].newCust),
backgroundColor: custColors,
borderRadius:6,borderSkipped:false
}]
},
options:{...cBase,plugins:{...cBase.plugins,tooltip:{callbacks:{label:ctx=>ctx.raw.toLocaleString()+' new customers'}}}}
});
// Channel donut — from real data
const chEntries = Object.entries(chTotals).sort((a,b)=>b[1]-a[1]);
const chColors = ['#6366f1','#818cf8','#a855f7','#06b6d4','#64748b','#ef4444','#f59e0b','#10b981'];
new Chart(document.getElementById('chChart'), {
type:'doughnut',
data:{
labels: chEntries.map(e => e[0]),
datasets:[{
data: chEntries.map(e => parseFloat((e[1]/chTotal*100).toFixed(1))),
backgroundColor: chColors.slice(0, chEntries.length),
borderWidth:0,spacing:2
}]
},
options:{responsive:true,maintainAspectRatio:false,cutout:'65%',
plugins:{legend:{position:'bottom',labels:{color:'#5a6d94',font:{size:10},padding:12,usePointStyle:true,pointStyleWidth:8}},
tooltip:{callbacks:{label:ctx=>ctx.label+': '+ctx.raw+'%'}}}}
});
// Update ROI calculator with real AOV
const latestAOV = yearly[latestYear] ? yearly[latestYear].rev / yearly[latestYear].orders : 35.02;
window._realAOV = latestAOV;
calcROI();
}).catch(err => console.warn('Offer charts: using static fallback', err));
// ══════ ROI CALCULATOR ══════
function calcROI() {
const n = parseInt(document.getElementById('roiSlider').value);
document.getElementById('sliderVal').textContent = n;
const aov = window._realAOV || 35.02; // live from API, fallback to 2025 actual
const cohortReturnRate = 0.576; // 12-month cohort return rate (verified from 728K orders)
const avgRepeats = 2; // conservative avg repeat purchases in year 1
const ltv = aov * (1 + cohortReturnRate * avgRepeats);
const monthlyRev = n * aov;
const annualRev = n * 12 * ltv;
const year1Cost = 4000 + 500*12 + 200*12;
const roi = annualRev / year1Cost;
const payback = year1Cost / monthlyRev; // first-purchase only — conservative
document.getElementById('roiMonthly').textContent = '£' + Math.round(monthlyRev).toLocaleString();
document.getElementById('roiAnnual').textContent = '£' + Math.round(annualRev).toLocaleString();
document.getElementById('roiMultiple').textContent = roi.toFixed(1) + 'x';
document.getElementById('roiPayback').textContent = payback.toFixed(1) + ' mo';
}
calcROI();
// ══════ PILLAR TOGGLE ══════
function togglePillar(el) { el.classList.toggle('open'); }
// ══════ FAQ TOGGLE ══════
function toggleFaq(el) { el.classList.toggle('open'); }
</script>
</body>
</html>