feat(web): SVG brand logo (ranked score bars) + favicon via app/icon.svg
LogoMark wired into header, footer and mobile drawer; full logo with CI-whisker signature in public/logo.svg. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Showing 5 changed files with +53 and −12
added
apps/web/app/icon.svg
+11 −0
@@ -0,0 +1,11 @@ | ||
| 1 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"> | |
| 2 | + <!-- | |
| 3 | + AI Risk Index favicon — ranked score bars, sharp cut. | |
| 4 | + Author: Simon-Pierre Boucher · contact@spboucher.ai | |
| 5 | + Copyright © 2026 Simon-Pierre Boucher. All rights reserved. | |
| 6 | + --> | |
| 7 | + <rect width="64" height="64" rx="12" fill="#2a78d6"/> | |
| 8 | + <rect x="13" y="14" width="38" height="9" rx="2" fill="#ffffff"/> | |
| 9 | + <rect x="13" y="28" width="27" height="9" rx="2" fill="#ffffff" opacity="0.82"/> | |
| 10 | + <rect x="13" y="42" width="16" height="9" rx="2" fill="#ffffff" opacity="0.62"/> | |
| 11 | +</svg> | |
modified
apps/web/app/layout.tsx
+5 −10
@@ -12,6 +12,7 @@ import Link from "next/link"; | ||
| 12 | 12 | import type { ReactNode } from "react"; |
| 13 | 13 | import { prisma } from "@airiskindex/db"; |
| 14 | 14 | import { INDEX_VERSION } from "@airiskindex/scoring"; |
| 15 | +import { LogoMark } from "@/components/logo"; | |
| 15 | 16 | import { MobileMenu } from "@/components/mobile-menu"; |
| 16 | 17 | import "./globals.css"; |
| 17 | 18 | |
@@ -77,11 +78,8 @@ export default async function RootLayout({ | ||
| 77 | 78 | )} |
| 78 | 79 | <header className="sticky top-0 z-40 border-b border-[var(--border)] backdrop-blur-md [background:var(--header)]"> |
| 79 | 80 | <nav className="relative mx-auto flex max-w-5xl items-center justify-between gap-3 px-4 py-3 sm:px-6"> |
| 80 | − <Link href="/" className="flex shrink-0 items-center gap-2 font-semibold tracking-tight"> | |
| 81 | − <span | |
| 82 | − aria-hidden="true" | |
| 83 | − className="inline-block h-2.5 w-2.5 rounded-full bg-[var(--seq)]" | |
| 84 | − /> | |
| 81 | + <Link href="/" className="flex shrink-0 items-center gap-2.5 font-semibold tracking-tight"> | |
| 82 | + <LogoMark size={24} /> | |
| 85 | 83 | AI Risk Index |
| 86 | 84 | </Link> |
| 87 | 85 | <div className="hidden items-center gap-6 text-sm text-[var(--ink-2)] sm:flex"> |
@@ -102,11 +100,8 @@ export default async function RootLayout({ | ||
| 102 | 100 | <footer className="mt-20 border-t border-[var(--border)] bg-[var(--surface-1)]"> |
| 103 | 101 | <div className="mx-auto grid max-w-5xl gap-8 px-4 py-10 sm:grid-cols-3 sm:px-6"> |
| 104 | 102 | <div> |
| 105 | − <p className="flex items-center gap-2 font-semibold tracking-tight"> | |
| 106 | − <span | |
| 107 | − aria-hidden="true" | |
| 108 | − className="inline-block h-2 w-2 rounded-full bg-[var(--seq)]" | |
| 109 | − /> | |
| 103 | + <p className="flex items-center gap-2.5 font-semibold tracking-tight"> | |
| 104 | + <LogoMark size={20} /> | |
| 110 | 105 | AI Risk Index |
| 111 | 106 | </p> |
| 112 | 107 | <p className="mt-2 text-xs leading-relaxed text-[var(--muted)]"> |
added
apps/web/components/logo.tsx
+19 −0
@@ -0,0 +1,19 @@ | ||
| 1 | +// File: logo.tsx | |
| 2 | +// Path: apps/web/components/logo.tsx | |
| 3 | +// Project: AI Risk Index — airiskindex.io | |
| 4 | +// Author: Simon-Pierre Boucher | |
| 5 | +// Contact: contact@spboucher.ai | |
| 6 | +// Copyright © 2026 Simon-Pierre Boucher. All rights reserved. | |
| 7 | +// | |
| 8 | +// Description: Brand mark — ranked score bars, sharp cut, on the index blue. | |
| 9 | + | |
| 10 | +export function LogoMark({ size = 22 }: { size?: number }): JSX.Element { | |
| 11 | + return ( | |
| 12 | + <svg width={size} height={size} viewBox="0 0 64 64" aria-hidden="true" className="shrink-0"> | |
| 13 | + <rect width="64" height="64" rx="12" fill="var(--seq)" /> | |
| 14 | + <rect x="13" y="14" width="38" height="9" rx="2" fill="#ffffff" /> | |
| 15 | + <rect x="13" y="28" width="27" height="9" rx="2" fill="#ffffff" opacity="0.82" /> | |
| 16 | + <rect x="13" y="42" width="16" height="9" rx="2" fill="#ffffff" opacity="0.62" /> | |
| 17 | + </svg> | |
| 18 | + ); | |
| 19 | +} | |
modified
apps/web/components/mobile-menu.tsx
+3 −2
@@ -13,6 +13,7 @@ | ||
| 13 | 13 | import Link from "next/link"; |
| 14 | 14 | import { useEffect, useState } from "react"; |
| 15 | 15 | import { createPortal } from "react-dom"; |
| 16 | +import { LogoMark } from "./logo"; | |
| 16 | 17 | |
| 17 | 18 | export function MobileMenu({ items }: { items: ReadonlyArray<readonly [string, string]> }): JSX.Element { |
| 18 | 19 | const [open, setOpen] = useState(false); |
@@ -65,8 +66,8 @@ export function MobileMenu({ items }: { items: ReadonlyArray<readonly [string, s | ||
| 65 | 66 | {/* Drawer sliding in from the right */} |
| 66 | 67 | <nav className="fixed right-0 top-0 z-50 flex h-dvh w-72 max-w-[85vw] animate-[drawer-in_180ms_ease-out] flex-col border-l border-[var(--border)] bg-[var(--surface-1)] shadow-2xl"> |
| 67 | 68 | <div className="flex items-center justify-between border-b border-[var(--grid)] px-5 py-3.5"> |
| 68 | − <span className="flex items-center gap-2 font-semibold tracking-tight"> | |
| 69 | − <span aria-hidden="true" className="h-2 w-2 rounded-full bg-[var(--seq)]" /> | |
| 69 | + <span className="flex items-center gap-2.5 font-semibold tracking-tight"> | |
| 70 | + <LogoMark size={20} /> | |
| 70 | 71 | AI Risk Index |
| 71 | 72 | </span> |
| 72 | 73 | <button |
added
apps/web/public/logo.svg
+15 −0
@@ -0,0 +1,15 @@ | ||
| 1 | +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 360 64" role="img" aria-label="AI Risk Index"> | |
| 2 | + <!-- | |
| 3 | + AI Risk Index logo — mark (score bars + confidence whisker) + wordmark. | |
| 4 | + Author: Simon-Pierre Boucher · contact@spboucher.ai | |
| 5 | + Copyright © 2026 Simon-Pierre Boucher. All rights reserved. | |
| 6 | + --> | |
| 7 | + <rect width="64" height="64" rx="12" fill="#2a78d6"/> | |
| 8 | + <rect x="13" y="14" width="38" height="9" rx="2" fill="#ffffff"/> | |
| 9 | + <rect x="13" y="28" width="27" height="9" rx="2" fill="#ffffff" opacity="0.82"/> | |
| 10 | + <rect x="13" y="42" width="16" height="9" rx="2" fill="#ffffff" opacity="0.62"/> | |
| 11 | + <!-- confidence whisker on the top bar --> | |
| 12 | + <line x1="45" y1="18.5" x2="56" y2="18.5" stroke="#cde2fb" stroke-width="2"/> | |
| 13 | + <line x1="56" y1="14.5" x2="56" y2="22.5" stroke="#cde2fb" stroke-width="2"/> | |
| 14 | + <text x="80" y="43" font-family="system-ui, -apple-system, 'Segoe UI', sans-serif" font-size="30" font-weight="700" letter-spacing="-0.5" fill="#0b0b0b">AI Risk Index</text> | |
| 15 | +</svg> | |
| 16 | ||