From bad92a9eaec19a850f16261f86365234d70bdc4f Mon Sep 17 00:00:00 2001 From: EthanHealy01 <80844253+EthanHealy01@users.noreply.github.com> Date: Fri, 17 Apr 2026 14:29:37 +0100 Subject: [PATCH] Chore/remove usage of mantine color scheme (#6108) Remove instances of `colorScheme === "dark" ?` in the app and rely on the theme.css' light and dark variables instead. --- frontend/.prettierignore | 2 + .../components/fileEditor/AddFileCard.tsx | 10 +- .../fileManager/EmptyFilesState.tsx | 16 +-- .../src/core/components/shared/LogoIcon.tsx | 14 ++ .../src/core/components/shared/TextInput.tsx | 11 +- .../src/core/components/shared/Wordmark.tsx | 20 +++ .../tools/FullscreenToolSurface.tsx | 24 +--- .../tools/convert/ConvertSettings.tsx | 17 +-- .../tools/convert/GroupedFormatDropdown.tsx | 26 +--- frontend/src/core/hooks/useLogoAssets.ts | 10 +- frontend/src/core/hooks/useLogoPath.ts | 25 ++-- frontend/src/core/pages/HomePage.tsx | 23 +--- frontend/src/core/pages/MobileScannerPage.tsx | 18 +-- frontend/src/core/styles/theme.css | 122 ++++++++++++++++++ .../components/BackendHealthIndicator.tsx | 23 +--- .../rightRail/RightRailFooterExtensions.tsx | 17 +-- .../routes/login/LoggedInState.tsx | 6 +- .../proprietary/routes/login/LoginHeader.tsx | 10 +- 18 files changed, 218 insertions(+), 176 deletions(-) create mode 100644 frontend/src/core/components/shared/LogoIcon.tsx create mode 100644 frontend/src/core/components/shared/Wordmark.tsx diff --git a/frontend/.prettierignore b/frontend/.prettierignore index 74f37221b6..3ad5fb2f0b 100644 --- a/frontend/.prettierignore +++ b/frontend/.prettierignore @@ -1,4 +1,6 @@ dist/ +# Tauri/Cargo build output (binary assets named *.js etc. confuse Prettier) +src-tauri/target/ node_modules/ public/vendor/ public/pdfjs*/ diff --git a/frontend/src/core/components/fileEditor/AddFileCard.tsx b/frontend/src/core/components/fileEditor/AddFileCard.tsx index 3fc2e97d89..7a566b032a 100644 --- a/frontend/src/core/components/fileEditor/AddFileCard.tsx +++ b/frontend/src/core/components/fileEditor/AddFileCard.tsx @@ -1,10 +1,10 @@ import React, { useRef, useState } from "react"; -import { Button, Group, useMantineColorScheme } from "@mantine/core"; +import { Button, Group } from "@mantine/core"; import { useTranslation } from "react-i18next"; import AddIcon from "@mui/icons-material/Add"; import { useFilesModalContext } from "@app/contexts/FilesModalContext"; import LocalIcon from "@app/components/shared/LocalIcon"; -import { useLogoAssets } from "@app/hooks/useLogoAssets"; +import { Wordmark } from "@app/components/shared/Wordmark"; import styles from "@app/components/fileEditor/FileEditor.module.css"; import { useFileActionTerminology } from "@app/hooks/useFileActionTerminology"; import { useFileActionIcons } from "@app/hooks/useFileActionIcons"; @@ -24,9 +24,7 @@ const AddFileCard = ({ const { t } = useTranslation(); const fileInputRef = useRef(null); const { openFilesModal } = useFilesModalContext(); - const { colorScheme } = useMantineColorScheme(); const [isUploadHover, setIsUploadHover] = useState(false); - const { wordmark } = useLogoAssets(); const terminology = useFileActionTerminology(); const icons = useFileActionIcons(); @@ -98,9 +96,9 @@ const AddFileCard = ({
{/* Stirling PDF Branding */} - Stirling PDF diff --git a/frontend/src/core/components/fileManager/EmptyFilesState.tsx b/frontend/src/core/components/fileManager/EmptyFilesState.tsx index f1a8922399..777b80085c 100644 --- a/frontend/src/core/components/fileManager/EmptyFilesState.tsx +++ b/frontend/src/core/components/fileManager/EmptyFilesState.tsx @@ -1,25 +1,17 @@ import React, { useState } from "react"; -import { - Button, - Group, - Text, - Stack, - useMantineColorScheme, -} from "@mantine/core"; +import { Button, Group, Text, Stack } from "@mantine/core"; import HistoryIcon from "@mui/icons-material/History"; import { useTranslation } from "react-i18next"; import { useFileManagerContext } from "@app/contexts/FileManagerContext"; import LocalIcon from "@app/components/shared/LocalIcon"; -import { useLogoAssets } from "@app/hooks/useLogoAssets"; +import { Wordmark } from "@app/components/shared/Wordmark"; import { useFileActionTerminology } from "@app/hooks/useFileActionTerminology"; import { useFileActionIcons } from "@app/hooks/useFileActionIcons"; const EmptyFilesState: React.FC = () => { const { t } = useTranslation(); - const { colorScheme } = useMantineColorScheme(); const { onLocalFileClick } = useFileManagerContext(); const [isUploadHover, setIsUploadHover] = useState(false); - const { wordmark } = useLogoAssets(); const terminology = useFileActionTerminology(); const icons = useFileActionIcons(); @@ -65,9 +57,9 @@ const EmptyFilesState: React.FC = () => { {/* Stirling PDF Logo */} - Stirling PDF diff --git a/frontend/src/core/components/shared/LogoIcon.tsx b/frontend/src/core/components/shared/LogoIcon.tsx new file mode 100644 index 0000000000..6723fc3c32 --- /dev/null +++ b/frontend/src/core/components/shared/LogoIcon.tsx @@ -0,0 +1,14 @@ +import React from "react"; +import { useMantineColorScheme } from "@mantine/core"; +import { useLogoPath } from "@app/hooks/useLogoPath"; + +interface LogoIconProps extends React.ImgHTMLAttributes { + alt?: string; +} + +export function LogoIcon({ alt = "", ...props }: LogoIconProps) { + const { colorScheme } = useMantineColorScheme(); + const logoPaths = useLogoPath(); + const src = colorScheme === "dark" ? logoPaths.dark : logoPaths.light; + return {alt}; +} diff --git a/frontend/src/core/components/shared/TextInput.tsx b/frontend/src/core/components/shared/TextInput.tsx index 53f592ebd3..12725f44e4 100644 --- a/frontend/src/core/components/shared/TextInput.tsx +++ b/frontend/src/core/components/shared/TextInput.tsx @@ -1,5 +1,4 @@ import React, { forwardRef } from "react"; -import { useMantineColorScheme } from "@mantine/core"; import LocalIcon from "@app/components/shared/LocalIcon"; import styles from "@app/components/shared/textInput/TextInput.module.css"; @@ -61,8 +60,6 @@ export const TextInput = forwardRef( }, ref, ) => { - const { colorScheme } = useMantineColorScheme(); - const handleClear = () => { if (onClear) { onClear(); @@ -79,7 +76,7 @@ export const TextInput = forwardRef( {icon && ( {icon} @@ -99,8 +96,8 @@ export const TextInput = forwardRef( aria-label={ariaLabel} onFocus={onFocus} style={{ - backgroundColor: colorScheme === "dark" ? "#4B525A" : "#FFFFFF", - color: colorScheme === "dark" ? "#FFFFFF" : "#6B7382", + backgroundColor: "var(--input-bg)", + color: "var(--search-text-and-icon-color)", paddingRight: shouldShowClearButton ? "40px" : "12px", paddingLeft: icon ? "40px" : "12px", }} @@ -111,7 +108,7 @@ export const TextInput = forwardRef( type="button" className={styles.clearButton} onClick={handleClear} - style={{ color: colorScheme === "dark" ? "#FFFFFF" : "#6B7382" }} + style={{ color: "var(--search-text-and-icon-color)" }} aria-label="Clear input" > diff --git a/frontend/src/core/components/shared/Wordmark.tsx b/frontend/src/core/components/shared/Wordmark.tsx new file mode 100644 index 0000000000..62185420c9 --- /dev/null +++ b/frontend/src/core/components/shared/Wordmark.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import { useMantineColorScheme } from "@mantine/core"; +import { useLogoAssets } from "@app/hooks/useLogoAssets"; + +interface WordmarkProps extends React.ImgHTMLAttributes { + alt?: string; + muted?: boolean; +} + +export function Wordmark({ alt = "", muted = false, ...props }: WordmarkProps) { + const { colorScheme } = useMantineColorScheme(); + const isDark = colorScheme === "dark"; + const { wordmark } = useLogoAssets(); + + // light: black text (standard) or grey text (muted) + // dark: white text for both variants + const src = isDark ? wordmark.white : muted ? wordmark.grey : wordmark.black; + + return {alt}; +} diff --git a/frontend/src/core/components/tools/FullscreenToolSurface.tsx b/frontend/src/core/components/tools/FullscreenToolSurface.tsx index d42e62895c..99683f3923 100644 --- a/frontend/src/core/components/tools/FullscreenToolSurface.tsx +++ b/frontend/src/core/components/tools/FullscreenToolSurface.tsx @@ -1,10 +1,5 @@ import { useState, useRef } from "react"; -import { - ActionIcon, - ScrollArea, - Switch, - useMantineColorScheme, -} from "@mantine/core"; +import { ActionIcon, ScrollArea, Switch } from "@mantine/core"; import DoubleArrowIcon from "@mui/icons-material/DoubleArrow"; import { useTranslation } from "react-i18next"; import ToolSearch from "@app/components/tools/toolPicker/ToolSearch"; @@ -12,8 +7,8 @@ import FullscreenToolList from "@app/components/tools/FullscreenToolList"; import { ToolRegistryEntry } from "@app/data/toolsTaxonomy"; import { ToolId } from "@app/types/toolId"; import { useFocusTrap } from "@app/hooks/useFocusTrap"; -import { useLogoPath } from "@app/hooks/useLogoPath"; -import { useLogoAssets } from "@app/hooks/useLogoAssets"; +import { LogoIcon } from "@app/components/shared/LogoIcon"; +import { Wordmark } from "@app/components/shared/Wordmark"; import { Tooltip } from "@app/components/shared/Tooltip"; import "@app/components/tools/ToolPanel.css"; import { ToolPanelGeometry } from "@app/hooks/tools/useToolPanelGeometry"; @@ -52,7 +47,6 @@ const FullscreenToolSurface = ({ geometry, }: FullscreenToolSurfaceProps) => { const { t } = useTranslation(); - const { colorScheme } = useMantineColorScheme(); const [isExiting, setIsExiting] = useState(false); const surfaceRef = useRef(null); const isRTL = @@ -62,9 +56,6 @@ const FullscreenToolSurface = ({ useFocusTrap(surfaceRef, !isExiting); const brandAltText = t("home.mobile.brandAlt", "Stirling PDF logo"); - const brandIconSrc = useLogoPath(); - const { wordmark } = useLogoAssets(); - const brandTextSrc = colorScheme === "dark" ? wordmark.white : wordmark.black; const handleExit = () => { const prefersReducedMotion = window.matchMedia( @@ -118,13 +109,8 @@ const FullscreenToolSurface = ({ >
- - + diff --git a/frontend/src/core/components/tools/convert/ConvertSettings.tsx b/frontend/src/core/components/tools/convert/ConvertSettings.tsx index c4f1959442..8b72e20ad5 100644 --- a/frontend/src/core/components/tools/convert/ConvertSettings.tsx +++ b/frontend/src/core/components/tools/convert/ConvertSettings.tsx @@ -6,7 +6,6 @@ import { Divider, UnstyledButton, useMantineTheme, - useMantineColorScheme, } from "@mantine/core"; import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; import { useTranslation } from "react-i18next"; @@ -64,7 +63,6 @@ const ConvertSettings = ({ }: ConvertSettingsProps) => { const { t } = useTranslation(); const theme = useMantineTheme(); - const { colorScheme } = useMantineColorScheme(); const { setSelectedFiles } = useFileSelection(); const { state, selectors } = useFileState(); const activeFiles = state.files.ids; @@ -339,14 +337,8 @@ const ConvertSettings = ({ padding: "0.5rem 0.75rem", border: `0.0625rem solid ${theme.colors.gray[4]}`, borderRadius: theme.radius.sm, - backgroundColor: - colorScheme === "dark" - ? theme.colors.dark[5] - : theme.colors.gray[1], - color: - colorScheme === "dark" - ? theme.colors.dark[2] - : theme.colors.gray[6], + backgroundColor: "var(--select-placeholder-bg)", + color: "var(--select-placeholder-text)", cursor: "not-allowed", }} > @@ -360,10 +352,7 @@ const ConvertSettings = ({ diff --git a/frontend/src/core/components/tools/convert/GroupedFormatDropdown.tsx b/frontend/src/core/components/tools/convert/GroupedFormatDropdown.tsx index 65ca64cffc..296a91056a 100644 --- a/frontend/src/core/components/tools/convert/GroupedFormatDropdown.tsx +++ b/frontend/src/core/components/tools/convert/GroupedFormatDropdown.tsx @@ -8,7 +8,6 @@ import { Popover, UnstyledButton, useMantineTheme, - useMantineColorScheme, } from "@mantine/core"; import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; import CloudOutlinedIcon from "@mui/icons-material/CloudOutlined"; @@ -47,7 +46,6 @@ const GroupedFormatDropdown = ({ }: GroupedFormatDropdownProps) => { const [dropdownOpened, setDropdownOpened] = useState(false); const theme = useMantineTheme(); - const { colorScheme } = useMantineColorScheme(); const groupedOptions = useMemo(() => { const groups: Record = {}; @@ -100,18 +98,12 @@ const GroupedFormatDropdown = ({ borderRadius: theme.radius.sm, backgroundColor: disabled ? theme.colors.gray[1] - : colorScheme === "dark" - ? theme.colors.dark[6] - : theme.white, + : "var(--dropdown-trigger-bg)", cursor: disabled ? "not-allowed" : "pointer", width: "100%", color: disabled - ? colorScheme === "dark" - ? theme.colors.dark[1] - : theme.colors.dark[7] - : colorScheme === "dark" - ? theme.colors.dark[0] - : theme.colors.dark[9], + ? "var(--dropdown-trigger-text-disabled)" + : "var(--dropdown-trigger-text)", }} > @@ -123,10 +115,7 @@ const GroupedFormatDropdown = ({ fontSize: "1rem", transform: dropdownOpened ? "rotate(180deg)" : "rotate(0deg)", transition: "transform 0.2s ease", - color: - colorScheme === "dark" - ? theme.colors.dark[2] - : theme.colors.gray[6], + color: "var(--dropdown-trigger-icon)", }} /> @@ -138,9 +127,8 @@ const GroupedFormatDropdown = ({ maxWidth: "90vw", maxHeight: "40vh", overflow: "auto", - backgroundColor: - colorScheme === "dark" ? theme.colors.dark[7] : theme.white, - border: `0.0625rem solid ${colorScheme === "dark" ? theme.colors.dark[4] : theme.colors.gray[4]}`, + backgroundColor: "var(--dropdown-panel-bg)", + border: `0.0625rem solid var(--dropdown-panel-border)`, }} > @@ -149,8 +137,8 @@ const GroupedFormatDropdown = ({ {groupName} diff --git a/frontend/src/core/hooks/useLogoAssets.ts b/frontend/src/core/hooks/useLogoAssets.ts index 521bc7673f..8fd0ad4ba5 100644 --- a/frontend/src/core/hooks/useLogoAssets.ts +++ b/frontend/src/core/hooks/useLogoAssets.ts @@ -15,16 +15,16 @@ export function useLogoAssets() { folder, folderPath, getAssetPath: (name: string) => `${folderPath}/${name}`, + wordmark: { + black: `${folderPath}/StirlingPDFLogoBlackText.svg`, + grey: `${folderPath}/StirlingPDFLogoGreyText.svg`, + white: `${folderPath}/StirlingPDFLogoWhiteText.svg`, + }, tooltipLogo: `${folderPath}/logo-tooltip.svg`, firstPage: `${folderPath}/Firstpage.png`, favicon: `${folderPath}/favicon.ico`, logo192: `${folderPath}/logo192.png`, logo512: `${folderPath}/logo512.png`, - wordmark: { - white: `${folderPath}/StirlingPDFLogoWhiteText.svg`, - black: `${folderPath}/StirlingPDFLogoBlackText.svg`, - grey: `${folderPath}/StirlingPDFLogoGreyText.svg`, - }, manifestHref: logoVariant === "classic" ? `${BASE_PATH}/manifest-classic.json` diff --git a/frontend/src/core/hooks/useLogoPath.ts b/frontend/src/core/hooks/useLogoPath.ts index b23be4de39..d1ccd9beec 100644 --- a/frontend/src/core/hooks/useLogoPath.ts +++ b/frontend/src/core/hooks/useLogoPath.ts @@ -1,22 +1,15 @@ import { useMemo } from "react"; -import { useMantineColorScheme } from "@mantine/core"; import { useLogoAssets } from "@app/hooks/useLogoAssets"; -/** - * Hook to get the correct logo path based on app config (logo style) and theme (light/dark) - * - * Logo styles: - * - classic: classic S logo stored in /classic-logo - * - modern: minimalist logo stored in /modern-logo - * - * @returns The path to the appropriate logo SVG file - */ -export function useLogoPath(): string { - const { colorScheme } = useMantineColorScheme(); +/** Theme-specific no-text logo SVG URLs under the active variant folder (`modern-logo` / `classic-logo`). */ +export function useLogoPath(): { dark: string; light: string } { const { folderPath } = useLogoAssets(); - return useMemo(() => { - const themeSuffix = colorScheme === "dark" ? "Dark" : "Light"; - return `${folderPath}/StirlingPDFLogoNoText${themeSuffix}.svg`; - }, [colorScheme, folderPath]); + return useMemo( + () => ({ + dark: `${folderPath}/StirlingPDFLogoNoTextDark.svg`, + light: `${folderPath}/StirlingPDFLogoNoTextLight.svg`, + }), + [folderPath], + ); } diff --git a/frontend/src/core/pages/HomePage.tsx b/frontend/src/core/pages/HomePage.tsx index f8515102a6..bba73d8243 100644 --- a/frontend/src/core/pages/HomePage.tsx +++ b/frontend/src/core/pages/HomePage.tsx @@ -1,14 +1,14 @@ import { useCallback, useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { useToolWorkflow } from "@app/contexts/ToolWorkflowContext"; -import { Group, useMantineColorScheme } from "@mantine/core"; +import { Group } from "@mantine/core"; import { useSidebarContext } from "@app/contexts/SidebarContext"; import { useDocumentMeta } from "@app/hooks/useDocumentMeta"; import { useBaseUrl } from "@app/hooks/useBaseUrl"; import { useIsMobile } from "@app/hooks/useIsMobile"; import { useAppConfig } from "@app/contexts/AppConfigContext"; -import { useLogoPath } from "@app/hooks/useLogoPath"; -import { useLogoAssets } from "@app/hooks/useLogoAssets"; +import { LogoIcon } from "@app/components/shared/LogoIcon"; +import { Wordmark } from "@app/components/shared/Wordmark"; import { useFileContext } from "@app/contexts/file/fileHooks"; import { useNavigationState, @@ -50,7 +50,6 @@ export default function HomePage() { } = useToolWorkflow(); const { openFilesModal } = useFilesModalContext(); - const { colorScheme } = useMantineColorScheme(); const { config } = useAppConfig(); const isMobile = useIsMobile(); const sliderRef = useRef(null); @@ -112,9 +111,6 @@ export default function HomePage() { )?.hideToolPanel ?? false; const brandAltText = t("home.mobile.brandAlt", "Stirling PDF logo"); - const brandIconSrc = useLogoPath(); - const { wordmark } = useLogoAssets(); - const brandTextSrc = colorScheme === "dark" ? wordmark.white : wordmark.black; const handleSelectMobileView = useCallback((view: MobileView) => { setActiveMobileView(view); @@ -241,17 +237,8 @@ export default function HomePage() {
- - {brandAltText} + +
( "choice", @@ -1024,16 +1019,11 @@ export default function MobileScannerPage() { }} > - {t("home.mobile.brandAlt", - Stirling PDF + diff --git a/frontend/src/core/styles/theme.css b/frontend/src/core/styles/theme.css index 02cd29ad12..6c7edfae26 100644 --- a/frontend/src/core/styles/theme.css +++ b/frontend/src/core/styles/theme.css @@ -391,6 +391,25 @@ /* Compare page label chip (light mode): slightly lighter than surrounding rows */ --compare-page-label-bg: var(--bg-muted); --compare-page-label-fg: var(--text-secondary); + + /* Status indicator dot ring shadow */ + --status-dot-ring: 0 0 0 2px rgba(0, 0, 0, 0.08); + + /* Input element styling */ + --input-bg: #ffffff; + + /* Select/dropdown placeholder state */ + --select-placeholder-bg: var(--mantine-color-gray-1); + --select-placeholder-text: var(--mantine-color-gray-6); + + /* Grouped format dropdown */ + --dropdown-trigger-bg: var(--mantine-color-white); + --dropdown-trigger-text: var(--mantine-color-dark-9); + --dropdown-trigger-text-disabled: var(--mantine-color-dark-7); + --dropdown-trigger-icon: var(--mantine-color-gray-6); + --dropdown-panel-bg: var(--mantine-color-white); + --dropdown-panel-border: var(--mantine-color-gray-4); + --dropdown-group-label: var(--mantine-color-gray-6); } /* Onboarding (light mode) */ @@ -681,6 +700,25 @@ /* Compare page label chip (dark mode): slightly darker than surrounding rows */ --compare-page-label-bg: #1f2329; --compare-page-label-fg: var(--text-secondary); + + /* Status indicator dot ring shadow (dark) */ + --status-dot-ring: 0 0 0 2px rgba(255, 255, 255, 0.18); + + /* Input element styling (dark) */ + --input-bg: #4b525a; + + /* Select/dropdown placeholder state (dark) */ + --select-placeholder-bg: var(--mantine-color-dark-5); + --select-placeholder-text: var(--mantine-color-dark-2); + + /* Grouped format dropdown (dark) */ + --dropdown-trigger-bg: var(--mantine-color-dark-6); + --dropdown-trigger-text: var(--mantine-color-dark-0); + --dropdown-trigger-text-disabled: var(--mantine-color-dark-1); + --dropdown-trigger-icon: var(--mantine-color-dark-2); + --dropdown-panel-bg: var(--mantine-color-dark-7); + --dropdown-panel-border: var(--mantine-color-dark-4); + --dropdown-group-label: var(--mantine-color-dark-2); } /* Dropzone drop state styling */ @@ -969,3 +1007,87 @@ [data-theme="dark"] { --shadow-color: rgba(0, 0, 0, 0.75); } + +/* Theme-aware image display utilities */ +/* Use .theme-img-light-only for images to show in light mode only */ +/* Use .theme-img-dark-only for images to show in dark mode only */ +.theme-img-light-only { + display: inline; +} +.theme-img-dark-only { + display: none; +} +[data-mantine-color-scheme="dark"] .theme-img-light-only { + display: none; +} +[data-mantine-color-scheme="dark"] .theme-img-dark-only { + display: inline; +} + +/* Modern logo icon */ +.logo-icon-modern__path1 { + fill: #acacac; + fill-opacity: 0.3; +} +.logo-icon-modern__path2 { + fill: #fc9999; + fill-opacity: 0.5; +} +[data-mantine-color-scheme="dark"] .logo-icon-modern__path1 { + fill: #e6e6e6; + fill-opacity: 0.4; +} +[data-mantine-color-scheme="dark"] .logo-icon-modern__path2 { + fill: #e6e6e6; + fill-opacity: 0.7; +} + +/* Classic logo icon — single path structure, colors change per theme */ +.logo-icon-classic__group { + opacity: 0.2; +} +.logo-icon-classic__body { + fill: #ff4b4b; +} +.logo-icon-classic__flap { + fill: #545454; +} +.logo-icon-classic__triangle { + fill: #d0dbdc; +} +.logo-icon-classic__s { + fill: white; +} +[data-mantine-color-scheme="dark"] .logo-icon-classic__group { + opacity: 1; +} +[data-mantine-color-scheme="dark"] .logo-icon-classic__body { + fill: white; +} +[data-mantine-color-scheme="dark"] .logo-icon-classic__flap { + fill: #d3d3d3; +} +[data-mantine-color-scheme="dark"] .logo-icon-classic__triangle { + fill: #d0dbdc; +} +[data-mantine-color-scheme="dark"] .logo-icon-classic__s { + fill: var(--mantine-color-body); +} + +/* Wordmark muted variant (used in empty/placeholder states) */ +/* Stirling text: 30% opacity in light mode, full opacity in dark */ +.wordmark__text--muted { + fill-opacity: 0.3; +} +[data-mantine-color-scheme="dark"] .wordmark__text--muted { + fill-opacity: 1; +} +/* PDF text: dimmed red in light mode, standard red in dark */ +.wordmark__pdf--muted { + fill: #d62626; + fill-opacity: 0.7; +} +[data-mantine-color-scheme="dark"] .wordmark__pdf--muted { + fill: #c56565; + fill-opacity: 1; +} diff --git a/frontend/src/desktop/components/BackendHealthIndicator.tsx b/frontend/src/desktop/components/BackendHealthIndicator.tsx index e494d4245e..a61a1e8726 100644 --- a/frontend/src/desktop/components/BackendHealthIndicator.tsx +++ b/frontend/src/desktop/components/BackendHealthIndicator.tsx @@ -1,12 +1,6 @@ import React, { useMemo, useCallback } from "react"; import { useTranslation } from "react-i18next"; -import { - Box, - Tooltip, - useMantineTheme, - useComputedColorScheme, - rem, -} from "@mantine/core"; +import { Box, Tooltip, useMantineTheme, rem } from "@mantine/core"; import { useBackendHealth } from "@app/hooks/useBackendHealth"; interface BackendHealthIndicatorProps { @@ -18,7 +12,6 @@ export const BackendHealthIndicator: React.FC = ({ }) => { const { t } = useTranslation(); const theme = useMantineTheme(); - const colorScheme = useComputedColorScheme("light"); const { status, isOnline, checkHealth } = useBackendHealth(); const label = useMemo(() => { @@ -60,14 +53,7 @@ export const BackendHealthIndicator: React.FC = ({ ); return ( - + = ({ height: rem(12), borderRadius: "50%", backgroundColor: dotColor, - boxShadow: - colorScheme === "dark" - ? "0 0 0 2px rgba(255, 255, 255, 0.18)" - : "0 0 0 2px rgba(0, 0, 0, 0.08)", + boxShadow: "var(--status-dot-ring)", cursor: "pointer", display: "inline-block", outline: "none", diff --git a/frontend/src/desktop/components/rightRail/RightRailFooterExtensions.tsx b/frontend/src/desktop/components/rightRail/RightRailFooterExtensions.tsx index d74a646082..96c4e106db 100644 --- a/frontend/src/desktop/components/rightRail/RightRailFooterExtensions.tsx +++ b/frontend/src/desktop/components/rightRail/RightRailFooterExtensions.tsx @@ -1,5 +1,5 @@ import { useState, useEffect, useMemo } from "react"; -import { Box, Tooltip, rem, useComputedColorScheme } from "@mantine/core"; +import { Box, Tooltip, rem } from "@mantine/core"; import { useTranslation } from "react-i18next"; import { connectionModeService, @@ -18,7 +18,6 @@ interface RightRailFooterExtensionsProps { function ConnectionStatusDot() { const { t } = useTranslation(); - const colorScheme = useComputedColorScheme("light"); const [connectionMode, setConnectionMode] = useState( null, ); @@ -84,14 +83,7 @@ function ConnectionStatusDot() { }, [connectionMode, selfHostedState, isOnline, t]); return ( - + { const timer = setTimeout(() => { @@ -47,8 +46,7 @@ export default function LoggedInState() { justifyContent: "center", }} > - Stirling PDF Logo diff --git a/frontend/src/proprietary/routes/login/LoginHeader.tsx b/frontend/src/proprietary/routes/login/LoginHeader.tsx index 1aa5d677e1..9d6f4d66d0 100644 --- a/frontend/src/proprietary/routes/login/LoginHeader.tsx +++ b/frontend/src/proprietary/routes/login/LoginHeader.tsx @@ -1,4 +1,4 @@ -import { useLogoAssets } from "@app/hooks/useLogoAssets"; +import { Wordmark } from "@app/components/shared/Wordmark"; interface LoginHeaderProps { title: string; @@ -11,18 +11,12 @@ export default function LoginHeader({ subtitle, centerOnly = false, }: LoginHeaderProps) { - const { wordmark } = useLogoAssets(); - return (
- Stirling PDF +
{title &&

{title}

} {subtitle &&

{subtitle}

}