From 88c7262a08f7d0471d7fd7588e82f32a7e818a21 Mon Sep 17 00:00:00 2001 From: Marco Sadjadi Date: Thu, 21 May 2026 23:25:26 +0200 Subject: [PATCH] fix(web): mobile-responsive hero, marketing site, docs and dashboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Hero h1 was a fixed text-[44px] — overflowed narrow phones. Now text-[30px] sm:text-[40px] md:text-[56px]. - Hero grid children get min-w-0 so the code blocks' overflow-x-auto actually constrains instead of widening the page. - Marketing nav: the inline links were hidden below md with no fallback. Added a hamburger MobileMenu; "Sign in" collapses into it on the smallest screens. - Section vertical padding is now responsive (py-14 sm:py-20). - globals.css: overflow-x: clip on as a safety net. - docs: the 240px sidebar is hidden below lg, article gets min-w-0. - dashboard header: nav labels collapse to icons on small screens. Verified: next build passes (40/40 pages). Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/web/app/(dashboard)/layout.tsx | 12 ++--- apps/web/app/(marketing)/layout.tsx | 15 ++++-- apps/web/app/(marketing)/page.tsx | 20 ++++---- apps/web/app/docs/layout.tsx | 6 +-- apps/web/app/globals.css | 4 ++ apps/web/components/marketing-mobile-menu.tsx | 47 +++++++++++++++++++ 6 files changed, 80 insertions(+), 24 deletions(-) create mode 100644 apps/web/components/marketing-mobile-menu.tsx diff --git a/apps/web/app/(dashboard)/layout.tsx b/apps/web/app/(dashboard)/layout.tsx index e687907..0072ec3 100644 --- a/apps/web/app/(dashboard)/layout.tsx +++ b/apps/web/app/(dashboard)/layout.tsx @@ -1,15 +1,15 @@ -import Link from 'next/link'; import { Logo } from '@/components/logo'; -import { LayoutGrid, Server, Settings, FileClock, Package } from 'lucide-react'; +import { FileClock, LayoutGrid, Package, Server, Settings } from 'lucide-react'; +import Link from 'next/link'; export default function DashboardLayout({ children }: { children: React.ReactNode }) { return (
-
-
+
+
-
-
-
); diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css index 3cca534..50c9dce 100644 --- a/apps/web/app/globals.css +++ b/apps/web/app/globals.css @@ -30,6 +30,10 @@ background: var(--color-bg); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; + /* Safety net against a stray wide element causing horizontal scroll on + mobile. `clip` (not `hidden`) does not create a scroll container, so it + leaves position: sticky intact. */ + overflow-x: clip; } body { background: var(--color-bg); diff --git a/apps/web/components/marketing-mobile-menu.tsx b/apps/web/components/marketing-mobile-menu.tsx new file mode 100644 index 0000000..34f8e85 --- /dev/null +++ b/apps/web/components/marketing-mobile-menu.tsx @@ -0,0 +1,47 @@ +'use client'; + +import { Menu, X } from 'lucide-react'; +import Link from 'next/link'; +import { useState } from 'react'; + +const LINKS = [ + { href: '/#how', label: 'How it works' }, + { href: '/templates', label: 'Templates' }, + { href: '/pricing', label: 'Pricing' }, + { href: '/docs', label: 'Docs' }, + { href: '/changelog', label: 'Changelog' }, +]; + +/** Hamburger menu shown below the md breakpoint, where the inline nav is hidden. */ +export function MarketingMobileMenu() { + const [open, setOpen] = useState(false); + return ( +
+ + {open && ( +
+ +
+ )} +
+ ); +}