refactor: establish local frontend workspace boundaries
Conventional commits / commits (pull_request) Successful in 24s
Frontend security / security (pull_request) Successful in 9s
Frontend verify / verify (pull_request) Successful in 5m18s
Frontend security / security (push) Successful in 10s
Frontend verify / verify (push) Successful in 6m45s

OpenSpec change: evolve-frontend-stack
This commit was merged in pull request #34.
This commit is contained in:
2026-09-22 22:11:02 +03:00
parent c86be7bf73
commit 85fcfe3d07
101 changed files with 1487 additions and 666 deletions
+86
View File
@@ -0,0 +1,86 @@
import "./styles.css";
import {
type CSSVariablesResolver,
colorsTuple,
createTheme,
getThemeColor,
type MantinePrimaryShade,
Modal,
rem,
rgba,
} from "@mantine/core";
import designTokens from "@wealthledger/tokens/tokens.json";
const { color, typography, spacing, radius, shadows, breakpoints } =
designTokens;
const mapValues = <T, U>(values: Record<string, T>, convert: (value: T) => U) =>
Object.fromEntries(
Object.entries(values).map(([name, value]) => [name, convert(value)]),
);
const colorRoles = mapValues(color.roles, (role) =>
role.shade === null ? role.color : `${role.color}.${role.shade}`,
);
const theme = createTheme({
respectReducedMotion: true,
components: {
Modal: Modal.extend({
defaultProps: {
overlayProps: { blur: 3 },
transitionProps: {
transition: "fade-down",
duration: 220,
exitDuration: 180,
timingFunction: "ease-out",
},
},
}),
},
primaryColor: color.roles.primary.color,
primaryShade: color.primaryShade as MantinePrimaryShade,
defaultRadius: radius.default,
white: color.base.white,
black: color.base.black,
colors: mapValues(color.palettes, colorsTuple),
fontFamily: typography.fontFamily,
fontFamilyMonospace: typography.fontFamilyMonospace,
fontSizes: mapValues(typography.fontSizes, (value) => rem(value)),
fontWeights: mapValues(typography.fontWeights, String),
lineHeights: mapValues(typography.lineHeights, String),
headings: {
fontFamily: typography.fontFamily,
fontWeight: String(typography.fontWeights.bold),
sizes: mapValues(typography.headings, (value) => ({
fontSize: rem(value.fontSize),
lineHeight: String(value.lineHeight),
})),
},
spacing: mapValues(spacing.values, (value) => rem(value)),
radius: mapValues(radius.values, (value) => rem(value)),
shadows: mapValues(shadows.values, (layers) =>
layers
.map(
(layer) =>
`${rem(layer.offsetX)} ${rem(layer.offsetY)} ${rem(layer.blur)} ${rem(layer.spread)} ${rgba(color.base[layer.color as keyof typeof color.base], layer.opacity)}`,
)
.join(", "),
),
breakpoints: mapValues(
breakpoints.values,
(value) => `${value}${breakpoints.unit}`,
),
});
const cssVariablesResolver: CSSVariablesResolver = (resolvedTheme) => ({
variables: Object.fromEntries(
Object.entries(colorRoles).map(([role, reference]) => [
`--wl-color-${role}`,
getThemeColor(reference, resolvedTheme),
]),
),
light: {},
dark: {},
});
export { colorRoles, cssVariablesResolver, designTokens, theme };