Refine paywall presentation and homepage copy

This commit is contained in:
fightme-cmd
2026-07-05 10:36:59 +02:00
parent 49f78ef6b0
commit 28e8ade05f
+41 -36
View File
@@ -234,6 +234,15 @@ const TABS = [
const FREE_LEVEL_IDS = new Set([1, 2, 3, 4, 8, 9, 10, 18]);
const CORE_ARTICLE_CASES = ['nominative', 'accusative', 'dative'];
const STRIPE_PLANS = [
{
id:'weekly',
name:'Weekly',
price:'$2.99',
cadence:'per week',
note:'Start here',
url: import.meta.env.VITE_STRIPE_WEEKLY_URL || '',
env:'VITE_STRIPE_WEEKLY_URL',
},
{
id:'yearly',
name:'Yearly',
@@ -252,15 +261,6 @@ const STRIPE_PLANS = [
url: import.meta.env.VITE_STRIPE_LIFETIME_URL || '',
env:'VITE_STRIPE_LIFETIME_URL',
},
{
id:'weekly',
name:'Weekly',
price:'$2.99',
cadence:'per week',
note:'Try it first',
url: import.meta.env.VITE_STRIPE_WEEKLY_URL || '',
env:'VITE_STRIPE_WEEKLY_URL',
},
];
const LEVELS = [
@@ -891,11 +891,11 @@ export default function App() {
<audio controls preload="none" src={a.src} style={{width:'100%', height:36}}/>
</div>
))}
</div>
)}
</div>
</div>
)}
</div>
<div style={{display:'flex', gap:10, justifyContent:'center', marginTop:18}}>
<div style={{display:'flex', gap:10, justifyContent:'center', marginTop:18}}>
{learnStep > 0 && (
<button style={{...S.nextBtn, background:'#fff', color:'#666', border:'1px solid #ddd'}}
onClick={()=>setLearnStep(s=>s-1)}> Zurück</button>
@@ -1088,8 +1088,8 @@ export default function App() {
)}
{/* SUMMARY */}
{scr === 'summary' && (
<div style={{textAlign:'center', paddingTop:60}}>
{scr === 'summary' && (
<div style={{textAlign:'center', paddingTop:60}}>
<div style={{fontSize:12,color:'#999',textTransform:'uppercase',letterSpacing:2,fontWeight:600}}>Complete</div>
<div style={{fontSize:56, fontWeight:700, color:'#1a1a1a', margin:'10px 0'}}>
{rc}<span style={{fontSize:24, color:'#bbb'}}>/{ROUND}</span>
@@ -1113,9 +1113,11 @@ export default function App() {
<div style={{marginTop:16}}>
<button style={S.linkBtn} onClick={()=>setScr('menu')}>back to menu</button>
</div>
</div>
)}
</div>
</div>
)}
<FeatureRequestFooter />
</div>
{chart && <ChartModal section={chartSection} q={q} onClose={()=>setChart(false)}/>}
@@ -1137,23 +1139,12 @@ function HomeScreen({ onStart }) {
<div style={{paddingTop:18}}>
<section style={S.hero}>
<div style={S.heroMark}>der · den · dem</div>
<h1 style={S.heroTitle}>Beat German cases into muscle memory.</h1>
<h1 style={S.heroTitle}>Learn German cases by feel.</h1>
<p style={S.heroCopy}>
No mascot. No scenic route. Drill the prepositions, articles, possessives, and pronouns that keep slowing you down, then get back to actual German.
Learn this stuff in days not months. Built by fast German learners for other fast German learners. Drill the prepositions, articles, possessives, and pronouns that slow you down, then get back to actual German.
</p>
<div style={S.claimStack}>
<div>Learn this stuff in days, not months.</div>
<div>Built by fast German learners for other fast German learners.</div>
<div>Have a feature request? Get in touch. Always looking to improve the tool.</div>
</div>
<div style={S.heroActions}>
<button style={S.nextBtn} onClick={onStart}>Get started</button>
<a
style={S.mailBtn}
href={`mailto:?subject=${encodeURIComponent('Beug feature request')}&body=${encodeURIComponent('Hey, I have a feature request for Beug:\n\n')}`}
>
Write an email
</a>
</div>
</section>
@@ -1162,6 +1153,20 @@ function HomeScreen({ onStart }) {
);
}
function FeatureRequestFooter() {
return (
<footer style={S.footerContact}>
<div>Have a feature request? Get in touch. Always looking to improve the tool.</div>
<a
style={S.footerMail}
href={`mailto:?subject=${encodeURIComponent('Beug feature request')}&body=${encodeURIComponent('Hey, I have a feature request for Beug:\n\n')}`}
>
Write an email
</a>
</footer>
);
}
function CoreReference() {
const prepositionGroups = [
['accusative', 'Akkusativ', PREPS_BY_CASE.accusative],
@@ -1618,10 +1623,7 @@ const S = {
heroMark: { fontSize:12, color:GREEN, fontWeight:800, textTransform:'uppercase', letterSpacing:0.8, marginBottom:10 },
heroTitle: { fontSize:38, lineHeight:1.05, margin:'0 0 12px', color:'#1a1a1a', letterSpacing:0, fontWeight:800 },
heroCopy: { fontSize:15, lineHeight:1.55, color:'#666', margin:'0 0 20px' },
claimStack: { display:'grid', gap:8, margin:'0 0 20px', fontSize:13, lineHeight:1.35, color:'#222', fontWeight:800 },
heroActions: { display:'flex', gap:10, flexWrap:'wrap' },
secondaryBtn: { padding:'11px 18px', borderRadius:8, border:'1.5px solid #ddd', background:'#fff', color:'#444', fontSize:14, fontWeight:700, cursor:'pointer', fontFamily:'inherit' },
mailBtn: { display:'inline-flex', alignItems:'center', justifyContent:'center', padding:'11px 18px', borderRadius:8, border:'1.5px solid #ddd', background:'#fff', color:'#444', fontSize:14, fontWeight:700, cursor:'pointer', fontFamily:'inherit', textDecoration:'none' },
sectionTitle: { fontSize:12, color:'#999', textTransform:'uppercase', letterSpacing:1, fontWeight:800, margin:'0 0 8px' },
coreGrid: { display:'grid', gridTemplateColumns:'1fr', gap:10 },
corePanel: { background:'#fff', border:'1px solid #eee', borderRadius:10, padding:'16px 16px' },
@@ -1630,7 +1632,7 @@ const S = {
miniTd: { padding:'7px 4px', fontSize:13, color:'#444', borderBottom:'1px solid #f3f3f3', textAlign:'center' },
lvRow: { display:'flex', alignItems:'center', gap:14, padding:'13px 16px', marginBottom:6, background:'#fff', borderRadius:10, border:'1px solid #eee' },
lvRowBlurred: { filter:'blur(2px)', opacity:0.62 },
lvRowBlurred: { filter:'blur(0.8px)', opacity:0.82 },
lvName: { fontSize:14, fontWeight:700, color:'#1a1a1a' },
lvDesc: { fontSize:12, color:'#999', marginTop:1 },
lvPct: { fontSize:14, fontWeight:700 },
@@ -1676,7 +1678,7 @@ const S = {
benefit: { fontSize:13, color:'#444', fontWeight:600 },
planGrid: { display:'grid', gridTemplateColumns:'1fr', gap:10 },
planCard: { position:'relative', display:'grid', gridTemplateColumns:'1fr auto', alignItems:'end', gap:'2px 12px', width:'100%', padding:'15px 14px', borderRadius:10, border:'1.5px solid #e6e6e6', background:'#fff', color:'#1a1a1a', cursor:'pointer', fontFamily:'inherit', textAlign:'left' },
planFeatured: { borderColor:GREEN, boxShadow:'0 0 0 3px rgba(88,167,0,0.10)' },
planFeatured: { borderColor:GREEN, background:'#f3ffe8', boxShadow:'0 0 0 3px rgba(88,167,0,0.14)' },
planNote: { gridColumn:'1 / -1', fontSize:10, fontWeight:800, letterSpacing:0.6, textTransform:'uppercase', color:GREEN, marginBottom:2 },
planName: { fontSize:14, fontWeight:800 },
planPrice: { fontSize:20, fontWeight:800, textAlign:'right' },
@@ -1684,6 +1686,9 @@ const S = {
payMsg: { marginTop:12, border:'1px solid #f5d0d0', background:'#fff7f7', color:'#b91c1c', borderRadius:8, padding:'10px 12px', fontSize:12, lineHeight:1.4 },
payFine: { marginTop:12, fontSize:11, color:'#aaa', lineHeight:1.4 },
footerContact: { borderTop:'1px solid #e9e9e9', marginTop:28, paddingTop:18, display:'flex', gap:12, justifyContent:'space-between', alignItems:'center', color:'#777', fontSize:12, lineHeight:1.4 },
footerMail: { flex:'0 0 auto', color:GREEN, fontSize:12, fontWeight:800, textDecoration:'none' },
overlay: { position:'fixed', inset:0, background:'rgba(0,0,0,0.35)', display:'flex', alignItems:'center', justifyContent:'center', zIndex:100, padding:16 },
modal: { background:'#fff', borderRadius:14, padding:'22px 22px', maxWidth:520, width:'100%', maxHeight:'88vh', overflow:'auto', boxShadow:'0 8px 30px rgba(0,0,0,0.12)' },