design: upgrade typography, shadows, spacing, empty states, 404 page, focus rings, noise overlay
This commit is contained in:
@@ -3,6 +3,7 @@ import { AppProviders } from '@/app/providers/AppProviders'
|
||||
import { AppRoutes } from '@/app/routes'
|
||||
import { CartSnackbar } from '@/shared/ui/CartSnackbar'
|
||||
import { ErrorBoundary } from '@/shared/ui/ErrorBoundary'
|
||||
import { NoiseOverlay } from '@/shared/ui/NoiseOverlay'
|
||||
|
||||
export function App() {
|
||||
return (
|
||||
@@ -12,6 +13,7 @@ export function App() {
|
||||
<AppRoutes />
|
||||
</ErrorBoundary>
|
||||
<CartSnackbar />
|
||||
<NoiseOverlay />
|
||||
</BrowserRouter>
|
||||
</AppProviders>
|
||||
)
|
||||
|
||||
@@ -23,8 +23,10 @@ export function MainLayout({ children }: PropsWithChildren) {
|
||||
<ScrollToTop />
|
||||
<AppHeader />
|
||||
|
||||
<Box component="main" sx={{ flex: 1, py: { xs: 4, md: 6 } }}>
|
||||
<Container maxWidth="lg">{children}</Container>
|
||||
<Box component="main" sx={{ flex: 1, py: { xs: 3, md: 5 } }}>
|
||||
<Container maxWidth="xl" sx={{ px: { xs: 2, sm: 3, md: 4 } }}>
|
||||
{children}
|
||||
</Container>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
@@ -33,24 +35,19 @@ export function MainLayout({ children }: PropsWithChildren) {
|
||||
mt: 'auto',
|
||||
borderTop: 1,
|
||||
borderColor: 'divider',
|
||||
bgcolor: 'background.default',
|
||||
py: { xs: 4, md: 6 },
|
||||
bgcolor: 'background.paper',
|
||||
py: { xs: 5, md: 7 },
|
||||
}}
|
||||
>
|
||||
<Container maxWidth="lg">
|
||||
<Grid container spacing={4}>
|
||||
<Container maxWidth="xl" sx={{ px: { xs: 2, sm: 3, md: 4 } }}>
|
||||
<Grid container spacing={5}>
|
||||
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
|
||||
<Typography variant="subtitle1" gutterBottom sx={{ fontWeight: 600, letterSpacing: '-0.25px' }}>
|
||||
Магазин
|
||||
<Typography variant="subtitle1" gutterBottom sx={{ fontWeight: 700, letterSpacing: '-0.5px' }}>
|
||||
{STORE_NAME}
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mt: 1, maxWidth: 260 }}>
|
||||
Изделия ручной работы: вещи с характером и вниманием к деталям.
|
||||
</Typography>
|
||||
<Stack spacing={1.5}>
|
||||
<Link component={RouterLink} to="/" color="inherit" underline="hover" variant="body2">
|
||||
Каталог
|
||||
</Link>
|
||||
<Typography variant="body2" color="text.secondary">
|
||||
Изделия ручной работы: вещи с характером и вниманием к деталям.
|
||||
</Typography>
|
||||
</Stack>
|
||||
</Grid>
|
||||
<Grid size={{ xs: 12, sm: 6, md: 3 }}>
|
||||
<Typography variant="subtitle1" gutterBottom sx={{ fontWeight: 600, letterSpacing: '-0.25px' }}>
|
||||
@@ -111,7 +108,7 @@ export function MainLayout({ children }: PropsWithChildren) {
|
||||
</Stack>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Divider sx={{ my: 3 }} />
|
||||
<Divider sx={{ my: 4 }} />
|
||||
<Box sx={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 0.5 }}>
|
||||
<Typography variant="caption" color="text.secondary" sx={{ display: 'block', textAlign: 'center' }}>
|
||||
© {year} {STORE_NAME}
|
||||
|
||||
@@ -92,13 +92,16 @@ function AppThemeInner({ children }: PropsWithChildren) {
|
||||
shape: { borderRadius: 12 },
|
||||
typography: {
|
||||
fontFamily: '"Outfit", "Segoe UI", system-ui, sans-serif',
|
||||
h4: { fontWeight: 700, letterSpacing: '-0.5px' },
|
||||
h5: { fontWeight: 600, letterSpacing: '-0.25px' },
|
||||
h6: { fontWeight: 600 },
|
||||
h1: { fontWeight: 700, letterSpacing: '-1px', lineHeight: 1.1, textWrap: 'balance' },
|
||||
h2: { fontWeight: 700, letterSpacing: '-0.75px', lineHeight: 1.15, textWrap: 'balance' },
|
||||
h3: { fontWeight: 700, letterSpacing: '-0.5px', lineHeight: 1.2, textWrap: 'balance' },
|
||||
h4: { fontWeight: 700, letterSpacing: '-0.5px', textWrap: 'balance' },
|
||||
h5: { fontWeight: 600, letterSpacing: '-0.25px', textWrap: 'balance' },
|
||||
h6: { fontWeight: 600, textWrap: 'balance' },
|
||||
subtitle1: { fontWeight: 600 },
|
||||
subtitle2: { fontWeight: 500 },
|
||||
body1: { fontSize: '0.875rem' },
|
||||
body2: { fontSize: '0.75rem' },
|
||||
body1: { fontSize: '0.875rem', lineHeight: 1.6 },
|
||||
body2: { fontSize: '0.75rem', lineHeight: 1.5 },
|
||||
button: { textTransform: 'none', fontWeight: 600 },
|
||||
},
|
||||
components: {
|
||||
@@ -109,30 +112,34 @@ function AppThemeInner({ children }: PropsWithChildren) {
|
||||
borderRadius: 12,
|
||||
fontWeight: 600,
|
||||
transition: 'all 0.2s ease-in-out',
|
||||
'&:focus-visible': {
|
||||
outline: '2px solid currentColor',
|
||||
outlineOffset: 2,
|
||||
},
|
||||
},
|
||||
contained: {
|
||||
boxShadow: '0 4px 14px 0 rgba(0,0,0,0.15)',
|
||||
boxShadow: '0 4px 14px 0 rgba(0,0,0,0.12)',
|
||||
'&:hover': {
|
||||
boxShadow: '0 6px 20px 0 rgba(0,0,0,0.25)',
|
||||
boxShadow: '0 6px 20px 0 rgba(0,0,0,0.18)',
|
||||
transform: 'translateY(-2px)',
|
||||
},
|
||||
'&:active': {
|
||||
boxShadow: '0 2px 8px 0 rgba(0,0,0,0.15)',
|
||||
transform: 'translateY(0)',
|
||||
boxShadow: '0 2px 8px 0 rgba(0,0,0,0.12)',
|
||||
transform: 'translateY(0) scale(0.98)',
|
||||
},
|
||||
},
|
||||
outlined: {
|
||||
border: '1px solid',
|
||||
'&:hover': {
|
||||
boxShadow: '0 2px 8px 0 rgba(0,0,0,0.1)',
|
||||
boxShadow: '0 2px 8px 0 rgba(0,0,0,0.08)',
|
||||
},
|
||||
'&:active': {
|
||||
boxShadow: 'none',
|
||||
transform: 'scale(0.98)',
|
||||
},
|
||||
},
|
||||
text: {
|
||||
'&:hover': {
|
||||
boxShadow: '0 1px 3px 0 rgba(0,0,0,0.1)',
|
||||
backgroundColor: 'action.hover',
|
||||
},
|
||||
'&:active': {
|
||||
@@ -147,12 +154,48 @@ function AppThemeInner({ children }: PropsWithChildren) {
|
||||
transition: 'all 0.2s ease-in-out',
|
||||
'&:hover': {
|
||||
backgroundColor: 'action.hover',
|
||||
transform: 'scale(1.1)',
|
||||
transform: 'scale(1.08)',
|
||||
},
|
||||
'&:active': {
|
||||
backgroundColor: 'action.selected',
|
||||
transform: 'scale(0.95)',
|
||||
},
|
||||
'&:focus-visible': {
|
||||
outline: '2px solid currentColor',
|
||||
outlineOffset: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiCard: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:focus-visible': {
|
||||
outline: '2px solid currentColor',
|
||||
outlineOffset: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiLink: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&:focus-visible': {
|
||||
outline: '2px solid currentColor',
|
||||
outlineOffset: 2,
|
||||
borderRadius: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiInputBase: {
|
||||
styleOverrides: {
|
||||
root: {
|
||||
'&.Mui-focused': {
|
||||
'& .MuiOutlinedInput-notchedOutline': {
|
||||
borderWidth: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -30,6 +30,9 @@
|
||||
:root {
|
||||
color-scheme: light;
|
||||
}
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
@@ -37,4 +40,6 @@ body,
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user