Fix announcement bar flash, header edge-pinned layout, calculator text sizes

This commit is contained in:
Jeffrey 2026-02-21 17:53:52 +01:00
parent f838dc1c6e
commit 488662fcbe
2 changed files with 21 additions and 12 deletions

View File

@ -59,7 +59,13 @@ export const HeaderClient: React.FC<HeaderClientProps> = ({ data, socialLinks =
className="relative z-20 w-full bg-white dark:bg-fd-navy border-b border-transparent dark:border-white/10" className="relative z-20 w-full bg-white dark:bg-fd-navy border-b border-transparent dark:border-white/10"
{...(theme ? { 'data-theme': theme } : {})} {...(theme ? { 'data-theme': theme } : {})}
> >
<div className="container py-5 flex justify-between items-center"> {/*
* Replaced `container` with consistent edge-pinned padding.
* px-6 (24px) on mobile, px-8 (32px) on tablet, px-12 (48px) on desktop.
* No max-width logo and nav stay near the viewport edges at all sizes.
* No more jumping between breakpoints.
*/}
<div className="w-full px-6 md:px-8 lg:px-12 py-5 flex justify-between items-center">
<Link href={logoHref}> <Link href={logoHref}>
<Logo loading="eager" priority="high" variant={isDark ? 'white' : 'blue'} className="max-w-[80px] md:max-w-[100px]" /> <Logo loading="eager" priority="high" variant={isDark ? 'white' : 'blue'} className="max-w-[80px] md:max-w-[100px]" />
</Link> </Link>

View File

@ -32,16 +32,24 @@ export const AnnouncementBarComponent: React.FC<Props> = ({
dismissible = true, dismissible = true,
backgroundColor = 'yellow', backgroundColor = 'yellow',
}) => { }) => {
const [dismissed, setDismissed] = useState(false) /*
* Start as 'unknown' don't render anything until we've checked localStorage.
* This prevents the flash where the bar shows then immediately hides.
* null = hasn't checked yet, true = dismissed, false = should show
*/
const [dismissed, setDismissed] = useState<boolean | null>(null)
useEffect(() => { useEffect(() => {
const key = `fd-announcement-${text?.slice(0, 20)}` const key = `fd-announcement-${text?.slice(0, 20)}`
if (typeof window !== 'undefined' && localStorage.getItem(key) === 'dismissed') { if (typeof window !== 'undefined' && localStorage.getItem(key) === 'dismissed') {
setDismissed(true) setDismissed(true)
} else {
setDismissed(false)
} }
}, [text]) }, [text])
if (dismissed || !text) return null // Don't render until we know the dismiss state (prevents flash)
if (dismissed === null || dismissed === true || !text) return null
const bgClass = const bgClass =
backgroundColor === 'navy' ? 'bg-fd-navy text-white' : backgroundColor === 'navy' ? 'bg-fd-navy text-white' :
@ -57,19 +65,15 @@ export const AnnouncementBarComponent: React.FC<Props> = ({
const href = resolveUrl(buttonLink) const href = resolveUrl(buttonLink)
const newTab = buttonLink?.newTab ?? false const newTab = buttonLink?.newTab ?? false
/*
* If a link is provided, the entire text becomes clickable.
* buttonLabel is appended to the text with an arrow if present,
* but it's all one inline link no alignment issues.
*/
const displayText = buttonLabel ? `${text} ${buttonLabel}` : text const displayText = buttonLabel ? `${text} ${buttonLabel}` : text
return ( return (
<div <div
className={`w-full px-10 py-2 relative flex items-center justify-center ${bgClass}`} className={`w-full px-4 md:px-10 py-2.5 relative flex items-center justify-center ${bgClass}`}
role="status" role="status"
> >
<div className="text-sm font-joey text-center"> {/* pr-8 reserves space for dismiss button on mobile */}
<div className={`text-sm font-joey text-center ${dismissible ? 'pr-8 md:pr-0' : ''}`}>
{href ? ( {href ? (
<a <a
href={href} href={href}
@ -84,11 +88,10 @@ export const AnnouncementBarComponent: React.FC<Props> = ({
)} )}
</div> </div>
{/* Dismiss — absolutely positioned so it doesn't affect centering */}
{dismissible && ( {dismissible && (
<button <button
onClick={handleDismiss} onClick={handleDismiss}
className="absolute right-4 top-1/2 -translate-y-1/2 opacity-60 hover:opacity-100 transition-opacity" className="absolute right-3 md:right-4 top-1/2 -translate-y-1/2 opacity-60 hover:opacity-100 transition-opacity p-1"
aria-label="Stäng notis" aria-label="Stäng notis"
> >