Diff -- /var/www/vhosts/3dshawn.com/crm.3dshawn.com/TEMPLATES/cf_marketing.html

O Operator
Diff

/var/www/vhosts/3dshawn.com/crm.3dshawn.com/TEMPLATES/cf_marketing.html

added on local at 2026-07-11 08:17:32

Added
+0
lines
Removed
-0
lines
Context
118
unchanged
Blobs
from 54b8b2837cf7
to 54b8b2837cf7
Restore this content →
Unified diff
Naive LCS-based line diff. Additions in emerald, deletions in rose. Both sides decompressed live from BLOB_STORE.
11<!DOCTYPE html>
22<html lang="en">
33<head>
44 <meta charset="UTF-8">
55 <meta name="viewport" content="width=device-width, initial-scale=1.0">
66 <!-- Anti-cache: belt-and-suspenders to the Cache-Control HTTP headers
77 the CGIs already emit. Some browser back/forward caches (bfcache)
88 still serve stale HTML even with no-cache headers; these meta tags
99 are the second line of defense. -->
1010 <meta http-equiv="Cache-Control" content="no-store, no-cache, must-revalidate, max-age=0">
1111 <meta http-equiv="Pragma" content="no-cache">
1212 <meta http-equiv="Expires" content="0">
1313 <link rel="icon" type="image/svg+xml" href="/assets/images/favicon.svg">
1414 <title>$title &middot; $website_title</title>
1515$meta_tags
1616 <link rel="preconnect" href="https://fonts.googleapis.com">
1717 <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
1818 <link href="https://fonts.googleapis.com/css2?family=Inter:wght\@400;500;600;700&family=Space+Grotesk:wght\@500;600;700&family=JetBrains+Mono:wght\@400;600&display=swap" rel="stylesheet">
1919 <link rel="stylesheet" href="$assets_css/site.css?v=2026-06-12-fixbrand">
2020 $extra_css
2121</head>
2222<body>
2323 $body
2424 <script src="$assets_js/site.js?v=2026-06-12-fixbrand"></script>
2525 <!-- In-app popup helper (confirm/alert/prompt/toast). Same script the
2626 dashboard uses, loaded on marketing pages too so logged-out flows
2727 get consistent overlays instead of native alert(). -->
2828 <script src="$assets_js/confirm.js?v=1"></script>
2929 <!-- Live chat widget: only loaded on logged-out marketing pages so
3030 prospects can reach support. The authenticated dashboard wrapper
3131 does NOT load this script -- in-app help lives at /help.cgi
3232 and /support.cgi instead. -->
3333 [if:!$heatmap_view]<script src="$assets_js/track.js?v=5"></script>[/if]
3434 <!-- ContactForge visitor analytics -- captures pageviews, sessions,
3535 referrer + UTM, browser + OS + device + country. Admin views the
3636 results at /admin_visitors.cgi, /admin_traffic.cgi,
3737 /admin_heatmap.cgi. Suppressed when the admin is previewing a
3838 page inside an iframe (heatmap_view=1) so admin clicks don't
3939 pollute visitor data. -->
4040 [if:!$heatmap_view]<script async src="/t.js?v=20260610"></script>[/if]
4141 $extra_js
4242
4343<!-- Anonymous path tracker. Only included from the marketing wrapper, so
4444 logged-in app pages never call /t.cgi. -->
4545<script>
4646(function(){
4747 try {
4848 var u = new URLSearchParams(location.search);
4949 var qs = '?p=' + encodeURIComponent(location.pathname + location.search)
5050 + '&r=' + encodeURIComponent(document.referrer || '')
5151 + '&us=' + encodeURIComponent(u.get('utm_source') || '')
5252 + '&um=' + encodeURIComponent(u.get('utm_medium') || '')
5353 + '&uc=' + encodeURIComponent(u.get('utm_campaign') || '');
5454 var img = new Image();
5555 img.referrerPolicy = 'no-referrer-when-downgrade';
5656 img.src = '/t.cgi' + qs;
5757 } catch (e) { /* silent */ }
5858})();
5959</script>
6060<script>
6161/* sidebar-scroll-preserve: keeps .sidebar scrollTop across page loads */
6262(function(){
6363 var sb = document.querySelector('.sidebar');
6464 if (!sb) return;
6565 var KEY = 'crm.3dshawn.com-sidebar-scroll';
6666 try { var s = parseInt(localStorage.getItem(KEY), 10) || 0; if (s > 0) sb.scrollTop = s; } catch(e){}
6767 var t = null;
6868 sb.addEventListener('scroll', function(){
6969 if (t) clearTimeout(t);
7070 t = setTimeout(function(){ try { localStorage.setItem(KEY, sb.scrollTop); } catch(e){} }, 80);
7171 }, { passive: true });
7272})();
7373</script>
7474<!-- Viewer-local timestamp renderer (portfolio-canonical).
7575 Server emits `<span class="ts" data-ts="EPOCH" data-fmt="…">FALLBACK</span>`.
7676 Formats: datetime | date | date-short | time | relative
7777 Original text is the no-JS fallback. Re-run via window.tzLocalize() after AJAX. -->
7878<script>
7979(function(){
8080 function fmt(el){
8181 var e = parseInt(el.getAttribute('data-ts'), 10);
8282 if (!e) return;
8383 var d = new Date(e * 1000);
8484 var kind = el.getAttribute('data-fmt') || 'datetime';
8585 var out;
8686 switch (kind) {
8787 case 'date': out = d.toLocaleDateString(undefined, {year:'numeric',month:'short',day:'numeric'}); break;
8888 case 'date-short': out = d.toLocaleDateString(undefined, {month:'short',day:'numeric'}); break;
8989 case 'time': out = d.toLocaleTimeString(undefined, {hour:'2-digit',minute:'2-digit'}); break;
9090 case 'relative': out = rel(e); break;
9191 default: out = d.toLocaleDateString(undefined, {year:'numeric',month:'short',day:'numeric'})
9292 + ' ' + d.toLocaleTimeString(undefined, {hour:'2-digit',minute:'2-digit'});
9393 }
9494 el.textContent = out;
9595 if (!el.title) el.title = d.toString();
9696 }
9797 function rel(e){
9898 var s = Math.floor(Date.now()/1000) - e, future = s < 0; s = Math.abs(s);
9999 var n, u;
100100 if (s < 60) { n = s; u = 'second'; }
101101 else if (s < 3600) { n = Math.floor(s/60); u = 'minute'; }
102102 else if (s < 86400) { n = Math.floor(s/3600); u = 'hour'; }
103103 else if (s < 2592000){ n = Math.floor(s/86400); u = 'day'; }
104104 else if (s < 31536000){n = Math.floor(s/2592000); u = 'month'; }
105105 else { n = Math.floor(s/31536000);u = 'year'; }
106106 var p = n === 1 ? '' : 's';
107107 return future ? ('in ' + n + ' ' + u + p) : (n + ' ' + u + p + ' ago');
108108 }
109109 function localize(root){ (root||document).querySelectorAll('span.ts[data-ts], time[data-ts]').forEach(fmt); }
110110 window.tzLocalize = localize;
111111 if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', function(){ localize(); });
112112 else localize();
113113 window.addEventListener('ts-refresh', function(){ localize(); });
114114})();
115115</script>
116116
117117</body>
118118</html>