diff --git a/probe.mjs b/probe.mjs
new file mode 100644
index 0000000..125807f
--- /dev/null
+++ b/probe.mjs
@@ -0,0 +1,24 @@
+import { chromium } from 'playwright';
+
+const browser = await chromium.launch();
+for (const w of [1600, 1440, 1366, 1280, 1180, 1024, 992, 900, 768, 640, 480, 390]) {
+ const page = await browser.newPage({ viewport: { width: w, height: 900 }, deviceScaleFactor: 1 });
+ await page.goto('http://localhost:3000/miletruth', { waitUntil: 'load', timeout: 90000 });
+ await page.waitForTimeout(1200);
+ const r = await page.evaluate(() => {
+ const copy = document.querySelector('#solution-miletruth-ai .sw-mt-copy');
+ const flow = document.querySelector('#solution-miletruth-ai .sw-mt-flow');
+ const labels = [...flow.querySelectorAll('.sw-mt-step-label')];
+ return {
+ copyW: Math.round(copy.getBoundingClientRect().width),
+ // widest single unbreakable label vs the track it was given
+ worst: labels.map(e => {
+ const track = e.parentElement.getBoundingClientRect().width;
+ return { txt: e.textContent, need: Math.round(e.scrollWidth), track: Math.round(track) };
+ }).filter(x => x.need > x.track + 1),
+ };
+ });
+ console.log(`${String(w).padStart(4)} copy=${String(r.copyW).padStart(3)} overflow=${r.worst.length ? JSON.stringify(r.worst) : 'none'}`);
+ await page.close();
+}
+await browser.close();
diff --git a/public/images/miletruth-ai-core.png b/public/images/miletruth-ai-core.png
new file mode 100644
index 0000000..a3c2bca
Binary files /dev/null and b/public/images/miletruth-ai-core.png differ
diff --git a/shot-miletruth.mjs b/shot-miletruth.mjs
new file mode 100644
index 0000000..c90da2b
--- /dev/null
+++ b/shot-miletruth.mjs
@@ -0,0 +1,49 @@
+import { chromium } from 'playwright';
+
+const shots = [
+ { name: 'desktop-1440', w: 1440, h: 1000 },
+ { name: 'laptop-1280', w: 1280, h: 900 },
+ { name: 'tablet-1024', w: 1024, h: 950 },
+ { name: 'mobile-390', w: 390, h: 844 },
+];
+
+for (const s of shots) {
+ // fresh browser each time: reusing one exhausts software WebGL contexts
+ const browser = await chromium.launch({
+ args: ['--use-gl=angle', '--use-angle=swiftshader', '--enable-unsafe-swiftshader'],
+ });
+ const page = await browser.newPage({ viewport: { width: s.w, height: s.h }, deviceScaleFactor: 1 });
+ const errs = [];
+ page.on('pageerror', e => errs.push('pageerror: ' + e.message));
+
+ await page.goto('http://localhost:3000/miletruth', { waitUntil: 'load', timeout: 90000 });
+ const toSec = () => page.evaluate(() => {
+ const el = document.querySelector('#solution-miletruth-ai');
+ if (el) window.scrollTo(0, window.scrollY + el.getBoundingClientRect().top - 8);
+ });
+ await toSec();
+ await page.waitForTimeout(18000);
+ await toSec();
+ await page.waitForTimeout(2500);
+
+ const info = await page.evaluate(() => {
+ const sec = document.querySelector('#solution-miletruth-ai');
+ const scene = sec.querySelector('.mtn-scene');
+ const sb = scene.getBoundingClientRect();
+ return {
+ canvas: sec.querySelectorAll('canvas').length,
+ labels: [...scene.querySelectorAll('.mtn-lbl')].map(e => {
+ const r = e.getBoundingClientRect();
+ const clip = r.left < sb.left || r.right > sb.right || r.top < sb.top || r.bottom > sb.bottom;
+ return e.querySelector('.mtn-lbl-n').textContent + (clip ? ' CLIPPED' : '');
+ }),
+ stepRows: new Set([...sec.querySelectorAll('.sw-mt-step')].map(e => Math.round(e.getBoundingClientRect().top))).size,
+ overflowX: document.documentElement.scrollWidth > document.documentElement.clientWidth,
+ };
+ });
+ console.log(`${s.name}: ` + JSON.stringify(info));
+ if (errs.length) console.log(' ERRORS:', errs.slice(0, 3));
+
+ await page.screenshot({ path: `/tmp/mt-${s.name}.png`, timeout: 90000 });
+ await browser.close();
+}
diff --git a/src/app/industries/page.tsx b/src/app/industries/page.tsx
new file mode 100644
index 0000000..2c13f2f
--- /dev/null
+++ b/src/app/industries/page.tsx
@@ -0,0 +1,35 @@
+import React from "react";
+import SolutionsHero from "@/components/sections/SolutionsHero";
+import IndustryStack from "@/components/sections/IndustryStack";
+
+/**
+ * Industries — "Who Doormile serves".
+ *
+ * This is the original industry-focused content that used to live at /solutions
+ * (see commit 205924e): the industry hero slider plus the IndustryStack cards
+ * ported from doormile-site/includes/sections/solution/card-1.php. The FMCG,
+ * Pharma and Enterprise & B2B copy is unchanged from that original; Retail and
+ * Quick Commerce were added later in the same layout.
+ *
+ * /solutions now answers "what Doormile offers" instead.
+ */
+export const metadata = {
+ title: "Industries – Doormile",
+ description:
+ "Discover how Doormile's connected logistics platform serves diverse industries — FMCG, Pharma, Enterprise & B2B, Retail and Quick Commerce — with tailored solutions.",
+};
+
+export default function IndustriesPage() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/app/miletruth/page.tsx b/src/app/miletruth/page.tsx
index 7cbb781..db69804 100644
--- a/src/app/miletruth/page.tsx
+++ b/src/app/miletruth/page.tsx
@@ -5,6 +5,14 @@ import Workflow1 from "../../components/sections/Workflow1";
import Workflow2 from "../../components/sections/Workflow2";
import Workflow4 from "../../components/sections/Workflow4";
import Workflow3Lazy from "../../components/sections/Workflow3Lazy";
+import {
+ SolutionAIVehicleSelection,
+ SolutionSmartRouteIntelligence,
+ SolutionQuantumDecisionEngine,
+ SolutionLiveLogisticsIntelligence,
+ SolutionMileTruthAI,
+ SolutionOperationsDashboard,
+} from "../../components/sections/SolutionsWorkflow";
export const metadata = {
title: "MileTruth – Doormile",
@@ -19,9 +27,15 @@ export default function MileTruthPage() {
+
+
+
+
+
+
diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts
index 219c488..8c6c1e6 100644
--- a/src/app/sitemap.ts
+++ b/src/app/sitemap.ts
@@ -10,11 +10,8 @@ export default function sitemap(): MetadataRoute.Sitemap {
"/contact",
"/blog",
"/air-freight",
- "/first-mile-delivery",
- "/mid-mile-delivery",
- "/last-mile-delivery",
- "/ev-logistics",
- "/strategy-optimization",
+ "/solutions",
+ "/industries",
"/how-it-works",
].map((route) => ({
url: `${SITE_URL}${route}`,
diff --git a/src/app/solutions/page.tsx b/src/app/solutions/page.tsx
index 7443256..39c8b3b 100644
--- a/src/app/solutions/page.tsx
+++ b/src/app/solutions/page.tsx
@@ -1,65 +1,119 @@
import React from "react";
-import SolutionsHero from "@/components/sections/SolutionsHero";
-import SolutionsWorkflow from "@/components/sections/SolutionsWorkflow";
+import SolutionsHero, { type HeroSlide } from "@/components/sections/SolutionsHero";
+import Miles3 from "@/components/sections/Miles3";
+import EVSection, { type EVFeature } from "@/components/sections/EVSection";
+import {
+ SolutionsSectionsShell,
+ SolOfferings,
+ SolWingsSpotlight,
+ SolMileTruthBand,
+ SolutionsWhyDoormile,
+ SolutionsResults,
+} from "@/components/sections/SolutionsSections";
+/**
+ * Solutions — "What Doormile offers".
+ *
+ * Services only: first mile, mid mile, last mile, Doormile Wings, EV fleet, and
+ * the fact that all of it is powered by MileTruth™. The technology story (AI
+ * architecture, routing, the decision engine) belongs to /miletruth and is
+ * deliberately not repeated here; industry detail belongs to /industries.
+ */
export const metadata = {
title: "Solutions – Doormile",
- description: "See how Doormile's AI-powered Logistics Intelligence Platform works end-to-end — from pickup and AI vehicle selection to Quantum routing, live shipment tracking, door-to-door movement, MileTruth AI and real-time operations monitoring.",
+ description:
+ "What Doormile offers: first mile pickup, mid mile line haul, last mile delivery, same-day air with Doormile Wings, and an electric fleet — every mile powered by MileTruth™.",
};
+const SOLUTIONS_SLIDES: HeroSlide[] = [
+ {
+ heading: "One Partner for Every Mile",
+ text: "First mile, mid mile and last mile — on road and in the air, with an electric fleet and one tracking link end to end.",
+ },
+ {
+ heading: "Everything Doormile Delivers",
+ text: "Take one service or the whole chain. Either way it is one contract, one team, and one place to see where your shipment is.",
+ },
+];
+
+/* Customer-facing framing of the EV fleet — the homepage section's own copy is
+ written around the EV-native platform design, which belongs on MileTruth. */
+const EV_FLEET_FEATURES: EVFeature[] = [
+ {
+ icon: (
+
+ ),
+ title: "Lower Cost Per Kilometre",
+ desc: "Electric running costs are a fraction of diesel, and that saving shows up on the miles you move with us.",
+ },
+ {
+ icon: (
+
+ ),
+ title: "No Range Surprises",
+ desc: "Charging is planned into the day before the vehicle leaves the depot, so an EV run arrives when a diesel run would.",
+ },
+ {
+ icon: (
+
+ ),
+ title: "Zero Tailpipe Emissions",
+ desc: "Clean deliveries into cities with low-emission zones, and a number you can put in your own sustainability reporting.",
+ },
+ {
+ icon: (
+
+ ),
+ title: "Built For Your Routes",
+ desc: "Urban and regional runs served by a fleet sized to the job, from small city vehicles to larger regional loads.",
+ },
+];
+
export default function SolutionsPage() {
return (
- <>
-
+
+
+
+
+
-
-
-
-
-
-
-
+ {/* One #sol-root scope for the whole page — the shell carries the
+ stylesheet and must not be rendered twice. Miles3 and EVSection
+ sit between beats; the shell's CSS is scoped to `.sol-*` only,
+ so their Elementor markup is unaffected. */}
+
+
+
+
+
+
+
+
+
- >
+
);
}
diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx
index 8ad69e7..55fe9c7 100644
--- a/src/components/layout/Footer.tsx
+++ b/src/components/layout/Footer.tsx
@@ -435,7 +435,7 @@ export default function Footer() {
How It Works
- Use Cases
+ Use Cases
Request Demo
diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx
index 9bb0c57..8f37e3b 100644
--- a/src/components/layout/Header.tsx
+++ b/src/components/layout/Header.tsx
@@ -19,6 +19,7 @@ const CURRENT_PAGE_MAP: Record = {
"/how-it-works": "how-it-works",
"/miletruth": "miletruth",
"/solutions": "solutions",
+ "/industries": "industries",
"/about": "about",
"/doormile-wings": "doormile-wings",
"/empowerment": "entarpreneurship",
@@ -38,6 +39,8 @@ const CURRENT_PAGE_ALIASES: Record = {
miletruth: ["miletruth"],
// Solutions is now a plain top-level link — no child pages own its active state.
solutions: ["solutions"],
+ // Industries is the sibling top-level link — "who Doormile serves".
+ industries: ["industries"],
"doormile-wings": ["doormile-wings"],
entarpreneurship: ["entarpreneurship"],
blogs: ["blogs"],
@@ -45,8 +48,8 @@ const CURRENT_PAGE_ALIASES: Record = {
"privacy-policy": ["privacy-policy"],
"terms-of-service": ["terms-of-service"],
"cookie-policy": ["cookie-policy"],
- // Company is the dropdown parent for About + Blogs + How It Works — active if any is.
- company: ["blogs", "how-it-works", "about"],
+ // Company is the dropdown parent for About + Industries + How It Works + Blogs — active if any is.
+ company: ["about", "industries", "how-it-works", "blogs"],
};
export default function Header() {
@@ -524,15 +527,13 @@ export default function Header() {
About