Files
cinny/src/app/features/lotus/backgrounds/triangles.ts
T

104 lines
6.0 KiB
TypeScript
Raw Normal View History

import { CSSProperties } from 'react';
import { ChatBgVariants } from './types';
// triangles — elegant low-poly / faceted-crystal mesh.
//
// The motif stays true to its name — a triangular tessellation — but is rebuilt
// to read as a *faceted crystalline surface* rather than the old flat isometric
// lines. Neighbouring triangular facets carry barely-there tonal shifts (one
// face catches a whisper of light, the adjacent one falls into a whisper of
// shade) so the plane looks gently faceted and dimensional, like brushed slate
// or cut glass seen at a shallow angle. A hairline "mesh glint" traces the facet
// edges so the crystalline structure is felt, never read. A soft tonal wash and
// a feathered vignette give the whole field quiet architectural depth.
//
// FACET SHADING
// An isometric triangle grid is three families of parallel lines at 0deg, 60deg
// and 120deg. Each `linear-gradient` below is a *hard-edged* two-band ramp along
// one of those axes: a faint tonal band followed by transparent, repeating
// across the tile. Overlapping the three axes partitions the plane into small
// triangular cells; because each axis contributes its shade to a different set
// of cells, up-pointing and down-pointing facets end up carrying subtly
// different summed tones — the alternating light/shadow facet look. A separate
// hairline layer per axis draws the thin edge glint at the facet borders.
//
// SEAMLESS TILING
// Equilateral geometry needs the tile height to be the width times sqrt(3). We
// use a 48x83px tile (48 * 1.732 = 83.1, rounded to 83) so the 60deg/120deg
// ramps close exactly on the tile box, and the horizontal edge family repeats on
// half-height (48x41.5 -> the 0deg hairline is sized to the full tile so its
// bands land on tile edges). Every facet-shade and edge layer shares this tile
// (or an exact multiple), and the 60/120 layers meet at the tile's mid columns,
// so triangles interlock across every seam with no drift. Wash and vignette are
// single non-repeating gradients at 100% 100%, so they never seam.
const dark: CSSProperties = {
// Deep navy base — the crystal sits on cool night stone.
backgroundColor: 'oklch(0.19 0.028 258)',
backgroundImage: [
// --- Facet shading: three cool-slate tonal ramps, one per triangle axis.
// Ascending-diagonal facets — a soft light band on one face family.
'linear-gradient(60deg,' +
' oklch(0.46 0.03 250 / 0.07) 0%, oklch(0.46 0.03 250 / 0.07) 50%,' +
' transparent 50%, transparent 100%)',
// Descending-diagonal facets — the shade family, closing the triangles.
'linear-gradient(120deg,' +
' oklch(0.34 0.03 255 / 0.06) 0%, oklch(0.34 0.03 255 / 0.06) 50%,' +
' transparent 50%, transparent 100%)',
// Horizontal facets — a third, fainter slate band so cells read three-sided.
'linear-gradient(0deg,' +
' oklch(0.42 0.028 248 / 0.045) 0%, oklch(0.42 0.028 248 / 0.045) 50%,' +
' transparent 50%, transparent 100%)',
// --- Mesh glint: hairline edges tracing the crystalline facet borders.
'linear-gradient(60deg, transparent 0, transparent calc(50% - 0.5px),' +
' oklch(0.62 0.035 250 / 0.10) calc(50% - 0.5px), oklch(0.62 0.035 250 / 0.10) 50%,' +
' transparent 50%)',
'linear-gradient(120deg, transparent 0, transparent calc(50% - 0.5px),' +
' oklch(0.62 0.035 250 / 0.10) calc(50% - 0.5px), oklch(0.62 0.035 250 / 0.10) 50%,' +
' transparent 50%)',
// --- Tonal wash — a gentle cool lift through the reading centre for depth.
'radial-gradient(ellipse 95% 80% at 50% 40%, oklch(0.28 0.03 255 / 0.45) 0%, transparent 62%)',
// --- Vignette — feather the corners into deeper navy.
'radial-gradient(ellipse 125% 130% at 50% 45%, transparent 58%, oklch(0.13 0.022 258 / 0.55) 100%)',
].join(','),
backgroundSize: '48px 83px, 48px 83px, 48px 83px, 48px 83px, 48px 83px, 100% 100%, 100% 100%',
// Offset the 120deg (shade) and its glint by half a tile so up/down facets
// interlock — this is what alternates the light/shadow triangles.
backgroundPosition: '0 0, 24px 0, 0 0, 0 0, 24px 0, 0 0, 0 0',
};
const light: CSSProperties = {
// Pale ice-white base — cut glass on frosted paper.
backgroundColor: 'oklch(0.975 0.004 250)',
backgroundImage: [
// --- Facet shading: soft cool-grey tonal ramps, one per triangle axis.
// Ascending-diagonal facets — a barely-there shade on one face family.
'linear-gradient(60deg,' +
' oklch(0.66 0.022 252 / 0.09) 0%, oklch(0.66 0.022 252 / 0.09) 50%,' +
' transparent 50%, transparent 100%)',
// Descending-diagonal facets — a hair darker, closing the triangles.
'linear-gradient(120deg,' +
' oklch(0.58 0.024 255 / 0.08) 0%, oklch(0.58 0.024 255 / 0.08) 50%,' +
' transparent 50%, transparent 100%)',
// Horizontal facets — the third, faintest cool-grey band.
'linear-gradient(0deg,' +
' oklch(0.62 0.02 250 / 0.055) 0%, oklch(0.62 0.02 250 / 0.055) 50%,' +
' transparent 50%, transparent 100%)',
// --- Mesh glint: crisp hairline facet edges in cool slate.
'linear-gradient(60deg, transparent 0, transparent calc(50% - 0.5px),' +
' oklch(0.50 0.03 255 / 0.11) calc(50% - 0.5px), oklch(0.50 0.03 255 / 0.11) 50%,' +
' transparent 50%)',
'linear-gradient(120deg, transparent 0, transparent calc(50% - 0.5px),' +
' oklch(0.50 0.03 255 / 0.11) calc(50% - 0.5px), oklch(0.50 0.03 255 / 0.11) 50%,' +
' transparent 50%)',
// --- Tonal wash — a clean white highlight through the reading centre.
'radial-gradient(ellipse 95% 80% at 50% 40%, oklch(0.995 0.003 250 / 0.60) 0%, transparent 62%)',
// --- Vignette — settle the corners into a faint cool grey.
'radial-gradient(ellipse 125% 130% at 50% 45%, transparent 58%, oklch(0.90 0.012 252 / 0.42) 100%)',
].join(','),
backgroundSize: '48px 83px, 48px 83px, 48px 83px, 48px 83px, 48px 83px, 100% 100%, 100% 100%',
backgroundPosition: '0 0, 24px 0, 0 0, 0 0, 24px 0, 0 0, 0 0',
};
export const triangles: ChatBgVariants = { dark, light };