Footer Mega Section
Full site footer with brand, newsletter field, link columns, status pill, social icons and legal row.
footernavigationnewslettersocial
Live Preview
Usage
Copy and paste this code into your React component:
tsx
import { FooterMegaSection } from 'react-component-kit-ui/sections';
<FooterMegaSection brand="Acme" columns={[{ title: 'Product', links: [{ label: 'Pricing', href: '/pricing' }] }]} socials={[{ label: 'GitHub', href: 'https://github.com', icon: 'github' }]} />Manual Installation
If you are not using the npm package, create a new file and paste the following code: src/components/sections/FooterMegaSection.tsx + FooterMegaSection.css:
FooterMegaSection.tsx
'use client';
import './FooterMegaSection.css';
interface Column { title: string; links: Array<{ label: string; href: string }> }
interface Social { label: string; href: string; icon: 'github' | 'x' | 'discord' | 'youtube' }
/**
* FooterMegaSection โ Full site footer: brand blurb, newsletter field, four link
* columns, social icons, system-status pill and legal row.
*
* @param {string} brand - Brand name.
* @param {string} tagline - Short brand description.
* @param {Array<{title: string, links: Array<{label: string, href: string}>}>} columns - Link columns.
* @param {Array<{label: string, href: string, icon: 'github'|'x'|'discord'|'youtube'}>} socials - Social links.
* @param {string} status - System status text (empty to hide).
* @param {string} copyright - Copyright line.
* @param {string} variant - Footer style (default|bordered|minimal).
* @param {string} size - Vertical rhythm (sm|md|lg).
* @param {string} className - Extra CSS class.
*/
export interface FooterMegaSectionProps {
brand?: string;
tagline?: string;
columns?: Column[];
socials?: Social[];
status?: string;
copyright?: string;
variant?: 'default' | 'bordered' | 'minimal';
size?: 'sm' | 'md' | 'lg';
className?: string;
}
export function FooterMegaSection({
brand = 'Astro Kit',
tagline = 'Accessible, zero-dependency components for building beautiful Astro sites.',
columns = [
{ title: 'Product', links: [{ label: 'Components', href: '#' }, { label: 'Sections', href: '#' }, { label: 'Charts', href: '#' }, { label: 'Changelog', href: '#' }] },
{ title: 'Resources', links: [{ label: 'Documentation', href: '#' }, { label: 'Installation', href: '#' }, { label: 'Notes', href: '#' }, { label: 'Showcase', href: '#' }] },
{ title: 'Company', links: [{ label: 'About', href: '#' }, { label: 'Careers', href: '#' }, { label: 'Contact', href: '#' }] },
{ title: 'Legal', links: [{ label: 'Privacy', href: '#' }, { label: 'Terms', href: '#' }, { label: 'License (MIT)', href: '#' }] },
],
socials = [
{ label: 'GitHub', href: '#', icon: 'github' },
{ label: 'X (Twitter)', href: '#', icon: 'x' },
{ label: 'Discord', href: '#', icon: 'discord' },
{ label: 'YouTube', href: '#', icon: 'youtube' },
],
status = 'All systems operational',
copyright = `ยฉ ${new Date().getFullYear()} Astro Kit. All rights reserved.`,
variant = 'default',
size = 'md',
className = '',
}: FooterMegaSectionProps) {
const icons = {
github: '<path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.9a3.4 3.4 0 0 0-.9-2.6c3.1-.4 6.4-1.5 6.4-7A5.4 5.4 0 0 0 20 4.8 5 5 0 0 0 19.9 1S18.7.6 16 2.5a13.4 13.4 0 0 0-7 0C6.3.6 5.1 1 5.1 1A5 5 0 0 0 5 4.8a5.4 5.4 0 0 0-1.5 3.7c0 5.4 3.3 6.6 6.4 7a3.4 3.4 0 0 0-.9 2.6V22"/>',
x: '<path d="M4 4l16 16M20 4 4 20"/>',
discord: '<path d="M8 12h.01M16 12h.01"/><path d="M7.5 7.5c3-1 6-1 9 0M7 16.5c3 1 7 1 10 0"/><path d="M15.5 17l1 3c3-1 5-3 5.5-4.5.5-4-1-8-3-11-1.5-.8-3-1.2-4.5-1.5L14 4.5M8.5 17l-1 3c-3-1-5-3-5.5-4.5-.5-4 1-8 3-11 1.5-.8 3-1.2 4.5-1.5L10 4.5"/>',
youtube: '<path d="M2.5 17a24 24 0 0 1 0-10 2 2 0 0 1 1.4-1.4 49.6 49.6 0 0 1 16.2 0A2 2 0 0 1 21.5 7a24 24 0 0 1 0 10 2 2 0 0 1-1.4 1.4 49.6 49.6 0 0 1-16.2 0A2 2 0 0 1 2.5 17"/><path d="m10 15 5-3-5-3z"/>',
};
const id = `fms-${Math.random().toString(36).slice(2, 8)}`;
return (
<>
<div className="cq-footer-mega-section-cq" data-rk-6cdbde="">
<footer className={`fms fms--${variant} fms--${size} ${className}`} aria-labelledby={id} data-rk-6cdbde="">
<h2 id={id} className="fms__sr" data-rk-6cdbde="">Site footer</h2>
<div className="fms__inner" data-rk-6cdbde="">
<div className="fms__top" data-rk-6cdbde="">
<div className="fms__brand" data-rk-6cdbde="">
<a className="fms__logo" href="/" data-rk-6cdbde="">
<svg width="28" height="28" viewBox="0 0 24 24" aria-hidden="true" data-rk-6cdbde=""><path d="M12 2 3 20h4l5-10 5 10h4z" fill="var(--c-primary-light, #d4a017)" data-rk-6cdbde="" /></svg>
{brand}
</a>
<p className="fms__tagline" data-rk-6cdbde="">{tagline}</p>
<form className="fms__news" action="#" method="post" data-rk-6cdbde="">
<label htmlFor={`${id}-email`} className="fms__news-label" data-rk-6cdbde="">Get product updates</label>
<div className="fms__news-field" data-rk-6cdbde="">
<input id={`${id}-email`} type="email" name="email" placeholder="you@company.com" autoComplete="email" required data-rk-6cdbde="" />
<button type="submit" aria-label="Subscribe to product updates" data-rk-6cdbde="">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" aria-hidden="true" data-rk-6cdbde=""><path d="M5 12h14M13 6l6 6-6 6" data-rk-6cdbde="" /></svg>
</button>
</div>
</form>
</div>
<nav className="fms__cols" aria-label="Footer" data-rk-6cdbde="">
{columns.map((c, __i: number) => (
<div key={__i} className="fms__col" data-rk-6cdbde="">
<h3 className="fms__col-title" data-rk-6cdbde="">{c.title}</h3>
<ul data-rk-6cdbde="">
{c.links.map((l, __i: number) => <li key={__i} data-rk-6cdbde=""><a href={l.href} data-rk-6cdbde="">{l.label}</a></li>)}
</ul>
</div>
))}
</nav>
</div>
<div className="fms__bottom" data-rk-6cdbde="">
<p className="fms__copy" data-rk-6cdbde="">{copyright}</p>
{status && (
<a className="fms__status" href="#" data-rk-6cdbde="">
<span className="fms__dot" aria-hidden="true" data-rk-6cdbde=""></span>{status}
</a>
)}
<ul className="fms__socials" data-rk-6cdbde="">
{socials.map((s, __i: number) => (
<li key={__i} data-rk-6cdbde="">
<a href={s.href} aria-label={s.label} data-rk-6cdbde="">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" dangerouslySetInnerHTML={{ __html: icons[s.icon] }} data-rk-6cdbde=""></svg>
</a>
</li>
))}
</ul>
</div>
</div>
</footer>
</div>
</>
);
}
export default FooterMegaSection;FooterMegaSection.css
/* FooterMegaSection โ ported from astro-component-kit (sections/FooterMegaSection.astro) */
.cq-footer-mega-section-cq:where([data-rk-6cdbde]) { container-type: inline-size; }
.fms:where([data-rk-6cdbde]) {
--fms-py: 4.5rem;
padding: var(--fms-py) var(--sp-6, 1.5rem) 2rem;
background: var(--c-bg-1, #0a0a0a);
border-top: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.06);
}
.fms--sm:where([data-rk-6cdbde]) { --fms-py: 3rem; }
.fms--lg:where([data-rk-6cdbde]) { --fms-py: 6rem; }
.fms--bordered:where([data-rk-6cdbde]) .fms__inner:where([data-rk-6cdbde]) { padding: clamp(1.5rem, 4vw, 3rem); border-radius: var(--r-xl, 28px); border: 1px solid var(--c-border, rgb(var(--ink-rgb, 255 255 255) / 0.08)); background: rgb(var(--ink-rgb, 255 255 255) / 0.015); }
.fms--minimal:where([data-rk-6cdbde]) { background: transparent; border-top: 0; }
.fms--minimal:where([data-rk-6cdbde]) .fms__news:where([data-rk-6cdbde]) { display: none; }
.fms__sr:where([data-rk-6cdbde]) { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.fms__inner:where([data-rk-6cdbde]) { max-width: 1180px; margin: 0 auto; }
.fms__top:where([data-rk-6cdbde]) { display: grid; grid-template-columns: 1.2fr 2fr; gap: clamp(2rem, 6vw, 5rem); padding-bottom: 3rem; border-bottom: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.07); }
.fms__logo:where([data-rk-6cdbde]) { display: inline-flex; align-items: center; gap: 0.6rem; min-height: 44px; font-size: 1.25rem; font-weight: 800; letter-spacing: -0.02em; color: var(--c-text-1, #fff); text-decoration: none; }
.fms__tagline:where([data-rk-6cdbde]) { margin: 0.75rem 0 1.75rem; max-width: 320px; font-size: 0.9375rem; line-height: 1.6; color: var(--c-text-2, #a3a3a3); }
.fms__news-label:where([data-rk-6cdbde]) { display: block; margin-bottom: 0.5rem; font-size: 0.8125rem; font-weight: 600; color: var(--c-text-1, #fff); }
.fms__news-field:where([data-rk-6cdbde]) { display: flex; max-width: 340px; border-radius: var(--r-md, 12px); border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.12); background: rgba(0, 0, 0, 0.3); overflow: hidden; transition: border-color 0.2s ease; }
.fms__news-field:focus-within:where([data-rk-6cdbde]) { border-color: var(--c-primary-light, #d4a017); }
.fms__news-field:where([data-rk-6cdbde]) input:where([data-rk-6cdbde]) { flex: 1; min-width: 0; min-height: 46px; padding: 0 0.9rem; border: 0; background: transparent; color: var(--c-text-1, #fff); font: inherit; font-size: 0.9375rem; }
.fms__news-field:where([data-rk-6cdbde]) input:focus:where([data-rk-6cdbde]) { outline: none; }
.fms__news-field:where([data-rk-6cdbde]) input:where([data-rk-6cdbde])::placeholder { color: var(--c-text-3, #737373); }
.fms__news-field:where([data-rk-6cdbde]) button:where([data-rk-6cdbde]) { width: 46px; border: 0; background: rgb(var(--ink-rgb, 255 255 255) / 0.06); color: var(--c-text-1, #fff); cursor: pointer; transition: background 0.2s ease; }
.fms__news-field:where([data-rk-6cdbde]) button:hover:where([data-rk-6cdbde]) { background: var(--c-primary-light, #d4a017); color: var(--c-on-primary, #0a0a0a); }
.fms__news-field:where([data-rk-6cdbde]) button:focus-visible:where([data-rk-6cdbde]) { outline: 2px solid var(--c-primary-light, #d4a017); outline-offset: -2px; }
.fms__cols:where([data-rk-6cdbde]) { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 2rem; }
.fms__col-title:where([data-rk-6cdbde]) { margin: 0 0 1rem; font-size: 0.8125rem; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--c-text-1, #fff); }
.fms__col:where([data-rk-6cdbde]) ul:where([data-rk-6cdbde]) { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.25rem; }
.fms__col:where([data-rk-6cdbde]) a:where([data-rk-6cdbde]), .fms__copy:where([data-rk-6cdbde]), .fms__status:where([data-rk-6cdbde]) { font-size: 0.9rem; color: var(--c-text-2, #a3a3a3); text-decoration: none; }
.fms__col:where([data-rk-6cdbde]) a:where([data-rk-6cdbde]) { display: inline-flex; align-items: center; min-height: 36px; transition: color 0.2s ease; }
.fms__col:where([data-rk-6cdbde]) a:hover:where([data-rk-6cdbde]) { color: var(--c-text-1, #fff); }
.fms:where([data-rk-6cdbde]) a:focus-visible:where([data-rk-6cdbde]) { outline: 2px solid var(--c-primary-light, #d4a017); outline-offset: 2px; border-radius: 4px; }
.fms__bottom:where([data-rk-6cdbde]) { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem; padding-top: 1.75rem; }
.fms__copy:where([data-rk-6cdbde]) { margin: 0; font-size: 0.8125rem; }
.fms__status:where([data-rk-6cdbde]) { display: inline-flex; align-items: center; gap: 0.5rem; min-height: 36px; padding: 0 0.85rem; border-radius: 999px; border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08); font-size: 0.8125rem; }
.fms__status:hover:where([data-rk-6cdbde]) { color: var(--c-text-1, #fff); }
.fms__dot:where([data-rk-6cdbde]) { width: 8px; height: 8px; border-radius: 50%; background: var(--chart-pos, #34c38f); box-shadow: 0 0 8px var(--chart-pos, #34c38f); }
.fms__socials:where([data-rk-6cdbde]) { list-style: none; margin: 0; padding: 0; display: flex; gap: 0.25rem; }
.fms__socials:where([data-rk-6cdbde]) a:where([data-rk-6cdbde]) { display: grid; place-items: center; width: 44px; height: 44px; border-radius: 10px; color: var(--c-text-2, #a3a3a3); transition: color 0.2s ease, background 0.2s ease; }
.fms__socials:where([data-rk-6cdbde]) a:hover:where([data-rk-6cdbde]) { color: var(--c-text-1, #fff); background: rgb(var(--ink-rgb, 255 255 255) / 0.06); }
@container (max-width: 860px) { .fms__top:where([data-rk-6cdbde]) { grid-template-columns: 1fr; } }
@container (max-width: 560px) { .fms__bottom:where([data-rk-6cdbde]) { flex-direction: column; align-items: flex-start; } }