feat: fixed footer with responsive height tokens
Footer is fixed bottom-0 with h-footer (5rem mobile) / md:h-footer-wide (4rem desktop). Body gets matching pb-footer/md:pb-footer-wide to reserve space. Tokens registered in @theme inline as --spacing-footer*.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import type { SiteSettingsRecord } from '$shared/api';
|
||||
import { getFirstRecord } from '$shared/api';
|
||||
import { buildFileUrl } from '$shared/lib';
|
||||
import { Button, Link } from '$shared/ui';
|
||||
import { Button, InlineSvg, Link } from '$shared/ui';
|
||||
|
||||
/**
|
||||
* Site-wide footer with contact email, social links, and CV download.
|
||||
@@ -9,21 +9,23 @@ import { Button, Link } from '$shared/ui';
|
||||
*/
|
||||
export async function Footer() {
|
||||
const settings = await getFirstRecord<SiteSettingsRecord>('site_settings', {
|
||||
expand: 'contacts,contacts.socials',
|
||||
expand: 'contacts,contacts.email,contacts.socials',
|
||||
tags: ['site_settings'],
|
||||
});
|
||||
|
||||
const cvUrl = settings?.cv ? buildFileUrl(settings.collectionId, settings.id, settings.cv) : null;
|
||||
const contacts = settings?.expand?.contacts;
|
||||
const email = contacts?.expand?.email;
|
||||
const socials = contacts?.expand?.socials ?? [];
|
||||
|
||||
return (
|
||||
<footer className="brutal-border-top px-8 py-6 lg:px-16 lg:py-8">
|
||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||
<div className="flex flex-wrap items-center gap-4">
|
||||
{contacts?.email && (
|
||||
<Link href={`mailto:${contacts.email}`} className="text-sm opacity-60 hover:opacity-100 no-underline">
|
||||
{contacts.email}
|
||||
<footer className="fixed bottom-0 left-0 right-0 z-50 h-footer md:h-footer-wide brutal-border-top bg-background px-8 lg:px-16 flex items-center">
|
||||
<div className="w-full flex flex-row justify-between gap-4">
|
||||
<div className="flex flex-wrap items-center gap-6 sm:gap-4">
|
||||
{email && (
|
||||
<Link href={email.url} external variant="secondary" className="flex items-center gap-1.5 text-sm">
|
||||
{email.icon && <InlineSvg svg={email.icon} className="inline-flex w-8 h-8 sm:hidden" />}
|
||||
<span className="hidden sm:block">{email.label}</span>
|
||||
</Link>
|
||||
)}
|
||||
{socials.map((social) => (
|
||||
@@ -31,9 +33,11 @@ export async function Footer() {
|
||||
key={social.id}
|
||||
href={social.url}
|
||||
external
|
||||
className="text-sm opacity-60 hover:opacity-100 no-underline"
|
||||
variant="secondary"
|
||||
className="flex items-center gap-1.5 text-sm"
|
||||
>
|
||||
{social.label}
|
||||
{social.icon && <InlineSvg svg={social.icon} className="inline-flex w-8 h-8 sm:hidden" />}
|
||||
<span className="hidden sm:block">{social.label}</span>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user