website: lay out the crowdfunding hero on mobile and light theme

The crowdfunding hero shipped desktop + dark only. This completes it for
phones and the light theme so it renders correctly everywhere the flag is on.

Mobile: the content is a one-screen CSS grid (no scroll -- sections are
scroll-snapped). Element rows keep their size; the gap rows distribute the
leftover height by weight with a minimum guard each, so the composition adapts
across phone aspect ratios without the bottom row drifting off. The download
and audit rows, which shipped as fixed px, are re-expressed in viewport-height
units so they scale with the rest.

Light theme: the decorative phones illustration was still leaking on mobile in
dark mode (the .dark background rule out-specified the hide), now cleared in
both themes; the app-store/google-play badge frames are filled black so the
badges read as solid buttons on the light background instead of gray outlines.

Also adds light-theme icon variants for Privacy Guides / Heise / Kuketz and
refreshed socials icons, and drops a sub-pixel reserve-block margin.

homeHero stays "default"; RTL is intentionally deferred (the campaign copy
stays English per the founder).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
another-simple-pixel
2026-06-16 16:33:55 -07:00
co-authored by Claude Opus 4.8
parent 55e685cc0f
commit 688defe2b6
13 changed files with 242 additions and 41 deletions
+1 -1
View File
@@ -266,7 +266,7 @@
"index-hero-download-desktop-btn-title": "Download SimpleX Desktop App",
"index-hero-cf-h1": "Own<br>Share",
"index-hero-cf-h2": "of Your Network",
"index-hero-cf-reserve-h": "Own a share of SimpleX Chat.",
"index-hero-cf-reserve-h": "Own a share <span class=\"cf-brk-d\"></span>of SimpleX <span class=\"cf-brk-m\"></span>Chat.",
"index-hero-cf-reserve-cta": "Reserve now.",
"index-hero-cf-invest": "Invest in SimpleX Chat via Wefunder",
"index-hero-cf-disclaimer": "Disclaimer: SimpleX Chat is testing the waters for a possible Reg CF offering. Were not asking for or accepting any money right now, and we wont accept any if sent. We cant accept any offers to buy securities or take any payments until the official filing is done and its live through a regulated platform. Our testing the waters and your possible indications of interest doesnt create any obligation or commitment of any kind.",
+18 -17
View File
@@ -6,24 +6,27 @@
<div class="content">
{%- if homeHero == 'testing-water' -%}
<h1>{{ "index-hero-h1" | i18n({}, lang) | safe }}</h1>
<h2 class="gradient-text">{{ "index-hero-h2" | i18n({}, lang) | safe }} &rarr;</h2>
<h2 class="gradient-text">{{ "index-hero-h2" | i18n({}, lang) | safe }} <span class="cf-arrow">&rarr;</span></h2>
{%- else -%}
<h1>{{ "index-hero-cf-h1" | i18n({}, lang) | safe }}</h1>
<h2 class="gradient-text">{{ "index-hero-cf-h2" | i18n({}, lang) | safe }}</h2>
{%- endif -%}
<p>{{ "index-hero-p1" | i18n({}, lang) | safe }}</p>
<img class="cf-flag dark:hidden" src="/img/design_3/wefunder-light.webp" alt="">
<img class="cf-flag hidden dark:block" src="/img/design_3/wefunder.webp" alt="">
{%- if homeHero == 'testing-water' -%}
<div class="cf-reserve">
<p class="cf-reserve-h">{{ "index-hero-cf-reserve-h" | i18n({}, lang) | safe }}
<a class="gradient-text" href="{{ reserveUrl }}" target="_blank" rel="noopener">{{ "index-hero-cf-reserve-cta" | i18n({}, lang) | safe }}</a>
</p>
<p class="cf-disclaimer">{{ "index-hero-cf-disclaimer" | i18n({}, lang) | safe }}</p>
<div class="cf-flag-block">
<img class="cf-flag dark:hidden" src="/img/design_3/wefunder-light.webp" alt="">
<img class="cf-flag hidden dark:block" src="/img/design_3/wefunder.webp" alt="">
<div class="cf-reserve">
<p class="cf-reserve-h">{{ "index-hero-cf-reserve-h" | i18n({}, lang) | safe }}
<a class="gradient-text" href="{{ reserveUrl }}" target="_blank" rel="noopener">{{ "index-hero-cf-reserve-cta" | i18n({}, lang) | safe }}</a>
</p>
<p class="cf-disclaimer">{{ "index-hero-cf-disclaimer" | i18n({}, lang) | safe }}</p>
</div>
</div>
{%- else -%}
<img class="cf-flag dark:hidden" src="/img/design_3/wefunder-light.webp" alt="">
<img class="cf-flag hidden dark:block" src="/img/design_3/wefunder.webp" alt="">
<a class="cf-invest gradient-text" href="{{ wefunderUrl }}" target="_blank" rel="noopener">{{ "index-hero-cf-invest" | i18n({}, lang) | safe }}</a>
{%- endif -%}
@@ -47,7 +50,7 @@
<div class="security-btns">
<a title="{{ 'index-security-assessment-title' | i18n({}, lang) }}" href="https://www.trailofbits.com/about" target="_blank">
<img class="dark:hidden" src="/img/trail-of-bits-light.png" alt="Trail of Bits">
<img class="hidden dark:block" src="/img/design_3/publications/trail-of-bits.png" alt="Trail of Bits">
<img class="hidden dark:block" src="/img/trail-of-bits-dark.png" alt="Trail of Bits">
</a>
<a class="box-btn btn-1" title="{{ 'index-security-review-2022-title' | i18n({}, lang) }}" href="/blog/20221108-simplex-chat-v4.2-security-audit-new-website.html">
2022
@@ -61,24 +64,22 @@
</div>
<div class="publications-btns">
<a title="{{ 'index-publications-privacy-guides-title' | i18n({}, lang) }}" href="https://www.privacyguides.org/en/real-time-communication/#simplex-chat" target="_blank">
<img class="dark:hidden" src="/img/privacy-guides-light.png" alt="Privacy Guides">
<img class="dark:hidden" src="/img/design_3/publications/privacy-guides-light.png" alt="Privacy Guides">
<img class="hidden dark:block" src="/img/design_3/publications/privacy-guides.png" alt="Privacy Guides">
</a>
<a title="{{ 'index-publications-whonix-title' | i18n({}, lang) }}" href="https://www.whonix.org/wiki/Chat#Recommendation" target="_blank">
<img class="whonix dark:hidden" src="/img/whonix-light.png" alt="Whonix">
<img class="whonix hidden dark:block" src="/img/design_3/publications/whonix.png" alt="Whonix">
<img class="whonix" src="/img/design_3/publications/whonix.png" alt="Whonix">
</a>
<a title="{{ 'index-publications-heise-title' | i18n({}, lang) }}" href="https://www.heise.de/suche/?q=simplex+chat&sort_by=date&rm=search" target="_blank">
<img class="dark:hidden" src="/img/heise-light.png" alt="Heise">
<img class="dark:hidden" src="/img/design_3/publications/heise-light.png" alt="Heise">
<img class="hidden dark:block" src="/img/design_3/publications/heise.png" alt="Heise">
</a>
<a title="{{ 'index-publications-kuketz-title' | i18n({}, lang) }}" href="https://www.kuketz-blog.de/simplex-eindruecke-vom-messenger-ohne-identifier/" target="_blank">
<img class="kuketz dark:hidden" src="/img/kuketz-blog-light.png" alt="Kuketz Blog">
<img class="kuketz dark:hidden" src="/img/design_3/publications/kuketz-blog-light.png" alt="Kuketz Blog">
<img class="kuketz hidden dark:block" src="/img/design_3/publications/kuketz-blog.png" alt="Kuketz Blog">
</a>
<a title="{{ 'index-publications-optout-title' | i18n({}, lang) }}" href="https://optoutpod.com/episodes/s3e02-simplexchat/" target="_blank">
<img class="dark:hidden" src="/img/optout.jpg" alt="Opt Out">
<img class="hidden dark:block" src="/img/design_3/publications/optout.png" alt="Opt Out">
<img src="/img/design_3/publications/optout.png" alt="Opt Out">
</a>
</div>
</div>
+223 -23
View File
@@ -1672,35 +1672,56 @@ section.page.footer {
/* testing-water: standalone flag phone + reserve block, bottom-right (matches the baked-in
flag position of the full background). FIRST PASS — positions to calibrate visually. */
.cf-hero--testing-water .cf-flag {
/* testing-water: flag + Reserve block are ONE positioned unit (flex), so they
stay attached when the block's width changes. */
.cf-hero--testing-water .cf-flag-block {
position: absolute;
bottom: calc(var(--sec-vhu) * 8);
height: calc(var(--sec-vhu) * 37.38);
bottom: calc(var(--sec-vhu) * 15);
left: 82%; /* horizontal CENTER of the group (it floats in the gutter, not pinned to the edge) */
transform: translateX(-50%);
width: max-content; /* size to content, so moving the position never squeezes the text */
display: flex;
align-items: center;
}
.cf-flag-block .cf-flag {
height: calc(var(--sec-vhu) * 37.42);
width: auto;
}
[dir="ltr"] .cf-hero--testing-water .cf-flag {
right: calc(var(--sec-vwu) * 22);
}
[dir="rtl"] .cf-hero--testing-water .cf-flag {
left: calc(var(--sec-vwu) * 22);
}
.cf-reserve {
position: absolute;
bottom: calc(var(--sec-vhu) * 10);
width: calc(var(--sec-vwu) * 20);
position: relative;
top: calc(var(--sec-vhu) * 8.34);
width: calc(var(--sec-vwu) * 11.7);
text-align: left;
}
[dir="ltr"] .cf-reserve {
right: calc(var(--sec-vwu) * 2);
[dir="rtl"] .cf-reserve {
text-align: right;
}
[dir="rtl"] .cf-reserve {
left: calc(var(--sec-vwu) * 2);
text-align: right;
/* nudge the inline arrow glyph down to sit on the text line */
.cf-arrow {
vertical-align: -0.08em;
}
/* light theme: cf-hero links + subheadline use the blue gradient (not the global gold);
scoped to .cf-hero so the rest of the site's .gradient-text is untouched */
:root:not(.dark) .cf-hero .gradient-text {
background-image: linear-gradient(100deg, #001aa7 0%, #0095e7 100%);
}
/* light theme: "Security Audits" label reads black on the light gradient */
:root:not(.dark) .cf-hero .security-audits {
color: #000000;
}
/* The bordered badges (App Store / Google Play / F-Droid) get the #4f4f4f frame + 6px radius that
unifies their height and corners, but the badge art's own corners/edges are tighter, so on the
light cf-hero the gap inside the frame shows through. Fill it black so the badge merges with the
frame into one solid rounded button (invisible on the dark cover, so scoped to cf-hero only). */
.cf-hero .socials a img:not(.no-border) {
background-color: #000;
}
.cf-reserve-h {
@@ -1708,13 +1729,17 @@ section.page.footer {
font-weight: 200;
font-size: calc(var(--sec-vwu) * 1.5625);
line-height: 1.25;
color: #023789;
color: #000000;
}
.cf-reserve-h a {
font-weight: 500;
}
/* reserve-heading line break: after "Own a share" on desktop, after "of SimpleX" on mobile */
.cf-brk-d { display: block; }
.cf-brk-m { display: none; }
.dark .cf-reserve-h {
color: #ffffff;
}
@@ -1723,7 +1748,182 @@ section.page.footer {
font-family: "Manrope", sans-serif;
font-weight: 300;
font-size: calc(var(--sec-vwu) * 0.52);
line-height: 1.35;
margin-top: calc(var(--sec-vhu) * 1.5);
color: #405585;
line-height: 1.25;
margin-top: calc(var(--sec-vhu) * 0.9);
color: #8ca0cd;
}
.dark .cf-disclaimer {
color: #526da9;
}
/* ===== Crowdfunding hero — mobile (≤959px). Calibrated to the mobile mockup. ===== */
@media (max-width: 959px) {
/* One full screen (height:100svh — matches the mockup's full-bleed composition) laid out as a
grid. Element rows are `auto`; each distributed gap is a fixed guard track + an fr share track
(see grid-template-rows below), so gap = guard + weight's share of the leftover. The leftover
(~24% of the screen on a normal phone, by design) fills the gaps per the --w-* weights —
calibrate those to place elements as in the mockup (small gap above the headline; the bulk
around the flag). Guards never collapse; only an extreme aspect can force an overflow. */
section.page.cf-hero--testing-water .content {
display: grid;
height: 100svh;
width: var(--sec-w);
padding: 0;
gap: 0;
justify-items: center;
--gz: calc(var(--sec-vhu) * 1.5); /* min guard for the distributed gaps */
--gz-flag: 0; /* guard around the flag — ×0, no fixed minimum */
--gz-bot: calc(var(--gz) * 0.7); /* below-audits guard (own multiplier of --gz) */
--ig: calc(var(--sec-vhu) * 1); /* fixed internal guard between headline lines */
--w-top: 58fr; /* above headline — the mockup has a lot of air above the headline */
--w-hf: 35fr; /* headline → flag */
--w-fd: 25fr; /* flag → downloads */
--w-da: 0fr; /* downloads → audits — guard only, no extra share */
--w-bot: 16fr; /* below audits */
/* Each distributed gap is TWO rows: a fixed guard track + an fr share track, so the gap =
guard + (weight's share of the leftover). Leftover = 100svh elements all guards, so
shrinking a guard frees space that the fr tracks redistribute by weight — elements shift
and the flag gets squeezed, exactly as expected. Row map: 1 top-guard · 2 top-fr · 3 h1 ·
4 ig · 5 h2 · 6 ig · 7 p · 8 hf-guard · 9 hf-fr · 10 flag · 11 fd-guard · 12 fd-fr ·
13 downloads · 14 da-guard · 15 da-fr · 16 audits · 17 bot-guard · 18 bot-fr. */
grid-template-rows:
var(--gz) var(--w-top)
auto
var(--ig)
auto
var(--ig)
auto
var(--gz-flag) var(--w-hf)
auto
var(--gz-flag) var(--w-fd)
auto
var(--gz) var(--w-da)
auto
var(--gz-bot) var(--w-bot);
}
/* .area is normally locked to the design canvas (height:var(--sec-h)), which is shorter than a
tall window and centered in the section — that offset is what pushed the grid's bottom row
off-screen. Fill the viewport so the grid maps 1:1 to it. */
section.page.cf-hero--testing-water .area {
height: 100svh;
}
.cf-hero--testing-water .content > h1 { grid-row: 3; }
.cf-hero--testing-water .content > h2 { grid-row: 5; }
.cf-hero--testing-water .content > p { grid-row: 7; }
.cf-hero--testing-water .cf-flag-block { grid-row: 10; }
.cf-hero--testing-water .socials { grid-row: 13; }
.cf-hero--testing-water .security-btns { grid-row: 16; }
.cf-hero .content h1 {
font-size: calc(var(--sec-vwu) * 22.5);
line-height: 0.85;
}
.cf-hero .content h2 {
font-size: calc(var(--sec-vwu) * 9.35);
}
/* no arrow after the subheadline on mobile */
.cf-arrow {
display: none;
}
/* mobile: reserve-heading breaks after "of SimpleX" instead of after "Own a share" */
.cf-brk-d { display: none; }
.cf-brk-m { display: block; }
.cf-hero .content > p {
font-size: calc(var(--sec-vwu) * 4.7);
line-height: 1.2;
max-width: calc(var(--sec-vwu) * 93);
}
/* desktop decorative phones are hidden on mobile — only the flag phone remains.
The .dark variants are listed too: the dark bg rules are `.dark .cf-hero--…` (higher
specificity), so without these a sliver of the illustration still showed in dark mode. */
.cf-hero--testing-water,
.cf-hero--crowdfunding-full,
.dark .cf-hero--testing-water,
.dark .cf-hero--crowdfunding-full {
background-image: none;
}
/* flag + Reserve in one grid row (placed above): reserve text on the left, flag phone on the
right (row-reverse vs the flag-first DOM order). Not absolutely positioned. */
.cf-hero--testing-water .cf-flag-block {
position: static;
left: auto;
transform: none;
width: auto;
flex-direction: row-reverse;
justify-content: center;
align-items: center;
gap: calc(var(--sec-vwu) * 0.75);
min-height: 0; /* allow the row to shrink with the flag on a short window */
}
.cf-flag-block .cf-flag {
width: auto;
height: auto;
/* design height 23vhu, but capped at a share of the real screen so it shrinks first on a
short/odd-aspect window instead of pushing the bottom rows off (no scroll here) */
max-height: min(calc(var(--sec-vhu) * 23), 25svh);
}
.cf-reserve {
position: static;
top: auto;
margin-inline-start: 0;
width: calc(var(--sec-vwu) * 53.5);
}
.cf-reserve-h {
font-size: calc(var(--sec-vwu) * 4.7);
}
.cf-disclaimer {
font-size: calc(var(--sec-vwu) * 1.78);
line-height: 1.25;
}
/* --- Bottom rows ship as fixed px (40px badges, 36px audit icons/pills, 1421px text),
so they don't shrink with the window and used to overflow a short one. Re-express them
in viewport-height units; two knobs drive each row, the ratios keep the original look.
!important is needed where the base rules use it. --- */
.cf-hero {
--cf-dl: 5.7; /* downloads row unit (vhu) */
--cf-aud: 4.4; /* audits row unit (vhu) */
}
.cf-hero .socials {
min-height: 0;
}
.cf-hero .socials a img,
.cf-hero .desktop-app-btn .btn-content {
height: calc(var(--sec-vhu) * var(--cf-dl));
}
.cf-hero .desktop-app-btn .btn-content img {
height: calc(var(--sec-vhu) * var(--cf-dl) * 0.6) !important;
}
.cf-hero .desktop-app-btn .btn-content p {
font-size: calc(var(--sec-vhu) * var(--cf-dl) * 0.275) !important;
}
.cf-hero .security-btns img {
height: calc(var(--sec-vhu) * var(--cf-aud));
}
.cf-hero .security-btns .box-btn {
height: calc(var(--sec-vhu) * var(--cf-aud));
font-size: calc(var(--sec-vhu) * var(--cf-aud) * 0.58) !important;
padding: 0 calc(var(--sec-vhu) * var(--cf-aud) * 0.3);
}
.cf-hero .security-audits {
font-size: calc(var(--sec-vhu) * var(--cf-aud) * 0.39) !important;
}
.cf-hero .security-btns {
gap: calc(var(--sec-vhu) * var(--cf-aud) * 0.33);
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 212 KiB

After

Width:  |  Height:  |  Size: 12 KiB