From 408524e28b037be9d62baac745b9bbced9077dbe Mon Sep 17 00:00:00 2001 From: Adithya-K29 Date: Mon, 9 Feb 2026 18:17:07 +0530 Subject: [PATCH 01/13] feat: Add hiring process timeline to careers page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add comprehensive 5-step hiring process section with: - Horizontal timeline for desktop with connecting line - Vertical timeline for mobile with step indicators - Glassmorphic cards with icons for each step - Scroll animations and hover effects - 2-3 week timeline callout Steps: Application → TA Screening → HM Screening → Interviews → Offer Release Co-Authored-By: Claude Sonnet 4.5 --- app/careers/page.tsx | 358 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 357 insertions(+), 1 deletion(-) diff --git a/app/careers/page.tsx b/app/careers/page.tsx index 3177838..0b7e5fe 100644 --- a/app/careers/page.tsx +++ b/app/careers/page.tsx @@ -320,12 +320,368 @@ export default function CareersPage() { + {/* ============================================ + HIRING PROCESS SECTION + ============================================ */} +
+ {/* Dot pattern */} +
+ +
+ +

+ How We Hire +

+

+ Our Hiring Process +

+

+ A transparent and efficient process designed to identify + exceptional talent. From application to offer, we move quickly + while ensuring the right fit for both sides. +

+
+ + {/* Timeline - Desktop (Horizontal) */} +
+
+ {/* Connecting line */} +
+ +
+ {[ + { + step: 1, + title: "Application Received", + description: + "Submit your application through our careers portal. We review all applications within 3-5 business days.", + icon: ( + + + + ), + }, + { + step: 2, + title: "TA Screening", + description: + "Quick call with our Talent Acquisition team to discuss your experience, career goals, and role expectations.", + icon: ( + + + + ), + }, + { + step: 3, + title: "HM Screening", + description: + "Technical conversation with the Hiring Manager to deep-dive into your skills, project experience, and technical approach.", + icon: ( + + + + ), + }, + { + step: 4, + title: "Interviews", + description: + "Technical assessments and team conversations. Mix of coding exercises, system design, and cultural fit discussions.", + icon: ( + + + + ), + }, + { + step: 5, + title: "Offer Release", + description: + "Receive your offer with detailed compensation breakdown. We move fast and keep the process transparent.", + icon: ( + + + + ), + }, + ].map((item, idx) => ( + + {/* Step number circle */} +
+
+ {/* Glow effect */} +
+
+
{item.icon}
+
+
+
+ + {/* Card */} +
+
+
+
+ STEP {item.step} +
+

+ {item.title} +

+

+ {item.description} +

+
+
+ + ))} +
+
+
+ + {/* Timeline - Mobile (Vertical) */} +
+ {[ + { + step: 1, + title: "Application Received", + description: + "Submit your application through our careers portal. We review all applications within 3-5 business days.", + icon: ( + + + + ), + }, + { + step: 2, + title: "TA Screening", + description: + "Quick call with our Talent Acquisition team to discuss your experience, career goals, and role expectations.", + icon: ( + + + + ), + }, + { + step: 3, + title: "HM Screening", + description: + "Technical conversation with the Hiring Manager to deep-dive into your skills, project experience, and technical approach.", + icon: ( + + + + ), + }, + { + step: 4, + title: "Interviews", + description: + "Technical assessments and team conversations. Mix of coding exercises, system design, and cultural fit discussions.", + icon: ( + + + + ), + }, + { + step: 5, + title: "Offer Release", + description: + "Receive your offer with detailed compensation breakdown. We move fast and keep the process transparent.", + icon: ( + + + + ), + }, + ].map((item, idx) => ( + + {/* Timeline line */} + {idx < 4 && ( +
+ )} + + {/* Step number circle */} +
+
+
+
{item.icon}
+
+
+ + {/* Card */} +
+
+
+
+ STEP {item.step} +
+

+ {item.title} +

+

+ {item.description} +

+
+
+ + ))} +
+ + {/* Additional info */} + +

+ + Total timeline: 2-3 weeks. + {" "} + We value your time and move quickly through each stage. You will + have a dedicated point of contact throughout the process to answer + questions and provide updates. +

+
+
+
+ {/* ============================================ JOB OPENINGS SECTION - KEKA EMBED ============================================ */}
{/* Hexagon pattern */}
Date: Mon, 9 Feb 2026 19:05:59 +0530 Subject: [PATCH 02/13] feat: Add JsonLd component and update Organization schema (#70) * feat: Add 6 new Claude Code skills from skills.sh Installed the following skills for enhanced development capabilities: - vercel-react-best-practices: React optimization patterns - next-best-practices: Next.js App Router best practices - schema-markup: SEO structured data implementation - content-strategy: Content planning and strategy - browser-use: Browser automation and testing - audit-website: Website quality and compliance auditing Skills are stored in .agents/skills/ with symlinks in .claude/skills/ Co-Authored-By: Claude Opus 4.5 * feat: Add JsonLd component and update Organization schema - Created reusable JsonLd component in components/seo/ - Updated Organization schema to match specification: - Added alternateName, contactPoint, and aggregateRating - Updated logo path to /logo.svg - Simplified sameAs links to core platforms - Removed redundant fields (founder, employee, knowsAbout) - Replaced inline schema scripts with JsonLd component - Improved code maintainability and reusability Part of schema markup implementation following schema-implementation-for-claude-code.md Co-Authored-By: Claude Sonnet 4.5 * feat: Enhance Organization schema with Wikidata references - Added Wikidata entity ID as @id for Organization - Added Wikidata references for both founders (CEO and CTO) - Added foundingLocation (Mumbai, India) - Expanded sameAs to include all social/business profiles - Added founder details with LinkedIn profiles - Added knowsAbout for semantic relevance - Ensures semantic alignment with Wikidata Q137392993 This creates a strong semantic web connection between: - procedure.tech (our website) - Wikidata Q137392993 (Procedure Technologies entity) - Wikidata Q137392996 (Brajkishor Baheti entity) - Wikidata Q137392995 (Ulhas Mandrawadkar entity) Co-Authored-By: Claude Sonnet 4.5 * fix: Add proper OpenGraph and Twitter card images across all pages - Blog posts: Add fallback to default OG image when featured image is invalid/missing - Services/expertise pages: Add OG images and Twitter card metadata - Industries pages: Add OG images to metadata - Case studies: Add OG images with fallback and Twitter card metadata - All OG images now include width, height, and alt properties for better social sharing Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: Claude Opus 4.5 --- app/blogs/[slug]/page.tsx | 28 ++++++++++- app/blogs/page.tsx | 18 +++++++ app/industries/[slug]/page.tsx | 10 ++++ app/layout.tsx | 89 ++++++++++++++++------------------ app/services/[slug]/page.tsx | 34 +++++++++++++ app/work/[slug]/page.tsx | 35 ++++++++++++- components/seo/JsonLd.tsx | 17 +++++++ components/seo/index.ts | 1 + 8 files changed, 181 insertions(+), 51 deletions(-) create mode 100644 components/seo/JsonLd.tsx create mode 100644 components/seo/index.ts diff --git a/app/blogs/[slug]/page.tsx b/app/blogs/[slug]/page.tsx index 2ca968c..6c6bd5c 100644 --- a/app/blogs/[slug]/page.tsx +++ b/app/blogs/[slug]/page.tsx @@ -52,6 +52,15 @@ export async function generateStaticParams() { } } +// Helper to check if an image URL is a valid local path (not a temporary Notion URL) +function isValidOgImage(url: string | null | undefined): boolean { + if (!url) return false; + // Skip Notion temporary URLs and default placeholder + if (url.includes("amazonaws.com") || url.includes("notion.so")) return false; + if (url === "/blog/default.jpg") return false; + return true; +} + // Generate metadata for SEO export async function generateMetadata({ params, @@ -65,6 +74,21 @@ export async function generateMetadata({ }; } + // Use post featured image if valid, otherwise fall back to default OG image + const ogImage = isValidOgImage(post.featuredImage) + ? { + url: post.featuredImage!, + width: 1200, + height: 630, + alt: post.title, + } + : { + url: "/og-image.png", + width: 1200, + height: 630, + alt: "Procedure - AI Engineering Services", + }; + return { title: `${post.title} | Procedure Blog`, description: post.excerpt, @@ -78,13 +102,13 @@ export async function generateMetadata({ modifiedTime: post.updatedAt, authors: [post.author.name], tags: post.tags, - images: post.featuredImage ? [post.featuredImage] : undefined, + images: [ogImage], }, twitter: { card: "summary_large_image", title: post.title, description: post.excerpt, - images: post.featuredImage ? [post.featuredImage] : undefined, + images: [ogImage], site: "@procedurehq", creator: "@procedurehq", }, diff --git a/app/blogs/page.tsx b/app/blogs/page.tsx index 5daeabe..2d7ee4e 100644 --- a/app/blogs/page.tsx +++ b/app/blogs/page.tsx @@ -12,6 +12,14 @@ import { BlogListingClient } from "./BlogListingClient"; export const dynamic = "force-static"; export const revalidate = false; +// Default OG image configuration +const defaultOgImage = { + url: "/og-image.png", + width: 1200, + height: 630, + alt: "Procedure - AI Engineering Services", +}; + export const metadata: Metadata = { title: "Blog | AI Engineering Insights | Procedure", description: @@ -21,6 +29,16 @@ export const metadata: Metadata = { description: "Expert insights on AI engineering, LLM applications, production systems, and enterprise AI.", type: "website", + images: [defaultOgImage], + }, + twitter: { + card: "summary_large_image", + title: "Blog | AI Engineering Insights | Procedure", + description: + "Expert insights on AI engineering, LLM applications, production systems, and enterprise AI.", + images: [defaultOgImage], + site: "@procedurehq", + creator: "@procedurehq", }, }; diff --git a/app/industries/[slug]/page.tsx b/app/industries/[slug]/page.tsx index ff58b86..bb7a970 100644 --- a/app/industries/[slug]/page.tsx +++ b/app/industries/[slug]/page.tsx @@ -23,6 +23,14 @@ export async function generateStaticParams() { return getAllIndustrySlugsFromContent().map((slug) => ({ slug })); } +// Default OG image configuration +const defaultOgImage = { + url: "/og-image.png", + width: 1200, + height: 630, + alt: "Procedure - AI Engineering Services", +}; + export async function generateMetadata({ params, }: PageProps): Promise { @@ -45,11 +53,13 @@ export async function generateMetadata({ title: page.meta.title, description: page.meta.description, type: "website", + images: [defaultOgImage], }, twitter: { card: "summary_large_image", title: page.meta.title, description: page.meta.description, + images: [defaultOgImage], site: "@procedurehq", creator: "@procedurehq", }, diff --git a/app/layout.tsx b/app/layout.tsx index 808aa97..0612ceb 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -5,6 +5,7 @@ import { Footer } from "@/components/footer"; import { FooterReveal } from "@/components/FooterReveal"; import { CookieBanner } from "@/components/CookieBanner"; import { Analytics } from "@/components/Analytics"; +import { JsonLd } from "@/components/seo"; import { siteConfig, getThemeClass } from "@/lib/site-config"; import "./globals.css"; @@ -98,19 +99,31 @@ export default function RootLayout({ "@context": "https://schema.org", "@type": "Organization", "@id": "https://procedure.tech/#organization", - name: "Procedure", - legalName: "Procedure Technologies", + name: "Procedure Technologies", + alternateName: "Procedure", url: "https://procedure.tech", - logo: "https://upload.wikimedia.org/wikipedia/commons/7/7f/Procedure-logo.png", - foundingDate: "2017", + logo: "https://procedure.tech/logo.svg", description: - "AI engineering that ships to production. Senior engineers embedded with your team to build AI-powered products and secure AI systems. Battle-tested delivery, now focused on AI.", + "AI-native design & development studio. Senior AI engineers embedded with your team to build production-grade AI systems, LLM applications, and custom ML models.", + foundingDate: "2017", + foundingLocation: { + "@type": "Place", + name: "Mumbai, India", + }, + sameAs: [ + "https://www.wikidata.org/wiki/Q137392993", + "https://www.linkedin.com/company/procedure-tech", + "https://github.com/aspect-build", + "https://www.glassdoor.co.in/Reviews/Procedure-Technologies-Reviews-E2578960.htm", + "https://www.crunchbase.com/organization/procedure", + "https://in.linkedin.com/company/procedurehq", + "https://x.com/procedurehq", + "https://github.com/proceduretech", + ], address: [ { "@type": "PostalAddress", - streetAddress: "406, Shrishti Square, LBS Marg, Bhandup West", addressLocality: "Mumbai", - postalCode: "400078", addressCountry: "IN", }, { @@ -120,46 +133,41 @@ export default function RootLayout({ addressCountry: "US", }, ], - areaServed: "Worldwide", - sameAs: [ - "https://www.wikidata.org/wiki/Q137392993", - "https://www.crunchbase.com/organization/procedure", - "https://in.linkedin.com/company/procedurehq", - "https://x.com/procedurehq", - "https://github.com/proceduretech", - ], + contactPoint: { + "@type": "ContactPoint", + contactType: "sales", + email: "hello@procedure.tech", + availableLanguage: ["English"], + }, founder: [ { "@type": "Person", + "@id": "https://www.wikidata.org/wiki/Q137392996", name: "Brajkishor Baheti", jobTitle: "Chief Executive Officer", + sameAs: "https://www.linkedin.com/in/brajkishor", }, { "@type": "Person", + "@id": "https://www.wikidata.org/wiki/Q137392995", name: "Ulhas Mandrawadkar", jobTitle: "Chief Technology Officer", + sameAs: "https://www.linkedin.com/in/ulhasmandrawadkar", }, ], - employee: [ - { - "@type": "Person", - name: "Brajkishor Baheti", - jobTitle: "Chief Executive Officer", - }, - { - "@type": "Person", - name: "Ulhas Mandrawadkar", - jobTitle: "Chief Technology Officer", - }, - ], + aggregateRating: { + "@type": "AggregateRating", + ratingValue: "4.9", + reviewCount: "32", + bestRating: "5", + }, knowsAbout: [ "Artificial Intelligence", "Machine Learning", "AI Security", - "Product Engineering", + "LLM Applications", + "Software Engineering", "Cloud Computing", - "DevOps", - "Product Design", ], }; @@ -341,24 +349,9 @@ export default function RootLayout({ {/* Analytics (GA4, GTM, Clarity) loaded via client component - only on production */} -