950 lines
83 KiB
HTML
950 lines
83 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>SVS MSP — Live Quote Calculator</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||
<link href="https://fonts.googleapis.com/css2?family=Cinzel:wght@700&family=Poppins:wght@500;600;700&family=Lato:wght@400;700&family=DM+Mono:wght@400;500&display=swap" rel="stylesheet">
|
||
<link rel="stylesheet" href="SVS-MSP-Calculator.css">
|
||
</head>
|
||
<body>
|
||
|
||
<!-- ════════════════════════════════════════════════════════════
|
||
MOBILE FLOATING QUOTE PILL
|
||
Fixed position, top-right, z-index:200 (above header z:100).
|
||
Visible only on ≤1100px via CSS.
|
||
Shows live MRR from #mrrDisplay via update() wrapper.
|
||
Click → openMobilePanel()
|
||
════════════════════════════════════════════════════════════ -->
|
||
<button class="mobile-quote-pill" onclick="openMobilePanel()" aria-label="View quote summary">
|
||
<div class="mobile-pill-icon">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" width="12" height="14" fill="#fff">
|
||
<path d="M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128h128L256 0zM112 256H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z"/>
|
||
</svg>
|
||
</div>
|
||
<div>
|
||
<div class="mobile-pill-mrr" id="mobilePillMrr">—</div>
|
||
<div class="mobile-pill-label">MRR</div>
|
||
</div>
|
||
</button>
|
||
|
||
<!-- ════════════════════════════════════════════════════════════
|
||
MOBILE QUOTE PANEL — full-screen bottom sheet overlay
|
||
z-index:300 (above everything). Hidden by default (opacity:0,
|
||
pointer-events:none). .open class triggers slide-up animation.
|
||
STRUCTURE:
|
||
.mobile-panel-backdrop — dark blur overlay, click to close
|
||
.mobile-panel-sheet — slides up from bottom, max-height:92vh
|
||
.mobile-panel-handle — decorative drag indicator bar
|
||
.mobile-panel-close-row — "QUOTE SUMMARY" label + × button
|
||
#mobilePanelContent — contains duplicate sidebar (_m IDs)
|
||
DUPLICATE SIDEBAR: All sidebar IDs duplicated with _m suffix.
|
||
update() calls syncEl/syncClass/syncStyle to keep _m in sync.
|
||
Never DOM-move the real .sidebar here — it breaks desktop.
|
||
════════════════════════════════════════════════════════════ -->
|
||
<div class="mobile-quote-panel" id="mobileQuotePanel">
|
||
<div class="mobile-panel-backdrop" onclick="closeMobilePanel()"></div>
|
||
<div class="mobile-panel-sheet" id="mobilePanelSheet">
|
||
<div class="mobile-panel-handle"></div>
|
||
<div class="mobile-panel-close-row">
|
||
<span class="mobile-panel-close-title">Quote Summary</span>
|
||
<button class="mobile-panel-close-btn" onclick="closeMobilePanel()" aria-label="Close">×</button>
|
||
</div>
|
||
<!-- Sidebar content injected here by JS on first open -->
|
||
<div id="mobilePanelContent">
|
||
|
||
<div class="sidebar">
|
||
<div class="sidebar-header">
|
||
<div class="sidebar-title">SVS MSP — Live Quote</div>
|
||
<div class="sidebar-client" id="clientNameDisplay_m">Client Name</div>
|
||
</div>
|
||
<div class="sidebar-body">
|
||
<div id="sidebarLines_m">
|
||
<div class="sidebar-line hidden" id="sl-users_m">
|
||
<span><span class="lbl-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" width="14" height="13" fill="currentColor" style="vertical-align:middle;"><path d="M144 0a80 80 0 1 1 0 160A80 80 0 1 1 144 0zM512 0a80 80 0 1 1 0 160A80 80 0 1 1 512 0zM0 298.7C0 239.8 47.8 192 106.7 192h42.7c15.9 0 31 3.5 44.6 9.7c-1.3 7.2-1.9 14.7-1.9 22.3c0 38.2 16.8 72.5 43.3 96c-.2 0-.4 0-.7 0H21.3C9.6 320 0 310.4 0 298.7zM405.3 320c-.2 0-.4 0-.7 0c26.6-23.5 43.3-57.8 43.3-96c0-7.6-.7-15-1.9-22.3c13.6-6.3 28.7-9.7 44.6-9.7h42.7C592.2 192 640 239.8 640 298.7c0 11.8-9.6 21.3-21.3 21.3H405.3zM224 224a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zM128 485.3C128 411.7 187.7 352 261.3 352H378.7C452.3 352 512 411.7 512 485.3c0 14.7-11.9 26.7-26.7 26.7H154.7c-14.7 0-26.7-11.9-26.7-26.7z"/></svg></span> Users</span>
|
||
<span class="val" id="sl-users-val_m">—</span>
|
||
</div>
|
||
<div class="sl-sub" style="display:none;" id="sl-users-sub_m"></div>
|
||
<div class="sidebar-line hidden" id="sl-endpoints_m">
|
||
<span><span class="lbl-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" width="14" height="13" fill="currentColor" style="vertical-align:middle;"><path d="M64 0C28.7 0 0 28.7 0 64V352c0 35.3 28.7 64 64 64H240l-10.7 32H160c-17.7 0-32 14.3-32 32s14.3 32 32 32H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H346.7L336 416H512c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H64zM512 64V352H64V64H512z"/></svg></span> Endpoints</span>
|
||
<span class="val" id="sl-endpoints-val_m">—</span>
|
||
</div>
|
||
<div class="sl-sub" style="display:none;" id="sl-endpoints-sub_m"></div>
|
||
<div class="sidebar-line hidden" id="sl-servers_m">
|
||
<span><span class="lbl-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="13" height="13" fill="currentColor" style="vertical-align:middle;"><path d="M64 32C28.7 32 0 60.7 0 96v64c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm280 72a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm48 24a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zM64 288c-35.3 0-64 28.7-64 64v64c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V352c0-35.3-28.7-64-64-64H64zm280 72a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm56 24a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z"/></svg></span> Servers</span>
|
||
<span class="val" id="sl-servers-val_m">—</span>
|
||
</div>
|
||
<div class="sidebar-line hidden" id="sl-zt_m">
|
||
<span><span class="lbl-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="11" height="13" fill="currentColor" style="vertical-align:middle;"><path d="M144 144v48H304V144c0-44.2-35.8-80-80-80s-80 35.8-80 80zM80 192V144C80 64.5 144.5 0 224 0s144 64.5 144 144v48h16c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V256c0-35.3 28.7-64 64-64H80z"/></svg></span> Zero Trust</span>
|
||
<span class="val" id="sl-zt-val_m">—</span>
|
||
</div>
|
||
<div class="sidebar-line hidden" id="sl-voip_m">
|
||
<span><span class="lbl-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="13" height="13" fill="currentColor" style="vertical-align:middle;"><path d="M164.9 24.6c-7.7-18.6-28-28.5-47.4-23.2l-88 24C11.7 30.3 0 46.7 0 64C0 311.4 200.6 512 448 512c17.3 0 33.7-11.7 38.6-29.5l24-88c5.3-19.4-4.6-39.7-23.2-47.4l-96-40c-16.3-6.8-35.2-2.1-46.3 11.6L304.7 368C234.3 334.7 177.3 277.7 144 207.3L193.3 167c13.7-11.2 18.4-30 11.6-46.3l-40-96z"/></svg></span> VoIP</span>
|
||
<span class="val" id="sl-voip-val_m">—</span>
|
||
</div>
|
||
<div class="sidebar-line" id="sl-admin_m">
|
||
<span><span class="lbl-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" width="12" height="13" fill="currentColor" style="vertical-align:middle;"><path d="M48 0C21.5 0 0 21.5 0 48V464c0 26.5 21.5 48 48 48h96V432c0-26.5 21.5-48 48-48s48 21.5 48 48v80h96c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48H48zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zm48-80v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16zm-144-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16zm144 208h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V352c0-8.8 7.2-16 16-16zm-144-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V352c0-8.8 7.2-16 16-16z"/></svg></span> Site Admin Fee</span>
|
||
<span class="val" id="sl-admin-val_m">$150</span>
|
||
</div>
|
||
<div class="sl-sub" id="sl-admin-sub_m"></div>
|
||
</div>
|
||
|
||
<!-- Discount line — hidden when no term discount -->
|
||
<div class="sidebar-line sidebar-line-discount hidden" id="sl-base-mrr-row_m">
|
||
<span class="sl-muted">Base MRR</span>
|
||
<span class="val sl-muted" id="sl-base-mrr-val_m">—</span>
|
||
</div>
|
||
<div class="sidebar-line sidebar-line-discount hidden" id="sl-discount-row_m">
|
||
<span class="sl-muted">Term Discount</span>
|
||
<span class="val sl-discount-val" id="sl-discount-val_m">—</span>
|
||
</div>
|
||
|
||
<div class="sidebar-mrr-label">Monthly Recurring (MRR)</div>
|
||
<div class="sidebar-mrr" id="mrrDisplay_m">$150</div>
|
||
|
||
<label class="sl-hst-toggle">
|
||
<input type="checkbox" id="hstToggle_m" onchange="document.getElementById('hstToggle').checked=this.checked; update();">
|
||
<span>Include Ontario HST (13%)</span>
|
||
</label>
|
||
|
||
<!-- HST line -->
|
||
<div class="sidebar-line sidebar-line-hst hidden" id="sl-hst-row_m">
|
||
<span class="sl-muted">HST (13%)</span>
|
||
<span class="val sl-hst-val" id="sl-hst-val_m">—</span>
|
||
</div>
|
||
|
||
<!-- Total inc. HST -->
|
||
<div class="sidebar-line sidebar-line-total hidden" id="sl-hst-total-row_m">
|
||
<span>Total (inc. HST)</span>
|
||
<span class="val" id="sl-hst-total-val_m">—</span>
|
||
</div>
|
||
|
||
<!-- Onboarding fee line -->
|
||
<div class="sidebar-line hidden" id="sl-otf-row_m">
|
||
<span>Onboarding Fee</span>
|
||
<span class="val" id="sl-otf-val_m">—</span>
|
||
</div>
|
||
|
||
<div class="sidebar-line">
|
||
<span>Annual Projection</span>
|
||
<span class="val" id="annualDisplay_m">$1,800</span>
|
||
</div>
|
||
<div class="sidebar-line" id="perUserRow_m" style="display:none;">
|
||
<span>Avg. Cost Per User<br><small class="per-user-cost-sub">(all services ÷ users)</small></span>
|
||
<span class="val" id="perUserDisplay_m">—</span>
|
||
</div>
|
||
<div class="sidebar-note sidebar-note-mono hidden" id="perUserBreakdown_m"></div>
|
||
|
||
<hr class="sidebar-divider">
|
||
<div class="sidebar-note" id="sideNote-admin_m">Admin fee = <strong id="adminPct_m">—</strong>% of total MRR</div>
|
||
<div class="sidebar-note hidden" id="sideNote-m365_m"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="14" height="14" fill="var(--green)" style="margin-right:6px;vertical-align:middle;flex-shrink:0;"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z"/></svg> Bundled M365 saves client up to <strong id="m365SaveAmt_m" style="color:var(--green);">—</strong>/mo vs retail licensing</div>
|
||
<div class="sidebar-note hidden" id="sideNote-byol_m"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="14" height="14" fill="var(--amber)" class="note-icon"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24V264c0 13.3-10.7 24-24 24s-24-10.7-24-24V152c0-13.3 10.7-24 24-24zm-32 224a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"/></svg> BYOL selected — client handles their own Microsoft or Google licensing</div>
|
||
|
||
<!-- VS Hiring In-House -->
|
||
<div id="vsComparison_m" class="hidden vs-comparison-wrap">
|
||
<div class="vs-label">VS. Hiring In-House</div>
|
||
<table class="vs-table">
|
||
<tr>
|
||
<td>
|
||
<svg width="14" height="14" viewBox="0 0 72 98" class="vs-inline-icon" xmlns="http://www.w3.org/2000/svg">
|
||
<polyline points="7.32 8.88 62.11 8.88 34.72 58.22" fill="#1f75a6"/>
|
||
<polyline points="40.7 55.33 64.4 12.64 71.88 12.64 44.48 61.99 40.7 55.33" fill="#8d252f"/>
|
||
</svg>
|
||
<span class="vs-svs-label">SVS MSP</span>
|
||
</td>
|
||
<td class="vs-val-accent" id="vs-svs-annual_m">—</td>
|
||
</tr>
|
||
<tr><td class="vs-td-muted"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="12" height="13" fill="currentColor" class="vs-td-icon"><path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3z"/></svg> 1 IT person + tools</td><td class="vs-td-muted" id="vs-1man-cost_m">—</td></tr>
|
||
<tr class="vs-save-row" id="vs-1man-save-row_m"><td><span id="vs-1man-save-lbl_m" class="vs-val-green">YOU SAVE</span></td><td id="vs-1man-save_m" class="vs-val-green">—</td></tr>
|
||
<tr><td class="vs-td-muted"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" width="14" height="13" fill="currentColor" class="vs-td-icon"><path d="M144 0a80 80 0 1 1 0 160A80 80 0 1 1 144 0zM512 0a80 80 0 1 1 0 160A80 80 0 1 1 512 0zM0 298.7C0 239.8 47.8 192 106.7 192h42.7c15.9 0 31 3.5 44.6 9.7c-1.3 7.2-1.9 14.7-1.9 22.3c0 38.2 16.8 72.5 43.3 96c-.2 0-.4 0-.7 0H21.3C9.6 320 0 310.4 0 298.7zM405.3 320c-.2 0-.4 0-.7 0c26.6-23.5 43.3-57.8 43.3-96c0-7.6-.7-15-1.9-22.3c13.6-6.3 28.7-9.7 44.6-9.7h42.7C592.2 192 640 239.8 640 298.7c0 11.8-9.6 21.3-21.3 21.3H405.3zM224 224a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zM128 485.3C128 411.7 187.7 352 261.3 352H378.7C452.3 352 512 411.7 512 485.3c0 14.7-11.9 26.7-26.7 26.7H154.7c-14.7 0-26.7-11.9-26.7-26.7z"/></svg> 5-person team</td><td class="vs-td-muted" id="vs-5man-cost_m">—</td></tr>
|
||
<tr class="vs-save-row" id="vs-5man-save-row_m"><td><span id="vs-5man-save-lbl_m" class="vs-val-green">YOU SAVE</span></td><td id="vs-5man-save_m" class="vs-val-green">—</td></tr>
|
||
</table>
|
||
<div class="vs-footnote" id="vs-footnote_m"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Nudge Banner -->
|
||
<div id="nudgeBanner_m" class="nudge-banner amber hidden">
|
||
<div class="nudge-header-row">
|
||
<span class="nudge-banner-label" style="margin-bottom:0;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" width="12" height="14" fill="currentColor" style="margin-right:6px;vertical-align:middle;"><path d="M272 384c9.6-31.9 29.5-59.1 49.2-86.2l0 0c5.2-7.1 10.4-14.2 15.4-21.4c19.8-28.5 31.4-63 31.4-100.3C368 78.8 289.2 0 192 0S16 78.8 16 176c0 37.3 11.6 71.9 31.4 100.3c5 7.2 10.2 14.3 15.4 21.4l0 0c19.8 27.1 39.7 54.4 49.2 86.2H272zM192 512c44.2 0 80-35.8 80-80V416H112v16c0 44.2 35.8 80 80 80zM112 352H272c0 0 0 0 0 0H112c0 0 0 0 0 0z"/></svg> Insight <span id="nudgeCounter_m" class="nudge-counter"></span></span>
|
||
<div class="nudge-nav-group">
|
||
<button onclick="cycleNudge(-1)" class="nudge-nav-btn" title="Previous"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg></button>
|
||
<button onclick="cycleNudge(1)" class="nudge-nav-btn" title="Next"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg></button>
|
||
</div>
|
||
</div>
|
||
<span id="nudgeText_m"></span>
|
||
</div>
|
||
|
||
<div class="export-wrap">
|
||
<button class="btn-export" onclick="printInvoice()">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="14" height="14" fill="currentColor" style="margin-right:7px;vertical-align:middle;"><path d="M128 0C92.7 0 64 28.7 64 64v96h64V64H354.7L384 93.3V160h64V93.3c0-17-6.7-33.3-18.7-45.3L400 18.7C388 6.7 371.7 0 354.7 0H128zM384 352v32 64H128V384 352H384zm64 32h32c17.7 0 32-14.3 32-32V256c0-35.3-28.7-64-64-64H64c-35.3 0-64 28.7-64 64v96c0 17.7 14.3 32 32 32H64v64c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V384zm-16-88a24 24 0 1 1 0 48 24 24 0 1 1 0-48z"/></svg>
|
||
Print / Save PDF
|
||
</button>
|
||
<button class="btn-export btn-export-secondary" onclick="exportQuoteJSON()">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" width="12" height="14" fill="currentColor" style="margin-right:7px;vertical-align:middle;"><path d="M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128h128L256 0zM216 232l-96 96 96 96 22.6-22.6L169.3 328l69.3-69.4L216 232zM168 232l-22.6 22.6 69.3 69.4-69.3 69.4L168 416l96-96-96-96z"/></svg>
|
||
Export JSON + Copy
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<!-- TOP BAR -->
|
||
<!-- ── TOP BAR ── sticky, z-index:100, cream bg (#ddd8d0) ──────── -->
|
||
<header class="top-bar">
|
||
<div class="top-bar-inner">
|
||
<svg class="top-bar-logo" height="32" viewBox="0 0 424.27 97.38" xmlns="http://www.w3.org/2000/svg">
|
||
<polyline points="7.32 8.88 62.11 8.88 34.72 58.22" fill="#1f75a6"/>
|
||
<polyline points="40.7 55.33 64.4 12.64 71.88 12.64 44.48 61.99 40.7 55.33" fill="#8d252f"/>
|
||
<path d="M110.03,89.91c-5.99,0-11.27-.66-15.86-1.99-4.59-1.33-8.6-3.2-12.05-5.63-3.45-2.42-6.54-5.27-9.27-8.53l14.21-15.92c3.79,4.85,7.75,8.05,11.88,9.61,4.13,1.55,8.01,2.33,11.65,2.33,1.44,0,2.73-.13,3.87-.4,1.14-.26,2.01-.7,2.62-1.31.61-.61.91-1.44.91-2.5,0-.98-.32-1.82-.97-2.5-.65-.68-1.5-1.27-2.56-1.76-1.06-.49-2.22-.91-3.47-1.25-1.25-.34-2.46-.62-3.64-.85-1.18-.23-2.22-.46-3.13-.68-4.55-1.06-8.53-2.35-11.94-3.87-3.41-1.51-6.25-3.33-8.53-5.46-2.27-2.12-3.96-4.55-5.06-7.28-1.1-2.73-1.65-5.8-1.65-9.21,0-3.87.89-7.39,2.67-10.57,1.78-3.18,4.17-5.91,7.16-8.19,2.99-2.27,6.4-4.02,10.23-5.23,3.83-1.21,7.79-1.82,11.88-1.82,5.99,0,10.99.55,15.01,1.65,4.02,1.1,7.39,2.67,10.12,4.72,2.73,2.05,5.08,4.43,7.05,7.16l-14.32,13.76c-1.67-1.59-3.41-2.9-5.23-3.92-1.82-1.02-3.7-1.78-5.63-2.27-1.93-.49-3.85-.74-5.74-.74-1.74,0-3.22.13-4.43.4-1.21.27-2.16.68-2.84,1.25-.68.57-1.02,1.35-1.02,2.33s.43,1.8,1.31,2.44c.87.64,1.97,1.19,3.3,1.65,1.32.46,2.65.82,3.98,1.08,1.33.27,2.44.47,3.35.62,4.17.76,8,1.8,11.48,3.13,3.49,1.33,6.54,3,9.15,5,2.61,2.01,4.62,4.51,6.03,7.5,1.4,3,2.1,6.54,2.1,10.63,0,5.84-1.46,10.73-4.38,14.67-2.92,3.94-6.84,6.92-11.77,8.92-4.93,2.01-10.42,3.01-16.48,3.01Z" fill="#0c0c0c"/>
|
||
<path d="M174.27,88.77l-31.72-79.58h24.56l12.73,34.79c.91,2.35,1.65,4.36,2.22,6.03.57,1.67,1.08,3.24,1.54,4.72.46,1.48.89,3.05,1.31,4.72.42,1.67.89,3.71,1.42,6.14h-3.98c.76-3.18,1.42-5.8,1.99-7.84.57-2.05,1.21-4.07,1.93-6.08.72-2.01,1.65-4.56,2.79-7.67l12.73-34.79h23.76l-31.95,79.58h-19.33Z" fill="#0c0c0c"/>
|
||
<path d="M257.94,89.91c-5.99,0-11.27-.66-15.86-1.99-4.59-1.33-8.6-3.2-12.05-5.63-3.45-2.42-6.54-5.27-9.27-8.53l14.21-15.92c3.79,4.85,7.75,8.05,11.88,9.61,4.13,1.55,8.02,2.33,11.65,2.33,1.44,0,2.73-.13,3.87-.4,1.14-.26,2.01-.7,2.62-1.31.61-.61.91-1.44.91-2.5,0-.98-.32-1.82-.97-2.5-.64-.68-1.5-1.27-2.56-1.76-1.06-.49-2.22-.91-3.47-1.25-1.25-.34-2.46-.62-3.64-.85-1.18-.23-2.22-.46-3.13-.68-4.55-1.06-8.53-2.35-11.94-3.87-3.41-1.51-6.25-3.33-8.53-5.46-2.27-2.12-3.96-4.55-5.06-7.28-1.1-2.73-1.65-5.8-1.65-9.21,0-3.87.89-7.39,2.67-10.57,1.78-3.18,4.17-5.91,7.16-8.19,2.99-2.27,6.4-4.02,10.23-5.23,3.83-1.21,7.79-1.82,11.88-1.82,5.99,0,10.99.55,15.01,1.65,4.02,1.1,7.39,2.67,10.12,4.72,2.73,2.05,5.08,4.43,7.05,7.16l-14.33,13.76c-1.67-1.59-3.41-2.9-5.23-3.92-1.82-1.02-3.69-1.78-5.63-2.27-1.93-.49-3.85-.74-5.74-.74-1.74,0-3.22.13-4.43.4-1.21.27-2.16.68-2.84,1.25-.68.57-1.02,1.35-1.02,2.33s.44,1.8,1.31,2.44c.87.64,1.97,1.19,3.3,1.65,1.33.46,2.65.82,3.98,1.08,1.33.27,2.44.47,3.35.62,4.17.76,8,1.8,11.48,3.13,3.49,1.33,6.54,3,9.15,5,2.62,2.01,4.62,4.51,6.03,7.5,1.4,3,2.1,6.54,2.1,10.63,0,5.84-1.46,10.73-4.38,14.67-2.92,3.94-6.84,6.92-11.77,8.92-4.93,2.01-10.42,3.01-16.48,3.01Z" fill="#0c0c0c"/>
|
||
<path d="M300.67,47.36V8.02h10.45l14.33,23.33-8.49-.06,14.5-23.27h10.12v39.35h-11.69v-9.39c0-3.37.08-6.41.25-9.11.17-2.7.46-5.38.87-8.04l1.35,3.54-9.5,14.73h-3.71l-9.33-14.73,1.41-3.54c.41,2.51.7,5.09.87,7.73.17,2.64.25,5.78.25,9.42v9.39h-11.69Z" fill="#0c0c0c"/>
|
||
<path d="M364.36,47.93c-2.96,0-5.57-.33-7.84-.98-2.27-.66-4.25-1.58-5.96-2.78-1.71-1.2-3.23-2.6-4.58-4.22l7.03-7.87c1.87,2.4,3.83,3.98,5.87,4.75,2.04.77,3.96,1.15,5.76,1.15.71,0,1.35-.07,1.91-.2.56-.13.99-.35,1.29-.65.3-.3.45-.71.45-1.24,0-.49-.16-.9-.48-1.24s-.74-.63-1.26-.87c-.53-.24-1.1-.45-1.71-.62-.62-.17-1.22-.31-1.8-.42-.58-.11-1.1-.22-1.55-.34-2.25-.52-4.22-1.16-5.9-1.91-1.69-.75-3.09-1.65-4.22-2.7-1.12-1.05-1.96-2.25-2.5-3.6-.54-1.35-.81-2.87-.81-4.55,0-1.91.44-3.65,1.32-5.23.88-1.57,2.06-2.92,3.54-4.05s3.17-1.99,5.06-2.58,3.85-.9,5.87-.9c2.96,0,5.43.27,7.42.81,1.99.54,3.65,1.32,5,2.33,1.35,1.01,2.51,2.19,3.49,3.54l-7.08,6.8c-.83-.79-1.69-1.43-2.59-1.94s-1.83-.88-2.78-1.12c-.96-.24-1.9-.37-2.84-.37-.86,0-1.59.07-2.19.2-.6.13-1.07.34-1.41.62-.34.28-.51.67-.51,1.15s.21.89.65,1.21c.43.32.97.59,1.63.82.66.22,1.31.4,1.97.53.66.13,1.21.23,1.66.31,2.06.38,3.95.89,5.68,1.55,1.72.66,3.23,1.48,4.53,2.47s2.29,2.23,2.98,3.71c.69,1.48,1.04,3.23,1.04,5.26,0,2.89-.72,5.3-2.16,7.25-1.44,1.95-3.38,3.42-5.82,4.41-2.44.99-5.15,1.49-8.15,1.49Z" fill="#0c0c0c"/>
|
||
<path d="M386.61,47.36V8.02h17.71c2.7,0,5.1.58,7.2,1.74,2.1,1.16,3.75,2.75,4.95,4.78,1.2,2.02,1.8,4.35,1.8,6.97s-.6,5.17-1.8,7.31c-1.2,2.14-2.85,3.81-4.95,5.03-2.1,1.22-4.5,1.83-7.2,1.83h-5.56v11.69h-12.14ZM398.53,25.33h3.54c.71,0,1.35-.14,1.91-.42.56-.28,1-.68,1.32-1.21.32-.52.48-1.18.48-1.97s-.16-1.42-.48-1.91c-.32-.49-.76-.85-1.32-1.1-.56-.24-1.2-.37-1.91-.37h-3.54v6.97Z" fill="#0c0c0c"/>
|
||
</svg>
|
||
<button id="themeToggle" class="theme-toggle-btn" onclick="toggleTheme()" aria-label="Toggle light/dark theme" title="Switch to light theme">
|
||
<span id="themeToggleIcon"><svg xmlns="http://www.w3.org/2000/svg" width="17" height="17" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="5"/><line x1="12" y1="1" x2="12" y2="3"/><line x1="12" y1="21" x2="12" y2="23"/><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"/><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"/><line x1="1" y1="12" x2="3" y2="12"/><line x1="21" y1="12" x2="23" y2="12"/><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"/><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"/></svg></span>
|
||
</button>
|
||
<div class="top-bar-right">
|
||
<span id="quoteRef">SVS-00000000-0000</span><br>
|
||
<span id="headerDate">—</span>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- ── MAIN LAYOUT GRID: 3fr main-col | 2fr side-col ────────────── -->
|
||
<div class="outer">
|
||
<!-- ── LEFT COLUMN: sections I–VI + client bar ──────────────────── -->
|
||
<div class="main-col">
|
||
|
||
<!-- CLIENT BAR -->
|
||
<div class="client-bar">
|
||
<div class="client-label">Prepared for</div>
|
||
<input class="client-input" id="clientName" type="text" placeholder="Client Name" oninput="update()">
|
||
</div>
|
||
|
||
<!-- ── QUOTE SETTINGS BAR ────────────────────────────────────────
|
||
Contract term toggle (3-way) and onboarding fee.
|
||
Contract term drives discountPct in calcQuote().
|
||
HST toggle shows/hides the +13% line in the sidebar.
|
||
One-time fee is included in JSON export but NOT in MRR.
|
||
──────────────────────────────────────────────────────────────── -->
|
||
<div class="quote-settings-bar">
|
||
<div class="qs-group">
|
||
<div class="qs-label">Contract Term</div>
|
||
<div class="tier-seg-wrap qs-term-wrap">
|
||
<input type="radio" name="contractTerm" id="termM2m" value="m2m" checked onchange="update()">
|
||
<label for="termM2m" class="tier-seg" id="seg-term-m2m">
|
||
<div class="tier-name">Month-to-Month</div>
|
||
<div class="tier-sub">No discount</div>
|
||
</label>
|
||
<input type="radio" name="contractTerm" id="term12mo" value="12mo" onchange="update()">
|
||
<label for="term12mo" class="tier-seg" id="seg-term-12mo">
|
||
<div class="tier-name">12-Month</div>
|
||
<div class="tier-sub">3% off MRR</div>
|
||
</label>
|
||
<input type="radio" name="contractTerm" id="term24mo" value="24mo" onchange="update()">
|
||
<label for="term24mo" class="tier-seg" id="seg-term-24mo">
|
||
<div class="tier-name">24-Month</div>
|
||
<div class="tier-sub">5% off MRR</div>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="qs-right">
|
||
<div class="qs-fee-row">
|
||
<div class="qs-fee-header">
|
||
<label class="qs-fee-label" for="oneTimeFee">Onboarding Fee</label>
|
||
<label class="qs-toggle-row qs-fee-waive">
|
||
<input type="checkbox" id="onboardingWaived" onchange="this.closest('.qs-fee-row').querySelector('#oneTimeFee').removeAttribute('data-manual'); update();">
|
||
<span class="qs-toggle-label">Waive</span>
|
||
</label>
|
||
</div>
|
||
<div class="qs-fee-input-wrap">
|
||
<span class="qs-fee-dollar">$</span>
|
||
<input type="number" id="oneTimeFee" class="qs-fee-input" min="0" placeholder="auto" oninput="this.dataset.manual='1'; update();">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ────────────────────────────────────────────────────────────
|
||
SECTION I — SITE ADMIN FEE
|
||
id="sec-01" sec-open = starts expanded
|
||
#adminFeeDisplay — rendered by update() → fmt(adminFeeNet)
|
||
#floorBar — progress bar width%, turns green at 100%
|
||
#floorProgress — "$X / $650" text label
|
||
#floorNote — threshold status message
|
||
#fb-base — siteAdminBase value
|
||
#fb-zt-row — hidden unless ztActive
|
||
#fb-pwm-row — hidden unless addPWM
|
||
#fb-total — adminFeeNet total
|
||
#sec01-summary — badge shown when section collapsed
|
||
──────────────────────────────────────────────────────────────── -->
|
||
<div class="section sec-open" id="sec-01">
|
||
<div class="section-header section-toggle" onclick="toggleSection('sec-01')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleSection('sec-01');event.preventDefault();}">
|
||
<div class="section-num">I</div>
|
||
<div class="section-title-block">
|
||
<div class="section-title">Environment Management Site Admin Fee</div>
|
||
<div class="section-subtitle">Flat monthly fee covering tenant, network, documentation & vendor management</div>
|
||
<span class="section-badge">Flat Monthly / Environment</span>
|
||
</div>
|
||
<span id="sec01-summary" class="sec-summary-badge"></span>
|
||
<div class="sec-chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></div>
|
||
</div>
|
||
<div class="section-body" id="sec-01-body">
|
||
<div class="section-content">
|
||
|
||
<div class="admin-fee-header">
|
||
<span class="admin-fee-title">Site Admin Fee</span>
|
||
<span id="adminFeeDisplay" class="admin-fee-val">$150/mo</span>
|
||
</div>
|
||
<div class="admin-fee-sub">Calculated from services below · floor $150/mo</div>
|
||
|
||
<div class="progress-wrap">
|
||
<div class="progress-label">
|
||
<span>Minimum Engagement Threshold</span>
|
||
<span id="floorProgress">$0 / $650</span>
|
||
</div>
|
||
<div class="progress-track">
|
||
<div class="progress-fill" id="floorBar" style="width:0%"></div>
|
||
</div>
|
||
</div>
|
||
<div id="floorNote" class="floor-note"></div>
|
||
|
||
<table class="fee-table" id="feeBreakdown">
|
||
<tr><td>Base Site Admin</td><td id="fb-base">—</td></tr>
|
||
<tr id="fb-zt-row" class="hidden"><td>Zero Trust Supplement</td><td id="fb-zt">+$250</td></tr>
|
||
<tr id="fb-pwm-row" class="hidden"><td>1Password Admin (10%)</td><td id="fb-pwm">—</td></tr>
|
||
<tr class="fee-total"><td>Total Admin Fee</td><td id="fb-total">—</td></tr>
|
||
</table>
|
||
|
||
<!-- What's Covered collapsible -->
|
||
<div class="collapsible-header collapsible-header--mt16" onclick="toggleCollapsible('adminCovered')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleCollapsible('adminCovered');event.preventDefault();}">
|
||
<span class="collapsible-toggle" id="adminCovered-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span>
|
||
<span class="collapsible-label">What's Covered by the Admin Fee</span>
|
||
</div>
|
||
<div class="collapsible-body" id="adminCovered">
|
||
<div class="feature-card-grid">
|
||
<div class="feature-card"><div class="feature-card-title"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" width="16" height="16" fill="var(--accent)" style="margin-right:8px;flex-shrink:0;vertical-align:middle;"><path d="M96 0C43 0 0 43 0 96V416c0 53 43 96 96 96H344.2c-1.5-9.5-2.2-19.2-2.2-29.1V384H96c-17.7 0-32-14.3-32-32V96c0-17.7 14.3-32 32-32H416c17.7 0 32 14.3 32 32v84.2c19.4 6.7 37.3 17.3 52.9 30.6c5.3-2.7 11.3-4.8 17.1-4.8c23.7 0 42.9 19.2 42.9 42.9V272c16.8 10.4 32 23.4 44.8 38.8V176c0-53-43-96-96-96H416V96c0-53-43-96-96-96H96zM224 320a64 64 0 1 1 128 0 64 64 0 1 1 -128 0zm-32 64h192c17.7 0 32 14.3 32 32v32H160V416c0-17.7 14.3-32 32-32zM128 176c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H144c-8.8 0-16-7.2-16-16V176zm0 96c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H144c-8.8 0-16-7.2-16-16V272zm128-96c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V176zm0 96c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V272zm128-96c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H384c-8.8 0-16-7.2-16-16V176zM496 512a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm0-96a48 48 0 1 1 0-96 48 48 0 1 1 0 96z"/></svg> Tenant & Identity Management</div><div class="feature-card-desc">Microsoft 365 / Entra ID tenant administration, user lifecycle, MFA enforcement, and conditional access policies.</div></div>
|
||
<div class="feature-card"><div class="feature-card-title"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" width="16" height="16" fill="var(--accent)" style="margin-right:8px;flex-shrink:0;vertical-align:middle;"><path d="M256 64H384v64H256V64zM240 0c-26.5 0-48 21.5-48 48v96c0 26.5 21.5 48 48 48h48v32H32c-17.7 0-32 14.3-32 32s14.3 32 32 32h176v32H160c-26.5 0-48 21.5-48 48v96c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V368c0-26.5-21.5-48-48-48H240V288H400v32H352c-26.5 0-48 21.5-48 48v96c0 26.5 21.5 48 48 48h128c26.5 0 48-21.5 48-48V368c0-26.5-21.5-48-48-48H432V288H608c17.7 0 32-14.3 32-32s-14.3-32-32-32H352V192h48c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48H240zM192 400H288v64H192V400zm256 0H544v64H448V400z"/></svg> Network & Infrastructure Oversight</div><div class="feature-card-desc">Firewall configuration reviews, DNS management, VLAN segmentation oversight, and network performance monitoring.</div></div>
|
||
<div class="feature-card"><div class="feature-card-title"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" width="14" height="16" fill="var(--accent)" style="margin-right:8px;flex-shrink:0;vertical-align:middle;"><path d="M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128h128L256 0zM112 256H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16zm0 64H272c8.8 0 16 7.2 16 16s-7.2 16-16 16H112c-8.8 0-16-7.2-16-16s7.2-16 16-16z"/></svg> Documentation & Runbooks</div><div class="feature-card-desc">Living IT documentation, network diagrams, asset registers, and runbooks updated continuously in your client portal.</div></div>
|
||
<div class="feature-card"><div class="feature-card-title"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" width="16" height="16" fill="var(--accent)" style="margin-right:8px;flex-shrink:0;vertical-align:middle;"><path d="M272.2 64.6l-51.1 51.1c-15.3 4.2-29.5 11.9-41.5 22.5L153 161.9C142.8 171 129.5 176 115.8 176H96V304c20.4 5.3 38.7 16.3 52.9 31.4l168.9 182.6c6.5 7 15.9 10.9 25.8 10.1C367.9 525.1 384 507.5 384 486.2v-25.9l-.1 .1c-16.4 16.4-43 16.4-59.4 0L234.5 370.5c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L370.1 415.5 416 369.6V316.3c0-18 7.2-35.3 19.9-48l38.1-38.1c-19.7-13.3-41.9-22.5-65.8-26.2l-42.8-6.8c-11.1-1.8-22.4-2.8-33.9-2.8c-19.7 0-38.9 2.8-57.2 7.8l-31.1-31.1c12.7-5.4 26.5-8.3 40.8-7.9C299 163.1 321 170 340 182l92.4-92.4C409.3 72.4 380.8 64 350.4 64c-27.8 0-54.7 8.3-77.8 23.1l-.4-22.5zM544 200.9c19.4 26.9 30.8 59.8 30.8 95.5c0 14.7-1.8 29.1-5.3 42.8l28.6 28.6c6.2 6.2 9.7 14.6 9.7 23.4V512h-96V461.3L412 358.3c-7.9-7.9-7.9-20.7 0-28.6l10.7-10.7 25.8-25.8c3.9-3.9 9.1-6.1 14.6-6.1H496c8.8 0 16-7.2 16-16V240c0-8.8-7.2-16-16-16H464.4l-53.5-53.5C428.6 164.4 452 160 476.8 160c24.2 0 47.5 5.4 67.2 14.9V200.9zM96 160H64c-17.7 0-32 14.3-32 32V448c0 17.7 14.3 32 32 32H96c17.7 0 32-14.3 32-32V192c0-17.7-14.3-32-32-32z"/></svg> Vendor Management</div><div class="feature-card-desc">Single point of contact for all technology vendors — ISPs, software, hardware, and cloud providers.</div></div>
|
||
<div class="feature-card"><div class="feature-card-title"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="14" height="16" fill="var(--accent)" style="margin-right:8px;flex-shrink:0;vertical-align:middle;"><path d="M256 0c4.6 0 9.2 1 13.4 2.9L457.7 82.8c22 9.3 38.4 31 38.3 57.2c-.5 99.2-41.3 280.7-213.6 363.2c-16.7 8-36.1 8-52.8 0C57.3 420.7 16.5 239.2 16 140c-.1-26.2 16.3-47.9 38.3-57.2L242.7 2.9C246.8 1 251.4 0 256 0zm0 66.8V444.8C394 378 431.1 230.1 432 141.4L256 66.8z"/></svg> Security Posture Management</div><div class="feature-card-desc">Monthly security reviews, vulnerability scan oversight, patch compliance reporting, and security baseline enforcement.</div></div>
|
||
<div class="feature-card"><div class="feature-card-title"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="16" height="16" fill="var(--accent)" style="margin-right:8px;flex-shrink:0;vertical-align:middle;"><path d="M32 32c17.7 0 32 14.3 32 32V400c0 8.8 7.2 16 16 16H480c17.7 0 32 14.3 32 32s-14.3 32-32 32H80c-44.2 0-80-35.8-80-80V64C0 46.3 14.3 32 32 32zm96 96c0-17.7 14.3-32 32-32l192 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-192 0c-17.7 0-32-14.3-32-32zm32 64H288c17.7 0 32 14.3 32 32s-14.3 32-32 32H160c-17.7 0-32-14.3-32-32s14.3-32 32-32zm0 96H352c17.7 0 32 14.3 32 32s-14.3 32-32 32H160c-17.7 0-32-14.3-32-32s14.3-32 32-32z"/></svg> Reporting & QBRs</div><div class="feature-card-desc">Monthly infrastructure health reports, ticket trend analysis, and quarterly business reviews with your account manager.</div></div>
|
||
<div class="feature-card"><div class="feature-card-title"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" width="18" height="16" fill="var(--accent)" style="margin-right:8px;flex-shrink:0;vertical-align:middle;"><path d="M0 336c0 79.5 64.5 144 144 144H512c70.7 0 128-57.3 128-128c0-61.9-44-113.6-102.4-125.4c4.1-10.7 6.4-22.4 6.4-34.6c0-53-43-96-96-96c-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32C167.6 32 96 103.6 96 192c0 2.7 .1 5.4 .2 8.1C40.2 219.8 0 273.2 0 336z"/></svg> Cloud Governance</div><div class="feature-card-desc">License optimization, cloud spend visibility, Microsoft Secure Score improvement, and policy compliance alignment.</div></div>
|
||
<div class="feature-card"><div class="feature-card-title"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="16" height="16" fill="var(--accent)" style="margin-right:8px;flex-shrink:0;vertical-align:middle;"><path d="M256 32c14.2 0 27.3 7.5 34.5 19.8l216 368c7.3 12.4 7.3 27.7 .2 40.1S486.3 480 472 480H40c-14.3 0-27.6-7.7-34.7-20.1s-7-27.8 .2-40.1l216-368C228.7 39.5 241.8 32 256 32zm0 128c-13.3 0-24 10.7-24 24V296c0 13.3 10.7 24 24 24s24-10.7 24-24V184c0-13.3-10.7-24-24-24zm32 224a32 32 0 1 0 -64 0 32 32 0 1 0 64 0z"/></svg> Incident Coordination</div><div class="feature-card-desc">Major incident management, root cause analysis, and coordinated response across all your managed services.</div></div>
|
||
<div class="feature-card"><div class="feature-card-title"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" width="18" height="16" fill="var(--accent)" style="margin-right:8px;flex-shrink:0;vertical-align:middle;"><path d="M0 80C0 53.5 21.5 32 48 32h96c26.5 0 48 21.5 48 48V96H384V80c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v96c0 26.5-21.5 48-48 48H432c-26.5 0-48-21.5-48-48v-16H192v16c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V80zM48 336H144V320c0-26.5 21.5-48 48-48H384c26.5 0 48 21.5 48 48v16h96c26.5 0 48 21.5 48 48v96c0 26.5-21.5 48-48 48H432c-26.5 0-48-21.5-48-48V416H192v16c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V384c0-26.5 21.5-48 48-48z"/></svg> Backup Monitoring</div><div class="feature-card-desc">Daily backup job verification, restore testing schedules, retention compliance checks, and failure alerting — separate from the Bare Metal Backup add-on.</div></div>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ────────────────────────────────────────────────────────────
|
||
SECTION II — USER PACKAGE
|
||
#rateM365 / #rateBYOL — radio inputs, read by calcQuote()
|
||
#byolCalloutGreen — shown when M365 selected (byol=false)
|
||
#byolCalloutRed — shown when BYOL selected (byol=true)
|
||
#byolRedSavings — dynamic savings $ inside red callout
|
||
#userCount — number input → users in calcQuote()
|
||
Add-ons: #addExtHours #addPWM #addINKY #addZT (checkboxes)
|
||
Row highlights: #row-ext #row-pwm #row-inky #row-zt
|
||
#sec02-summary — badge shown when collapsed
|
||
──────────────────────────────────────────────────────────────── -->
|
||
<div class="section sec-open" id="sec-02">
|
||
<div class="section-header section-toggle" onclick="toggleSection('sec-02')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleSection('sec-02');event.preventDefault();}">
|
||
<div class="section-num">II</div>
|
||
<div class="section-title-block">
|
||
<div class="section-title">User Package</div>
|
||
<div class="section-subtitle">Per-user monthly services — identity, email, security & helpdesk</div>
|
||
<span class="section-badge">Per User / Month</span>
|
||
</div>
|
||
<span id="sec02-summary" class="sec-summary-badge"></span>
|
||
<div class="sec-chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></div>
|
||
</div>
|
||
<div class="section-body" id="sec-02-body">
|
||
<div class="section-content">
|
||
|
||
<!-- Base Rate Toggle -->
|
||
<div class="pill-toggle">
|
||
<input type="radio" name="baseRate" id="rateM365" value="m365" checked onchange="update()">
|
||
<label for="rateM365">
|
||
<span class="pill-price">$130<small>/user/mo</small></span>
|
||
<span class="pill-desc">M365 Included — Identity, Email & Business Protection</span>
|
||
</label>
|
||
<input type="radio" name="baseRate" id="rateBYOL" value="byol" onchange="update()">
|
||
<label for="rateBYOL">
|
||
<span class="pill-price">$110<small>/user/mo</small></span>
|
||
<span class="pill-desc">BYOL — Bring Your Own License (M365 or Google Workspace)</span>
|
||
</label>
|
||
</div>
|
||
|
||
<div id="byolCalloutGreen" class="callout-green">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="14" height="14" fill="var(--green)" style="flex-shrink:0;margin-top:2px;"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z"/></svg><span>Bundled M365 Business Premium saves up to $15/user/mo vs buying retail — runs ~$29–36/mo CAD on its own</span>
|
||
</div>
|
||
<div id="byolCalloutRed" class="callout-red hidden">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="14" height="14" fill="#e06070" style="flex-shrink:0;margin-top:2px;"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24V264c0 13.3-10.7 24-24 24s-24-10.7-24-24V152c0-13.3 10.7-24 24-24zm-32 224a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"/></svg><span>Missed saving — switching to M365 Business Premium would save <span id="byolRedSavings">$150</span>/mo across your team vs retail pricing</span>
|
||
</div>
|
||
|
||
<!-- What's Included collapsible -->
|
||
<div class="collapsible-header" onclick="toggleCollapsible('userIncluded')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleCollapsible('userIncluded');event.preventDefault();}">
|
||
<span class="collapsible-toggle" id="userIncluded-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span>
|
||
<span class="collapsible-label">What's Included in This Package</span>
|
||
</div>
|
||
<div class="collapsible-body" id="userIncluded">
|
||
<ul class="feature-list">
|
||
<li>Microsoft 365 Business Premium (M365 tier) — Word, Excel, PowerPoint, Teams, Exchange</li>
|
||
<li>Entra ID & MFA — identity protection, conditional access, and SSO</li>
|
||
<li>Microsoft Defender for Business — endpoint + email threat protection</li>
|
||
<li>Helpdesk support (business hours) — tickets, remote sessions, escalations</li>
|
||
<li>Onboarding & offboarding — provisioning, access revocation, equipment checklists</li>
|
||
<li>Security awareness training (SAT) — phishing simulations & training modules</li>
|
||
<li>User-level documentation — accounts, devices, access tracked per user</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="input-row">
|
||
<div>
|
||
<div class="input-label">Number of Users</div>
|
||
</div>
|
||
<div class="num-stepper">
|
||
<button class="step-btn" onclick="stepInput('userCount',-1)">−</button>
|
||
<input class="num-input" id="userCount" type="number" min="0" value="1" oninput="update()">
|
||
<button class="step-btn" onclick="stepInput('userCount',1)">+</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Per-User Add-Ons collapsible -->
|
||
<div class="collapsible-header collapsible-header--addon" onclick="toggleCollapsible('addonsA')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleCollapsible('addonsA');event.preventDefault();}">
|
||
<span class="collapsible-toggle" id="addonsA-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span>
|
||
<span class="collapsible-label">Per-User Add-Ons</span>
|
||
<div id="addonsA-preview" class="addon-preview-wrap">
|
||
<span class="addon-preview-pill">Extended Hours</span>
|
||
<span class="addon-preview-pill">1Password</span>
|
||
<span class="addon-preview-pill">INKY Pro</span>
|
||
<span class="addon-preview-pill">Zero Trust</span>
|
||
</div>
|
||
</div>
|
||
<div class="collapsible-body" id="addonsA">
|
||
<div class="addon-grid">
|
||
<label class="addon-row" id="row-ext" onclick="toggleAddon('addExtHours','row-ext');update()">
|
||
<input type="checkbox" id="addExtHours">
|
||
<div><div class="addon-name">Extended Help Desk Hours</div><div class="addon-desc">8am–8pm Mon–Fri coverage via staggered shifts</div></div>
|
||
<span class="addon-price">+$25/user/mo</span>
|
||
</label>
|
||
<label class="addon-row" id="row-pwm" onclick="toggleAddon('addPWM','row-pwm');update()">
|
||
<input type="checkbox" id="addPWM">
|
||
<div><div class="addon-name">1Password Management</div><div class="addon-desc">Business password vault, admin console & SSO integration</div></div>
|
||
<span class="addon-price">+$9/user/mo</span>
|
||
</label>
|
||
<label class="addon-row" id="row-inky" onclick="toggleAddon('addINKY','row-inky');update()">
|
||
<input type="checkbox" id="addINKY">
|
||
<div><div class="addon-name">INKY Pro Email Security</div><div class="addon-desc">AI-powered phishing protection & email authentication layer</div></div>
|
||
<span class="addon-price">+$5/user/mo</span>
|
||
</label>
|
||
<label class="addon-row" id="row-zt" onclick="toggleAddon('addZT','row-zt');update()">
|
||
<input type="checkbox" id="addZT">
|
||
<div><div class="addon-name">Zero Trust User Seat</div><div class="addon-desc">Cytracom ZT identity-aware access — deny by default network control</div></div>
|
||
<span class="addon-price">+$55/user/mo</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ────────────────────────────────────────────────────────────
|
||
SECTION III — ENDPOINT PACKAGE
|
||
#endpointCount — number input → endpoints in calcQuote()
|
||
Add-ons: #addBMB (+$25/endpoint) #addUSB (+$4/endpoint)
|
||
Row highlights: #row-bmb #row-usb
|
||
#sec03-summary — badge shown when collapsed
|
||
──────────────────────────────────────────────────────────────── -->
|
||
<div class="section sec-open" id="sec-03">
|
||
<div class="section-header section-toggle" onclick="toggleSection('sec-03')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleSection('sec-03');event.preventDefault();}">
|
||
<div class="section-num">III</div>
|
||
<div class="section-title-block">
|
||
<div class="section-title">Endpoint Package</div>
|
||
<div class="section-subtitle">Per-device managed protection — workstations & laptops</div>
|
||
<span class="section-badge">$35 / Endpoint / Month</span>
|
||
</div>
|
||
<span id="sec03-summary" class="sec-summary-badge"></span>
|
||
<div class="sec-chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></div>
|
||
</div>
|
||
<div class="section-body" id="sec-03-body">
|
||
<div class="section-content">
|
||
|
||
<!-- What's Included collapsible -->
|
||
<div class="collapsible-header" onclick="toggleCollapsible('endpointIncluded')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleCollapsible('endpointIncluded');event.preventDefault();}">
|
||
<span class="collapsible-toggle" id="endpointIncluded-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span>
|
||
<span class="collapsible-label">What's Included in This Package</span>
|
||
</div>
|
||
<div class="collapsible-body" id="endpointIncluded">
|
||
<ul class="feature-list">
|
||
<li>RMM agent — remote monitoring, patching & automated remediation</li>
|
||
<li>Huntress EDR — 24/7 SOC-backed threat hunting & incident response</li>
|
||
<li>Patch management — OS & third-party software, tested & staged rollouts</li>
|
||
<li>Disk encryption enforcement — BitLocker management & key escrow</li>
|
||
<li>Asset inventory — hardware specs, software, warranties tracked per device</li>
|
||
<li>Cyber warranty — up to $1M coverage backed by our toolstack compliance</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="input-row">
|
||
<div>
|
||
<div class="input-label">Number of Endpoints</div>
|
||
<div class="input-sublabel">Workstations, laptops — per managed device</div>
|
||
</div>
|
||
<div class="num-stepper">
|
||
<button class="step-btn" onclick="stepInput('endpointCount',-1)">−</button>
|
||
<input class="num-input" id="endpointCount" type="number" min="0" value="1" oninput="update()">
|
||
<button class="step-btn" onclick="stepInput('endpointCount',1)">+</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Per-Endpoint Add-Ons collapsible -->
|
||
<div class="collapsible-header collapsible-header--addon" onclick="toggleCollapsible('addonsB')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleCollapsible('addonsB');event.preventDefault();}">
|
||
<span class="collapsible-toggle" id="addonsB-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span>
|
||
<span class="collapsible-label">Per-Endpoint Add-Ons</span>
|
||
<div id="addonsB-preview" class="addon-preview-wrap">
|
||
<span class="addon-preview-pill">Bare Metal Backup</span>
|
||
<span class="addon-preview-pill">USB Blocking</span>
|
||
</div>
|
||
</div>
|
||
<div class="collapsible-body" id="addonsB">
|
||
<div class="addon-grid">
|
||
<label class="addon-row" id="row-bmb" onclick="toggleAddon('addBMB','row-bmb');update()">
|
||
<input type="checkbox" id="addBMB">
|
||
<div><div class="addon-name">Bare Metal Backup</div><div class="addon-desc">Image-based backup with bare metal restore — local & cloud retention</div></div>
|
||
<span class="addon-price">+$25/endpoint/mo</span>
|
||
</label>
|
||
<label class="addon-row" id="row-usb" onclick="toggleAddon('addUSB','row-usb');update()">
|
||
<input type="checkbox" id="addUSB">
|
||
<div><div class="addon-name">USB Device Blocking</div><div class="addon-desc">Policy-enforced USB control — block unauthorized removable media</div></div>
|
||
<span class="addon-price">+$4/endpoint/mo</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ────────────────────────────────────────────────────────────
|
||
SECTION IV — SERVER MANAGEMENT
|
||
Starts COLLAPSED (no sec-open class, body display:none)
|
||
#serverCount — number input → servers in calcQuote()
|
||
Rate: $120/server/mo (serverBase = servers * 120)
|
||
Counted in baseSubtotal → affects admin fee threshold
|
||
#sec04-summary — badge shown when collapsed
|
||
──────────────────────────────────────────────────────────────── -->
|
||
<div class="section" id="sec-04">
|
||
<div class="section-header section-toggle" onclick="toggleSection('sec-04')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleSection('sec-04');event.preventDefault();}">
|
||
<div class="section-num">IV</div>
|
||
<div class="section-title-block">
|
||
<div class="section-title">Server Management</div>
|
||
<div class="section-subtitle">Dedicated management for physical & virtual servers</div>
|
||
<span class="section-badge">$120 / Server / Month</span>
|
||
</div>
|
||
<span id="sec04-summary" class="sec-summary-badge"></span>
|
||
<div class="sec-chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></div>
|
||
</div>
|
||
<div class="section-body" id="sec-04-body" style="display:none;">
|
||
<div class="section-content">
|
||
|
||
<div class="collapsible-header" onclick="toggleCollapsible('serverIncluded')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleCollapsible('serverIncluded');event.preventDefault();}">
|
||
<span class="collapsible-toggle" id="serverIncluded-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span>
|
||
<span class="collapsible-label">What's Included in Server Management</span>
|
||
</div>
|
||
<div class="collapsible-body" id="serverIncluded">
|
||
<ul class="feature-list">
|
||
<li>RMM monitoring — CPU, RAM, disk, services & event log alerting</li>
|
||
<li>OS patch management — Windows Server updates, tested & scheduled</li>
|
||
<li>Role & service management — AD, DNS, DHCP, file shares, print services</li>
|
||
<li>Performance baselines — capacity planning & proactive alerting</li>
|
||
<li>Backup monitoring — verify, test restores & retention compliance</li>
|
||
<li>Security hardening — CIS benchmarks, local admin control, audit logging</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<div class="input-row">
|
||
<div>
|
||
<div class="input-label">Number of Servers</div>
|
||
<div class="input-sublabel">Physical or virtual — each managed server</div>
|
||
</div>
|
||
<div class="num-stepper">
|
||
<button class="step-btn" onclick="stepInput('serverCount',-1)">−</button>
|
||
<input class="num-input" id="serverCount" type="number" min="0" value="0" oninput="update()">
|
||
<button class="step-btn" onclick="stepInput('serverCount',1)">+</button>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ────────────────────────────────────────────────────────────
|
||
SECTION V — ZERO TRUST NETWORKING HaaS
|
||
Starts COLLAPSED. Two independent inputs:
|
||
#ztNetSeats — ZT user seats @ $25/seat/mo (ztNetSeats)
|
||
#ztNetRouters — HaaS router devices @ $100/device/mo (ztNetRouters)
|
||
ztActive = addZT (Sec II checkbox) OR ztSeats > 0
|
||
When ztActive → adds ADMIN_FEE_ZT ($250) to admin fee
|
||
ztNetTotal added to MRR but NOT to baseSubtotal
|
||
#sec05-summary — badge shown when collapsed
|
||
──────────────────────────────────────────────────────────────── -->
|
||
<div class="section" id="sec-05">
|
||
<div class="section-header section-toggle" onclick="toggleSection('sec-05')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleSection('sec-05');event.preventDefault();}">
|
||
<div class="section-num">V</div>
|
||
<div class="section-title-block">
|
||
<div class="section-title">Zero Trust Networking <span class="section-title-tag">HaaS</span></div>
|
||
<div class="section-subtitle">Cytracom-powered ZT network access — seats & managed hardware as a service</div>
|
||
<span class="section-badge">Per User + Per Device / Month</span>
|
||
</div>
|
||
<span id="sec05-summary" class="sec-summary-badge"></span>
|
||
<div class="sec-chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></div>
|
||
</div>
|
||
<div class="section-body" id="sec-05-body" style="display:none;">
|
||
<div class="section-content">
|
||
|
||
<!-- ZT relationship explainer -->
|
||
<div class="callout-green" style="margin-bottom:20px;">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="14" height="14" fill="var(--green)" style="flex-shrink:0;margin-top:2px;"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24V264c0 13.3-10.7 24-24 24s-24-10.7-24-24V152c0-13.3 10.7-24 24-24zm-32 224a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"/></svg>
|
||
<span><strong>Section II vs Section V — what's the difference?</strong><br>
|
||
Section II's <em>Zero Trust User Seat</em> (+$55/user) adds the ZT software agent to each person's device — identity-aware access, deny-by-default policy, per-user.<br>
|
||
Section V adds <em>ZT network infrastructure</em>: <strong>seats</strong> cover non-user devices (printers, IoT, cameras) that need network access control, and <strong>routers</strong> are the managed ZTNA gateway hardware delivered as a service. Both can be active together.</span>
|
||
</div>
|
||
|
||
<div class="input-row">
|
||
<div>
|
||
<div class="input-label">5A — ZT User Seats</div>
|
||
<div class="input-sublabel">Identity-aware access control per user · $25/seat/mo</div>
|
||
</div>
|
||
<div class="num-stepper">
|
||
<button class="step-btn" onclick="stepInput('ztNetSeats',-1)">−</button>
|
||
<input class="num-input" id="ztNetSeats" type="number" min="0" value="0" oninput="update()">
|
||
<button class="step-btn" onclick="stepInput('ztNetSeats',1)">+</button>
|
||
</div>
|
||
</div>
|
||
<div class="input-row">
|
||
<div>
|
||
<div class="input-label">5B — HaaS Devices</div>
|
||
<div class="input-sublabel">Managed router/firewall hardware · $100/device/mo</div>
|
||
</div>
|
||
<div class="num-stepper">
|
||
<button class="step-btn" onclick="stepInput('ztNetRouters',-1)">−</button>
|
||
<input class="num-input" id="ztNetRouters" type="number" min="0" value="0" oninput="update()">
|
||
<button class="step-btn" onclick="stepInput('ztNetRouters',1)">+</button>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ────────────────────────────────────────────────────────────
|
||
SECTION VI — VOIP / UCaaS
|
||
Starts COLLAPSED. Three-tier radio toggle:
|
||
#voipBasic/$28 #voipStandard/$35 #voipPremium/$45
|
||
.tier-seg.active set by activateTier() AND update()
|
||
#voipSeats — seat count input
|
||
#addVoipPhone — Desk Phone HaaS +$15/seat
|
||
#addVoipFax — eFax line +$10 flat (not per seat)
|
||
#currentPhoneBill — optional savings comparator input
|
||
#savingsComparator — green/amber result, rendered by updateSavings()
|
||
voipTotal NOT counted in baseSubtotal (no effect on admin fee)
|
||
#sec06-summary — badge shown when collapsed
|
||
──────────────────────────────────────────────────────────────── -->
|
||
<div class="section" id="sec-06">
|
||
<div class="section-header section-toggle" onclick="toggleSection('sec-06')" tabindex="0" role="button" onkeydown="if(event.key==='Enter'||event.key===' '){toggleSection('sec-06');event.preventDefault();}">
|
||
<div class="section-num">VI</div>
|
||
<div class="section-title-block">
|
||
<div class="section-title">VoIP / Unified Communications <span class="section-title-tag">UCaaS</span></div>
|
||
<div class="section-subtitle">United Cloud-powered business phone — seats, features & optional desk phones</div>
|
||
<span class="section-badge">Per Seat / Month</span>
|
||
</div>
|
||
<span id="sec06-summary" class="sec-summary-badge"></span>
|
||
<div class="sec-chevron"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></div>
|
||
</div>
|
||
<div class="section-body" id="sec-06-body" style="display:none;">
|
||
<div class="section-content">
|
||
|
||
<!-- Tier Selector -->
|
||
<div class="tier-seg-wrap">
|
||
<input type="radio" name="voipTier" id="voipBasic" value="basic" checked onchange="update()">
|
||
<label for="voipBasic" class="tier-seg" id="seg-basic" onclick="activateTier('basic')">
|
||
<div class="tier-name">Basic</div>
|
||
<div class="tier-price">$28</div>
|
||
<div class="tier-sub">/seat/mo</div>
|
||
</label>
|
||
<input type="radio" name="voipTier" id="voipStandard" value="standard" onchange="update()">
|
||
<label for="voipStandard" class="tier-seg" id="seg-standard" onclick="activateTier('standard')">
|
||
<div class="tier-name">Standard</div>
|
||
<div class="tier-price">$35</div>
|
||
<div class="tier-sub">/seat/mo</div>
|
||
</label>
|
||
<input type="radio" name="voipTier" id="voipPremium" value="premium" onchange="update()">
|
||
<label for="voipPremium" class="tier-seg" id="seg-premium" onclick="activateTier('premium')">
|
||
<div class="tier-name">Premium</div>
|
||
<div class="tier-price">$45</div>
|
||
<div class="tier-sub">/seat/mo</div>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="input-row">
|
||
<div>
|
||
<div class="input-label">Number of Seats</div>
|
||
<div class="input-sublabel">One seat per phone user</div>
|
||
</div>
|
||
<div class="num-stepper">
|
||
<button class="step-btn" onclick="stepInput('voipSeats',-1)">−</button>
|
||
<input class="num-input" id="voipSeats" type="number" min="0" value="0" oninput="update()">
|
||
<button class="step-btn" onclick="stepInput('voipSeats',1)">+</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="addon-grid" style="margin-top:8px;">
|
||
<label class="addon-row" id="row-vphone" onclick="toggleAddon('addVoipPhone','row-vphone');update()">
|
||
<input type="checkbox" id="addVoipPhone">
|
||
<div><div class="addon-name">Desk Phone HaaS</div><div class="addon-desc">Managed physical desk phone hardware per seat</div></div>
|
||
<span class="addon-price">+$15/seat/mo</span>
|
||
</label>
|
||
<label class="addon-row" id="row-vfax" onclick="toggleAddon('addVoipFax','row-vfax');update()">
|
||
<input type="checkbox" id="addVoipFax">
|
||
<div><div class="addon-name">eFax Line</div><div class="addon-desc">Digital fax number — send & receive via email or portal</div></div>
|
||
<span class="addon-price">+$10/line/mo</span>
|
||
</label>
|
||
</div>
|
||
|
||
<!-- Phone Bill Savings -->
|
||
<div class="savings-input-row">
|
||
<label for="currentPhoneBill">Current monthly phone bill (optional)</label>
|
||
<input type="number" id="currentPhoneBill" placeholder="$0" min="0"
|
||
oninput="updateSavings()" onchange="updateSavings()">
|
||
</div>
|
||
<div id="savingsPrompt" class="savings-prompt" style="display:none;">
|
||
Enter your current phone bill above to see potential savings.
|
||
</div>
|
||
<div id="savingsComparator" class="savings-result hidden"></div>
|
||
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
</div><!-- END main-col — sections I–VI -->
|
||
|
||
<!-- SIDEBAR -->
|
||
<!-- ── RIGHT COLUMN: sticky sidebar (desktop only ≥1100px) ─────────
|
||
Hidden on mobile via CSS. Duplicate exists in #mobilePanelContent.
|
||
nudgeBanner must stay INSIDE .sidebar-body or it gets clipped.
|
||
──────────────────────────────────────────────────────────────── -->
|
||
<div class="side-col">
|
||
<div class="sidebar">
|
||
<div class="sidebar-header">
|
||
<div class="sidebar-title">SVS MSP — Live Quote</div>
|
||
<div class="sidebar-client" id="clientNameDisplay">Client Name</div>
|
||
</div>
|
||
<div class="sidebar-body">
|
||
<!-- ── SIDEBAR SERVICE LINES ──────────────────────────────────
|
||
Each .sidebar-line hidden by default.
|
||
update() calls show(id, condition) to toggle .hidden.
|
||
sl-users / sl-endpoints / sl-servers / sl-zt / sl-voip
|
||
shown only when their respective count > 0.
|
||
sl-admin is always visible (never hidden).
|
||
sl-*-sub rows are sub-labels (e.g. "5 × $130/user")
|
||
toggled via style.display not .hidden class.
|
||
──────────────────────────────────────────────────────────── -->
|
||
<div id="sidebarLines">
|
||
<div class="sidebar-line hidden" id="sl-users">
|
||
<span><span class="lbl-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" width="14" height="13" fill="currentColor" style="vertical-align:middle;"><path d="M144 0a80 80 0 1 1 0 160A80 80 0 1 1 144 0zM512 0a80 80 0 1 1 0 160A80 80 0 1 1 512 0zM0 298.7C0 239.8 47.8 192 106.7 192h42.7c15.9 0 31 3.5 44.6 9.7c-1.3 7.2-1.9 14.7-1.9 22.3c0 38.2 16.8 72.5 43.3 96c-.2 0-.4 0-.7 0H21.3C9.6 320 0 310.4 0 298.7zM405.3 320c-.2 0-.4 0-.7 0c26.6-23.5 43.3-57.8 43.3-96c0-7.6-.7-15-1.9-22.3c13.6-6.3 28.7-9.7 44.6-9.7h42.7C592.2 192 640 239.8 640 298.7c0 11.8-9.6 21.3-21.3 21.3H405.3zM224 224a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zM128 485.3C128 411.7 187.7 352 261.3 352H378.7C452.3 352 512 411.7 512 485.3c0 14.7-11.9 26.7-26.7 26.7H154.7c-14.7 0-26.7-11.9-26.7-26.7z"/></svg></span> Users</span>
|
||
<span class="val" id="sl-users-val">—</span>
|
||
</div>
|
||
<div class="sl-sub" style="display:none;" id="sl-users-sub"></div>
|
||
<div class="sidebar-line hidden" id="sl-endpoints">
|
||
<span><span class="lbl-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" width="14" height="13" fill="currentColor" style="vertical-align:middle;"><path d="M64 0C28.7 0 0 28.7 0 64V352c0 35.3 28.7 64 64 64H240l-10.7 32H160c-17.7 0-32 14.3-32 32s14.3 32 32 32H416c17.7 0 32-14.3 32-32s-14.3-32-32-32H346.7L336 416H512c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H64zM512 64V352H64V64H512z"/></svg></span> Endpoints</span>
|
||
<span class="val" id="sl-endpoints-val">—</span>
|
||
</div>
|
||
<div class="sl-sub" style="display:none;" id="sl-endpoints-sub"></div>
|
||
<div class="sidebar-line hidden" id="sl-servers">
|
||
<span><span class="lbl-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="13" height="13" fill="currentColor" style="vertical-align:middle;"><path d="M64 32C28.7 32 0 60.7 0 96v64c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V96c0-35.3-28.7-64-64-64H64zm280 72a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm48 24a24 24 0 1 1 48 0 24 24 0 1 1 -48 0zM64 288c-35.3 0-64 28.7-64 64v64c0 35.3 28.7 64 64 64H448c35.3 0 64-28.7 64-64V352c0-35.3-28.7-64-64-64H64zm280 72a24 24 0 1 1 0 48 24 24 0 1 1 0-48zm56 24a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z"/></svg></span> Servers</span>
|
||
<span class="val" id="sl-servers-val">—</span>
|
||
</div>
|
||
<div class="sidebar-line hidden" id="sl-zt">
|
||
<span><span class="lbl-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="11" height="13" fill="currentColor" style="vertical-align:middle;"><path d="M144 144v48H304V144c0-44.2-35.8-80-80-80s-80 35.8-80 80zM80 192V144C80 64.5 144.5 0 224 0s144 64.5 144 144v48h16c35.3 0 64 28.7 64 64V448c0 35.3-28.7 64-64 64H64c-35.3 0-64-28.7-64-64V256c0-35.3 28.7-64 64-64H80z"/></svg></span> Zero Trust</span>
|
||
<span class="val" id="sl-zt-val">—</span>
|
||
</div>
|
||
<div class="sidebar-line hidden" id="sl-voip">
|
||
<span><span class="lbl-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="13" height="13" fill="currentColor" style="vertical-align:middle;"><path d="M164.9 24.6c-7.7-18.6-28-28.5-47.4-23.2l-88 24C11.7 30.3 0 46.7 0 64C0 311.4 200.6 512 448 512c17.3 0 33.7-11.7 38.6-29.5l24-88c5.3-19.4-4.6-39.7-23.2-47.4l-96-40c-16.3-6.8-35.2-2.1-46.3 11.6L304.7 368C234.3 334.7 177.3 277.7 144 207.3L193.3 167c13.7-11.2 18.4-30 11.6-46.3l-40-96z"/></svg></span> VoIP</span>
|
||
<span class="val" id="sl-voip-val">—</span>
|
||
</div>
|
||
<div class="sidebar-line" id="sl-admin">
|
||
<span><span class="lbl-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" width="12" height="13" fill="currentColor" style="vertical-align:middle;"><path d="M48 0C21.5 0 0 21.5 0 48V464c0 26.5 21.5 48 48 48h96V432c0-26.5 21.5-48 48-48s48 21.5 48 48v80h96c26.5 0 48-21.5 48-48V48c0-26.5-21.5-48-48-48H48zM64 240c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V240zm112-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V240c0-8.8 7.2-16 16-16zm48-80v32c0 8.8-7.2 16-16 16H176c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16h32c8.8 0 16 7.2 16 16zm-144-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V144c0-8.8 7.2-16 16-16zm144 208h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H272c-8.8 0-16-7.2-16-16V352c0-8.8 7.2-16 16-16zm-144-16h32c8.8 0 16 7.2 16 16v32c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V352c0-8.8 7.2-16 16-16z"/></svg></span> Site Admin Fee</span>
|
||
<span class="val" id="sl-admin-val">$150</span>
|
||
</div>
|
||
<div class="sl-sub" id="sl-admin-sub"></div>
|
||
</div>
|
||
|
||
<!-- Discount line — hidden when no term discount -->
|
||
<div class="sidebar-line sidebar-line-discount hidden" id="sl-base-mrr-row">
|
||
<span class="sl-muted">Base MRR</span>
|
||
<span class="val sl-muted" id="sl-base-mrr-val">—</span>
|
||
</div>
|
||
<div class="sidebar-line sidebar-line-discount hidden" id="sl-discount-row">
|
||
<span class="sl-muted">Term Discount</span>
|
||
<span class="val sl-discount-val" id="sl-discount-val">—</span>
|
||
</div>
|
||
|
||
<div class="sidebar-mrr-label">Monthly Recurring (MRR)</div>
|
||
<div class="sidebar-mrr" id="mrrDisplay">$150</div>
|
||
|
||
<label class="sl-hst-toggle">
|
||
<input type="checkbox" id="hstToggle" onchange="update()">
|
||
<span>Include Ontario HST (13%)</span>
|
||
</label>
|
||
|
||
<!-- HST line — hidden unless HST toggle enabled -->
|
||
<div class="sidebar-line sidebar-line-hst hidden" id="sl-hst-row">
|
||
<span class="sl-muted">HST (13%)</span>
|
||
<span class="val sl-hst-val" id="sl-hst-val">—</span>
|
||
</div>
|
||
|
||
<!-- Total inc. HST — hidden unless HST enabled -->
|
||
<div class="sidebar-line sidebar-line-total hidden" id="sl-hst-total-row">
|
||
<span>Total (inc. HST)</span>
|
||
<span class="val" id="sl-hst-total-val">—</span>
|
||
</div>
|
||
|
||
<!-- Onboarding fee line — hidden unless set -->
|
||
<div class="sidebar-line hidden" id="sl-otf-row">
|
||
<span>Onboarding Fee</span>
|
||
<span class="val" id="sl-otf-val">—</span>
|
||
</div>
|
||
|
||
<div class="sidebar-line">
|
||
<span>Annual Projection</span>
|
||
<span class="val" id="annualDisplay">$1,800</span>
|
||
</div>
|
||
<div class="sidebar-line" id="perUserRow" style="display:none;">
|
||
<span>Avg. Cost Per User<br><small class="per-user-cost-sub">(all services ÷ users)</small></span>
|
||
<span class="val" id="perUserDisplay">—</span>
|
||
</div>
|
||
<div class="sidebar-note sidebar-note-mono hidden" id="perUserBreakdown"></div>
|
||
|
||
<hr class="sidebar-divider">
|
||
<div class="sidebar-note" id="sideNote-admin">Admin fee = <strong id="adminPct">—</strong>% of total MRR</div>
|
||
<div class="sidebar-note hidden" id="sideNote-m365"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="14" height="14" fill="var(--green)" class="note-icon"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM369 209L241 337c-9.4 9.4-24.6 9.4-33.9 0l-64-64c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l47 47L335 175c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z"/></svg> Bundled M365 saves client up to <strong id="m365SaveAmt" class="savings-amount">—</strong>/mo vs retail licensing</div>
|
||
<div class="sidebar-note hidden" id="sideNote-byol"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="14" height="14" fill="var(--amber)" class="note-icon"><path d="M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zm0-384c13.3 0 24 10.7 24 24V264c0 13.3-10.7 24-24 24s-24-10.7-24-24V152c0-13.3 10.7-24 24-24zm-32 224a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z"/></svg> BYOL selected — client handles their own Microsoft or Google licensing</div>
|
||
|
||
<!-- ── VS HIRING IN-HOUSE ─────────────────────────────────────
|
||
Hidden (.hidden) until users>0 OR endpoints>0.
|
||
updateVsComparison(q) renders all values.
|
||
vs-1man-save-row / vs-5man-save-row: background + text colour
|
||
set inline by JS (green = savings, amber = costs more).
|
||
These rows use document.querySelector to reach the
|
||
inner <span> — if the HTML structure changes, update that
|
||
selector in updateVsComparison().
|
||
──────────────────────────────────────────────────────────── -->
|
||
<div id="vsComparison" class="hidden vs-comparison-wrap">
|
||
<div class="vs-label">VS. Hiring In-House</div>
|
||
<table class="vs-table">
|
||
<tr>
|
||
<td>
|
||
<svg width="14" height="14" viewBox="0 0 72 98" class="vs-inline-icon" xmlns="http://www.w3.org/2000/svg">
|
||
<polyline points="7.32 8.88 62.11 8.88 34.72 58.22" fill="#1f75a6"/>
|
||
<polyline points="40.7 55.33 64.4 12.64 71.88 12.64 44.48 61.99 40.7 55.33" fill="#8d252f"/>
|
||
</svg>
|
||
<span class="vs-svs-label">SVS MSP</span>
|
||
</td>
|
||
<td class="vs-val-accent" id="vs-svs-annual">—</td>
|
||
</tr>
|
||
<tr><td class="vs-td-muted"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="12" height="13" fill="currentColor" class="vs-td-icon"><path d="M224 256A128 128 0 1 0 224 0a128 128 0 1 0 0 256zm-45.7 48C79.8 304 0 383.8 0 482.3C0 498.7 13.3 512 29.7 512H418.3c16.4 0 29.7-13.3 29.7-29.7C448 383.8 368.2 304 269.7 304H178.3z"/></svg> 1 IT person + tools</td><td class="vs-td-muted" id="vs-1man-cost">—</td></tr>
|
||
<tr class="vs-save-row" id="vs-1man-save-row"><td><span id="vs-1man-save-lbl" class="vs-val-green">YOU SAVE</span></td><td id="vs-1man-save" class="vs-val-green">—</td></tr>
|
||
<tr><td class="vs-td-muted"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" width="14" height="13" fill="currentColor" class="vs-td-icon"><path d="M144 0a80 80 0 1 1 0 160A80 80 0 1 1 144 0zM512 0a80 80 0 1 1 0 160A80 80 0 1 1 512 0zM0 298.7C0 239.8 47.8 192 106.7 192h42.7c15.9 0 31 3.5 44.6 9.7c-1.3 7.2-1.9 14.7-1.9 22.3c0 38.2 16.8 72.5 43.3 96c-.2 0-.4 0-.7 0H21.3C9.6 320 0 310.4 0 298.7zM405.3 320c-.2 0-.4 0-.7 0c26.6-23.5 43.3-57.8 43.3-96c0-7.6-.7-15-1.9-22.3c13.6-6.3 28.7-9.7 44.6-9.7h42.7C592.2 192 640 239.8 640 298.7c0 11.8-9.6 21.3-21.3 21.3H405.3zM224 224a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zM128 485.3C128 411.7 187.7 352 261.3 352H378.7C452.3 352 512 411.7 512 485.3c0 14.7-11.9 26.7-26.7 26.7H154.7c-14.7 0-26.7-11.9-26.7-26.7z"/></svg> 5-person team</td><td class="vs-td-muted" id="vs-5man-cost">—</td></tr>
|
||
<tr class="vs-save-row" id="vs-5man-save-row"><td><span id="vs-5man-save-lbl" class="vs-val-green">YOU SAVE</span></td><td id="vs-5man-save" class="vs-val-green">—</td></tr>
|
||
</table>
|
||
<div class="vs-footnote" id="vs-footnote"></div>
|
||
</div>
|
||
|
||
<!-- ── INSIGHT NUDGE BANNER ────────────────────────────────────
|
||
MUST remain inside .sidebar-body div.
|
||
If this div is placed after the closing sidebar-body div
|
||
it breaks on mobile (clipped outside container).
|
||
Controlled entirely by renderNudge() via applyNudge("").
|
||
Mobile duplicate: #nudgeBanner_m (synced via syncClass/syncEl).
|
||
.hidden class toggled by renderNudge() when nudges=[]
|
||
──────────────────────────────────────────────────────────────── -->
|
||
<div id="nudgeBanner" class="nudge-banner amber hidden">
|
||
<div class="nudge-header-row">
|
||
<span class="nudge-banner-label" style="margin-bottom:0;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" width="12" height="14" fill="currentColor" style="margin-right:6px;vertical-align:middle;"><path d="M272 384c9.6-31.9 29.5-59.1 49.2-86.2l0 0c5.2-7.1 10.4-14.2 15.4-21.4c19.8-28.5 31.4-63 31.4-100.3C368 78.8 289.2 0 192 0S16 78.8 16 176c0 37.3 11.6 71.9 31.4 100.3c5 7.2 10.2 14.3 15.4 21.4l0 0c19.8 27.1 39.7 54.4 49.2 86.2H272zM192 512c44.2 0 80-35.8 80-80V416H112v16c0 44.2 35.8 80 80 80zM112 352H272c0 0 0 0 0 0H112c0 0 0 0 0 0z"/></svg> Insight <span id="nudgeCounter" class="nudge-counter"></span></span>
|
||
<div class="nudge-nav-group">
|
||
<button onclick="cycleNudge(-1)" class="nudge-nav-btn" title="Previous"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="15 18 9 12 15 6"/></svg></button>
|
||
<button onclick="cycleNudge(1)" class="nudge-nav-btn" title="Next"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg></button>
|
||
</div>
|
||
</div>
|
||
<span id="nudgeText"></span>
|
||
</div>
|
||
|
||
<!-- ── EXPORT BUTTONS ───────────────────────────────────────────
|
||
Export A: window.print() — triggers browser print/save-as-PDF.
|
||
Export B: exportQuoteJSON() — downloads .json + copies to clipboard.
|
||
exportQuote() — plain-text .txt (original, kept for reference).
|
||
──────────────────────────────────────────────────────────────── -->
|
||
<div class="export-wrap">
|
||
<button class="btn-export" onclick="printInvoice()">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="14" height="14" fill="currentColor" style="margin-right:7px;vertical-align:middle;"><path d="M128 0C92.7 0 64 28.7 64 64v96h64V64H354.7L384 93.3V160h64V93.3c0-17-6.7-33.3-18.7-45.3L400 18.7C388 6.7 371.7 0 354.7 0H128zM384 352v32 64H128V384 352H384zm64 32h32c17.7 0 32-14.3 32-32V256c0-35.3-28.7-64-64-64H64c-35.3 0-64 28.7-64 64v96c0 17.7 14.3 32 32 32H64v64c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V384zm-16-88a24 24 0 1 1 0 48 24 24 0 1 1 0-48z"/></svg>
|
||
Print / Save PDF
|
||
</button>
|
||
<button class="btn-export btn-export-secondary" id="btnExportJSON" onclick="exportQuoteJSON()">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" width="12" height="14" fill="currentColor" style="margin-right:7px;vertical-align:middle;"><path d="M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H320c35.3 0 64-28.7 64-64V160H256c-17.7 0-32-14.3-32-32V0H64zM256 0V128h128L256 0zM216 232l-96 96 96 96 22.6-22.6L169.3 328l69.3-69.4L216 232zM168 232l-22.6 22.6 69.3 69.4-69.3 69.4L168 416l96-96-96-96z"/></svg>
|
||
Export JSON + Copy
|
||
</button>
|
||
</div>
|
||
</div><!-- END sidebar-body -->
|
||
</div><!-- END sidebar -->
|
||
</div><!-- END side-col — desktop sidebar -->
|
||
|
||
</div><!-- END outer grid (3fr main-col / 2fr side-col) -->
|
||
|
||
<!-- BOTTOM PITCH -->
|
||
<div class="pitch-wrap">
|
||
<div class="pitch-inner">
|
||
<div class="pitch-grid">
|
||
<div class="pitch-item">
|
||
<div class="pitch-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="18" height="20" fill="var(--accent)" style="vertical-align:middle;"><path d="M256 0c4.6 0 9.2 1 13.4 2.9L457.7 82.8c22 9.3 38.4 31 38.3 57.2c-.5 99.2-41.3 280.7-213.6 363.2c-16.7 8-36.1 8-52.8 0C57.3 420.7 16.5 239.2 16 140c-.1-26.2 16.3-47.9 38.3-57.2L242.7 2.9C246.8 1 251.4 0 256 0zm0 66.8V444.8C394 378 431.1 230.1 432 141.4L256 66.8z"/></svg></div>
|
||
<div class="pitch-title">Security-First MSP</div>
|
||
<div class="pitch-desc">Every engagement is built on a security baseline — EDR, MFA, patch management, and cyber warranty included.</div>
|
||
</div>
|
||
<div class="pitch-item">
|
||
<div class="pitch-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512" width="14" height="20" fill="var(--accent)" style="vertical-align:middle;"><path d="M215.7 499.2C267 435 384 279.4 384 192C384 86 298 0 192 0S0 86 0 192c0 87.4 117 243 168.3 307.2c12.3 15.3 35.1 15.3 47.4 0zM192 128a64 64 0 1 1 0 128 64 64 0 1 1 0-128z"/></svg></div>
|
||
<div class="pitch-title">Ottawa-Based Team</div>
|
||
<div class="pitch-desc">Local presence, Canadian data sovereignty, and an account team that knows your business and your region.</div>
|
||
</div>
|
||
<div class="pitch-item">
|
||
<div class="pitch-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="20" height="20" fill="var(--accent)" style="vertical-align:middle;"><path d="M78.6 5C69.1-2.4 55.6-1.5 47 7L7 47c-8.5 8.5-9.4 22-2.1 31.6l80 104c4.5 5.9 11.6 9.4 19 9.4h54.1l109 109c-14.7 29-10 65.4 14.3 89.6l112 112c12.5 12.5 32.8 12.5 45.3 0l64-64c12.5-12.5 12.5-32.8 0-45.3l-112-112c-24.2-24.2-60.6-29-89.6-14.3l-109-109V104c0-7.5-3.5-14.5-9.4-19L78.6 5zM19.9 396.1C7.2 408.8 0 426.1 0 444.1C0 481.6 30.4 512 67.9 512c18 0 35.3-7.2 48-19.9L233.7 374.3c-7.8-20.9-9-43.6-3.6-65.1l-61.7-61.7L19.9 396.1zM512 144c0-10.5-1.1-20.7-3.2-30.5c-2.4-11.2-16.1-14.1-24.2-6l-63.9 63.9c-3 3-7.1 4.7-11.3 4.7H352c-8.8 0-16-7.2-16-16V102.6c0-4.2 1.7-8.3 4.7-11.3l63.9-63.9c8.1-8.1 5.2-21.8-6-24.2C388.7 1.1 378.5 0 368 0C288.5 0 224 64.5 224 144l0 .8 85.3 85.3c36-9.1 75.8 .5 104 28.7L429 274.5c49-23 83-72.8 83-130.5zM56 432a24 24 0 1 1 48 0 24 24 0 1 1 -48 0z"/></svg></div>
|
||
<div class="pitch-title">Flat-Rate, No Surprises</div>
|
||
<div class="pitch-desc">Predictable monthly billing with no per-ticket charges — aligned incentives mean we fix things right the first time.</div>
|
||
</div>
|
||
<div class="pitch-item">
|
||
<div class="pitch-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="20" height="20" fill="var(--accent)" style="vertical-align:middle;"><path d="M64 64c0-17.7-14.3-32-32-32S0 46.3 0 64V400c0 44.2 35.8 80 80 80H480c17.7 0 32-14.3 32-32s-14.3-32-32-32H80c-8.8 0-16-7.2-16-16V64zm406.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L320 210.7l-57.4-57.4c-12.5-12.5-32.8-12.5-45.3 0l-112 112c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L240 221.3l57.4 57.4c12.5 12.5 32.8 12.5 45.3 0l128-128z"/></svg></div>
|
||
<div class="pitch-title">Scales With You</div>
|
||
<div class="pitch-desc">Add users, endpoints, servers, ZT networking, or VoIP as you grow — one vendor, one invoice, one relationship.</div>
|
||
</div>
|
||
</div>
|
||
<div class="pitch-footer">
|
||
✓ No lock-in contracts on standard plans · ✓ Onboarding included · ✓ Canadian company, Canadian support
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<script src="SVS-MSP-Calculator.js"></script>
|
||
</body>
|
||
</html>
|