74 lines
4.7 KiB
TypeScript
74 lines
4.7 KiB
TypeScript
|
|
import { CSSProperties } from 'react';
|
||
|
|
import { ChatBgVariants } from './types';
|
||
|
|
|
||
|
|
// topographic — an elegant contour / elevation map.
|
||
|
|
//
|
||
|
|
// The motif is a delicate cartographic contour survey: nested rings suggest two
|
||
|
|
// gentle "peaks" and a shallow "valley", drawn with occasional heavier "index
|
||
|
|
// contour" lines for authenticity, all floating over a soft tonal wash. It is
|
||
|
|
// tuned to be *felt, not read* — line opacities sit well under legibility
|
||
|
|
// thresholds so crisp message text stays comfortably WCAG-AA in both themes.
|
||
|
|
//
|
||
|
|
// SEAMLESS TILING
|
||
|
|
// Each contour system is a `repeating-radial-gradient` whose ring period P is a
|
||
|
|
// clean divisor of its `backgroundSize` tile. A repeating-radial-gradient tiles
|
||
|
|
// seamlessly only when the tile edge falls on a whole number of ring periods, so
|
||
|
|
// every layer below uses tile = N * P. Peak A's fine (32px) and index (128px)
|
||
|
|
// layers share one 256px tile (256 = 8*32 = 2*128) AND one center, so the heavy
|
||
|
|
// index lines land exactly on every 4th fine ring — a true index contour, never
|
||
|
|
// drifting out of register. Peak B tiles 288 = 12*24; the valley tiles 384 =
|
||
|
|
// 8*48. The tonal washes/vignette are single non-repeating gradients sized to
|
||
|
|
// the same tiles, so nothing shows a visible seam.
|
||
|
|
|
||
|
|
const dark: CSSProperties = {
|
||
|
|
backgroundColor: 'oklch(0.205 0.018 235)',
|
||
|
|
backgroundImage: [
|
||
|
|
// Peak A — fine contour lines (soft teal), 32px period.
|
||
|
|
'repeating-radial-gradient(circle at 27% 34%, transparent 0, transparent 26px,' +
|
||
|
|
' oklch(0.62 0.055 190 / 0.09) 27px, oklch(0.62 0.055 190 / 0.09) 28px, transparent 29px, transparent 32px)',
|
||
|
|
// Peak A — index (heavier) contour every 4th ring, 128px period.
|
||
|
|
'repeating-radial-gradient(circle at 27% 34%, transparent 0, transparent 122px,' +
|
||
|
|
' oklch(0.66 0.06 190 / 0.10) 123px, oklch(0.66 0.06 190 / 0.10) 125px, transparent 126px, transparent 128px)',
|
||
|
|
// Peak B — fine contour lines (cooler sage-teal), 24px period.
|
||
|
|
'repeating-radial-gradient(circle at 78% 72%, transparent 0, transparent 19px,' +
|
||
|
|
' oklch(0.60 0.05 200 / 0.07) 20px, oklch(0.60 0.05 200 / 0.07) 21px, transparent 22px, transparent 24px)',
|
||
|
|
// Valley — broad shallow rings (very faint), 48px period.
|
||
|
|
'repeating-radial-gradient(circle at 52% 8%, transparent 0, transparent 42px,' +
|
||
|
|
' oklch(0.58 0.045 195 / 0.05) 43px, oklch(0.58 0.045 195 / 0.05) 44px, transparent 45px, transparent 48px)',
|
||
|
|
// Tonal wash — lifts the "peaks", sinks the corners for depth.
|
||
|
|
'radial-gradient(circle at 27% 34%, oklch(0.26 0.03 200 / 0.55) 0%, transparent 46%)',
|
||
|
|
'radial-gradient(circle at 78% 72%, oklch(0.24 0.028 205 / 0.45) 0%, transparent 44%)',
|
||
|
|
// Vignette — soft edge darkening keeps the field calm behind text.
|
||
|
|
'radial-gradient(ellipse 120% 130% at 50% 42%, transparent 58%, oklch(0.15 0.02 235 / 0.55) 100%)',
|
||
|
|
].join(','),
|
||
|
|
backgroundSize:
|
||
|
|
'256px 256px, 256px 256px, 288px 288px, 384px 384px, 100% 100%, 100% 100%, 100% 100%',
|
||
|
|
};
|
||
|
|
|
||
|
|
const light: CSSProperties = {
|
||
|
|
backgroundColor: 'oklch(0.965 0.008 85)',
|
||
|
|
backgroundImage: [
|
||
|
|
// Peak A — fine contour lines (warm graphite/sand), 32px period.
|
||
|
|
'repeating-radial-gradient(circle at 27% 34%, transparent 0, transparent 26px,' +
|
||
|
|
' oklch(0.45 0.03 70 / 0.08) 27px, oklch(0.45 0.03 70 / 0.08) 28px, transparent 29px, transparent 32px)',
|
||
|
|
// Peak A — index (heavier) contour every 4th ring, 128px period.
|
||
|
|
'repeating-radial-gradient(circle at 27% 34%, transparent 0, transparent 122px,' +
|
||
|
|
' oklch(0.40 0.035 68 / 0.10) 123px, oklch(0.40 0.035 68 / 0.10) 125px, transparent 126px, transparent 128px)',
|
||
|
|
// Peak B — fine contour lines (soft sage-graphite), 24px period.
|
||
|
|
'repeating-radial-gradient(circle at 78% 72%, transparent 0, transparent 19px,' +
|
||
|
|
' oklch(0.47 0.028 120 / 0.06) 20px, oklch(0.47 0.028 120 / 0.06) 21px, transparent 22px, transparent 24px)',
|
||
|
|
// Valley — broad shallow rings (very faint), 48px period.
|
||
|
|
'repeating-radial-gradient(circle at 52% 8%, transparent 0, transparent 42px,' +
|
||
|
|
' oklch(0.46 0.025 75 / 0.045) 43px, oklch(0.46 0.025 75 / 0.045) 44px, transparent 45px, transparent 48px)',
|
||
|
|
// Tonal wash — warm paper highlights over the "peaks".
|
||
|
|
'radial-gradient(circle at 27% 34%, oklch(0.985 0.012 85 / 0.60) 0%, transparent 46%)',
|
||
|
|
'radial-gradient(circle at 78% 72%, oklch(0.945 0.014 95 / 0.45) 0%, transparent 44%)',
|
||
|
|
// Vignette — feather the edges to a slightly deeper sand for depth.
|
||
|
|
'radial-gradient(ellipse 120% 130% at 50% 42%, transparent 58%, oklch(0.90 0.016 80 / 0.45) 100%)',
|
||
|
|
].join(','),
|
||
|
|
backgroundSize:
|
||
|
|
'256px 256px, 256px 256px, 288px 288px, 384px 384px, 100% 100%, 100% 100%, 100% 100%',
|
||
|
|
};
|
||
|
|
|
||
|
|
export const topographic: ChatBgVariants = { dark, light };
|