Landing: - Rebuilt app/(landing)/page.tsx from a 539-line client monolith to a ~150-line server component in the /resources editorial style. - New scoped app/(landing)/landing.css mirrors the resources palette (#0c0c0c / lime #d4ff00 / #252525), IBM Plex Mono + Libre Baskerville loaded in (landing)/layout.tsx, faint grid overlay. - Removed the animated Mini* previews and inline Ico* set (clashed with the editorial look). Split into components/landing/icons.tsx and components/landing/resource-showcase.tsx for separation. - Resource showcase: one row of six square tiles with the real project SVG logos linking to atlas/space-after-dark/proposal-duel/ zine/learner/governance. Responsive 6 -> 3 -> 2. - BrandMark accepts an optional style prop. Fix: - KB search crashed the Ops page. filteredLeads referenced l.member_name (the column is lead_handle), so undefined.toLowerCase() threw on every keystroke since the filter memos recompute on shared search state across tabs. All Ops filter predicates are now null-safe via a shared has() helper; filteredSecrets no longer assumes a non-null title. Docs: - docs/PERMISSIONS_DESIGN.md: concrete plan for customizable permissions, per-item Ops ACLs, and area-lead roles. That work is security-sensitive (RLS rewrites on secrets/knowledge_base) and is scoped as its own next pass, not bundled here. 266/266 tests pass. Production build clean. No migration this pass.
34 lines
998 B
TypeScript
34 lines
998 B
TypeScript
import type { Metadata } from 'next'
|
|
import { IBM_Plex_Mono, Libre_Baskerville } from 'next/font/google'
|
|
import './landing.css'
|
|
|
|
const ibmPlexMono = IBM_Plex_Mono({
|
|
subsets: ['latin'],
|
|
weight: ['400', '500'],
|
|
variable: '--font-ibm-plex-mono',
|
|
display: 'swap',
|
|
})
|
|
|
|
const libreBaskerville = Libre_Baskerville({
|
|
subsets: ['latin'],
|
|
weight: ['400', '700'],
|
|
style: ['normal', 'italic'],
|
|
variable: '--font-libre-baskerville',
|
|
display: 'swap',
|
|
})
|
|
|
|
export const metadata: Metadata = {
|
|
title: 'hackerspace.sh — Operational software for makerspaces',
|
|
description:
|
|
'Member management, dues tracking, task coordination, and project visibility. Built by people who have actually run these spaces.',
|
|
}
|
|
|
|
export default function LandingLayout({ children }: { children: React.ReactNode }) {
|
|
return (
|
|
<div className={`landing-root ${ibmPlexMono.variable} ${libreBaskerville.variable}`}>
|
|
<div className="landing-grid-bg" aria-hidden="true" />
|
|
{children}
|
|
</div>
|
|
)
|
|
}
|