Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added assets/writer-desk-mobile.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/writer-desk.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions features-init.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@
frame.addEventListener('pointerleave', () => { if (raf) cancelAnimationFrame(raf); raf = 0; win.style.transform = ''; });
}

// The photograph behind the hero drifts slower than the page.
const art = document.querySelector('.fx-hero-art img');
if (art) {
let ticking = false;
const drift = () => { ticking = false; const y = Math.min(window.scrollY, 900); art.style.transform = 'translateY(' + (y * 0.18).toFixed(1) + 'px)'; };
addEventListener('scroll', () => { if (!ticking) { ticking = true; requestAnimationFrame(drift); } }, { passive: true });
}

// Each card's warm glow follows the pointer.
document.querySelectorAll('.fx-card').forEach(card => {
card.addEventListener('pointermove', e => {
Expand Down
10 changes: 8 additions & 2 deletions features.css
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
.fx .button.outline{background:transparent;color:var(--text);border:1px solid color-mix(in srgb,var(--gold) 60%,var(--line));box-shadow:none;transition:border-color .4s var(--ease),background .4s var(--ease),transform .4s var(--ease)}
.fx .button.outline:hover{border-color:var(--gold);background:color-mix(in srgb,var(--gold) 10%,transparent);transform:translateY(-2px)}

/* Hero */
.fx-hero{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:clamp(2rem,5vw,5rem);align-items:center;padding-top:clamp(1rem,4vw,3rem);padding-bottom:clamp(2rem,4vw,3rem)}
/* Hero, over a photograph: full-bleed, washed toward the page colour on the copy side and
at the bottom edge, so the type stays legible in both themes. */
.fx-hero{position:relative;isolation:isolate;display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:clamp(2rem,5vw,5rem);align-items:center;padding-top:clamp(1rem,4vw,3rem);padding-bottom:clamp(2rem,4vw,3rem)}
.fx-hero .hero-actions{display:flex;flex-wrap:wrap;justify-content:flex-start;gap:var(--space-3);margin:0}
.fx-hero .hero-note{margin-top:var(--space-4);font-size:var(--text-sm);text-align:left}

Expand Down Expand Up @@ -132,3 +133,8 @@
.fx-card,.fx-chips li,.fx-window,.fx-icon,.fx-inspect{transition:none}
.fx-card:hover,.fx-chips li:hover{transform:none}
}

.fx-hero-art{position:absolute;top:-1px;bottom:0;left:50%;width:100vw;transform:translateX(-50%);z-index:-1;overflow:hidden;pointer-events:none}
.fx-hero-art img{width:100%;height:112%;object-fit:cover;object-position:center 64%;opacity:.78;filter:saturate(.9);will-change:transform}
[data-theme=light] .fx-hero-art img{opacity:.5;filter:saturate(.75) brightness(1.1)}
.fx-hero-art::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,color-mix(in srgb,var(--bg) 78%,transparent) 0%,color-mix(in srgb,var(--bg) 40%,transparent) 45%,color-mix(in srgb,var(--bg) 8%,transparent) 100%),linear-gradient(180deg,color-mix(in srgb,var(--bg) 35%,transparent) 0%,transparent 25%,transparent 62%,var(--bg) 100%)}
7 changes: 4 additions & 3 deletions features.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,500;0,600;1,500;1,600&family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<link rel="stylesheet" href="landing.css?v=2">
<link rel="stylesheet" href="features.css?v=1">
<link rel="stylesheet" href="features.css?v=2">
<script src="landing-init.js?v=3" defer></script>
<script src="features-init.js?v=1" defer></script>
<script src="features-init.js?v=2" defer></script>
</head>
<body class="fx-body">
<a class="skip-link" href="#main">Skip to content</a>
Expand All @@ -40,6 +40,7 @@

<!-- HERO: the claim, and the product as it actually renders -->
<section class="fx-hero section-width">
<div class="fx-hero-art" aria-hidden="true"><img src="assets/writer-desk.jpg" srcset="assets/writer-desk-mobile.jpg 800w, assets/writer-desk.jpg 1600w" sizes="100vw" alt="" width="1600" height="2400" fetchpriority="high" decoding="async"></div>
<div class="fx-hero-copy fx-reveal">
<span class="eyebrow">FEATURES</span>
<h1>The manuscript diagnostic built for <em>serious</em> authors.</h1>
Expand Down Expand Up @@ -183,7 +184,7 @@ <h2>Your manuscript already contains the evidence.<br><em>See what it says.</em>
</section>
</main>

<footer class="site-footer section-width"><div><a class="footer-brand" href="index.html">AuthorScrolls</a><p>Your book. Understood.</p></div><nav aria-label="Footer"><a href="features.html">Features</a><a href="pricing.html">Pricing</a><a href="faq.html">Help & FAQ</a><a href="blog.html">Journal</a><a href="legal.html#privacy">Privacy</a><a href="legal.html#terms">Terms</a></nav><small>© 2026 AuthorScrolls</small></footer>
<footer class="site-footer section-width"><div><a class="footer-brand" href="index.html">AuthorScrolls</a><p>Your book. Understood.</p></div><nav aria-label="Footer"><a href="features.html">Features</a><a href="pricing.html">Pricing</a><a href="faq.html">Help & FAQ</a><a href="blog.html">Journal</a><a href="legal.html#privacy">Privacy</a><a href="legal.html#terms">Terms</a></nav><small>© 2026 AuthorScrolls · Photograph by Ayşenaz Bilgin on Pexels</small></footer>

<dialog id="auth-dialog" aria-labelledby="auth-title">
<button class="dialog-close" id="auth-close" aria-label="Close sign-in dialog">×</button>
Expand Down
48 changes: 31 additions & 17 deletions pricing-init.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
// Pricing page — Firebase init + checkout + FAQ
firebase.initializeApp(FIREBASE_CONFIG);
document.querySelectorAll('.faq-item').forEach(function(item){item.querySelector('.faq-q').addEventListener('click',function(){item.classList.toggle('open')})});
document.querySelectorAll('.checkout-tier').forEach(function(btn){btn.addEventListener('click',async function(){
// Wait for the restored session rather than reading currentUser before Firebase has loaded it.
var user=await new Promise(function(resolve){var stop=firebase.auth().onAuthStateChanged(function(u){stop();resolve(u)})});
if(!user){alert('Please sign in first at the home page');window.location.href='index.html';return}
var plan=btn.dataset.plan;btn.textContent='Redirecting...';btn.disabled=true;
try{
var hdrs={'content-type':'application/json'};
try{hdrs['authorization']='Bearer '+await user.getIdToken()}catch(e){}
var resp=await fetch('/api/checkout',{method:'POST',headers:hdrs,body:JSON.stringify({userId:user.uid,email:user.email,plan})});
var data=await resp.json();
if(data.url)window.location.href=data.url;
else{alert(data.error||'Checkout failed');btn.textContent='Get '+plan.charAt(0).toUpperCase()+plan.slice(1);btn.disabled=false}
}catch(e){alert('Error: '+e.message);btn.textContent='Get '+plan.charAt(0).toUpperCase()+plan.slice(1);btn.disabled=false}
})});
// Pricing page: FAQ and checkout. Sign-in and the header live in landing-init.js. The page must
// read and its FAQ must work even when the Firebase SDK cannot load; only checkout needs it.
(function(){
'use strict';
var hasFirebase=typeof firebase!=='undefined'&&typeof FIREBASE_CONFIG!=='undefined';
if(hasFirebase&&!firebase.apps.length)firebase.initializeApp(FIREBASE_CONFIG);
document.querySelectorAll('.faq-item').forEach(function(item){
var q=item.querySelector('.faq-q');
q.addEventListener('click',function(){var open=item.classList.toggle('open');q.setAttribute('aria-expanded',String(open));});
});
function openSignIn(){
var signIn=document.getElementById('nav-signin');
if(signIn)signIn.click();else window.location.href='index.html#signup';
}
document.querySelectorAll('.checkout-tier').forEach(function(btn){btn.addEventListener('click',async function(){
var label=btn.dataset.label||btn.textContent;
if(!hasFirebase){openSignIn();return;}
// Wait for the restored session rather than reading currentUser before Firebase has loaded it.
var user=await new Promise(function(resolve){var stop=firebase.auth().onAuthStateChanged(function(u){stop();resolve(u)})});
if(!user){openSignIn();return;}
var plan=btn.dataset.plan;btn.textContent='Redirecting…';btn.disabled=true;
try{
var hdrs={'content-type':'application/json'};
try{hdrs['authorization']='Bearer '+await user.getIdToken()}catch(e){}
var resp=await fetch('/api/checkout',{method:'POST',headers:hdrs,body:JSON.stringify({userId:user.uid,email:user.email,plan})});
var data=await resp.json();
if(data.url)window.location.href=data.url;
else{alert(data.error||'Checkout failed');btn.textContent=label;btn.disabled=false}
}catch(e){alert('Error: '+e.message);btn.textContent=label;btn.disabled=false}
})});
})();
48 changes: 48 additions & 0 deletions pricing.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* Pricing page, on the features page's base (features.css). */
.pr-hero{text-align:center;padding-top:clamp(1rem,4vw,3rem);padding-bottom:clamp(2rem,4vw,3rem)}
.pr-hero h1{margin:0 auto;max-width:16ch}
.pr-hero .fx-lede{margin:var(--space-6) auto var(--space-4);max-width:58ch}

.pr-plans{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-6);align-items:stretch;padding-bottom:clamp(3rem,7vw,6rem)}
.pr-plan{display:flex;flex-direction:column}
.pr-plan .fx-list{flex:1;margin-bottom:var(--space-8)}
.pr-plan .fx-list li{color:var(--muted)}
.pr-plan .fx-list li:first-child{color:var(--text)}
.pr-price{display:flex;align-items:baseline;gap:.5rem;margin:.2rem 0 var(--space-4)}
.pr-amount{font-family:var(--display);font-size:3rem;font-weight:600;line-height:1;color:var(--text)}
.pr-per{font-size:var(--text-sm);color:var(--muted)}
.pr-desc{font-size:var(--text-sm);min-height:3.2em}
.pr-cta{width:100%;justify-content:center;margin:0}
.pr-fine{font-size:var(--text-xs);color:var(--muted);margin-top:var(--space-3);text-align:center}
.pr-featured{border-color:color-mix(in srgb,var(--gold) 55%,var(--line));box-shadow:0 30px 70px -40px rgba(0,0,0,.7)}
.pr-flag{position:absolute;top:-.7rem;left:var(--space-8);font-size:var(--text-xs);letter-spacing:.12em;text-transform:uppercase;color:var(--bg);background:var(--gold);border-radius:999px;padding:.25rem .7rem}

.pr-how{display:grid;grid-template-columns:minmax(0,4fr) minmax(0,8fr);gap:clamp(2rem,5vw,5rem);align-items:start;border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding-top:clamp(3rem,6vw,5rem);padding-bottom:clamp(3rem,6vw,5rem)}
.pr-facts{margin:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-6)}
.pr-facts div{padding-left:var(--space-4);border-left:2px solid var(--gold);transition:border-color .4s var(--ease),transform .4s var(--ease)}
.pr-facts div:hover{transform:translateX(3px);border-color:var(--text)}
.pr-facts dt{font-family:var(--display);font-size:1.25rem;color:var(--text);margin-bottom:.35rem}
.pr-facts dd{margin:0;font-size:var(--text-sm);color:var(--muted);line-height:1.55}

.pr-faq{padding-top:clamp(3rem,6vw,5rem)}
.pr-faq h2{margin-bottom:var(--space-8)}
.faq-list{max-width:72ch}
.faq-item{border-top:1px solid var(--line)}
.faq-item:last-child{border-bottom:1px solid var(--line)}
.faq-q{display:flex;justify-content:space-between;align-items:center;gap:var(--space-4);width:100%;text-align:left;background:none;border:0;padding:1rem 0;font:600 1.05rem/1.3 var(--display);color:var(--text);cursor:pointer;transition:color .3s var(--ease)}
.faq-q::after{content:"+";font-family:var(--body);font-size:1.1rem;color:var(--gold);transition:transform .35s var(--ease)}
.faq-q:hover{color:var(--gold)}
.faq-item.open .faq-q::after{transform:rotate(45deg)}
.faq-a{display:grid;grid-template-rows:0fr;transition:grid-template-rows .45s var(--ease)}
.faq-a>p{overflow:hidden;margin:0;font-size:var(--text-sm);line-height:1.6;padding-bottom:0;transition:padding .45s var(--ease)}
.faq-item.open .faq-a{grid-template-rows:1fr}
.faq-item.open .faq-a>p{padding-bottom:1rem}

@media(max-width:960px){
.pr-plans{grid-template-columns:1fr;max-width:520px;margin-inline:auto}
.pr-how{grid-template-columns:1fr}
.pr-facts{grid-template-columns:1fr}
}
@media(prefers-reduced-motion:reduce){
.faq-a,.faq-q::after,.pr-facts div{transition:none}
}
Loading
Loading