77 lines
4.6 KiB
TypeScript
77 lines
4.6 KiB
TypeScript
|
|
import { CSSProperties } from 'react';
|
|||
|
|
import { ChatBgVariants } from './types';
|
|||
|
|
|
|||
|
|
// chevron — refined woven-upholstery zigzag.
|
|||
|
|
//
|
|||
|
|
// The motif is a continuous, crisp chevron built to read as *textured fabric*
|
|||
|
|
// rather than flat stripes. The zigzag threads themselves are drawn with a
|
|||
|
|
// tiny inline-SVG tile (guaranteed geometrically seamless — the "V" path exits
|
|||
|
|
// each tile edge exactly where the next tile's path enters, both horizontally
|
|||
|
|
// and vertically). Over that, layered CSS gradients add the premium feel:
|
|||
|
|
// • a soft light→shade sweep across the weave gives each band an embossed,
|
|||
|
|
// woven cross-section (catches light on one diagonal face, shade on the
|
|||
|
|
// other);
|
|||
|
|
// • a faint two-tone wash alternates the tint of successive chevron rows for
|
|||
|
|
// an interlocked-yarn look;
|
|||
|
|
// • a gentle centre lift + corner vignette settle the field so text always
|
|||
|
|
// sits over the calmer middle.
|
|||
|
|
//
|
|||
|
|
// SEAMLESS TILING
|
|||
|
|
// The SVG is a WxH tile whose path is one full zigzag wave: it starts at the
|
|||
|
|
// left edge, dips to the vertex, rises to the right edge at the SAME y it
|
|||
|
|
// started — so horizontally each tile's end meets the next tile's start with no
|
|||
|
|
// step. Two stacked strokes (offset by H) fill the vertical repeat, and the
|
|||
|
|
// tile height equals the row pitch, so vertical stacking is seamless too. The
|
|||
|
|
// gradient overlays are non-repeating (100% 100%) or share the SVG's tile
|
|||
|
|
// width, so none of them introduce a seam.
|
|||
|
|
//
|
|||
|
|
// Everything sits at low alpha (~0.03–0.11) so the pattern is felt, not read:
|
|||
|
|
// crisp message text stays comfortably WCAG-AA in both themes.
|
|||
|
|
|
|||
|
|
// One zigzag wave, 40px wide × 20px tall. Path enters at (0,4), dips to the
|
|||
|
|
// vertex at (20,16), climbs back to (40,4) — identical entry/exit y => seamless
|
|||
|
|
// horizontal repeat. A second copy shifted +10 in y keeps a soft double thread.
|
|||
|
|
const svg = (stroke: string, faint: string) =>
|
|||
|
|
'url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20' +
|
|||
|
|
'width%3D%2240%22%20height%3D%2220%22%3E' +
|
|||
|
|
`%3Cpath%20d%3D%22M0%204%20L20%2016%20L40%204%22%20fill%3D%22none%22%20stroke%3D%22${stroke}%22%20stroke-width%3D%223%22%2F%3E` +
|
|||
|
|
`%3Cpath%20d%3D%22M0%2014%20L20%2026%20L40%2014%20M0%20-6%20L20%206%20L40%20-6%22%20fill%3D%22none%22%20stroke%3D%22${faint}%22%20stroke-width%3D%222%22%2F%3E` +
|
|||
|
|
'%3C%2Fsvg%3E")';
|
|||
|
|
|
|||
|
|
const dark: CSSProperties = {
|
|||
|
|
backgroundColor: 'oklch(0.20 0.022 260)',
|
|||
|
|
backgroundImage: [
|
|||
|
|
// 1. The zigzag threads — muted indigo/slate, main + fainter under-thread.
|
|||
|
|
svg('oklch(0.55 0.05 265 %2F 0.16)', 'oklch(0.50 0.045 262 %2F 0.07)'),
|
|||
|
|
// 2. Woven emboss — a soft diagonal light→shade sweep across the weave so
|
|||
|
|
// the bands catch light on one face and fall to shade on the other.
|
|||
|
|
'linear-gradient(135deg, oklch(0.62 0.05 265 / 0.05) 0%, transparent 45%, transparent 55%, oklch(0.14 0.02 260 / 0.06) 100%)',
|
|||
|
|
// 3. Two-tone weft — a whisper shade on alternate chevron rows.
|
|||
|
|
'repeating-linear-gradient(0deg, oklch(0.50 0.04 258 / 0.035) 0px, oklch(0.50 0.04 258 / 0.035) 20px, transparent 20px, transparent 40px)',
|
|||
|
|
// 4. Tonal wash — cool centre lift for gentle depth.
|
|||
|
|
'radial-gradient(ellipse 90% 75% at 50% 42%, oklch(0.26 0.03 262 / 0.40) 0%, transparent 60%)',
|
|||
|
|
// 5. Vignette — feather corners into deeper charcoal-blue.
|
|||
|
|
'radial-gradient(ellipse 120% 130% at 50% 45%, transparent 60%, oklch(0.15 0.02 260 / 0.55) 100%)',
|
|||
|
|
].join(','),
|
|||
|
|
backgroundSize: '40px 20px, 100% 100%, 40px 40px, 100% 100%, 100% 100%',
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const light: CSSProperties = {
|
|||
|
|
backgroundColor: 'oklch(0.965 0.006 85)',
|
|||
|
|
backgroundImage: [
|
|||
|
|
// 1. The zigzag threads — soft dusty-blue, main + fainter under-thread.
|
|||
|
|
svg('oklch(0.55 0.05 255 %2F 0.14)', 'oklch(0.52 0.045 255 %2F 0.06)'),
|
|||
|
|
// 2. Woven emboss — diagonal light→shade sweep for a knit-fabric surface.
|
|||
|
|
'linear-gradient(135deg, oklch(0.99 0.008 85 / 0.06) 0%, transparent 45%, transparent 55%, oklch(0.55 0.05 255 / 0.05) 100%)',
|
|||
|
|
// 3. Two-tone weft — faint alternating-row shade.
|
|||
|
|
'repeating-linear-gradient(0deg, oklch(0.52 0.04 255 / 0.03) 0px, oklch(0.52 0.04 255 / 0.03) 20px, transparent 20px, transparent 40px)',
|
|||
|
|
// 4. Tonal wash — warm paper highlight through the reading centre.
|
|||
|
|
'radial-gradient(ellipse 90% 75% at 50% 42%, oklch(0.99 0.008 85 / 0.55) 0%, transparent 60%)',
|
|||
|
|
// 5. Vignette — settle corners into a slightly deeper dusty tone.
|
|||
|
|
'radial-gradient(ellipse 120% 130% at 50% 45%, transparent 60%, oklch(0.91 0.012 250 / 0.40) 100%)',
|
|||
|
|
].join(','),
|
|||
|
|
backgroundSize: '40px 20px, 100% 100%, 40px 40px, 100% 100%, 100% 100%',
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
export const chevron: ChatBgVariants = { dark, light };
|