diff --git a/echo/frontend/src/components/form/MarkdownWYSIWYG/styles.css b/echo/frontend/src/components/form/MarkdownWYSIWYG/styles.css index 1bc0511d..4aaf3c56 100644 --- a/echo/frontend/src/components/form/MarkdownWYSIWYG/styles.css +++ b/echo/frontend/src/components/form/MarkdownWYSIWYG/styles.css @@ -384,7 +384,7 @@ --basePageBg: var(--app-background, #F6F4F1); --baseBase: var(--slate-1); --baseBgSubtle: var(--slate-2); - --baseBg: var(--slate-3); + --baseBg: var(--mantine-color-primary-2); --baseBgHover: var(--slate-4); --baseBgActive: var(--slate-5); --baseLine: var(--slate-6); diff --git a/echo/frontend/src/components/participant/refine/RefineSelection.tsx b/echo/frontend/src/components/participant/refine/RefineSelection.tsx index 7f583299..c76bfa5d 100644 --- a/echo/frontend/src/components/participant/refine/RefineSelection.tsx +++ b/echo/frontend/src/components/participant/refine/RefineSelection.tsx @@ -69,13 +69,13 @@ export const RefineSelection = () => { > - + <Title order={3} fw={600}> <Trans id="participant.refine.make.concrete"> Make it concrete </Trans> - + Take some time to create an outcome that makes your contribution concrete. @@ -123,11 +123,11 @@ export const RefineSelection = () => { > - + <Title order={3} fw={600}> <Trans id="participant.refine.go.deeper">Go deeper</Trans> - + Get an immediate reply from Dembrane to help you deepen the conversation. diff --git a/echo/frontend/src/components/participant/verify/VerifySelection.tsx b/echo/frontend/src/components/participant/verify/VerifySelection.tsx index 535147d3..893f7665 100644 --- a/echo/frontend/src/components/participant/verify/VerifySelection.tsx +++ b/echo/frontend/src/components/participant/verify/VerifySelection.tsx @@ -197,7 +197,7 @@ export const VerifySelection = () => { > {/* Main content */} - + <Title order={3} className="font-semibold"> <Trans id="participant.concrete.selection.title"> What do you want to make concrete? </Trans> diff --git a/echo/frontend/src/fonts/DMSans-Light.woff2 b/echo/frontend/src/fonts/DMSans-Light.woff2 new file mode 100644 index 00000000..10f42487 Binary files /dev/null and b/echo/frontend/src/fonts/DMSans-Light.woff2 differ diff --git a/echo/frontend/src/fonts/DMSans-Regular.woff2 b/echo/frontend/src/fonts/DMSans-Regular.woff2 deleted file mode 100644 index 38a1e4dd..00000000 Binary files a/echo/frontend/src/fonts/DMSans-Regular.woff2 and /dev/null differ diff --git a/echo/frontend/src/fonts/dm-sans.css b/echo/frontend/src/fonts/dm-sans.css index 69a4ff76..f59d92ec 100644 --- a/echo/frontend/src/fonts/dm-sans.css +++ b/echo/frontend/src/fonts/dm-sans.css @@ -1,6 +1,6 @@ @font-face { font-family: 'DM Sans Variable'; - src: url('./DMSans-Regular.woff2') format('woff2'); + src: url('./DMSans-Light.woff2') format('woff2'); font-weight: 100 1000; font-style: normal; font-display: swap; diff --git a/echo/frontend/src/hooks/useAppPreferences.tsx b/echo/frontend/src/hooks/useAppPreferences.tsx index 49e0541a..94524c2d 100644 --- a/echo/frontend/src/hooks/useAppPreferences.tsx +++ b/echo/frontend/src/hooks/useAppPreferences.tsx @@ -91,6 +91,7 @@ export const AppPreferencesProvider = ({ // Apply font and linked color scheme to document useEffect(() => { const isDmSans = preferences.fontFamily === "dm-sans"; + const root = document.documentElement; // Font const fontValue = isDmSans @@ -108,32 +109,141 @@ export const AppPreferencesProvider = ({ const backgroundColor = isDmSans ? "#F6F4F1" : "#FFFFFF"; const textColor = isDmSans ? "#2D2D2C" : "#000000"; - // Set our custom CSS variables - document.documentElement.style.setProperty("--app-font-family", fontValue); - document.documentElement.style.setProperty( - "--app-background", - backgroundColor, - ); - document.documentElement.style.setProperty("--app-text", textColor); + const baseFontSize = isDmSans ? "18px" : "16px"; - // Override Mantine's CSS variables so components using them update dynamically - document.documentElement.style.setProperty( - "--mantine-color-white", - backgroundColor, + // Space Grotesk: Original Mantine-based sizes with medium weight + const typography = isDmSans + ? { + fontSizeLg: "1.125rem", + fontSizeMd: "1rem", + fontSizeSm: "0.875rem", + fontSizeXl: "1.333rem", + // Font sizes + fontSizeXs: "0.75rem", + h1LineHeight: "1.2", + // Heading sizes + h1Size: "2.778rem", + h2LineHeight: "1.25", + h2Size: "2.369rem", + h3LineHeight: "1.3", + h3Size: "1.777rem", + h4LineHeight: "1.4", + h4Size: "1.333rem", + h5LineHeight: "1.5", + h5Size: "1rem", + h6LineHeight: "1.5", + h6Size: "0.875rem", + // Heading font weight + headingFontWeight: "300", + lineHeightLg: "1.6", + lineHeightMd: "1.55", + lineHeightSm: "1.45", + lineHeightXl: "1.65", + // Line heights + lineHeightXs: "1.4", + } + : { + fontSizeLg: "1.125rem", + fontSizeMd: "1rem", + fontSizeSm: "0.875rem", + fontSizeXl: "1.25rem", + // Font sizes (original Mantine defaults) + fontSizeXs: "0.75rem", + h1LineHeight: "1.3", + // Heading sizes (original Mantine defaults with --mantine-scale) + h1Size: "2.125rem", + h2LineHeight: "1.35", + h2Size: "1.875rem", + h3LineHeight: "1.4", + h3Size: "1.5rem", + h4LineHeight: "1.45", + h4Size: "1.25rem", + h5LineHeight: "1.5", + h5Size: "1rem", + h6LineHeight: "1.5", + h6Size: "0.875rem", + // Heading font weight + headingFontWeight: "500", + lineHeightLg: "1.6", + lineHeightMd: "1.55", + lineHeightSm: "1.45", + lineHeightXl: "1.65", + // Line heights + lineHeightXs: "1.4", + }; + + // Icon sizes: DM Sans uses larger icons to match the bolder typography + const homeIconSize = isDmSans ? "40px" : "30px"; + + // Set base font size + root.style.setProperty("--app-base-font-size", baseFontSize); + + // Set font family + root.style.setProperty("--app-font-family", fontValue); + + // Set colors + root.style.setProperty("--app-background", backgroundColor); + root.style.setProperty("--app-text", textColor); + + // Set icon sizes + root.style.setProperty("--app-home-icon-size", homeIconSize); + + // Set typography - font sizes + root.style.setProperty("--app-font-size-xs", typography.fontSizeXs); + root.style.setProperty("--app-font-size-sm", typography.fontSizeSm); + root.style.setProperty("--app-font-size-md", typography.fontSizeMd); + root.style.setProperty("--app-font-size-lg", typography.fontSizeLg); + root.style.setProperty("--app-font-size-xl", typography.fontSizeXl); + + // Set typography - line heights + root.style.setProperty("--app-line-height-xs", typography.lineHeightXs); + root.style.setProperty("--app-line-height-sm", typography.lineHeightSm); + root.style.setProperty("--app-line-height-md", typography.lineHeightMd); + root.style.setProperty("--app-line-height-lg", typography.lineHeightLg); + root.style.setProperty("--app-line-height-xl", typography.lineHeightXl); + + // Set typography - heading sizes + root.style.setProperty( + "--app-heading-font-weight", + typography.headingFontWeight, + ); + root.style.setProperty("--app-heading-h1-size", typography.h1Size); + root.style.setProperty( + "--app-heading-h1-line-height", + typography.h1LineHeight, + ); + root.style.setProperty("--app-heading-h2-size", typography.h2Size); + root.style.setProperty( + "--app-heading-h2-line-height", + typography.h2LineHeight, + ); + root.style.setProperty("--app-heading-h3-size", typography.h3Size); + root.style.setProperty( + "--app-heading-h3-line-height", + typography.h3LineHeight, ); - document.documentElement.style.setProperty( - "--mantine-color-black", - textColor, + root.style.setProperty("--app-heading-h4-size", typography.h4Size); + root.style.setProperty( + "--app-heading-h4-line-height", + typography.h4LineHeight, ); - document.documentElement.style.setProperty( - "--mantine-color-text", - textColor, + root.style.setProperty("--app-heading-h5-size", typography.h5Size); + root.style.setProperty( + "--app-heading-h5-line-height", + typography.h5LineHeight, ); - document.documentElement.style.setProperty( - "--mantine-color-body", - backgroundColor, + root.style.setProperty("--app-heading-h6-size", typography.h6Size); + root.style.setProperty( + "--app-heading-h6-line-height", + typography.h6LineHeight, ); + // Override Mantine's CSS variables so components using them update dynamically + root.style.setProperty("--mantine-color-white", backgroundColor); + root.style.setProperty("--mantine-color-black", textColor); + root.style.setProperty("--mantine-color-text", textColor); + root.style.setProperty("--mantine-color-body", backgroundColor); + // Apply to body document.body.style.fontFamily = fontValue; document.body.style.backgroundColor = backgroundColor; @@ -141,16 +251,10 @@ export const AppPreferencesProvider = ({ document.body.style.fontFeatureSettings = fontFeatureSettings; // Set CSS variable for font feature settings - document.documentElement.style.setProperty( - "--app-font-feature-settings", - fontFeatureSettings, - ); + root.style.setProperty("--app-font-feature-settings", fontFeatureSettings); // Set data attribute for potential CSS selectors - document.documentElement.setAttribute( - "data-theme", - isDmSans ? "parchment" : "clean", - ); + root.setAttribute("data-theme", isDmSans ? "parchment" : "clean"); }, [preferences.fontFamily]); return ( diff --git a/echo/frontend/src/icons/index.tsx b/echo/frontend/src/icons/index.tsx index a84b4844..3138473c 100644 --- a/echo/frontend/src/icons/index.tsx +++ b/echo/frontend/src/icons/index.tsx @@ -49,6 +49,7 @@ const Plus: React.FC<React.SVGProps<SVGSVGElement>> = (props) => ( </svg> ); +import { HouseIcon } from "@phosphor-icons/react"; import type { SVGProps } from "react"; import refresh from "../assets/refresh.png"; @@ -99,21 +100,20 @@ const Diamond = ({ ); }; -const Home = (props: SVGProps<SVGSVGElement>) => ( - <svg - xmlns="http://www.w3.org/2000/svg" - width={30} - height={30} - fill="none" - role="graphics-symbol img" - {...props} - > - <path - fill="currentColor" - d="M12.5 25v-7.5h5V25h6.25V15h3.75L15 3.75 2.5 15h3.75v10z" +// Home icon uses Phosphor HouseIcon, size controlled by CSS variable for theme +const Home = () => { + // Import is at top of file + return ( + <HouseIcon + size="var(--app-home-icon-size, 30)" + color="currentColor" + style={{ + height: "var(--app-home-icon-size, 30px)", + width: "var(--app-home-icon-size, 30px)", + }} /> - </svg> -); + ); +}; const Calendar = (props: SVGProps<SVGSVGElement>) => ( <svg diff --git a/echo/frontend/src/index.css b/echo/frontend/src/index.css index 7249a28b..7d3e68bf 100644 --- a/echo/frontend/src/index.css +++ b/echo/frontend/src/index.css @@ -17,17 +17,64 @@ /* Space Grotesk (default) → White + Black */ /* DM Sans → Parchment + Graphite */ :root { + /* DM Sans (default) uses 18px, Space Grotesk uses 16px */ + /* Dynamically updated by useAppPreferences based on font selection */ + --app-base-font-size: 16px; + + /* Theme colors */ --app-background: #F6F4F1; --app-text: #2D2D2C; --app-scrollbar-thumb: #8b8b8b; --app-scrollbar-thumb-hover: #636363; + + /* Font settings */ --app-font-family: 'DM Sans Variable', sans-serif; --app-font-feature-settings: 'ss01' on, 'ss02' on, 'ss03' on, 'ss04' on, 'ss05' on, 'ss06' on, 'ss08' on; + + /* Typography - Font sizes (DM Sans defaults, 1.333 ratio scale) */ + --app-font-size-xs: 0.75rem; + --app-font-size-sm: 0.875rem; + --app-font-size-md: 1rem; + --app-font-size-lg: 1.125rem; + --app-font-size-xl: 1.333rem; + + /* Typography - Line heights */ + --app-line-height-xs: 1.4; + --app-line-height-sm: 1.45; + --app-line-height-md: 1.55; + --app-line-height-lg: 1.6; + --app-line-height-xl: 1.65; + + /* Typography - Heading sizes (DM Sans defaults, 1.333 ratio scale) */ + --app-heading-font-weight: 300; + --app-heading-h1-size: 2.778rem; + --app-heading-h1-line-height: 1.2; + --app-heading-h2-size: 2.369rem; + --app-heading-h2-line-height: 1.25; + --app-heading-h3-size: 1.777rem; + --app-heading-h3-line-height: 1.3; + --app-heading-h4-size: 1.333rem; + --app-heading-h4-line-height: 1.4; + --app-heading-h5-size: 1rem; + --app-heading-h5-line-height: 1.5; + --app-heading-h6-size: 0.875rem; + --app-heading-h6-line-height: 1.5; + + /* Icon sizes */ + /* DM Sans (default) uses 50px, Space Grotesk uses 30px */ + --app-home-icon-size: 40px; + + /* Scrollbar */ --scrollbar-track: var(--app-background); --scrollbar-thumb: var(--app-scrollbar-thumb); --scrollbar-thumb-hover: var(--app-scrollbar-thumb-hover); } +/* Set base font size on html element for rem calculations */ +html { + font-size: var(--app-base-font-size); +} + body { background-color: var(--app-background); color: var(--app-text); diff --git a/echo/frontend/src/routes/participant/ParticipantPostConversation.tsx b/echo/frontend/src/routes/participant/ParticipantPostConversation.tsx index ddaf1a69..c01aefe9 100644 --- a/echo/frontend/src/routes/participant/ParticipantPostConversation.tsx +++ b/echo/frontend/src/routes/participant/ParticipantPostConversation.tsx @@ -119,7 +119,7 @@ export const ParticipantPostConversation = () => { return ( <div - className="container mx-auto h-full max-w-2xl" + className="container mx-auto max-w-2xl" {...testId("portal-finish-container")} > <Stack className="mt-[64px] px-4 py-8"> diff --git a/echo/frontend/src/routes/project/ProjectsHome.tsx b/echo/frontend/src/routes/project/ProjectsHome.tsx index 677bbfa0..e260c37a 100644 --- a/echo/frontend/src/routes/project/ProjectsHome.tsx +++ b/echo/frontend/src/routes/project/ProjectsHome.tsx @@ -119,7 +119,7 @@ export const ProjectsHomeRoute = () => { label: ( <Group> <Icons.Home /> - <Title order={1}> + <Title order={2}> <Trans>Home</Trans> @@ -142,7 +142,7 @@ export const ProjectsHomeRoute = () => { - + <Title order={3}> <Trans>Projects</Trans> diff --git a/echo/frontend/src/routes/settings/UserSettingsRoute.tsx b/echo/frontend/src/routes/settings/UserSettingsRoute.tsx index fe05a198..118e93a2 100644 --- a/echo/frontend/src/routes/settings/UserSettingsRoute.tsx +++ b/echo/frontend/src/routes/settings/UserSettingsRoute.tsx @@ -35,7 +35,7 @@ export const UserSettingsRoute = () => { > - + <Title order={2}> <Trans>Settings</Trans> diff --git a/echo/frontend/src/theme.tsx b/echo/frontend/src/theme.tsx index bdef6068..5068dadf 100644 --- a/echo/frontend/src/theme.tsx +++ b/echo/frontend/src/theme.tsx @@ -315,36 +315,52 @@ export const theme = createTheme({ }, }, fontFamily: "var(--app-font-family, 'DM Sans Variable', sans-serif)", + // Space Grotesk: Original Mantine-based sizes + // Variables are set dynamically by useAppPreferences + fontSizes: { + lg: "var(--app-font-size-lg)", + md: "var(--app-font-size-md)", + sm: "var(--app-font-size-sm)", + xl: "var(--app-font-size-xl)", + xs: "var(--app-font-size-xs)", + }, headings: { fontFamily: "var(--app-font-family, 'DM Sans Variable', sans-serif)", - fontWeight: "500", + fontWeight: "var(--app-heading-font-weight, 300)", sizes: { h1: { - fontSize: "calc(2.125rem * var(--mantine-scale))", - lineHeight: "1.3", + fontSize: "var(--app-heading-h1-size)", + lineHeight: "var(--app-heading-h1-line-height)", }, h2: { - fontSize: "calc(1.875rem * var(--mantine-scale))", - lineHeight: "1.35", + fontSize: "var(--app-heading-h2-size)", + lineHeight: "var(--app-heading-h2-line-height)", }, h3: { - fontSize: "calc(1.5rem * var(--mantine-scale))", - lineHeight: "1.4", + fontSize: "var(--app-heading-h3-size)", + lineHeight: "var(--app-heading-h3-line-height)", }, h4: { - fontSize: "calc(1.25rem * var(--mantine-scale))", - lineHeight: "1.45", + fontSize: "var(--app-heading-h4-size)", + lineHeight: "var(--app-heading-h4-line-height)", }, h5: { - fontSize: "calc(1rem * var(--mantine-scale))", - lineHeight: "1.5", + fontSize: "var(--app-heading-h5-size)", + lineHeight: "var(--app-heading-h5-line-height)", }, h6: { - fontSize: "calc(0.875rem * var(--mantine-scale))", - lineHeight: "1.5", + fontSize: "var(--app-heading-h6-size)", + lineHeight: "var(--app-heading-h6-line-height)", }, }, }, + lineHeights: { + lg: "var(--app-line-height-lg)", + md: "var(--app-line-height-md)", + sm: "var(--app-line-height-sm)", + xl: "var(--app-line-height-xl)", + xs: "var(--app-line-height-xs)", + }, primaryColor: "primary", // Updated to match Tailwind radius radius: {