spb/trouve-ka Public
Trouve-KA — moteur de recherche web indépendant, Québec-first. Crawler distribué, index OpenSearch, ranking bilingue, galerie d'images. En prod : www.trouve-ka.com
Python 76.8%
TypeScript 15.7%
SQL 3.9%
Shell 1.4%
CSS 1.3%
Dockerfile 0.7%
1/**2 * Trouve-KA — layout racine de l'application web3 * Author: Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 */67import type { Metadata, Viewport } from "next";8import { Inter, JetBrains_Mono, Space_Grotesk } from "next/font/google";9import Link from "next/link";10import { Wordmark } from "@/components/wordmark";11import { LiveCrawl } from "@/components/live-crawl";12import "./globals.css";1314const spaceGrotesk = Space_Grotesk({15 subsets: ["latin"],16 variable: "--font-space-grotesk",17});18const inter = Inter({ subsets: ["latin"], variable: "--font-inter" });19const jetbrains = JetBrains_Mono({20 subsets: ["latin"],21 variable: "--font-jetbrains",22});2324export const metadata: Metadata = {25 metadataBase: new URL(process.env.PUBLIC_URL ?? "https://www.trouve-ka.com"),26 title: {27 default: "Trouve-KA — Cherche le Québec",28 template: "%s — Trouve-KA",29 },30 description:31 "Moteur de recherche indépendant du web québécois. Trouve-KA découvre, indexe et classe les sites du Québec — en continu.",32};3334export const viewport: Viewport = {35 themeColor: "#141814",36 width: "device-width",37 initialScale: 1,38};3940const FOOTER_LINKS = [41 { href: "/trouveka-bot", label: "À propos du robot" },42 { href: "/status", label: "État du moteur" },43 { href: "/soumettre", label: "Soumettre un site" },44] as const;4546const SISTER_SITES = [47 ["Groupe·KA", "https://www.groupe-ka.com"],48 ["Lou·Ka", "https://www.lou-ka.com"],49 ["Immo·Ka", "https://www.immo-ka.com"],50 ["Auto·Ka", "https://www.auto-ka.com"],51 ["Fabri·Ka", "https://www.fabri-ka.com"],52 ["Food·Ka", "https://www.food-ka.com"],53] as const;5455export default function RootLayout({56 children,57}: Readonly<{ children: React.ReactNode }>) {58 return (59 <html lang="fr">60 <body61 className={`${spaceGrotesk.variable} ${inter.variable} ${jetbrains.variable} flex min-h-screen flex-col bg-paper font-body text-ink antialiased`}62 >63 <a64 href="#contenu"65 className="sr-only focus:not-sr-only focus:absolute focus:left-4 focus:top-4 focus:z-[100] focus:rounded-ctl focus:border-[1.5px] focus:border-ink focus:bg-ink focus:px-4 focus:py-2 focus:font-display focus:text-sm focus:font-bold focus:text-lime"66 >67 Aller au contenu principal68 </a>6970 <header className="sticky top-0 z-40 border-b-2 border-ink bg-paper md:bg-[rgba(245,243,238,0.9)] md:backdrop-blur-xl">71 <div className="mx-auto flex h-14 max-w-6xl items-center justify-between px-4 sm:px-6">72 <Link href="/" className="group rounded-sm" aria-label="Trouve-KA — accueil">73 <Wordmark />74 </Link>75 <nav aria-label="Navigation principale">76 <ul className="flex items-center gap-1">77 <li>78 <Link79 href="/status"80 className="gk-display inline-block rounded-full border-[1.5px] border-transparent px-3 py-[6px] text-[13px] font-bold text-ink-2 transition-colors hover:border-ink hover:text-ink"81 >82 État du moteur83 </Link>84 </li>85 <li>86 <Link87 href="/soumettre"88 className="gk-display inline-block rounded-full border-[1.5px] border-transparent px-3 py-[6px] text-[13px] font-bold text-ink-2 transition-colors hover:border-ink hover:text-ink"89 >90 Soumettre un site91 </Link>92 </li>93 </ul>94 </nav>95 </div>96 </header>9798 <div className="flex flex-1 flex-col">{children}</div>99100 <footer className="border-t-2 border-ink bg-ink py-9 text-[13px] text-[rgba(245,243,238,0.75)]">101 <div className="mx-auto max-w-6xl px-4 sm:px-6">102 <div className="flex flex-wrap items-baseline justify-between gap-x-8 gap-y-3">103 <Wordmark variant="footer" />104 <p className="gk-display text-[15px] font-bold text-[rgba(245,243,238,0.85)]">105 Un moteur de recherche par{" "}106 <a107 href="https://www.groupe-ka.com"108 target="_blank"109 rel="noopener noreferrer"110 className="whitespace-nowrap underline-offset-4 hover:underline hover:decoration-lime"111 >112 <span className="text-paper">Groupe</span>{" "}113 <span className="text-lime">KA</span>114 </a>115 </p>116 </div>117 <p className="gk-display mt-3 text-[15px] font-bold text-lime">118 Cherche le Québec.119 </p>120 <LiveCrawl />121 <nav aria-label="Liens de pied de page" className="mt-5">122 <ul className="flex flex-wrap gap-x-6 gap-y-2">123 {FOOTER_LINKS.map((link) => (124 <li key={link.href}>125 <Link126 href={link.href}127 className="rounded-sm text-[rgba(245,243,238,0.75)] underline-offset-4 transition-colors hover:text-lime hover:underline hover:decoration-lime"128 >129 {link.label}130 </Link>131 </li>132 ))}133 </ul>134 </nav>135 <ul className="gk-mono mt-6 flex flex-wrap gap-x-6 gap-y-2 text-[11px] font-bold uppercase tracking-[0.1em]">136 {SISTER_SITES.map(([label, href]) => (137 <li key={label}>138 <a139 href={href}140 target="_blank"141 rel="noopener noreferrer"142 className="text-[rgba(245,243,238,0.6)] underline-offset-4 transition-colors hover:text-lime hover:underline hover:decoration-lime"143 >144 {label}145 </a>146 </li>147 ))}148 </ul>149 <p className="gk-mono mt-7 border-t border-[rgba(245,243,238,0.15)] pt-5 text-[11px] text-[rgba(245,243,238,0.45)]">150 © 2026 Trouve-KA — Simon-Pierre Boucher ·{" "}151 <a152 href="mailto:contact@spboucher.ai"153 className="underline-offset-4 hover:text-lime hover:underline"154 >155 contact@spboucher.ai156 </a>157 </p>158 </div>159 </footer>160 </body>161 </html>162 );163}164