10 Commits

Author SHA1 Message Date
e168a646a1 Fit mobile nav on small screens 2026-05-16 22:49:16 +01:00
d93f862cba Tighten mobile CTA sizing 2026-05-16 22:45:57 +01:00
ebec21f1ac Merge 3D typography preview into main 2026-05-16 22:39:55 +01:00
b77883a16c Revert "Merge pull request '3D' (#4) from 3D into main"
This reverts commit e69e20f753, reversing
changes made to 0ac37261a8.
2026-05-16 21:12:28 +01:00
e69e20f753 Merge pull request '3D' (#4) from 3D into main
Reviewed-on: #4
2026-05-16 20:49:27 +01:00
9186d90aac Separate mobile 3D callout from model 2026-05-16 18:58:19 +01:00
3bed358990 Polish mobile 3D annotations 2026-05-16 18:55:37 +01:00
c6143d7d13 Tune 3D model responsive scale 2026-05-16 18:52:38 +01:00
4ccfaf7b92 Refine 3D showcase framing 2026-05-16 18:49:21 +01:00
24beb5aa5e Add annotated glasses 3D showcase 2026-05-16 18:43:40 +01:00
3 changed files with 11 additions and 10 deletions

View File

@@ -13,6 +13,7 @@ All notable changes to the New Optic website will be documented in this file.
- Kept the language switcher visible in the mobile top navigation bar. - Kept the language switcher visible in the mobile top navigation bar.
- Added cursor-reactive stretch motion to desktop nav links and matched the glossy dark WhatsApp CTA style on mobile. - Added cursor-reactive stretch motion to desktop nav links and matched the glossy dark WhatsApp CTA style on mobile.
- Corrected the French 2004 trust wording to use "depuis" without "autour de". - Corrected the French 2004 trust wording to use "depuis" without "autour de".
- Tightened mobile sizing for the WhatsApp nav pill and hero trust badge.
## [1.0.0] - 2026-05-16 ## [1.0.0] - 2026-05-16

View File

@@ -29,9 +29,9 @@ export default function HeroSection({ t, whatsappUrl }: { t: Messages; whatsappU
<motion.div className="absolute left-1/2 top-24 hidden h-72 w-72 -translate-x-1/2 rounded-full bg-optical/10 blur-3xl lg:block" animate={canAnimateIntro ? { scale: [1, 1.16, 1], opacity: [0.55, 0.88, 0.55] } : undefined} transition={{ duration: 8, repeat: Infinity, ease: "easeInOut" }} /> <motion.div className="absolute left-1/2 top-24 hidden h-72 w-72 -translate-x-1/2 rounded-full bg-optical/10 blur-3xl lg:block" animate={canAnimateIntro ? { scale: [1, 1.16, 1], opacity: [0.55, 0.88, 0.55] } : undefined} transition={{ duration: 8, repeat: Infinity, ease: "easeInOut" }} />
<div className="mx-auto grid max-w-7xl items-center gap-12 lg:grid-cols-[1fr_0.92fr]"> <div className="mx-auto grid max-w-7xl items-center gap-12 lg:grid-cols-[1fr_0.92fr]">
<motion.div initial={canAnimateIntro ? { opacity: 0, y: 24 } : false} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.8, ease: [0.22, 1, 0.36, 1] }} className="relative z-10 text-center lg:text-start"> <motion.div initial={canAnimateIntro ? { opacity: 0, y: 24 } : false} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.8, ease: [0.22, 1, 0.36, 1] }} className="relative z-10 text-center lg:text-start">
<div className="mx-auto mb-6 inline-flex items-center gap-2 rounded-full border border-ink/10 bg-white/65 px-4 py-2 text-xs font-semibold uppercase tracking-[0.18em] text-ink/60 shadow-sm backdrop-blur lg:mx-0"> <div className="mx-auto mb-5 inline-flex max-w-full items-center gap-1.5 rounded-full border border-ink/10 bg-white/65 px-3 py-1.5 text-[10px] font-semibold uppercase tracking-[0.12em] text-ink/60 shadow-sm backdrop-blur max-[374px]:px-2.5 max-[374px]:text-[9px] max-[374px]:tracking-[0.08em] sm:mb-6 sm:gap-2 sm:px-4 sm:py-2 sm:text-xs sm:tracking-[0.18em] lg:mx-0">
<ShieldCheck size={15} className="text-optical" /> <ShieldCheck className="size-3.5 shrink-0 text-optical sm:size-[15px]" />
{t.hero.eyebrow} <span className="whitespace-nowrap leading-4">{t.hero.eyebrow}</span>
</div> </div>
<h1 className="mx-auto max-w-4xl text-5xl font-semibold tracking-[-0.075em] text-ink sm:text-7xl lg:mx-0 lg:text-8xl">{t.hero.title}</h1> <h1 className="mx-auto max-w-4xl text-5xl font-semibold tracking-[-0.075em] text-ink sm:text-7xl lg:mx-0 lg:text-8xl">{t.hero.title}</h1>
<p className="mx-auto mt-6 max-w-2xl text-lg leading-8 text-ink/64 sm:text-xl lg:mx-0">{t.hero.subtitle}</p> <p className="mx-auto mt-6 max-w-2xl text-lg leading-8 text-ink/64 sm:text-xl lg:mx-0">{t.hero.subtitle}</p>

View File

@@ -26,10 +26,10 @@ export default function Navbar({ locale, onLocaleChange, t, whatsappUrl }: { loc
} }
return ( return (
<header className="fixed inset-x-0 top-0 z-50 px-4 pt-4 sm:px-6"> <header className="fixed inset-x-0 top-0 z-50 px-4 pt-4 max-[374px]:px-2.5 sm:px-6">
<nav className="glass premium-glass mx-auto flex max-w-7xl items-center justify-between gap-2 rounded-full px-3 py-3 sm:px-5" aria-label="Main navigation"> <nav className="glass premium-glass mx-auto flex max-w-7xl items-center justify-between gap-2 rounded-full px-3 py-3 max-[374px]:px-2 max-[374px]:py-2.5 sm:px-5" aria-label="Main navigation">
<a href="#home" onClick={(event) => scrollToSection(event, "#home")} className="relative z-[3] flex items-center gap-3" aria-label="New Optic home"> <a href="#home" onClick={(event) => scrollToSection(event, "#home")} className="relative z-[3] flex items-center gap-3" aria-label="New Optic home">
<span className="relative grid size-10 place-items-center overflow-hidden rounded-full bg-white shadow-sm"> <span className="relative grid size-10 place-items-center overflow-hidden rounded-full bg-white shadow-sm max-[374px]:size-9">
<Image src={business.assets.logo} alt="New Optic logo" fill sizes="40px" className="object-contain p-1" priority /> <Image src={business.assets.logo} alt="New Optic logo" fill sizes="40px" className="object-contain p-1" priority />
</span> </span>
<span className="hidden text-sm font-semibold tracking-[-0.02em] xs:inline sm:inline">{business.name}</span> <span className="hidden text-sm font-semibold tracking-[-0.02em] xs:inline sm:inline">{business.name}</span>
@@ -48,9 +48,9 @@ export default function Navbar({ locale, onLocaleChange, t, whatsappUrl }: { loc
</PhysicsButton> </PhysicsButton>
</div> </div>
<div className="relative z-[3] flex items-center gap-2 md:hidden"> <div className="relative z-[3] flex items-center gap-1 max-[374px]:gap-0.5 sm:gap-2 md:hidden">
<LanguageSwitcher locale={locale} onLocaleChange={onLocaleChange} className="bg-white/80 backdrop-blur-none" buttonClassName="px-2 sm:px-3" /> <LanguageSwitcher locale={locale} onLocaleChange={onLocaleChange} className="bg-white/80 backdrop-blur-none max-[374px]:p-0.5" buttonClassName="px-2 max-[374px]:px-1.5 max-[374px]:py-1.5 sm:px-3" />
<PhysicsButton href={whatsappUrl} external className={`${navCtaClassName} px-3 py-2.5 text-xs max-[374px]:hidden sm:px-5 sm:text-sm`}> <PhysicsButton href={whatsappUrl} external className={`${navCtaClassName} px-2.5 py-2 text-[11px] max-[374px]:px-1.5 max-[374px]:py-1.5 max-[374px]:text-[9px] sm:px-5 sm:py-2.5 sm:text-sm`}>
{t.nav.cta} {t.nav.cta}
</PhysicsButton> </PhysicsButton>
<motion.button <motion.button
@@ -58,7 +58,7 @@ export default function Navbar({ locale, onLocaleChange, t, whatsappUrl }: { loc
onClick={() => setOpen((value) => !value)} onClick={() => setOpen((value) => !value)}
whileTap={{ scale: 0.94 }} whileTap={{ scale: 0.94 }}
transition={{ duration: 0.08 }} transition={{ duration: 0.08 }}
className="grid size-11 place-items-center rounded-full bg-white/70 text-ink outline-none transition focus-visible:ring-2 focus-visible:ring-optical/45 focus-visible:ring-offset-2" className="grid size-11 place-items-center rounded-full bg-white/70 text-ink outline-none transition max-[374px]:size-9 focus-visible:ring-2 focus-visible:ring-optical/45 focus-visible:ring-offset-2"
aria-label={t.nav.menu} aria-label={t.nav.menu}
aria-expanded={open} aria-expanded={open}
> >