Files
deepstock/src/styles.css
Dorian 8f74118a28 fix: stack the affiliate button full-width on mobile rec items
Replaced the inline-styled cost + button row inside each .rec-item with
a .rec-item-foot class so it can respond to media queries. Desktop
(>=768px) keeps the existing layout — cost left, button right via
space-between. Mobile (<768px) breaks the button onto its own row
beneath the cost and stretches it to full width with chunkier vertical
padding for a comfortable tap target.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 10:52:40 +01:00

1869 lines
60 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
:root {
--black: #FAFAFA;
--deep: #F2F2F0;
--panel: #FAFAFA;
--card: #FAFAFA;
--border: #E4E4E0;
--muted: #C8C8C4;
--text-dim: #8A8A84;
--text: #5A5A54;
--bright: #3A3A34;
--white: #1A1A18;
--red: #5A9A78;
--red-dim: #E8F2EC;
--orange: #4A8A68;
--orange-dim: #E8F2EC;
--yellow: #5A9A78;
--green: #5A9A78;
--green-dim: #E8F2EC;
--green-bright: #4A8A68;
--teal: #5A9090;
--accent: #5A9A78;
--accent-dim: #E8F2EC;
--font-display: 'DM Serif Display', serif;
--font-body: 'Barlow', sans-serif;
--font-mono: 'Space Mono', monospace;
--radius: 10px;
--radius-lg: 16px;
--trans: all 0.25s cubic-bezier(0.4,0,0.2,1);
}
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; -webkit-tap-highlight-color: transparent;
-webkit-overflow-scrolling: touch; }
body { background: #FAFAFA; color: var(--text); font-family: var(--font-body); font-size: 16px; line-height: 1.6; height: 100vh; height: 100dvh; overflow: hidden; }
/* Vue mount point — match the body's full viewport so .app inside can
reach full height the way it did pre-Vue. The original <main class="app">
was a direct child of <body>; the new wrapper div has to forward those
dimensions or the hero stops short. dvh tracks the visible viewport so
mobile centering survives the URL-bar show/hide. */
#app {
height: 100vh;
height: 100dvh;
display: flex;
flex-direction: column;
}
/* ── HEADER ── */
.site-header {
position: fixed; top: 0; left: 0; right: 0; z-index: 100;
background: rgba(250,250,250,0.92);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-bottom: 1px solid var(--border);
padding: 0 24px;
height: 60px;
display: flex; align-items: center; justify-content: space-between;
}
@media (min-width: 768px) {
.site-header { padding: 0 28px; }
}
.logo {
font-family: var(--font-display);
font-weight: 400;
font-size: 20px;
letter-spacing: 0.02em;
color: var(--white);
}
.logo .b { color: var(--red); }
.header-right { display: flex; align-items: center; gap: 12px; }
.lang-toggle {
display: flex;
background: var(--panel);
border: 1px solid var(--border);
border-radius: 0;
overflow: hidden;
}
.lang-btn {
padding: 5px 12px;
border: none;
background: none;
font-family: var(--font-mono);
font-size: 11px;
font-weight: 700;
letter-spacing: 0.1em;
color: var(--text-dim);
cursor: pointer;
transition: var(--trans);
}
.lang-btn.active { background: var(--red); color: #FFFFFF; }
/* ── APP ── */
.app { padding-top: 0; height: 100vh; height: 100dvh; display: flex; flex-direction: column; overflow: hidden; }
/* ── HERO ── */
.hero {
position: relative;
/* asymmetric vertical padding shifts the centered content past the fixed header
and compensates for the scenario-strip below — net effect: visually centered on the viewport */
padding: 100px 16px 24px;
text-align: center;
background: url('/images/bg-1.jpg') center/cover no-repeat;
overflow: hidden;
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.hero-eyebrow {
position: relative; z-index: 1;
font-family: var(--font-body);
font-size: 11px;
letter-spacing: 0.3em;
text-transform: uppercase;
color: #0a0a0a;
margin-bottom: 12px;
animation: fadeUp 1s ease both;
font-weight: 400;
}
.hero h1 {
position: relative; z-index: 1;
font-family: var(--font-display);
font-weight: 400;
/* Default (DE / "Kammergut") — divisor ≈ rendered-text-to-font-size
ratio of the wider wordmark in DM Serif Display at 0.05em tracking.
EN ("Deepstock") gets a smaller divisor below to fill at its own
ratio. -32px matches the hero's 16px padding each side. */
font-size: calc((100vw - 32px) / 6);
line-height: 1;
letter-spacing: 0.05em;
color: #1A1A18;
margin-bottom: 40px;
animation: fadeUp 1s 0.15s ease both;
}
/* Mobile — soften the bg image to 50% by overlaying the body fill */
@media (max-width: 767px) {
.hero {
background: linear-gradient(rgba(250,250,250,0.5), rgba(250,250,250,0.5)), url('/images/bg-1.jpg') center/cover no-repeat;
}
}
/* Tablet — same fill behaviour as mobile (hero padding stays 16px
each side). */
@media (min-width: 768px) {
.hero h1 { font-size: calc((100vw - 32px) / 6); }
}
@media (min-width: 900px) {
.hero h1 { font-size: clamp(120px, 14vw, 176px); }
}
/* English brand ("Deepstock") — narrower wordmark needs a smaller
divisor (≈ ratio measured at 0.05em tracking) to fill the same
16px-padded width as the wider Kammergut. */
html[lang="en"] .hero h1 { font-size: calc((100vw - 32px) / 5.2); }
@media (min-width: 768px) {
html[lang="en"] .hero h1 { font-size: calc((100vw - 32px) / 5.2); }
}
@media (min-width: 900px) {
html[lang="en"] .hero h1 { font-size: clamp(120px, 17vw, 220px); }
}
.hero h1 .b { color: #5A9A78; }
/* Trademark mark — only auto-attached to the small header logo. The
hero H1 uses an explicit sibling .brand-tm span instead, since CSS
filters on the H1 (paint-3d) would otherwise pull ™ into the gloss. */
.logo[data-i18n="brand"]::after {
content: "™";
font-size: 0.4em;
vertical-align: super;
letter-spacing: 0;
}
/* Hero brand line — flex wrapper so ™ can sit next to the painted H1
without being inside the H1's filter scope. The wrapper takes over
the H1's bottom margin and entrance animation so the line moves
together. */
.hero .brand-line {
display: inline-block;
white-space: nowrap;
position: relative; z-index: 1;
margin: 0 auto 40px;
animation: fadeUp 1s 0.15s ease both;
}
.hero .brand-line h1.paint-3d {
display: inline-block;
vertical-align: top;
margin-bottom: 0;
animation: none;
}
.brand-tm {
display: inline-block;
vertical-align: super;
font-family: var(--font-display);
font-weight: 400;
/* 1/5 of H1 size to match the small superscript scale used elsewhere */
font-size: calc((100vw - 32px) / 25);
line-height: 1;
color: #1A1A18;
letter-spacing: 0;
margin-left: 0.05em;
}
@media (min-width: 768px) {
.brand-tm { font-size: calc((100vw - 64px) / 25); }
}
@media (min-width: 900px) {
.brand-tm { font-size: clamp(24px, 2.8vw, 35px); }
}
/* Glossy 3D paint effect on the brand title — no hover state by design,
the wordmark holds its painted look regardless of pointer position. */
.hero h1.paint-3d {
filter: url(#paintGloss);
-webkit-filter: url(#paintGloss);
/* subtle vertical sheen — top catches light, bottom sinks back into the paint */
background: linear-gradient(180deg, #2a2a26 0%, #1A1A18 45%, #060604 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
padding: 0.12em 0.08em 0.2em;
}
.hero-sub {
position: relative; z-index: 1;
font-family: var(--font-body);
font-size: 13px;
letter-spacing: 0.3em;
text-transform: uppercase;
font-weight: 400;
color: #0a0a0a;
max-width: 520px;
margin: 0 auto 40px;
line-height: 1.6;
animation: fadeUp 1s 0.3s ease both;
}
.cta-btn {
display: inline-flex;
align-items: center;
gap: 10px;
font-family: var(--font-body);
font-weight: 400;
font-size: 13px;
letter-spacing: 0.2em;
text-transform: uppercase;
padding: 18px 48px;
border-radius: 0;
cursor: pointer;
transition: color 0.3s ease, var(--trans);
animation: fadeUp 1s 0.45s ease both;
/* Lift above .hero::after radial fade so the button isn't washed out */
z-index: 2;
}
.cta-btn span { position: relative; }
/* ── EMAIL CAPTURE ── */
.email-section {
background: var(--panel);
border-bottom: 1px solid var(--border);
padding: 28px 24px;
}
.email-inner {
max-width: 540px;
margin: 0 auto;
}
.email-label {
font-family: var(--font-mono);
font-size: 10px;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(--red);
margin-bottom: 8px;
}
.email-title {
font-family: var(--font-display);
font-weight: 800;
font-size: 20px;
color: var(--white);
margin-bottom: 6px;
}
.email-sub {
font-size: 13px;
color: var(--text-dim);
margin-bottom: 16px;
line-height: 1.6;
}
.email-form {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.email-input {
flex: 1;
min-width: 200px;
padding: 13px 16px;
background: var(--card);
border: 1.5px solid var(--border);
border-radius: var(--radius);
color: var(--white);
font-family: var(--font-body);
font-size: 15px;
outline: none;
transition: var(--trans);
}
.email-input:focus { border-color: var(--red); }
.email-input::placeholder { color: var(--muted); }
.email-submit {
padding: 13px 24px;
background: var(--red);
border: none;
border-radius: var(--radius);
color: #0C0C0E;
font-family: var(--font-body);
font-weight: 600;
font-size: 14px;
letter-spacing: 0.1em;
text-transform: uppercase;
cursor: pointer;
transition: var(--trans);
white-space: nowrap;
}
.email-submit:hover { background: #7AB498; }
.email-success {
display: none;
padding: 14px 20px;
background: var(--green-dim);
border: 1px solid var(--green);
border-radius: var(--radius);
color: var(--green-bright);
font-size: 14px;
font-weight: 600;
margin-top: 10px;
}
.email-success.show { display: block; }
.email-note {
font-size: 11px;
color: var(--muted);
margin-top: 10px;
}
/* ── SCENARIO STRIP ── */
.scenario-strip {
display: flex;
overflow-x: auto;
gap: 12px;
padding: 20px 24px;
background: var(--panel);
border-bottom: 1px solid var(--border);
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
}
.scenario-strip::-webkit-scrollbar { display: none; }
.scenario-pill {
flex-shrink: 0;
display: flex;
align-items: center;
gap: 8px;
padding: 10px 18px;
border-radius: 40px;
border: 1px solid rgba(255,255,255,0.06);
font-family: var(--font-body);
font-weight: 500;
font-size: 13px;
letter-spacing: 0.03em;
white-space: nowrap;
color: var(--text-dim);
background: rgba(255,255,255,0.02);
}
.pill-1 { border-color: rgba(90,154,120,0.2); color: var(--red); }
.pill-2 { border-color: rgba(90,154,120,0.15); color: var(--text); }
.pill-3 { border-color: rgba(90,154,120,0.15); color: var(--text); }
.pill-4 { border-color: rgba(106,170,138,0.2); color: var(--green); }
.pill-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: 0.6; }
/* ── QUESTIONNAIRE ── */
.quiz-section {
width: 100%;
min-height: 100vh;
min-height: 100dvh;
display: flex;
flex-direction: column;
}
.quiz-section.hidden { display: none !important; }
.quiz-progress-bar {
position: fixed;
top: 0;
left: 0; right: 0;
background: rgba(250,250,250,0.92);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-bottom: 1px solid var(--border);
/* Match .site-header dimensions: 60px tall, 24px mobile / 28px desktop padding */
height: 60px;
padding: 0 24px;
z-index: 110;
}
@media (min-width: 768px) {
.quiz-progress-bar { padding: 0 28px; }
}
body.quiz-active .site-header { display: none; }
.quiz-progress-bar .progress-wrap { max-width: 540px; margin: 0 auto; }
.quiz-progress-bar .progress-header { margin-bottom: 6px; }
.quiz-content {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
padding: 80px 24px 110px;
width: 100%;
}
.quiz-content #question-container {
width: 100%;
max-width: 540px;
margin: 0 auto;
}
.quiz-footer {
position: fixed;
bottom: 0;
left: 0; right: 0;
background: rgba(250,250,250,0.92);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-top: 1px solid var(--border);
padding: 14px 24px max(14px, env(safe-area-inset-bottom));
z-index: 90;
}
.quiz-footer .q-nav { max-width: 540px; margin: 0 auto; }
.quiz-footer:empty { display: none; }
.progress-wrap { margin-bottom: 0; }
.progress-header { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 10px; }
.progress-label { font-family: var(--font-mono); font-size: 11px; color: var(--text-dim); letter-spacing: 0.1em; text-transform: uppercase; }
.progress-count { font-family: var(--font-mono); font-size: 13px; color: var(--bright); }
.progress-bar { height: 3px; background: var(--muted); border-radius: 99px; overflow: hidden; }
.progress-fill { height: 100%; background: var(--red); border-radius: 99px; transition: width 0.5s cubic-bezier(0.4,0,0.2,1); }
.question-card {
background: var(--card);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 28px 24px;
animation: fadeUp 0.35s ease both;
}
.q-step { font-family: var(--font-mono); font-size: 10px; color: var(--red); letter-spacing: 0.15em; text-transform: uppercase; margin-bottom: 12px; }
.q-text { font-family: var(--font-display); font-weight: 400; font-size: 24px; color: var(--white); line-height: 1.3; margin-bottom: 8px; }
.q-sub { font-size: 13px; color: var(--text-dim); line-height: 1.6; margin-bottom: 24px; }
.q-options { display: flex; flex-direction: column; gap: 10px; }
.q-opt {
display: flex; align-items: center; gap: 14px;
padding: 14px 16px;
background: var(--panel);
border: 1.5px solid var(--border);
border-radius: var(--radius);
cursor: pointer;
transition: var(--trans);
-webkit-tap-highlight-color: transparent;
-webkit-overflow-scrolling: touch;
}
.q-opt:hover { border-color: rgba(255,255,255,0.08); background: var(--deep); }
.q-opt.selected { border-color: var(--red); background: rgba(90,154,120,0.06); }
.q-opt.selected .opt-radio { border-color: var(--red); }
.q-opt.selected .opt-radio::after { display: block; }
.opt-radio {
width: 18px; height: 18px; border-radius: 50%;
border: 1.5px solid var(--muted);
flex-shrink: 0; position: relative; transition: var(--trans);
}
.opt-radio::after {
content: ''; display: none;
position: absolute; top: 50%; left: 50%;
transform: translate(-50%,-50%);
width: 8px; height: 8px;
background: var(--red); border-radius: 50%;
}
.opt-label { font-size: 15px; color: var(--bright); line-height: 1.4; }
.opt-sub { font-size: 12px; color: var(--text-dim); margin-top: 2px; }
.q-opt.multi .opt-radio { border-radius: 4px; }
.q-opt.multi.selected .opt-radio { border-color: var(--red); background: var(--red); border-radius: 4px; }
.q-opt.multi.selected .opt-radio::after {
display: block; content: '✓'; color: white; font-size: 11px; font-weight: bold;
background: none; width: auto; height: auto; top: 50%; left: 50%;
transform: translate(-50%,-55%); border-radius: 0;
}
.slider-wrap { padding: 8px 0; }
.slider-labels { display: flex; justify-content: space-between; margin-bottom: 12px; }
.slider-labels span { font-size: 12px; color: var(--text-dim); font-family: var(--font-mono); }
input[type=range] { width: 100%; -webkit-appearance: none; appearance: none; height: 4px; background: var(--muted); border-radius: 99px; outline: none; cursor: pointer; }
/* Slider thumb — dark green paint style. CSS-only approximation of the
SVG paintGlossBtn filter the CTA buttons use: a #2a3010 base with a
linear gradient simulating the embossed top-highlight / bottom-shadow,
plus an inset top stroke and a soft drop shadow. */
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 22px; height: 22px;
border-radius: 50%;
background: linear-gradient(180deg, #3a4220 0%, #2a3010 55%, #161a08 100%);
border: 1px solid rgba(0,0,0,0.40);
cursor: pointer;
box-shadow:
inset 0 1px 0 rgba(255,236,200,0.22),
0 2px 6px rgba(0,0,0,0.30),
0 0 0 4px rgba(42,48,16,0.10);
}
input[type=range]::-moz-range-thumb {
width: 22px; height: 22px;
border-radius: 50%;
background: linear-gradient(180deg, #3a4220 0%, #2a3010 55%, #161a08 100%);
border: 1px solid rgba(0,0,0,0.40);
cursor: pointer;
box-shadow:
inset 0 1px 0 rgba(255,236,200,0.22),
0 2px 6px rgba(0,0,0,0.30),
0 0 0 4px rgba(42,48,16,0.10);
}
.slider-val { text-align: center; font-family: var(--font-display); font-weight: 800; font-size: 32px; color: var(--white); margin-top: 16px; }
.slider-val span { font-size: 18px; color: var(--text-dim); margin-left: 4px; }
.q-nav { display: flex; gap: 12px; }
.btn-back { flex: 1; height: 52px; background: var(--panel); border: 1px solid var(--border); border-radius: 0; color: var(--text-dim); font-family: var(--font-body); font-weight: 600; font-size: 14px; letter-spacing: 0.1em; text-transform: uppercase; cursor: pointer; transition: var(--trans); display: flex; align-items: center; justify-content: center; }
.btn-back:hover { border-color: var(--muted); color: var(--text); }
.btn-next { flex: 1; height: 52px; background: var(--red); border: none; border-radius: 0; color: #FFFFFF; font-family: var(--font-body); font-weight: 600; font-size: 14px; letter-spacing: 0.1em; text-transform: uppercase; cursor: pointer; transition: var(--trans); box-shadow: 0 2px 20px rgba(90,154,120,0.15); }
.btn-next:hover { background: #C8A870; }
.btn-next:disabled { background: var(--muted); box-shadow: none; cursor: not-allowed; color: var(--deep); }
/* ── RESULTS ── */
.results-section { padding: 84px 20px 80px; max-width: 600px; margin: 0 auto; width: 100%; display: none; }
@media (min-width: 768px) {
/* Desktop — bump the content column ~15% so the result panels and
recommendation cards have more breathing room on a wide viewport. */
.results-section { max-width: 690px; }
}
.results-section.active { display: block; }
/* Risk banner — wrapper provides positioning + padding so risk-* variants
can paint their fill via ::before (the dark-green paint variant uses an
SVG gloss filter that needs an isolated stacking context). */
.risk-banner {
position: relative;
isolation: isolate;
overflow: hidden;
padding: 28px 24px;
border-radius: var(--radius-lg);
margin-bottom: 24px;
text-align: center;
animation: fadeUp 0.4s ease both;
}
.risk-level { font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.2em; text-transform: uppercase; margin-bottom: 10px; opacity: 0.85; }
/* Heading typeface unified with the button font (Barlow / var(--font-body))
instead of the DM Serif display face — keeps the assessment headings in
the same family as the CTA buttons. */
.risk-title {
font-family: var(--font-body);
font-weight: 800;
font-size: 36px;
letter-spacing: 0.05em;
text-transform: uppercase;
line-height: 1;
margin-bottom: 10px;
}
.risk-desc { font-size: 14px; opacity: 0.9; line-height: 1.6; }
/* Risk variants — each state wears a paint card in its own deep tint.
::before carries the painted fill (paintGlossBtn filter for the glossy
embossed look that the CTA buttons use); the wrapper itself is just
the drop shadow + positioning context. Text colours flip to warm cream
for legibility on the dark backgrounds. */
.risk-critical,
.risk-high,
.risk-medium,
.risk-low {
background: transparent;
border: none;
box-shadow: 0 8px 18px rgba(0,0,0,0.18);
}
.risk-critical::before,
.risk-high::before,
.risk-medium::before,
.risk-low::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
z-index: -1;
filter: url(#paintGlossBtn);
-webkit-filter: url(#paintGlossBtn);
}
.risk-critical::before { background: #5A1818; } /* deep maroon — critical */
.risk-high::before { background: #5A3818; } /* deep amber — high */
.risk-medium::before { background: #4A3A10; } /* dark olive — moderate */
.risk-low::before { background: #2A3010; } /* dark green — prepared */
.risk-critical .risk-level,
.risk-critical .risk-title,
.risk-critical .risk-desc,
.risk-high .risk-level,
.risk-high .risk-title,
.risk-high .risk-desc,
.risk-medium .risk-level,
.risk-medium .risk-title,
.risk-medium .risk-desc,
.risk-low .risk-level,
.risk-low .risk-title,
.risk-low .risk-desc { color: #f4ecd8; }
/* Scenario tabs — flat row inside the white-paint Recommendations panel.
No outer container border/padding (the panel frame already provides
that); inactive tabs are quiet text buttons. The active tab wears the
green-paint CTA look (same paint gloss + #2a3010 fill as the protein
button) so the current scenario reads at a glance. */
.scenario-tabs {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 6px;
background: transparent;
border: none;
border-radius: 0;
padding: 0;
margin-bottom: 16px;
animation: fadeUp 0.4s 0.1s ease both;
}
@media (min-width: 768px) {
/* Desktop has room for one row of 4. */
.scenario-tabs { grid-template-columns: repeat(4, 1fr); }
}
.s-tab {
flex: 1;
position: relative;
isolation: isolate;
padding: 10px 6px;
border: none;
background: transparent;
border-radius: 4px;
font-family: var(--font-body);
font-weight: 400;
font-size: 11px;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--text-dim);
cursor: pointer;
transition: color 0.2s ease;
text-align: center;
line-height: 1.3;
}
.s-tab:hover { color: var(--text); }
/* Active state — green-paint button. ::before holds the glossy fill so
the text colour stays solid against the dark green. */
.s-tab.active-s1,
.s-tab.active-s2,
.s-tab.active-s3,
.s-tab.active-s4 {
color: #f4ecd8;
}
.s-tab.active-s1::before,
.s-tab.active-s2::before,
.s-tab.active-s3::before,
.s-tab.active-s4::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
z-index: -1;
background: #2a3010;
filter: url(#paintGlossBtn);
-webkit-filter: url(#paintGlossBtn);
transition: filter 0.6s ease;
}
/* Recommendation cards — wear the white-paint inner-item look (#F0F0F0 +
embossed shadow + inset highlight), parallel to the .q-opt items inside
the question card. The rec-cards sit inside the .result-panel which is
#FAFAFA, mirroring the question-card / q-opt nesting. Text colours flip
to dark for legibility on the light background. */
.rec-cards { animation: fadeUp 0.4s 0.15s ease both; }
.rec-card {
background: #F0F0F0;
border: 1px solid rgba(0,0,0,0.06);
border-radius: var(--radius);
margin-bottom: 12px;
overflow: hidden;
box-shadow: 0 3px 6px rgba(0,0,0,0.06), inset 0 1px 0 rgba(255,255,255,0.7);
}
.rec-header { padding: 14px 16px; display: flex; align-items: center; gap: 12px; border-bottom: 1px solid rgba(0,0,0,0.06); }
/* Green-paint icon chip — matches the painted CTA buttons. ::before
carries the dark-green fill with the gloss filter; the icon SVG inside
inherits the warm-cream stroke colour via currentColor. */
.rec-icon {
position: relative;
isolation: isolate;
width: 40px; height: 40px;
border-radius: 10px;
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
color: #f4ecd8;
}
.rec-icon::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
z-index: -1;
background: #2a3010;
filter: url(#paintGlossBtn);
-webkit-filter: url(#paintGlossBtn);
}
.rec-cat { font-family: var(--font-mono); font-size:14px; color: var(--text-dim); letter-spacing: 0.12em; text-transform: uppercase; }
.rec-title { font-family: var(--font-display); font-weight: 400; font-size: 18px; color: var(--text); line-height: 1.2; }
.priority-badge { margin-left: auto; padding: 4px 10px; border-radius: 99px; font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.1em; font-weight: 700; flex-shrink: 0; }
.p-critical { background: rgba(90,154,120,0.10); color: var(--red); border: 1px solid rgba(90,154,120,0.30); }
.p-high { background: rgba(184,152,106,0.12); color: var(--orange); border: 1px solid rgba(184,152,106,0.30); }
.p-medium { background: rgba(90,154,120,0.08); color: var(--green-bright); border: 1px solid rgba(90,154,120,0.20); }
.rec-body { padding: 14px 16px; }
.rec-items { display: flex; flex-direction: column; gap: 12px; }
.rec-item { display: flex; flex-direction: column; gap: 8px; padding-bottom: 12px; border-bottom: 1px solid rgba(0,0,0,0.06); }
.rec-item:last-child { border-bottom: none; padding-bottom: 0; }
.item-name { font-weight: 600; font-size: 15px; color: var(--text); }
.item-why { font-size: 13px; color: var(--text-dim); line-height: 1.55; }
.item-cost { font-family: var(--font-mono); font-size: 13px; color: var(--green-bright); }
/* Cost + affiliate-btn footer row inside each rec-item. Default (desktop)
is the cost on the left and the button on the right; on mobile the
button drops to its own row at full width — easier tap target. */
.rec-item-foot {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 8px;
}
.affiliate-btn {
display: inline-flex; align-items: center; gap: 6px;
padding: 8px 14px;
background: rgba(0,0,0,0.04);
border: 1px solid rgba(0,0,0,0.10);
border-radius: 0;
color: var(--text);
font-size: 12px; font-weight: 600;
text-decoration: none; cursor: pointer;
transition: var(--trans); width: fit-content;
}
.affiliate-btn:hover { background: rgba(0,0,0,0.08); }
@media (max-width: 767px) {
/* Mobile — break the button onto its own row beneath the cost and let
it fill the rec-item width. flex-wrap on the parent does the line
break; flex-basis: 100% guarantees the row split even when the cost
is short. */
.rec-item-foot .affiliate-btn {
flex: 0 0 100%;
width: 100%;
justify-content: center;
padding: 12px 14px;
margin-top: 4px;
}
}
/* Budget meter — same logic as the rec-cards: text flips to dark since
the .result-panel underneath is white-paint. The .budget-meter wrapper
itself is stripped to transparent in the panel-body override (line ~615),
so only the inner element colours need adjusting here. */
.budget-meter { background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 20px; margin-bottom: 20px; animation: fadeUp 0.4s 0.2s ease both; }
/* Inner budget title matches the panel header typography (.rp-title:
var(--font-body), 700, 0.02em tracking) but a touch bigger so the
total reads as the primary stat inside the panel. */
.bm-title {
font-family: var(--font-body);
font-weight: 700;
font-size: 19px;
letter-spacing: 0.02em;
line-height: 1.3;
color: var(--text);
margin-bottom: 16px;
}
.budget-cats { display: flex; flex-direction: column; gap: 10px; }
.bcat { display: flex; align-items: center; gap: 10px; }
.bcat-label { font-size: 16px; color: var(--text-dim); width: 110px; flex-shrink: 0; }
.bcat-bar-wrap { flex: 1; height: 6px; background: rgba(0,0,0,0.08); border-radius: 99px; overflow: hidden; }
.bcat-bar { height: 100%; border-radius: 99px; transition: width 0.8s cubic-bezier(0.4,0,0.2,1); }
.bcat-cost { font-family: var(--font-mono); font-size: 15px; color: var(--text); width: 72px; text-align: right; flex-shrink: 0; }
/* Total row — sums the breakdown above. Same .bcat layout so the label
and amount align with the category rows, plus a top divider and a
touch more weight to set it apart as the summary line. */
.bcat-total {
margin-top: 6px;
padding-top: 10px;
border-top: 1px solid rgba(0,0,0,0.08);
}
.bcat-total .bcat-label { color: var(--text); font-weight: 600; }
.bcat-total .bcat-cost { color: var(--text); font-weight: 700; }
.bcat-total .bcat-bar-wrap { background: transparent; height: 0; }
/* Timeline — same dark-on-light flip. Connector line uses a subtle dark
border colour so it reads on the white-paint panel. */
.timeline { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius-lg); padding: 20px; margin-bottom: 20px; animation: fadeUp 0.4s 0.25s ease both; }
.tl-title { font-family: var(--font-display); font-weight: 700; font-size: 16px; color: var(--text); margin-bottom: 16px; }
.tl-items { display: flex; flex-direction: column; gap: 0; }
/* Each step gets generous breathing room top + bottom so the timeline
reads as a sequence of distinct moments rather than a tight list.
Padding is consistent across every item (no first/last overrides) so
the connector line positioning is stable from step to step. */
.tl-item { display: flex; gap: 16px; padding: 14px 0 28px; position: relative; }
.tl-item:last-child { padding-bottom: 4px; }
/* Connector line — light dotted column drawn as a dotted left border on a
zero-width pseudo. Top starts 46px from item-top (just under a 32px dot
sat on 14px padding) and bottom extends -14px past the item so it
reaches the next item's dot at its 14px padding offset. */
.tl-item:not(:last-child)::before {
content: '';
position: absolute;
left: 15px;
top: 46px;
bottom: -14px;
width: 0;
border-left: 2px dotted rgba(0,0,0,0.18);
}
/* Timeline dot — green-paint circle that matches the rec-icon chip but
round. Same painted ::before with a slightly larger size so the icon
inside reads at small viewport sizes. */
.tl-dot {
position: relative;
isolation: isolate;
width: 32px; height: 32px;
border-radius: 50%;
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
z-index: 1;
color: #f4ecd8;
}
.tl-dot::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
z-index: -1;
background: #2a3010;
filter: url(#paintGlossBtn);
-webkit-filter: url(#paintGlossBtn);
}
/* Step title — vertically centred against the 32px dot using min-height
+ flex centring so the label sits at the dot's mid-line rather than
its top edge. Dark-green-paint colour so the title matches the rest
of the brand-paint elements. */
.tl-when {
font-family: var(--font-body);
font-weight: 600;
font-size: 14px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: #2a3010;
margin-bottom: 6px;
min-height: 32px;
display: flex;
align-items: center;
}
.tl-action { font-size:16px; color: var(--text); line-height: 1.5; }
.tl-cost { font-family: var(--font-mono); font-size:15px; color: var(--green-bright); margin-top: 4px; }
/* ── RESULT PANELS — collapsible accordions for progressive disclosure.
Recommendations open by default; Budget and Timeline collapsed so the
results page doesn't overwhelm. The panel itself becomes the white-paint
card; inner sections (.budget-meter, .timeline, .scenario-tabs) drop their
own box treatment so the panel frame is the only container. */
.result-panel {
background: #FAFAFA;
border: 1px solid rgba(0,0,0,0.06);
border-radius: var(--radius-lg);
margin-bottom: 14px;
overflow: hidden;
box-shadow: 0 7px 10.6px rgba(0,0,0,0.12), inset 0 1px 0 rgba(255,255,255,0.7);
}
.result-panel-header {
display: flex;
align-items: center;
gap: 12px;
padding: 16px 18px;
cursor: pointer;
list-style: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
transition: background 0.15s ease;
}
.result-panel-header::-webkit-details-marker { display: none; }
.result-panel-header:hover { background: rgba(0,0,0,0.02); }
.rp-title {
font-family: var(--font-body);
font-weight: 700;
font-size: 16px;
color: var(--text);
flex: 1;
letter-spacing: 0.02em;
line-height: 1.3;
}
/* ── ICONS ── inline SVG line-icons inherit colour via currentColor.
Sized via the width/height attribute on the <svg>; vertical-align
keeps the icon flush with its sibling text in flex/inline contexts. */
.icon { display: inline-block; vertical-align: middle; }
/* Narrative ("Your Personal Analysis") — green icon next to the title. */
.narrative-icon { display: inline-flex; color: var(--green-bright); }
/* Protein-offer badge — small lock chip prefixing the eyebrow text. */
.protein-offer-badge .badge-icon {
display: inline-flex;
align-items: center;
color: var(--green-bright);
margin-right: 4px;
vertical-align: -2px;
}
/* Success state inside the modal — large check + small mail prefix on
the spam-folder note. */
.success-check {
width: 56px; height: 56px;
border-radius: 50%;
background: rgba(90,154,120,0.10);
border: 1px solid rgba(90,154,120,0.30);
color: var(--green-bright);
display: flex; align-items: center; justify-content: center;
margin: 0 auto 10px;
}
.success-spam {
margin-top: 14px;
padding: 12px 16px;
background: rgba(212,168,32,0.1);
border: 1px solid rgba(212,168,32,0.35);
border-radius: 8px;
display: flex;
gap: 10px;
align-items: flex-start;
text-align: left;
}
.success-spam-icon {
flex-shrink: 0;
display: inline-flex;
color: #D4A820;
margin-top: 1px;
}
.success-spam > div {
font-size: 14px;
color: #D4A820;
line-height: 1.7;
}
/* Affiliate button — small cart icon flush with the label. */
.affiliate-btn .icon { color: currentColor; }
/* In-body hint above the scenario tabs — full-width sage-green paint
banner matching the protein-offer / risk-low look so it reads as a
small action prompt rather than a footnote. Center-aligned with a
touch more weight than the previous mono caption. */
.rp-hint {
display: block;
width: 100%;
text-align: center;
font-family: var(--font-body);
font-weight: 400;
font-size: 12px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--text);
background: #E5F0E0;
border: 1px solid rgba(90,154,120,0.30);
border-radius: var(--radius);
padding: 10px 14px;
margin: 0 0 12px;
box-shadow: 0 3px 6px rgba(0,0,0,0.06), inset 0 1px 0 rgba(255,255,255,0.7);
}
.rp-chevron {
font-size: 14px;
color: var(--text-dim);
transition: transform 0.2s ease;
flex-shrink: 0;
}
.result-panel[open] .rp-chevron { transform: rotate(180deg); }
.result-panel-body {
/* Generous top padding so the expanded content has clear breathing
room beneath the panel header (was 0 → 20px). */
padding: 20px 18px 18px;
}
/* Strip box treatment from inner cards when wrapped in a panel — the panel
is now the visible container. */
.result-panel-body .budget-meter,
.result-panel-body .timeline {
background: transparent;
border: none;
border-radius: 0;
padding: 0;
margin: 0;
box-shadow: none;
animation: none;
}
.result-panel-body .scenario-tabs {
margin-bottom: 16px;
animation: none;
}
.result-panel-body .rec-cards { animation: none; }
/* Drop the redundant inner timeline title — the panel header replaces it. */
.result-panel-body .tl-title { display: none; }
/* Results email capture */
.results-email {
background: linear-gradient(135deg, var(--red-dim), #141210);
border: 1px solid rgba(90,154,120,0.2);
border-radius: var(--radius-lg);
padding: 24px;
margin-bottom: 20px;
animation: fadeUp 0.4s 0.3s ease both;
}
.results-email .email-label { color: var(--red); }
.results-email .email-title { font-size: 18px; }
.restart-btn { width: 100%; padding: 16px; background: var(--panel); border: 1px solid var(--border); border-radius: 0; color: var(--text-dim); font-family: var(--font-display); font-weight: 700; font-size: 16px; letter-spacing: 0.06em; text-transform: uppercase; cursor: pointer; transition: var(--trans); margin-top: 8px; }
.restart-btn:hover { border-color: var(--muted); color: var(--text); }
/* ── ABOUT ── */
.about-section { background: var(--deep); border-top: 1px solid rgba(255,255,255,0.04); padding: 56px 24px; text-align: center; }
.about-section h2 { font-family: var(--font-display); font-weight: 400; font-size: 26px; color: var(--white); margin-bottom: 14px; }
.about-section p { font-size: 14px; color: var(--text-dim); max-width: 380px; margin: 0 auto 20px; line-height: 1.8; font-weight: 300; }
.affiliate-note { font-family: var(--font-mono); font-size: 10px; color: var(--muted); letter-spacing: 0.08em; line-height: 1.8; }
@keyframes fadeUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
.hidden { display: none !important; }
/* ── SINGLE FOLD: hide non-essential sections on load ──
(header stays visible with a transparent background on the homepage) */
.site-header { background: transparent; backdrop-filter: none; -webkit-backdrop-filter: none; border-bottom: none; }
/* Results-page header — soft white fade so content doesn't visually
clash with the logo / language toggle when scrolling underneath
(especially noticeable on mobile). The header itself becomes a
translucent white veil; a ::after pseudo extends ~28px below it
with a fade-to-transparent so the boundary feels organic. */
body.results-active .site-header {
background: rgba(250,250,250,0.86);
-webkit-backdrop-filter: blur(20px);
backdrop-filter: blur(20px);
}
body.results-active .site-header::after {
content: '';
position: absolute;
top: 100%;
left: 0;
right: 0;
height: 28px;
background: linear-gradient(180deg, rgba(250,250,250,0.86) 0%, rgba(250,250,250,0) 100%);
-webkit-backdrop-filter: blur(8px);
backdrop-filter: blur(8px);
pointer-events: none;
}
.scenario-strip,
.email-section,
.about-section { display: none !important; }
/* Language switcher — wears the white-paint look (#F0F0F0 fill, soft
light-grey ambient shadow + faint top highlight to match the H1
white paint). Inner buttons stay transparent so the fill reads as
one unit. */
.lang-toggle {
background: #F0F0F0 !important;
border: 1px solid rgba(0,0,0,0.06) !important;
border-radius: 4px;
box-shadow: 0 3px 5px rgba(0,0,0,0.07), inset 0 1px 0 rgba(255,255,255,0.6);
overflow: hidden;
}
.lang-btn { background: transparent !important; color: var(--text-dim); }
.lang-btn.active { background: transparent !important; color: var(--red); }
/* ── CAPTURE FORM ── */
/* Capture form container — wears the same white-paint look as the inner
selectors, but a touch whiter (#FAFAFA vs #F0F0F0) so it reads as the
outer container while keeping the H1's dy=7 / blur≈10 / 0.12 alpha drop
and faint inset top highlight for the gloss feel. */
.capture-form-wrap{background:#FAFAFA;border:1px solid rgba(0,0,0,0.06);border-radius:var(--radius-lg);padding:28px 24px;margin-bottom:20px;animation:fadeUp 0.4s 0.3s ease both;box-shadow:0 7px 10.6px rgba(0,0,0,0.12), inset 0 1px 0 rgba(255,255,255,0.7);}
/* Country/region indicator hidden — not needed in this build. */
#region-indicator { display: none !important; }
/* ── Paint variants (ported from paint.html for in-page experimentation) ── */
body.paint-green .hero h1.paint-3d {
background: #2a3010;
-webkit-background-clip: text;
background-clip: text;
}
body.paint-green .cta-btn::before {
background: #2a3010;
}
body.paint-white .hero h1.paint-3d {
filter: url(#paintGlossWhite);
-webkit-filter: url(#paintGlossWhite);
background: #F0F0F0;
-webkit-background-clip: text;
background-clip: text;
}
body.paint-white .cta-btn { color: #1A1A18; }
body.paint-white .cta-btn:hover { color: #060604; }
body.paint-white .cta-btn::before {
background: #F0F0F0;
filter: url(#paintGlossWhiteBtn);
-webkit-filter: url(#paintGlossWhiteBtn);
}
/* Header / quiz-progress-bar logos follow the active paint colour so
the small wordmark stays in sync with the hero as the user plays
with the modifier. Reads --mod-fill (set by the fill picker) and
falls back to the variant's default. White paint is intentionally
excluded — a near-white logo would vanish against the light
site-header background. */
body.paint-green .logo,
body.paint-green .qpb-logo {
color: var(--mod-fill, #2a3010);
}
/* Paint picker UI — top-right swatches */
.paint-picker { display: flex; gap: 8px; align-items: center; }
.paint-swatch {
width: 28px; height: 28px;
border-radius: 50%;
border: 1px solid var(--border);
cursor: pointer;
padding: 0;
transition: transform 0.15s ease;
}
.paint-swatch:hover { transform: scale(1.08); }
.paint-swatch.swatch-dark { background: linear-gradient(180deg, #2a2a26, #060604); }
.paint-swatch.swatch-green { background: #2a3010; }
.paint-swatch.swatch-white { background: linear-gradient(180deg, #FFFFFF, #DDDDDD); }
.paint-swatch.active {
outline: 2px solid var(--red);
outline-offset: 2px;
}
/* Modifier toggle ⚙ — wears the same white-paint look as the lang-toggle */
/* Hidden for now — styles preserved so we can re-enable the modifier
panel later by removing this single rule. */
.mod-open-btn { display: none !important; }
.mod-open-btn {
background: #F0F0F0;
border: 1px solid rgba(0,0,0,0.06);
border-radius: 4px;
box-shadow: 0 7px 10.6px rgba(0,0,0,0.12), inset 0 1px 0 rgba(255,255,255,0.7);
width: 28px; height: 28px;
cursor: pointer;
font-size: 14px;
line-height: 1;
padding: 0;
color: var(--text-dim);
transition: var(--trans);
}
.mod-open-btn:hover { color: var(--text); }
/* Quiz progress bar — flex row with logo (left), progress (center), lang (right).
Logo matches the site-header .logo: same 20px DM Serif Display. */
.quiz-progress-bar { display: flex; align-items: center; gap: 16px; }
@media (min-width: 768px) {
.quiz-progress-bar { gap: 32px; }
}
.quiz-progress-bar .qpb-logo {
font-family: var(--font-display);
font-weight: 400;
font-size: 20px;
letter-spacing: 0.02em;
color: var(--white);
white-space: nowrap;
text-decoration: none;
}
.quiz-progress-bar .progress-wrap { flex: 1; max-width: none; margin: 0; }
/* Desktop — cap the progress bar at the form width (540px) so it reads
tighter and lines up with the question card below. Auto margins on the
flex item absorb leftover horizontal space symmetrically, centring the
bar between the logo (left) and lang-toggle (right). */
@media (min-width: 768px) {
.quiz-progress-bar .progress-wrap { max-width: 540px; margin: 0 auto; }
}
.quiz-progress-bar .lang-toggle { flex-shrink: 0; }
@media (max-width: 767px) {
.quiz-progress-bar .lang-toggle { display: none; }
}
/* Active language button — bolded red so the current selection stands
out against the white-paint container fill. */
.lang-btn.active { font-weight: 800 !important; color: var(--red) !important; }
/* Outer question-card wears the glossy white-paint look at #FAFAFA —
a touch whiter than the inner .q-opt (#F0F0F0) so it reads as the
surrounding container while keeping the same drop-shadow + inset
top highlight as .capture-form-wrap. */
.question-card {
background: #FAFAFA !important;
border: 1px solid rgba(0,0,0,0.06) !important;
box-shadow: 0 7px 10.6px rgba(0,0,0,0.12), inset 0 1px 0 rgba(255,255,255,0.7);
}
/* Inner selection options wear the white-paint look: #F0F0F0 fill,
soft light-grey ambient shadow + faint inset top highlight.
Shadow kept lighter than the outer .question-card so the depth
reads as outer-elevated > inner-resting. */
.q-opt {
background: #F0F0F0 !important;
border: 1px solid rgba(0,0,0,0.06) !important;
box-shadow: 0 3px 6px rgba(0,0,0,0.06), inset 0 1px 0 rgba(255,255,255,0.7);
}
.q-opt:hover { border-color: rgba(0,0,0,0.12) !important; background: #F4F4F4 !important; }
.q-opt.selected { border-color: var(--red) !important; }
/* Modifier panel — hidden by default, opens when body has .mod-open */
.mod-panel {
position: fixed;
top: 72px;
right: 12px;
width: 280px;
max-height: calc(100dvh - 84px);
overflow-y: auto;
background: rgba(255,255,255,0.96);
border: 1px solid var(--border);
border-radius: 6px;
box-shadow: 0 8px 32px rgba(0,0,0,0.08);
z-index: 200;
font-family: var(--font-mono);
font-size: 11px;
padding: 8px;
display: none;
}
body.mod-open .mod-panel { display: block; }
.mod-header {
display: flex; align-items: center; justify-content: space-between;
padding: 4px 8px;
border-bottom: 1px solid var(--border);
margin-bottom: 8px;
}
.mod-header h3 {
font-family: var(--font-display);
font-size: 14px; font-weight: 400; margin: 0;
}
.mod-paint-label {
font-family: var(--font-mono); font-size: 10px;
color: var(--red); letter-spacing: 0.1em;
text-transform: uppercase; margin-left: 8px;
}
.mod-toggle {
background: none; border: 1px solid var(--border); border-radius: 3px;
width: 22px; height: 22px; cursor: pointer; font-size: 14px; line-height: 1;
padding: 0;
}
.mod-fieldset {
border: 1px solid var(--border); border-radius: 4px;
padding: 6px 8px; margin: 0 0 8px;
}
.mod-fieldset legend {
padding: 0 4px;
font-weight: 600; font-size: 10px;
letter-spacing: 0.05em; text-transform: uppercase;
color: var(--text-dim);
}
.mod-row {
display: grid;
grid-template-columns: 56px 1fr 38px;
gap: 6px; align-items: center; margin: 4px 0;
}
.mod-row > span:first-child {
font-size: 10px; color: var(--text-dim);
}
.mod-row input[type="range"] { width: 100%; }
.mod-row input[type="color"] {
width: 100%; height: 22px; padding: 0;
border: 1px solid var(--border); border-radius: 3px;
grid-column: 2 / span 2;
}
.mod-row output {
font-size: 10px; text-align: right;
font-variant-numeric: tabular-nums;
}
.mod-actions {
display: flex; align-items: center; gap: 8px;
padding-top: 8px; border-top: 1px solid var(--border);
}
.mod-actions button {
flex: 1; padding: 6px 12px;
background: var(--red); color: #fff;
border: none; border-radius: 3px; cursor: pointer;
font-family: var(--font-mono); font-size: 11px;
font-weight: 600; text-transform: uppercase; letter-spacing: 0.1em;
}
.mod-copy-status {
font-size: 10px; color: var(--green); white-space: nowrap;
}
.mod-fieldset[data-hide] { display: none; }
.capture-label{font-family:var(--font-mono);font-size:10px;color:var(--red);letter-spacing:0.15em;text-transform:uppercase;margin-bottom:12px;display:block;}
.capture-title{font-family:var(--font-display);font-weight:900;font-size:24px;color:var(--white);margin-bottom:6px;}
.capture-sub{font-size:13px;color:var(--text-dim);line-height:1.6;margin-bottom:20px;}
.form-grid{display:flex;flex-direction:column;gap:12px;}
.form-row{display:flex;gap:10px;flex-wrap:wrap;}
.form-field{display:flex;flex-direction:column;gap:5px;flex:1;min-width:140px;}
.field-label{font-size:11px;color:var(--text-dim);font-family:var(--font-mono);letter-spacing:0.06em;text-transform:uppercase;}
.form-input,.form-select{width:100%;padding:12px 14px;background:var(--card);border:1.5px solid var(--border);border-radius:var(--radius);color:var(--white);font-family:var(--font-body);font-size:14px;outline:none;transition:var(--trans);}
.form-input:focus,.form-select:focus{border-color:rgba(90,154,120,0.4);}
.form-input::placeholder{color:var(--muted);}
.form-select{cursor:pointer;-webkit-appearance:none;appearance:none;}
.form-select option{background:var(--card);color:var(--white);}
.form-input[rows]{resize:vertical;min-height:80px;line-height:1.5;}
.capture-submit{width:100%;padding:16px;background:var(--red);border:none;border-radius:0;color:#0C0C0E;font-family:var(--font-body);font-weight:600;font-size:14px;letter-spacing:0.1em;text-transform:uppercase;cursor:pointer;transition:var(--trans);margin-top:4px;box-shadow:0 4px 24px rgba(90,154,120,0.2);}
.capture-submit:hover{background:#7AB498;transform:translateY(-1px);}
/* ── NARRATIVE SECTION ── */
/* Narrative card — white-paint container that matches the form / result
panels (#FAFAFA, embossed shadow, inset highlight). The header takes a
slightly greyer tint (#F0F0F0) so it reads as a subtle band above the
body — same nesting as the result-panel header. */
.narrative-section {
background: #FAFAFA;
border: 1px solid rgba(0,0,0,0.06);
border-radius: var(--radius-lg);
margin-bottom: 24px;
overflow: hidden;
animation: fadeUp 0.4s ease both;
box-shadow: 0 7px 10.6px rgba(0,0,0,0.12), inset 0 1px 0 rgba(255,255,255,0.7);
}
.narrative-header {
padding: 14px 18px;
background: #F0F0F0;
border-bottom: 1px solid rgba(0,0,0,0.06);
display: flex;
align-items: center;
gap: 10px;
}
.narrative-title {
font-family: var(--font-body);
font-weight: 700;
font-size: 16px;
color: var(--text);
letter-spacing: 0.02em;
}
.narrative-tag {
margin-left: auto;
font-family: var(--font-mono);
font-size: 11px;
color: var(--red);
letter-spacing: 0.12em;
text-transform: uppercase;
border: 1px solid var(--red-dim);
padding: 3px 8px;
border-radius: 4px;
}
.narrative-body {
padding: 20px 24px;
font-size: 14px;
line-height: 1.75;
color: var(--text);
}
.narrative-body h4 {
font-family: var(--font-display);
font-weight: 800;
font-size: 16px;
color: var(--text);
margin: 20px 0 8px;
letter-spacing: 0.02em;
}
.narrative-body h4:first-child { margin-top: 0; }
.narrative-body p { margin: 0 0 12px; }
.narrative-body ul { margin: 8px 0 12px; padding-left: 20px; }
.narrative-body li { margin-bottom: 6px; }
.narrative-body strong { color: var(--text); font-weight: 700; }
.narrative-loading {
padding: 32px 24px;
text-align: center;
}
.loading-dots {
display: inline-flex;
gap: 6px;
margin-bottom: 12px;
}
.loading-dots span {
width: 6px; height: 6px;
background: var(--red);
border-radius: 50%;
animation: bounce 1.4s infinite;
}
.loading-dots span:nth-child(2) { animation-delay: 0.2s; }
.loading-dots span:nth-child(3) { animation-delay: 0.4s; }
@keyframes bounce {
0%, 80%, 100% { transform: scale(0.6); opacity: 0.4; }
40% { transform: scale(1); opacity: 1; }
}
.loading-text {
font-family: var(--font-mono);
font-size: 11px;
color: var(--text-dim);
letter-spacing: 0.1em;
text-transform: uppercase;
}
.scroll-hint {
text-align: center;
padding: 12px;
font-family: var(--font-mono);
font-size: 10px;
color: var(--text-dim);
letter-spacing: 0.1em;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 0.4; }
50% { opacity: 1; }
}
/* ── REQUIRED BADGE ── */
.capture-required-badge {
background: rgba(90,154,120,0.06);
border: 1px solid rgba(90,154,120,0.15);
border-radius: var(--radius);
padding: 10px 14px;
font-family: var(--font-mono);
font-size: 10px;
color: var(--red);
letter-spacing: 0.1em;
text-transform: uppercase;
margin-bottom: 20px;
text-align: center;
}
/* ── NEWSLETTER CHECKBOX ── */
.newsletter-check {
display: flex;
align-items: flex-start;
gap: 12px;
cursor: pointer;
padding: 12px 14px;
background: var(--panel);
border: 1.5px solid var(--border);
border-radius: var(--radius);
transition: var(--trans);
margin-top: 4px;
}
.newsletter-check:hover { border-color: var(--muted); }
.newsletter-check input[type=checkbox] { display: none; }
.check-box {
width: 20px; height: 20px;
border: 2px solid var(--muted);
border-radius: 4px;
flex-shrink: 0;
margin-top: 1px;
position: relative;
transition: var(--trans);
background: transparent;
}
.newsletter-check input:checked ~ .check-box {
background: rgba(90,154,120,0.9);
border-color: var(--red);
}
.newsletter-check input:checked ~ .check-box::after {
content: '✓';
position: absolute;
top: 50%; left: 50%;
transform: translate(-50%, -55%);
color: white;
font-size: 12px;
font-weight: 700;
}
.check-label {
font-size: 13px;
color: var(--text);
line-height: 1.5;
}
/* ── NARRATIVE PROGRESS BAR ── */
.narrative-progress {
height: 3px;
background: var(--muted);
margin: 0 24px 0;
border-radius: 99px;
overflow: hidden;
}
.narrative-progress-fill {
height: 100%;
width: 0%;
background: var(--red);
border-radius: 99px;
transition: width 0.5s linear;
}
/* ── STAGED REVEAL ── */
.reveal-section {
display: none;
}
.reveal-section.revealed {
display: block;
animation: fadeUp 0.5s ease both;
}
/* ── NARRATIVE CTA ── */
.narrative-cta {
padding: 16px 20px;
border-top: 1px solid var(--border);
text-align: center;
}
.narrative-cta-btn {
display: inline-flex;
align-items: center;
gap: 8px;
background: var(--red);
color: #0C0C0E;
border: none;
border-radius: 0;
padding: 14px 24px;
font-family: var(--font-body);
font-weight: 600;
font-size: 13px;
letter-spacing: 0.1em;
text-transform: uppercase;
cursor: pointer;
transition: var(--trans);
width: 100%;
justify-content: center;
line-height: 1.4;
text-align: center;
}
.narrative-cta-btn:hover { transform: translateY(-1px); box-shadow: 0 4px 24px rgba(90,154,120,0.25); background: #7AB498; }
/* ── CAPTURE FORM HEADER ── */
.capture-form-header {
font-family: var(--font-display);
font-weight: 400;
font-size: 22px;
color: var(--white);
letter-spacing: 0.01em;
padding-bottom: 16px;
border-bottom: 1px solid rgba(90,154,120,0.2);
margin-bottom: 20px;
}
/* ── PROPRIETARY PROTEIN OFFER ── */
.protein-offer {
background: #E5F0E0;
border: 1px solid rgba(90,154,120,0.30);
border-radius: var(--radius-lg);
padding: 24px;
margin-bottom: 20px;
animation: fadeUp 0.5s ease both;
display: none;
box-shadow: 0 7px 10.6px rgba(0,0,0,0.08), inset 0 1px 0 rgba(255,255,255,0.7);
}
.protein-offer.show { display: block; }
.protein-offer-badge {
display: inline-flex;
align-items: center;
gap: 6px;
background: rgba(40,160,96,0.15);
border: 1px solid rgba(40,160,96,0.4);
border-radius: 4px;
padding: 4px 10px;
font-family: var(--font-mono);
font-size: 11px;
color: var(--green-bright);
letter-spacing: 0.12em;
text-transform: uppercase;
margin-bottom: 12px;
}
.protein-offer-title {
font-family: var(--font-body);
font-weight: 700;
font-size: 20px;
color: var(--white);
margin-bottom: 8px;
line-height: 1.25;
letter-spacing: 0.01em;
}
.protein-offer-body {
font-size: 14px;
color: var(--text-dim);
line-height: 1.7;
margin-bottom: 16px;
}
.protein-offer-btn {
display: inline-flex;
align-items: center;
gap: 8px;
background: var(--green);
color: white;
border: none;
border-radius: 0;
padding: 14px 24px;
font-family: var(--font-display);
font-weight: 800;
font-size: 16px;
letter-spacing: 0.04em;
text-transform: uppercase;
cursor: pointer;
text-decoration: none;
transition: var(--trans);
width: 100%;
justify-content: center;
}
.protein-offer-btn:hover { background: #32C070; transform: translateY(-1px); }
/* Responsive label — short on mobile (narrow card), long on desktop. */
.protein-offer-btn .po-label-desktop { display: none; }
@media (min-width: 768px) {
.protein-offer-btn .po-label-mobile { display: none; }
.protein-offer-btn .po-label-desktop { display: inline; }
}
.scenario-strip{
overflow:hidden;
padding:16px 0;
background:var(--panel);
border-bottom:1px solid var(--border);
cursor:grab;
position:relative;
}
.scenario-strip:active{cursor:grabbing;}
.scenario-strip-track{
display:flex;
gap:12px;
padding:4px 24px;
width:max-content;
animation:scroll-pills 28s linear infinite;
-webkit-overflow-scrolling:touch;
}
.scenario-strip:hover .scenario-strip-track,
.scenario-strip:focus-within .scenario-strip-track {
animation-play-state:paused;
}
@keyframes scroll-pills {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}
/* ── Painted button system ──────────────────────────────────────────
Shared embossed-paint fill for primary CTAs (.cta-btn, .btn-next,
.narrative-cta-btn, .capture-submit). Secondary actions
(.btn-back, .restart-btn) keep their original flat panel style. */
.cta-btn,
.btn-next,
.narrative-cta-btn,
.capture-submit,
.protein-offer-btn {
position: relative;
isolation: isolate;
background: transparent;
border: none;
box-shadow: none;
}
.cta-btn::before,
.btn-next::before,
.narrative-cta-btn::before,
.capture-submit::before,
.protein-offer-btn::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
z-index: -1;
transition: filter 0.6s ease;
}
/* Primary — dark fill */
.cta-btn,
.btn-next,
.narrative-cta-btn,
.capture-submit {
color: #f4ecd8;
}
.cta-btn::before,
.btn-next::before,
.narrative-cta-btn::before,
.capture-submit::before {
background: linear-gradient(180deg, #2a2a26 0%, #1A1A18 45%, #060604 100%);
filter: url(#paintGlossBtn);
-webkit-filter: url(#paintGlossBtn);
}
.cta-btn:hover::before,
.btn-next:hover::before,
.narrative-cta-btn:hover::before,
.capture-submit:hover::before {
filter: url(#paintGlossBtnHover);
-webkit-filter: url(#paintGlossBtnHover);
}
.cta-btn:hover,
.btn-next:hover,
.narrative-cta-btn:hover,
.capture-submit:hover,
.protein-offer-btn:hover {
background: transparent;
color: #fff8e8;
transform: none;
box-shadow: none;
}
.cta-btn:active,
.btn-next:active,
.narrative-cta-btn:active,
.capture-submit:active,
.protein-offer-btn:active { opacity: 0.9; }
/* Green-paint variant — the protein-offer button always wears the green
paint regardless of body.paint-* state (parallels body.paint-green
.cta-btn::before, but pinned to this button as a one-off). */
.protein-offer-btn { color: #f4ecd8; }
.protein-offer-btn::before {
background: #2a3010;
filter: url(#paintGlossBtn);
-webkit-filter: url(#paintGlossBtn);
}
.protein-offer-btn:hover::before {
filter: url(#paintGlossBtnHover);
-webkit-filter: url(#paintGlossBtnHover);
}
/* Unified button typography — every primary CTA wears the .cta-btn font
(var(--font-body), 400 weight, 13px, 0.2em tracking, uppercase) so the
results-page actions match the homepage "Begin" button. Padding and
width stay per-button so visual hierarchy is preserved. Place after
the per-button rules above so this wins the cascade. */
.cta-btn,
.btn-next,
.btn-back,
.narrative-cta-btn,
.capture-submit,
.protein-offer-btn,
.restart-btn,
.form-modal-close {
font-family: var(--font-body);
font-weight: 400;
font-size: 14px;
letter-spacing: 0.2em;
text-transform: uppercase;
}
/* ── FORM MODAL ──
Layout: fixed overlay with the panel scaled to the viewport. Panel is a
flex column — header (sticky) / body (scrollable) / footer (sticky) —
so the submit button stays in view while long forms scroll inside. */
.form-modal {
position: fixed;
inset: 0;
z-index: 200;
display: none;
padding: 16px;
background: rgba(20, 20, 20, 0.55);
-webkit-backdrop-filter: blur(6px);
backdrop-filter: blur(6px);
align-items: center;
justify-content: center;
}
.form-modal.open {
display: flex;
animation: fadeUp 0.22s ease;
}
.form-modal-panel {
position: relative;
width: 100%;
max-width: 580px;
max-height: calc(100dvh - 32px);
display: flex;
flex-direction: column;
background: #FAFAFA;
border: 1px solid rgba(0,0,0,0.06);
border-radius: var(--radius-lg);
overflow: hidden;
box-shadow: 0 12px 32px rgba(0,0,0,0.25), inset 0 1px 0 rgba(255,255,255,0.7);
animation: fadeUp 0.3s ease both;
}
.form-modal-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 14px 18px;
border-bottom: 1px solid rgba(0,0,0,0.06);
flex-shrink: 0;
}
.form-modal-header .modal-title {
font-family: var(--font-display);
font-weight: 700;
font-size: 18px;
color: var(--text);
letter-spacing: 0.01em;
line-height: 1.2;
}
.form-modal-body {
flex: 1 1 auto;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
padding: 18px;
}
.form-modal-body .capture-sub {
margin-bottom: 16px;
}
.form-modal-footer {
flex-shrink: 0;
padding: 14px 18px max(14px, env(safe-area-inset-bottom));
border-top: 1px solid rgba(0,0,0,0.06);
background: #FAFAFA;
}
.form-modal-footer .capture-submit {
width: 100%;
margin: 0;
}
/* Close button — secondary style: white card with subtle border (parallels
the .btn-back / restart-btn flat panel look). The × is drawn from two
CSS strokes via ::before / ::after so it sits pixel-centred regardless
of font metrics; the button's text content is sized to 0 so the inline
"×" character isn't rendered. */
.form-modal-close {
position: relative;
width: 34px;
height: 34px;
border: 1px solid rgba(0,0,0,0.12);
border-radius: 4px;
background: #FAFAFA;
color: var(--text);
padding: 0;
cursor: pointer;
flex-shrink: 0;
font-size: 0; /* hides the literal "×" character */
line-height: 0;
transition: background 0.15s ease, border-color 0.15s ease;
box-shadow: inset 0 1px 0 rgba(255,255,255,0.7);
}
.form-modal-close::before,
.form-modal-close::after {
content: '';
position: absolute;
left: 50%;
top: 50%;
width: 14px;
height: 1.5px;
background: var(--text);
border-radius: 1px;
transform-origin: center;
}
.form-modal-close::before { transform: translate(-50%, -50%) rotate(45deg); }
.form-modal-close::after { transform: translate(-50%, -50%) rotate(-45deg); }
.form-modal-close:hover { background: #FFFFFF; border-color: rgba(0,0,0,0.20); }
.form-modal-close:active { background: #F0F0F0; }
/* In-form privacy note — sits between the protein field and newsletter
checkbox (above the fixed footer submit). */
.form-privacy {
font-size: 10px;
color: var(--muted);
text-align: center;
line-height: 1.7;
margin: 4px 0 0;
}
/* iOS-Safari-safe scroll lock — overflow:hidden alone leaks touch scroll
on iOS, so we also pin position:fixed and width:100%. JS sets the
`top` inline style to -savedScrollY so the page stays where it was,
then restores scrollY on close. */
body.modal-open {
overflow: hidden;
position: fixed;
width: 100%;
left: 0;
right: 0;
}
.btn-next:disabled,
.btn-next:disabled:hover {
opacity: 0.4;
cursor: not-allowed;
background: transparent;
color: #f4ecd8;
box-shadow: none;
}
.btn-next:disabled::before,
.btn-next:disabled:hover::before {
filter: url(#paintGlossBtn);
-webkit-filter: url(#paintGlossBtn);
}