From 60e0a4103e54d2166aa1dcc4a0d33c73b8f21692 Mon Sep 17 00:00:00 2001 From: Frilly Date: Tue, 28 Jul 2026 21:15:38 +0200 Subject: [PATCH] feat: mobile-responsive landing page - Add viewport-fit=cover for safe-area support - Add CSS safe-area utilities, touch targets (44px min), overscroll-behavior containment - Nav: stack buttons on mobile with full-width touch targets (py-3, min-h-44px) - Hero: prism visible on mobile above headline (max-w-[280px]), full-width CTAs on mobile, responsive text clamp - Tools grid: responsive 2-col grid with adaptive padding (p-4 sm:p-5), smaller text on mobile - How it works: smaller step icons on mobile (w-10/h-10), responsive text sizing, tighter spacing - CTA: full-width buttons on mobile with min-h-44px touch targets - Footer: column stack on mobile, responsive padding, improved text colors --- frontend/index.html | 2 +- frontend/src/index.css | 65 ++++++++++++++ frontend/src/pages/LandingPage.tsx | 139 ++++++++++++++++------------- 3 files changed, 143 insertions(+), 63 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index 336cead..e1dc22f 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -3,7 +3,7 @@ - + Crystal-PDF diff --git a/frontend/src/index.css b/frontend/src/index.css index 5a926e0..ceba8c4 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -37,16 +37,60 @@ height: 100%; } + /* Safe-area insets for notched devices */ + :root { + --safe-top: env(safe-area-inset-top, 0); + --safe-right: env(safe-area-inset-right, 0); + --safe-bottom: env(safe-area-inset-bottom, 0); + --safe-left: env(safe-area-inset-left, 0); + } + body { background-color: var(--color-bg); color: var(--color-text); font-family: 'Plus Jakarta Sans', ui-sans-serif, system-ui, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; + /* Prevent horizontal overflow */ + overflow-x: hidden; + /* Safe-area padding for body */ + padding-bottom: max(var(--safe-bottom), 0); } * { border-color: var(--color-border); + /* Prevent horizontal overflow on all elements */ + box-sizing: border-box; + } + + /* Touch targets - minimum 44x44px touch targets for accessibility */ + button, + [role="button"], + a[href], + input, + select, + textarea { + touch-action: manipulation; + min-height: 44px; + min-width: 44px; + } + + /* Prevent overscroll bounce on iOS */ + html, body { + overscroll-behavior: contain; + } + + /* Prevent text size adjust on orientation change */ + html { + -webkit-text-size-adjust: 100%; + text-size-adjust: 100%; + } + + /* Improved text rendering on mobile */ + body { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; } } @@ -68,6 +112,27 @@ box-shadow: 0 4px 16px rgba(0,0,0,0.25); } +/* ── Safe-area utility classes ─────────────────────────────────────────────── */ +.safe-top { padding-top: max(var(--safe-top), 0); } +.safe-bottom { padding-bottom: max(var(--safe-bottom), 0); } +.safe-left { padding-left: max(var(--safe-left), 0); } +.safe-right { padding-right: max(var(--safe-right), 0); } +.safe-x { padding-left: max(var(--safe-left), 0); padding-right: max(var(--safe-right), 0); } +.safe-y { padding-top: max(var(--safe-top), 0); padding-bottom: max(var(--safe-bottom), 0); } +.safe-all { padding: max(var(--safe-top), 0) max(var(--safe-right), 0) max(var(--safe-bottom), 0) max(var(--safe-left), 0); } + +/* ── Mobile utilities ──────────────────────────────────────────────────────── */ +/* Ensure full-width buttons on mobile */ +@media (max-width: 639px) { + .btn-mobile-full { + width: 100%; + } + /* Prevent text from being too small on mobile */ + .text-mobile-sm { font-size: 0.875rem; line-height: 1.25rem; } + .text-mobile-base { font-size: 1rem; line-height: 1.5rem; } + .text-mobile-lg { font-size: 1.125rem; line-height: 1.75rem; } +} + /* ── Category section fade-in ────────────────────────────────────────────── */ @keyframes fadeUp { from { opacity: 0; transform: translateY(8px); } diff --git a/frontend/src/pages/LandingPage.tsx b/frontend/src/pages/LandingPage.tsx index baede37..d2c272c 100644 --- a/frontend/src/pages/LandingPage.tsx +++ b/frontend/src/pages/LandingPage.tsx @@ -35,7 +35,7 @@ const steps = [ export default function LandingPage() { return ( -
+
{/* ── CSS ─────────────────────────────────────────────── */} {/* ── Ambient glow ───────────────────────────────────── */} @@ -140,27 +145,27 @@ export default function LandingPage() {
{/* ── Nav ────────────────────────────────────────────── */} - {/* ── Hero ───────────────────────────────────────────── */} -
+
+ {/* Crystal visual - shown on mobile ABOVE text, on desktop to the right */} +
+
+
+
+ +
+
+
+
+ {/* Text column */} -
+

- Every
PDF tool
you'll ever{' '} - need. + text-[clamp(2rem,6vw,3.5rem)] sm:text-[clamp(2.5rem,7vw,4rem)] lg:text-[clamp(2.8rem,8vw,4.8rem)] text-white anim-reveal"> + Every PDF tool you\u0027ll ever + need.

-

- Merge, split, compress, protect, convert, and annotate — +

+ Merge, split, compress, protect, convert, and annotate— from one elegant workspace. No subscriptions, no upload limits.

-
+
+ hover:-translate-y-px active:translate-y-0 transition-all w-full sm:w-auto min-h-[44px]"> Start for free + hover:bg-white/[.03] transition-all w-full sm:w-auto min-h-[44px]"> Sign in to workspace
- {/* Crystal visual */} -
-
- {/* Inner facets */} + {/* Crystal visual - desktop only, on the right */} +
+
@@ -215,36 +230,36 @@ export default function LandingPage() {
{/* ── Tools grid ─────────────────────────────────────── */} -
-
+
+
{/* Section header */} -
+

Toolkit

-

Everything in
one workspace

-

+

Every operation produces a new file — your originals stay untouched.

{/* Grid */} -
+
{tools.map((t) => ( -
+
-

+

{t.name}

-

+

{t.desc}

@@ -254,15 +269,15 @@ export default function LandingPage() {
{/* ── How it works ───────────────────────────────────── */} -
-
-
-

+

+
+
+

How it works

-

- Three steps, that's it + Three steps, that\u0027s it

@@ -270,24 +285,24 @@ export default function LandingPage() { {steps.map((s, i) => (
{/* Step row */} -
+
{/* Left: number + icon */} -
-
+
{/* Right: text */} -
+

Step {s.num}

-

+

{s.title}

-

+

{s.body}

@@ -295,8 +310,8 @@ export default function LandingPage() { {/* Connector between steps */} {i < steps.length - 1 && ( -
-
+
+
@@ -308,8 +323,8 @@ export default function LandingPage() {
{/* ── CTA ────────────────────────────────────────────── */} -
-
+
+
{/* Soft top glow */}
@@ -322,18 +337,18 @@ export default function LandingPage() { Start working with
your PDFs today. -
+
+ hover:-translate-y-px transition-all w-full sm:w-auto min-h-[44px]"> Create free account + className="inline-flex items-center justify-center gap-2 px-7 py-3.5 rounded-xl text-[15px] font-medium + text-slate-400 hover:text-slate-200 transition-colors w-full sm:w-auto min-h-[44px]"> or sign in
@@ -341,12 +356,12 @@ export default function LandingPage() {
{/* ── Footer ─────────────────────────────────────────── */} -