First Init
Deploy to Production / Build & Verify (push) Failing after 5m56s
Ping Search Engines / Notify Search Engines (push) Successful in 2s
Deploy to Production / Pre-Deploy Tests (push) Has been skipped
Deploy to Production / Deploy to Railway (push) Has been skipped
Deploy to Production / Deploy to Render (push) Has been skipped
Deploy to Production / Deploy to VPS (PM2) (push) Has been skipped
Deploy to Production / Deploy to Fly.io (push) Has been skipped
Deploy to Production / Post-Deploy Verification (push) Has been skipped
Deploy to Production / Notify on Failure (push) Successful in 2s
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
E2E Test Suite / Smoke Tests (P0) (push) Failing after 11m26s
E2E Test Suite / Form Interaction Tests (push) Failing after 11m42s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 12m2s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 16m14s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 17m45s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 25m23s
E2E Test Suite / Security Header Tests (push) Failing after 7m55s
E2E Test Suite / Test Report Summary (push) Failing after 20s
E2E Test Suite / Mobile Device Tests (push) Failing after 2h49m9s
Uptime Monitor / Health & Response Time (push) Failing after 2s
Uptime Monitor / SSL Certificate (push) Successful in 2s
Uptime Monitor / Send Alerts (push) Failing after 3s
Uptime Monitor / Record Uptime Success (push) Has been skipped
Deploy to Production / Build & Verify (push) Failing after 5m56s
Ping Search Engines / Notify Search Engines (push) Successful in 2s
Deploy to Production / Pre-Deploy Tests (push) Has been skipped
Deploy to Production / Deploy to Railway (push) Has been skipped
Deploy to Production / Deploy to Render (push) Has been skipped
Deploy to Production / Deploy to VPS (PM2) (push) Has been skipped
Deploy to Production / Deploy to Fly.io (push) Has been skipped
Deploy to Production / Post-Deploy Verification (push) Has been skipped
Deploy to Production / Notify on Failure (push) Successful in 2s
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
E2E Test Suite / Smoke Tests (P0) (push) Failing after 11m26s
E2E Test Suite / Form Interaction Tests (push) Failing after 11m42s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 12m2s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 16m14s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 17m45s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 25m23s
E2E Test Suite / Security Header Tests (push) Failing after 7m55s
E2E Test Suite / Test Report Summary (push) Failing after 20s
E2E Test Suite / Mobile Device Tests (push) Failing after 2h49m9s
Uptime Monitor / Health & Response Time (push) Failing after 2s
Uptime Monitor / SSL Certificate (push) Successful in 2s
Uptime Monitor / Send Alerts (push) Failing after 3s
Uptime Monitor / Record Uptime Success (push) Has been skipped
This commit is contained in:
@@ -0,0 +1,351 @@
|
||||
---
|
||||
// Base Layout for WorkRoot IT Solutions
|
||||
// Features: SEO meta tags, global styles, header, footer slot, skip link
|
||||
|
||||
import Header from '../components/Header.astro';
|
||||
import Footer from '../components/Footer.astro';
|
||||
import Analytics from '../components/Analytics.astro';
|
||||
import PWAInstallPrompt from '../components/PWAInstallPrompt.astro';
|
||||
import '../styles/global.css';
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
description?: string;
|
||||
canonicalUrl?: string;
|
||||
ogImage?: string;
|
||||
noIndex?: boolean;
|
||||
}
|
||||
|
||||
const {
|
||||
title,
|
||||
description = 'WorkRoot IT Solutions - Professional IT services including web development, cloud solutions, and digital transformation for businesses.',
|
||||
canonicalUrl = Astro.url.href,
|
||||
ogImage = '/og-image.jpg',
|
||||
noIndex = false,
|
||||
} = Astro.props;
|
||||
|
||||
const siteName = 'WorkRoot IT Solutions';
|
||||
const fullTitle = title === 'Home' ? siteName : `${title} | ${siteName}`;
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en" class="scroll-smooth">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<!-- Primary Meta Tags -->
|
||||
<title>{fullTitle}</title>
|
||||
<meta name="title" content={fullTitle} />
|
||||
<meta name="description" content={description} />
|
||||
<meta name="author" content="WorkRoot IT Solutions" />
|
||||
<meta name="keywords" content="web development, mobile app development, AI solutions, machine learning, cloud services, IT consulting, digital transformation, custom software, enterprise solutions, React, Next.js, React Native, Flutter, AWS, Azure, Python, TensorFlow" />
|
||||
<meta name="language" content="English" />
|
||||
<meta name="revisit-after" content="7 days" />
|
||||
<meta name="rating" content="general" />
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
|
||||
<!-- Canonical URL -->
|
||||
<link rel="canonical" href={canonicalUrl} />
|
||||
|
||||
<!-- DNS Prefetch & Preconnect for external resources -->
|
||||
<link rel="dns-prefetch" href="https://images.unsplash.com" />
|
||||
<link rel="preconnect" href="https://images.unsplash.com" crossorigin />
|
||||
|
||||
<!-- Robots -->
|
||||
{noIndex ? (
|
||||
<meta name="robots" content="noindex, nofollow" />
|
||||
) : (
|
||||
<meta name="robots" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1" />
|
||||
)}
|
||||
<meta name="googlebot" content="index, follow" />
|
||||
<meta name="bingbot" content="index, follow" />
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content={canonicalUrl} />
|
||||
<meta property="og:title" content={fullTitle} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:image" content={new URL(ogImage, Astro.url).href} />
|
||||
<meta property="og:image:secure_url" content={new URL(ogImage, Astro.url).href} />
|
||||
<meta property="og:image:type" content="image/jpeg" />
|
||||
<meta property="og:image:alt" content={fullTitle} />
|
||||
<meta property="og:image:width" content="1200" />
|
||||
<meta property="og:image:height" content="630" />
|
||||
<meta property="og:site_name" content={siteName} />
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta property="fb:app_id" content="your-facebook-app-id" />
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:site" content="@workroot" />
|
||||
<meta name="twitter:creator" content="@workroot" />
|
||||
<meta name="twitter:url" content={canonicalUrl} />
|
||||
<meta name="twitter:title" content={fullTitle} />
|
||||
<meta name="twitter:description" content={description} />
|
||||
<meta name="twitter:image" content={new URL(ogImage, Astro.url).href} />
|
||||
<meta name="twitter:image:alt" content={fullTitle} />
|
||||
<meta name="twitter:domain" content="workroot.in" />
|
||||
<meta name="twitter:label1" content="Est. reading time" />
|
||||
<meta name="twitter:data1" content="3 minutes" />
|
||||
|
||||
<!-- Theme Color -->
|
||||
<meta name="theme-color" content="#0891b2" />
|
||||
|
||||
<!-- JSON-LD Structured Data - Organization Schema -->
|
||||
<script type="application/ld+json" set:html={JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "WorkRoot IT Solutions",
|
||||
"alternateName": "WorkRoot",
|
||||
"url": "https://workroot.in",
|
||||
"logo": {
|
||||
"@type": "ImageObject",
|
||||
"url": "https://workroot.in/logo.png",
|
||||
"width": "512",
|
||||
"height": "512"
|
||||
},
|
||||
"image": "https://workroot.in/og-image.jpg",
|
||||
"description": "Professional IT services including web development, cloud solutions, and digital transformation for businesses.",
|
||||
"foundingDate": "2014",
|
||||
"founder": {
|
||||
"@type": "Person",
|
||||
"name": "Sarah Chen"
|
||||
},
|
||||
"address": {
|
||||
"@type": "PostalAddress",
|
||||
"streetAddress": "123 Tech Plaza, Suite 400",
|
||||
"addressLocality": "San Francisco",
|
||||
"addressRegion": "CA",
|
||||
"postalCode": "94105",
|
||||
"addressCountry": "US"
|
||||
},
|
||||
"contactPoint": [{
|
||||
"@type": "ContactPoint",
|
||||
"telephone": "+1-555-123-4567",
|
||||
"contactType": "customer service",
|
||||
"email": "hello@workroot.in",
|
||||
"availableLanguage": ["English"],
|
||||
"areaServed": "Worldwide"
|
||||
}, {
|
||||
"@type": "ContactPoint",
|
||||
"telephone": "+1-555-123-4567",
|
||||
"contactType": "sales",
|
||||
"email": "sales@workroot.in",
|
||||
"availableLanguage": ["English"],
|
||||
"areaServed": "Worldwide"
|
||||
}],
|
||||
"sameAs": [
|
||||
"https://twitter.com/workroot",
|
||||
"https://linkedin.com/company/workroot",
|
||||
"https://github.com/workroot",
|
||||
"https://facebook.com/workroot"
|
||||
],
|
||||
"areaServed": {
|
||||
"@type": "GeoShape",
|
||||
"name": "Worldwide"
|
||||
},
|
||||
"serviceType": ["Web Development", "Mobile App Development", "AI & Machine Learning", "Cloud Services"],
|
||||
"knowsAbout": ["Web Development", "Software Engineering", "Cloud Computing", "Artificial Intelligence", "Machine Learning", "Mobile Development"],
|
||||
"slogan": "Transforming Ideas Into Digital Reality",
|
||||
"aggregateRating": {
|
||||
"@type": "AggregateRating",
|
||||
"ratingValue": "4.9",
|
||||
"reviewCount": "127",
|
||||
"bestRating": "5",
|
||||
"worstRating": "1"
|
||||
}
|
||||
})} />
|
||||
|
||||
<!-- JSON-LD Structured Data - WebSite Schema -->
|
||||
<script type="application/ld+json" set:html={JSON.stringify({
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebSite",
|
||||
"name": "WorkRoot IT Solutions",
|
||||
"url": "https://workroot.in",
|
||||
"description": "Professional IT services including web development, cloud solutions, and digital transformation for businesses.",
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "WorkRoot IT Solutions"
|
||||
},
|
||||
"potentialAction": {
|
||||
"@type": "SearchAction",
|
||||
"target": {
|
||||
"@type": "EntryPoint",
|
||||
"urlTemplate": "https://workroot.in/blog?search={search_term_string}"
|
||||
},
|
||||
"query-input": "required name=search_term_string"
|
||||
},
|
||||
"inLanguage": "en-US"
|
||||
})} />
|
||||
|
||||
<!-- Preconnect to Google Fonts (must come before font stylesheet) -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
|
||||
<!-- Non-blocking font load: Plus Jakarta Sans (variable) + JetBrains Mono (variable) -->
|
||||
<!-- Replaces the render-blocking @import that was previously in global.css -->
|
||||
<link
|
||||
rel="preload"
|
||||
as="style"
|
||||
href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap"
|
||||
onload="this.onload=null;this.rel='stylesheet'"
|
||||
/>
|
||||
<noscript>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&family=JetBrains+Mono:ital,wght@0,100..800;1,100..800&display=swap" />
|
||||
</noscript>
|
||||
|
||||
<!-- Critical CSS for above-the-fold content -->
|
||||
<style is:inline>
|
||||
/* Critical CSS for faster FCP - system fonts render immediately */
|
||||
*,*::before,*::after{box-sizing:border-box}
|
||||
html{line-height:1.5;-webkit-text-size-adjust:100%;scroll-behavior:smooth}
|
||||
body{margin:0;font-family:'Plus Jakarta Sans',system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;min-height:100vh;display:flex;flex-direction:column;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
|
||||
img,video{max-width:100%;height:auto;display:block}
|
||||
/* Prevent layout shift from lazy images */
|
||||
img[loading="lazy"]{background:#e2e8f0}
|
||||
/* Prevent CLS from images without explicit dimensions */
|
||||
img{aspect-ratio:attr(width)/attr(height)}
|
||||
/* Hero section above-the-fold critical styles */
|
||||
.min-h-screen{min-height:100vh}
|
||||
.flex{display:flex}
|
||||
.flex-col{flex-direction:column}
|
||||
.items-center{align-items:center}
|
||||
/* Prevent animation flicker on initial load */
|
||||
.animate-slide-up{animation-fill-mode:forwards}
|
||||
/* Skip link - always accessible */
|
||||
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}
|
||||
</style>
|
||||
|
||||
<!-- Analytics (GA4 or Plausible) -->
|
||||
<Analytics />
|
||||
|
||||
<!-- Additional head content slot -->
|
||||
<slot name="head" />
|
||||
</head>
|
||||
|
||||
<body class="min-h-screen flex flex-col antialiased">
|
||||
<!-- Skip to main content link for accessibility -->
|
||||
<a
|
||||
href="#main-content"
|
||||
class="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-[100] focus:px-4 focus:py-2 focus:bg-primary focus:text-white focus:rounded-lg focus:outline-none focus:ring-2 focus:ring-primary-400 focus:ring-offset-2"
|
||||
>
|
||||
Skip to main content
|
||||
</a>
|
||||
|
||||
<!-- Header -->
|
||||
<Header />
|
||||
|
||||
<!-- Main Content -->
|
||||
<main id="main-content" class="flex-1" tabindex="-1">
|
||||
<slot />
|
||||
</main>
|
||||
|
||||
<!-- Footer -->
|
||||
<Footer />
|
||||
|
||||
<!-- Scripts slot for page-specific scripts -->
|
||||
<slot name="scripts" />
|
||||
|
||||
<!-- Global external link tracking -->
|
||||
<script>
|
||||
import { bindExternalLinkTracking } from '../utils/analytics';
|
||||
document.addEventListener('DOMContentLoaded', bindExternalLinkTracking);
|
||||
</script>
|
||||
|
||||
<!-- Scroll-reveal & micro-interactions -->
|
||||
<script>
|
||||
import { initAllAnimations } from '../utils/animations';
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initAllAnimations);
|
||||
} else {
|
||||
initAllAnimations();
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Button radial highlight (cursor tracker) -->
|
||||
<script>
|
||||
function initButtonHighlight() {
|
||||
document.querySelectorAll<HTMLElement>('.btn-primary, .btn-primary-lg, .btn-accent').forEach((btn) => {
|
||||
btn.addEventListener('mousemove', (e: MouseEvent) => {
|
||||
const rect = btn.getBoundingClientRect();
|
||||
const x = ((e.clientX - rect.left) / rect.width) * 100;
|
||||
const y = ((e.clientY - rect.top) / rect.height) * 100;
|
||||
btn.style.setProperty('--x', `${x}%`);
|
||||
btn.style.setProperty('--y', `${y}%`);
|
||||
});
|
||||
});
|
||||
}
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initButtonHighlight);
|
||||
} else {
|
||||
initButtonHighlight();
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Service Worker Registration -->
|
||||
<script>
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
navigator.serviceWorker
|
||||
.register('/sw.js', { scope: '/' })
|
||||
.catch(() => {
|
||||
// SW registration failed silently — site still works normally
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- PWA Install Prompt -->
|
||||
<PWAInstallPrompt />
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<style is:global>
|
||||
/* Smooth scrolling for anchor links */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
/* Focus styles for accessibility */
|
||||
:focus-visible {
|
||||
outline: 2px solid theme('colors.primary.DEFAULT');
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* Remove focus outline for mouse users */
|
||||
:focus:not(:focus-visible) {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Selection color */
|
||||
::selection {
|
||||
background-color: theme('colors.primary.200');
|
||||
color: theme('colors.secondary.900');
|
||||
}
|
||||
|
||||
/* Custom scrollbar (optional - webkit only) */
|
||||
::-webkit-scrollbar {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: theme('colors.secondary.100');
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: theme('colors.secondary.300');
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: theme('colors.secondary.400');
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user