diff --git a/packages/og/hslToHex.ts b/packages/og/hslToHex.ts
new file mode 100644
index 00000000..e4ad4a3d
--- /dev/null
+++ b/packages/og/hslToHex.ts
@@ -0,0 +1,59 @@
+/**
+ * Converts between an HSL string and its HEX representation.
+ */
+export function hslToHex(hslString: string): string {
+ // Regular expression to extract H, S, and L values
+ const hslRegex = /hsl\((?
\d+)deg,\s*(?\d+)%,\s(?\d+)%,.*\)/;
+ const match = hslRegex.exec(hslString);
+
+ if (!match) {
+ throw new Error('Invalid HSL string format');
+ }
+
+ // Extract values and convert them to integers
+ const hue = parseInt(match.groups?.hue ?? '', 10);
+ const saturation = parseInt(match.groups?.saturation ?? '', 10) / 100;
+ const lightness = parseInt(match.groups?.lightness ?? '', 10) / 100;
+
+ // Convert HSL to RGB
+ const c = (1 - Math.abs(2 * lightness - 1)) * saturation;
+ const x = c * (1 - Math.abs(((hue / 60) % 2) - 1));
+ const m = lightness - c / 2;
+ let r = 0,
+ g = 0,
+ b = 0;
+
+ if (hue >= 0 && hue < 60) {
+ r = c;
+ g = x;
+ b = 0;
+ } else if (hue >= 60 && hue < 120) {
+ r = x;
+ g = c;
+ b = 0;
+ } else if (hue >= 120 && hue < 180) {
+ r = 0;
+ g = c;
+ b = x;
+ } else if (hue >= 180 && hue < 240) {
+ r = 0;
+ g = x;
+ b = c;
+ } else if (hue >= 240 && hue < 300) {
+ r = x;
+ g = 0;
+ b = c;
+ } else if (hue >= 300 && hue < 360) {
+ r = c;
+ g = 0;
+ b = x;
+ }
+
+ // Convert RGB to HEX
+ const toHex = (value: number): string => {
+ const hex = Math.round((value + m) * 255).toString(16);
+ return hex.length === 1 ? `0${hex}` : hex;
+ };
+
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
+}
diff --git a/packages/ui/core/ButtonWithTooltip.tsx b/packages/ui/core/ButtonWithTooltip.tsx
deleted file mode 100644
index c0f058c2..00000000
--- a/packages/ui/core/ButtonWithTooltip.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import type { ButtonProps, TooltipProps } from '@mui/material';
-import { Button, Tooltip } from '@mui/material';
-
-/**
- * Handles weird layout problems with buttons and tooltips by wrapping it in a div
- */
-export function ButtonWithTooltip({
- tooltipProps,
- buttonProps,
- children,
-}: {
- tooltipProps: Partial> & Pick;
- buttonProps: Partial>;
- children: React.ReactNode;
-}) {
- return (
-
-
-
-
-
- );
-}
diff --git a/packages/ui/core/ColorSchemeButton.tsx b/packages/ui/core/ColorSchemeButton.tsx
index f3976002..f1497fb2 100644
--- a/packages/ui/core/ColorSchemeButton.tsx
+++ b/packages/ui/core/ColorSchemeButton.tsx
@@ -1,8 +1,7 @@
import { Moon, Sun, Monitor } from 'lucide-react';
-import type { Theme } from '@mui/material';
+import { Button, Tooltip } from '@mui/material';
import { useColorScheme } from '../theme/useColorScheme';
import type { ColorSchemeMode } from '../theme/useColorScheme';
-import { ButtonWithTooltip } from './ButtonWithTooltip';
type Mode = ColorSchemeMode | 'system';
@@ -22,63 +21,50 @@ const ICONS: Record = {
system: ,
} as const;
-function getColor(mode: Mode, theme: Theme) {
- switch (mode) {
- case 'light':
- return theme.vars.palette.warning.main;
- case 'dark':
- return theme.vars.palette.secondary.light;
- case 'system':
- return theme.vars.palette.primary.dark;
- }
-}
+const TOOLTIP: Record = {
+ light: 'Use light color mode',
+ dark: 'Use dark color mode',
+ system: `Use system color mode`,
+} as const;
/**
* Creates an icon that is clickable to update to a preferred color scheme
* if we have one that's set already. Otherwise, renders a disabled icon.
*/
export function ColorSchemeButton({ mode }: ColorSchemeButtonProps) {
- const { updatePreferredMode } = useColorScheme();
- const tooltip = (() => {
- switch (mode) {
- case 'light':
- return 'Use light color mode';
- case 'dark':
- return 'Use dark color mode';
- case 'system':
- return `Use system color mode`;
- }
- })();
-
+ const {
+ updatePreferredMode,
+ colorScheme: { isInitialized },
+ } = useColorScheme();
+ const tooltip = TOOLTIP[mode];
return (
- {
+
+
+ }}
+ >
+ {ICONS[mode]}
+
+
);
}
diff --git a/packages/ui/core/ColorSchemeToggle.tsx b/packages/ui/core/ColorSchemeToggle.tsx
index 083c1e88..06e1e951 100644
--- a/packages/ui/core/ColorSchemeToggle.tsx
+++ b/packages/ui/core/ColorSchemeToggle.tsx
@@ -8,7 +8,7 @@ import { ColorSchemeButton } from './ColorSchemeButton';
export function ColorSchemeToggle() {
return (
-
+
diff --git a/packages/ui/dependent/ContentCard.tsx b/packages/ui/dependent/ContentCard.tsx
index aa5f5555..6b47f6e9 100644
--- a/packages/ui/dependent/ContentCard.tsx
+++ b/packages/ui/dependent/ContentCard.tsx
@@ -71,6 +71,11 @@ function getCardSx(
boxShadow: theme.vars.extraShadows.card.hovered,
},
}),
+ [theme.breakpoints.down('md')]: {
+ justifySelf: 'center',
+ maxWidth: '85vw',
+ minWidth: 'min(fit-content, 85vw)',
+ },
[theme.breakpoints.up('md')]: {
...(verticalSpan && {
gridRow: `span ${verticalSpan}`,
diff --git a/packages/ui/dependent/Image.tsx b/packages/ui/dependent/Image.tsx
index 3e268824..09b7805f 100644
--- a/packages/ui/dependent/Image.tsx
+++ b/packages/ui/dependent/Image.tsx
@@ -5,6 +5,9 @@ import { BREAKPOINT_MAX_SIZES } from '../helpers/imageSizes';
type ImageProps = Partial & {
url: Asset['url'];
+ width: Asset['width'];
+ height: Asset['height'];
+ fill?: boolean;
/**
* Alt text, required, but defaults to title
@@ -46,18 +49,7 @@ type ImageProps = Partial & {
*/
extraLarge: number;
};
-} & (
- | {
- fill: true;
- width?: never;
- height?: never;
- }
- | {
- fill?: never;
- width: Asset['width'];
- height: Asset['height'];
- }
- );
+};
/**
* All images need to be max width'd for our layouts
@@ -93,11 +85,19 @@ const generateSizesString = (sizes: ImageProps['sizes']): string => {
* Shows a Next Image with the contents of the Asset and custom
* sizes as needed.
*/
-export function Image({ url, title, alt, sizes, ...props }: ImageProps) {
+export function Image({ url, title, alt, sizes, width, height, fill, ...props }: ImageProps) {
if (!url) {
return null;
}
- return (
-
- );
+ const sharedProps = {
+ alt: title ?? alt,
+ src: url,
+ sizes: generateSizesString(sizes),
+ ...props,
+ };
+
+ if (!fill) {
+ return ;
+ }
+ return ;
}
diff --git a/packages/ui/theme/color.ts b/packages/ui/theme/color.ts
index b0d29d89..285f837c 100644
--- a/packages/ui/theme/color.ts
+++ b/packages/ui/theme/color.ts
@@ -3,45 +3,42 @@
* not custom outside of it.
*/
export const COLORS = {
- PRIMARY: '#16ac7f',
- SECONDARY: '#168eac',
- MUTED_TEXT: '#73828c',
LIGHT: {
- DEFAULT_BACKGROUND: 'hsl(206, 60%, 96%)',
- PAPER_BACKGROUND: 'hsl(206, 60%, 96%)',
- CARD_BACKGROUND: 'rgb(255, 255, 255)',
- CARD_BORDER: 'rgba(89,107,120,.125)',
- CODE_BACKGROUND: 'hsl(206deg 32% 88%)',
- YELLOW: '#dec51d',
- TEXT: '#415462',
- H1: '#1b2832',
- H2: '#24333e',
- H3: '#2c3d49',
- H4: '#374956',
- H5: '#415462',
- H6: '#4d606d',
+ DEFAULT_BACKGROUND: 'hsl(24deg, 48%, 90%, 1)',
+ PAPER_BACKGROUND: 'hsl(24deg, 52%, 94%, 1)',
+ CARD_BORDER: 'hsl(24deg, 10%, 50%, 0.25)',
+ PRIMARY: 'hsl(183deg, 33%, 39%, 1)',
+ SECONDARY: 'hsl(183deg, 33%, 39%, 0.75)',
+ TEXT: 'hsl(183deg, 12%, 27%, 1)',
+ MUTED_TEXT: 'hsl(183deg, 12%, 48%, 1)',
+ H1: 'hsl(183deg, 33%, 37%, 1)',
+ H2: 'hsl(183deg, 31%, 35%, 1)',
+ H3: 'hsl(183deg, 29%, 32%, 1)',
+ H4: 'hsl(183deg, 27%, 29%, 1)',
+ H5: 'hsl(183deg, 25%, 27%, 1)',
+ H6: 'hsl(183deg, 23%, 20%, 1)',
MAP: {
- MARKER_BACKGROUND: 'rgba(58, 123, 172, 0.25)',
- MARKER_BORDER: 'rgba(139, 185, 220, 0.75)',
+ MARKER_BACKGROUND: 'hsl(183deg, 33%, 37%, 0.25)',
+ MARKER_BORDER: 'hsl(183deg, 33%, 37%, 0.75)',
},
},
DARK: {
- DEFAULT_BACKGROUND: 'rgb(17, 25, 31)',
- PAPER_BACKGROUND: 'hsl(206, 24%, 22%)',
- CARD_BACKGROUND: 'hsl(206, 24%, 18%)',
- CARD_BORDER: 'rgba(115,130,140,.25)',
- CODE_BACKGROUND: '#18232c',
- YELLOW: '#ffff00',
- TEXT: '#bbc6ce',
- H1: '#edf0f3',
- H2: '#e1e6eb',
- H3: '#d5dce2',
- H4: '#c8d1d8',
- H5: '#bbc6ce',
- H6: '#afbbc4',
+ DEFAULT_BACKGROUND: 'hsl(183deg, 92%, 10%, 1)',
+ PAPER_BACKGROUND: 'hsl(183deg, 90%, 14%, 1)',
+ CARD_BORDER: 'hsl(183deg, 10%, 50%, 0.25)',
+ PRIMARY: 'hsl(24deg, 88%, 70%, 1)',
+ SECONDARY: 'hsl(24deg, 88%, 70%, 0.75)',
+ TEXT: 'hsl(24deg, 1%, 79%, 1)',
+ MUTED_TEXT: 'hsl(24deg, 1%, 47%, 1)',
+ H1: 'hsl(24deg, 58%, 70%, 1)',
+ H2: 'hsl(24deg, 38%, 70%, 1)',
+ H3: 'hsl(24deg, 28%, 70%, 1)',
+ H4: 'hsl(24deg, 28%, 70%, 1)',
+ H5: 'hsl(24deg, 18%, 82%, 1)',
+ H6: 'hsl(24deg, 18%, 82%, 1)',
MAP: {
- MARKER_BACKGROUND: 'rgba(58, 123, 172, 0.5)',
- MARKER_BORDER: 'rgba(166, 189, 206, 0.5)',
+ MARKER_BACKGROUND: 'hsl(24deg, 58%, 70%, 0.15)',
+ MARKER_BORDER: 'hsl(24deg, 58%, 70%, 0.75)',
},
},
};
diff --git a/packages/ui/theme/extraShadows.ts b/packages/ui/theme/extraShadows.ts
index d4ce6801..470c2e4f 100644
--- a/packages/ui/theme/extraShadows.ts
+++ b/packages/ui/theme/extraShadows.ts
@@ -13,7 +13,7 @@ const lightShadows = {
...sharedShadows,
card: {
...sharedShadows.card,
- main: 'none',
+ main: '0.0145rem 0.029rem 0.174rem rgba(0,0,0,.017),0.0335rem 0.067rem 0.402rem rgba(0,0,0,.024),0.0625rem 0.125rem 0.75rem rgba(0,0,0,.03),0.1125rem 0.225rem 1.35rem rgba(0,0,0,.036),0.2085rem 0.417rem 2.502rem rgba(0,0,0,.043),0.5rem 1rem 6rem rgba(0,0,0,.06),0 0 0 0.0625rem rgba(0,0,0,.015)',
hovered:
'0 0.125rem 2rem rgba(27, 40, 50, 0.04),0 0.125rem 4rem rgba(27, 40, 50, 0.08),0 0 0 0.125rem rgba(27, 40, 50, 0.024);',
},
diff --git a/packages/ui/theme/index.ts b/packages/ui/theme/index.ts
index fe6e7782..14b2d119 100644
--- a/packages/ui/theme/index.ts
+++ b/packages/ui/theme/index.ts
@@ -54,21 +54,22 @@ export function getTheme(): Theme {
styleOverrides: (theme) => ({
':root': {
wordBreak: 'break-word',
+ fontVariant: 'tabular-nums',
// Ensure while swapping themes, we have no animations
':root[data-animations-enabled="false"] *': {
transition: 'none',
},
[theme.breakpoints.up('sm')]: {
- fontSize: 17,
+ fontSize: 16,
},
[theme.breakpoints.up('md')]: {
- fontSize: 18,
+ fontSize: 17,
},
[theme.breakpoints.up('lg')]: {
- fontSize: 19,
+ fontSize: 18,
},
[theme.breakpoints.up('xl')]: {
- fontSize: 20,
+ fontSize: 19,
},
},
}),
@@ -101,8 +102,8 @@ export function getTheme(): Theme {
{
props: { variant: 'code' },
style: ({ theme }) => ({
- background: theme.vars.palette.code.background,
- color: theme.vars.palette.code.text,
+ background: theme.vars.palette.background.paper,
+ color: theme.vars.palette.text.secondary,
}),
},
{
@@ -176,7 +177,7 @@ export function getTheme(): Theme {
color in theme.vars.palette
? theme.vars.palette[
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
- color as 'primary' | 'secondary' | 'warning' | 'info' | 'success'
+ color as 'primary' | 'secondary' | 'info' | 'success'
]
: null;
if (!paletteColor) {
@@ -199,18 +200,18 @@ export function getTheme(): Theme {
styleOverrides: {
root: ({ theme }) => ({
textTransform: 'initial',
- borderRadius: theme.spacing(6),
- padding: theme.spacing(1, 3),
+ borderRadius: theme.spacing(1),
+ padding: theme.spacing(0.75, 2),
}),
},
},
MuiCard: {
styleOverrides: {
root: ({ theme }) => ({
- background: theme.vars.palette.card.background,
- borderRadius: theme.spacing(6),
+ background: theme.vars.palette.background.paper,
+ borderRadius: theme.spacing(4),
borderColor: theme.vars.palette.card.border,
- borderWidth: 1,
+ borderWidth: 'thin',
borderStyle: 'solid',
boxShadow: theme.vars.extraShadows.card.main,
}),
@@ -220,13 +221,13 @@ export function getTheme(): Theme {
styleOverrides: {
tooltip: ({ theme }) => ({
...theme.typography.caption,
- background: theme.vars.palette.card.background,
- borderRadius: theme.spacing(6),
+ background: theme.vars.palette.background.paper,
+ borderRadius: theme.spacing(1.5),
borderColor: theme.vars.palette.card.border,
- borderWidth: 1,
+ borderWidth: 'thin',
borderStyle: 'solid',
- boxShadow: theme.shadows[2],
- padding: theme.spacing(0.5, 1.5),
+ boxShadow: theme.vars.extraShadows.card.main,
+ padding: theme.spacing(0.5, 1.25),
color: theme.vars.palette.text.primary,
}),
},
diff --git a/packages/ui/theme/palette.ts b/packages/ui/theme/palette.ts
index df03d008..36b96204 100644
--- a/packages/ui/theme/palette.ts
+++ b/packages/ui/theme/palette.ts
@@ -3,30 +3,21 @@ import { COLORS } from './color';
const lightPalette: PaletteOptions = {
primary: {
- main: COLORS.PRIMARY,
+ main: COLORS.LIGHT.PRIMARY,
},
secondary: {
- main: COLORS.SECONDARY,
+ main: COLORS.LIGHT.SECONDARY,
},
card: {
- background: COLORS.LIGHT.CARD_BACKGROUND,
border: COLORS.LIGHT.CARD_BORDER,
},
- code: {
- background: COLORS.LIGHT.CODE_BACKGROUND,
- text: COLORS.MUTED_TEXT,
- },
background: {
default: COLORS.LIGHT.DEFAULT_BACKGROUND,
paper: COLORS.LIGHT.PAPER_BACKGROUND,
},
- warning: { main: COLORS.LIGHT.YELLOW },
- active: {
- main: COLORS.LIGHT.YELLOW,
- },
text: {
primary: COLORS.LIGHT.TEXT,
- secondary: COLORS.MUTED_TEXT,
+ secondary: COLORS.LIGHT.MUTED_TEXT,
h1: COLORS.LIGHT.H1,
h2: COLORS.LIGHT.H2,
h3: COLORS.LIGHT.H3,
@@ -42,30 +33,21 @@ const lightPalette: PaletteOptions = {
const darkPalette: PaletteOptions = {
primary: {
- main: COLORS.PRIMARY,
+ main: COLORS.DARK.PRIMARY,
},
secondary: {
- main: COLORS.SECONDARY,
+ main: COLORS.DARK.SECONDARY,
},
card: {
- background: COLORS.DARK.CARD_BACKGROUND,
border: COLORS.DARK.CARD_BORDER,
},
- code: {
- background: COLORS.DARK.CODE_BACKGROUND,
- text: COLORS.MUTED_TEXT,
- },
background: {
default: COLORS.DARK.DEFAULT_BACKGROUND,
paper: COLORS.DARK.PAPER_BACKGROUND,
},
- warning: { main: COLORS.DARK.YELLOW },
- active: {
- main: COLORS.SECONDARY,
- },
text: {
primary: COLORS.DARK.TEXT,
- secondary: COLORS.MUTED_TEXT,
+ secondary: COLORS.DARK.MUTED_TEXT,
h1: COLORS.DARK.H1,
h2: COLORS.DARK.H2,
h3: COLORS.DARK.H3,
diff --git a/packages/ui/theme/shape.ts b/packages/ui/theme/shape.ts
index ec85cb4d..eec64256 100644
--- a/packages/ui/theme/shape.ts
+++ b/packages/ui/theme/shape.ts
@@ -6,8 +6,8 @@ import type { ThemeOptions } from '@mui/material';
export function getShape() {
const shape: ThemeOptions['shape'] = {
gridGap: 2,
- gridGapLarge: 3.35,
- gridItemDimension: 16.5,
+ gridGapLarge: 3.65,
+ gridItemDimension: 17.25,
gridItemSize: undefined, // set below
};
diff --git a/packages/ui/theme/typography.ts b/packages/ui/theme/typography.ts
index 2630dc53..c53252d4 100644
--- a/packages/ui/theme/typography.ts
+++ b/packages/ui/theme/typography.ts
@@ -27,6 +27,8 @@ export function getTypography(theme: Theme): TypographyOptions {
h1: {
fontSize: 34,
fontWeight: 700,
+ fontStretch: 'expanded',
+ fontVariant: 'all-small-caps',
},
h2: {
fontSize: 29.75,
@@ -38,15 +40,16 @@ export function getTypography(theme: Theme): TypographyOptions {
},
h4: {
fontSize: 21.25,
- fontWeight: 700,
+ fontWeight: 600,
},
h5: {
- fontSize: 19.125,
- fontWeight: 700,
+ fontSize: 17,
+ fontWeight: 600,
+ fontStretch: 'semi-expanded',
},
h6: {
- fontSize: 17,
- fontWeight: 700,
+ fontSize: 16,
+ fontWeight: 600,
},
body1: {
fontSize: 17,
@@ -55,20 +58,22 @@ export function getTypography(theme: Theme): TypographyOptions {
fontSize: 17,
},
overline: {
- fontSize: 12,
- textTransform: 'uppercase',
- fontWeight: 600,
+ fontSize: 13,
+ fontVariant: 'all-small-caps',
+ fontWeight: 500,
+ fontStretch: 'expanded',
},
caption: {
- fontSize: 13,
- fontWeight: 600,
+ fontSize: 14,
+ fontStretch: 'semi-expanded',
+ fontWeight: 500,
},
button: {
- fontSize: 17,
+ fontSize: 16,
fontWeight: 600,
},
code: {
- fontSize: 16,
+ fontSize: 15,
lineHeight: 1.875, // 30px
fontFamily:
'"Menlo","Consolas","Roboto Mono","Ubuntu Monospace","Noto Mono","Oxygen Mono","Liberation Mono",monospace,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"',
diff --git a/packages/ui/types/mui.d.ts b/packages/ui/types/mui.d.ts
index 03c1c6b0..9f22ed01 100644
--- a/packages/ui/types/mui.d.ts
+++ b/packages/ui/types/mui.d.ts
@@ -21,28 +21,19 @@ declare module '@mui/material/styles' {
};
type CardColors = {
- background: NonNullableColor;
border: NonNullableColor;
};
- type CodeColors = {
- background: NonNullableColor;
- text: NonNullableColor;
- };
type MapColors = {
markerBackground: NonNullableColor;
markerBorder: NonNullableColor;
};
interface Palette {
- active: Palette['primary'];
card: CardColors;
- code: CodeColors;
map: MapColors;
}
interface PaletteOptions {
- active: PaletteOptions['primary'];
card: CardColors;
- code: CodeColors;
map: MapColors;
}
interface Theme {