Initial commit
This commit is contained in:
138
src/providers/themeProvider/ThemeProvider.tsx
Normal file
138
src/providers/themeProvider/ThemeProvider.tsx
Normal file
@@ -0,0 +1,138 @@
|
||||
"use client";
|
||||
|
||||
import { createContext, useContext, useMemo } from "react";
|
||||
import type { ThemeConfig, ThemeProviderProps } from "./config/types";
|
||||
import { borderRadiusMap, borderRadiusCappedMap, contentWidthMap, expandedContentWidthMap, baseVwMap, textSizingMap, backgroundComponents, headingFontWeightMap } from "./config/constants";
|
||||
import { cardStyleMap, getGradientBorderedPseudo } from "./styles/cardStyles";
|
||||
import { primaryButtonStyleMap, getInsetGlowPseudo } from "./styles/primaryButtonStyles";
|
||||
import { secondaryButtonStyleMap } from "./styles/secondaryButtonStyles";
|
||||
|
||||
const ThemeContext = createContext<ThemeConfig | undefined>(undefined);
|
||||
|
||||
export const useTheme = () => {
|
||||
const context = useContext(ThemeContext);
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
"useTheme must be used within a ThemeProvider. Wrap your sections in <ThemeProvider> at the app/page level."
|
||||
);
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
export const ThemeProvider = ({
|
||||
children,
|
||||
defaultButtonVariant,
|
||||
defaultTextAnimation,
|
||||
borderRadius,
|
||||
contentWidth,
|
||||
sizing,
|
||||
background,
|
||||
cardStyle,
|
||||
primaryButtonStyle,
|
||||
secondaryButtonStyle,
|
||||
headingFontWeight,
|
||||
}: ThemeProviderProps) => {
|
||||
const themeConfig = useMemo<ThemeConfig>(() => ({
|
||||
defaultButtonVariant,
|
||||
defaultTextAnimation,
|
||||
borderRadius,
|
||||
contentWidth,
|
||||
sizing,
|
||||
background,
|
||||
cardStyle,
|
||||
primaryButtonStyle,
|
||||
secondaryButtonStyle,
|
||||
headingFontWeight,
|
||||
}), [
|
||||
defaultButtonVariant, defaultTextAnimation, borderRadius,
|
||||
contentWidth, sizing, background, cardStyle,
|
||||
primaryButtonStyle, secondaryButtonStyle, headingFontWeight,
|
||||
]);
|
||||
|
||||
const BackgroundComponent = backgroundComponents[background];
|
||||
|
||||
const styleString = useMemo(() => {
|
||||
const borderRadiusValue = borderRadiusMap[borderRadius];
|
||||
const borderRadiusCappedValue = borderRadiusCappedMap[borderRadius];
|
||||
const contentWidthValues = contentWidthMap[contentWidth];
|
||||
const expandedContentWidthValues = expandedContentWidthMap[contentWidth];
|
||||
const baseVwValues = baseVwMap[sizing];
|
||||
const textSizingValues = textSizingMap[sizing];
|
||||
const headingFontWeightValue = headingFontWeightMap[headingFontWeight];
|
||||
|
||||
const cardCss = cardStyleMap[cardStyle];
|
||||
const primaryButtonCss = primaryButtonStyleMap[primaryButtonStyle];
|
||||
const secondaryButtonCss = secondaryButtonStyleMap[secondaryButtonStyle];
|
||||
|
||||
const gradientBorderedPseudo = getGradientBorderedPseudo(cardStyle);
|
||||
const insetGlowPseudo = getInsetGlowPseudo(primaryButtonStyle);
|
||||
|
||||
return `
|
||||
:root {
|
||||
--theme-border-radius: ${borderRadiusValue};
|
||||
--theme-border-radius-capped: ${borderRadiusCappedValue};
|
||||
--width-content-width: ${contentWidthValues.desktop};
|
||||
--width-content-width-expanded: ${expandedContentWidthValues.desktop};
|
||||
--vw: ${baseVwValues.desktop};
|
||||
--heading-font-weight: ${headingFontWeightValue};
|
||||
--text-2xs: ${textSizingValues.desktop.text2xs};
|
||||
--text-xs: ${textSizingValues.desktop.textXs};
|
||||
--text-sm: ${textSizingValues.desktop.textSm};
|
||||
--text-base: ${textSizingValues.desktop.textBase};
|
||||
--text-lg: ${textSizingValues.desktop.textLg};
|
||||
--text-xl: ${textSizingValues.desktop.textXl};
|
||||
--text-2xl: ${textSizingValues.desktop.text2xl};
|
||||
--text-3xl: ${textSizingValues.desktop.text3xl};
|
||||
--text-4xl: ${textSizingValues.desktop.text4xl};
|
||||
--text-5xl: ${textSizingValues.desktop.text5xl};
|
||||
--text-6xl: ${textSizingValues.desktop.text6xl};
|
||||
--text-7xl: ${textSizingValues.desktop.text7xl};
|
||||
--text-8xl: ${textSizingValues.desktop.text8xl};
|
||||
--text-9xl: ${textSizingValues.desktop.text9xl};
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
:root {
|
||||
--width-content-width: ${contentWidthValues.mobile};
|
||||
--width-content-width-expanded: ${expandedContentWidthValues.mobile};
|
||||
--vw: ${baseVwValues.mobile};
|
||||
--text-2xs: ${textSizingValues.mobile.text2xs};
|
||||
--text-xs: ${textSizingValues.mobile.textXs};
|
||||
--text-sm: ${textSizingValues.mobile.textSm};
|
||||
--text-base: ${textSizingValues.mobile.textBase};
|
||||
--text-lg: ${textSizingValues.mobile.textLg};
|
||||
--text-xl: ${textSizingValues.mobile.textXl};
|
||||
--text-2xl: ${textSizingValues.mobile.text2xl};
|
||||
--text-3xl: ${textSizingValues.mobile.text3xl};
|
||||
--text-4xl: ${textSizingValues.mobile.text4xl};
|
||||
--text-5xl: ${textSizingValues.mobile.text5xl};
|
||||
--text-6xl: ${textSizingValues.mobile.text6xl};
|
||||
--text-7xl: ${textSizingValues.mobile.text7xl};
|
||||
--text-8xl: ${textSizingValues.mobile.text8xl};
|
||||
--text-9xl: ${textSizingValues.mobile.text9xl};
|
||||
}
|
||||
}
|
||||
.card {
|
||||
${cardCss}
|
||||
}
|
||||
${gradientBorderedPseudo}
|
||||
.primary-button {
|
||||
${primaryButtonCss}
|
||||
}
|
||||
${insetGlowPseudo}
|
||||
.secondary-button {
|
||||
${secondaryButtonCss}
|
||||
}
|
||||
`;
|
||||
}, [
|
||||
borderRadius, contentWidth, sizing, headingFontWeight,
|
||||
cardStyle, primaryButtonStyle, secondaryButtonStyle,
|
||||
]);
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={themeConfig}>
|
||||
<style>{styleString}</style>
|
||||
{BackgroundComponent && <BackgroundComponent />}
|
||||
{children}
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
};
|
||||
25
src/providers/themeProvider/config/background.ts
Normal file
25
src/providers/themeProvider/config/background.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import CircleGradientBackground from "@/components/background/CircleGradientBackground";
|
||||
import AuroraBackground from "@/components/background/AuroraBackground";
|
||||
import FloatingGradientBackground from "@/components/background/floatingGradientBackground/FloatingGradientBackground";
|
||||
import NoiseBackground from "@/components/background/NoiseBackground";
|
||||
import NoiseDiagonalGradientBackground from "@/components/background/NoiseDiagonalGradientBackground";
|
||||
import FluidBackground from "@/components/background/FluidBackground";
|
||||
import BlurBottomBackground from "@/components/background/BlurBottomBackground";
|
||||
import GridBackround from "@/components/background/GridBackround";
|
||||
import type { BackgroundType } from "./types";
|
||||
|
||||
interface BackgroundComponentProps {
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export const backgroundComponents: Record<BackgroundType, React.ComponentType<BackgroundComponentProps> | null> = {
|
||||
none: null,
|
||||
circleGradient: CircleGradientBackground,
|
||||
aurora: AuroraBackground,
|
||||
floatingGradient: FloatingGradientBackground,
|
||||
noise: NoiseBackground,
|
||||
noiseDiagonalGradient: NoiseDiagonalGradientBackground,
|
||||
fluid: FluidBackground,
|
||||
blurBottom: BlurBottomBackground,
|
||||
grid: GridBackround,
|
||||
};
|
||||
44
src/providers/themeProvider/config/baseVw.ts
Normal file
44
src/providers/themeProvider/config/baseVw.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import type { SizingPreset } from "./types";
|
||||
|
||||
export const baseVwMap: Record<SizingPreset, { desktop: string; mobile: string }> = {
|
||||
medium: {
|
||||
desktop: "clamp(0.5rem, 0.8vw, 1rem)",
|
||||
mobile: "3vw",
|
||||
},
|
||||
mediumLarge: {
|
||||
desktop: "clamp(0.5rem, 0.84vw, 1rem)",
|
||||
mobile: "3.15vw",
|
||||
},
|
||||
largeSmall: {
|
||||
desktop: "clamp(0.5rem, 0.88vw, 1rem)",
|
||||
mobile: "3.30vw",
|
||||
},
|
||||
large: {
|
||||
desktop: "clamp(0.5rem, 0.92vw, 1rem)",
|
||||
mobile: "3.45vw",
|
||||
},
|
||||
mediumSizeLargeTitles: {
|
||||
desktop: "clamp(0.5rem, 0.8vw, 1rem)",
|
||||
mobile: "3vw",
|
||||
},
|
||||
largeSizeMediumTitles: {
|
||||
desktop: "clamp(0.5rem, 0.92vw, 1rem)",
|
||||
mobile: "3.45vw",
|
||||
},
|
||||
mediumLargeSizeLargeTitles: {
|
||||
desktop: "clamp(0.5rem, 0.84vw, 1rem)",
|
||||
mobile: "3.15vw",
|
||||
},
|
||||
largeSmallSizeLargeTitles: {
|
||||
desktop: "clamp(0.5rem, 0.88vw, 1rem)",
|
||||
mobile: "3.30vw",
|
||||
},
|
||||
mediumLargeSizeMediumTitles: {
|
||||
desktop: "clamp(0.5rem, 0.84vw, 1rem)",
|
||||
mobile: "3.15vw",
|
||||
},
|
||||
largeSmallSizeMediumTitles: {
|
||||
desktop: "clamp(0.5rem, 0.88vw, 1rem)",
|
||||
mobile: "3.30vw",
|
||||
},
|
||||
};
|
||||
13
src/providers/themeProvider/config/borderRadius.ts
Normal file
13
src/providers/themeProvider/config/borderRadius.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import type { BorderRadiusPreset } from "./types";
|
||||
|
||||
export const borderRadiusMap: Record<BorderRadiusPreset, string> = {
|
||||
rounded: "var(--radius)",
|
||||
soft: "var(--radius-lg)",
|
||||
pill: "var(--radius-full)",
|
||||
};
|
||||
|
||||
export const borderRadiusCappedMap: Record<BorderRadiusPreset, string> = {
|
||||
rounded: "var(--radius)",
|
||||
soft: "var(--radius-lg)",
|
||||
pill: "var(--radius-xl)",
|
||||
};
|
||||
7
src/providers/themeProvider/config/constants.ts
Normal file
7
src/providers/themeProvider/config/constants.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
// Re-export all config modules for backward compatibility
|
||||
export { borderRadiusMap, borderRadiusCappedMap } from "./borderRadius";
|
||||
export { contentWidthMap, expandedContentWidthMap } from "./contentWidth";
|
||||
export { textSizingMap, type TextSizingValues } from "./textSizing";
|
||||
export { baseVwMap } from "./baseVw";
|
||||
export { backgroundComponents } from "./background";
|
||||
export { headingFontWeightMap, type TextboxLayout, type InvertedBackground } from "./shared";
|
||||
82
src/providers/themeProvider/config/contentWidth.ts
Normal file
82
src/providers/themeProvider/config/contentWidth.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import type { ContentWidthPreset } from "./types";
|
||||
|
||||
export const contentWidthMap: Record<ContentWidthPreset, { desktop: string; mobile: string }> = {
|
||||
small: {
|
||||
desktop: "clamp(40rem, 70vw, 100rem)",
|
||||
mobile: "80vw",
|
||||
},
|
||||
smallMedium: {
|
||||
desktop: "clamp(40rem, 72.5vw, 100rem)",
|
||||
mobile: "80vw",
|
||||
},
|
||||
compact: {
|
||||
desktop: "clamp(40rem, 75vw, 100rem)",
|
||||
mobile: "80vw",
|
||||
},
|
||||
mediumSmall: {
|
||||
desktop: "clamp(40rem, 77.5vw, 100rem)",
|
||||
mobile: "80vw",
|
||||
},
|
||||
medium: {
|
||||
desktop: "clamp(40rem, 80vw, 100rem)",
|
||||
mobile: "80vw",
|
||||
},
|
||||
mediumLarge: {
|
||||
desktop: "clamp(40rem, 82.5vw, 100rem)",
|
||||
mobile: "85vw",
|
||||
},
|
||||
};
|
||||
|
||||
function calculateExpandedWidth(width: string): string {
|
||||
const clampMatch = width.match(/clamp\(([\d.]+)rem,\s*([\d.]+)vw,\s*([\d.]+)rem\)/);
|
||||
if (clampMatch) {
|
||||
const minRem = clampMatch[1];
|
||||
const vwValue = parseFloat(clampMatch[2]);
|
||||
const maxRem = clampMatch[3];
|
||||
|
||||
const remainingVw = 100 - vwValue;
|
||||
const expandedVw = vwValue + (remainingVw / 2);
|
||||
|
||||
const expandedMin = `calc(${minRem}rem - (${minRem}rem - 100vw) / 2)`;
|
||||
const expandedMax = `calc(${maxRem}rem + (100vw - ${maxRem}rem) / 2)`;
|
||||
|
||||
return `clamp(${expandedMin}, ${expandedVw}vw, ${expandedMax})`;
|
||||
}
|
||||
|
||||
const vwMatch = width.match(/([\d.]+)vw/);
|
||||
if (vwMatch) {
|
||||
const vwValue = parseFloat(vwMatch[1]);
|
||||
const remainingVw = 100 - vwValue;
|
||||
const expandedVw = vwValue + (remainingVw / 2);
|
||||
return `${expandedVw}vw`;
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
export const expandedContentWidthMap: Record<ContentWidthPreset, { desktop: string; mobile: string }> = {
|
||||
small: {
|
||||
desktop: calculateExpandedWidth(contentWidthMap.small.desktop),
|
||||
mobile: calculateExpandedWidth(contentWidthMap.small.mobile),
|
||||
},
|
||||
smallMedium: {
|
||||
desktop: calculateExpandedWidth(contentWidthMap.smallMedium.desktop),
|
||||
mobile: calculateExpandedWidth(contentWidthMap.smallMedium.mobile),
|
||||
},
|
||||
compact: {
|
||||
desktop: calculateExpandedWidth(contentWidthMap.compact.desktop),
|
||||
mobile: calculateExpandedWidth(contentWidthMap.compact.mobile),
|
||||
},
|
||||
mediumSmall: {
|
||||
desktop: calculateExpandedWidth(contentWidthMap.mediumSmall.desktop),
|
||||
mobile: calculateExpandedWidth(contentWidthMap.mediumSmall.mobile),
|
||||
},
|
||||
medium: {
|
||||
desktop: calculateExpandedWidth(contentWidthMap.medium.desktop),
|
||||
mobile: calculateExpandedWidth(contentWidthMap.medium.mobile),
|
||||
},
|
||||
mediumLarge: {
|
||||
desktop: calculateExpandedWidth(contentWidthMap.mediumLarge.desktop),
|
||||
mobile: calculateExpandedWidth(contentWidthMap.mediumLarge.mobile),
|
||||
},
|
||||
};
|
||||
16
src/providers/themeProvider/config/shared.ts
Normal file
16
src/providers/themeProvider/config/shared.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import type { HeadingFontWeight } from "./types";
|
||||
|
||||
/**
|
||||
* Shared component layout and styling type definitions
|
||||
*/
|
||||
export type TextboxLayout = "default" | "split" | "split-actions" | "split-description" | "inline-image";
|
||||
export type InvertedBackground = boolean;
|
||||
|
||||
export const headingFontWeightMap: Record<HeadingFontWeight, string> = {
|
||||
light: "300",
|
||||
normal: "400",
|
||||
medium: "500",
|
||||
semibold: "600",
|
||||
bold: "700",
|
||||
extrabold: "800",
|
||||
};
|
||||
385
src/providers/themeProvider/config/textSizing.ts
Normal file
385
src/providers/themeProvider/config/textSizing.ts
Normal file
@@ -0,0 +1,385 @@
|
||||
import type { SizingPreset } from "./types";
|
||||
|
||||
export interface TextSizingValues {
|
||||
text2xs: string;
|
||||
textXs: string;
|
||||
textSm: string;
|
||||
textBase: string;
|
||||
textLg: string;
|
||||
textXl: string;
|
||||
text2xl: string;
|
||||
text3xl: string;
|
||||
text4xl: string;
|
||||
text5xl: string;
|
||||
text6xl: string;
|
||||
text7xl: string;
|
||||
text8xl: string;
|
||||
text9xl: string;
|
||||
}
|
||||
|
||||
export const textSizingMap: Record<SizingPreset, { desktop: TextSizingValues; mobile: TextSizingValues }> = {
|
||||
medium: {
|
||||
desktop: {
|
||||
text2xs: "clamp(0.465rem, 0.62vw, 0.62rem)",
|
||||
textXs: "clamp(0.54rem, 0.72vw, 0.72rem)",
|
||||
textSm: "clamp(0.615rem, 0.82vw, 0.82rem)",
|
||||
textBase: "clamp(0.69rem, 0.92vw, 0.92rem)",
|
||||
textLg: "clamp(0.75rem, 1vw, 1rem)",
|
||||
textXl: "clamp(0.825rem, 1.1vw, 1.1rem)",
|
||||
text2xl: "clamp(0.975rem, 1.3vw, 1.3rem)",
|
||||
text3xl: "clamp(1.2rem, 1.6vw, 1.6rem)",
|
||||
text4xl: "clamp(1.5rem, 2vw, 2rem)",
|
||||
text5xl: "clamp(2.025rem, 2.75vw, 2.75rem)",
|
||||
text6xl: "clamp(2.475rem, 3.3vw, 3.3rem)",
|
||||
text7xl: "clamp(3rem, 4vw, 4rem)",
|
||||
text8xl: "clamp(3.5rem, 4.5vw, 4.5rem)",
|
||||
text9xl: "clamp(5.25rem, 7vw, 7rem)",
|
||||
},
|
||||
mobile: {
|
||||
text2xs: "2.5vw",
|
||||
textXs: "2.75vw",
|
||||
textSm: "3vw",
|
||||
textBase: "3.25vw",
|
||||
textLg: "3.5vw",
|
||||
textXl: "4.25vw",
|
||||
text2xl: "5vw",
|
||||
text3xl: "6vw",
|
||||
text4xl: "7vw",
|
||||
text5xl: "7.5vw",
|
||||
text6xl: "8.5vw",
|
||||
text7xl: "10vw",
|
||||
text8xl: "12vw",
|
||||
text9xl: "14vw",
|
||||
},
|
||||
},
|
||||
mediumLarge: {
|
||||
desktop: {
|
||||
text2xs: "clamp(0.465rem, 0.651vw, 0.62rem)",
|
||||
textXs: "clamp(0.54rem, 0.756vw, 0.72rem)",
|
||||
textSm: "clamp(0.615rem, 0.861vw, 0.82rem)",
|
||||
textBase: "clamp(0.69rem, 0.966vw, 0.92rem)",
|
||||
textLg: "clamp(0.75rem, 1.05vw, 1rem)",
|
||||
textXl: "clamp(0.825rem, 1.155vw, 1.1rem)",
|
||||
text2xl: "clamp(0.975rem, 1.365vw, 1.3rem)",
|
||||
text3xl: "clamp(1.2rem, 1.68vw, 1.6rem)",
|
||||
text4xl: "clamp(1.5rem, 2.1vw, 2rem)",
|
||||
text5xl: "clamp(2.025rem, 2.8875vw, 2.75rem)",
|
||||
text6xl: "clamp(2.475rem, 3.465vw, 3.3rem)",
|
||||
text7xl: "clamp(3rem, 4.2vw, 4rem)",
|
||||
text8xl: "clamp(3.5rem, 4.725vw, 4.5rem)",
|
||||
text9xl: "clamp(5.25rem, 7.35vw, 7rem)",
|
||||
},
|
||||
mobile: {
|
||||
text2xs: "2.625vw",
|
||||
textXs: "2.8875vw",
|
||||
textSm: "3.15vw",
|
||||
textBase: "3.4125vw",
|
||||
textLg: "3.675vw",
|
||||
textXl: "4.4625vw",
|
||||
text2xl: "5.25vw",
|
||||
text3xl: "6.3vw",
|
||||
text4xl: "7.35vw",
|
||||
text5xl: "7.875vw",
|
||||
text6xl: "8.925vw",
|
||||
text7xl: "10.5vw",
|
||||
text8xl: "12.6vw",
|
||||
text9xl: "14.7vw",
|
||||
},
|
||||
},
|
||||
largeSmall: {
|
||||
desktop: {
|
||||
text2xs: "clamp(0.465rem, 0.682vw, 0.62rem)",
|
||||
textXs: "clamp(0.54rem, 0.792vw, 0.72rem)",
|
||||
textSm: "clamp(0.615rem, 0.902vw, 0.82rem)",
|
||||
textBase: "clamp(0.69rem, 1.012vw, 0.92rem)",
|
||||
textLg: "clamp(0.75rem, 1.1vw, 1rem)",
|
||||
textXl: "clamp(0.825rem, 1.21vw, 1.1rem)",
|
||||
text2xl: "clamp(0.975rem, 1.43vw, 1.3rem)",
|
||||
text3xl: "clamp(1.2rem, 1.76vw, 1.6rem)",
|
||||
text4xl: "clamp(1.5rem, 2.2vw, 2rem)",
|
||||
text5xl: "clamp(2.025rem, 3.025vw, 2.75rem)",
|
||||
text6xl: "clamp(2.475rem, 3.63vw, 3.3rem)",
|
||||
text7xl: "clamp(3rem, 4.4vw, 4rem)",
|
||||
text8xl: "clamp(3.5rem, 4.95vw, 4.5rem)",
|
||||
text9xl: "clamp(5.25rem, 7.7vw, 7rem)",
|
||||
},
|
||||
mobile: {
|
||||
text2xs: "2.75vw",
|
||||
textXs: "3.025vw",
|
||||
textSm: "3.3vw",
|
||||
textBase: "3.575vw",
|
||||
textLg: "3.85vw",
|
||||
textXl: "4.675vw",
|
||||
text2xl: "5.5vw",
|
||||
text3xl: "6.6vw",
|
||||
text4xl: "7.7vw",
|
||||
text5xl: "8.25vw",
|
||||
text6xl: "9.35vw",
|
||||
text7xl: "11vw",
|
||||
text8xl: "13.2vw",
|
||||
text9xl: "15.4vw",
|
||||
},
|
||||
},
|
||||
large: {
|
||||
desktop: {
|
||||
text2xs: "clamp(0.465rem, 0.713vw, 0.62rem)",
|
||||
textXs: "clamp(0.54rem, 0.828vw, 0.72rem)",
|
||||
textSm: "clamp(0.615rem, 0.943vw, 0.82rem)",
|
||||
textBase: "clamp(0.69rem, 1.058vw, 0.92rem)",
|
||||
textLg: "clamp(0.75rem, 1.15vw, 1rem)",
|
||||
textXl: "clamp(0.825rem, 1.265vw, 1.1rem)",
|
||||
text2xl: "clamp(0.975rem, 1.495vw, 1.3rem)",
|
||||
text3xl: "clamp(1.2rem, 1.84vw, 1.6rem)",
|
||||
text4xl: "clamp(1.5rem, 2.3vw, 2rem)",
|
||||
text5xl: "clamp(2.025rem, 3.1625vw, 2.75rem)",
|
||||
text6xl: "clamp(2.475rem, 3.795vw, 3.3rem)",
|
||||
text7xl: "clamp(3rem, 4.6vw, 4rem)",
|
||||
text8xl: "clamp(3.5rem, 5.175vw, 4.5rem)",
|
||||
text9xl: "clamp(5.25rem, 8.05vw, 7rem)",
|
||||
},
|
||||
mobile: {
|
||||
text2xs: "2.875vw",
|
||||
textXs: "3.1625vw",
|
||||
textSm: "3.45vw",
|
||||
textBase: "3.7375vw",
|
||||
textLg: "4.025vw",
|
||||
textXl: "4.8875vw",
|
||||
text2xl: "5.75vw",
|
||||
text3xl: "6.9vw",
|
||||
text4xl: "8.05vw",
|
||||
text5xl: "8.625vw",
|
||||
text6xl: "9.775vw",
|
||||
text7xl: "11.5vw",
|
||||
text8xl: "13.8vw",
|
||||
text9xl: "16.1vw",
|
||||
},
|
||||
},
|
||||
mediumSizeLargeTitles: {
|
||||
desktop: {
|
||||
// Medium body text sizes: use medium values
|
||||
text2xs: "clamp(0.465rem, 0.62vw, 0.62rem)",
|
||||
textXs: "clamp(0.54rem, 0.72vw, 0.72rem)",
|
||||
textSm: "clamp(0.615rem, 0.82vw, 0.82rem)",
|
||||
textBase: "clamp(0.69rem, 0.92vw, 0.92rem)",
|
||||
textLg: "clamp(0.75rem, 1vw, 1rem)",
|
||||
textXl: "clamp(0.825rem, 1.1vw, 1.1rem)",
|
||||
text2xl: "clamp(0.975rem, 1.3vw, 1.3rem)",
|
||||
text3xl: "clamp(1.2rem, 1.6vw, 1.6rem)",
|
||||
text4xl: "clamp(1.5rem, 2vw, 2rem)",
|
||||
// Large title sizes: use large preset values
|
||||
text5xl: "clamp(2.025rem, 3.1625vw, 2.75rem)",
|
||||
text6xl: "clamp(2.475rem, 3.795vw, 3.3rem)",
|
||||
text7xl: "clamp(3rem, 4.6vw, 4rem)",
|
||||
text8xl: "clamp(3.5rem, 5.175vw, 4.5rem)",
|
||||
text9xl: "clamp(5.25rem, 8.05vw, 7rem)",
|
||||
},
|
||||
mobile: {
|
||||
// Medium body text sizes: use medium values
|
||||
text2xs: "2.5vw",
|
||||
textXs: "2.75vw",
|
||||
textSm: "3vw",
|
||||
textBase: "3.25vw",
|
||||
textLg: "3.5vw",
|
||||
textXl: "4.25vw",
|
||||
text2xl: "5vw",
|
||||
text3xl: "6vw",
|
||||
text4xl: "7vw",
|
||||
// Large title sizes: use large preset values
|
||||
text5xl: "8.625vw",
|
||||
text6xl: "9.775vw",
|
||||
text7xl: "11.5vw",
|
||||
text8xl: "13.8vw",
|
||||
text9xl: "16.1vw",
|
||||
},
|
||||
},
|
||||
largeSizeMediumTitles: {
|
||||
desktop: {
|
||||
// Large body text sizes: use large values
|
||||
text2xs: "clamp(0.465rem, 0.713vw, 0.62rem)",
|
||||
textXs: "clamp(0.54rem, 0.828vw, 0.72rem)",
|
||||
textSm: "clamp(0.615rem, 0.943vw, 0.82rem)",
|
||||
textBase: "clamp(0.69rem, 1.058vw, 0.92rem)",
|
||||
textLg: "clamp(0.75rem, 1.15vw, 1rem)",
|
||||
textXl: "clamp(0.825rem, 1.265vw, 1.1rem)",
|
||||
text2xl: "clamp(0.975rem, 1.495vw, 1.3rem)",
|
||||
text3xl: "clamp(1.2rem, 1.84vw, 1.6rem)",
|
||||
text4xl: "clamp(1.5rem, 2.3vw, 2rem)",
|
||||
// Medium title sizes: use medium preset values
|
||||
text5xl: "clamp(2.025rem, 2.75vw, 2.75rem)",
|
||||
text6xl: "clamp(2.475rem, 3.3vw, 3.3rem)",
|
||||
text7xl: "clamp(3rem, 4vw, 4rem)",
|
||||
text8xl: "clamp(3.5rem, 4.5vw, 4.5rem)",
|
||||
text9xl: "clamp(5.25rem, 7vw, 7rem)",
|
||||
},
|
||||
mobile: {
|
||||
// Large body text sizes: use large values
|
||||
text2xs: "2.875vw",
|
||||
textXs: "3.1625vw",
|
||||
textSm: "3.45vw",
|
||||
textBase: "3.7375vw",
|
||||
textLg: "4.025vw",
|
||||
textXl: "4.8875vw",
|
||||
text2xl: "5.75vw",
|
||||
text3xl: "6.9vw",
|
||||
text4xl: "8.05vw",
|
||||
// Medium title sizes: use medium preset values
|
||||
text5xl: "7.5vw",
|
||||
text6xl: "8.5vw",
|
||||
text7xl: "10vw",
|
||||
text8xl: "12vw",
|
||||
text9xl: "14vw",
|
||||
},
|
||||
},
|
||||
mediumLargeSizeLargeTitles: {
|
||||
desktop: {
|
||||
// MediumLarge body text sizes
|
||||
text2xs: "clamp(0.465rem, 0.651vw, 0.62rem)",
|
||||
textXs: "clamp(0.54rem, 0.756vw, 0.72rem)",
|
||||
textSm: "clamp(0.615rem, 0.861vw, 0.82rem)",
|
||||
textBase: "clamp(0.69rem, 0.966vw, 0.92rem)",
|
||||
textLg: "clamp(0.75rem, 1.05vw, 1rem)",
|
||||
textXl: "clamp(0.825rem, 1.155vw, 1.1rem)",
|
||||
text2xl: "clamp(0.975rem, 1.365vw, 1.3rem)",
|
||||
text3xl: "clamp(1.2rem, 1.68vw, 1.6rem)",
|
||||
text4xl: "clamp(1.5rem, 2.1vw, 2rem)",
|
||||
// Large title sizes
|
||||
text5xl: "clamp(2.025rem, 3.1625vw, 2.75rem)",
|
||||
text6xl: "clamp(2.475rem, 3.795vw, 3.3rem)",
|
||||
text7xl: "clamp(3rem, 4.6vw, 4rem)",
|
||||
text8xl: "clamp(3.5rem, 5.175vw, 4.5rem)",
|
||||
text9xl: "clamp(5.25rem, 8.05vw, 7rem)",
|
||||
},
|
||||
mobile: {
|
||||
// MediumLarge body text sizes
|
||||
text2xs: "2.625vw",
|
||||
textXs: "2.8875vw",
|
||||
textSm: "3.15vw",
|
||||
textBase: "3.4125vw",
|
||||
textLg: "3.675vw",
|
||||
textXl: "4.4625vw",
|
||||
text2xl: "5.25vw",
|
||||
text3xl: "6.3vw",
|
||||
text4xl: "7.35vw",
|
||||
// Large title sizes
|
||||
text5xl: "8.625vw",
|
||||
text6xl: "9.775vw",
|
||||
text7xl: "11.5vw",
|
||||
text8xl: "13.8vw",
|
||||
text9xl: "16.1vw",
|
||||
},
|
||||
},
|
||||
largeSmallSizeLargeTitles: {
|
||||
desktop: {
|
||||
// LargeSmall body text sizes
|
||||
text2xs: "clamp(0.465rem, 0.682vw, 0.62rem)",
|
||||
textXs: "clamp(0.54rem, 0.792vw, 0.72rem)",
|
||||
textSm: "clamp(0.615rem, 0.902vw, 0.82rem)",
|
||||
textBase: "clamp(0.69rem, 1.012vw, 0.92rem)",
|
||||
textLg: "clamp(0.75rem, 1.1vw, 1rem)",
|
||||
textXl: "clamp(0.825rem, 1.21vw, 1.1rem)",
|
||||
text2xl: "clamp(0.975rem, 1.43vw, 1.3rem)",
|
||||
text3xl: "clamp(1.2rem, 1.76vw, 1.6rem)",
|
||||
text4xl: "clamp(1.5rem, 2.2vw, 2rem)",
|
||||
// Large title sizes
|
||||
text5xl: "clamp(2.025rem, 3.1625vw, 2.75rem)",
|
||||
text6xl: "clamp(2.475rem, 3.795vw, 3.3rem)",
|
||||
text7xl: "clamp(3rem, 4.6vw, 4rem)",
|
||||
text8xl: "clamp(3.5rem, 5.175vw, 4.5rem)",
|
||||
text9xl: "clamp(5.25rem, 8.05vw, 7rem)",
|
||||
},
|
||||
mobile: {
|
||||
// LargeSmall body text sizes
|
||||
text2xs: "2.75vw",
|
||||
textXs: "3.025vw",
|
||||
textSm: "3.3vw",
|
||||
textBase: "3.575vw",
|
||||
textLg: "3.85vw",
|
||||
textXl: "4.675vw",
|
||||
text2xl: "5.5vw",
|
||||
text3xl: "6.6vw",
|
||||
text4xl: "7.7vw",
|
||||
// Large title sizes
|
||||
text5xl: "8.625vw",
|
||||
text6xl: "9.775vw",
|
||||
text7xl: "11.5vw",
|
||||
text8xl: "13.8vw",
|
||||
text9xl: "16.1vw",
|
||||
},
|
||||
},
|
||||
mediumLargeSizeMediumTitles: {
|
||||
desktop: {
|
||||
// MediumLarge body text sizes
|
||||
text2xs: "clamp(0.465rem, 0.651vw, 0.62rem)",
|
||||
textXs: "clamp(0.54rem, 0.756vw, 0.72rem)",
|
||||
textSm: "clamp(0.615rem, 0.861vw, 0.82rem)",
|
||||
textBase: "clamp(0.69rem, 0.966vw, 0.92rem)",
|
||||
textLg: "clamp(0.75rem, 1.05vw, 1rem)",
|
||||
textXl: "clamp(0.825rem, 1.155vw, 1.1rem)",
|
||||
text2xl: "clamp(0.975rem, 1.365vw, 1.3rem)",
|
||||
text3xl: "clamp(1.2rem, 1.68vw, 1.6rem)",
|
||||
text4xl: "clamp(1.5rem, 2.1vw, 2rem)",
|
||||
// Medium title sizes
|
||||
text5xl: "clamp(2.025rem, 2.75vw, 2.75rem)",
|
||||
text6xl: "clamp(2.475rem, 3.3vw, 3.3rem)",
|
||||
text7xl: "clamp(3rem, 4vw, 4rem)",
|
||||
text8xl: "clamp(3.5rem, 4.5vw, 4.5rem)",
|
||||
text9xl: "clamp(5.25rem, 7vw, 7rem)",
|
||||
},
|
||||
mobile: {
|
||||
// MediumLarge body text sizes
|
||||
text2xs: "2.625vw",
|
||||
textXs: "2.8875vw",
|
||||
textSm: "3.15vw",
|
||||
textBase: "3.4125vw",
|
||||
textLg: "3.675vw",
|
||||
textXl: "4.4625vw",
|
||||
text2xl: "5.25vw",
|
||||
text3xl: "6.3vw",
|
||||
text4xl: "7.35vw",
|
||||
// Medium title sizes
|
||||
text5xl: "7.5vw",
|
||||
text6xl: "8.5vw",
|
||||
text7xl: "10vw",
|
||||
text8xl: "12vw",
|
||||
text9xl: "14vw",
|
||||
},
|
||||
},
|
||||
largeSmallSizeMediumTitles: {
|
||||
desktop: {
|
||||
// LargeSmall body text sizes
|
||||
text2xs: "clamp(0.465rem, 0.682vw, 0.62rem)",
|
||||
textXs: "clamp(0.54rem, 0.792vw, 0.72rem)",
|
||||
textSm: "clamp(0.615rem, 0.902vw, 0.82rem)",
|
||||
textBase: "clamp(0.69rem, 1.012vw, 0.92rem)",
|
||||
textLg: "clamp(0.75rem, 1.1vw, 1rem)",
|
||||
textXl: "clamp(0.825rem, 1.21vw, 1.1rem)",
|
||||
text2xl: "clamp(0.975rem, 1.43vw, 1.3rem)",
|
||||
text3xl: "clamp(1.2rem, 1.76vw, 1.6rem)",
|
||||
text4xl: "clamp(1.5rem, 2.2vw, 2rem)",
|
||||
// Medium title sizes
|
||||
text5xl: "clamp(2.025rem, 2.75vw, 2.75rem)",
|
||||
text6xl: "clamp(2.475rem, 3.3vw, 3.3rem)",
|
||||
text7xl: "clamp(3rem, 4vw, 4rem)",
|
||||
text8xl: "clamp(3.5rem, 4.5vw, 4.5rem)",
|
||||
text9xl: "clamp(5.25rem, 7vw, 7rem)",
|
||||
},
|
||||
mobile: {
|
||||
// LargeSmall body text sizes
|
||||
text2xs: "2.75vw",
|
||||
textXs: "3.025vw",
|
||||
textSm: "3.3vw",
|
||||
textBase: "3.575vw",
|
||||
textLg: "3.85vw",
|
||||
textXl: "4.675vw",
|
||||
text2xl: "5.5vw",
|
||||
text3xl: "6.6vw",
|
||||
text4xl: "7.7vw",
|
||||
// Medium title sizes
|
||||
text5xl: "7.5vw",
|
||||
text6xl: "8.5vw",
|
||||
text7xl: "10vw",
|
||||
text8xl: "12vw",
|
||||
text9xl: "14vw",
|
||||
},
|
||||
},
|
||||
};
|
||||
48
src/providers/themeProvider/config/types.ts
Normal file
48
src/providers/themeProvider/config/types.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
import type { CTAButtonVariant } from "@/components/button/types";
|
||||
import type { AnimationType } from "@/components/text/types";
|
||||
|
||||
export type BorderRadiusPreset = "rounded" | "soft" | "pill";
|
||||
export type ContentWidthPreset = "small" | "smallMedium" | "compact" | "mediumSmall" | "medium" | "mediumLarge";
|
||||
export type SizingPreset = "medium" | "mediumLarge" | "largeSmall" | "large" | "mediumSizeLargeTitles" | "mediumLargeSizeLargeTitles" | "largeSmallSizeLargeTitles" | "largeSizeMediumTitles" | "mediumLargeSizeMediumTitles" | "largeSmallSizeMediumTitles";
|
||||
export type HeadingFontWeight = "light" | "normal" | "medium" | "semibold" | "bold" | "extrabold";
|
||||
export type BackgroundType =
|
||||
| "none"
|
||||
| "circleGradient"
|
||||
| "aurora"
|
||||
| "floatingGradient"
|
||||
| "noise"
|
||||
| "noiseDiagonalGradient"
|
||||
| "fluid"
|
||||
| "blurBottom"
|
||||
| "grid";
|
||||
|
||||
export type CardStyleVariant = "solid" | "outline" | "gradient-mesh" | "gradient-radial" | "inset" | "glass-elevated" | "glass-depth" | "gradient-bordered" | "layered-gradient" | "soft-shadow" | "subtle-shadow" | "elevated-border" | "inner-glow" | "spotlight";
|
||||
export type PrimaryButtonStyleVariant = "gradient" | "shadow" | "flat" | "radial-glow" | "diagonal-gradient" | "double-inset" | "primary-glow" | "inset-glow" | "soft-glow" | "glass-shimmer" | "neon-outline" | "lifted" | "depth-layers" | "accent-edge" | "metallic";
|
||||
export type SecondaryButtonStyleVariant = "glass" | "solid" | "layered" | "radial-glow";
|
||||
|
||||
export interface ThemeConfig {
|
||||
defaultButtonVariant: CTAButtonVariant;
|
||||
defaultTextAnimation: AnimationType;
|
||||
borderRadius: BorderRadiusPreset;
|
||||
contentWidth: ContentWidthPreset;
|
||||
sizing: SizingPreset;
|
||||
background: BackgroundType;
|
||||
cardStyle: CardStyleVariant;
|
||||
primaryButtonStyle: PrimaryButtonStyleVariant;
|
||||
secondaryButtonStyle: SecondaryButtonStyleVariant;
|
||||
headingFontWeight: HeadingFontWeight;
|
||||
}
|
||||
|
||||
export interface ThemeProviderProps {
|
||||
children: React.ReactNode;
|
||||
defaultButtonVariant: CTAButtonVariant;
|
||||
defaultTextAnimation: AnimationType;
|
||||
borderRadius: BorderRadiusPreset;
|
||||
contentWidth: ContentWidthPreset;
|
||||
sizing: SizingPreset;
|
||||
background: BackgroundType;
|
||||
cardStyle: CardStyleVariant;
|
||||
primaryButtonStyle: PrimaryButtonStyleVariant;
|
||||
secondaryButtonStyle: SecondaryButtonStyleVariant;
|
||||
headingFontWeight: HeadingFontWeight;
|
||||
}
|
||||
120
src/providers/themeProvider/styles/cardStyles.ts
Normal file
120
src/providers/themeProvider/styles/cardStyles.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import type { CardStyleVariant } from "../config/types";
|
||||
|
||||
export const cardStyleMap: Record<CardStyleVariant, string> = {
|
||||
"solid": `
|
||||
position: relative;
|
||||
background: var(--color-card);
|
||||
`,
|
||||
"outline": `
|
||||
position: relative;
|
||||
background: var(--color-card);
|
||||
border: 1px solid color-mix(in srgb, var(--color-accent) 25%, transparent);
|
||||
`,
|
||||
"gradient-mesh": `
|
||||
position: relative;
|
||||
background:
|
||||
radial-gradient(at 0% 0%, color-mix(in srgb, var(--color-accent) 15%, transparent) 0px, transparent 50%),
|
||||
radial-gradient(at 100% 0%, color-mix(in srgb, var(--color-accent) 10%, transparent) 0px, transparent 50%),
|
||||
radial-gradient(at 100% 100%, color-mix(in srgb, var(--color-accent) 20%, transparent) 0px, transparent 50%),
|
||||
radial-gradient(at 0% 100%, color-mix(in srgb, var(--color-accent) 12%, transparent) 0px, transparent 50%),
|
||||
var(--color-card);
|
||||
`,
|
||||
"gradient-radial": `
|
||||
position: relative;
|
||||
background: radial-gradient(circle at center, color-mix(in srgb, var(--color-card) 100%, var(--color-accent) 20%) 0%, var(--color-card) 90%);
|
||||
`,
|
||||
"inset": `
|
||||
position: relative;
|
||||
background: color-mix(in srgb, var(--color-card) 95%, var(--color-accent) 5%);
|
||||
box-shadow:
|
||||
inset 2px 2px 4px color-mix(in srgb, var(--color-foreground) 8%, transparent),
|
||||
inset -2px -2px 4px color-mix(in srgb, var(--color-background) 20%, transparent);
|
||||
`,
|
||||
"glass-elevated": `
|
||||
position: relative;
|
||||
backdrop-filter: blur(8px);
|
||||
background: linear-gradient(to bottom right, color-mix(in srgb, var(--color-card) 80%, transparent), color-mix(in srgb, var(--color-card) 40%, transparent));
|
||||
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
border: 1px solid var(--color-card);
|
||||
`,
|
||||
"glass-depth": `
|
||||
position: relative;
|
||||
background: color-mix(in srgb, var(--color-card) 80%, transparent);
|
||||
backdrop-filter: blur(14px);
|
||||
box-shadow:
|
||||
inset 0 0 20px 0 color-mix(in srgb, var(--color-accent) 7.5%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--color-accent) 7.5%, transparent);
|
||||
`,
|
||||
"gradient-bordered": `
|
||||
position: relative;
|
||||
background: linear-gradient(180deg, color-mix(in srgb, var(--color-card) 100%, var(--color-accent) 5%) -35%, var(--color-card) 65%);
|
||||
box-shadow: 0px 0px 10px 4px color-mix(in srgb, var(--color-accent) 4%, transparent);
|
||||
`,
|
||||
"layered-gradient": `
|
||||
position: relative;
|
||||
background:
|
||||
linear-gradient(color-mix(in srgb, var(--color-accent) 6%, transparent) 0%, transparent 59.26%),
|
||||
linear-gradient(var(--color-card) 0%, var(--color-card) 100%),
|
||||
var(--color-card);
|
||||
box-shadow:
|
||||
20px 18px 7px color-mix(in srgb, var(--color-accent) 0%, transparent),
|
||||
2px 2px 2px color-mix(in srgb, var(--color-accent) 6.5%, transparent),
|
||||
1px 1px 2px color-mix(in srgb, var(--color-accent) 2%, transparent);
|
||||
border: 2px solid var(--color-secondary-cta);
|
||||
`,
|
||||
"soft-shadow": `
|
||||
position: relative;
|
||||
background: var(--color-card);
|
||||
box-shadow: color-mix(in srgb, var(--color-accent) 10%, transparent) 0px 0.706592px 0.706592px -0.666667px, color-mix(in srgb, var(--color-accent) 8%, transparent) 0px 1.80656px 1.80656px -1.33333px, color-mix(in srgb, var(--color-accent) 7%, transparent) 0px 3.62176px 3.62176px -2px, color-mix(in srgb, var(--color-accent) 7%, transparent) 0px 6.8656px 6.8656px -2.66667px, color-mix(in srgb, var(--color-accent) 5%, transparent) 0px 13.6468px 13.6468px -3.33333px, color-mix(in srgb, var(--color-accent) 2%, transparent) 0px 30px 30px -4px, var(--color-background) 0px 3px 1px 0px inset;
|
||||
`,
|
||||
"subtle-shadow": `
|
||||
position: relative;
|
||||
background: var(--color-card);
|
||||
box-shadow: color-mix(in srgb, var(--color-foreground) 5%, transparent) 0px 4px 32px 0px;
|
||||
`,
|
||||
"elevated-border": `
|
||||
position: relative;
|
||||
background: linear-gradient(180deg, color-mix(in srgb, var(--color-card) 100%, var(--color-foreground) 3%) 0%, var(--color-card) 100%);
|
||||
box-shadow: 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 8%, transparent), 0 4px 6px -1px color-mix(in srgb, var(--color-foreground) 5%, transparent), 0 10px 15px -3px color-mix(in srgb, var(--color-foreground) 4%, transparent);
|
||||
border: 1px solid color-mix(in srgb, var(--color-foreground) 6%, transparent);
|
||||
`,
|
||||
"inner-glow": `
|
||||
position: relative;
|
||||
background: var(--color-card);
|
||||
box-shadow: inset 0 0 30px 0 color-mix(in srgb, var(--color-foreground) 4%, transparent), inset 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 8%, transparent), 0 4px 12px -4px color-mix(in srgb, var(--color-foreground) 8%, transparent);
|
||||
`,
|
||||
"spotlight": `
|
||||
position: relative;
|
||||
background:
|
||||
radial-gradient(ellipse at 0% 0%, color-mix(in srgb, var(--color-accent) 20%, transparent) 0%, transparent 50%),
|
||||
var(--color-card);
|
||||
box-shadow: inset 1px 1px 0 0 color-mix(in srgb, var(--color-foreground) 10%, transparent), 0 4px 16px -4px color-mix(in srgb, var(--color-foreground) 10%, transparent);
|
||||
`,
|
||||
};
|
||||
|
||||
export const getGradientBorderedPseudo = (cardStyle: CardStyleVariant): string => {
|
||||
if (cardStyle !== "gradient-bordered") return '';
|
||||
|
||||
return `
|
||||
.card::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
inset: 0;
|
||||
padding: 1px;
|
||||
border-radius: inherit;
|
||||
background: linear-gradient(
|
||||
160deg,
|
||||
color-mix(in srgb, var(--color-accent) 25%, transparent) 0%,
|
||||
color-mix(in srgb, var(--color-accent) 5%, transparent) 35%,
|
||||
color-mix(in srgb, var(--color-foreground) 5%, transparent) 75%,
|
||||
color-mix(in srgb, var(--color-background-accent) 15%, transparent) 100%
|
||||
);
|
||||
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
|
||||
mask-composite: exclude;
|
||||
}
|
||||
`;
|
||||
};
|
||||
|
||||
101
src/providers/themeProvider/styles/primaryButtonStyles.ts
Normal file
101
src/providers/themeProvider/styles/primaryButtonStyles.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import type { PrimaryButtonStyleVariant } from "../config/types";
|
||||
|
||||
export const primaryButtonStyleMap: Record<PrimaryButtonStyleVariant, string> = {
|
||||
gradient: `
|
||||
background: linear-gradient(to bottom, color-mix(in srgb, var(--color-primary-cta) 75%, transparent), var(--color-primary-cta));
|
||||
box-shadow: color-mix(in srgb, var(--color-background) 25%, transparent) 0px 1px 1px 0px inset, color-mix(in srgb, var(--color-primary-cta) 15%, transparent) 3px 3px 3px 0px;
|
||||
`,
|
||||
shadow: `
|
||||
background: var(--color-primary-cta);
|
||||
box-shadow: 2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-primary-cta) 40%, transparent);
|
||||
`,
|
||||
flat: `
|
||||
background: var(--color-primary-cta);
|
||||
box-shadow: none;
|
||||
`,
|
||||
"radial-glow": `
|
||||
background:
|
||||
radial-gradient(circle at 0% 0%, color-mix(in srgb, var(--color-background) 32.5%, transparent) 0%, transparent 45%),
|
||||
radial-gradient(circle at 100% 100%, color-mix(in srgb, var(--color-background) 32.5%, transparent) 0%, transparent 45%),
|
||||
var(--color-primary-cta);
|
||||
box-shadow: 2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-accent) 30%, transparent);
|
||||
`,
|
||||
"diagonal-gradient": `
|
||||
background: linear-gradient(to bottom right, color-mix(in srgb, var(--color-primary-cta) 80%, transparent), var(--color-foreground));
|
||||
box-shadow: 2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-accent) 30%, transparent);
|
||||
`,
|
||||
"double-inset": `
|
||||
background: var(--color-primary-cta);
|
||||
box-shadow: color-mix(in srgb, var(--color-background) 15%, transparent) 0px 4px 10px 0px inset, color-mix(in srgb, var(--color-background) 15%, transparent) 0px -4px 8px 0px inset;
|
||||
`,
|
||||
"primary-glow": `
|
||||
background: var(--color-primary-cta);
|
||||
box-shadow: color-mix(in srgb, var(--color-background) 20%, transparent) 0px 3px 1px 0px inset, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 0.839802px 0.503881px -0.3125px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 1.99048px 1.19429px -0.625px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 3.63084px 2.1785px -0.9375px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 6.03627px 3.62176px -1.25px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 9.74808px 5.84885px -1.5625px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 15.9566px 9.57398px -1.875px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 27.4762px 16.4857px -2.1875px, color-mix(in srgb, var(--color-primary-cta) 13%, transparent) 0px 50px 30px -2.5px;
|
||||
`,
|
||||
"inset-glow": `
|
||||
position: relative;
|
||||
background: linear-gradient(180deg, color-mix(in srgb, var(--color-primary-cta) 65%, var(--color-background)) -35%, var(--color-primary-cta) 65%);
|
||||
box-shadow: 0 10px 18px -7px color-mix(in srgb, var(--color-background) 50%, transparent), inset 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 15%, transparent);
|
||||
`,
|
||||
"soft-glow": `
|
||||
position: relative;
|
||||
background: radial-gradient(ellipse at 50% -20%, color-mix(in srgb, var(--color-primary-cta) 70%, var(--color-foreground)) 0%, var(--color-primary-cta) 70%);
|
||||
box-shadow: 0 8px 24px -6px color-mix(in srgb, var(--color-primary-cta) 35%, transparent), inset 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 20%, transparent);
|
||||
`,
|
||||
"glass-shimmer": `
|
||||
position: relative;
|
||||
background: linear-gradient(165deg, color-mix(in srgb, var(--color-primary-cta) 85%, var(--color-foreground)) 0%, var(--color-primary-cta) 40%, color-mix(in srgb, var(--color-primary-cta) 90%, var(--color-background)) 100%);
|
||||
box-shadow: inset 0 1px 1px 0 color-mix(in srgb, var(--color-foreground) 25%, transparent), inset 0 -1px 1px 0 color-mix(in srgb, var(--color-background) 15%, transparent), 0 4px 12px -2px color-mix(in srgb, var(--color-primary-cta) 25%, transparent);
|
||||
`,
|
||||
"neon-outline": `
|
||||
position: relative;
|
||||
background: var(--color-primary-cta);
|
||||
box-shadow: 0 0 5px color-mix(in srgb, var(--color-accent) 50%, transparent), 0 0 15px color-mix(in srgb, var(--color-accent) 30%, transparent), 0 0 30px color-mix(in srgb, var(--color-accent) 15%, transparent), inset 0 0 8px color-mix(in srgb, var(--color-accent) 10%, transparent);
|
||||
`,
|
||||
"lifted": `
|
||||
position: relative;
|
||||
background: linear-gradient(180deg, color-mix(in srgb, var(--color-primary-cta) 95%, var(--color-foreground)) 0%, var(--color-primary-cta) 50%, color-mix(in srgb, var(--color-primary-cta) 95%, var(--color-background)) 100%);
|
||||
box-shadow: inset 0 2px 3px 0 color-mix(in srgb, var(--color-foreground) 20%, transparent), inset 0 -2px 3px 0 color-mix(in srgb, var(--color-background) 25%, transparent), 0 2px 4px -1px color-mix(in srgb, var(--color-background) 40%, transparent);
|
||||
`,
|
||||
"depth-layers": `
|
||||
position: relative;
|
||||
background: var(--color-primary-cta);
|
||||
box-shadow: 0 1px 2px color-mix(in srgb, var(--color-primary-cta) 20%, transparent), 0 2px 4px color-mix(in srgb, var(--color-primary-cta) 20%, transparent), 0 4px 8px color-mix(in srgb, var(--color-primary-cta) 15%, transparent), 0 8px 16px color-mix(in srgb, var(--color-primary-cta) 10%, transparent), 0 16px 32px color-mix(in srgb, var(--color-primary-cta) 5%, transparent);
|
||||
`,
|
||||
"accent-edge": `
|
||||
position: relative;
|
||||
background: linear-gradient(180deg, var(--color-primary-cta) 0%, color-mix(in srgb, var(--color-primary-cta) 90%, var(--color-background)) 100%);
|
||||
box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-accent) 60%, transparent), 0 4px 12px -2px color-mix(in srgb, var(--color-accent) 35%, transparent), inset 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 20%, transparent);
|
||||
`,
|
||||
"metallic": `
|
||||
position: relative;
|
||||
background: linear-gradient(135deg, color-mix(in srgb, var(--color-primary-cta) 80%, var(--color-foreground)) 0%, var(--color-primary-cta) 25%, color-mix(in srgb, var(--color-primary-cta) 90%, var(--color-background)) 50%, var(--color-primary-cta) 75%, color-mix(in srgb, var(--color-primary-cta) 85%, var(--color-foreground)) 100%);
|
||||
box-shadow: inset 0 1px 0 0 color-mix(in srgb, var(--color-foreground) 30%, transparent), 0 3px 8px -2px color-mix(in srgb, var(--color-background) 50%, transparent);
|
||||
`,
|
||||
};
|
||||
|
||||
export const getInsetGlowPseudo = (style: PrimaryButtonStyleVariant): string => {
|
||||
if (style !== "inset-glow") return '';
|
||||
|
||||
return `
|
||||
.primary-button::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
inset: 0;
|
||||
padding: 1px;
|
||||
border-radius: inherit;
|
||||
background: linear-gradient(
|
||||
0deg,
|
||||
color-mix(in srgb, var(--color-primary-cta) 20%, var(--color-background)) 0%,
|
||||
color-mix(in srgb, var(--color-primary-cta) 40%, var(--color-background)) 27%,
|
||||
color-mix(in srgb, var(--color-primary-cta) 60%, var(--color-foreground)) 62%,
|
||||
color-mix(in srgb, var(--color-primary-cta) 80%, var(--color-foreground)) 100%
|
||||
);
|
||||
-webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
|
||||
mask-composite: exclude;
|
||||
}
|
||||
`;
|
||||
};
|
||||
33
src/providers/themeProvider/styles/secondaryButtonStyles.ts
Normal file
33
src/providers/themeProvider/styles/secondaryButtonStyles.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import type { SecondaryButtonStyleVariant } from "../config/types";
|
||||
|
||||
export const secondaryButtonStyleMap: Record<SecondaryButtonStyleVariant, string> = {
|
||||
glass: `
|
||||
backdrop-filter: blur(8px);
|
||||
background: linear-gradient(to bottom right, color-mix(in srgb, var(--color-secondary-cta) 80%, transparent), var(--color-secondary-cta));
|
||||
box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
border: 1px solid var(--color-secondary-cta);
|
||||
`,
|
||||
solid: `
|
||||
background: var(--color-secondary-cta);
|
||||
box-shadow: none;
|
||||
`,
|
||||
layered: `
|
||||
background:
|
||||
linear-gradient(color-mix(in srgb, var(--color-accent) 5%, transparent) 0%, transparent 59.26%),
|
||||
linear-gradient(var(--color-secondary-cta), var(--color-secondary-cta)),
|
||||
linear-gradient(var(--color-secondary-cta), var(--color-secondary-cta)),
|
||||
linear-gradient(color-mix(in srgb, var(--color-accent) 5%, transparent) 0%, transparent 59.26%),
|
||||
linear-gradient(color-mix(in srgb, var(--color-secondary-cta) 60%, transparent), color-mix(in srgb, var(--color-secondary-cta) 60%, transparent)),
|
||||
var(--color-secondary-cta);
|
||||
box-shadow:
|
||||
2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-accent) 10%, transparent);
|
||||
border: 1px solid var(--color-secondary-cta);
|
||||
`,
|
||||
"radial-glow": `
|
||||
background:
|
||||
radial-gradient(circle at 0% 0%, color-mix(in srgb, var(--color-accent) 15%, transparent) 0%, transparent 40%),
|
||||
radial-gradient(circle at 100% 100%, color-mix(in srgb, var(--color-accent) 15%, transparent) 0%, transparent 40%),
|
||||
var(--color-secondary-cta);
|
||||
box-shadow: 2.10837px 3.16256px 9.48767px color-mix(in srgb, var(--color-accent) 10%, transparent);
|
||||
`,
|
||||
};
|
||||
21
src/providers/themeProvider/utils/detectLightBackground.ts
Normal file
21
src/providers/themeProvider/utils/detectLightBackground.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Detects if the current background color is light or dark
|
||||
* Used for AnimatedAuroraBackground to determine if colors should be inverted
|
||||
*
|
||||
* @returns true for light backgrounds (hex starting with 8-f), false for dark backgrounds (hex starting with 0-7)
|
||||
*/
|
||||
export const detectLightBackground = (): boolean => {
|
||||
if (typeof window === 'undefined') return true;
|
||||
|
||||
const computedBg = getComputedStyle(document.documentElement)
|
||||
.getPropertyValue('--background')
|
||||
.trim();
|
||||
|
||||
// If it starts with #0-7, it's likely dark
|
||||
if (computedBg.startsWith('#')) {
|
||||
const firstChar = computedBg.charAt(1).toLowerCase();
|
||||
return firstChar >= '8'; // 8-f is light, 0-7 is dark
|
||||
}
|
||||
|
||||
return true; // Default to light
|
||||
};
|
||||
Reference in New Issue
Block a user