diff --git a/src/components/ClientLogos.astro b/src/components/ClientLogos.astro new file mode 100644 index 0000000..0f95e40 --- /dev/null +++ b/src/components/ClientLogos.astro @@ -0,0 +1,144 @@ +--- +/** + * ClientLogos Component + * + * Social-proof strip of client/partner logos shown beneath the hero on the + * homepage. Renders as a grayscale, lazy-loaded grid that pops to full colour + * on hover so the section stays subtle but credible. + * + * The component accepts an optional `clients` prop. Each entry can carry: + * - name: display name and accessible alt text (required) + * - logo: path to a logo image asset (optional). When provided the + * image is lazy-loaded and rendered grayscale; otherwise the + * name is rendered as a typographic wordmark fallback so the + * strip still renders intentionally while real assets are + * being collected. + * - href: optional outbound URL or internal anchor (e.g. a portfolio + * case study). Omitted entries render as non-interactive items. + * - subtitle: optional one-liner under the wordmark (e.g. "11 districts"). + * + * If no `clients` prop is supplied the component uses a sensible default set + * sourced from the active WorkRoot portfolio (PLNR, RENTEC, IIT Patna, MOC + * Soft Technologies, Government of Bihar). When the real logo assets land + * in `public/images/clients/.svg` simply add the `logo` field to the + * matching entry (see TODO block in this file) and the component will swap + * the wordmark for the image automatically. + * + * @prop {Array<{ name: string; logo?: string; href?: string; subtitle?: string }>} [clients] + * @prop {string} [heading] - Eyebrow text rendered above the strip + * @prop {'light' | 'dark'} [theme] - 'light' for white sections, 'dark' for + * dark/hero adjacent placement + * @prop {string} [class] - Extra classes merged onto the wrapper section + */ + +interface ClientEntry { + name: string; + logo?: string; + href?: string; + subtitle?: string; +} + +interface Props { + clients?: ClientEntry[]; + heading?: string; + theme?: 'light' | 'dark'; + class?: string; +} + +const { + clients, + heading = 'Trusted by teams shipping production software', + theme = 'light', + class: extraClass = '', +} = Astro.props; + +// ----------------------------------------------------------------------------- +// Default client roster — sourced from the live portfolio and testimonials. +// TODO(frontend-specialist): drop real SVG/PNG wordmarks into +// public/images/clients/.svg +// and populate the `logo` field below. Required asset slugs: +// - plnr.svg (PLNR Financing platform) +// - rentec.svg (RENTEC / FPC Cart) +// - iit-patna.svg (IIT Patna University Management) +// - moc-soft.svg (MOC Soft Technologies) +// - gov-bihar.svg (Government of Bihar — Police Management / SCMS) +// Logos should be supplied as monochrome SVG on a transparent background and +// sized roughly 160 × 48 — the grayscale filter handles the rest. +// ----------------------------------------------------------------------------- +const defaultClients: ClientEntry[] = [ + { name: 'PLNR', subtitle: 'Financing Platform' }, + { name: 'RENTEC', subtitle: 'FPC Cart' }, + { name: 'IIT Patna', subtitle: 'University System' }, + { name: 'MOC Soft Technologies', subtitle: 'Enterprise Partner' }, + { name: 'Govt. of Bihar', subtitle: '11 Districts' }, +]; + +const items: ClientEntry[] = clients && clients.length > 0 ? clients : defaultClients; + +const isDark = theme === 'dark'; + +const sectionClass = [ + 'relative', + isDark + ? 'bg-secondary-900' + : 'bg-white dark:bg-secondary-900', + extraClass, +].filter(Boolean).join(' '); + +const eyebrowClass = isDark + ? 'text-xs sm:text-sm uppercase tracking-[0.2em] text-secondary-400 font-semibold' + : 'text-xs sm:text-sm uppercase tracking-[0.2em] text-secondary-500 dark:text-secondary-400 font-semibold'; + +const wordmarkClass = isDark + ? 'text-lg sm:text-xl font-bold text-white/80 group-hover:text-white transition-colors' + : 'text-lg sm:text-xl font-bold text-secondary-700 dark:text-secondary-200 group-hover:text-secondary-900 dark:group-hover:text-white transition-colors'; + +const subtitleClass = isDark + ? 'block text-[11px] uppercase tracking-wider text-secondary-500 mt-1' + : 'block text-[11px] uppercase tracking-wider text-secondary-400 dark:text-secondary-500 mt-1'; + +const imageFilter = 'grayscale opacity-70 group-hover:grayscale-0 group-hover:opacity-100 transition-all duration-300'; +--- + +
+
+

{heading}

+ +
    + {items.map((client) => { + const Wrapper = client.href ? 'a' : 'div'; + const wrapperProps = client.href + ? { href: client.href, 'aria-label': `Learn more about ${client.name}` } + : { 'aria-label': client.name }; + return ( +
  • + + {client.logo ? ( + {`${client.name} + ) : ( + {client.name} + )} + {client.subtitle && ( + {client.subtitle} + )} + +
  • + ); + })} +
+
+
diff --git a/src/pages/index.astro b/src/pages/index.astro index 5ec8b86..406787a 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -2,6 +2,7 @@ // Home page - WorkRoot IT Solutions import BaseLayout from '../layouts/BaseLayout.astro'; import SEO from '../components/SEO.astro'; +import ClientLogos from '../components/ClientLogos.astro'; // Benefits/Features data const benefits = [ @@ -27,30 +28,39 @@ const benefits = [ }, ]; -// Services data +// Services data — outcome-led headlines with anchor slugs that deep-link +// into the matching detail sections on /services. const services = [ { icon: 'code', + slug: 'web-development', title: 'Web Development', - description: 'Custom web applications built with Angular, React, Next.js, Astro, and Spring Boot.', + outcome: 'Ship a fast, SEO-ready web product your customers actually convert on.', + description: 'Angular, React, Next.js, Astro frontends backed by Spring Boot APIs — built for speed, scale, and search visibility.', features: ['Angular/React/Next.js', 'Spring Boot APIs', 'Astro Static Sites'], }, { icon: 'smartphone', + slug: 'mobile-development', title: 'Mobile Apps', - description: 'Cross-platform and native mobile applications for iOS and Android.', + outcome: 'Launch on iOS and Android from a single codebase — without the native-team overhead.', + description: 'Cross-platform React Native and Expo apps with offline-first sync, push notifications, and store-ready builds.', features: ['React Native / Expo', 'iOS & Android', 'Offline-First Apps'], }, { icon: 'brain', + slug: 'erp-solutions', title: 'ERP & Enterprise Systems', - description: 'Custom ERP, CRM, and management systems for enterprises and government bodies.', + outcome: 'Replace spreadsheets and ageing tools with one system your operations team trusts.', + description: 'Custom ERP, CRM, and admin platforms designed around your real workflows — already running in universities and government bodies.', features: ['University Management', 'Police Management', 'Crematorium SCMS'], }, { icon: 'cloud', + slug: 'government-systems', title: 'Government IT Solutions', - description: 'Scalable technology solutions deployed across government departments and districts.', + outcome: 'Roll out secure, compliant platforms across districts without rewriting them for each one.', + description: 'Multi-district deployments with role-based access, audit trails, and the uptime public services require.', features: ['Multi-District Deployments', 'Secure & Compliant', 'High Availability'], }, ]; @@ -143,7 +153,7 @@ const faqs = [