website: update cf page (#7577)

Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
This commit is contained in:
Evgeny
2026-09-24 07:16:35 +01:00
committed by GitHub
co-authored by Evgeny @ SimpleX Chat
parent 3af6e2abfe
commit 2214b8990c
+24 -235
View File
@@ -220,61 +220,6 @@ templateEngineOverride: njk
color: #dfeaff;
}
.cf-hero-offer {
position: relative;
margin-top: calc(var(--sec-vhu) * 6.3);
width: calc(var(--sec-vwu) * 56);
}
.cf-hero-offer p { font-family: "Manrope", sans-serif; }
.cf-hero-offer .cf-offer-lead {
font-weight: 600;
font-size: calc(var(--sec-vwu) * 2.1);
line-height: 1.4;
color: #ffffff;
font-variant-numeric: tabular-nums;
}
.cf-hero-offer .cf-offer-lead b {
font-weight: 700;
background: linear-gradient(90deg, #019bfe 0%, #64fdff 58%, #c8feff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
color: transparent;
}
.cf-hero-offer .cf-offer-lead span { white-space: nowrap; }
.cf-hero-offer .cf-offer-terms {
font-weight: 300;
font-size: calc(var(--sec-vwu) * 1.55);
line-height: 1.55;
color: #dfeaff;
margin-top: calc(var(--sec-vhu) * 0.4);
}
.cf-hero-offer .cf-offer-terms a { position: relative; color: inherit; text-decoration: none; }
.cf-hero-offer .cf-offer-terms abbr { text-decoration: underline dotted; text-underline-offset: 3px; cursor: pointer; }
.cf-hero-offer .cf-offer-terms a::after {
content: attr(data-tip);
position: absolute;
left: calc(100% + 12px);
top: 50%;
transform: translateY(-50%);
white-space: nowrap;
padding: 7px 12px;
border-radius: 8px;
border: 1px solid rgba(255, 255, 255, .18);
background: rgba(5, 9, 32, .96);
color: #dfeaff;
font-family: "Manrope", sans-serif;
font-weight: 400;
font-size: calc(var(--sec-vwu) * 1.1);
line-height: 1.4;
opacity: 0;
visibility: hidden;
transition: opacity .12s ease;
pointer-events: none;
}
.cf-hero-offer .cf-offer-terms a:hover::after,
.cf-hero-offer .cf-offer-terms a:focus-visible::after { opacity: 1; visibility: visible; }
/* ---- close: same left-aligned layout as the hero ---- */
.cf-close .area { position: relative; display: flex; align-items: flex-end; padding: 0 calc(var(--sec-vwu) * 7.5) calc(var(--sec-vhu) * 22) 0; }
@@ -655,7 +600,7 @@ templateEngineOverride: njk
--cf-phone-h: calc(var(--cf-phone-w) / 0.4914);
--cf-phone-part: 0.55;
/* bottom of the hero text block, measured from the section top */
--cf-hero-text-b: calc(var(--cf-top-base) + max(0px, calc(-1 * var(--cf-area-off))) + 92.5vw);
--cf-hero-text-b: calc(var(--cf-top-base) + max(0px, calc(-1 * var(--cf-area-off))) + 75vw);
/* the arc crest starts 0.2678 down the cover image, which is
2.349 phone widths tall and sits 0.4034 phone heights above
the phone top: the phone may rise no higher than this */
@@ -714,19 +659,6 @@ templateEngineOverride: njk
}
.cf-close-offer p { font-size: calc(var(--sec-vwu) * 3.6); }
.cf-stats { top: 0; gap: calc(var(--sec-vwu) * 8); margin-top: calc(var(--sec-vhu) * 3); }
.cf-hero .cf-hero-offer {
position: relative;
top: 0;
width: auto;
z-index: 4;
margin-top: calc(var(--sec-vhu) * 2);
padding: 10px var(--cf-text-pad) 12px;
margin-left: calc(-1 * var(--cf-gutter));
margin-right: calc(-1 * var(--cf-gutter));
background: linear-gradient(to bottom, rgba(2, 7, 29, 0) 0%, rgba(2, 7, 29, var(--cf-offer-veil, 0)) 22%, rgba(2, 7, 29, var(--cf-offer-veil, 0)) 78%, rgba(2, 7, 29, 0) 100%);
}
.cf-hero-offer .cf-offer-lead { font-size: calc(var(--sec-vwu) * 4.2); line-height: 1.3; white-space: nowrap; }
.cf-hero-offer .cf-offer-terms { font-size: calc(var(--sec-vwu) * 4); margin-top: calc(var(--sec-vhu) * 0.8); }
.cf-stat img { width: calc(var(--sec-vwu) * 8); }
.cf-stat b { font-size: calc(var(--sec-vwu) * 6.5); }
.cf-stat span { font-size: calc(var(--sec-vwu) * 3.4); }
@@ -826,11 +758,9 @@ templateEngineOverride: njk
.cf-tag .n { font-size: 3.54cqh; line-height: 1.3; }
}
/* tall phones (modern ratios, with or without the browser bars): the headline takes the
room the screen has; short ones keep the smaller size. */
@media screen and (max-width: 959px) and (orientation: portrait) and (max-aspect-ratio: 62/100) {
.cf-hero h1 { font-size: calc(var(--sec-vwu) * 9.6); }
:root { --cf-hero-text-b: calc(var(--cf-top-base) + max(0px, calc(-1 * var(--cf-area-off))) + 91vw); }
:root { --cf-hero-text-b: calc(var(--cf-top-base) + max(0px, calc(-1 * var(--cf-area-off))) + 72.8vw); }
}
/* 320pt phones: keep the headline at three lines */
@@ -1106,10 +1036,6 @@ templateEngineOverride: njk
<div><b>520K</b><span>Monthly users</span></div>
</div>
</div>
<div class="cf-hero-offer" id="cf-offer">
<p class="cf-offer-lead"><span id="cf-offer-what">SimpleX name for 7 years</span><span id="cf-offer-clock"></span></p>
<p class="cf-offer-terms" id="cf-offer-terms">Invest $500+ by the end of September 22, <a href="https://en.wikipedia.org/wiki/Anywhere_on_Earth" target="_blank" rel="noopener" data-tip="Anywhere on Earth: UTC−12, the last time zone" aria-label="Anywhere on Earth: UTC−12, the last time zone"><abbr>AoE</abbr></a>.</p>
</div>
</div>
<img class="cf-phone" src="/img/crowdfunding/phone.png" alt="">
<img class="cf-mask" src="/img/crowdfunding/phone-mask.png" alt="">
@@ -1231,13 +1157,13 @@ templateEngineOverride: njk
</div>
</div>
<div class="cf-close-offer">
<p>Invest $500+ by November 22 during early bird terms and get a SimpleX public name for your channel or business for 5 years, ahead of public launch.</p>
<p>Invest $500+ during early bird terms and get a SimpleX public name for your channel or business for 5 years, ahead of public launch.</p>
</div>
</div>
</section>
<!-- 8 · FOOTER -->
<section class="page cf cf-footer" data-section="footer">
<section class="page cf cf-footer">
<div class="cf-footer-inner">
<p class="cf-fine">This Regulation Crowdfunding offering is made available through Wefunder Portal LLC. This investment involves a high degree of risk, including the possible loss of your investment.</p>
<p class="cf-fine cf-fine-links">
@@ -1388,119 +1314,33 @@ templateEngineOverride: njk
</div>
<script>
(function cfOffer() {
var offer = document.getElementById('cf-offer');
var what = document.getElementById('cf-offer-what');
var clock = document.getElementById('cf-offer-clock');
var terms = document.getElementById('cf-offer-terms');
if (!offer || !what || !clock || !terms) return;
var PHASES = [
{ until: Date.UTC(2026, 8, 23, 12, 0, 0), what: 'SimpleX name for 7 years', terms: null },
{ until: Date.UTC(2026, 10, 23, 12, 0, 0), what: 'SimpleX name for 5 years',
terms: 'Invest $500+ during early bird terms.',
wide: 'Invest $500+ during early bird terms, and get the name ahead of public launch.' },
{ until: Infinity, what: 'SimpleX name for 5 years',
terms: 'Invest $500+ during early bird terms.' }
];
var shown = -1;
var digits = null;
var lead = what.parentNode;
var block = offer.parentNode;
(function cfHero() {
var block = document.querySelector('.cf-hero .cf-hero-text');
if (!block) return;
var hero = block.closest('section');
var leadShort = document.querySelector('.cf-hero .lead-short');
var logos = document.querySelectorAll('#navbar .logo img');
var narrow = window.matchMedia('(max-width: 959px) and (orientation: portrait)');
function logoBottom() {
var bottom = 0;
for (var i = 0; i < logos.length; i++) { var r = logos[i].getBoundingClientRect(); if (r.height > 0) bottom = Math.max(bottom, r.bottom); }
return bottom;
}
var canvas = document.createElement('canvas').getContext('2d');
function metrics(el, text) {
var cs = getComputedStyle(el);
canvas.font = cs.fontWeight + ' ' + cs.fontSize + ' ' + cs.fontFamily;
var m = canvas.measureText(text);
if (m.fontBoundingBoxAscent === undefined) return null;
return { asc: m.fontBoundingBoxAscent, desc: m.fontBoundingBoxDescent, inkUp: m.actualBoundingBoxAscent, inkDown: m.actualBoundingBoxDescent, lineHeight: parseFloat(cs.lineHeight) };
}
var probe = document.createElement('span');
probe.style.cssText = 'display:inline-block;width:0;height:0;vertical-align:baseline;overflow:hidden';
function baselineOf(el) {
el.insertBefore(probe, el.firstChild);
var y = probe.getBoundingClientRect().bottom;
el.removeChild(probe);
return y;
}
function blockBaseline(el) { return baselineOf(el); }
function inlineBaseline(el) { return baselineOf(el); }
var raster = document.createElement('canvas');
function inkRows(el, text, baseline) {
var cs = getComputedStyle(el);
var size = parseFloat(cs.fontSize);
var top = Math.floor(baseline - size * 1.5), height = Math.ceil(size * 2.5), width = Math.ceil(size * text.length) + 8;
if (raster.width !== width || raster.height !== height) { raster.width = width; raster.height = height; }
var g = raster.getContext('2d');
g.clearRect(0, 0, width, height);
g.font = cs.fontWeight + ' ' + cs.fontSize + ' ' + cs.fontFamily;
g.fillStyle = '#fff';
g.textBaseline = 'alphabetic';
g.fillText(text, 4, baseline - top);
var px = g.getImageData(0, 0, width, height).data, first = -1, last = -1, y, x;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) { if (px[(y * width + x) * 4 + 3] > 150) { if (first < 0) first = y; last = y; break; } }
}
return first < 0 ? null : { top: top + first, bottom: top + last };
}
function statsInk(figures, labels) {
var top = Infinity, bottom = -Infinity, i, rows;
for (i = 0; i < figures.length; i++) {
var mf = metrics(figures[i], figures[i].textContent);
rows = mf && inkRows(figures[i], figures[i].textContent, blockBaseline(figures[i]));
if (rows) top = Math.min(top, rows.top);
}
for (i = 0; i < labels.length; i++) {
var body = labels[i].textContent.replace(/[gjpqy]/g, 'n');
var ml = metrics(labels[i], body);
rows = ml && inkRows(labels[i], body, inlineBaseline(labels[i]));
if (rows) bottom = Math.max(bottom, rows.bottom);
}
return isFinite(top) && isFinite(bottom) ? { top: top, bottom: bottom } : null;
}
var phoneImg = document.querySelector('.cf-phone');
function veil() {
offer.style.removeProperty('--cf-offer-veil');
if (!narrow.matches || !phoneImg) return;
var phone = phoneImg.getBoundingClientRect();
var arcTop = phone.top - phone.height * 0.4034 + phone.width * 2.349 * 0.2678;
var need = offer.getBoundingClientRect().bottom + 8 - arcTop;
var alpha = Math.max(0, Math.min(1, need / 40)) * 0.82;
if (alpha > 0) offer.style.setProperty('--cf-offer-veil', alpha.toFixed(2));
function fit() {
if (!leadShort) return;
leadShort.style.fontSize = '';
if (!narrow.matches) return;
var cs = getComputedStyle(leadShort);
var base = parseFloat(cs.fontSize);
var box = leadShort.clientWidth - parseFloat(cs.paddingLeft) - parseFloat(cs.paddingRight);
var range = document.createRange();
range.selectNodeContents(leadShort);
var line = range.getBoundingClientRect().width;
if (base > 0 && box > 0 && line > 0) leadShort.style.fontSize = (base * box / line).toFixed(2) + 'px';
}
function place() {
offer.style.marginTop = '';
block.style.transform = '';
veil();
if (narrow.matches) return;
var pill = block.querySelector('.cf-hero-cta .cf-pill');
var figures = block.querySelectorAll('.cf-stats .cf-stat b');
var labels = block.querySelectorAll('.cf-stats .cf-stat span');
var mo = metrics(lead, lead.textContent);
var ink = pill && figures.length && labels.length && mo ? statsInk(figures, labels) : null;
if (!ink) return;
var above = ink.top - Math.round(pill.getBoundingClientRect().bottom);
var text = lead.textContent;
var leadInkTop = blockBaseline(lead) - mo.inkUp;
var base = Math.round(parseFloat(getComputedStyle(offer).marginTop) + (ink.bottom + 1 + above) - leadInkTop);
var best = null;
for (var d = -3; d <= 3; d++) {
offer.style.marginTop = (base + d) + 'px';
var now = statsInk(figures, labels);
var lit = inkRows(lead, text, blockBaseline(lead));
if (!now || !lit) break;
var below = lit.top - now.bottom - 1;
if (best === null || Math.abs(below - above) < Math.abs(best.below - above)) best = { d: d, below: below };
if (below === above) break;
}
if (best) offer.style.marginTop = (base + best.d) + 'px';
if (!hero) return;
if (narrow.matches || !hero) return;
var unit = Math.min(window.innerWidth * 1080 / 1920, window.innerHeight) / 100;
var top = block.getBoundingClientRect().top;
var minTop = logoBottom() + unit * 2;
@@ -1508,59 +1348,9 @@ templateEngineOverride: njk
var down = Math.min(Math.max(0, minTop - top), Math.max(0, spare));
if (down > 0) block.style.transform = 'translateY(' + Math.round(down) + 'px)';
}
function two(n) { return (n < 10 ? '0' : '') + n; }
var leadShort = document.querySelector('.cf-hero .lead-short');
function fitLine(el) {
el.style.fontSize = '';
if (!narrow.matches) return;
var cs = getComputedStyle(el);
var base = parseFloat(cs.fontSize);
var box = el.clientWidth - parseFloat(cs.paddingLeft) - parseFloat(cs.paddingRight);
var range = document.createRange();
range.selectNodeContents(el);
var line = range.getBoundingClientRect().width;
if (base > 0 && box > 0 && line > 0) el.style.fontSize = (base * box / line).toFixed(2) + 'px';
}
function fit() {
fitLine(lead);
if (leadShort) fitLine(leadShort);
}
var narrow = window.matchMedia('(max-width: 959px) and (orientation: portrait)');
var desktop = window.matchMedia('(min-width: 960px)');
function left(ms) {
var total = Math.floor(ms / 1000);
var days = Math.floor(total / 86400);
var rest = total - days * 86400;
var hms = two(Math.floor(rest / 3600)) + ':' + two(Math.floor(rest / 60) % 60) + ':' + two(rest % 60);
return days > 0 ? days + (days === 1 ? ' day ' : ' days ') + hms : hms;
}
function tick() {
var now = Date.now();
var i = 0;
while (i < PHASES.length && now >= PHASES[i].until) i++;
var timed = PHASES[i].until !== Infinity;
var changed = i !== shown;
if (changed) {
shown = i;
what.textContent = PHASES[i].what + (timed ? ':' : '');
var line = desktop.matches && PHASES[i].wide ? PHASES[i].wide : PHASES[i].terms;
if (line !== null) terms.textContent = line;
if (!timed) { clock.textContent = ''; clearInterval(timer); fit(); return; }
}
if (!digits) {
digits = document.createElement('b');
clock.append(' ', digits, ' left');
changed = true;
}
var text = left(PHASES[i].until - now);
if (text.length !== digits.textContent.length) changed = true;
digits.textContent = text;
if (changed) fit();
}
var timer = setInterval(tick, 1000);
tick();
fit();
place();
window.addEventListener('resize', function () { shown = -1; tick(); fit(); place(); });
window.addEventListener('resize', function () { fit(); place(); });
if (document.fonts && document.fonts.ready) document.fonts.ready.then(function () { fit(); place(); });
})();
</script>
@@ -1582,8 +1372,7 @@ templateEngineOverride: njk
}, { threshold: 0.4 })
sections.forEach(function (s) { watch.observe(s) })
var places = [['#cf-hero-invest', 'Invest', 'hero'], ['.cf-close .cf-primary', 'Invest', 'close'], ['.cf-fine-links a[href*="wefunder"]', 'Invest', 'footer'],
['#cf-hero-subscribe', 'Subscribe', 'hero'], ['.cf-hero-corner', 'Subscribe', 'corner'], ['.cf-close .cf-cta-link', 'Subscribe', 'close'],
['#cf-offer-terms a', 'AoE', 'hero']]
['#cf-hero-subscribe', 'Subscribe', 'hero'], ['.cf-hero-corner', 'Subscribe', 'corner'], ['.cf-close .cf-cta-link', 'Subscribe', 'close']]
places.forEach(function (p) {
var el = document.querySelector(p[0])
if (el) el.addEventListener('click', function () { track(p[1], { props: { place: p[2] } }) })