Styling
Emotion, Material-UI theming, and styling patterns
The Odysee.ai frontend uses Emotion with Material-UI for styling, providing a powerful theming system and component customization.
Styling Approaches
import { styled } from '@mui/material/styles';
import { Box } from '@mui/material';
// Styled component
const StyledCard = styled(Box)(({ theme }) => ({
padding: theme.spacing(2),
backgroundColor: theme.palette.background.paper,
borderRadius: theme.shape.borderRadius,
boxShadow: theme.shadows[1],
}));
// Usage
export const Card = ({ children }) => {
return <StyledCard>{children}</StyledCard>;
};Use Emotion with Material-UI for component styling.
// theme/index.ts
import { createTheme } from "@mui/material/styles"
export const theme = createTheme({
palette: {
mode: "light",
primary: {
main: "#1976d2",
},
secondary: {
main: "#dc004e",
},
},
typography: {
fontFamily: "Inter, sans-serif",
},
})Configure theme tokens for consistent styling across the app.
import { Box } from '@mui/material';
export const Card = ({ children }) => {
return (
<Box
sx={{
p: 2,
bgcolor: 'background.paper',
borderRadius: 1,
boxShadow: 1,
}}
>
{children}
</Box>
);
};Use the sx prop for quick, one-off styles.
Theme Provider
Wrap your app with the theme provider:
import { ThemeProvider } from '@shared/ui';
import { theme } from '@/styles/theme';
export default function RootLayout({ children }) {
return (
<html>
<body>
<ThemeProvider theme={theme}>
{children}
</ThemeProvider>
</body>
</html>
);
}Theme Tokens
Access theme tokens in your components:
const StyledComponent = styled("div")(({ theme }) => ({
// Spacing
padding: theme.spacing(2), // 16px
// Colors
color: theme.palette.primary.main,
backgroundColor: theme.palette.background.paper,
// Typography
fontSize: theme.typography.h1.fontSize,
fontFamily: theme.typography.fontFamily,
// Breakpoints
[theme.breakpoints.up("md")]: {
padding: theme.spacing(4),
},
// Shadows
boxShadow: theme.shadows[2],
// Border radius
borderRadius: theme.shape.borderRadius,
}))Responsive Design
Use breakpoints for responsive styles:
<Box
sx={{
width: {
xs: '100%', // 0-600px
sm: '80%', // 600-900px
md: '60%', // 900-1200px
lg: '50%', // 1200-1536px
xl: '40%', // 1536px+
},
}}
>
Content
</Box>Dark Mode
Toggle between light and dark modes:
'use client';
import { useTheme } from '@mui/material/styles';
import { IconButton } from '@mui/material';
import { Brightness4, Brightness7 } from '@mui/icons-material';
export const ThemeToggle = () => {
const theme = useTheme();
const toggleTheme = () => {
// Toggle theme mode
};
return (
<IconButton onClick={toggleTheme}>
{theme.palette.mode === 'dark' ? <Brightness7 /> : <Brightness4 />}
</IconButton>
);
};Best Practices
Next: Learn about Authentication.