✨ feat: add light theme

can be accessed using the theme query param
(eg `?theme=system`)
This commit is contained in:
2025-06-16 17:45:40 +02:00
committed by Michele Tartari
parent ca98e66206
commit e0c7314313
4 changed files with 111 additions and 28 deletions
+43 -6
View File
@@ -7,28 +7,52 @@ import { EmailIconLink, GitHubIconLink, LinkedInIconLink } from 'components/atom
const Hero = (props: { scrollTarget?: React.ForwardedRef<HTMLSelectElement> }) => { const Hero = (props: { scrollTarget?: React.ForwardedRef<HTMLSelectElement> }) => {
return ( return (
<Box <Box
sx={{ sx={theme => ({
position: 'relative', position: 'relative',
minHeight: '100vh', minHeight: '100vh',
boxShadow: '0 0.25em 0.5em 0 rgba(0, 0, 0, 0.25)', boxShadow: '0 0.25em 0.5em 0 rgba(0, 0, 0, 0.25)',
backgroundImage: 'url("images/banner-blur.webp")', backgroundImage: 'url("images/banner.webp")',
backgroundPosition: 'center center', backgroundPosition: 'center center',
backgroundAttachment: { xs: 'scroll !important', md: 'fixed' }, backgroundAttachment: { xs: 'scroll !important', md: 'fixed' },
backgroundSize: 'cover', backgroundSize: 'cover',
display: 'flex', display: 'flex',
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
wrap: 'wrap', wrap: 'wrap',
}}>
...(theme.palette.mode === 'dark' && {
backgroundImage: 'url("images/banner-blur.webp")',
}),
...(theme.palette.mode === 'light' && {
backgroundImage: 'url("images/banner.webp")',
'&::before': {
content: '""',
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '100%',
zIndex: 0,
backgroundImage: 'inherit',
backgroundPosition: 'center center',
backgroundAttachment: 'inherit',
backgroundSize: 'cover',
filter: 'blur(5px)',
},
}),
})}>
<Box <Box
color="white"
sx={theme => ({ sx={theme => ({
display: 'flex', display: 'flex',
justifyContent: 'center', justifyContent: 'center',
alignItems: 'center', alignItems: 'center',
gap: '3em', gap: '3em',
zIndex: 1,
[theme.breakpoints.down('md')]: { [theme.breakpoints.down('md')]: {
flexDirection: 'column', flexDirection: 'column',
@@ -50,13 +74,19 @@ const Hero = (props: { scrollTarget?: React.ForwardedRef<HTMLSelectElement> }) =
variant="h6" variant="h6"
color="text.secondary" color="text.secondary"
sx={{ sx={{
color: t => (t.palette.mode === 'light' ? 'inherit' : 'text.secondary'),
margin: '0.5em 0 0 0', margin: '0.5em 0 0 0',
pt: 1, pt: 1,
}}> }}>
Discover some of my works below. Discover some of my works below.
<br /> Send a message to get in touch. <br /> Send a message to get in touch.
</Typography> </Typography>
<Stack direction="row" gap={2} mt={2} justifyContent={{ xs: 'center', md: 'end' }} color="text.secondary"> <Stack
direction="row"
gap={2}
mt={2}
justifyContent={{ xs: 'center', md: 'end' }}
color={t => (t.palette.mode === 'light' ? 'inherit' : 'text.secondary')}>
<LinkedInIconLink fontSize="large" href="https://www.linkedin.com/in/m-tartari/" /> <LinkedInIconLink fontSize="large" href="https://www.linkedin.com/in/m-tartari/" />
<GitHubIconLink fontSize="large" href="https://www.github.com/m-tartari/" /> <GitHubIconLink fontSize="large" href="https://www.github.com/m-tartari/" />
<EmailIconLink fontSize="large" href="mailto:info@m-tartari.eu" /> <EmailIconLink fontSize="large" href="mailto:info@m-tartari.eu" />
@@ -78,7 +108,14 @@ const Hero = (props: { scrollTarget?: React.ForwardedRef<HTMLSelectElement> }) =
<IconButton <IconButton
size="large" size="large"
onClick={() => (props.scrollTarget as React.RefObject<HTMLElement | null>).current?.scrollIntoView()} onClick={() => (props.scrollTarget as React.RefObject<HTMLElement | null>).current?.scrollIntoView()}
sx={{ position: 'absolute', p: 1, bottom: 2, left: '50%', transform: 'translate(-50%, 0)' }}> sx={{
position: 'absolute',
p: 1,
bottom: 2,
left: '50%',
transform: 'translate(-50%, 0)',
color: t => (t.palette.mode === 'light' ? 'white' : 'text.primary'),
}}>
<ExpandMore fontSize="large" /> <ExpandMore fontSize="large" />
</IconButton> </IconButton>
)} )}
+30 -10
View File
@@ -26,7 +26,9 @@ const AppBarButton = styled(Button<typeof RouterLink>)(({ theme }) => ({
color: 'inherit', color: 'inherit',
':hover': { ':hover': {
backgroundColor: 'transparent', backgroundColor: 'transparent',
...(theme.palette.mode === 'dark' && {
color: theme.palette.primary.main, color: theme.palette.primary.main,
}),
}, },
})) }))
const DrawerButton = styled(ListItemButton<typeof RouterLink>)(({ theme }) => ({ const DrawerButton = styled(ListItemButton<typeof RouterLink>)(({ theme }) => ({
@@ -57,7 +59,13 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
} }
const drawer = ( const drawer = (
<Box onClick={handleDrawerToggle} sx={{ textAlign: 'center' }}> <Box
onClick={handleDrawerToggle}
sx={theme => ({
height: '100%',
textAlign: 'center',
...(theme.palette.mode === 'light' && { backgroundColor: 'background.default' }),
})}>
<Typography variant="h6" sx={{ my: 2 }}> <Typography variant="h6" sx={{ my: 2 }}>
Michele Tartari Michele Tartari
</Typography> </Typography>
@@ -90,10 +98,14 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
return ( return (
<> <>
<AppBar <AppBar
elevation={0} elevation={theme.palette.mode === 'light' ? 1 : 0}
{...props} {...props}
sx={{ sx={{
backgroundColor: trigger ? (theme.palette.mode === 'dark' ? 'background.paper' : undefined) : 'transparent', backgroundColor: trigger ? 'background.paper' : 'transparent',
...(theme.palette.mode === 'light' && {
backgroundColor: 'hsla(0, 0%, 100%, 0.75)',
backdropFilter: 'blur(8px)',
}),
...props.sx, ...props.sx,
}}> }}>
<Toolbar <Toolbar
@@ -122,17 +134,25 @@ const CustomToolbar: React.FC<CustomToolbarProps> = ({ drawerWidth = 240, window
mr: 'auto', mr: 'auto',
}, },
})}> })}>
<Typography variant="h6"> Michele Tartari</Typography> <Typography variant="h6" color="text.primary">
Michele Tartari
</Typography>
</AppBarButton> </AppBarButton>
<Stack component="div" direction="row" spacing={2} sx={{ display: { xs: 'none', md: 'flex' } }}> <Stack component="div" direction="row" spacing={2} sx={{ display: { xs: 'none', md: 'flex' } }}>
<AppBarButton component={RouterLink} to="/"> <AppBarButton component={RouterLink} to="/" disableRipple>
<Typography variant="h6">Home</Typography> <Typography color={theme.palette.mode === 'dark' ? 'inherit' : 'text.secondary'} variant="h6">
Home
</Typography>
</AppBarButton> </AppBarButton>
<AppBarButton component={RouterLink} to="/projects"> <AppBarButton component={RouterLink} to="/projects" disableRipple>
<Typography variant="h6">Projects</Typography> <Typography color={theme.palette.mode === 'dark' ? 'inherit' : 'text.secondary'} variant="h6">
Projects
</Typography>
</AppBarButton> </AppBarButton>
<AppBarButton component={RouterLink} to="/curriculum"> <AppBarButton component={RouterLink} to="/curriculum" disableRipple>
<Typography variant="h6">Curriculum</Typography> <Typography color={theme.palette.mode === 'dark' ? 'inherit' : 'text.secondary'} variant="h6">
Curriculum
</Typography>
</AppBarButton> </AppBarButton>
<Button <Button
component={RouterLink} component={RouterLink}
+8 -1
View File
@@ -18,11 +18,18 @@ import theme from 'style/theme.js'
import App from './App.js' import App from './App.js'
import './index.css' import './index.css'
const themeParam = new URLSearchParams(window.location.search).get('theme')
let mode: 'light' | 'dark' | 'system' = 'dark'
if (themeParam === 'light' || themeParam === 'dark' || themeParam === 'system') {
mode = themeParam
}
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement) const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render( root.render(
<React.StrictMode> <React.StrictMode>
<AnalyticsProvider instance={analytics}> <AnalyticsProvider instance={analytics}>
<ThemeProvider theme={theme}> <ThemeProvider theme={theme} defaultMode={mode}>
<CssBaseline /> <CssBaseline />
<App /> <App />
</ThemeProvider> </ThemeProvider>
+22 -3
View File
@@ -24,19 +24,38 @@ let theme = createTheme({
fontWeight: 700, fontWeight: 700,
}, },
}, },
colorSchemes: {
dark: {
palette: { palette: {
mode: 'dark',
primary: { primary: {
main: '#e44c65', main: '#e44c65', // Rouge Red (similar)
// main:'#df4661', // Pantone PMS 198 C
}, },
secondary: { secondary: {
main: '#3f51b5', main: '#3f51b5', // Early Spring Night (similar)
// main: '#3a5dae', // Pantone 7455 C Color
}, },
background: { background: {
default: '#101018', default: '#101018',
paper: '#1b1d27', paper: '#1b1d27',
}, },
}, },
},
light: {
palette: {
primary: {
main: '#AC1D1B', // Casual Red
// main: '#AF231C' // Pantone 2350 C
// main: '#AB2328' // Pantone 7621 C
},
secondary: {
main: '#006269', // Pantone 7715 C
},
background: { default: '#fafafa', paper: '#eeeeee' }, // Light background
text: { secondary: '#666' }, // Dark text for readability
},
},
},
}) })
theme = responsiveFontSizes(theme) theme = responsiveFontSizes(theme)