diff --git a/404.html b/404.html
new file mode 100644
index 0000000..4bdd456
--- /dev/null
+++ b/404.html
@@ -0,0 +1,219 @@
+---
+layout: default
+title: Page Not Found
+description: The page you're looking for could not be found. Return to CodeStorm Hub homepage or explore our services.
+keywords: 404, page not found, error
+permalink: /404.html
+---
+
+
+
+
+
+
+
Page Not Found
+
+ Oops! The page you're looking for seems to have wandered off into the digital void.
+ Don't worry, even the best code sometimes takes unexpected paths.
+
+
+
+
+
+
+
+
+
+
+
Maybe you're looking for:
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..0c2a3a7
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,50 @@
+source "https://rubygems.org"
+# Hello! This is where you manage which Jekyll version is used to run.
+# When you want to use a different version, change it below, save the
+# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
+#
+# bundle exec jekyll serve
+#
+# This will help ensure the proper Jekyll version is running.
+# Happy Jekylling!
+
+# Use GitHub Pages compatible version
+gem "github-pages", "~> 231", group: :jekyll_plugins
+
+# If you want to use Jekyll native, uncomment this line:
+# gem "jekyll", "~> 4.3.3"
+
+# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
+# and associated library.
+platforms :mingw, :x64_mingw, :mswin, :jruby do
+ gem "tzinfo", ">= 1", "< 3"
+ gem "tzinfo-data"
+end
+
+# Performance-booster for watching directories on Windows
+gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
+
+# Lock `http_parser.rb` gem to `v0.6.x` on JRuby builds since newer versions of the gem
+# do not have a Java counterpart.
+gem "http_parser.rb", "~> 0.6.0", :platforms => [:jruby]
+
+# Jekyll plugins for enhanced functionality
+group :jekyll_plugins do
+ gem "jekyll-feed", "~> 0.12"
+ gem "jekyll-sitemap"
+ gem "jekyll-seo-tag"
+ gem "jekyll-paginate"
+ gem "jekyll-compose"
+ gem "jekyll-redirect-from"
+ gem "jekyll-minifier"
+ gem "jekyll-imageoptim"
+end
+
+# Development and testing gems
+group :development, :test do
+ gem "html-proofer"
+ gem "rake"
+ gem "rspec"
+ gem "capybara"
+ gem "selenium-webdriver"
+end
\ No newline at end of file
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..a0bad86
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,132 @@
+require 'rake'
+require 'rspec/core/rake_task'
+require 'html-proofer'
+
+# Default task
+task default: [:test]
+
+# Define test task
+task test: [:spec, :htmlproofer]
+
+# RSpec task
+RSpec::Core::RakeTask.new(:spec) do |t|
+ t.pattern = 'spec/**/*_spec.rb'
+ t.rspec_opts = '--format documentation --color'
+end
+
+# Jekyll build task
+task :build do
+ puts "Building Jekyll site..."
+ system('bundle exec jekyll build')
+end
+
+# Jekyll serve task for development
+task :serve do
+ puts "Starting Jekyll development server..."
+ system('bundle exec jekyll serve --livereload')
+end
+
+# HTML Proofer task for link checking
+task :htmlproofer => :build do
+ puts "Running HTML Proofer..."
+ HTMLProofer.check_directory(
+ "./_site",
+ {
+ assume_extension: true,
+ check_html: true,
+ check_img_http: true,
+ disable_external: true, # Disable external link checking for faster tests
+ empty_alt_ignore: true,
+ allow_hash_href: true,
+ url_ignore: [/localhost/, /127.0.0.1/, /example\.com/]
+ }
+ ).run
+end
+
+# Lighthouse performance testing (requires lighthouse CLI)
+task :lighthouse => :build do
+ puts "Running Lighthouse audit..."
+ urls = ['http://localhost:4000/', 'http://localhost:4000/about/', 'http://localhost:4000/contact/']
+
+ # Start Jekyll server for testing
+ pid = spawn('bundle exec jekyll serve --port 4000')
+ sleep 5 # Wait for server to start
+
+ begin
+ urls.each do |url|
+ puts "Auditing #{url}..."
+ system("npx lighthouse #{url} --chrome-flags='--headless' --quiet --output json --output-path /tmp/lighthouse-#{url.gsub(/[^\w]/, '')}.json")
+ end
+ ensure
+ Process.kill('TERM', pid)
+ end
+end
+
+# Security audit task
+task :security do
+ puts "Running security checks..."
+
+ # Check for common security issues
+ puts "Checking for exposed sensitive files..."
+ sensitive_files = ['.env', '.env.local', 'config/database.yml', 'id_rsa', '.ssh/']
+
+ sensitive_files.each do |file|
+ if File.exist?(file)
+ puts "WARNING: Sensitive file #{file} found!"
+ end
+ end
+
+ # Check for CSP headers in _config.yml
+ if File.exist?('_config.yml')
+ config = File.read('_config.yml')
+ unless config.include?('content_security_policy') || config.include?('csp')
+ puts "RECOMMENDATION: Add Content Security Policy headers"
+ end
+ end
+
+ puts "Security check complete."
+end
+
+# Clean task
+task :clean do
+ puts "Cleaning build artifacts..."
+ FileUtils.rm_rf(['./_site', './.sass-cache', './.jekyll-cache'])
+end
+
+# Deploy task (for GitHub Pages)
+task :deploy => [:test, :build] do
+ puts "Site ready for deployment!"
+ puts "Commit and push to main branch to deploy to GitHub Pages."
+end
+
+# Development workflow task
+task :dev do
+ puts "Starting development workflow..."
+ puts "1. Installing dependencies..."
+ system('bundle install')
+
+ puts "2. Building site..."
+ Rake::Task[:build].execute
+
+ puts "3. Running tests..."
+ Rake::Task[:test].execute
+
+ puts "4. Starting development server..."
+ Rake::Task[:serve].execute
+end
+
+desc "Show available tasks"
+task :help do
+ puts "Available tasks:"
+ puts " rake build - Build the Jekyll site"
+ puts " rake serve - Start development server"
+ puts " rake test - Run all tests"
+ puts " rake spec - Run RSpec tests only"
+ puts " rake htmlproofer - Run HTML validation"
+ puts " rake lighthouse - Run Lighthouse audit"
+ puts " rake security - Run security checks"
+ puts " rake clean - Clean build artifacts"
+ puts " rake deploy - Test and prepare for deployment"
+ puts " rake dev - Full development workflow"
+ puts " rake help - Show this help"
+end
\ No newline at end of file
diff --git a/_config.yml b/_config.yml
index d45562d..27059bb 100644
--- a/_config.yml
+++ b/_config.yml
@@ -70,4 +70,31 @@ social:
google_analytics: G-XXXXXXXXXX
# Contact form settings
-contact_form_action: "https://formspree.io/f/your-form-id"
\ No newline at end of file
+contact_form_action: "https://formspree.io/f/your-form-id"
+
+# Performance and SEO settings
+permalink: pretty
+future: false
+show_drafts: false
+safe: true
+
+# Compression settings
+sass:
+ style: compressed
+ sourcemap: never
+
+# Content Security Policy
+content_security_policy:
+ default_src: "'self'"
+ script_src: "'self' 'unsafe-inline' https://www.googletagmanager.com https://www.google-analytics.com https://cdnjs.cloudflare.com"
+ style_src: "'self' 'unsafe-inline' https://fonts.googleapis.com https://cdnjs.cloudflare.com"
+ font_src: "'self' https://fonts.gstatic.com https://cdnjs.cloudflare.com"
+ img_src: "'self' data: https: *.google-analytics.com"
+ connect_src: "'self' https://www.google-analytics.com"
+
+# Additional meta tags
+meta_tags:
+ robots: "index, follow"
+ rating: "general"
+ distribution: "global"
+ charset: "utf-8"
\ No newline at end of file
diff --git a/_includes/breadcrumb.html b/_includes/breadcrumb.html
new file mode 100644
index 0000000..b263fed
--- /dev/null
+++ b/_includes/breadcrumb.html
@@ -0,0 +1,98 @@
+
+{% unless page.url == '/' %}
+
+
+
+
+
+ Home
+
+
+
+
+ {% assign crumbs = page.url | remove:'/index.html' | split: '/' %}
+ {% assign position = 2 %}
+
+ {% for crumb in crumbs offset: 1 %}
+ {% unless crumb == '' %}
+ {% assign crumb_limit = forloop.index | plus: 1 %}
+ {% assign crumb_url = '' %}
+ {% for part in crumbs limit: crumb_limit %}
+ {% unless part == '' %}
+ {% assign crumb_url = crumb_url | append: '/' | append: part %}
+ {% endunless %}
+ {% endfor %}
+
+ /
+
+ {% if forloop.last %}
+ {{ page.title | default: crumb | capitalize }}
+ {% else %}
+
+ {{ crumb | capitalize }}
+
+ {% endif %}
+
+
+ {% assign position = position | plus: 1 %}
+ {% endunless %}
+ {% endfor %}
+
+
+
+
+
+{% endunless %}
\ No newline at end of file
diff --git a/_includes/critical.css b/_includes/critical.css
new file mode 100644
index 0000000..d4f6c38
--- /dev/null
+++ b/_includes/critical.css
@@ -0,0 +1,306 @@
+/* Critical CSS - Above the fold styles for CodeStorm Hub */
+/* This file contains only the essential styles needed for the initial page render */
+
+/* CSS Variables - Essential only */
+:root {
+ --primary-color: #6366f1;
+ --primary-dark: #4f46e5;
+ --white: #ffffff;
+ --gray-100: #f3f4f6;
+ --gray-200: #e5e7eb;
+ --gray-500: #6b7280;
+ --gray-700: #374151;
+ --gray-900: #111827;
+ --font-primary: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
+ --font-heading: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
+ --text-base: 1rem;
+ --text-lg: 1.125rem;
+ --text-xl: 1.25rem;
+ --text-2xl: 1.5rem;
+ --text-3xl: 1.875rem;
+ --text-4xl: 2.25rem;
+ --text-5xl: 3rem;
+ --space-4: 1rem;
+ --space-6: 1.5rem;
+ --space-8: 2rem;
+ --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+ --transition-fast: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
+}
+
+[data-theme="dark"] {
+ --text-color: var(--gray-100);
+ --text-secondary: var(--gray-300);
+ --bg-color: var(--gray-900);
+ --bg-secondary: var(--gray-800);
+ --border-color: var(--gray-700);
+}
+
+[data-theme="light"] {
+ --text-color: var(--gray-900);
+ --text-secondary: var(--gray-700);
+ --bg-color: var(--white);
+ --bg-secondary: var(--gray-100);
+ --border-color: var(--gray-200);
+}
+
+/* Essential Reset */
+*, *::before, *::after {
+ box-sizing: border-box;
+}
+
+* {
+ margin: 0;
+ padding: 0;
+}
+
+html {
+ font-size: 16px;
+ scroll-behavior: smooth;
+}
+
+body {
+ font-family: var(--font-primary);
+ font-size: var(--text-base);
+ line-height: 1.6;
+ color: var(--text-color);
+ background-color: var(--bg-color);
+ transition: var(--transition);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+/* Typography - Critical only */
+h1, h2, h3 {
+ font-family: var(--font-heading);
+ font-weight: 600;
+ line-height: 1.3;
+ margin-bottom: var(--space-4);
+ color: var(--text-color);
+}
+
+h1 { font-size: var(--text-5xl); }
+h2 { font-size: var(--text-4xl); }
+h3 { font-size: var(--text-3xl); }
+
+p {
+ margin-bottom: var(--space-4);
+ color: var(--text-secondary);
+}
+
+a {
+ color: var(--primary-color);
+ text-decoration: none;
+ transition: var(--transition-fast);
+}
+
+/* Container */
+.container {
+ max-width: 1200px;
+ margin: 0 auto;
+ padding: 0 var(--space-6);
+}
+
+/* Header - Critical styles only */
+.header {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 1000;
+ background-color: var(--bg-color);
+ border-bottom: 1px solid var(--border-color);
+ transition: var(--transition);
+}
+
+.navbar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: var(--space-4) 0;
+}
+
+.navbar-brand {
+ font-size: var(--text-xl);
+ font-weight: 700;
+ color: var(--primary-color);
+}
+
+/* Hero Section - Above the fold */
+.hero {
+ min-height: 100vh;
+ display: flex;
+ align-items: center;
+ position: relative;
+ overflow: hidden;
+ background: linear-gradient(135deg, var(--bg-color) 0%, var(--bg-secondary) 100%);
+ padding-top: 80px;
+}
+
+.hero-content {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: var(--space-8);
+ align-items: center;
+ width: 100%;
+}
+
+.hero-title {
+ font-size: var(--text-5xl);
+ font-weight: 700;
+ margin-bottom: var(--space-6);
+ line-height: 1.2;
+}
+
+.gradient-text {
+ background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-dark) 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+}
+
+.hero-description {
+ font-size: var(--text-lg);
+ margin-bottom: var(--space-8);
+ color: var(--text-secondary);
+}
+
+/* Buttons - Critical only */
+.btn {
+ display: inline-flex;
+ align-items: center;
+ gap: var(--space-2);
+ padding: 12px 24px;
+ border: none;
+ border-radius: 6px;
+ font-weight: 500;
+ text-decoration: none;
+ transition: var(--transition-fast);
+ cursor: pointer;
+}
+
+.btn-primary {
+ background-color: var(--primary-color);
+ color: var(--white);
+}
+
+.btn-primary:hover {
+ background-color: var(--primary-dark);
+ color: var(--white);
+}
+
+.btn-outline {
+ background-color: transparent;
+ color: var(--primary-color);
+ border: 1px solid var(--primary-color);
+}
+
+.btn-lg {
+ padding: 16px 32px;
+ font-size: var(--text-lg);
+}
+
+.hero-buttons {
+ display: flex;
+ gap: var(--space-4);
+ margin-bottom: var(--space-8);
+}
+
+/* Mobile Navigation - Critical */
+.mobile-menu-btn {
+ display: none;
+ flex-direction: column;
+ gap: 4px;
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: var(--space-2);
+}
+
+.hamburger-line {
+ width: 24px;
+ height: 2px;
+ background-color: var(--text-color);
+ transition: var(--transition-fast);
+}
+
+/* Skip Link for Accessibility */
+.skip-link {
+ position: absolute;
+ top: -40px;
+ left: 6px;
+ background: var(--primary-color);
+ color: var(--white);
+ padding: 8px;
+ text-decoration: none;
+ z-index: 100;
+}
+
+.skip-link:focus {
+ top: 6px;
+}
+
+/* Loading Spinner - Critical */
+.loading-spinner {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: var(--bg-color);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ z-index: 9999;
+ opacity: 1;
+ transition: opacity 0.3s ease;
+}
+
+.loading-spinner.hidden {
+ opacity: 0;
+ pointer-events: none;
+}
+
+.spinner {
+ width: 40px;
+ height: 40px;
+ border: 4px solid var(--border-color);
+ border-top: 4px solid var(--primary-color);
+ border-radius: 50%;
+ animation: spin 1s linear infinite;
+}
+
+@keyframes spin {
+ 0% { transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); }
+}
+
+/* Responsive - Mobile First Critical Styles */
+@media (max-width: 768px) {
+ .container {
+ padding: 0 var(--space-4);
+ }
+
+ .hero-content {
+ grid-template-columns: 1fr;
+ text-align: center;
+ }
+
+ .hero-title {
+ font-size: var(--text-4xl);
+ }
+
+ .btn-lg {
+ padding: 14px 28px;
+ font-size: var(--text-base);
+ }
+
+ .hero-buttons {
+ flex-direction: column;
+ align-items: center;
+ }
+
+ .mobile-menu-btn {
+ display: flex;
+ }
+}
\ No newline at end of file
diff --git a/_layouts/default.html b/_layouts/default.html
index b860c64..98325d1 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -6,6 +6,12 @@
+
+
+
+
+
+
@@ -13,14 +19,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
{% if page.title %}{{ page.title }} - {{ site.title }}{% else %}{{ site.title }}{% endif %}
@@ -35,8 +54,14 @@
-
-
+
+
+
+
+
+
+
+ {% if page.url == '/' %}
+
+
+ {% endif %}
+
+ {% if page.layout == 'post' or page.layout == 'project' %}
+
+
+ {% endif %}