67 lines
4.0 KiB
TypeScript
67 lines
4.0 KiB
TypeScript
|
|
import { CSSProperties } from 'react';
|
|||
|
|
import { ChatBgVariants } from './types';
|
|||
|
|
|
|||
|
|
// hexgrid — a refined sci-fi HUD honeycomb lattice.
|
|||
|
|
//
|
|||
|
|
// The motif is a crisp pointy-top hexagon honeycomb, drawn as thin interlocking
|
|||
|
|
// outlines like the readout of a sci-fi interface. It is layered over a soft
|
|||
|
|
// depth sheen: a faint central glow lifts the middle of the field and a gentle
|
|||
|
|
// vignette settles the corners, so the lattice reads as a lit HUD surface with
|
|||
|
|
// dimension rather than a flat repeating tile. Everything is kept at low alpha
|
|||
|
|
// (hex lines ~0.14–0.16, washes well under legibility thresholds) so the motif
|
|||
|
|
// is *felt, not read* — crisp message text stays comfortably WCAG-AA in both
|
|||
|
|
// themes.
|
|||
|
|
//
|
|||
|
|
// SEAMLESS TILING
|
|||
|
|
// The hex outlines live in a single inline-SVG data-URI tile of exactly
|
|||
|
|
// √3·s × 3·s = 34.641 × 60 (side length s = 20). That is the natural repeat cell
|
|||
|
|
// of a pointy-top honeycomb: one full central hexagon plus the six neighbours
|
|||
|
|
// whose bodies straddle the tile edges. Because each straddling hexagon is drawn
|
|||
|
|
// in full, the half that spills past one edge is completed pixel-for-pixel by the
|
|||
|
|
// matching half re-entering from the opposite edge on the next repeat — the six
|
|||
|
|
// vertical side edges land exactly on x = 0 and x = 34.641, the slanted edges
|
|||
|
|
// meet across y = 0 / y = 60, so the lattice interlocks with no seam and no
|
|||
|
|
// moiré. `backgroundSize: 34.641px 60px` locks the tile to that period; the glow
|
|||
|
|
// and vignette are single non-repeating layers sized to 100%.
|
|||
|
|
//
|
|||
|
|
// DARK vs LIGHT
|
|||
|
|
// Dark: cool cyan hex lines (oklch 0.72 0.1 200) on a deep blue-black base, with
|
|||
|
|
// a soft cyan-tinted central glow — the classic "cold HUD" look.
|
|||
|
|
// Light: soft slate-blue hexes (oklch 0.55 0.07 250) on a pale cool-white sheet,
|
|||
|
|
// with a bright paper highlight at centre. Each alpha/lightness is tuned
|
|||
|
|
// independently so both feel equally quiet against their own base.
|
|||
|
|
|
|||
|
|
// One seamless honeycomb tile (√3·20 × 3·20). Colour is injected per-theme.
|
|||
|
|
const hexTile = (stroke: string): string =>
|
|||
|
|
`url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2234.641%22%20height%3D%2260%22%3E%3Cpath%20d%3D%22M17.32%2010L0%2020L0%2040L17.32%2050L34.64%2040L34.64%2020Z%20M0%20-20L-17.32%20-10L-17.32%2010L0%2020L17.32%2010L17.32%20-10Z%20M34.64%20-20L17.32%20-10L17.32%2010L34.64%2020L51.96%2010L51.96%20-10Z%20M0%2040L-17.32%2050L-17.32%2070L0%2080L17.32%2070L17.32%2050Z%20M34.64%2040L17.32%2050L17.32%2070L34.64%2080L51.96%2070L51.96%2050Z%20M17.32%20-50L0%20-40L0%20-20L17.32%20-10L34.64%20-20L34.64%20-40Z%20M17.32%2070L0%2080L0%20100L17.32%20110L34.64%20100L34.64%2080Z%22%20fill%3D%22none%22%20stroke%3D%22${encodeURIComponent(
|
|||
|
|
stroke,
|
|||
|
|
)}%22%20stroke-width%3D%220.9%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E")`;
|
|||
|
|
|
|||
|
|
const dark: CSSProperties = {
|
|||
|
|
backgroundColor: 'oklch(0.19 0.03 245)',
|
|||
|
|
backgroundImage: [
|
|||
|
|
// 1. the honeycomb lattice — cool cyan hex outlines.
|
|||
|
|
hexTile('oklch(0.72 0.1 200 / 0.14)'),
|
|||
|
|
// 2. central glow — a soft cyan lift so the field looks lit from within.
|
|||
|
|
'radial-gradient(120% 90% at 50% 42%, oklch(0.30 0.05 210 / 0.55) 0%, transparent 60%)',
|
|||
|
|
// 3. vignette — settles the corners into the deep base for depth.
|
|||
|
|
'radial-gradient(130% 130% at 50% 45%, transparent 55%, oklch(0.13 0.02 240 / 0.55) 100%)',
|
|||
|
|
].join(','),
|
|||
|
|
backgroundSize: '34.641px 60px, 100% 100%, 100% 100%',
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const light: CSSProperties = {
|
|||
|
|
backgroundColor: 'oklch(0.965 0.008 240)',
|
|||
|
|
backgroundImage: [
|
|||
|
|
// 1. the honeycomb lattice — soft slate-blue hex outlines.
|
|||
|
|
hexTile('oklch(0.55 0.07 250 / 0.16)'),
|
|||
|
|
// 2. central highlight — a hint of brighter paper toward the middle.
|
|||
|
|
'radial-gradient(120% 90% at 50% 40%, oklch(0.99 0.005 240 / 0.7) 0%, transparent 60%)',
|
|||
|
|
// 3. vignette — feather the edges into a slightly cooler paper.
|
|||
|
|
'radial-gradient(130% 130% at 50% 45%, transparent 58%, oklch(0.90 0.015 245 / 0.5) 100%)',
|
|||
|
|
].join(','),
|
|||
|
|
backgroundSize: '34.641px 60px, 100% 100%, 100% 100%',
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export const hexgrid: ChatBgVariants = { dark, light };
|