{fleet.total_duration_minutes != null ? `${fleet.total_duration_minutes}` : '—'}
diff --git a/src/pages/nearle/invoice/invoice.js b/src/pages/nearle/invoice/invoice.js
index d6234fd..fce8cd0 100644
--- a/src/pages/nearle/invoice/invoice.js
+++ b/src/pages/nearle/invoice/invoice.js
@@ -35,12 +35,16 @@ import {
MdEventNote,
MdCurrencyRupee,
MdVisibility,
- MdInventory2
+ MdInventory2,
+ MdOutlinePendingActions,
+ MdOutlineCheckCircle
} from 'react-icons/md';
import { fetchinvoiceinsight, fetchdeliverylist } from 'pages/api/api';
import Loader from 'components/Loader';
import DebounceSearchBar from 'components/nearle_components/DebounceSearchBar';
+import PageHeader from 'components/nearle_components/PageHeader';
+import StatCard from 'components/nearle_components/StatCard';
import { OrdersTableSkeleton } from '../orders/OrdersTableSkeleton';
import { MobileCard, MobileCardList, MobileField, MobileFieldGrid } from 'components/nearle_components/MobileCard';
@@ -50,10 +54,10 @@ import { MobileCard, MobileCardList, MobileField, MobileFieldGrid } from 'compon
// ============================================================================
const DT = {
radiusPill: 999,
- radiusCard: 16,
- shadowSoft: '0 14px 40px rgba(15, 23, 42, 0.10)',
- shadowMd: '0 8px 24px rgba(15, 23, 42, 0.08)',
- shadowPop: '0 18px 50px rgba(15, 23, 42, 0.18)',
+ radiusCard: 14,
+ shadowSoft: '0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 24px rgba(15, 23, 42, 0.05)',
+ shadowMd: '0 1px 3px rgba(15, 23, 42, 0.06)',
+ shadowPop: '0 12px 32px rgba(15, 23, 42, 0.12)',
textPrimary: '#0f172a',
textSecondary: '#64748b',
textMuted: '#94a3b8',
@@ -69,7 +73,6 @@ const ring = (c) => a(c, '26');
const edge = (c) => a(c, '55');
const BRAND = '#662582';
-const BRAND_LIGHT = '#9255AB';
const AccentAvatar = ({ color, selected, size = 24, children }) => (
{
const KPI_META = [
{ idx: 0, label: 'All Invoices', color: BRAND, icon: MdDashboard, value: insightdata?.totalcount ?? 0 },
- { idx: 1, label: 'Open', color: '#ef4444', icon: MdHourglassEmpty, value: insightdata?.pendingcount ?? 0 },
+ { idx: 1, label: 'Open', color: '#ef4444', icon: MdOutlinePendingActions, value: insightdata?.pendingcount ?? 0 },
{ idx: 2, label: 'Overdue', color: '#f59e0b', icon: MdReportProblem, value: insightdata?.overduecount ?? 0 },
- { idx: 3, label: 'Paid', color: '#10b981', icon: MdCheckCircle, value: insightdata?.paidcount ?? 0 }
+ { idx: 3, label: 'Paid', color: '#10b981', icon: MdOutlineCheckCircle, value: insightdata?.paidcount ?? 0 }
];
const activeMeta = STATUS_META[billStatus];
@@ -211,64 +214,11 @@ const Invoice = () => {
{(isloader || isLoading) && }
{/* ============================================= || Header || ============================================= */}
-
-
-
-
-
-
-
-
- Invoices
-
-
-
-
- Live · Viewing {activeMeta.label.toLowerCase()} invoices
-
-
-
-
+ {
px: 1.5,
py: 0.875,
borderRadius: 999,
- bgcolor: tint(BRAND),
+ bgcolor: '#ffffff',
border: `1.5px solid ${edge(BRAND)}`,
color: BRAND,
fontWeight: 800,
@@ -292,90 +242,30 @@ const Invoice = () => {
{formatNumberToRupees(grandTotal)}
-
-
+ }
+ />
{/* ============================================= || KPI Cards (clickable filter) || ============================================= */}
-
+
{KPI_META.map((item) => {
const Icon = item.icon;
- const active = billStatus === item.idx;
return (
- {
setBillStatus(item.idx);
setPage(0);
}}
- sx={{
- position: 'relative',
- overflow: 'hidden',
- cursor: 'pointer',
- p: { xs: 1.25, sm: 1.75, md: 2.25 },
- borderRadius: DT.radiusCard / 8,
- border: '1px solid',
- borderColor: active ? edge(item.color) : DT.borderSubtle,
- background: active ? tint(item.color) : '#fff',
- boxShadow: active ? `0 0 0 3px ${ring(item.color)}` : 'none',
- transition: 'transform 0.2s, box-shadow 0.2s, border-color 0.2s, background 0.2s',
- '&:hover': {
- transform: 'translateY(-3px)',
- boxShadow: DT.shadowMd,
- borderColor: edge(item.color)
- }
- }}
+ sx={{ cursor: 'pointer', height: '100%' }}
>
- }
+ color={item.color}
+ loading={isInsightLoading}
/>
-
-
-
- {item.label}
-
-
- {item.value}
-
-
-
-
-
-
-
+
);
})}
@@ -438,32 +328,32 @@ const Invoice = () => {
flexShrink: 0,
cursor: 'pointer',
borderRadius: 999,
- border: `1.5px solid ${active ? meta.color : edge(meta.color)}`,
- bgcolor: active ? meta.color : tint(meta.color),
- color: active ? '#fff' : meta.color,
- fontWeight: 700,
- boxShadow: active ? `0 6px 18px ${ring(meta.color)}` : 'none',
- transition: 'all 0.18s',
+ border: `1px solid ${active ? meta.color : DT.borderSubtle}`,
+ bgcolor: active ? meta.color : DT.surface,
+ color: active ? '#fff' : DT.textSecondary,
+ fontWeight: 600,
+ boxShadow: 'none',
+ transition: 'background-color 0.15s, border-color 0.15s, color 0.15s',
'&:hover': {
- borderColor: meta.color,
- boxShadow: active ? `0 6px 18px ${ring(meta.color)}` : `0 0 0 3px ${ring(meta.color)}`
+ borderColor: active ? meta.color : '#cbd5e1',
+ bgcolor: active ? meta.color : DT.surfaceAlt
}
}}
>
-
+
{
{count}
@@ -503,10 +393,10 @@ const Invoice = () => {
m: 0,
width: '100%',
borderRadius: 999,
- bgcolor: tint(BRAND),
- '& fieldset': { borderColor: edge(BRAND), borderWidth: 1.5 },
- '&:hover fieldset': { borderColor: BRAND },
- '&.Mui-focused fieldset': { borderColor: BRAND, borderWidth: 2 },
+ bgcolor: '#ffffff',
+ '& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
+ '&:hover fieldset': { borderColor: '#cbd5e1' },
+ '&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 },
'&.Mui-focused': { boxShadow: `0 0 0 3px ${ring(BRAND)}` }
}}
/>
@@ -628,7 +518,7 @@ const Invoice = () => {
px: 1,
py: 0.375,
borderRadius: 999,
- bgcolor: tint(BRAND),
+ bgcolor: '#ffffff',
border: `1px solid ${edge(BRAND)}`,
color: BRAND,
fontSize: 11,
@@ -883,7 +773,7 @@ const Invoice = () => {
px: 1,
py: 0.375,
borderRadius: 999,
- bgcolor: tint(BRAND),
+ bgcolor: '#ffffff',
border: `1px solid ${edge(BRAND)}`,
color: BRAND,
fontSize: 11,
@@ -936,7 +826,7 @@ const Invoice = () => {
sx={{
px: 2,
py: 1,
- background: `linear-gradient(135deg, ${tint(BRAND)} 0%, ${tint(BRAND_LIGHT)} 100%)`
+ background: '#ffffff'
}}
>
diff --git a/src/pages/nearle/login.js b/src/pages/nearle/login.js
index bf7bba2..9cdbc7a 100644
--- a/src/pages/nearle/login.js
+++ b/src/pages/nearle/login.js
@@ -149,37 +149,123 @@ const Login = () => {
};
return (
-
+
{loading && }
-
-
- {/* Logo */}
-
-
-
+ />
+
- {/* Title */}
-
- Login
+
+
+
+
+
+
+
+
+ Operate your dispatch,
+
+ end to end.
+
+ Orders, AI route optimisation, live rider tracking and billing — all in the NearlExpress operator console.
+
+
-
+
+ {['Real-time fleet visibility', 'AI-optimised dispatch routes', 'Tenant, pricing & invoice control'].map((t) => (
+
+
+ ✓
+
+ {t}
+
+ ))}
+
+
+
+ {/* ---- Right form panel ---- */}
+
+
+
+ {/* Logo */}
+
+
+
+
+ {/* Title */}
+
+ Welcome back
+
+
+ Sign in to the NearlExpress console
+
+
+
-
-
-
- {/* footer */}
-
-
- © All rights reserved
-
-
- Terms and Conditions
-
-
- Privacy Policy
-
-
+
+
+
+ {/* footer */}
+
+
+ © All rights reserved
+
+
+ Terms and Conditions
+
+
+ Privacy Policy
+
+
+
+
);
};
diff --git a/src/pages/nearle/orders/OrdersRedesign.css b/src/pages/nearle/orders/OrdersRedesign.css
index 0302fa0..950f7af 100644
--- a/src/pages/nearle/orders/OrdersRedesign.css
+++ b/src/pages/nearle/orders/OrdersRedesign.css
@@ -696,7 +696,7 @@
.weight-card-btn.active.weight-heavy {
background: rgba(99, 102, 241, 0.04) !important;
- border-color: #6366f1 !important;
+ border-color: #662582 !important;
box-shadow: 0 6px 16px rgba(99, 102, 241, 0.15) !important;
}
@@ -707,7 +707,7 @@
left: 0;
right: 0;
height: 3px;
- background: #6366f1;
+ background: #662582;
}
/* Premium Card Overrides */
diff --git a/src/pages/nearle/orders/orders.js b/src/pages/nearle/orders/orders.js
index deafa24..ae460e1 100644
--- a/src/pages/nearle/orders/orders.js
+++ b/src/pages/nearle/orders/orders.js
@@ -21,13 +21,16 @@ import {
MdHourglassEmpty,
MdCheckCircle,
MdCancel,
+ MdOutlineReceiptLong,
+ MdOutlinePendingActions,
+ MdOutlineCheckCircle,
+ MdOutlineCancel,
MdMyLocation,
MdGroups,
MdPlace,
MdStraighten,
MdCurrencyRupee,
MdInventory2,
- MdReceiptLong,
MdHistoryToggleOff,
MdCalendarMonth
} from 'react-icons/md';
@@ -39,6 +42,8 @@ import MainCard from 'components/MainCard';
import { OpenToast } from 'components/third-party/OpenToast';
import { OrdersTableSkeleton } from './OrdersTableSkeleton';
import LocationAutocomplete from 'components/nearle_components/LocationAutocomplete';
+import PageHeader from 'components/nearle_components/PageHeader';
+import StatCard from 'components/nearle_components/StatCard';
import AiImage from '../../../assets/images/aiImage.png';
import ArrowBackIcon from '@mui/icons-material/ArrowBack';
import EnergySavingsLeafIcon from '@mui/icons-material/EnergySavingsLeaf';
@@ -73,7 +78,6 @@ import {
DialogContent,
DialogTitle,
Tooltip,
- Skeleton,
DialogActions,
Autocomplete,
TableContainer,
@@ -122,10 +126,10 @@ import Dispatch from '../dispatch/Dispatch';
// ============================================================================
const DT = {
radiusPill: 999,
- radiusCard: 16,
- shadowSoft: '0 14px 40px rgba(15, 23, 42, 0.10)',
- shadowMd: '0 8px 24px rgba(15, 23, 42, 0.08)',
- shadowPop: '0 18px 50px rgba(15, 23, 42, 0.18)',
+ radiusCard: 14,
+ shadowSoft: '0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 24px rgba(15, 23, 42, 0.05)',
+ shadowMd: '0 1px 3px rgba(15, 23, 42, 0.06)',
+ shadowPop: '0 12px 32px rgba(15, 23, 42, 0.12)',
textPrimary: '#0f172a',
textSecondary: '#64748b',
textMuted: '#94a3b8',
@@ -141,7 +145,6 @@ const dtRing = (c) => dtA(c, '26');
const dtEdge = (c) => dtA(c, '55');
const BRAND = '#662582';
-const BRAND_LIGHT = '#9255AB';
const SoftPaper = (props) => (
(
);
-const pillFieldSx = (color) => ({
+const pillFieldSx = () => ({
'& .MuiOutlinedInput-root': {
- borderRadius: DT.radiusPill + 'px',
- bgcolor: dtTint(color),
+ borderRadius: '10px',
+ bgcolor: '#ffffff',
fontWeight: 600,
- '& fieldset': { borderColor: dtEdge(color), borderWidth: 1.5 },
- '&:hover fieldset': { borderColor: color },
- '&.Mui-focused': { boxShadow: `0 0 0 3px ${dtRing(color)}` },
- '&.Mui-focused fieldset': { borderColor: color, borderWidth: 2 }
+ '& fieldset': { borderColor: '#e2e8f0', borderWidth: 1 },
+ '&:hover fieldset': { borderColor: '#cbd5e1' },
+ '&.Mui-focused': { boxShadow: `0 0 0 3px ${dtRing('#662582')}` },
+ '&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 }
}
});
@@ -929,64 +932,11 @@ const Orders = () => {
)}
{/* ============================================= || Header || ============================================= */}
-
-
-
-
-
-
-
-
- Orders
-
-
-
-
- Live · {locaName || 'All Zones'} · {datestatus}
-
-
-
-
+ {
paperComponent={SoftPaper}
sx={{ width: { xs: '100%', sm: 280 }, zIndex: 100 }}
/>
-
-
+ }
+ />
{/* ============================================= || KPI Cards || ============================================= */}
-
+
{[
- { key: 'created', label: 'Created Orders', color: '#0ea5e9', icon: MdLocalShipping, value: percentageData?.created, percentage: percentageData?.percentage1 },
- { key: 'pending', label: 'Pending Orders', color: '#f59e0b', icon: MdHourglassEmpty, value: percentageData?.uncoveredOrders, percentage: percentageData?.percentage2 },
- { key: 'delivered', label: 'Delivered Orders', color: '#10b981', icon: MdCheckCircle, value: percentageData?.coveredOrders, percentage: percentageData?.percentage3 },
- { key: 'cancelled', label: 'Cancelled Orders', color: '#ef4444', icon: MdCancel, value: percentageData?.cancelled, percentage: percentageData?.percentage4 }
+ { key: 'created', label: 'Created Orders', color: '#662582', icon: MdOutlineReceiptLong, value: percentageData?.created, percentage: percentageData?.percentage1 },
+ { key: 'pending', label: 'Pending Orders', color: '#f59e0b', icon: MdOutlinePendingActions, value: percentageData?.uncoveredOrders, percentage: percentageData?.percentage2 },
+ { key: 'delivered', label: 'Delivered Orders', color: '#10b981', icon: MdOutlineCheckCircle, value: percentageData?.coveredOrders, percentage: percentageData?.percentage3 },
+ { key: 'cancelled', label: 'Cancelled Orders', color: '#ef4444', icon: MdOutlineCancel, value: percentageData?.cancelled, percentage: percentageData?.percentage4 }
].map((item) => {
const Icon = item.icon;
return (
-
-
-
-
-
- {item.label}
-
-
- {fetchpercentageIsLoading ? : (item.value ?? 0)}
-
- {item.percentage != null && (
-
- {item.percentage}%
-
- )}
-
-
-
-
-
-
+ }
+ color={item.color}
+ loading={fetchpercentageIsLoading}
+ caption={item.percentage != null ? `${item.percentage}% of total` : undefined}
+ />
);
})}
@@ -1147,7 +1030,7 @@ const Orders = () => {
...params.InputProps,
startAdornment: (
-
+
@@ -1198,7 +1081,7 @@ const Orders = () => {
...params.InputProps,
startAdornment: (
-
+
@@ -1218,20 +1101,21 @@ const Orders = () => {
display: 'inline-flex',
alignItems: 'center',
gap: 0.75,
- px: 1.25,
- py: 0.75,
- borderRadius: 999,
+ px: 1.5,
+ py: 0.875,
+ borderRadius: '10px',
cursor: 'pointer',
- bgcolor: dtTint('#f59e0b'),
- border: `1.5px solid ${dtEdge('#f59e0b')}`,
- color: '#f59e0b',
- fontWeight: 800,
+ bgcolor: '#ffffff',
+ border: '1px solid #e2e8f0',
+ color: '#475569',
+ fontWeight: 600,
fontSize: 12,
- transition: 'all 0.18s',
- '&:hover': { borderColor: '#f59e0b', boxShadow: `0 0 0 3px ${dtRing('#f59e0b')}` }
+ transition: 'border-color 0.15s, box-shadow 0.15s',
+ '&:hover': { borderColor: '#cbd5e1' },
+ '& svg': { color: '#94a3b8' }
}}
>
-
+
{dayjs(startdate).format('DD/MM/YY')} – {dayjs(enddate).format('DD/MM/YY')}
@@ -1242,15 +1126,14 @@ const Orders = () => {
gap: 0.5,
px: 1,
py: 0.5,
- borderRadius: 999,
- bgcolor: dtTint(BRAND),
- border: `1px solid ${dtEdge(BRAND)}`,
- color: BRAND,
+ borderRadius: '8px',
+ bgcolor: '#f1f5f9',
+ color: '#64748b',
fontSize: 11,
- fontWeight: 800
+ fontWeight: 600
}}
>
- {datestatus}
+ {datestatus}
@@ -1320,49 +1203,49 @@ const Orders = () => {
py: 0.5,
flexShrink: 0,
cursor: 'pointer',
- borderRadius: 999,
- border: `1.5px solid ${active ? t.color : dtEdge(t.color)}`,
- bgcolor: active ? t.color : dtTint(t.color),
- color: active ? '#fff' : t.color,
- fontWeight: 700,
- boxShadow: active ? `0 6px 18px ${dtRing(t.color)}` : 'none',
- transition: 'all 0.18s',
+ borderRadius: DT.radiusField + 'px',
+ border: `1px solid ${active ? t.color : DT.borderSubtle}`,
+ bgcolor: active ? t.color : DT.surface,
+ color: active ? '#fff' : DT.textSecondary,
+ fontWeight: 600,
+ boxShadow: 'none',
+ transition: 'background-color 0.15s, border-color 0.15s, color 0.15s',
'&:hover': {
- borderColor: t.color,
- boxShadow: active ? `0 6px 18px ${dtRing(t.color)}` : `0 0 0 3px ${dtRing(t.color)}`
+ borderColor: active ? t.color : DT.borderHover,
+ bgcolor: active ? t.color : DT.surfaceAlt
}
}}
>
-
+
{t.label}
{count}
@@ -1384,8 +1267,8 @@ const Orders = () => {
borderRadius: 999,
bgcolor: dtTint(BRAND),
'& fieldset': { borderColor: dtEdge(BRAND), borderWidth: 1.5 },
- '&:hover fieldset': { borderColor: BRAND },
- '&.Mui-focused fieldset': { borderColor: BRAND, borderWidth: 2 },
+ '&:hover fieldset': { borderColor: '#cbd5e1' },
+ '&.Mui-focused fieldset': { borderColor: '#662582', borderWidth: 1.5 },
'&.Mui-focused': { boxShadow: `0 0 0 3px ${dtRing(BRAND)}` }
}}
/>
diff --git a/src/pages/nearle/reports/RidersRoutes.js b/src/pages/nearle/reports/RidersRoutes.js
index be15e19..24fc765 100644
--- a/src/pages/nearle/reports/RidersRoutes.js
+++ b/src/pages/nearle/reports/RidersRoutes.js
@@ -104,10 +104,10 @@ export default function RidersRoutes({ details, loading, riderName, dateRange, o
// Numbered step icon as a data URL — drawn fresh per render so we can pass
// the step number into the SVG without juggling external assets. Color is
- // a fixed indigo to match the planned-route polyline below.
+ // brand purple to match the planned-route polyline below.
const stepIcon = (n, isFocused) => {
const size = isFocused ? 38 : 32;
- const color = isFocused ? '#4338ca' : '#6366f1';
+ const color = isFocused ? '#4D1C61' : '#662582';
const svg = encodeURIComponent(
`
>
);
};
diff --git a/src/themes/index.js b/src/themes/index.js
index efe2ec7..9444eaf 100644
--- a/src/themes/index.js
+++ b/src/themes/index.js
@@ -12,6 +12,37 @@ import Typography from './typography';
import CustomShadows from './shadows';
import componentsOverride from './overrides';
+// Refined enterprise elevation ramp — soft, layered, low-contrast shadows
+// (Stripe/Linear feel) instead of MUI's default hard grey drop-shadows.
+// MUI requires exactly 25 entries (index 0 = 'none').
+const softShadows = [
+ 'none',
+ '0 1px 2px rgba(15, 23, 42, 0.04)',
+ '0 1px 3px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04)',
+ '0 2px 6px rgba(15, 23, 42, 0.06), 0 1px 2px rgba(15, 23, 42, 0.04)',
+ '0 4px 10px rgba(15, 23, 42, 0.06), 0 1px 3px rgba(15, 23, 42, 0.05)',
+ '0 6px 14px rgba(15, 23, 42, 0.07), 0 2px 4px rgba(15, 23, 42, 0.05)',
+ '0 8px 18px rgba(15, 23, 42, 0.08), 0 2px 5px rgba(15, 23, 42, 0.05)',
+ '0 10px 22px rgba(15, 23, 42, 0.08), 0 3px 6px rgba(15, 23, 42, 0.05)',
+ '0 12px 26px rgba(15, 23, 42, 0.09), 0 4px 8px rgba(15, 23, 42, 0.06)',
+ '0 14px 30px rgba(15, 23, 42, 0.10), 0 4px 9px rgba(15, 23, 42, 0.06)',
+ '0 16px 34px rgba(15, 23, 42, 0.10), 0 5px 10px rgba(15, 23, 42, 0.06)',
+ '0 18px 38px rgba(15, 23, 42, 0.11), 0 6px 11px rgba(15, 23, 42, 0.07)',
+ '0 20px 42px rgba(15, 23, 42, 0.11), 0 6px 12px rgba(15, 23, 42, 0.07)',
+ '0 22px 46px rgba(15, 23, 42, 0.12), 0 7px 13px rgba(15, 23, 42, 0.07)',
+ '0 24px 50px rgba(15, 23, 42, 0.12), 0 8px 14px rgba(15, 23, 42, 0.08)',
+ '0 26px 54px rgba(15, 23, 42, 0.13), 0 8px 15px rgba(15, 23, 42, 0.08)',
+ '0 28px 58px rgba(15, 23, 42, 0.13), 0 9px 16px rgba(15, 23, 42, 0.08)',
+ '0 30px 62px rgba(15, 23, 42, 0.14), 0 10px 17px rgba(15, 23, 42, 0.09)',
+ '0 32px 66px rgba(15, 23, 42, 0.14), 0 10px 18px rgba(15, 23, 42, 0.09)',
+ '0 34px 70px rgba(15, 23, 42, 0.15), 0 11px 19px rgba(15, 23, 42, 0.09)',
+ '0 36px 74px rgba(15, 23, 42, 0.15), 0 12px 20px rgba(15, 23, 42, 0.10)',
+ '0 38px 78px rgba(15, 23, 42, 0.16), 0 12px 21px rgba(15, 23, 42, 0.10)',
+ '0 40px 82px rgba(15, 23, 42, 0.16), 0 13px 22px rgba(15, 23, 42, 0.10)',
+ '0 42px 86px rgba(15, 23, 42, 0.17), 0 14px 23px rgba(15, 23, 42, 0.11)',
+ '0 44px 90px rgba(15, 23, 42, 0.18), 0 14px 24px rgba(15, 23, 42, 0.11)'
+];
+
// ==============================|| DEFAULT THEME - MAIN ||============================== //
export default function ThemeCustomization({ children }) {
@@ -52,6 +83,9 @@ export default function ThemeCustomization({ children }) {
}
},
direction: themeDirection,
+ shape: {
+ borderRadius: 8
+ },
mixins: {
toolbar: {
minHeight: 60,
@@ -61,7 +95,8 @@ export default function ThemeCustomization({ children }) {
},
palette: theme.palette,
customShadows: themeCustomShadows,
- typography: themeTypography
+ typography: themeTypography,
+ shadows: softShadows
}),
[themeDirection, theme, themeTypography, themeCustomShadows]
);
@@ -75,38 +110,37 @@ export default function ThemeCustomization({ children }) {
diff --git a/src/themes/overrides/Autocomplete.js b/src/themes/overrides/Autocomplete.js
index ee29f94..5c61492 100644
--- a/src/themes/overrides/Autocomplete.js
+++ b/src/themes/overrides/Autocomplete.js
@@ -9,6 +9,27 @@ export default function Autocomplete() {
padding: '3px 9px'
}
},
+ // Soft, rounded popup with comfortable option rows — matches the
+ // SoftPaper used by the redesigned pages.
+ paper: {
+ borderRadius: 12,
+ boxShadow: '0 18px 50px rgba(15, 23, 42, 0.18)',
+ border: '1px solid #e2e8f0',
+ overflow: 'hidden'
+ },
+ listbox: {
+ padding: 6,
+ '& .MuiAutocomplete-option': {
+ borderRadius: 8,
+ margin: '1px 0',
+ '&[aria-selected="true"]': {
+ backgroundColor: 'rgba(102, 37, 130, 0.08)'
+ },
+ '&.Mui-focused': {
+ backgroundColor: 'rgba(102, 37, 130, 0.06)'
+ }
+ }
+ },
popupIndicator: {
width: 'auto',
height: 'auto'
diff --git a/src/themes/overrides/Button.js b/src/themes/overrides/Button.js
index 1077206..be59396 100644
--- a/src/themes/overrides/Button.js
+++ b/src/themes/overrides/Button.js
@@ -14,24 +14,21 @@ function getColorStyle({ variant, color, theme }) {
const buttonShadow = `${color}Button`;
const shadows = getShadow(theme, buttonShadow);
+ // Clean keyboard-focus ring (soft brand-tinted halo) — replaces the old
+ // flashy expanding ::after glow that read as "template / AI default".
const commonShadow = {
- '&::after': {
- boxShadow: `0 0 5px 5px ${alpha(main, 0.9)}`
- },
- '&:active::after': {
- boxShadow: `0 0 0 0 ${alpha(main, 0.9)}`
- },
'&:focus-visible': {
- outline: `2px solid ${dark}`,
- outlineOffset: 2
+ boxShadow: `0 0 0 3px ${alpha(main, 0.32)}`
}
};
switch (variant) {
case 'contained':
return {
+ boxShadow: 'none',
'&:hover': {
- backgroundColor: dark
+ backgroundColor: dark,
+ boxShadow: 'none'
},
...commonShadow
};
@@ -103,28 +100,10 @@ export default function Button(theme) {
},
styleOverrides: {
root: {
- fontWeight: 400,
- '&::after': {
- content: '""',
- display: 'block',
- position: 'absolute',
- left: 0,
- top: 0,
- width: '100%',
- height: '100%',
- borderRadius: 4,
- opacity: 0,
- transition: 'all 0.5s'
- },
-
- '&:active::after': {
- position: 'absolute',
- borderRadius: 4,
- left: 0,
- top: 0,
- opacity: 1,
- transition: '0s'
- }
+ fontWeight: 600,
+ borderRadius: 8,
+ textTransform: 'none',
+ transition: 'background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease'
},
contained: {
...disabledStyle
diff --git a/src/themes/overrides/Chip.js b/src/themes/overrides/Chip.js
index c0d6769..9b931d7 100644
--- a/src/themes/overrides/Chip.js
+++ b/src/themes/overrides/Chip.js
@@ -40,7 +40,8 @@ export default function Chip(theme) {
MuiChip: {
styleOverrides: {
root: {
- borderRadius: 4,
+ borderRadius: 8,
+ fontWeight: 600,
'&:active': {
boxShadow: 'none'
},
diff --git a/src/themes/overrides/Dialog.js b/src/themes/overrides/Dialog.js
index ccc0384..2777069 100644
--- a/src/themes/overrides/Dialog.js
+++ b/src/themes/overrides/Dialog.js
@@ -8,9 +8,15 @@ export default function Dialog() {
MuiDialog: {
styleOverrides: {
root: {
+ // Lighter, slightly blurred scrim — less heavy than a near-opaque black.
'& .MuiBackdrop-root': {
- backgroundColor: alpha('#000', 0.7)
+ backgroundColor: alpha('#0f172a', 0.45),
+ backdropFilter: 'blur(2px)'
}
+ },
+ paper: {
+ borderRadius: 16,
+ boxShadow: '0 24px 60px rgba(15, 23, 42, 0.22), 0 8px 18px rgba(15, 23, 42, 0.12)'
}
}
}
diff --git a/src/themes/overrides/DialogTitle.js b/src/themes/overrides/DialogTitle.js
index 6a30338..8ae2fc2 100644
--- a/src/themes/overrides/DialogTitle.js
+++ b/src/themes/overrides/DialogTitle.js
@@ -5,8 +5,9 @@ export default function DialogTitle() {
MuiDialogTitle: {
styleOverrides: {
root: {
- fontSize: '1rem',
- fontWeight: 500
+ fontSize: '1.0625rem',
+ fontWeight: 600,
+ letterSpacing: '-0.01em'
}
}
}
diff --git a/src/themes/overrides/Tab.js b/src/themes/overrides/Tab.js
index 76dcad1..2cbff00 100644
--- a/src/themes/overrides/Tab.js
+++ b/src/themes/overrides/Tab.js
@@ -7,13 +7,13 @@ export default function Tab(theme) {
root: {
minHeight: 46,
color: theme.palette.text.primary,
- borderRadius: 4,
+ borderRadius: 8,
'&:hover': {
backgroundColor: theme.palette.primary.lighter + 60,
color: theme.palette.primary.main
},
'&:focus-visible': {
- borderRadius: 4,
+ borderRadius: 8,
outline: `2px solid ${theme.palette.secondary.dark}`,
outlineOffset: -3
}
diff --git a/src/themes/overrides/TableCell.js b/src/themes/overrides/TableCell.js
index 9df0b92..ef0dcf2 100644
--- a/src/themes/overrides/TableCell.js
+++ b/src/themes/overrides/TableCell.js
@@ -1,42 +1,31 @@
// ==============================|| OVERRIDES - TABLE CELL ||============================== //
export default function TableCell(theme) {
- const commonCell = {
- '&:not(:last-of-type)': {
- position: 'relative',
- '&:after': {
- position: 'absolute',
- content: '""',
- backgroundColor: theme.palette.divider,
- width: 1,
- height: 'calc(100% - 30px)',
- right: 0,
- top: 16
- }
- }
- };
-
return {
MuiTableCell: {
styleOverrides: {
root: {
fontSize: '0.875rem',
- padding: 12,
+ padding: '14px 12px',
borderColor: theme.palette.divider
},
sizeSmall: {
- padding: 8
+ padding: '10px 8px'
},
+ // Clean enterprise header: small, muted, well-tracked uppercase labels.
+ // The old vertical divider rules between header cells were removed —
+ // modern data tables (Stripe/Linear) keep headers borderless and quiet.
head: {
- fontSize: '0.75rem',
+ fontSize: '0.6875rem',
fontWeight: 700,
+ letterSpacing: '0.06em',
textTransform: 'uppercase',
- ...commonCell
+ color: theme.palette.text.secondary
},
footer: {
fontSize: '0.75rem',
textTransform: 'uppercase',
- ...commonCell
+ color: theme.palette.text.secondary
}
}
}
diff --git a/src/themes/overrides/TableHead.js b/src/themes/overrides/TableHead.js
index 23f45dd..b513626 100644
--- a/src/themes/overrides/TableHead.js
+++ b/src/themes/overrides/TableHead.js
@@ -1,4 +1,4 @@
-// ==============================|| OVERRIDES - TABLE CELL ||============================== //
+// ==============================|| OVERRIDES - TABLE HEAD ||============================== //
export default function TableHead(theme) {
return {
@@ -6,8 +6,11 @@ export default function TableHead(theme) {
styleOverrides: {
root: {
backgroundColor: theme.palette.grey[50],
- borderTop: `1px solid ${theme.palette.divider}`,
- borderBottom: `2px solid ${theme.palette.divider}`
+ borderTop: 'none',
+ borderBottom: `1px solid ${theme.palette.divider}`,
+ '& .MuiTableCell-root': {
+ borderBottom: `1px solid ${theme.palette.divider}`
+ }
}
}
}
diff --git a/src/themes/shadows.js b/src/themes/shadows.js
index 9e17860..51ee478 100644
--- a/src/themes/shadows.js
+++ b/src/themes/shadows.js
@@ -13,7 +13,7 @@ const CustomShadows = (theme) => ({
z1:
theme.palette.mode === ThemeMode.DARK
? `0px 1px 1px rgb(0 0 0 / 14%), 0px 2px 1px rgb(0 0 0 / 12%), 0px 1px 3px rgb(0 0 0 / 20%)`
- : `0px 1px 4px ${alpha(theme.palette.grey[900], 0.08)}`,
+ : `0 1px 3px rgba(15, 23, 42, 0.06), 0 6px 16px rgba(15, 23, 42, 0.06)`,
primary: `0 0 0 2px ${alpha(theme.palette.primary.main, 0.2)}`,
secondary: `0 0 0 2px ${alpha(theme.palette.secondary.main, 0.2)}`,
error: `0 0 0 2px ${alpha(theme.palette.error.main, 0.2)}`,
diff --git a/src/themes/typography.js b/src/themes/typography.js
index d6dd849..a44b096 100644
--- a/src/themes/typography.js
+++ b/src/themes/typography.js
@@ -1,5 +1,9 @@
// ==============================|| DEFAULT THEME - TYPOGRAPHY ||============================== //
+// Refined enterprise type scale (Stripe / Linear feel):
+// - Tight negative tracking on display headings so large text reads crisp, not loose.
+// - Buttons are medium-weight and case-preserving (no shouty UPPERCASE / Capitalize).
+// - Slightly looser tracking on the small uppercase eyebrow/overline labels for legibility.
const Typography = (fontFamily) => ({
htmlFontSize: 16,
fontFamily,
@@ -8,52 +12,62 @@ const Typography = (fontFamily) => ({
fontWeightMedium: 500,
fontWeightBold: 600,
h1: {
- fontWeight: 600,
- fontSize: '2.375rem',
- lineHeight: 1.21
+ fontWeight: 700,
+ fontSize: '2.25rem',
+ lineHeight: 1.2,
+ letterSpacing: '-0.025em'
},
h2: {
- fontWeight: 600,
+ fontWeight: 700,
fontSize: '1.875rem',
- lineHeight: 1.27
+ lineHeight: 1.25,
+ letterSpacing: '-0.02em'
},
h3: {
fontWeight: 600,
fontSize: '1.5rem',
- lineHeight: 1.33
+ lineHeight: 1.33,
+ letterSpacing: '-0.018em'
},
h4: {
fontWeight: 600,
fontSize: '1.25rem',
- lineHeight: 1.4
+ lineHeight: 1.4,
+ letterSpacing: '-0.014em'
},
h5: {
fontWeight: 600,
fontSize: '1rem',
- lineHeight: 1.5
+ lineHeight: 1.5,
+ letterSpacing: '-0.01em'
},
h6: {
- fontWeight: 400,
+ fontWeight: 500,
fontSize: '0.875rem',
- lineHeight: 1.57
+ lineHeight: 1.57,
+ letterSpacing: '-0.006em'
},
caption: {
fontWeight: 400,
fontSize: '0.75rem',
- lineHeight: 1.66
+ lineHeight: 1.66,
+ letterSpacing: '0'
},
body1: {
fontSize: '0.875rem',
- lineHeight: 1.57
+ lineHeight: 1.57,
+ letterSpacing: '-0.006em'
},
body2: {
fontSize: '0.75rem',
- lineHeight: 1.66
+ lineHeight: 1.66,
+ letterSpacing: '0'
},
subtitle1: {
fontSize: '0.875rem',
fontWeight: 600,
- lineHeight: 1.57
+ lineHeight: 1.57,
+ letterSpacing: '-0.006em'
},
subtitle2: {
fontSize: '0.75rem',
@@ -61,10 +75,16 @@ const Typography = (fontFamily) => ({
lineHeight: 1.66
},
overline: {
- lineHeight: 1.66
+ fontWeight: 600,
+ fontSize: '0.6875rem',
+ lineHeight: 1.66,
+ letterSpacing: '0.06em',
+ textTransform: 'uppercase'
},
button: {
- textTransform: 'capitalize'
+ fontWeight: 600,
+ letterSpacing: '-0.004em',
+ textTransform: 'none'
}
});
diff --git a/yarn.lock b/yarn.lock
index 4118619..47d7a71 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6572,6 +6572,11 @@ fs.realpath@^1.0.0:
resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
+fsevents@^2.3.2, fsevents@~2.3.2:
+ version "2.3.3"
+ resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz"
+ integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
+
function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"